/*		DirectDraw using DGA or Xlib(XSHM)
 *
 * Copyright 1997,1998 Marcus Meissner
 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
 */
/* XF86DGA:
 * When DirectVideo mode is enabled you can no longer use 'normal' X 
 * applications nor can you switch to a virtual console. Also, enabling
 * only works, if you have switched to the screen where the application
 * is running.
 * Some ways to debug this stuff are:
 * - A terminal connected to the serial port. Can be bought used for cheap.
 *   (This is the method I am using.)
 * - Another machine connected over some kind of network.
 */

#include "config.h"
#include <unistd.h>
#include <assert.h>
#include "ts_xlib.h"
#include "ts_xutil.h"
#include <sys/signal.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "windows.h"

#ifdef HAVE_LIBXXF86VM
/* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
   this is a crude hack to get around it */
#define XMD_H
#include "ts_xf86vmode.h"
#endif

#include "winerror.h"
#include "gdi.h"
#include "heap.h"
#include "ldt.h"
#include "dc.h"
#include "win.h"
#include "miscemu.h"
#include "ddraw.h"
#include "d3d.h"
#include "debug.h"
#include "spy.h"
#include "message.h"
#include "x11drv.h"
#include "options.h"

#ifdef HAVE_LIBXXF86DGA
#include "ts_xf86dga.h"
#endif

#ifdef HAVE_LIBXXSHM
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "ts_xshm.h"
#endif

/* This for all the enumeration and creation of D3D-related objects */
#include "d3d_private.h"

/* define this if you want to play Diablo using XF86DGA. (bug workaround) */
#undef DIABLO_HACK

/* Restore signal handlers overwritten by XF86DGA 
 * this is a define, for it will only work in emulator mode
 */
#undef RESTORE_SIGNALS

/* Where do these GUIDs come from?  mkuuid.
 * They exist solely to distinguish between the targets Wine support,
 * and should be different than any other GUIDs in existence.
 */
static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
	0xe2dcb020,
	0xdc60,
	0x11d1,
	{0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
};

static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
    0x1574a740,
    0xdc61,
    0x11d1,
    {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
};

static struct IDirectDrawSurface3_VTable	dga_dds3vt, xlib_dds3vt;
static struct IDirectDraw_VTable		dga_ddvt, xlib_ddvt;
static struct IDirectDraw2_VTable		dga_dd2vt, xlib_dd2vt;
static struct IDirectDrawClipper_VTable	ddclipvt;
static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
static struct IDirect3D_VTable			d3dvt;
static struct IDirect3D2_VTable			d3d2vt;

#ifdef HAVE_LIBXXF86VM
static XF86VidModeModeInfo *orig_mode = NULL;
#endif

BOOL32
DDRAW_DGA_Available()
{
#ifdef HAVE_LIBXXF86DGA
	int evbase, evret, fd;
	
   	if (Options.noDGA)
     	  return 0;
   
	/* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
        /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
        /* others. --stephenc */
        if ((fd = open("/dev/mem", O_RDWR)) != -1)
          close(fd);

	return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
#else /* defined(HAVE_LIBXXF86DGA) */
	return 0;
#endif /* defined(HAVE_LIBXXF86DGA) */
}

HRESULT WINAPI
DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
	if (DDRAW_DGA_Available()) {
	  TRACE(ddraw, "Enumerating DGA interface\n");
		ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
	}
	TRACE(ddraw, "Enumerating Xlib interface\n");
	ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
	TRACE(ddraw, "Enumerating Default interface\n");
	ddenumproc(NULL,"WINE (default)","display",data);
	return DD_OK;
}

/* What is this doing here? */
HRESULT WINAPI 
DSoundHelp(DWORD x,DWORD y,DWORD z) {
	FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
	return 0;
}


/******************************************************************************
 *		internal helper functions
 */
static void _dump_DDBLTFX(DWORD flagmask) {
	int	i;
	const struct {
		DWORD	mask;
		char	*name;
	} flags[] = {
#define FE(x) { x, #x},
		FE(DDBLTFX_ARITHSTRETCHY)
		FE(DDBLTFX_MIRRORLEFTRIGHT)
		FE(DDBLTFX_MIRRORUPDOWN)
		FE(DDBLTFX_NOTEARING)
		FE(DDBLTFX_ROTATE180)
		FE(DDBLTFX_ROTATE270)
		FE(DDBLTFX_ROTATE90)
		FE(DDBLTFX_ZBUFFERRANGE)
		FE(DDBLTFX_ZBUFFERBASEDEST)
	};
	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
	   if (flags[i].mask & flagmask) {
	      DUMP("%s ",flags[i].name);
	      
	   };
	DUMP("\n");
	
}

static void _dump_DDBLTFAST(DWORD flagmask) {
	int	i;
	const struct {
		DWORD	mask;
		char	*name;
	} flags[] = {
#define FE(x) { x, #x},
		FE(DDBLTFAST_NOCOLORKEY)
		FE(DDBLTFAST_SRCCOLORKEY)
		FE(DDBLTFAST_DESTCOLORKEY)
		FE(DDBLTFAST_WAIT)
	};
	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
		if (flags[i].mask & flagmask)
			DUMP("%s ",flags[i].name);
	DUMP("\n");
}

static void _dump_DDBLT(DWORD flagmask) {
	int	i;
	const struct {
		DWORD	mask;
		char	*name;
	} flags[] = {
#define FE(x) { x, #x},
		FE(DDBLT_ALPHADEST)
		FE(DDBLT_ALPHADESTCONSTOVERRIDE)
		FE(DDBLT_ALPHADESTNEG)
		FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
		FE(DDBLT_ALPHAEDGEBLEND)
		FE(DDBLT_ALPHASRC)
		FE(DDBLT_ALPHASRCCONSTOVERRIDE)
		FE(DDBLT_ALPHASRCNEG)
		FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
		FE(DDBLT_ASYNC)
		FE(DDBLT_COLORFILL)
		FE(DDBLT_DDFX)
		FE(DDBLT_DDROPS)
		FE(DDBLT_KEYDEST)
		FE(DDBLT_KEYDESTOVERRIDE)
		FE(DDBLT_KEYSRC)
		FE(DDBLT_KEYSRCOVERRIDE)
		FE(DDBLT_ROP)
		FE(DDBLT_ROTATIONANGLE)
		FE(DDBLT_ZBUFFER)
		FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
		FE(DDBLT_ZBUFFERDESTOVERRIDE)
		FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
		FE(DDBLT_ZBUFFERSRCOVERRIDE)
		FE(DDBLT_WAIT)
		FE(DDBLT_DEPTHFILL)
	};
	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
		if (flags[i].mask & flagmask)
			DUMP("%s ",flags[i].name);
}

static void _dump_DDSCAPS(DWORD flagmask) {
	int	i;
	const struct {
		DWORD	mask;
		char	*name;
	} flags[] = {
#define FE(x) { x, #x},
		FE(DDSCAPS_RESERVED1)
		FE(DDSCAPS_ALPHA)
		FE(DDSCAPS_BACKBUFFER)
		FE(DDSCAPS_COMPLEX)
		FE(DDSCAPS_FLIP)
		FE(DDSCAPS_FRONTBUFFER)
		FE(DDSCAPS_OFFSCREENPLAIN)
		FE(DDSCAPS_OVERLAY)
		FE(DDSCAPS_PALETTE)
		FE(DDSCAPS_PRIMARYSURFACE)
		FE(DDSCAPS_PRIMARYSURFACELEFT)
		FE(DDSCAPS_SYSTEMMEMORY)
		FE(DDSCAPS_TEXTURE)
		FE(DDSCAPS_3DDEVICE)
		FE(DDSCAPS_VIDEOMEMORY)
		FE(DDSCAPS_VISIBLE)
		FE(DDSCAPS_WRITEONLY)
		FE(DDSCAPS_ZBUFFER)
		FE(DDSCAPS_OWNDC)
		FE(DDSCAPS_LIVEVIDEO)
		FE(DDSCAPS_HWCODEC)
		FE(DDSCAPS_MODEX)
		FE(DDSCAPS_MIPMAP)
		FE(DDSCAPS_RESERVED2)
		FE(DDSCAPS_ALLOCONLOAD)
		FE(DDSCAPS_VIDEOPORT)
		FE(DDSCAPS_LOCALVIDMEM)
		FE(DDSCAPS_NONLOCALVIDMEM)
		FE(DDSCAPS_STANDARDVGAMODE)
		FE(DDSCAPS_OPTIMIZED)
	};
	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
		if (flags[i].mask & flagmask)
			DUMP("%s ",flags[i].name);
	DUMP("\n");
}

static void _dump_DDSD(DWORD flagmask) {
	int	i;
	const struct {
		DWORD	mask;
		char	*name;
	} flags[] = {
		FE(DDSD_CAPS)
		FE(DDSD_HEIGHT)
		FE(DDSD_WIDTH)
		FE(DDSD_PITCH)
		FE(DDSD_BACKBUFFERCOUNT)
		FE(DDSD_ZBUFFERBITDEPTH)
		FE(DDSD_ALPHABITDEPTH)
		FE(DDSD_PIXELFORMAT)
		FE(DDSD_CKDESTOVERLAY)
		FE(DDSD_CKDESTBLT)
		FE(DDSD_CKSRCOVERLAY)
		FE(DDSD_CKSRCBLT)
		FE(DDSD_MIPMAPCOUNT)
		FE(DDSD_REFRESHRATE)
		FE(DDSD_LINEARSIZE)
		FE(DDSD_LPSURFACE)
	};
	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
		if (flags[i].mask & flagmask)
			DUMP("%s ",flags[i].name);
	DUMP("\n");
}

static void _dump_DDCOLORKEY(DWORD flagmask) {
	int	i;
	const struct {
		DWORD	mask;
		char	*name;
	} flags[] = {
#define FE(x) { x, #x},
	        FE(DDPF_ALPHAPIXELS)
		FE(DDPF_ALPHA)
		FE(DDPF_FOURCC)
		FE(DDPF_PALETTEINDEXED4)
		FE(DDPF_PALETTEINDEXEDTO8)
		FE(DDPF_PALETTEINDEXED8)
		FE(DDPF_RGB)
		FE(DDPF_COMPRESSED)
		FE(DDPF_RGBTOYUV)
		FE(DDPF_YUV)
		FE(DDPF_ZBUFFER)
		FE(DDPF_PALETTEINDEXED1)
		FE(DDPF_PALETTEINDEXED2)
		FE(DDPF_ZPIXELS)
	};
	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
		if (flags[i].mask & flagmask)
			DUMP("%s ",flags[i].name);
	DUMP("\n");
}

static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
  DUMP("Size : %ld\n", pf->dwSize);
  if (pf->dwFlags)
  _dump_DDCOLORKEY(pf->dwFlags);
  DUMP("dwFourCC : %ld\n", pf->dwFourCC);
  DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
  DUMP("Masks : R %08lx  G %08lx  B %08lx  A %08lx\n",
       pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
}

