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.
22 #include <sys/signal.h>
28 #ifdef HAVE_LIBXXF86VM
29 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
30 this is a crude hack to get around it */
32 #include "ts_xf86vmode.h"
51 #ifdef HAVE_LIBXXF86DGA
52 #include "ts_xf86dga.h"
56 #include <sys/types.h>
62 /* This for all the enumeration and creation of D3D-related objects */
63 #include "d3d_private.h"
65 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
68 /* Restore signal handlers overwritten by XF86DGA
69 * this is a define, for it will only work in emulator mode
71 #undef RESTORE_SIGNALS
73 /* Where do these GUIDs come from? mkuuid.
74 * They exist solely to distinguish between the targets Wine support,
75 * and should be different than any other GUIDs in existence.
77 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
81 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
84 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
88 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
91 static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt;
92 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
93 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
94 static struct IDirectDrawClipper_VTable ddclipvt;
95 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
96 static struct IDirect3D_VTable d3dvt;
97 static struct IDirect3D2_VTable d3d2vt;
99 #ifdef HAVE_LIBXXF86VM
100 static XF86VidModeModeInfo *orig_mode = NULL;
104 DDRAW_DGA_Available(void)
106 #ifdef HAVE_LIBXXF86DGA
107 int evbase, evret, fd;
112 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
113 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
114 /* others. --stephenc */
115 if ((fd = open("/dev/mem", O_RDWR)) != -1)
118 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
119 #else /* defined(HAVE_LIBXXF86DGA) */
121 #endif /* defined(HAVE_LIBXXF86DGA) */
125 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
126 if (DDRAW_DGA_Available()) {
127 TRACE(ddraw, "Enumerating DGA interface\n");
128 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
130 TRACE(ddraw, "Enumerating Xlib interface\n");
131 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
132 TRACE(ddraw, "Enumerating Default interface\n");
133 ddenumproc(NULL,"WINE (default)","display",data);
137 /* What is this doing here? */
139 DSoundHelp(DWORD x,DWORD y,DWORD z) {
140 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
145 /******************************************************************************
146 * internal helper functions
148 static void _dump_DDBLTFX(DWORD flagmask) {
154 #define FE(x) { x, #x},
155 FE(DDBLTFX_ARITHSTRETCHY)
156 FE(DDBLTFX_MIRRORLEFTRIGHT)
157 FE(DDBLTFX_MIRRORUPDOWN)
158 FE(DDBLTFX_NOTEARING)
159 FE(DDBLTFX_ROTATE180)
160 FE(DDBLTFX_ROTATE270)
162 FE(DDBLTFX_ZBUFFERRANGE)
163 FE(DDBLTFX_ZBUFFERBASEDEST)
165 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
166 if (flags[i].mask & flagmask) {
167 DUMP("%s ",flags[i].name);
174 static void _dump_DDBLTFAST(DWORD flagmask) {
180 #define FE(x) { x, #x},
181 FE(DDBLTFAST_NOCOLORKEY)
182 FE(DDBLTFAST_SRCCOLORKEY)
183 FE(DDBLTFAST_DESTCOLORKEY)
186 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
187 if (flags[i].mask & flagmask)
188 DUMP("%s ",flags[i].name);
192 static void _dump_DDBLT(DWORD flagmask) {
198 #define FE(x) { x, #x},
200 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
201 FE(DDBLT_ALPHADESTNEG)
202 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
203 FE(DDBLT_ALPHAEDGEBLEND)
205 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
206 FE(DDBLT_ALPHASRCNEG)
207 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
213 FE(DDBLT_KEYDESTOVERRIDE)
215 FE(DDBLT_KEYSRCOVERRIDE)
217 FE(DDBLT_ROTATIONANGLE)
219 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
220 FE(DDBLT_ZBUFFERDESTOVERRIDE)
221 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
222 FE(DDBLT_ZBUFFERSRCOVERRIDE)
226 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
227 if (flags[i].mask & flagmask)
228 DUMP("%s ",flags[i].name);
231 static void _dump_DDSCAPS(DWORD flagmask) {
237 #define FE(x) { x, #x},
238 FE(DDSCAPS_RESERVED1)
240 FE(DDSCAPS_BACKBUFFER)
243 FE(DDSCAPS_FRONTBUFFER)
244 FE(DDSCAPS_OFFSCREENPLAIN)
247 FE(DDSCAPS_PRIMARYSURFACE)
248 FE(DDSCAPS_PRIMARYSURFACELEFT)
249 FE(DDSCAPS_SYSTEMMEMORY)
252 FE(DDSCAPS_VIDEOMEMORY)
254 FE(DDSCAPS_WRITEONLY)
257 FE(DDSCAPS_LIVEVIDEO)
261 FE(DDSCAPS_RESERVED2)
262 FE(DDSCAPS_ALLOCONLOAD)
263 FE(DDSCAPS_VIDEOPORT)
264 FE(DDSCAPS_LOCALVIDMEM)
265 FE(DDSCAPS_NONLOCALVIDMEM)
266 FE(DDSCAPS_STANDARDVGAMODE)
267 FE(DDSCAPS_OPTIMIZED)
269 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
270 if (flags[i].mask & flagmask)
271 DUMP("%s ",flags[i].name);
275 static void _dump_DDSD(DWORD flagmask) {
285 FE(DDSD_BACKBUFFERCOUNT)
286 FE(DDSD_ZBUFFERBITDEPTH)
287 FE(DDSD_ALPHABITDEPTH)
289 FE(DDSD_CKDESTOVERLAY)
291 FE(DDSD_CKSRCOVERLAY)
298 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
299 if (flags[i].mask & flagmask)
300 DUMP("%s ",flags[i].name);
304 static void _dump_DDCOLORKEY(DWORD flagmask) {
310 #define FE(x) { x, #x},
314 FE(DDPF_PALETTEINDEXED4)
315 FE(DDPF_PALETTEINDEXEDTO8)
316 FE(DDPF_PALETTEINDEXED8)
322 FE(DDPF_PALETTEINDEXED1)
323 FE(DDPF_PALETTEINDEXED2)
326 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
327 if (flags[i].mask & flagmask)
328 DUMP("%s ",flags[i].name);
332 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
333 DUMP("Size : %ld\n", pf->dwSize);
335 _dump_DDCOLORKEY(pf->dwFlags);
336 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
337 DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
338 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
339 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
342 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
343 static XVisualInfo *vi;
348 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
351 pf->dwSize = sizeof(DDPIXELFORMAT);
352 if (ddraw->d.depth==8) {
353 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
354 pf->x.dwRGBBitCount = 8;
355 pf->y.dwRBitMask = 0;
356 pf->z.dwGBitMask = 0;
357 pf->xx.dwBBitMask = 0;
358 pf->xy.dwRGBAlphaBitMask= 0;
361 if (ddraw->d.depth==16) {
362 pf->dwFlags = DDPF_RGB;
363 pf->x.dwRGBBitCount = 16;
364 pf->y.dwRBitMask = vi[0].red_mask;
365 pf->z.dwGBitMask = vi[0].green_mask;
366 pf->xx.dwBBitMask = vi[0].blue_mask;
367 pf->xy.dwRGBAlphaBitMask= 0;
370 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
371 return DDERR_GENERIC;
374 /******************************************************************************
375 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
377 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
378 * DDS and DDS2 use those functions. (Function calls did not change (except
379 * using different DirectDrawSurfaceX version), just added flags and functions)
381 static HRESULT WINAPI IDirectDrawSurface3_Lock(
382 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
384 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
385 this,lprect,lpddsd,flags,(DWORD)hnd);
386 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
387 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
388 this,lprect,lpddsd,flags,(DWORD)hnd);
390 /* First, copy the Surface description */
391 *lpddsd = this->s.surface_desc;
393 /* If asked only for a part, change the surface pointer */
395 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
396 lprect->top,lprect->left,lprect->bottom,lprect->right
398 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
399 (lprect->top*this->s.surface_desc.lPitch) +
400 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
402 assert(this->s.surface_desc.y.lpSurface);
407 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
408 LPDIRECTDRAWSURFACE3 this,LPVOID surface
410 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
414 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
415 LPDIRECTDRAWSURFACE3 this,LPVOID surface)
417 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
419 if (!this->s.ddraw->d.paintable)
422 /* Only redraw the screen when unlocking the buffer that is on screen */
423 if ((this->t.xlib.image != NULL) &&
424 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
426 if (this->s.ddraw->e.xlib.xshm_active)
427 TSXShmPutImage(display,
428 this->s.ddraw->d.drawable,
429 DefaultGCOfScreen(screen),
432 this->t.xlib.image->width,
433 this->t.xlib.image->height,
437 TSXPutImage( display,
438 this->s.ddraw->d.drawable,
439 DefaultGCOfScreen(screen),
442 this->t.xlib.image->width,
443 this->t.xlib.image->height);
445 if (this->s.palette && this->s.palette->cm)
446 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
452 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
453 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
455 #ifdef HAVE_LIBXXF86DGA
456 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
458 if (this->s.backbuffer)
459 flipto = this->s.backbuffer;
463 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
465 if (flipto->s.palette && flipto->s.palette->cm) {
466 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
468 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
474 tmp = this->t.dga.fb_height;
475 this->t.dga.fb_height = flipto->t.dga.fb_height;
476 flipto->t.dga.fb_height = tmp;
478 ptmp = this->s.surface_desc.y.lpSurface;
479 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
480 flipto->s.surface_desc.y.lpSurface = ptmp;
483 #else /* defined(HAVE_LIBXXF86DGA) */
485 #endif /* defined(HAVE_LIBXXF86DGA) */
488 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
489 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
491 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
492 if (!this->s.ddraw->d.paintable)
496 if (this->s.backbuffer)
497 flipto = this->s.backbuffer;
503 if (this->s.ddraw->e.xlib.xshm_active) {
504 TSXShmPutImage(display,
505 this->s.ddraw->d.drawable,
506 DefaultGCOfScreen(screen),
507 flipto->t.xlib.image,
509 flipto->t.xlib.image->width,
510 flipto->t.xlib.image->height,
515 this->s.ddraw->d.drawable,
516 DefaultGCOfScreen(screen),
517 flipto->t.xlib.image,
519 flipto->t.xlib.image->width,
520 flipto->t.xlib.image->height);
522 if (flipto->s.palette && flipto->s.palette->cm) {
523 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,flipto->s.palette->cm);
528 tmp = this->t.xlib.image;
529 this->t.xlib.image = flipto->t.xlib.image;
530 flipto->t.xlib.image = tmp;
531 surf = this->s.surface_desc.y.lpSurface;
532 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
533 flipto->s.surface_desc.y.lpSurface = surf;
539 /* The IDirectDrawSurface3::SetPalette method attaches the specified
540 * DirectDrawPalette object to a surface. The surface uses this palette for all
541 * subsequent operations. The palette change takes place immediately.
543 static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
544 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
547 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
550 if( this->s.palette != NULL )
551 this->s.palette->lpvtbl->fnRelease( this->s.palette );
552 this->s.palette = pal;
557 if( !(pal->cm) && (this->s.ddraw->d.depth<=8))
559 pal->cm = TSXCreateColormap(display,this->s.ddraw->d.drawable,DefaultVisualOfScreen(screen),AllocAll);
561 if (!Options.managed)
562 TSXInstallColormap(display,pal->cm);
564 for (i=0;i<256;i++) {
567 xc.red = pal->palents[i].peRed<<8;
568 xc.blue = pal->palents[i].peBlue<<8;
569 xc.green = pal->palents[i].peGreen<<8;
570 xc.flags = DoRed|DoBlue|DoGreen;
572 TSXStoreColor(display,pal->cm,&xc);
574 TSXInstallColormap(display,pal->cm);
577 /* According to spec, we are only supposed to
578 * AddRef if this is not the same palette.
580 if( this->s.palette != pal )
583 pal->lpvtbl->fnAddRef( pal );
584 if( this->s.palette != NULL )
585 this->s.palette->lpvtbl->fnRelease( this->s.palette );
586 this->s.palette = pal;
588 /* I think that we need to attach it to all backbuffers...*/
589 if( this->s.backbuffer ) {
590 if( this->s.backbuffer->s.palette )
591 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
592 this->s.backbuffer->s.palette );
593 this->s.backbuffer->s.palette = pal;
595 pal->lpvtbl->fnAddRef( pal );
597 /* Perform the refresh */
598 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
603 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
604 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
606 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
607 #ifdef HAVE_LIBXXF86DGA
608 /* According to spec, we are only supposed to
609 * AddRef if this is not the same palette.
611 if( this->s.palette != pal )
614 pal->lpvtbl->fnAddRef( pal );
615 if( this->s.palette != NULL )
616 this->s.palette->lpvtbl->fnRelease( this->s.palette );
617 this->s.palette = pal;
619 /* I think that we need to attach it to all backbuffers...*/
620 if( this->s.backbuffer ) {
621 if( this->s.backbuffer->s.palette )
622 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
623 this->s.backbuffer->s.palette = pal;
624 if( pal ) pal->lpvtbl->fnAddRef( pal );
626 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
629 #else /* defined(HAVE_LIBXXF86DGA) */
631 #endif /* defined(HAVE_LIBXXF86DGA) */
636 static HRESULT WINAPI IDirectDrawSurface3_Blt(
637 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
640 DDSURFACEDESC ddesc,sdesc;
643 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
644 this,rdst,src,rsrc,dwFlags,lpbltfx);
647 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
648 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
650 if (TRACE_ON(ddraw)) {
651 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
652 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
653 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
654 if (dwFlags & DDBLT_DDFX) {
655 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
660 memcpy(&xdst,rdst,sizeof(xdst));
663 xdst.bottom = ddesc.dwHeight;
665 xdst.right = ddesc.dwWidth;
669 memcpy(&xsrc,rsrc,sizeof(xsrc));
673 xsrc.bottom = sdesc.dwHeight;
675 xsrc.right = sdesc.dwWidth;
677 memset(&xsrc,0,sizeof(xsrc));
681 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
683 if (dwFlags & DDBLT_COLORFILL) {
684 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
687 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
688 for (i=xdst.top;i<xdst.bottom;i++) {
689 xpixel = xline+bpp*xdst.left;
691 for (j=xdst.left;j<xdst.right;j++) {
692 /* FIXME: this only works on little endian
693 * architectures, where DWORD starts with low
696 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
699 xline += ddesc.lPitch;
701 dwFlags &= ~(DDBLT_COLORFILL);
706 TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
708 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
712 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
713 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
714 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
715 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
718 memcpy(ddesc.y.lpSurface,
720 ddesc.dwHeight * ddesc.lPitch);
722 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
723 int srcheight = xsrc.bottom - xsrc.top;
724 int srcwidth = xsrc.right - xsrc.left;
725 int dstheight = xdst.bottom - xdst.top;
726 int dstwidth = xdst.right - xdst.left;
727 int width = (xsrc.right - xsrc.left) * bpp;
730 /* Sanity check for rectangle sizes */
731 if ((srcheight != dstheight) || (srcwidth != dstwidth)) {
734 /* I think we should do a Blit with 'stretching' here....
735 Tomb Raider II uses this to display the background during the menu selection
736 when the screen resolution is != than 40x480 */
737 TRACE(ddraw, "Blt with stretching\n");
739 /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
741 /* In this case, we cannot do any anti-aliasing */
742 for (y = xdst.top; y < xdst.bottom; y++) {
743 for (x = xdst.left; x < xdst.right; x++) {
745 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
746 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
748 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
749 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
751 dbuf[(y * ddesc.lPitch) + x] = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
755 FIXME(ddraw, "Not done yet for depth != 8\n");
758 /* Same size => fast blit */
759 for (h = 0; h < srcheight; h++) {
760 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
761 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
767 if (dwFlags && FIXME_ON(ddraw)) {
768 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
771 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
772 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
777 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
778 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
781 DDSURFACEDESC ddesc,sdesc;
783 if (1 || TRACE_ON(ddraw)) {
784 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
785 this,dstx,dsty,src,rsrc,trans
787 FIXME(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
788 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
790 /* We need to lock the surfaces, or we won't get refreshes when done. */
791 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
792 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
793 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
794 h=rsrc->bottom-rsrc->top;
795 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
796 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
798 w=rsrc->right-rsrc->left;
799 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
800 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
804 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
805 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
809 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
810 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
814 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
815 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
817 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
823 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
824 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
826 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
827 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
831 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
832 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
834 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
837 /* Simply copy the surface description stored in the object */
838 *ddsd = this->s.surface_desc;
840 if (TRACE_ON(ddraw)) {
841 fprintf(stderr," flags: ");
842 _dump_DDSD(ddsd->dwFlags);
843 if (ddsd->dwFlags & DDSD_CAPS) {
844 fprintf(stderr, " caps: ");
845 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
847 fprintf(stderr,"\n");
853 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
854 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
856 return ++(this->ref);
859 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
860 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
862 #ifdef HAVE_LIBXXF86DGA
863 if (!--(this->ref)) {
864 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
865 /* clear out of surface list */
866 if (this->t.dga.fb_height == -1) {
867 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
869 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
872 /* Free the backbuffer */
873 if (this->s.backbuffer)
874 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
876 HeapFree(GetProcessHeap(),0,this);
879 #endif /* defined(HAVE_LIBXXF86DGA) */
883 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
884 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
886 if (!--(this->ref)) {
887 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
889 if( this->s.backbuffer )
890 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
892 if (this->t.xlib.image != NULL) {
893 this->t.xlib.image->data = NULL;
896 if (this->s.ddraw->e.xlib.xshm_active) {
897 TSXShmDetach(display, &(this->t.xlib.shminfo));
898 TSXDestroyImage(this->t.xlib.image);
899 shmdt(this->t.xlib.shminfo.shmaddr);
902 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
903 TSXDestroyImage(this->t.xlib.image);
908 this->t.xlib.image = 0;
910 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
914 this->s.palette->lpvtbl->fnRelease(this->s.palette);
916 HeapFree(GetProcessHeap(),0,this);
923 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
924 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
926 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
927 this, lpddsd, lpdsf);
929 if (TRACE_ON(ddraw)) {
930 TRACE(ddraw," caps ");
931 _dump_DDSCAPS(lpddsd->dwCaps);
934 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
935 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
939 /* FIXME: should handle more than one backbuffer */
940 *lpdsf = this->s.backbuffer;
942 if( this->s.backbuffer )
943 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
948 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
949 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
951 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
953 return DDERR_ALREADYINITIALIZED;
956 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
957 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
959 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
961 *pf = this->s.surface_desc.ddpfPixelFormat;
966 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
967 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
971 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
972 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
974 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
978 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
979 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
981 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
985 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
986 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
988 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
990 /* This hack will be enough for the moment */
991 if (this->s.backbuffer == NULL)
992 this->s.backbuffer = surf;
996 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
997 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
998 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1002 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
1003 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
1004 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1009 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
1012 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1013 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1015 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
1016 * the same interface. And IUnknown does that too of course.
1018 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1019 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1020 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1021 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1024 this->lpvtbl->fnAddRef(this);
1026 TRACE(ddraw, " Creating IDirect3DSurfaceX interface (%p)\n", *obj);
1030 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1032 /* Texture interface */
1033 *obj = d3dtexture2_create(this);
1034 this->lpvtbl->fnAddRef(this);
1036 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1040 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1042 /* Texture interface */
1043 *obj = d3dtexture_create(this);
1044 this->lpvtbl->fnAddRef(this);
1046 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1050 else if (is_OpenGL_dx3(refiid, (LPDIRECTDRAWSURFACE) this, (LPDIRECT3DDEVICE *) obj))
1052 /* It is the OpenGL Direct3D Device */
1053 this->lpvtbl->fnAddRef(this);
1055 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1060 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1061 return OLE_E_ENUM_NOMORE;
1064 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
1065 TRACE(ddraw,"(%p)->(), stub!\n",this);
1066 return DD_OK; /* hmm */
1069 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1070 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
1074 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
1075 FIXME(ddraw,"(%p)->(),stub!\n",this);
1079 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
1080 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey )
1082 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",this,dwFlags,ckey);
1084 if( dwFlags & DDCKEY_SRCBLT )
1086 dwFlags &= ~DDCKEY_SRCBLT;
1087 this->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1088 memcpy( &(this->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1091 if( dwFlags & DDCKEY_DESTBLT )
1093 dwFlags &= ~DDCKEY_DESTBLT;
1094 this->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1095 memcpy( &(this->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1098 if( dwFlags & DDCKEY_SRCOVERLAY )
1100 dwFlags &= ~DDCKEY_SRCOVERLAY;
1101 this->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1102 memcpy( &(this->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1105 if( dwFlags & DDCKEY_DESTOVERLAY )
1107 dwFlags &= ~DDCKEY_DESTOVERLAY;
1108 this->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1109 memcpy( &(this->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1114 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1121 static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect(
1122 LPDIRECTDRAWSURFACE3 this,
1125 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
1130 static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface(
1131 LPDIRECTDRAWSURFACE3 this,
1133 LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface )
1135 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
1140 static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders(
1141 LPDIRECTDRAWSURFACE3 this,
1144 LPDDENUMSURFACESCALLBACK lpfnCallback )
1146 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1147 lpContext, lpfnCallback );
1152 static HRESULT WINAPI IDirectDrawSurface3_GetClipper(
1153 LPDIRECTDRAWSURFACE3 this,
1154 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1156 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1161 static HRESULT WINAPI IDirectDrawSurface3_GetColorKey(
1162 LPDIRECTDRAWSURFACE3 this,
1164 LPDDCOLORKEY lpDDColorKey )
1166 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", this, dwFlags, lpDDColorKey);
1168 if( dwFlags & DDCKEY_SRCBLT ) {
1169 dwFlags &= ~DDCKEY_SRCBLT;
1170 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1173 if( dwFlags & DDCKEY_DESTBLT )
1175 dwFlags &= ~DDCKEY_DESTBLT;
1176 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1179 if( dwFlags & DDCKEY_SRCOVERLAY )
1181 dwFlags &= ~DDCKEY_SRCOVERLAY;
1182 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1185 if( dwFlags & DDCKEY_DESTOVERLAY )
1187 dwFlags &= ~DDCKEY_DESTOVERLAY;
1188 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1193 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1199 static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus(
1200 LPDIRECTDRAWSURFACE3 this,
1203 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1208 static HRESULT WINAPI IDirectDrawSurface3_GetPalette(
1209 LPDIRECTDRAWSURFACE3 this,
1210 LPDIRECTDRAWPALETTE* lplpDDPalette )
1212 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1217 static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition(
1218 LPDIRECTDRAWSURFACE3 this,
1222 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1227 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay(
1228 LPDIRECTDRAWSURFACE3 this,
1230 LPDIRECTDRAWSURFACE3 lpDDDestSurface,
1231 LPRECT32 lpDestRect,
1233 LPDDOVERLAYFX lpDDOverlayFx )
1235 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1236 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1241 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay(
1242 LPDIRECTDRAWSURFACE3 this,
1245 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1250 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder(
1251 LPDIRECTDRAWSURFACE3 this,
1253 LPDIRECTDRAWSURFACE3 lpDDSReference )
1255 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1260 static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface(
1261 LPDIRECTDRAWSURFACE3 this,
1264 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1266 /* Not sure about that... */
1267 *lplpDD = (void *) this->s.ddraw;
1272 static HRESULT WINAPI IDirectDrawSurface3_PageLock(
1273 LPDIRECTDRAWSURFACE3 this,
1276 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1281 static HRESULT WINAPI IDirectDrawSurface3_PageUnlock(
1282 LPDIRECTDRAWSURFACE3 this,
1285 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1290 static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc(
1291 LPDIRECTDRAWSURFACE3 this,
1292 LPDDSURFACEDESC lpDDSD,
1295 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1300 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
1301 IDirectDrawSurface3_QueryInterface,
1302 IDirectDrawSurface3_AddRef,
1303 DGA_IDirectDrawSurface3_Release,
1304 IDirectDrawSurface3_AddAttachedSurface,
1305 IDirectDrawSurface3_AddOverlayDirtyRect,
1306 IDirectDrawSurface3_Blt,
1307 IDirectDrawSurface3_BltBatch,
1308 IDirectDrawSurface3_BltFast,
1309 IDirectDrawSurface3_DeleteAttachedSurface,
1310 IDirectDrawSurface3_EnumAttachedSurfaces,
1311 IDirectDrawSurface3_EnumOverlayZOrders,
1312 DGA_IDirectDrawSurface3_Flip,
1313 IDirectDrawSurface3_GetAttachedSurface,
1314 IDirectDrawSurface3_GetBltStatus,
1315 IDirectDrawSurface3_GetCaps,
1316 IDirectDrawSurface3_GetClipper,
1317 IDirectDrawSurface3_GetColorKey,
1318 IDirectDrawSurface3_GetDC,
1319 IDirectDrawSurface3_GetFlipStatus,
1320 IDirectDrawSurface3_GetOverlayPosition,
1321 IDirectDrawSurface3_GetPalette,
1322 IDirectDrawSurface3_GetPixelFormat,
1323 IDirectDrawSurface3_GetSurfaceDesc,
1324 IDirectDrawSurface3_Initialize,
1325 IDirectDrawSurface3_IsLost,
1326 IDirectDrawSurface3_Lock,
1327 IDirectDrawSurface3_ReleaseDC,
1328 IDirectDrawSurface3_Restore,
1329 IDirectDrawSurface3_SetClipper,
1330 IDirectDrawSurface3_SetColorKey,
1331 IDirectDrawSurface3_SetOverlayPosition,
1332 DGA_IDirectDrawSurface3_SetPalette,
1333 DGA_IDirectDrawSurface3_Unlock,
1334 IDirectDrawSurface3_UpdateOverlay,
1335 IDirectDrawSurface3_UpdateOverlayDisplay,
1336 IDirectDrawSurface3_UpdateOverlayZOrder,
1337 IDirectDrawSurface3_GetDDInterface,
1338 IDirectDrawSurface3_PageLock,
1339 IDirectDrawSurface3_PageUnlock,
1340 IDirectDrawSurface3_SetSurfaceDesc,
1343 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
1344 IDirectDrawSurface3_QueryInterface,
1345 IDirectDrawSurface3_AddRef,
1346 Xlib_IDirectDrawSurface3_Release,
1347 IDirectDrawSurface3_AddAttachedSurface,
1348 IDirectDrawSurface3_AddOverlayDirtyRect,
1349 IDirectDrawSurface3_Blt,
1350 IDirectDrawSurface3_BltBatch,
1351 IDirectDrawSurface3_BltFast,
1352 IDirectDrawSurface3_DeleteAttachedSurface,
1353 IDirectDrawSurface3_EnumAttachedSurfaces,
1354 IDirectDrawSurface3_EnumOverlayZOrders,
1355 Xlib_IDirectDrawSurface3_Flip,
1356 IDirectDrawSurface3_GetAttachedSurface,
1357 IDirectDrawSurface3_GetBltStatus,
1358 IDirectDrawSurface3_GetCaps,
1359 IDirectDrawSurface3_GetClipper,
1360 IDirectDrawSurface3_GetColorKey,
1361 IDirectDrawSurface3_GetDC,
1362 IDirectDrawSurface3_GetFlipStatus,
1363 IDirectDrawSurface3_GetOverlayPosition,
1364 IDirectDrawSurface3_GetPalette,
1365 IDirectDrawSurface3_GetPixelFormat,
1366 IDirectDrawSurface3_GetSurfaceDesc,
1367 IDirectDrawSurface3_Initialize,
1368 IDirectDrawSurface3_IsLost,
1369 IDirectDrawSurface3_Lock,
1370 IDirectDrawSurface3_ReleaseDC,
1371 IDirectDrawSurface3_Restore,
1372 IDirectDrawSurface3_SetClipper,
1373 IDirectDrawSurface3_SetColorKey,
1374 IDirectDrawSurface3_SetOverlayPosition,
1375 Xlib_IDirectDrawSurface3_SetPalette,
1376 Xlib_IDirectDrawSurface3_Unlock,
1377 IDirectDrawSurface3_UpdateOverlay,
1378 IDirectDrawSurface3_UpdateOverlayDisplay,
1379 IDirectDrawSurface3_UpdateOverlayZOrder,
1380 IDirectDrawSurface3_GetDDInterface,
1381 IDirectDrawSurface3_PageLock,
1382 IDirectDrawSurface3_PageUnlock,
1383 IDirectDrawSurface3_SetSurfaceDesc,
1386 /******************************************************************************
1387 * DirectDrawCreateClipper (DDRAW.7)
1389 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1390 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1391 LPUNKNOWN pUnkOuter)
1393 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1395 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1396 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1397 (*lplpDDClipper)->ref = 1;
1402 /******************************************************************************
1403 * IDirectDrawClipper
1405 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1406 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1408 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1412 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1413 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1418 HeapFree(GetProcessHeap(),0,this);
1422 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1423 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1425 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1430 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1431 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1433 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1437 static HRESULT WINAPI IDirectDrawClipper_QueryInterface(
1438 LPDIRECTDRAWCLIPPER this,
1442 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,riid,ppvObj);
1443 return OLE_E_ENUM_NOMORE;
1446 static ULONG WINAPI IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER this )
1448 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1449 return ++(this->ref);
1452 static HRESULT WINAPI IDirectDrawClipper_GetHWnd(
1453 LPDIRECTDRAWCLIPPER this,
1456 FIXME(ddraw,"(%p)->(%p),stub!\n",this,HWndPtr);
1460 static HRESULT WINAPI IDirectDrawClipper_Initialize(
1461 LPDIRECTDRAWCLIPPER this,
1465 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD,dwFlags);
1469 static HRESULT WINAPI IDirectDrawClipper_IsClipListChanged(
1470 LPDIRECTDRAWCLIPPER this,
1471 BOOL32* lpbChanged )
1473 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpbChanged);
1477 static struct IDirectDrawClipper_VTable ddclipvt = {
1478 IDirectDrawClipper_QueryInterface,
1479 IDirectDrawClipper_AddRef,
1480 IDirectDrawClipper_Release,
1481 IDirectDrawClipper_GetClipList,
1482 IDirectDrawClipper_GetHWnd,
1483 IDirectDrawClipper_Initialize,
1484 IDirectDrawClipper_IsClipListChanged,
1485 IDirectDrawClipper_SetClipList,
1486 IDirectDrawClipper_SetHwnd
1490 /******************************************************************************
1491 * IDirectDrawPalette
1493 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1494 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1498 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1499 this,x,start,count,palent);
1501 if (!this->cm) /* should not happen */ {
1502 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1503 return DDERR_GENERIC;
1505 for (i=0;i<count;i++) {
1506 palent[i].peRed = this->palents[start+i].peRed;
1507 palent[i].peBlue = this->palents[start+i].peBlue;
1508 palent[i].peGreen = this->palents[start+i].peGreen;
1509 palent[i].peFlags = this->palents[start+i].peFlags;
1515 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1516 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1521 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1522 this,x,start,count,palent
1524 for (i=0;i<count;i++) {
1525 xc.red = palent[i].peRed<<8;
1526 xc.blue = palent[i].peBlue<<8;
1527 xc.green = palent[i].peGreen<<8;
1528 xc.flags = DoRed|DoBlue|DoGreen;
1532 TSXStoreColor(display,this->cm,&xc);
1534 this->palents[start+i].peRed = palent[i].peRed;
1535 this->palents[start+i].peBlue = palent[i].peBlue;
1536 this->palents[start+i].peGreen = palent[i].peGreen;
1537 this->palents[start+i].peFlags = palent[i].peFlags;
1539 if (!this->cm) /* should not happen */ {
1544 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1545 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1547 #ifdef HAVE_LIBXXF86DGA
1552 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1553 this,x,start,count,palent
1555 if (!this->cm) /* should not happen */ {
1556 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1557 return DDERR_GENERIC;
1559 /* FIXME: free colorcells instead of freeing whole map */
1561 this->cm = TSXCopyColormapAndFree(display,this->cm);
1562 TSXFreeColormap(display,cm);
1564 for (i=0;i<count;i++) {
1565 xc.red = palent[i].peRed<<8;
1566 xc.blue = palent[i].peBlue<<8;
1567 xc.green = palent[i].peGreen<<8;
1568 xc.flags = DoRed|DoBlue|DoGreen;
1571 TSXStoreColor(display,this->cm,&xc);
1573 this->palents[start+i].peRed = palent[i].peRed;
1574 this->palents[start+i].peBlue = palent[i].peBlue;
1575 this->palents[start+i].peGreen = palent[i].peGreen;
1576 this->palents[start+i].peFlags = palent[i].peFlags;
1578 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1580 #else /* defined(HAVE_LIBXXF86DGA) */
1581 return E_UNEXPECTED;
1582 #endif /* defined(HAVE_LIBXXF86DGA) */
1585 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1586 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1587 if (!--(this->ref)) {
1589 TSXFreeColormap(display,this->cm);
1592 HeapFree(GetProcessHeap(),0,this);
1598 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1600 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1601 return ++(this->ref);
1604 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1605 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1607 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1609 return DDERR_ALREADYINITIALIZED;
1612 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1613 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1615 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1619 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1620 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1624 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1625 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1630 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1631 IDirectDrawPalette_QueryInterface,
1632 IDirectDrawPalette_AddRef,
1633 IDirectDrawPalette_Release,
1634 IDirectDrawPalette_GetCaps,
1635 IDirectDrawPalette_GetEntries,
1636 IDirectDrawPalette_Initialize,
1637 DGA_IDirectDrawPalette_SetEntries
1640 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1641 IDirectDrawPalette_QueryInterface,
1642 IDirectDrawPalette_AddRef,
1643 IDirectDrawPalette_Release,
1644 IDirectDrawPalette_GetCaps,
1645 IDirectDrawPalette_GetEntries,
1646 IDirectDrawPalette_Initialize,
1647 Xlib_IDirectDrawPalette_SetEntries
1650 /*******************************************************************************
1653 static HRESULT WINAPI IDirect3D_QueryInterface(
1654 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1656 /* FIXME: Not sure if this is correct */
1659 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1660 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1661 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1663 this->lpvtbl->fnAddRef(this);
1665 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
1669 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1672 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1674 d3d->ddraw = (LPDIRECTDRAW)this;
1675 this->lpvtbl->fnAddRef(this);
1676 d3d->lpvtbl = &d3dvt;
1679 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
1683 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1686 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1688 d3d->ddraw = (LPDIRECTDRAW)this;
1689 this->lpvtbl->fnAddRef(this);
1690 d3d->lpvtbl = &d3d2vt;
1693 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
1697 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1698 return OLE_E_ENUM_NOMORE;
1701 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1702 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1704 return ++(this->ref);
1707 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1709 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1711 if (!--(this->ref)) {
1712 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1713 HeapFree(GetProcessHeap(),0,this);
1719 static HRESULT WINAPI IDirect3D_Initialize(
1720 LPDIRECT3D this, REFIID refiid )
1722 /* FIXME: Not sure if this is correct */
1725 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1726 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1728 return DDERR_ALREADYINITIALIZED;
1731 static HRESULT WINAPI IDirect3D_EnumDevices(LPDIRECT3D this,
1732 LPD3DENUMDEVICESCALLBACK cb,
1734 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1736 /* Call functions defined in d3ddevices.c */
1737 if (d3d_OpenGL_dx3(cb, context))
1743 static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,
1744 LPDIRECT3DLIGHT *lplight,
1747 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
1749 /* Call the creation function that is located in d3dlight.c */
1750 *lplight = d3dlight_create_dx3(this);
1755 static HRESULT WINAPI IDirect3D_CreateMaterial(LPDIRECT3D this,
1756 LPDIRECT3DMATERIAL *lpmaterial,
1759 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
1761 /* Call the creation function that is located in d3dviewport.c */
1762 *lpmaterial = d3dmaterial_create(this);
1767 static HRESULT WINAPI IDirect3D_CreateViewport(LPDIRECT3D this,
1768 LPDIRECT3DVIEWPORT *lpviewport,
1771 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
1773 /* Call the creation function that is located in d3dviewport.c */
1774 *lpviewport = d3dviewport_create(this);
1779 static HRESULT WINAPI IDirect3D_FindDevice(LPDIRECT3D this,
1780 LPD3DFINDDEVICESEARCH lpfinddevsrc,
1781 LPD3DFINDDEVICERESULT lpfinddevrst)
1783 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
1788 static struct IDirect3D_VTable d3dvt = {
1789 IDirect3D_QueryInterface,
1792 IDirect3D_Initialize,
1793 IDirect3D_EnumDevices,
1794 IDirect3D_CreateLight,
1795 IDirect3D_CreateMaterial,
1796 IDirect3D_CreateViewport,
1797 IDirect3D_FindDevice
1800 /*******************************************************************************
1803 static HRESULT WINAPI IDirect3D2_QueryInterface(
1804 LPDIRECT3D2 this,REFIID refiid,LPVOID *obj) {
1805 /* For the moment, we use the same function as in IDirect3D */
1806 TRACE(ddraw, "Calling IDirect3D enumerating function.\n");
1808 return IDirect3D_QueryInterface((LPDIRECT3D) this, refiid, obj);
1811 static ULONG WINAPI IDirect3D2_AddRef(LPDIRECT3D2 this) {
1812 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1814 return ++(this->ref);
1817 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1818 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1820 if (!--(this->ref)) {
1821 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1822 HeapFree(GetProcessHeap(),0,this);
1828 static HRESULT WINAPI IDirect3D2_EnumDevices(
1829 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1831 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1833 /* Call functions defined in d3ddevices.c */
1834 if (d3d_OpenGL(cb, context))
1840 static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,
1841 LPDIRECT3DLIGHT *lplight,
1844 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
1846 /* Call the creation function that is located in d3dlight.c */
1847 *lplight = d3dlight_create(this);
1852 static HRESULT WINAPI IDirect3D2_CreateMaterial(LPDIRECT3D2 this,
1853 LPDIRECT3DMATERIAL2 *lpmaterial,
1856 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
1858 /* Call the creation function that is located in d3dviewport.c */
1859 *lpmaterial = d3dmaterial2_create(this);
1864 static HRESULT WINAPI IDirect3D2_CreateViewport(LPDIRECT3D2 this,
1865 LPDIRECT3DVIEWPORT2 *lpviewport,
1868 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
1870 /* Call the creation function that is located in d3dviewport.c */
1871 *lpviewport = d3dviewport2_create(this);
1876 static HRESULT WINAPI IDirect3D2_FindDevice(LPDIRECT3D2 this,
1877 LPD3DFINDDEVICESEARCH lpfinddevsrc,
1878 LPD3DFINDDEVICERESULT lpfinddevrst)
1880 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
1885 static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,
1887 LPDIRECTDRAWSURFACE surface,
1888 LPDIRECT3DDEVICE2 *device)
1892 WINE_StringFromCLSID(rguid,xbuf);
1893 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",this,xbuf,surface,device);
1895 if (is_OpenGL(rguid, surface, device, this)) {
1896 this->lpvtbl->fnAddRef(this);
1900 return DDERR_INVALIDPARAMS;
1903 static struct IDirect3D2_VTable d3d2vt = {
1904 IDirect3D2_QueryInterface,
1907 IDirect3D2_EnumDevices,
1908 IDirect3D2_CreateLight,
1909 IDirect3D2_CreateMaterial,
1910 IDirect3D2_CreateViewport,
1911 IDirect3D2_FindDevice,
1912 IDirect3D2_CreateDevice
1915 /*******************************************************************************
1919 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1920 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1922 static INT32 ddrawXlibThisOffset = 0;
1924 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
1925 LPDDSURFACEDESC lpddsd,
1926 LPDIRECTDRAWSURFACE lpdsf)
1930 /* The surface was already allocated when entering in this function */
1931 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
1933 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
1934 /* This is a Z Buffer */
1935 bpp = lpddsd->x.dwZBufferBitDepth;
1937 /* This is a standard image */
1938 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
1939 /* No pixel format => use DirectDraw's format */
1940 _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
1941 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
1943 /* To check what the program wants */
1944 if (TRACE_ON(ddraw)) {
1945 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
1950 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
1953 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
1956 /* Copy the surface description */
1957 lpdsf->s.surface_desc = *lpddsd;
1959 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1960 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
1961 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
1966 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1967 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1969 #ifdef HAVE_LIBXXF86DGA
1972 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1973 if (TRACE_ON(ddraw)) {
1974 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1975 _dump_DDSD(lpddsd->dwFlags);
1976 fprintf(stderr,"caps ");
1977 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1978 fprintf(stderr,"]\n");
1981 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1982 this->lpvtbl->fnAddRef(this);
1985 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1986 (*lpdsf)->s.ddraw = this;
1987 (*lpdsf)->s.palette = NULL;
1988 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
1990 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1991 lpddsd->dwWidth = this->d.width;
1992 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1993 lpddsd->dwHeight = this->d.height;
1995 /* Check if this a 'primary surface' or not */
1996 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1997 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1999 /* This is THE primary surface => there is DGA-specific code */
2000 /* First, store the surface description */
2001 (*lpdsf)->s.surface_desc = *lpddsd;
2003 /* Find a viewport */
2005 if (!(this->e.dga.vpmask & (1<<i)))
2007 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2008 /* if i == 32 or maximum ... return error */
2009 this->e.dga.vpmask|=(1<<i);
2010 (*lpdsf)->s.surface_desc.y.lpSurface =
2011 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
2012 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
2013 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
2014 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
2016 /* Add flags if there were not present */
2017 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2018 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2019 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2020 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
2021 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
2022 (*lpdsf)->s.backbuffer = NULL;
2024 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2025 LPDIRECTDRAWSURFACE3 back;
2027 if (lpddsd->dwBackBufferCount>1)
2028 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2030 (*lpdsf)->s.backbuffer = back =
2031 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
2032 this->lpvtbl->fnAddRef(this);
2034 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
2036 if (!(this->e.dga.vpmask & (1<<i)))
2038 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2039 /* if i == 32 or maximum ... return error */
2040 this->e.dga.vpmask|=(1<<i);
2041 back->t.dga.fb_height = i*this->e.dga.fb_height;
2043 /* Copy the surface description from the front buffer */
2044 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2045 /* Change the parameters that are not the same */
2046 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
2047 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
2048 back->s.ddraw = this;
2049 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2052 /* Add relevant info to front and back buffers */
2053 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2054 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2055 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2056 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2059 /* There is no DGA-specific code here...
2060 Go to the common surface creation function */
2061 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2065 #else /* defined(HAVE_LIBXXF86DGA) */
2066 return E_UNEXPECTED;
2067 #endif /* defined(HAVE_LIBXXF86DGA) */
2070 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
2073 #ifdef HAVE_LIBXXSHM
2074 if (this->e.xlib.xshm_active) {
2075 img = TSXShmCreateImage(display,
2076 DefaultVisualOfScreen(screen),
2080 &(lpdsf->t.xlib.shminfo),
2081 lpdsf->s.surface_desc.dwWidth,
2082 lpdsf->s.surface_desc.dwHeight);
2087 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2088 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2089 TSXDestroyImage(img);
2093 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2095 if (img->data == (char *) -1) {
2096 TSXDestroyImage(img);
2097 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2100 lpdsf->t.xlib.shminfo.readOnly = False;
2102 TSXShmAttach(display, &(lpdsf->t.xlib.shminfo));
2103 TSXSync(display, False);
2105 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2107 lpdsf->s.surface_desc.y.lpSurface = img->data;
2110 /* Allocate surface memory */
2111 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2112 lpdsf->s.surface_desc.dwWidth *
2113 lpdsf->s.surface_desc.dwHeight *
2114 (this->d.depth / 8));
2116 /* In this case, create an XImage */
2118 TSXCreateImage(display,
2119 DefaultVisualOfScreen(screen),
2123 lpdsf->s.surface_desc.y.lpSurface,
2124 lpdsf->s.surface_desc.dwWidth,
2125 lpdsf->s.surface_desc.dwHeight,
2127 lpdsf->s.surface_desc.dwWidth * (this->d.depth / 8)
2130 #ifdef HAVE_LIBXXSHM
2133 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2138 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
2139 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2141 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2142 this,lpddsd,lpdsf,lpunk);
2144 if (TRACE_ON(ddraw)) {
2145 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2146 _dump_DDSD(lpddsd->dwFlags);
2147 fprintf(stderr,"caps ");
2148 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2149 fprintf(stderr,"]\n");
2152 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2154 this->lpvtbl->fnAddRef(this);
2155 (*lpdsf)->s.ddraw = this;
2157 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
2158 (*lpdsf)->s.palette = NULL;
2159 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2161 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2162 lpddsd->dwWidth = this->d.width;
2163 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2164 lpddsd->dwHeight = this->d.height;
2166 /* Check if this a 'primary surface' or not */
2167 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2168 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2171 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
2173 /* First, store the surface description */
2174 (*lpdsf)->s.surface_desc = *lpddsd;
2176 /* Create the XImage */
2177 img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf);
2179 return DDERR_OUTOFMEMORY;
2180 (*lpdsf)->t.xlib.image = img;
2182 /* Add flags if there were not present */
2183 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2184 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2185 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2186 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
2187 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
2188 (*lpdsf)->s.backbuffer = NULL;
2190 /* Check for backbuffers */
2191 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2192 LPDIRECTDRAWSURFACE3 back;
2195 if (lpddsd->dwBackBufferCount>1)
2196 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2198 (*lpdsf)->s.backbuffer = back =
2199 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
2201 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2203 this->lpvtbl->fnAddRef(this);
2204 back->s.ddraw = this;
2207 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
2208 /* Copy the surface description from the front buffer */
2209 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2211 /* Create the XImage */
2212 img = create_ximage(this, back);
2214 return DDERR_OUTOFMEMORY;
2215 back->t.xlib.image = img;
2217 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2220 /* Add relevant info to front and back buffers */
2221 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2222 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2223 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2224 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2227 /* There is no Xlib-specific code here...
2228 Go to the common surface creation function */
2229 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2235 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
2236 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2238 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
2239 *dst = src; /* FIXME */
2244 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2245 * even when the approbiate bitmasks are not specified.
2247 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
2248 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
2255 FE(DDSCL_FULLSCREEN)
2256 FE(DDSCL_ALLOWREBOOT)
2257 FE(DDSCL_NOWINDOWCHANGES)
2259 FE(DDSCL_ALLOWMODEX)
2261 FE(DDSCL_SETFOCUSWINDOW)
2262 FE(DDSCL_SETDEVICEWINDOW)
2263 FE(DDSCL_CREATEDEVICEWINDOW)
2266 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
2267 if(TRACE_ON(ddraw)){
2268 dbg_decl_str(ddraw, 512);
2269 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2270 if (flagmap[i].mask & cooplevel)
2271 dsprintf(ddraw, "%s ", flagmap[i].name);
2272 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2274 this->d.mainWindow = hwnd;
2276 /* This will be overwritten in the case of Full Screen mode.
2277 Windowed games could work with that :-) */
2279 this->d.drawable = ((X11DRV_WND_DATA *) WIN_FindWndPtr(hwnd)->pDriverData)->window;
2284 /* Small helper to either use the cooperative window or create a new
2285 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2287 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
2290 /* Do not destroy the application supplied cooperative window */
2291 if (this->d.window && this->d.window != this->d.mainWindow) {
2292 DestroyWindow32(this->d.window);
2295 /* Sanity check cooperative window before assigning it to drawing. */
2296 if ( IsWindow32(this->d.mainWindow) &&
2297 IsWindowVisible32(this->d.mainWindow)
2299 GetWindowRect32(this->d.mainWindow,&rect);
2300 if (((rect.right-rect.left) >= this->d.width) &&
2301 ((rect.bottom-rect.top) >= this->d.height)
2303 this->d.window = this->d.mainWindow;
2305 /* ... failed, create new one. */
2306 if (!this->d.window) {
2307 this->d.window = CreateWindowEx32A(
2311 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2320 /*Store THIS with the window. We'll use it in the window procedure*/
2321 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
2322 ShowWindow32(this->d.window,TRUE);
2323 UpdateWindow32(this->d.window);
2325 SetFocus32(this->d.window);
2328 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
2329 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2331 #ifdef HAVE_LIBXXF86DGA
2332 int i,*depths,depcount,mode_count;
2334 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
2336 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2337 for (i=0;i<depcount;i++)
2338 if (depths[i]==depth)
2341 if (i==depcount) {/* not found */
2342 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
2343 return DDERR_UNSUPPORTEDMODE;
2345 if (this->d.width < width) {
2346 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
2347 return DDERR_UNSUPPORTEDMODE;
2349 this->d.width = width;
2350 this->d.height = height;
2351 this->d.depth = depth;
2353 /* adjust fb_height, so we don't overlap */
2354 if (this->e.dga.fb_height < height)
2355 this->e.dga.fb_height = height;
2356 _common_IDirectDraw_SetDisplayMode(this);
2358 #ifdef HAVE_LIBXXF86VM
2360 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
2361 XF86VidModeModeLine mod_tmp;
2364 /* save original video mode and set fullscreen if available*/
2365 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
2366 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
2367 orig_mode->hdisplay = mod_tmp.hdisplay;
2368 orig_mode->hsyncstart = mod_tmp.hsyncstart;
2369 orig_mode->hsyncend = mod_tmp.hsyncend;
2370 orig_mode->htotal = mod_tmp.htotal;
2371 orig_mode->vdisplay = mod_tmp.vdisplay;
2372 orig_mode->vsyncstart = mod_tmp.vsyncstart;
2373 orig_mode->vsyncend = mod_tmp.vsyncend;
2374 orig_mode->vtotal = mod_tmp.vtotal;
2375 orig_mode->flags = mod_tmp.flags;
2376 orig_mode->private = mod_tmp.private;
2378 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2379 for (i=0;i<mode_count;i++)
2381 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2383 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2384 *vidmode = *(all_modes[i]);
2387 TSXFree(all_modes[i]->private);
2392 WARN(ddraw, "Fullscreen mode not available!\n");
2396 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2397 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
2402 /* FIXME: this function OVERWRITES several signal handlers.
2403 * can we save them? and restore them later? In a way that
2404 * it works for the library too?
2406 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2408 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2411 #ifdef RESTORE_SIGNALS
2412 SIGNAL_InitEmulator();
2415 #else /* defined(HAVE_LIBXXF86DGA) */
2416 return E_UNEXPECTED;
2417 #endif /* defined(HAVE_LIBXXF86DGA) */
2420 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2421 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2423 int i,*depths,depcount;
2426 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2427 this, width, height, depth);
2429 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2430 for (i=0;i<depcount;i++)
2431 if (depths[i]==depth)
2434 if (i==depcount) {/* not found */
2435 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2436 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2437 return DDERR_UNSUPPORTEDMODE;
2439 this->d.width = width;
2440 this->d.height = height;
2441 this->d.depth = depth;
2443 _common_IDirectDraw_SetDisplayMode(this);
2445 this->d.paintable = 1;
2446 this->d.drawable = ((X11DRV_WND_DATA *) WIN_FindWndPtr(this->d.window)->pDriverData)->window;
2447 /* We don't have a context for this window. Host off the desktop */
2448 if( !this->d.drawable )
2449 this->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
2453 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
2454 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2456 #ifdef HAVE_LIBXXF86DGA
2457 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2458 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
2459 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2460 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2462 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
2463 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2464 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2467 #else /* defined(HAVE_LIBXXF86DGA) */
2468 return E_UNEXPECTED;
2469 #endif /* defined(HAVE_LIBXXF86DGA) */
2472 static void fill_caps(LPDDCAPS caps) {
2473 /* This function tries to fill the capabilities of Wine's DDraw implementation.
2474 Need to be fixed, though.. */
2478 caps->dwSize = sizeof(*caps);
2479 caps->dwCaps = DDCAPS_3D | DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
2480 DDCAPS_CANBLTSYSMEM | DDCAPS_PALETTE | DDCAPS_ZBLTS;
2481 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NO2DDURING3DSCENE | DDCAPS2_NOPAGELOCKREQUIRED |
2482 DDCAPS2_WIDESURFACES;
2483 caps->dwCKeyCaps = 0;
2485 caps->dwFXAlphaCaps = 0;
2486 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
2488 caps->dwZBufferBitDepths = DDBD_16;
2489 /* I put here 8 Mo so that D3D applications will believe they have enough memory
2490 to put textures in video memory.
2491 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
2493 caps->dwVidMemTotal = 8192 * 1024;
2494 caps->dwVidMemFree = 8192 * 1024;
2495 /* These are all the supported capabilities of the surfaces */
2496 caps->ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
2497 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
2498 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE |
2499 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE | DDSCAPS_ZBUFFER;
2502 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
2503 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2505 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2507 /* Put the same caps for the two capabilities */
2514 static HRESULT WINAPI IDirectDraw2_CreateClipper(
2515 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
2517 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
2518 this,x,lpddclip,lpunk
2520 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
2521 (*lpddclip)->ref = 1;
2522 (*lpddclip)->lpvtbl = &ddclipvt;
2526 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
2527 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2529 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2530 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2531 (*lpddpal)->ref = 1;
2532 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2533 (*lpddpal)->installed = 0;
2534 if (this->d.depth<=8) {
2535 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
2537 /* we don't want palettes in hicolor or truecolor */
2545 if (dwFlags & DDPCAPS_1BIT)
2547 else if (dwFlags & DDPCAPS_2BIT)
2549 else if (dwFlags & DDPCAPS_4BIT)
2551 else if (dwFlags & DDPCAPS_8BIT)
2554 ERR(ddraw, "unhandled palette format\n");
2556 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
2561 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
2562 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2565 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2566 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
2567 if (res != 0) return res;
2568 (*lpddpal)->lpvtbl = &dga_ddpalvt;
2572 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
2573 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2575 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
2576 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2578 TRACE(ddraw, "Palette created : %p\n", *lpddpal);
2580 if (*lpddpal == NULL)
2581 return E_OUTOFMEMORY;
2583 (*lpddpal)->ref = 1;
2584 (*lpddpal)->installed = 0;
2585 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
2587 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2588 this->lpvtbl->fnAddRef(this);
2593 if (dwFlags & DDPCAPS_1BIT)
2595 else if (dwFlags & DDPCAPS_2BIT)
2597 else if (dwFlags & DDPCAPS_4BIT)
2599 else if (dwFlags & DDPCAPS_8BIT)
2602 ERR(ddraw, "unhandled palette format\n");
2604 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
2610 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2611 #ifdef HAVE_LIBXXF86DGA
2612 TRACE(ddraw, "(%p)->()\n",this);
2614 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2615 #ifdef RESTORE_SIGNALS
2616 SIGNAL_InitEmulator();
2619 #else /* defined(HAVE_LIBXXF86DGA) */
2620 return E_UNEXPECTED;
2624 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2625 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
2630 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
2631 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
2633 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
2637 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
2638 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2640 return ++(this->ref);
2643 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2644 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2646 #ifdef HAVE_LIBXXF86DGA
2647 if (!--(this->ref)) {
2648 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2650 #ifdef HAVE_LIBXXF86VM
2652 TSXF86VidModeSwitchToMode(
2654 DefaultScreen(display),
2656 if (orig_mode->privsize)
2657 TSXFree(orig_mode->private);
2663 #ifdef RESTORE_SIGNALS
2664 SIGNAL_InitEmulator();
2666 HeapFree(GetProcessHeap(),0,this);
2669 #endif /* defined(HAVE_LIBXXF86DGA) */
2673 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2674 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2676 if (!--(this->ref)) {
2677 HeapFree(GetProcessHeap(),0,this);
2680 /* FIXME: destroy window ... */
2684 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
2685 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2689 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2690 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2691 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2693 this->lpvtbl->fnAddRef(this);
2695 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
2699 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2700 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
2701 this->lpvtbl->fnAddRef(this);
2704 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
2708 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2709 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
2710 this->lpvtbl->fnAddRef(this);
2713 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
2717 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2720 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2722 d3d->ddraw = (LPDIRECTDRAW)this;
2723 this->lpvtbl->fnAddRef(this);
2724 d3d->lpvtbl = &d3dvt;
2727 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2731 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2734 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2736 d3d->ddraw = (LPDIRECTDRAW)this;
2737 this->lpvtbl->fnAddRef(this);
2738 d3d->lpvtbl = &d3d2vt;
2741 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2745 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2746 return OLE_E_ENUM_NOMORE;
2749 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
2750 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2754 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2755 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2756 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2758 this->lpvtbl->fnAddRef(this);
2760 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
2764 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2765 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
2766 this->lpvtbl->fnAddRef(this);
2769 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
2773 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2774 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
2775 this->lpvtbl->fnAddRef(this);
2778 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
2782 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2785 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2787 d3d->ddraw = (LPDIRECTDRAW)this;
2788 this->lpvtbl->fnAddRef(this);
2789 d3d->lpvtbl = &d3dvt;
2792 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2796 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2799 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2801 d3d->ddraw = (LPDIRECTDRAW)this;
2802 this->lpvtbl->fnAddRef(this);
2803 d3d->lpvtbl = &d3d2vt;
2806 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2810 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2811 return OLE_E_ENUM_NOMORE;
2814 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
2815 LPDIRECTDRAW2 this,BOOL32 *status
2817 TRACE(ddraw,"(%p)->(%p)\n",this,status);
2822 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
2823 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
2825 DDSURFACEDESC ddsfd;
2828 } modes[5] = { /* some of the usual modes */
2835 static int depths[4] = {8,16,24,32};
2838 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
2839 ddsfd.dwSize = sizeof(ddsfd);
2840 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2841 if (dwFlags & DDEDM_REFRESHRATES) {
2842 ddsfd.dwFlags |= DDSD_REFRESHRATE;
2843 ddsfd.x.dwRefreshRate = 60;
2846 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
2847 ddsfd.dwBackBufferCount = 1;
2848 ddsfd.ddpfPixelFormat.dwFourCC = 0;
2849 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2850 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
2851 /* FIXME: those masks would have to be set in depth > 8 */
2853 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
2854 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
2855 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
2856 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2857 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
2858 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
2860 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2862 /* FIXME: We should query those from X itself */
2863 switch (depths[i]) {
2865 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f;
2866 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0;
2867 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00;
2870 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2871 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2872 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2875 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2876 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2877 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2882 ddsfd.dwWidth = screenWidth;
2883 ddsfd.dwHeight = screenHeight;
2884 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2885 if (!modescb(&ddsfd,context)) return DD_OK;
2887 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
2888 ddsfd.dwWidth = modes[j].w;
2889 ddsfd.dwHeight = modes[j].h;
2890 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2891 if (!modescb(&ddsfd,context)) return DD_OK;
2894 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
2895 /* modeX is not standard VGA */
2897 ddsfd.dwHeight = 200;
2898 ddsfd.dwWidth = 320;
2899 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
2900 if (!modescb(&ddsfd,context)) return DD_OK;
2906 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
2907 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2909 #ifdef HAVE_LIBXXF86DGA
2910 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
2911 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2912 lpddsfd->dwHeight = screenHeight;
2913 lpddsfd->dwWidth = screenWidth;
2914 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2915 lpddsfd->dwBackBufferCount = 1;
2916 lpddsfd->x.dwRefreshRate = 60;
2917 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2918 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2920 #else /* defined(HAVE_LIBXXF86DGA) */
2921 return E_UNEXPECTED;
2922 #endif /* defined(HAVE_LIBXXF86DGA) */
2925 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
2926 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2928 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
2929 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2930 lpddsfd->dwHeight = screenHeight;
2931 lpddsfd->dwWidth = screenWidth;
2932 /* POOLE FIXME: Xlib */
2933 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2934 /* END FIXME: Xlib */
2935 lpddsfd->dwBackBufferCount = 1;
2936 lpddsfd->x.dwRefreshRate = 60;
2937 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2938 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2942 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
2943 TRACE(ddraw,"(%p)->()\n",this);
2947 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
2948 LPDIRECTDRAW2 this,LPDWORD freq
2950 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
2951 *freq = 60*100; /* 60 Hz */
2955 /* what can we directly decompress? */
2956 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
2957 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
2959 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
2963 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
2964 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
2966 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
2970 static HRESULT WINAPI IDirectDraw2_Compact(
2971 LPDIRECTDRAW2 this )
2973 FIXME(ddraw,"(%p)->()\n", this );
2979 /* Note: Hack so we can reuse the old functions without compiler warnings */
2981 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
2983 # define XCAST(fun) (void*)
2986 static struct IDirectDraw_VTable dga_ddvt = {
2987 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
2988 XCAST(AddRef)IDirectDraw2_AddRef,
2989 XCAST(Release)DGA_IDirectDraw2_Release,
2990 XCAST(Compact)IDirectDraw2_Compact,
2991 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2992 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
2993 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
2994 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2995 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2996 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2997 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2998 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2999 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3000 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3001 XCAST(GetGDISurface)15,
3002 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3003 XCAST(GetScanLine)17,
3004 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3005 XCAST(Initialize)19,
3006 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3007 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3008 DGA_IDirectDraw_SetDisplayMode,
3009 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3012 static struct IDirectDraw_VTable xlib_ddvt = {
3013 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
3014 XCAST(AddRef)IDirectDraw2_AddRef,
3015 XCAST(Release)Xlib_IDirectDraw2_Release,
3016 XCAST(Compact)IDirectDraw2_Compact,
3017 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3018 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
3019 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
3020 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3021 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3022 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3023 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3024 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
3025 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
3026 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3027 XCAST(GetGDISurface)15,
3028 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3029 XCAST(GetScanLine)17,
3030 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3031 XCAST(Initialize)19,
3032 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
3033 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3034 Xlib_IDirectDraw_SetDisplayMode,
3035 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3038 /*****************************************************************************
3044 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
3045 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3047 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3050 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
3051 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3053 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3056 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
3057 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3059 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3060 this,ddscaps,total,free
3062 if (total) *total = this->e.dga.fb_memsize * 1024;
3063 if (free) *free = this->e.dga.fb_memsize * 1024;
3067 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
3068 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3070 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3071 this,ddscaps,total,free
3073 if (total) *total = 2048 * 1024;
3074 if (free) *free = 2048 * 1024;
3078 static IDirectDraw2_VTable dga_dd2vt = {
3079 DGA_IDirectDraw2_QueryInterface,
3080 IDirectDraw2_AddRef,
3081 DGA_IDirectDraw2_Release,
3082 IDirectDraw2_Compact,
3083 IDirectDraw2_CreateClipper,
3084 DGA_IDirectDraw2_CreatePalette,
3085 DGA_IDirectDraw2_CreateSurface,
3087 IDirectDraw2_EnumDisplayModes,
3088 IDirectDraw2_EnumSurfaces,
3089 IDirectDraw2_FlipToGDISurface,
3090 DGA_IDirectDraw2_GetCaps,
3091 DGA_IDirectDraw2_GetDisplayMode,
3092 IDirectDraw2_GetFourCCCodes,
3094 IDirectDraw2_GetMonitorFrequency,
3096 IDirectDraw2_GetVerticalBlankStatus,
3098 DGA_IDirectDraw2_RestoreDisplayMode,
3099 IDirectDraw2_SetCooperativeLevel,
3100 DGA_IDirectDraw2_SetDisplayMode,
3101 IDirectDraw2_WaitForVerticalBlank,
3102 DGA_IDirectDraw2_GetAvailableVidMem
3105 static struct IDirectDraw2_VTable xlib_dd2vt = {
3106 Xlib_IDirectDraw2_QueryInterface,
3107 IDirectDraw2_AddRef,
3108 Xlib_IDirectDraw2_Release,
3109 IDirectDraw2_Compact,
3110 IDirectDraw2_CreateClipper,
3111 Xlib_IDirectDraw2_CreatePalette,
3112 Xlib_IDirectDraw2_CreateSurface,
3114 IDirectDraw2_EnumDisplayModes,
3115 IDirectDraw2_EnumSurfaces,
3116 IDirectDraw2_FlipToGDISurface,
3117 Xlib_IDirectDraw2_GetCaps,
3118 Xlib_IDirectDraw2_GetDisplayMode,
3119 IDirectDraw2_GetFourCCCodes,
3121 IDirectDraw2_GetMonitorFrequency,
3123 IDirectDraw2_GetVerticalBlankStatus,
3125 Xlib_IDirectDraw2_RestoreDisplayMode,
3126 IDirectDraw2_SetCooperativeLevel,
3127 Xlib_IDirectDraw2_SetDisplayMode,
3128 IDirectDraw2_WaitForVerticalBlank,
3129 Xlib_IDirectDraw2_GetAvailableVidMem
3132 /******************************************************************************
3136 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
3139 LPDIRECTDRAW ddraw = NULL;
3142 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
3144 SetLastError( ERROR_SUCCESS );
3145 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
3147 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
3150 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
3155 /* Perform any special direct draw functions */
3157 ddraw->d.paintable = 1;
3159 /* Now let the application deal with the rest of this */
3160 if( ddraw->d.mainWindow )
3163 /* Don't think that we actually need to call this but...
3164 might as well be on the safe side of things... */
3166 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
3167 it should be the procedures of our fake window that gets called
3168 instead of those of the window provided by the application.
3169 And with this patch, mouse clicks work with Monkey Island III
3171 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
3175 /* We didn't handle the message - give it to the application */
3176 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
3177 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
3178 ddraw->d.mainWindow, msg, wParam, lParam );
3183 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
3189 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
3195 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
3196 #ifdef HAVE_LIBXXF86DGA
3197 int memsize,banksize,width,major,minor,flags,height;
3201 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
3202 if ((fd = open("/dev/mem", O_RDWR)) != -1)
3206 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
3207 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
3208 return E_UNEXPECTED;
3210 if (!DDRAW_DGA_Available()) {
3211 TRACE(ddraw,"No XF86DGA detected.\n");
3212 return DDERR_GENERIC;
3214 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
3215 (*lplpDD)->lpvtbl = &dga_ddvt;
3217 TSXF86DGAQueryVersion(display,&major,&minor);
3218 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
3219 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
3220 if (!(flags & XF86DGADirectPresent))
3221 MSG("direct video is NOT PRESENT.\n");
3222 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
3223 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
3224 addr,width,banksize,memsize
3226 (*lplpDD)->e.dga.fb_width = width;
3227 (*lplpDD)->d.width = width;
3228 (*lplpDD)->e.dga.fb_addr = addr;
3229 (*lplpDD)->e.dga.fb_memsize = memsize;
3230 (*lplpDD)->e.dga.fb_banksize = banksize;
3232 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
3233 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3234 (*lplpDD)->e.dga.fb_height = screenHeight;
3236 (*lplpDD)->e.dga.vpmask = 1;
3238 (*lplpDD)->e.dga.vpmask = 0;
3241 /* just assume the default depth is the DGA depth too */
3242 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
3243 #ifdef RESTORE_SIGNALS
3244 SIGNAL_InitEmulator();
3248 #else /* defined(HAVE_LIBXXF86DGA) */
3249 return DDERR_INVALIDDIRECTDRAWGUID;
3250 #endif /* defined(HAVE_LIBXXF86DGA) */
3254 DDRAW_XSHM_Available(void)
3256 #ifdef HAVE_LIBXXSHM
3257 if (TSXShmQueryExtension(display))
3262 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
3274 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
3276 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
3277 (*lplpDD)->lpvtbl = &xlib_ddvt;
3279 (*lplpDD)->d.drawable = 0; /* in SetDisplayMode */
3281 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
3282 (*lplpDD)->d.height = screenHeight;
3283 (*lplpDD)->d.width = screenWidth;
3285 #ifdef HAVE_LIBXXSHM
3286 /* Test if XShm is available.
3287 As XShm is not ready yet for 'prime-time', it is disabled for now */
3288 if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */))
3289 TRACE(ddraw, "Using XShm extesion.\n");
3295 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
3302 WINE_StringFromCLSID(lpGUID,xclsid);
3304 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
3308 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
3311 /* if they didn't request a particular interface, use the best
3313 if (DDRAW_DGA_Available())
3314 lpGUID = &DGA_DirectDraw_GUID;
3316 lpGUID = &XLIB_DirectDraw_GUID;
3319 wc.style = CS_GLOBALCLASS;
3320 wc.lpfnWndProc = Xlib_DDWndProc;
3322 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
3323 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
3325 /* We can be a child of the desktop since we're really important */
3326 pParentWindow = WIN_GetDesktop();
3327 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
3331 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
3332 wc.hbrBackground= NULL_BRUSH;
3333 wc.lpszMenuName = 0;
3334 wc.lpszClassName= "WINE_DirectDraw";
3335 RegisterClass32A(&wc);
3337 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
3338 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
3339 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
3340 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
3344 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
3348 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
3349 return DDERR_INVALIDDIRECTDRAWGUID;