static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
	static XVisualInfo	*vi;
	XVisualInfo		vt;
	int			nitems;

	if (!vi)
		vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);

	pf->dwFourCC = 0;
	pf->dwSize = sizeof(DDPIXELFORMAT);
	if (ddraw->d.depth==8) {
		pf->dwFlags 		= DDPF_RGB|DDPF_PALETTEINDEXED8;
		pf->x.dwRGBBitCount	= 8;
		pf->y.dwRBitMask  	= 0;
		pf->z.dwGBitMask  	= 0;
		pf->xx.dwBBitMask 	= 0;
		pf->xy.dwRGBAlphaBitMask= 0;
		return 0;
	}
	if (ddraw->d.depth==16) {
		pf->dwFlags       	= DDPF_RGB;
		pf->x.dwRGBBitCount	= 16;
		pf->y.dwRBitMask	= vi[0].red_mask;
		pf->z.dwGBitMask	= vi[0].green_mask;
		pf->xx.dwBBitMask	= vi[0].blue_mask;
		pf->xy.dwRGBAlphaBitMask= 0;
		return 0;
	}
	FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
	return DDERR_GENERIC;
}

/******************************************************************************
 *		IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
 *
 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
 * DDS and DDS2 use those functions. (Function calls did not change (except
 * using different DirectDrawSurfaceX version), just added flags and functions)
 */
static HRESULT WINAPI IDirectDrawSurface3_Lock(
    LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
) {
        TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
		this,lprect,lpddsd,flags,(DWORD)hnd);
	if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
	    WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
			 this,lprect,lpddsd,flags,(DWORD)hnd);

	/* First, copy the Surface description */
	*lpddsd = this->s.surface_desc;

	/* If asked only for a part, change the surface pointer */
	if (lprect) {
		FIXME(ddraw,"	lprect: %dx%d-%dx%d\n",
			lprect->top,lprect->left,lprect->bottom,lprect->right
		);
		lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
			(lprect->top*this->s.surface_desc.lPitch) +
			(lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
	} else {
		assert(this->s.surface_desc.y.lpSurface);
	}
	return DD_OK;
}

static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
	LPDIRECTDRAWSURFACE3 this,LPVOID surface
) {
	TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
	return DD_OK;
}

static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
	LPDIRECTDRAWSURFACE3 this,LPVOID surface)
{
	TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);

	if (!this->s.ddraw->e.xlib.paintable)
		return DD_OK;

  /* Only redraw the screen when unlocking the buffer that is on screen */
	if ((this->t.xlib.image != NULL) &&
	    (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
#ifdef HAVE_LIBXXSHM
    if (this->s.ddraw->e.xlib.xshm_active)
      TSXShmPutImage(display,
		     this->s.ddraw->d.drawable,
		     DefaultGCOfScreen(screen),
		     this->t.xlib.image,
		     0, 0, 0, 0,
		     this->t.xlib.image->width,
		     this->t.xlib.image->height,
		     False);
    else
#endif
	TSXPutImage(		display,
				this->s.ddraw->d.drawable,
				DefaultGCOfScreen(screen),
				this->t.xlib.image,
				0, 0, 0, 0,
				this->t.xlib.image->width,
		  this->t.xlib.image->height);
  
	if (this->s.palette && this->s.palette->cm)
		TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
	}

	return DD_OK;
}

static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
) {
#ifdef HAVE_LIBXXF86DGA
	TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
	if (!flipto) {
		if (this->s.backbuffer)
			flipto = this->s.backbuffer;
		else
			flipto = this;
	}
	TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);

	if (flipto->s.palette && flipto->s.palette->cm) {
		TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
	}
	while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
	}
	if (flipto!=this) {
		int	tmp;
		LPVOID	ptmp;

		tmp = this->t.dga.fb_height;
		this->t.dga.fb_height = flipto->t.dga.fb_height;
		flipto->t.dga.fb_height = tmp;

		ptmp = this->s.surface_desc.y.lpSurface;
		this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
		flipto->s.surface_desc.y.lpSurface = ptmp;
	}
	return DD_OK;
#else /* defined(HAVE_LIBXXF86DGA) */
	return E_UNEXPECTED;
#endif /* defined(HAVE_LIBXXF86DGA) */
}

static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
) {
	TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
	if (!this->s.ddraw->e.xlib.paintable)
		return DD_OK;

	if (!flipto) {
		if (this->s.backbuffer)
			flipto = this->s.backbuffer;
		else
			flipto = this;
	}
  
#ifdef HAVE_LIBXXSHM
	if (this->s.ddraw->e.xlib.xshm_active) {
	  TSXShmPutImage(display,
			 this->s.ddraw->d.drawable,
			 DefaultGCOfScreen(screen),
			 flipto->t.xlib.image,
			 0, 0, 0, 0,
			 flipto->t.xlib.image->width,
			 flipto->t.xlib.image->height,
			 False);
	} else
#endif
	TSXPutImage(display,
				this->s.ddraw->d.drawable,
				DefaultGCOfScreen(screen),
				flipto->t.xlib.image,
				0, 0, 0, 0,
				flipto->t.xlib.image->width,
				flipto->t.xlib.image->height);
	
	if (flipto->s.palette && flipto->s.palette->cm) {
	  TSXSetWindowColormap(display,this->s.ddraw->d.drawable,flipto->s.palette->cm);
	}
	if (flipto!=this) {
		XImage *tmp;
		LPVOID	*surf;
		tmp = this->t.xlib.image;
		this->t.xlib.image = flipto->t.xlib.image;
		flipto->t.xlib.image = tmp;
		surf = this->s.surface_desc.y.lpSurface;
		this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
		flipto->s.surface_desc.y.lpSurface = surf;
	}
	return DD_OK;
}


/* The IDirectDrawSurface3::SetPalette method attaches the specified
 * DirectDrawPalette object to a surface. The surface uses this palette for all
 * subsequent operations. The palette change takes place immediately.
 */
static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
) {
	int i;
	TRACE(ddraw,"(%p)->(%p)\n",this,pal);

	if (pal == NULL) {
          if( this->s.palette != NULL )
            this->s.palette->lpvtbl->fnRelease( this->s.palette );
	  this->s.palette = pal;

	  return DD_OK;
	}
	
	if( !(pal->cm) && (this->s.ddraw->d.depth<=8)) 
	{
		pal->cm = TSXCreateColormap(display,this->s.ddraw->d.drawable,DefaultVisualOfScreen(screen),AllocAll);

		for (i=0;i<256;i++) {
			XColor xc;

			xc.red = pal->palents[i].peRed<<8;
			xc.blue = pal->palents[i].peBlue<<8;
			xc.green = pal->palents[i].peGreen<<8;
			xc.flags = DoRed|DoBlue|DoGreen;
			xc.pixel = i;
			TSXStoreColor(display,pal->cm,&xc);
		}
        }

        /* According to spec, we are only supposed to 
         * AddRef if this is not the same palette.
         */
        if( this->s.palette != pal )
        {
          if( pal != NULL )
            pal->lpvtbl->fnAddRef( pal );
          if( this->s.palette != NULL )
            this->s.palette->lpvtbl->fnRelease( this->s.palette );
	  this->s.palette = pal; 

          /* I think that we need to attach it to all backbuffers...*/
          if( this->s.backbuffer ) {
             if( this->s.backbuffer->s.palette )
               this->s.backbuffer->s.palette->lpvtbl->fnRelease(
                 this->s.backbuffer->s.palette );
             this->s.backbuffer->s.palette = pal;
             if( pal )
                pal->lpvtbl->fnAddRef( pal );
           }
          /* Perform the refresh */
          TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
        }
	return DD_OK;
}

static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
) {
	TRACE(ddraw,"(%p)->(%p)\n",this,pal);
#ifdef HAVE_LIBXXF86DGA
        /* According to spec, we are only supposed to 
         * AddRef if this is not the same palette.
         */
        if( this->s.palette != pal )
        {
          if( pal != NULL ) 
	  	pal->lpvtbl->fnAddRef( pal );
          if( this->s.palette != NULL )
            this->s.palette->lpvtbl->fnRelease( this->s.palette );
	  this->s.palette = pal; 

          /* I think that we need to attach it to all backbuffers...*/
          if( this->s.backbuffer ) {
             if( this->s.backbuffer->s.palette )
               this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
             this->s.backbuffer->s.palette = pal;
             if( pal ) pal->lpvtbl->fnAddRef( pal );
          }
	  TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
        }
	return DD_OK;
#else /* defined(HAVE_LIBXXF86DGA) */
	return E_UNEXPECTED;
#endif /* defined(HAVE_LIBXXF86DGA) */


}

static HRESULT WINAPI IDirectDrawSurface3_Blt(
	LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
) {
	RECT32	xdst,xsrc;
	DDSURFACEDESC	ddesc,sdesc;
	int	i,j;

	  TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
		this,rdst,src,rsrc,dwFlags,lpbltfx);

	if (src != NULL)
	  src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
	this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
	
	if (TRACE_ON(ddraw)) {
	  if (rdst) TRACE(ddraw,"	destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
	  if (rsrc) TRACE(ddraw,"	srcrect  :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
	  TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
	  if (dwFlags & DDBLT_DDFX) {
	    TRACE(ddraw,"	blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
	  }
	}
		
	if (rdst) {
		memcpy(&xdst,rdst,sizeof(xdst));
	} else {
		xdst.top	= 0;
		xdst.bottom	= ddesc.dwHeight;
		xdst.left	= 0;
		xdst.right	= ddesc.dwWidth;
	}

	if (rsrc) {
		memcpy(&xsrc,rsrc,sizeof(xsrc));
	} else {
		if (src) {
		xsrc.top	= 0;
		xsrc.bottom	= sdesc.dwHeight;
		xsrc.left	= 0;
		xsrc.right	= sdesc.dwWidth;
		} else {
		    memset(&xsrc,0,sizeof(xsrc));
		}
	}

	dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
	
	if (dwFlags & DDBLT_COLORFILL) {
		int	bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
		LPBYTE	xline,xpixel;

		xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
		for (i=xdst.top;i<xdst.bottom;i++) {
			xpixel = xline+bpp*xdst.left;

			for (j=xdst.left;j<xdst.right;j++) {
				/* FIXME: this only works on little endian
				 * architectures, where DWORD starts with low
				 * byte first!
				 */
				memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
				xpixel += bpp;
			}
			xline += ddesc.lPitch;
		}
		dwFlags &= ~(DDBLT_COLORFILL);
	}

	if (!src) {
	    if (dwFlags) {
	      TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
	    }
	    this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
	    return DD_OK;
	}

	if (	(xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
		(xsrc.left==0) && (xsrc.right  ==ddesc.dwWidth) &&
		(xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
		(xdst.left==0) && (xdst.right  ==ddesc.dwWidth)  &&
		!dwFlags
	) {
		memcpy(ddesc.y.lpSurface,
		       sdesc.y.lpSurface,
		       ddesc.dwHeight * ddesc.lPitch);
	} else {
	  int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
	  int srcheight = xsrc.bottom - xsrc.top;
	  int srcwidth = xsrc.right - xsrc.left;
	  int dstheight = xdst.bottom - xdst.top;
	  int dstwidth = xdst.right - xdst.left;
	  int width = (xsrc.right - xsrc.left) * bpp;
	  int h;

	  /* Sanity check for rectangle sizes */
	  if ((srcheight != dstheight) || (srcwidth  != dstwidth)) {
	    int x, y;
	    
	    /* I think we should do a Blit with 'stretching' here....
	       Tomb Raider II uses this to display the background during the menu selection
	       when the screen resolution is != than 40x480 */
	    TRACE(ddraw, "Blt with stretching\n");

	    /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
	    if (bpp == 1) {
	      /* In this case, we cannot do any anti-aliasing */
	      for (y = xdst.top; y < xdst.bottom; y++) {
		for (x = xdst.left; x < xdst.right; x++) {
		  double sx, sy;
		  unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
		  unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;

		  sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
		  sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
		  
		  dbuf[(y * ddesc.lPitch) + x] = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
		}
	      }
	    } else {
	      FIXME(ddraw, "Not done yet for depth != 8\n");
	    }
	  } else {
	    /* Same size => fast blit */
	    for (h = 0; h < srcheight; h++) {
	    memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
		   sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
		   width);
	  }
	}
	}
	
	if (dwFlags && FIXME_ON(ddraw)) {
	  FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
	}

	this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
	src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);

	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_BltFast(
	LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
) {
	int		i,bpp,w,h;
	DDSURFACEDESC	ddesc,sdesc;

	if (1  || TRACE_ON(ddraw)) {
	    FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
		    this,dstx,dsty,src,rsrc,trans
	    );
	    FIXME(ddraw,"	trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
	    FIXME(ddraw,"	srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
	}
	/* We need to lock the surfaces, or we won't get refreshes when done. */
	src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
	this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
	bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
	h=rsrc->bottom-rsrc->top;
	if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
	if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
	if (h<0) h=0;
	w=rsrc->right-rsrc->left;
	if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
	if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
	if (w<0) w=0;

	for (i=0;i<h;i++) {
		memcpy(	ddesc.y.lpSurface+(dsty     +i)*ddesc.lPitch+dstx*bpp,
			sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
			w*bpp
		);
	}
	this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
	src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
	LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
) {
	FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
		this,ddbltbatch,x,y
	);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
	LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
) {
	TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
	caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
	LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
) { 
		TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
			     this,ddsd);
  
  /* Simply copy the surface description stored in the object */
  *ddsd = this->s.surface_desc;
  
  if (TRACE_ON(ddraw)) {
		fprintf(stderr,"	flags: ");
		_dump_DDSD(ddsd->dwFlags);
    if (ddsd->dwFlags & DDSD_CAPS) {
      fprintf(stderr, "  caps:  ");
      _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
    }
		fprintf(stderr,"\n");
	}

	return DD_OK;
}

static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );

	return ++(this->ref);
}

static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );

#ifdef HAVE_LIBXXF86DGA
	if (!--(this->ref)) {
		this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
		/* clear out of surface list */
		if (this->t.dga.fb_height == -1) {
			HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
		} else {
			this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
		}
		HeapFree(GetProcessHeap(),0,this);
		return 0;
	}
#endif /* defined(HAVE_LIBXXF86DGA) */
	return this->ref;
}

static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );

	if (!--(this->ref)) {
		this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);

		if( this->s.backbuffer )
		  this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);

    if (this->t.xlib.image != NULL) {
		this->t.xlib.image->data = NULL;
      
#ifdef HAVE_LIBXXSHM
      if (this->s.ddraw->e.xlib.xshm_active) {
	TSXShmDetach(display, &(this->t.xlib.shminfo));
		TSXDestroyImage(this->t.xlib.image);
	shmdt(this->t.xlib.shminfo.shmaddr);
      } else {
#endif
	      HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
	TSXDestroyImage(this->t.xlib.image);
#ifdef HAVE_LIBXXSHM	
      }
#endif
      
		this->t.xlib.image = 0;
    } else {
	    HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
    }

		if (this->s.palette)
                	this->s.palette->lpvtbl->fnRelease(this->s.palette);

		HeapFree(GetProcessHeap(),0,this);
		return 0;
	}
  
	return this->ref;
}

static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
	LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
) {
        TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
		     this, lpddsd, lpdsf);

	if (TRACE_ON(ddraw)) {
		TRACE(ddraw,"	caps ");
		_dump_DDSCAPS(lpddsd->dwCaps);
	}

	if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
		FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
		return E_FAIL;
	}

	/* FIXME: should handle more than one backbuffer */
	*lpdsf = this->s.backbuffer;
 
        if( this->s.backbuffer )
          this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );

	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_Initialize(
	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
) {
	TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);

	return DDERR_ALREADYINITIALIZED;
}

static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
	LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
) {
	TRACE(ddraw,"(%p)->(%p)\n",this,pf);

	*pf = this->s.surface_desc.ddpfPixelFormat;
	
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
	FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
	LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
) {
	FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
) {
	FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
) {
	FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);

	/* This hack will be enough for the moment */
	if (this->s.backbuffer == NULL)
	this->s.backbuffer = surf;
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
	FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
	*lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
	FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
	EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
	return DD_OK;
}


static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
        char    xrefiid[50];

        WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
        TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
	
	/* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
	 * the same interface. And IUnknown does that too of course.
	 */
	if (	!memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID))	||
		!memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID))	||
		!memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID))	||
		!memcmp(&IID_IUnknown,refiid,sizeof(IID))
	) {
		*obj = this;
		this->lpvtbl->fnAddRef(this);

		TRACE(ddraw, "  Creating IDirect3DSurfaceX interface (%p)\n", *obj);
		
		return S_OK;
	}
	else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
	  {
	    /* Texture interface */
	    *obj = d3dtexture2_create(this);
	    this->lpvtbl->fnAddRef(this);
	    
	    TRACE(ddraw, "  Creating IDirect3DTexture2 interface (%p)\n", *obj);
	    
	    return S_OK;
	  }
	else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
	  {
	    /* Texture interface */
	    *obj = d3dtexture_create(this);
	    this->lpvtbl->fnAddRef(this);
	    
	    TRACE(ddraw, "  Creating IDirect3DTexture interface (%p)\n", *obj);
	    
	    return S_OK;
	  }
	else if (is_OpenGL_dx3(refiid, (LPDIRECTDRAWSURFACE) this, (LPDIRECT3DDEVICE *) obj))
	  {
	    /* It is the OpenGL Direct3D Device */
	    this->lpvtbl->fnAddRef(this);

	    TRACE(ddraw, "  Creating IDirect3DDevice interface (%p)\n", *obj);
			
		return S_OK;
	}
	
	FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
	return OLE_E_ENUM_NOMORE;
}

static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
	TRACE(ddraw,"(%p)->(), stub!\n",this);
	return DD_OK; /* hmm */
}

static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
	FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
	FIXME(ddraw,"(%p)->(),stub!\n",this);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
	LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey ) 
{
        TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",this,dwFlags,ckey);

        if( dwFlags & DDCKEY_SRCBLT )
        {
           dwFlags &= ~DDCKEY_SRCBLT;
           memcpy( &(this->s.ckSrcBlt), ckey, sizeof( *ckey ) );
        }

        if( dwFlags & DDCKEY_DESTBLT )
        {
           dwFlags &= ~DDCKEY_DESTBLT;
           memcpy( &(this->s.ckDestBlt), ckey, sizeof( *ckey ) );
        }

        if( dwFlags & DDCKEY_SRCOVERLAY )
        {
           dwFlags &= ~DDCKEY_SRCOVERLAY;
           memcpy( &(this->s.ckSrcOverlay), ckey, sizeof( *ckey ) );
        }
        if( dwFlags & DDCKEY_DESTOVERLAY )
        {
           dwFlags &= ~DDCKEY_DESTOVERLAY;
           memcpy( &(this->s.ckDestOverlay), ckey, sizeof( *ckey ) );
        }

        if( dwFlags )
        {
          FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
        }

        return DD_OK;

}

static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect(
        LPDIRECTDRAWSURFACE3 this, 
        LPRECT32 lpRect )
{
  FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect); 

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface(
        LPDIRECTDRAWSURFACE3 this, 
        DWORD dwFlags,
        LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface )
{
  FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders(
        LPDIRECTDRAWSURFACE3 this,
        DWORD dwFlags,
        LPVOID lpContext,
        LPDDENUMSURFACESCALLBACK lpfnCallback )
{
  FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
          lpContext, lpfnCallback );

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_GetClipper(
        LPDIRECTDRAWSURFACE3 this,
        LPDIRECTDRAWCLIPPER* lplpDDClipper )
{
  FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_GetColorKey(
        LPDIRECTDRAWSURFACE3 this,
        DWORD dwFlags,
        LPDDCOLORKEY lpDDColorKey )
{
  TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", this, dwFlags, lpDDColorKey);

  if( dwFlags & DDCKEY_SRCBLT )  {
     dwFlags &= ~DDCKEY_SRCBLT;
     memcpy( lpDDColorKey, &(this->s.ckSrcBlt), sizeof( *lpDDColorKey ) );
  }

  if( dwFlags & DDCKEY_DESTBLT )
  {
    dwFlags &= ~DDCKEY_DESTBLT;
    memcpy( lpDDColorKey, &(this->s.ckDestBlt), sizeof( *lpDDColorKey ) );
  }

  if( dwFlags & DDCKEY_SRCOVERLAY )
  {
    dwFlags &= ~DDCKEY_SRCOVERLAY;
    memcpy( lpDDColorKey, &(this->s.ckSrcOverlay), sizeof( *lpDDColorKey ) );
  }

  if( dwFlags & DDCKEY_DESTOVERLAY )
  {
    dwFlags &= ~DDCKEY_DESTOVERLAY;
    memcpy( lpDDColorKey, &(this->s.ckDestOverlay), sizeof( *lpDDColorKey ) );
  }

  if( dwFlags )
  {
    FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
  }

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus(
        LPDIRECTDRAWSURFACE3 this,
        DWORD dwFlags ) 
{
  FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_GetPalette(
        LPDIRECTDRAWSURFACE3 this,
        LPDIRECTDRAWPALETTE* lplpDDPalette )
{
  FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition(
        LPDIRECTDRAWSURFACE3 this,
        LONG lX,
        LONG lY)
{
  FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay(
        LPDIRECTDRAWSURFACE3 this,
        LPRECT32 lpSrcRect,
        LPDIRECTDRAWSURFACE3 lpDDDestSurface,
        LPRECT32 lpDestRect,
        DWORD dwFlags,
        LPDDOVERLAYFX lpDDOverlayFx )
{
  FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
         lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );  

  return DD_OK;
}
 
static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay(
        LPDIRECTDRAWSURFACE3 this,
        DWORD dwFlags )
{
  FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags); 

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder(
        LPDIRECTDRAWSURFACE3 this,
        DWORD dwFlags,
        LPDIRECTDRAWSURFACE3 lpDDSReference )
{
  FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface(
        LPDIRECTDRAWSURFACE3 this,
        LPVOID* lplpDD )
{
  FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);

  /* Not sure about that... */
  *lplpDD = (void *) this->s.ddraw;
  
  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_PageLock(
        LPDIRECTDRAWSURFACE3 this,
        DWORD dwFlags )
{
  FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_PageUnlock(
        LPDIRECTDRAWSURFACE3 this,
        DWORD dwFlags )
{
  FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc(
        LPDIRECTDRAWSURFACE3 this,
        LPDDSURFACEDESC lpDDSD,
        DWORD dwFlags )
{
  FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);

  return DD_OK;
}

static struct IDirectDrawSurface3_VTable dga_dds3vt = {
	IDirectDrawSurface3_QueryInterface,
	IDirectDrawSurface3_AddRef,
	DGA_IDirectDrawSurface3_Release,
	IDirectDrawSurface3_AddAttachedSurface,
	IDirectDrawSurface3_AddOverlayDirtyRect,
	IDirectDrawSurface3_Blt,
	IDirectDrawSurface3_BltBatch,
	IDirectDrawSurface3_BltFast,
	IDirectDrawSurface3_DeleteAttachedSurface,
	IDirectDrawSurface3_EnumAttachedSurfaces,
	IDirectDrawSurface3_EnumOverlayZOrders,
	DGA_IDirectDrawSurface3_Flip,
	IDirectDrawSurface3_GetAttachedSurface,
	IDirectDrawSurface3_GetBltStatus,
	IDirectDrawSurface3_GetCaps,
	IDirectDrawSurface3_GetClipper,
	IDirectDrawSurface3_GetColorKey,
	IDirectDrawSurface3_GetDC,
	IDirectDrawSurface3_GetFlipStatus,
	IDirectDrawSurface3_GetOverlayPosition,
	IDirectDrawSurface3_GetPalette,
	IDirectDrawSurface3_GetPixelFormat,
	IDirectDrawSurface3_GetSurfaceDesc,
	IDirectDrawSurface3_Initialize,
	IDirectDrawSurface3_IsLost,
	IDirectDrawSurface3_Lock,
	IDirectDrawSurface3_ReleaseDC,
	IDirectDrawSurface3_Restore,
	IDirectDrawSurface3_SetClipper,
	IDirectDrawSurface3_SetColorKey,
	IDirectDrawSurface3_SetOverlayPosition,
	DGA_IDirectDrawSurface3_SetPalette,
	DGA_IDirectDrawSurface3_Unlock,
	IDirectDrawSurface3_UpdateOverlay,
	IDirectDrawSurface3_UpdateOverlayDisplay,
	IDirectDrawSurface3_UpdateOverlayZOrder,
	IDirectDrawSurface3_GetDDInterface,
	IDirectDrawSurface3_PageLock,
	IDirectDrawSurface3_PageUnlock,
	IDirectDrawSurface3_SetSurfaceDesc,
};

static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
	IDirectDrawSurface3_QueryInterface,
	IDirectDrawSurface3_AddRef,
	Xlib_IDirectDrawSurface3_Release,
	IDirectDrawSurface3_AddAttachedSurface,
	IDirectDrawSurface3_AddOverlayDirtyRect,
	IDirectDrawSurface3_Blt,
	IDirectDrawSurface3_BltBatch,
	IDirectDrawSurface3_BltFast,
	IDirectDrawSurface3_DeleteAttachedSurface,
	IDirectDrawSurface3_EnumAttachedSurfaces,
	IDirectDrawSurface3_EnumOverlayZOrders,
	Xlib_IDirectDrawSurface3_Flip,
	IDirectDrawSurface3_GetAttachedSurface,
	IDirectDrawSurface3_GetBltStatus,
	IDirectDrawSurface3_GetCaps,
	IDirectDrawSurface3_GetClipper,
	IDirectDrawSurface3_GetColorKey,
	IDirectDrawSurface3_GetDC,
	IDirectDrawSurface3_GetFlipStatus,
	IDirectDrawSurface3_GetOverlayPosition,
	IDirectDrawSurface3_GetPalette,
	IDirectDrawSurface3_GetPixelFormat,
	IDirectDrawSurface3_GetSurfaceDesc,
	IDirectDrawSurface3_Initialize,
	IDirectDrawSurface3_IsLost,
	IDirectDrawSurface3_Lock,
	IDirectDrawSurface3_ReleaseDC,
	IDirectDrawSurface3_Restore,
	IDirectDrawSurface3_SetClipper,
	IDirectDrawSurface3_SetColorKey,
	IDirectDrawSurface3_SetOverlayPosition,
	Xlib_IDirectDrawSurface3_SetPalette,
	Xlib_IDirectDrawSurface3_Unlock,
	IDirectDrawSurface3_UpdateOverlay,
	IDirectDrawSurface3_UpdateOverlayDisplay,
	IDirectDrawSurface3_UpdateOverlayZOrder,
	IDirectDrawSurface3_GetDDInterface,
	IDirectDrawSurface3_PageLock,
	IDirectDrawSurface3_PageUnlock,
	IDirectDrawSurface3_SetSurfaceDesc,
};

/******************************************************************************
 *			DirectDrawCreateClipper (DDRAW.7)
 */
HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
				        LPDIRECTDRAWCLIPPER *lplpDDClipper,
				        LPUNKNOWN pUnkOuter)
{
  TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);

  *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
  (*lplpDDClipper)->lpvtbl = &ddclipvt;
  (*lplpDDClipper)->ref = 1;

  return DD_OK;
}

/******************************************************************************
 *			IDirectDrawClipper
 */
static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
	LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
) {
	FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
	return DD_OK;
}

static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );

	this->ref--;
	if (this->ref)
		return this->ref;
	HeapFree(GetProcessHeap(),0,this);
	return 0;
}

static HRESULT WINAPI IDirectDrawClipper_GetClipList(
	LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
) {
	FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
	if (hmm) *hmm=0;
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawClipper_SetClipList(
	LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
) {
	FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawClipper_QueryInterface(
         LPDIRECTDRAWCLIPPER this,
         REFIID riid,
         LPVOID* ppvObj )
{
   FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,riid,ppvObj);
   return OLE_E_ENUM_NOMORE;
}

static ULONG WINAPI IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER this )
{
  TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
  return ++(this->ref);
}

static HRESULT WINAPI IDirectDrawClipper_GetHWnd(
         LPDIRECTDRAWCLIPPER this,
         HWND32* HWndPtr )
{
   FIXME(ddraw,"(%p)->(%p),stub!\n",this,HWndPtr);
   return DD_OK;
}

static HRESULT WINAPI IDirectDrawClipper_Initialize(
         LPDIRECTDRAWCLIPPER this,
         LPDIRECTDRAW lpDD,
         DWORD dwFlags )
{
   FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD,dwFlags);
   return DD_OK;
}

static HRESULT WINAPI IDirectDrawClipper_IsClipListChanged(
         LPDIRECTDRAWCLIPPER this,
         BOOL32* lpbChanged )
{
   FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpbChanged);
   return DD_OK;
}

static struct IDirectDrawClipper_VTable ddclipvt = {
        IDirectDrawClipper_QueryInterface,
        IDirectDrawClipper_AddRef,
        IDirectDrawClipper_Release,
        IDirectDrawClipper_GetClipList,
        IDirectDrawClipper_GetHWnd,
        IDirectDrawClipper_Initialize,
        IDirectDrawClipper_IsClipListChanged,
        IDirectDrawClipper_SetClipList,
        IDirectDrawClipper_SetHwnd
};


/******************************************************************************
 *			IDirectDrawPalette
 */
static HRESULT WINAPI IDirectDrawPalette_GetEntries(
	LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
) {
	int	i;

	TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
	      this,x,start,count,palent);

	if (!this->cm) /* should not happen */ {
		FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
		return DDERR_GENERIC;
	}
	for (i=0;i<count;i++) {
                palent[i].peRed   = this->palents[start+i].peRed;
                palent[i].peBlue  = this->palents[start+i].peBlue;
                palent[i].peGreen = this->palents[start+i].peGreen;
                palent[i].peFlags = this->palents[start+i].peFlags;

	}
	return DD_OK;
}

static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
	LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
) {
	XColor		xc;
	int		i;

	TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
		this,x,start,count,palent
	);
	for (i=0;i<count;i++) {
		xc.red = palent[i].peRed<<8;
		xc.blue = palent[i].peBlue<<8;
		xc.green = palent[i].peGreen<<8;
		xc.flags = DoRed|DoBlue|DoGreen;
		xc.pixel = start+i;

		if (this->cm)
		    TSXStoreColor(display,this->cm,&xc);

		this->palents[start+i].peRed = palent[i].peRed;
		this->palents[start+i].peBlue = palent[i].peBlue;
		this->palents[start+i].peGreen = palent[i].peGreen;
                this->palents[start+i].peFlags = palent[i].peFlags;
	}
	if (!this->cm) /* should not happen */ {
	}
	return DD_OK;
}

static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
	LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
) {
#ifdef HAVE_LIBXXF86DGA
	XColor		xc;
	Colormap	cm;
	int		i;

	TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
		this,x,start,count,palent
	);
	if (!this->cm) /* should not happen */ {
		FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
		return DDERR_GENERIC;
	}
	/* FIXME: free colorcells instead of freeing whole map */
	cm = this->cm;
	this->cm = TSXCopyColormapAndFree(display,this->cm);
	TSXFreeColormap(display,cm);

	for (i=0;i<count;i++) {
		xc.red = palent[i].peRed<<8;
		xc.blue = palent[i].peBlue<<8;
		xc.green = palent[i].peGreen<<8;
		xc.flags = DoRed|DoBlue|DoGreen;
		xc.pixel = i+start;

		TSXStoreColor(display,this->cm,&xc);

		this->palents[start+i].peRed = palent[i].peRed;
		this->palents[start+i].peBlue = palent[i].peBlue;
		this->palents[start+i].peGreen = palent[i].peGreen;
                this->palents[start+i].peFlags = palent[i].peFlags;
	}
	TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
	return DD_OK;
#else /* defined(HAVE_LIBXXF86DGA) */
	return E_UNEXPECTED;
#endif /* defined(HAVE_LIBXXF86DGA) */
}

static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
	if (!--(this->ref)) {
		if (this->cm) {
			TSXFreeColormap(display,this->cm);
			this->cm = 0;
		}
		HeapFree(GetProcessHeap(),0,this);
		return 0;
	}
	return this->ref;
}

static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {

        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
	return ++(this->ref);
}

static HRESULT WINAPI IDirectDrawPalette_Initialize(
	LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
) {
        TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);

	return DDERR_ALREADYINITIALIZED;
}

static HRESULT WINAPI IDirectDrawPalette_GetCaps(
         LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
{
   FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
   return DD_OK;
} 

static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
        LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj ) 
{
  char    xrefiid[50];

  WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
  FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);

  return S_OK;
}

static struct IDirectDrawPalette_VTable dga_ddpalvt = {
	IDirectDrawPalette_QueryInterface,
	IDirectDrawPalette_AddRef,
	IDirectDrawPalette_Release,
	IDirectDrawPalette_GetCaps,
	IDirectDrawPalette_GetEntries,
	IDirectDrawPalette_Initialize,
	DGA_IDirectDrawPalette_SetEntries
};

static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
	IDirectDrawPalette_QueryInterface,
	IDirectDrawPalette_AddRef,
	IDirectDrawPalette_Release,
	IDirectDrawPalette_GetCaps,
	IDirectDrawPalette_GetEntries,
	IDirectDrawPalette_Initialize,
	Xlib_IDirectDrawPalette_SetEntries
};

/*******************************************************************************
 *				IDirect3D
 */
static HRESULT WINAPI IDirect3D_QueryInterface(
        LPDIRECT3D this,REFIID refiid,LPVOID *obj
) {
	/* FIXME: Not sure if this is correct */
        char    xrefiid[50];

        WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
        TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
        if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
                *obj = this;
                this->lpvtbl->fnAddRef(this);

		TRACE(ddraw, "  Creating IUnknown interface (%p)\n", *obj);
		
                return S_OK;
        }
        if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
                LPDIRECT3D      d3d;

                d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
                d3d->ref = 1;
                d3d->ddraw = (LPDIRECTDRAW)this;
                this->lpvtbl->fnAddRef(this);
                d3d->lpvtbl = &d3dvt;
                *obj = d3d;

		TRACE(ddraw, "  Creating IDirect3D interface (%p)\n", *obj);

                return S_OK;
        }
        if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
                LPDIRECT3D2     d3d;

                d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
                d3d->ref = 1;
                d3d->ddraw = (LPDIRECTDRAW)this;
                this->lpvtbl->fnAddRef(this);
                d3d->lpvtbl = &d3d2vt;
                *obj = d3d;

		TRACE(ddraw, "  Creating IDirect3D2 interface (%p)\n", *obj);

                return S_OK;
        }
        FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
        return OLE_E_ENUM_NOMORE;
}

static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );

        return ++(this->ref);
}

static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
{
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );

        if (!--(this->ref)) {
                this->ddraw->lpvtbl->fnRelease(this->ddraw);
                HeapFree(GetProcessHeap(),0,this);
                return 0;
        }
        return this->ref;
}

static HRESULT WINAPI IDirect3D_Initialize(
         LPDIRECT3D this, REFIID refiid )
{
  /* FIXME: Not sure if this is correct */
  char    xrefiid[50];

  WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
  FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
  
  return DDERR_ALREADYINITIALIZED;
}

static HRESULT WINAPI IDirect3D_EnumDevices(LPDIRECT3D this,
					    LPD3DENUMDEVICESCALLBACK cb,
					    LPVOID context) {
  FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);

  /* Call functions defined in d3ddevices.c */
  if (d3d_OpenGL_dx3(cb, context))
    return DD_OK;

  return DD_OK;
}

static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,
					    LPDIRECT3DLIGHT *lplight,
					    IUnknown *lpunk)
{
  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
  
  /* Call the creation function that is located in d3dlight.c */
  *lplight = d3dlight_create_dx3(this);
  
  return DD_OK;
}

static HRESULT WINAPI IDirect3D_CreateMaterial(LPDIRECT3D this,
					       LPDIRECT3DMATERIAL *lpmaterial,
					       IUnknown *lpunk)
{
  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);

  /* Call the creation function that is located in d3dviewport.c */
  *lpmaterial = d3dmaterial_create(this);
  
  return DD_OK;
}

static HRESULT WINAPI IDirect3D_CreateViewport(LPDIRECT3D this,
					       LPDIRECT3DVIEWPORT *lpviewport,
					       IUnknown *lpunk)
{
  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
  
  /* Call the creation function that is located in d3dviewport.c */
  *lpviewport = d3dviewport_create(this);
  
  return DD_OK;
}

static HRESULT WINAPI IDirect3D_FindDevice(LPDIRECT3D this,
					   LPD3DFINDDEVICESEARCH lpfinddevsrc,
					   LPD3DFINDDEVICERESULT lpfinddevrst)
{
  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
  
  return DD_OK;
}

static struct IDirect3D_VTable d3dvt = {
        IDirect3D_QueryInterface,
        IDirect3D_AddRef,
        IDirect3D_Release,
        IDirect3D_Initialize,
        IDirect3D_EnumDevices,
        IDirect3D_CreateLight,
        IDirect3D_CreateMaterial,
        IDirect3D_CreateViewport,
	IDirect3D_FindDevice
};

/*******************************************************************************
 *				IDirect3D2
 */
static HRESULT WINAPI IDirect3D2_QueryInterface(
        LPDIRECT3D2 this,REFIID refiid,LPVOID *obj) {
  /* For the moment, we use the same function as in IDirect3D */
  TRACE(ddraw, "Calling IDirect3D enumerating function.\n");
  
  return IDirect3D_QueryInterface((LPDIRECT3D) this, refiid, obj);
}

static ULONG WINAPI IDirect3D2_AddRef(LPDIRECT3D2 this) {
        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );

        return ++(this->ref);
}

static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );

	if (!--(this->ref)) {
		this->ddraw->lpvtbl->fnRelease(this->ddraw);
		HeapFree(GetProcessHeap(),0,this);
		return 0;
	}
	return this->ref;
}

static HRESULT WINAPI IDirect3D2_EnumDevices(
	LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
) {
	FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);

	/* Call functions defined in d3ddevices.c */
	if (d3d_OpenGL(cb, context))
	  return DD_OK;

	return DD_OK;
}

static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,
					     LPDIRECT3DLIGHT *lplight,
					     IUnknown *lpunk)
{
  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);

  /* Call the creation function that is located in d3dlight.c */
  *lplight = d3dlight_create(this);
  
	return DD_OK;
}

static HRESULT WINAPI IDirect3D2_CreateMaterial(LPDIRECT3D2 this,
						LPDIRECT3DMATERIAL2 *lpmaterial,
						IUnknown *lpunk)
{
  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);

  /* Call the creation function that is located in d3dviewport.c */
  *lpmaterial = d3dmaterial2_create(this);

  return DD_OK;
}

static HRESULT WINAPI IDirect3D2_CreateViewport(LPDIRECT3D2 this,
						LPDIRECT3DVIEWPORT2 *lpviewport,
						IUnknown *lpunk)
{
  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
  
  /* Call the creation function that is located in d3dviewport.c */
  *lpviewport = d3dviewport2_create(this);
  
  return DD_OK;
}

static HRESULT WINAPI IDirect3D2_FindDevice(LPDIRECT3D2 this,
					    LPD3DFINDDEVICESEARCH lpfinddevsrc,
					    LPD3DFINDDEVICERESULT lpfinddevrst)
{
  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);

  return DD_OK;
}

static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,
					      REFCLSID rguid,
					      LPDIRECTDRAWSURFACE surface,
					      LPDIRECT3DDEVICE2 *device)
{
  char	xbuf[50];
  
  WINE_StringFromCLSID(rguid,xbuf);
  FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",this,xbuf,surface,device);

  if (is_OpenGL(rguid, surface, device, this)) {
    this->lpvtbl->fnAddRef(this);
    return DD_OK;
}

  return DDERR_INVALIDPARAMS;
}

static struct IDirect3D2_VTable d3d2vt = {
	IDirect3D2_QueryInterface,
	IDirect3D2_AddRef,
        IDirect3D2_Release,
        IDirect3D2_EnumDevices,
	IDirect3D2_CreateLight,
	IDirect3D2_CreateMaterial,
	IDirect3D2_CreateViewport,
	IDirect3D2_FindDevice,
	IDirect3D2_CreateDevice
};

/*******************************************************************************
 *				IDirectDraw
 */

/* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
 */
static INT32 ddrawXlibThisOffset = 0;

static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
					       LPDDSURFACEDESC lpddsd,
					       LPDIRECTDRAWSURFACE lpdsf)
{
  int bpp;
  
  /* The surface was already allocated when entering in this function */
  TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);

  if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
    /* This is a Z Buffer */
    bpp = lpddsd->x.dwZBufferBitDepth;
  } else {
    /* This is a standard image */
  if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
    /* No pixel format => use DirectDraw's format */
    _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
    lpddsd->dwFlags |= DDSD_PIXELFORMAT;
  }  else {
    /* To check what the program wants */
    if (TRACE_ON(ddraw)) {
      _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
    }
  }
  }

  if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
    bpp = 1;
  } else {
  bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
  }

  /* Copy the surface description */
  lpdsf->s.surface_desc = *lpddsd;
  
  lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
  lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
  lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
  
  return DD_OK;
}

static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
) {
#ifdef HAVE_LIBXXF86DGA
	int	i;

	TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
	if (TRACE_ON(ddraw)) {
		DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
		_dump_DDSD(lpddsd->dwFlags);
		fprintf(stderr,"caps ");
		_dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
		fprintf(stderr,"]\n");
	}

	*lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
	this->lpvtbl->fnAddRef(this);
        
	(*lpdsf)->ref = 1;
	(*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
	(*lpdsf)->s.ddraw = this;
	(*lpdsf)->s.palette = NULL;
	(*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */

	if (!(lpddsd->dwFlags & DDSD_WIDTH))
	  lpddsd->dwWidth  = this->d.width;
	if (!(lpddsd->dwFlags & DDSD_HEIGHT))
	  lpddsd->dwHeight = this->d.height;
	
	/* Check if this a 'primary surface' or not */
	if ((lpddsd->dwFlags & DDSD_CAPS) &&
	    (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {

	  /* This is THE primary surface => there is DGA-specific code */
	  /* First, store the surface description */
	  (*lpdsf)->s.surface_desc = *lpddsd;
	  
	  /* Find a viewport */
		for (i=0;i<32;i++)
			if (!(this->e.dga.vpmask & (1<<i)))
				break;
		TRACE(ddraw,"using viewport %d for a primary surface\n",i);
		/* if i == 32 or maximum ... return error */
		this->e.dga.vpmask|=(1<<i);
	  (*lpdsf)->s.surface_desc.y.lpSurface =
	    this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
		(*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
	  (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
	  lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;

	  /* Add flags if there were not present */
	  (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
	  (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
	  (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
	  (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
	  _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
	(*lpdsf)->s.backbuffer = NULL;
	  
	if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
		LPDIRECTDRAWSURFACE3	back;

		if (lpddsd->dwBackBufferCount>1)
			FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);

	    (*lpdsf)->s.backbuffer = back =
	      (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
		this->lpvtbl->fnAddRef(this);
		back->ref = 1;
		back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
		for (i=0;i<32;i++)
			if (!(this->e.dga.vpmask & (1<<i)))
				break;
		TRACE(ddraw,"using viewport %d for backbuffer\n",i);
		/* if i == 32 or maximum ... return error */
		this->e.dga.vpmask|=(1<<i);
		back->t.dga.fb_height = i*this->e.dga.fb_height;

	    /* Copy the surface description from the front buffer */
	    back->s.surface_desc = (*lpdsf)->s.surface_desc;
	    /* Change the parameters that are not the same */
	    back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
	      ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
		back->s.ddraw = this;
		back->s.backbuffer = NULL; /* does not have a backbuffer, it is
					    * one! */

	    /* Add relevant info to front and back buffers */
	    (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
	    back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
	    back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
	    back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
	  }
	} else {
	  /* There is no DGA-specific code here...
	     Go to the common surface creation function */
	  return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
	}
	
	return DD_OK;
#else /* defined(HAVE_LIBXXF86DGA) */
	return E_UNEXPECTED;
#endif /* defined(HAVE_LIBXXF86DGA) */
}

static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
  XImage *img;

#ifdef HAVE_LIBXXSHM
  if (this->e.xlib.xshm_active) {
    img = TSXShmCreateImage(display,
			    DefaultVisualOfScreen(screen),
			    this->d.depth,
			    ZPixmap,
			    NULL,
			    &(lpdsf->t.xlib.shminfo),
			    lpdsf->s.surface_desc.dwWidth,
			    lpdsf->s.surface_desc.dwHeight);
    
    if (img == NULL)
      return NULL;

    lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
    if (lpdsf->t.xlib.shminfo.shmid < 0) {
      TSXDestroyImage(img);
      return NULL;
    }

    lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
      
    if (img->data == (char *) -1) {
      TSXDestroyImage(img);
      shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
      return NULL;
    }
    lpdsf->t.xlib.shminfo.readOnly = False;
      
    TSXShmAttach(display, &(lpdsf->t.xlib.shminfo));
    TSXSync(display, False);

    shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);

    lpdsf->s.surface_desc.y.lpSurface = img->data;
  } else {
#endif
    /* Allocate surface memory */
    lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
						  lpdsf->s.surface_desc.dwWidth *
						  lpdsf->s.surface_desc.dwHeight *
						  (this->d.depth / 8));
    
    /* In this case, create an XImage */
    img =
      TSXCreateImage(display,
		     DefaultVisualOfScreen(screen),
		     this->d.depth,
		     ZPixmap,
		     0,
		     lpdsf->s.surface_desc.y.lpSurface,
		     lpdsf->s.surface_desc.dwWidth,
		     lpdsf->s.surface_desc.dwHeight,
		     32,
		     lpdsf->s.surface_desc.dwWidth * (this->d.depth / 8)
		     );
    
#ifdef HAVE_LIBXXSHM
  }
#endif
  lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
  
  return img;
}

static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
) {
	TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
		     this,lpddsd,lpdsf,lpunk);

	if (TRACE_ON(ddraw)) {
		fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
		_dump_DDSD(lpddsd->dwFlags);
		fprintf(stderr,"caps ");
		_dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
		fprintf(stderr,"]\n");
	}

	*lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));

	this->lpvtbl->fnAddRef(this);
	(*lpdsf)->s.ddraw             = this;
	(*lpdsf)->ref                 = 1;
	(*lpdsf)->lpvtbl              = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
	(*lpdsf)->s.palette = NULL;
	(*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */

	if (!(lpddsd->dwFlags & DDSD_WIDTH))
		lpddsd->dwWidth	 = this->d.width;
	if (!(lpddsd->dwFlags & DDSD_HEIGHT))
		lpddsd->dwHeight = this->d.height;

	/* Check if this a 'primary surface' or not */
  if ((lpddsd->dwFlags & DDSD_CAPS) && 
	    (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
    XImage *img;
      
    TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);

	  /* First, store the surface description */
	  (*lpdsf)->s.surface_desc = *lpddsd;
	  
    /* Create the XImage */
    img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf);
    if (img == NULL)
      return DDERR_OUTOFMEMORY;
    (*lpdsf)->t.xlib.image = img;

	  /* Add flags if there were not present */
	  (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
	  (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
	  (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
	  (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
	  _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
	  (*lpdsf)->s.backbuffer = NULL;
    
    /* Check for backbuffers */
	if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
		LPDIRECTDRAWSURFACE3	back;
      XImage *img;

		if (lpddsd->dwBackBufferCount>1)
			FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);

      (*lpdsf)->s.backbuffer = back =
	(LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));

      TRACE(ddraw,"allocated back-buffer (%p)\n", back);
      
		this->lpvtbl->fnAddRef(this);
		back->s.ddraw = this;

		back->ref = 1;
		back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
	    /* Copy the surface description from the front buffer */
	    back->s.surface_desc = (*lpdsf)->s.surface_desc;

      /* Create the XImage */
      img = create_ximage(this, back);
      if (img == NULL)
	return DDERR_OUTOFMEMORY;
      back->t.xlib.image = img;
      
		back->s.backbuffer = NULL; /* does not have a backbuffer, it is
					    * one! */

	    /* Add relevant info to front and back buffers */
	    (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
	    back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
	    back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
	    back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
	}
	} else {
	  /* There is no Xlib-specific code here...
	     Go to the common surface creation function */
	  return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
  }
  
	return DD_OK;
}

static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
	LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
) {
	FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
	*dst = src; /* FIXME */
	return DD_OK;
}

/* 
 * The Xlib Implementation tries to use the passed hwnd as drawing window,
 * even when the approbiate bitmasks are not specified.
 */
static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
	LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
) {
	int	i;
	const struct {
		int	mask;
		char	*name;
	} flagmap[] = {
		FE(DDSCL_FULLSCREEN)
		FE(DDSCL_ALLOWREBOOT)
		FE(DDSCL_NOWINDOWCHANGES)
		FE(DDSCL_NORMAL)
		FE(DDSCL_ALLOWMODEX)
		FE(DDSCL_EXCLUSIVE)
		FE(DDSCL_SETFOCUSWINDOW)
		FE(DDSCL_SETDEVICEWINDOW)
		FE(DDSCL_CREATEDEVICEWINDOW)
	};

	FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
	if(TRACE_ON(ddraw)){
	  dbg_decl_str(ddraw, 512);
	  for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
	    if (flagmap[i].mask & cooplevel)
	      dsprintf(ddraw, "%s ", flagmap[i].name);
	  TRACE(ddraw,"	cooperative level %s\n", dbg_str(ddraw));
	}
        this->d.mainWindow = hwnd;

	/* This will be overwritten in the case of Full Screen mode.
	   Windowed games could work with that :-) */
	if (hwnd)
	this->d.drawable  = ((X11DRV_WND_DATA *) WIN_FindWndPtr(hwnd)->pDriverData)->window;

	return DD_OK;
}

/* Small helper to either use the cooperative window or create a new 
 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
 */
static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
	RECT32	rect;

	/* Do not destroy the application supplied cooperative window */
	if (this->d.window && this->d.window != this->d.mainWindow) {
		DestroyWindow32(this->d.window);
		this->d.window = 0;
	}
	/* Sanity check cooperative window before assigning it to drawing. */
	if (	IsWindow32(this->d.mainWindow) &&
		IsWindowVisible32(this->d.mainWindow)
	) {
		GetWindowRect32(this->d.mainWindow,&rect);
		if (((rect.right-rect.left) >= this->d.width)	&&
		    ((rect.bottom-rect.top) >= this->d.height)
		)
			this->d.window = this->d.mainWindow;
	}
	/* ... failed, create new one. */
	if (!this->d.window) {
	    this->d.window = CreateWindowEx32A(
		    0,
		    "WINE_DirectDraw",
		    "WINE_DirectDraw",
		    WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
		    0,0,
		    this->d.width,
		    this->d.height,
		    0,
		    0,
		    0,
		    NULL
	    );
	    /*Store THIS with the window. We'll use it in the window procedure*/
	    SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
	    ShowWindow32(this->d.window,TRUE);
	    UpdateWindow32(this->d.window);
	}
	SetFocus32(this->d.window);
}

static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
	LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
) {
#ifdef HAVE_LIBXXF86DGA
        int	i,*depths,depcount,mode_count;

	TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);

	depths = TSXListDepths(display,DefaultScreen(display),&depcount);
	for (i=0;i<depcount;i++)
		if (depths[i]==depth)
			break;
	TSXFree(depths);
	if (i==depcount) {/* not found */
		ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
		return DDERR_UNSUPPORTEDMODE;
	}
	if (this->d.width < width) {
		ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
		return DDERR_UNSUPPORTEDMODE;
	}
	this->d.width	= width;
	this->d.height	= height;
	this->d.depth	= depth;

	/* adjust fb_height, so we don't overlap */
	if (this->e.dga.fb_height < height)
		this->e.dga.fb_height = height;
	_common_IDirectDraw_SetDisplayMode(this);

#ifdef HAVE_LIBXXF86VM
        {
            XF86VidModeModeInfo **all_modes, *vidmode = NULL;
	    XF86VidModeModeLine mod_tmp;
	    int dotclock_tmp;

            /* save original video mode and set fullscreen if available*/
	    orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));  
	    TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
	    orig_mode->hdisplay = mod_tmp.hdisplay; 
	    orig_mode->hsyncstart = mod_tmp.hsyncstart;
	    orig_mode->hsyncend = mod_tmp.hsyncend; 
	    orig_mode->htotal = mod_tmp.htotal;
	    orig_mode->vdisplay = mod_tmp.vdisplay; 
	    orig_mode->vsyncstart = mod_tmp.vsyncstart;
	    orig_mode->vsyncend = mod_tmp.vsyncend; 
	    orig_mode->vtotal = mod_tmp.vtotal;
	    orig_mode->flags = mod_tmp.flags; 
	    orig_mode->private = mod_tmp.private;
	    
            TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
            for (i=0;i<mode_count;i++)
            {
                if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
                {
                    vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
                    *vidmode = *(all_modes[i]);
                    break;
                } else
                    TSXFree(all_modes[i]->private);
            }
            TSXFree(all_modes);

            if (!vidmode)
                WARN(ddraw, "Fullscreen mode not available!\n");

            if (vidmode)
	      {
                TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
		TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
	      }
        }
#endif

	/* FIXME: this function OVERWRITES several signal handlers. 
	 * can we save them? and restore them later? In a way that
	 * it works for the library too?
	 */
	TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
#ifdef DIABLO_HACK
	TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
#endif

#ifdef RESTORE_SIGNALS
	SIGNAL_InitEmulator();
#endif
	return DD_OK;
#else /* defined(HAVE_LIBXXF86DGA) */
	return E_UNEXPECTED;
#endif /* defined(HAVE_LIBXXF86DGA) */
}

static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
	LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
) {
	int	i,*depths,depcount;
	char	buf[200];

	TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
		      this, width, height, depth);

	depths = TSXListDepths(display,DefaultScreen(display),&depcount);
	for (i=0;i<depcount;i++)
		if (depths[i]==depth)
			break;
	TSXFree(depths);
	if (i==depcount) {/* not found */
		sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
		MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
		return DDERR_UNSUPPORTEDMODE;
	}
	this->d.width	= width;
	this->d.height	= height;
	this->d.depth	= depth;

	_common_IDirectDraw_SetDisplayMode(this);

	this->e.xlib.paintable = 1;
        this->d.drawable  = ((X11DRV_WND_DATA *) WIN_FindWndPtr(this->d.window)->pDriverData)->window;  
        /* We don't have a context for this window. Host off the desktop */
        if( !this->d.drawable )
           this->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
	return DD_OK;
}

static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
	LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
) {
#ifdef HAVE_LIBXXF86DGA
	TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
	caps1->dwVidMemTotal = this->e.dga.fb_memsize;
	caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);		/* we can do anything */
	caps1->ddsCaps.dwCaps = 0xffffffff;	/* we can do anything */
	if (caps2) {
		caps2->dwVidMemTotal = this->e.dga.fb_memsize;
		caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);		/* we can do anything */
		caps2->ddsCaps.dwCaps = 0xffffffff;	/* we can do anything */
	}
	return DD_OK;
#else /* defined(HAVE_LIBXXF86DGA) */
	return E_UNEXPECTED;
#endif /* defined(HAVE_LIBXXF86DGA) */
}

static void fill_caps(LPDDCAPS caps) {
  /* This function tries to fill the capabilities of Wine's DDraw implementation.
     Need to be fixed, though.. */
  if (caps == NULL)
    return;

  caps->dwSize = sizeof(*caps);
  caps->dwCaps = DDCAPS_3D | DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
    DDCAPS_CANBLTSYSMEM | DDCAPS_PALETTE | DDCAPS_ZBLTS;
  caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NO2DDURING3DSCENE | DDCAPS2_NOPAGELOCKREQUIRED |
    DDCAPS2_WIDESURFACES;
  caps->dwCKeyCaps = 0;
  caps->dwFXCaps = 0;
  caps->dwFXAlphaCaps = 0;
  caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
  caps->dwSVCaps = 0;
  caps->dwZBufferBitDepths = DDBD_16;
  /* I put here 8 Mo so that D3D applications will believe they have enough memory
     to put textures in video memory.
     BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
     for example) ? */
  caps->dwVidMemTotal = 8192 * 1024;
  caps->dwVidMemFree = 8192 * 1024;
  /* These are all the supported capabilities of the surfaces */
  caps->ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
    DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
      DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE |
	DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE | DDSCAPS_ZBUFFER;
}

static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
	LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
)  {
	TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);

	/* Put the same caps for the two capabilities */
	fill_caps(caps1);
	fill_caps(caps2);

	return DD_OK;
}

static HRESULT WINAPI IDirectDraw2_CreateClipper(
	LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
) {
	FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
		this,x,lpddclip,lpunk
	);
	*lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
	(*lpddclip)->ref = 1;
	(*lpddclip)->lpvtbl = &ddclipvt;
	return DD_OK;
}

static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
	LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
) {
	*lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
	if (*lpddpal == NULL) return E_OUTOFMEMORY;
	(*lpddpal)->ref = 1;
	(*lpddpal)->ddraw = (LPDIRECTDRAW)this;
	(*lpddpal)->installed = 0;
	if (this->d.depth<=8) {
		(*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
	} else {
		/* we don't want palettes in hicolor or truecolor */
		(*lpddpal)->cm = 0;
	}

        if (palent)
        {
 	  int size = 0;
	  
	  if (dwFlags & DDPCAPS_1BIT)
	    size = 2;
	  else if (dwFlags & DDPCAPS_2BIT)
	    size = 4;
	  else if (dwFlags & DDPCAPS_4BIT)
	    size = 16;
	  else if (dwFlags & DDPCAPS_8BIT)
	    size = 256;
	  else
	    ERR(ddraw, "unhandled palette format\n");
	  
	  memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
        }
	return DD_OK;
}

static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
	LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
) {
	HRESULT res;
	TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
	res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
	if (res != 0) return res;
	(*lpddpal)->lpvtbl = &dga_ddpalvt;
	return DD_OK;
}

static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
	LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
) {
	TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
	*lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));

	TRACE(ddraw, "Palette created : %p\n", *lpddpal);
	
	if (*lpddpal == NULL) 
		return E_OUTOFMEMORY;

	(*lpddpal)->ref = 1;
	(*lpddpal)->installed = 0;
	(*lpddpal)->lpvtbl = &xlib_ddpalvt;

	(*lpddpal)->ddraw = (LPDIRECTDRAW)this;
        this->lpvtbl->fnAddRef(this);

	if (palent) {
	  int size = 0;

	  if (dwFlags & DDPCAPS_1BIT)
	    size = 2;
	  else if (dwFlags & DDPCAPS_2BIT)
	    size = 4;
	  else if (dwFlags & DDPCAPS_4BIT)
	    size = 16;
	  else if (dwFlags & DDPCAPS_8BIT)
	    size = 256;
	  else
	    ERR(ddraw, "unhandled palette format\n");
	  
	  memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
	}

	return DD_OK;
}

static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
#ifdef HAVE_LIBXXF86DGA
	TRACE(ddraw, "(%p)->()\n",this);
	Sleep(1000);
	TSXF86DGADirectVideo(display,DefaultScreen(display),0);
#ifdef RESTORE_SIGNALS
	SIGNAL_InitEmulator();
#endif
	return DD_OK;
#else /* defined(HAVE_LIBXXF86DGA) */
	return E_UNEXPECTED;
#endif
}

static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
	TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
	Sleep(1000);
	return DD_OK;
}

static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
	LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
) {
	TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
	return DD_OK;
}

static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );

	return ++(this->ref);
}

static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );

#ifdef HAVE_LIBXXF86DGA
	if (!--(this->ref)) {
		TSXF86DGADirectVideo(display,DefaultScreen(display),0);

#ifdef HAVE_LIBXXF86VM
		if (orig_mode)
		  TSXF86VidModeSwitchToMode(display, DefaultScreen(display), orig_mode);
		if (orig_mode->privsize)
		  TSXFree(orig_mode->private);		
		free(orig_mode);
		orig_mode = NULL;
#endif
		
#ifdef RESTORE_SIGNALS
		SIGNAL_InitEmulator();
#endif
		HeapFree(GetProcessHeap(),0,this);
		return 0;
	}
#endif /* defined(HAVE_LIBXXF86DGA) */
	return this->ref;
}

static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );

	if (!--(this->ref)) {
		HeapFree(GetProcessHeap(),0,this);
		return 0;
	}
	/* FIXME: destroy window ... */
	return this->ref;
}

static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
	LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
) {
	char    xrefiid[50];

	WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
	TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
	if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
		*obj = this;
		this->lpvtbl->fnAddRef(this);

		TRACE(ddraw, "  Creating IUnknown interface (%p)\n", *obj);
		
		return S_OK;
	}
	if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
		this->lpvtbl->fnAddRef(this);
		*obj = this;

		TRACE(ddraw, "  Creating IDirectDraw interface (%p)\n", *obj);
		
		return S_OK;
	}
	if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
		this->lpvtbl->fnAddRef(this);
		*obj = this;

		TRACE(ddraw, "  Creating IDirectDraw2 interface (%p)\n", *obj);

		return S_OK;
	}
	if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
		LPDIRECT3D	d3d;

		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
		d3d->ref = 1;
		d3d->ddraw = (LPDIRECTDRAW)this;
		this->lpvtbl->fnAddRef(this);
		d3d->lpvtbl = &d3dvt;
		*obj = d3d;

		TRACE(ddraw, "  Creating IDirect3D interface (%p)\n", *obj);
		
		return S_OK;
	}
	if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
		LPDIRECT3D2	d3d;

		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
		d3d->ref = 1;
		d3d->ddraw = (LPDIRECTDRAW)this;
		this->lpvtbl->fnAddRef(this);
		d3d->lpvtbl = &d3d2vt;
		*obj = d3d;

		TRACE(ddraw, "  Creating IDirect3D2 interface (%p)\n", *obj);
		
		return S_OK;
	}
	WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
        return OLE_E_ENUM_NOMORE;
}

static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
	LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
) {
	char    xrefiid[50];

	WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
	TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
	if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
		*obj = this;
		this->lpvtbl->fnAddRef(this);

		TRACE(ddraw, "  Creating IUnknown interface (%p)\n", *obj);
		
		return S_OK;
	}
	if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
		this->lpvtbl->fnAddRef(this);
		*obj = this;

		TRACE(ddraw, "  Creating IDirectDraw interface (%p)\n", *obj);
		
		return S_OK;
	}
	if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
		this->lpvtbl->fnAddRef(this);
		*obj = this;

		TRACE(ddraw, "  Creating IDirectDraw2 interface (%p)\n", *obj);
		
		return S_OK;
	}
	if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
		LPDIRECT3D	d3d;

		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
		d3d->ref = 1;
		d3d->ddraw = (LPDIRECTDRAW)this;
		this->lpvtbl->fnAddRef(this);
		d3d->lpvtbl = &d3dvt;
		*obj = d3d;

		TRACE(ddraw, "  Creating IDirect3D interface (%p)\n", *obj);

		return S_OK;
	}
	if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
		LPDIRECT3D2	d3d;

		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
		d3d->ref = 1;
		d3d->ddraw = (LPDIRECTDRAW)this;
		this->lpvtbl->fnAddRef(this);
		d3d->lpvtbl = &d3d2vt;
		*obj = d3d;

		TRACE(ddraw, "  Creating IDirect3D2 interface (%p)\n", *obj);

		return S_OK;
	}
	WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
        return OLE_E_ENUM_NOMORE;
}

static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
	LPDIRECTDRAW2 this,BOOL32 *status
) {
        TRACE(ddraw,"(%p)->(%p)\n",this,status);
	*status = TRUE;
	return DD_OK;
}

static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
	LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
) {
	DDSURFACEDESC	ddsfd;
	static struct {
		int w,h;
	} modes[5] = { /* some of the usual modes */
		{512,384},
		{640,400},
		{640,480},
		{800,600},
		{1024,768},
	};
	static int depths[4] = {8,16,24,32};
	int	i,j;

	TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
	ddsfd.dwSize = sizeof(ddsfd);
	ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
	if (dwFlags & DDEDM_REFRESHRATES) {
		ddsfd.dwFlags |= DDSD_REFRESHRATE;
		ddsfd.x.dwRefreshRate = 60;
	}

	for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
		ddsfd.dwBackBufferCount = 1;
		ddsfd.ddpfPixelFormat.dwFourCC	= 0;
		ddsfd.ddpfPixelFormat.dwFlags 	= DDPF_RGB;
		ddsfd.ddpfPixelFormat.x.dwRGBBitCount	= depths[i];
		/* FIXME: those masks would have to be set in depth > 8 */
		if (depths[i]==8) {
		ddsfd.ddpfPixelFormat.y.dwRBitMask  	= 0;
		ddsfd.ddpfPixelFormat.z.dwGBitMask  	= 0;
		ddsfd.ddpfPixelFormat.xx.dwBBitMask 	= 0;
		ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
			ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
			ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
		} else {
		  ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
		  
		  /* FIXME: We should query those from X itself */
		  switch (depths[i]) {
		  case 16:
		    ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f;
		    ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0;
		    ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00;
		    break;
		  case 24:
		    ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
		    ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
		    ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
		    break;
		  case 32:
		    ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
		    ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
		    ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
		    break;
		  }
		}

		ddsfd.dwWidth = screenWidth;
		ddsfd.dwHeight = screenHeight;
		TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
		if (!modescb(&ddsfd,context)) return DD_OK;

		for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
			ddsfd.dwWidth	= modes[j].w;
			ddsfd.dwHeight	= modes[j].h;
			TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
			if (!modescb(&ddsfd,context)) return DD_OK;
		}

		if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
			/* modeX is not standard VGA */

			ddsfd.dwHeight = 200;
			ddsfd.dwWidth = 320;
			TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
			if (!modescb(&ddsfd,context)) return DD_OK;
		}
	}
	return DD_OK;
}

static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
) {
#ifdef HAVE_LIBXXF86DGA
	TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
	lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
	lpddsfd->dwHeight = screenHeight;
	lpddsfd->dwWidth = screenWidth;
	lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
	lpddsfd->dwBackBufferCount = 1;
	lpddsfd->x.dwRefreshRate = 60;
	lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
	_getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
	return DD_OK;
#else /* defined(HAVE_LIBXXF86DGA) */
	return E_UNEXPECTED;
#endif /* defined(HAVE_LIBXXF86DGA) */
}

static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
) {
	TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
	lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
	lpddsfd->dwHeight = screenHeight;
	lpddsfd->dwWidth = screenWidth;
	/* POOLE FIXME: Xlib */
	lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
	/* END FIXME: Xlib */
	lpddsfd->dwBackBufferCount = 1;
	lpddsfd->x.dwRefreshRate = 60;
	lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
	_getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
	return DD_OK;
}

static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
	TRACE(ddraw,"(%p)->()\n",this);
	return DD_OK;
}

static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
	LPDIRECTDRAW2 this,LPDWORD freq
) {
	FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
	*freq = 60*100; /* 60 Hz */
	return DD_OK;
}

/* what can we directly decompress? */
static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
	LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
) {
	FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
	return DD_OK;
}

static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
	LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
) {
  FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
  return DD_OK;
}

static HRESULT WINAPI IDirectDraw2_Compact(
          LPDIRECTDRAW2 this )
{
  FIXME(ddraw,"(%p)->()\n", this );
 
  return DD_OK;
}


/* Note: Hack so we can reuse the old functions without compiler warnings */
#ifdef __GNUC__
# define XCAST(fun)	(typeof(dga_ddvt.fn##fun))
#else
# define XCAST(fun)	(void*)
#endif

static struct IDirectDraw_VTable dga_ddvt = {
	XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
	XCAST(AddRef)IDirectDraw2_AddRef,
	XCAST(Release)DGA_IDirectDraw2_Release,
	XCAST(Compact)IDirectDraw2_Compact,
	XCAST(CreateClipper)IDirectDraw2_CreateClipper,
	XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
	XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
	XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
	XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
	XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
	XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
	XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
	XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
	XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
	XCAST(GetGDISurface)15,
	XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
	XCAST(GetScanLine)17,
	XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
	XCAST(Initialize)19,
	XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
	XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
	DGA_IDirectDraw_SetDisplayMode,
	XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
};

static struct IDirectDraw_VTable xlib_ddvt = {
	XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
	XCAST(AddRef)IDirectDraw2_AddRef,
	XCAST(Release)Xlib_IDirectDraw2_Release,
	XCAST(Compact)IDirectDraw2_Compact,
	XCAST(CreateClipper)IDirectDraw2_CreateClipper,
	XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
	XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
	XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
	XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
	XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
	XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
	XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
	XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
	XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
	XCAST(GetGDISurface)15,
	XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
	XCAST(GetScanLine)17,
	XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
	XCAST(Initialize)19,
	XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
	XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
	Xlib_IDirectDraw_SetDisplayMode,
	XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
};

/*****************************************************************************
 * 	IDirectDraw2
 *
 */


static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
	LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
) {
	return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
}

static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
	LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
) {
	return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
}

static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
	LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
) {
	TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
		this,ddscaps,total,free
	);
	if (total) *total = this->e.dga.fb_memsize * 1024;
	if (free) *free = this->e.dga.fb_memsize * 1024;
	return DD_OK;
}

static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
	LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
) {
	TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
		this,ddscaps,total,free
	);
	if (total) *total = 2048 * 1024;
	if (free) *free = 2048 * 1024;
	return DD_OK;
}

static IDirectDraw2_VTable dga_dd2vt = {
	DGA_IDirectDraw2_QueryInterface,
	IDirectDraw2_AddRef,
	DGA_IDirectDraw2_Release,
	IDirectDraw2_Compact,
	IDirectDraw2_CreateClipper,
	DGA_IDirectDraw2_CreatePalette,
	DGA_IDirectDraw2_CreateSurface,
	(void*)8,
	IDirectDraw2_EnumDisplayModes,
	IDirectDraw2_EnumSurfaces,
	IDirectDraw2_FlipToGDISurface,
	DGA_IDirectDraw2_GetCaps,
	DGA_IDirectDraw2_GetDisplayMode,
	IDirectDraw2_GetFourCCCodes,
	(void*)15,
	IDirectDraw2_GetMonitorFrequency,
	(void*)17,
	IDirectDraw2_GetVerticalBlankStatus,
	(void*)19,
	DGA_IDirectDraw2_RestoreDisplayMode,
	IDirectDraw2_SetCooperativeLevel,
	DGA_IDirectDraw2_SetDisplayMode,
	IDirectDraw2_WaitForVerticalBlank,
	DGA_IDirectDraw2_GetAvailableVidMem
};

static struct IDirectDraw2_VTable xlib_dd2vt = {
	Xlib_IDirectDraw2_QueryInterface,
	IDirectDraw2_AddRef,
	Xlib_IDirectDraw2_Release,
	IDirectDraw2_Compact,
	IDirectDraw2_CreateClipper,
	Xlib_IDirectDraw2_CreatePalette,
	Xlib_IDirectDraw2_CreateSurface,
	(void*)8,
	IDirectDraw2_EnumDisplayModes,
	IDirectDraw2_EnumSurfaces,
	IDirectDraw2_FlipToGDISurface,
	Xlib_IDirectDraw2_GetCaps,
	Xlib_IDirectDraw2_GetDisplayMode,
	IDirectDraw2_GetFourCCCodes,
	(void*)15,
	IDirectDraw2_GetMonitorFrequency,
	(void*)17,
	IDirectDraw2_GetVerticalBlankStatus,
	(void*)19,
	Xlib_IDirectDraw2_RestoreDisplayMode,
	IDirectDraw2_SetCooperativeLevel,
	Xlib_IDirectDraw2_SetDisplayMode,
	IDirectDraw2_WaitForVerticalBlank,
	Xlib_IDirectDraw2_GetAvailableVidMem	
};

/******************************************************************************
 * 				DirectDrawCreate
 */

LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
{
   LRESULT ret;
   LPDIRECTDRAW ddraw = NULL;
   DWORD lastError;

   /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */

   SetLastError( ERROR_SUCCESS );
   ddraw  = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
   if( (!ddraw)  &&
       ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
     ) 
   {
     ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
   }

   if( ddraw )
   {
      /* Perform any special direct draw functions */
      if (msg==WM_PAINT)
        ddraw->e.xlib.paintable = 1;

      /* Now let the application deal with the rest of this */
      if( ddraw->d.mainWindow )
      {
    
        /* Don't think that we actually need to call this but... 
           might as well be on the safe side of things... */

	/* I changed hwnd to ddraw->d.mainWindow as I did not see why
	   it should be the procedures of our fake window that gets called
	   instead of those of the window provided by the application.
	   And with this patch, mouse clicks work with Monkey Island III
	     - Lionel */
	ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );

        if( !ret )
        {
          /* We didn't handle the message - give it to the application */
	  if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
          	ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
               	                   ddraw->d.mainWindow, msg, wParam, lParam );
	  }
        }
        
      } else {
        ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
      } 

    }
    else
    {
	ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
    }

    return ret;
}

HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
#ifdef HAVE_LIBXXF86DGA
	int	memsize,banksize,width,major,minor,flags,height;
	char	*addr;
	int     fd;             	

        /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
        if ((fd = open("/dev/mem", O_RDWR)) != -1)
	  close(fd);
	
	if (fd  == -1) {
	  MSG("Must be able to access /dev/mem to use XF86DGA!\n");
	  MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
	  return E_UNEXPECTED;
	}
	if (!DDRAW_DGA_Available()) {
	        TRACE(ddraw,"No XF86DGA detected.\n");
	        return DDERR_GENERIC;
	}
	*lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
	(*lplpDD)->lpvtbl = &dga_ddvt;
	(*lplpDD)->ref = 1;
	TSXF86DGAQueryVersion(display,&major,&minor);
	TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
	TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
	if (!(flags & XF86DGADirectPresent))
		MSG("direct video is NOT PRESENT.\n");
	TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
	TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
		addr,width,banksize,memsize
	);
	(*lplpDD)->e.dga.fb_width = width;
	(*lplpDD)->d.width = width;
	(*lplpDD)->e.dga.fb_addr = addr;
	(*lplpDD)->e.dga.fb_memsize = memsize;
	(*lplpDD)->e.dga.fb_banksize = banksize;

	TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
	TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
	(*lplpDD)->e.dga.fb_height = screenHeight;
#ifdef DIABLO_HACK
	(*lplpDD)->e.dga.vpmask = 1;
#else
	(*lplpDD)->e.dga.vpmask = 0;
#endif

	/* just assume the default depth is the DGA depth too */
	(*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
#ifdef RESTORE_SIGNALS
	SIGNAL_InitEmulator();
#endif

	return DD_OK;
#else /* defined(HAVE_LIBXXF86DGA) */
	return DDERR_INVALIDDIRECTDRAWGUID;
#endif /* defined(HAVE_LIBXXF86DGA) */
}

BOOL32
DDRAW_XSHM_Available()
   {
#ifdef HAVE_LIBXXSHM
  if (TSXShmQueryExtension(display))
      {
      int major, minor;
      Bool shpix;

      if (TSXShmQueryVersion(display, &major, &minor, &shpix))
	return 1;
      else
	return 0;
    }
    else
    return 0;
#else
  return 0;
#endif
}

HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {

	*lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
	(*lplpDD)->lpvtbl = &xlib_ddvt;
	(*lplpDD)->ref = 1;
	(*lplpDD)->d.drawable = 0; /* in SetDisplayMode */

	(*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
	(*lplpDD)->d.height = screenHeight;
	(*lplpDD)->d.width = screenWidth;

#ifdef HAVE_LIBXXSHM
	/* Test if XShm is available.
	   As XShm is not ready yet for 'prime-time', it is disabled for now */
	if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */))
	  TRACE(ddraw, "Using XShm extesion.\n");
#endif
	
	return DD_OK;
}

HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
	char	xclsid[50];
	WNDCLASS32A	wc;
        WND*            pParentWindow; 
	HRESULT ret;

	if (HIWORD(lpGUID))
		WINE_StringFromCLSID(lpGUID,xclsid);
	else {
		sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
		lpGUID = NULL;
	}

	TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);

	if (!lpGUID) {
		/* if they didn't request a particular interface, use the best
		 * supported one */
		if (DDRAW_DGA_Available())
			lpGUID = &DGA_DirectDraw_GUID;
		else
			lpGUID = &XLIB_DirectDraw_GUID;
	}

	wc.style	= CS_GLOBALCLASS;
	wc.lpfnWndProc	= Xlib_DDWndProc;
	wc.cbClsExtra	= 0;
	wc.cbWndExtra	= /* Defines extra mem for window. This is used for storing this */
                          sizeof( LPDIRECTDRAW ); /*  ddrawXlibThisOffset */

        /* We can be a child of the desktop since we're really important */
        pParentWindow   = WIN_GetDesktop();
	wc.hInstance	= pParentWindow ? pParentWindow->hwndSelf : 0;
        wc.hInstance    = 0; 

	wc.hIcon	= 0;
	wc.hCursor	= (HCURSOR32)IDC_ARROW32A;
	wc.hbrBackground= NULL_BRUSH;
	wc.lpszMenuName	= 0;
	wc.lpszClassName= "WINE_DirectDraw";
	RegisterClass32A(&wc);

	if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
		ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
	else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
		ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
	else
	  goto err;

	(*lplpDD)->d.winclass = RegisterClass32A(&wc);
	return ret;

      err:
	fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
	return DDERR_INVALIDDIRECTDRAWGUID;
}
