/*		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"

#ifndef X_DISPLAY_MISSING 

#include "ts_xlib.h"
#include "ts_xutil.h"

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

#ifdef HAVE_LIBXXF86DGA
#include "ts_xf86dga.h"
#endif /* defined(HAVE_LIBXXF86DGA) */

#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
typedef int INT32;
#include "ts_xf86vmode.h"
#endif /* defined(HAVE_LIBXXF86VM) */

#include "x11drv.h"

#include <unistd.h>
#include <assert.h>
#include <sys/signal.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

#include "winerror.h"
#include "gdi.h"
#include "heap.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 "options.h"
#include "monitor.h"

/* 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 
 */
#define 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 IDirectDrawSurface4_VTable	dga_dds4vt, xlib_dds4vt;
static struct IDirectDraw_VTable		dga_ddvt, xlib_ddvt;
static struct IDirectDraw2_VTable		dga_dd2vt, xlib_dd2vt;
static struct IDirectDraw4_VTable		dga_dd4vt, xlib_dd4vt;
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

#ifdef HAVE_LIBXXSHM
static int XShmErrorFlag = 0;
#endif

BOOL
DDRAW_DGA_Available(void)
{
#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) */
}

/**********************************************************************/

typedef struct {
  LPVOID lpCallback;
  LPVOID lpContext; 
} DirectDrawEnumerateProcData;

/***********************************************************************
 *		DirectDrawEnumerateExA (DDRAW.*)
 */
HRESULT WINAPI DirectDrawEnumerateExA(
  LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
{
  TRACE(ddraw, "(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
  
  if (TRACE_ON(ddraw)) {
    DUMP("  Flags : ");
    if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
      DUMP("DDENUM_ATTACHEDSECONDARYDEVICES ");
    if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
      DUMP("DDENUM_DETACHEDSECONDARYDEVICES ");
    if (dwFlags & DDENUM_NONDISPLAYDEVICES)
      DUMP("DDENUM_NONDISPLAYDEVICES ");
    DUMP("\n");
  }

  if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
    /* For the moment, Wine does not support any 3D only accelerators */
    return DD_OK;
  }
  
  if (DDRAW_DGA_Available()) {
    TRACE(ddraw, "Enumerating DGA interface\n");
    if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, NULL))
      return DD_OK;
  }

  TRACE(ddraw, "Enumerating Xlib interface\n");
  if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, NULL))
    return DD_OK;
  
  TRACE(ddraw, "Enumerating Default interface\n");
  if (!lpCallback(NULL,"WINE (default)", "display", lpContext, NULL))
    return DD_OK;
  
  return DD_OK;
}

/***********************************************************************
 *		DirectDrawEnumerateExW (DDRAW.*)
 */

static BOOL DirectDrawEnumerateExProcW(
	GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, 
	LPVOID lpContext, HMONITOR hm)
{
  DirectDrawEnumerateProcData *pEPD =
    (DirectDrawEnumerateProcData *) lpContext;
  LPWSTR lpDriverDescriptionW =
    HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
  LPWSTR lpDriverNameW =
    HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);

  BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
    lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);

  HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
  HeapFree(GetProcessHeap(), 0, lpDriverNameW);

  return bResult;
}

/**********************************************************************/

HRESULT WINAPI DirectDrawEnumerateExW(
  LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
{
  DirectDrawEnumerateProcData epd;
  epd.lpCallback = lpCallback;
  epd.lpContext = lpContext;

  return DirectDrawEnumerateExA(&DirectDrawEnumerateExProcW, 
				  (LPVOID) &epd, 0);
}

/***********************************************************************
 *		DirectDrawEnumerateA (DDRAW.*)
 */

static BOOL DirectDrawEnumerateProcA(
	GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, 
	LPVOID lpContext, HMONITOR hm)
{
  DirectDrawEnumerateProcData *pEPD = 
    (DirectDrawEnumerateProcData *) lpContext;
  
  return (*(LPDDENUMCALLBACKA *) pEPD->lpCallback)(
    lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
}

/**********************************************************************/

HRESULT WINAPI DirectDrawEnumerateA(
  LPDDENUMCALLBACKA lpCallback, LPVOID lpContext) 
{
  DirectDrawEnumerateProcData epd;  
  epd.lpCallback = lpCallback;
  epd.lpContext = lpContext;

  return DirectDrawEnumerateExA(&DirectDrawEnumerateProcA, 
				(LPVOID) &epd, 0);
}

/***********************************************************************
 *		DirectDrawEnumerateW (DDRAW.*)
 */

static BOOL DirectDrawEnumerateProcW(
  GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName, 
  LPVOID lpContext, HMONITOR hm)
{
  DirectDrawEnumerateProcData *pEPD = 
    (DirectDrawEnumerateProcData *) lpContext;
  
  return (*(LPDDENUMCALLBACKW *) pEPD->lpCallback)(
    lpGUID, lpDriverDescription, lpDriverName, 
    pEPD->lpContext);
}

/**********************************************************************/

HRESULT WINAPI DirectDrawEnumerateW(
  LPDDENUMCALLBACKW lpCallback, LPVOID lpContext) 
{
  DirectDrawEnumerateProcData epd;  
  epd.lpCallback = lpCallback;
  epd.lpContext = lpContext;

  return DirectDrawEnumerateExW(&DirectDrawEnumerateProcW, 
				(LPVOID) &epd, 0);
}

/***********************************************************************
 *		DSoundHelp (DDRAW.?)
 */

/* 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);
	DUMP("\n");
}

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_paletteformat(DWORD dwFlags) {
  int	i;
  const struct {
    DWORD	mask;
    char	*name;
  } flags[] = {
#define FE(x) { x, #x},
    FE(DDPCAPS_4BIT)
    FE(DDPCAPS_8BITENTRIES)
    FE(DDPCAPS_8BIT)
    FE(DDPCAPS_INITIALIZE)
    FE(DDPCAPS_PRIMARYSURFACE)
    FE(DDPCAPS_PRIMARYSURFACELEFT)
    FE(DDPCAPS_ALLOW256)
    FE(DDPCAPS_VSYNC)
    FE(DDPCAPS_1BIT)
    FE(DDPCAPS_2BIT)
    FE(DDPCAPS_ALPHA)
  };
  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
    if (flags[i].mask & dwFlags)
      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);
}

/******************************************************************************
 *		IDirectDrawSurface methods
 *
 * 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 IDirectDrawSurface4_Lock(
    LPDIRECTDRAWSURFACE4 this,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE 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;
	TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
	      lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);

	/* 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_IDirectDrawSurface4_Unlock(
	LPDIRECTDRAWSURFACE4 this,LPVOID surface
) {
	TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
	return DD_OK;
}

static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE4 this) {
  if (this->s.ddraw->d.pixel_convert != NULL)
    this->s.ddraw->d.pixel_convert(this->s.surface_desc.y.lpSurface,
				   this->t.xlib.image->data,
				   this->s.surface_desc.dwWidth,
				   this->s.surface_desc.dwHeight,
				   this->s.surface_desc.lPitch,
				   this->s.palette);

#ifdef HAVE_LIBXXSHM
    if (this->s.ddraw->e.xlib.xshm_active)
      TSXShmPutImage(display,
		     this->s.ddraw->d.drawable,
		     DefaultGCOfScreen(X11DRV_GetXScreen()),
		     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(X11DRV_GetXScreen()),
				this->t.xlib.image,
				0, 0, 0, 0,
				this->t.xlib.image->width,
		  this->t.xlib.image->height);
}

static HRESULT WINAPI Xlib_IDirectDrawSurface4_Unlock(
	LPDIRECTDRAWSURFACE4 this,LPVOID surface)
{
	TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
  
	if (!this->s.ddraw->d.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)) {
	  Xlib_copy_surface_on_screen(this);
	  
	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_IDirectDrawSurface4_Flip(
	LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 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_IDirectDrawSurface4_Flip(
	LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
) {
	TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
	if (!this->s.ddraw->d.paintable)
		return DD_OK;

	if (!flipto) {
		if (this->s.backbuffer)
			flipto = this->s.backbuffer;
		else
			flipto = this;
	}
  
	Xlib_copy_surface_on_screen(this);
	
	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 IDirectDrawSurface4::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_IDirectDrawSurface4_SetPalette(
	LPDIRECTDRAWSURFACE4 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.screen_pixelformat.x.dwRGBBitCount<=8)) 
	{
		pal->cm = TSXCreateColormap(display,this->s.ddraw->d.drawable,
					    DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);

    	    	if (!Options.managed)
			TSXInstallColormap(display,pal->cm);

		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);
		}
		TSXInstallColormap(display,pal->cm);
        }

        /* 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_IDirectDrawSurface4_SetPalette(
	LPDIRECTDRAWSURFACE4 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 IDirectDrawSurface4_Blt(
	LPDIRECTDRAWSURFACE4 this,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
) {
	RECT	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);
	  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 */
	
	/* First, all the 'source-less' blits */
	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 (dwFlags & DDBLT_DEPTHFILL) {
#ifdef HAVE_MESAGL
	  GLboolean ztest;
	  
	  /* Clears the screen */
	  TRACE(ddraw, "	Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
	  glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
	  glGetBooleanv(GL_DEPTH_TEST, &ztest);
	  glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
	  glClear(GL_DEPTH_BUFFER_BIT);
	  glDepthMask(ztest);
	  
	  dwFlags &= ~(DDBLT_DEPTHFILL);
#endif HAVE_MESAGL
	}
	
	if (!src) {
	    if (dwFlags) {
	      TRACE(ddraw,"\t(src=NULL):Unsupported flags: "); _dump_DDBLT(dwFlags);
	    }
	    this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
	    return DD_OK;
	}

	/* Now the 'with source' blits */

	/* Standard 'full-surface' blit without special effects */
	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 640x480 */
	    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 */
	      if(dwFlags & DDBLT_KEYSRC) {
		for (y = xdst.top; y < xdst.bottom; y++) {
		  for (x = xdst.left; x < xdst.right; x++) {
		    double sx, sy;
		    unsigned char tmp;
		    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;

		    tmp = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
		    
		    if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
		      dbuf[(y * ddesc.lPitch) + x] = tmp;
		  }
		}
	      } else {
	      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 */
	    if (dwFlags & DDBLT_KEYSRC) {
	      switch (bpp) {
	      case 1: {
		unsigned char tmp,*psrc,*pdst;
		int h,i;
		
	    for (h = 0; h < srcheight; h++) {
		  psrc=sdesc.y.lpSurface +
		    ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
		  pdst=ddesc.y.lpSurface +
		    ((h + xdst.top) * ddesc.lPitch) + xdst.left;
		  for(i=0;i<srcwidth;i++) {
		    tmp=*(psrc + i);
		    if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
		      *(pdst + i)=tmp;
		  }
		}
		dwFlags&=~(DDBLT_KEYSRC);
	      } break;
		
	      case 2: {
		unsigned short tmp,*psrc,*pdst;
		int h,i;
		
		for (h = 0; h < srcheight; h++) {
		  psrc=sdesc.y.lpSurface +
		    ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
		  pdst=ddesc.y.lpSurface +
		    ((h + xdst.top) * ddesc.lPitch) + xdst.left;
		  for(i=0;i<srcwidth;i++) {
		    tmp=*(psrc + i);
		    if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
		      *(pdst + i)=tmp;
		  }
		}
		dwFlags&=~(DDBLT_KEYSRC);
	      } break;
		
	      default:
		FIXME(ddraw, "Bitblt, KEYSRC: Not done yet for depth > 16\n");
	      }
	    } else {
	      /* Non-stretching Blt without color keying */
	      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 IDirectDrawSurface4_BltFast(
	LPDIRECTDRAWSURFACE4 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT 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:");
	    if (FIXME_ON(ddraw))
	      _dump_DDBLTFAST(trans);
	    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 IDirectDrawSurface4_BltBatch(
	LPDIRECTDRAWSURFACE4 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 IDirectDrawSurface4_GetCaps(
	LPDIRECTDRAWSURFACE4 this,LPDDSCAPS caps
) {
	TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
	caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4_GetSurfaceDesc(
	LPDIRECTDRAWSURFACE4 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)) {
    DUMP("   flags: ");
		_dump_DDSD(ddsd->dwFlags);
    if (ddsd->dwFlags & DDSD_CAPS) {
      DUMP("   caps:  ");
      _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
    }
    if (ddsd->dwFlags & DDSD_PIXELFORMAT) {
      DUMP("   pixel format : \n");
      _dump_pixelformat(&(ddsd->ddpfPixelFormat));
    }
	}

	return DD_OK;
}

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

	return ++(this->ref);
}

static ULONG WINAPI DGA_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 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));
		}

		/* Free the backbuffer */
		if (this->s.backbuffer)
			this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);

		HeapFree(GetProcessHeap(),0,this);
		return 0;
	}
#endif /* defined(HAVE_LIBXXF86DGA) */
	return this->ref;
}

static ULONG WINAPI Xlib_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 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) {
      if (this->s.ddraw->d.pixel_convert != NULL) {
	/* In pixel conversion mode, there are two buffers to release... */
	HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
	
#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->t.xlib.image->data);
	  this->t.xlib.image->data = NULL;
	  TSXDestroyImage(this->t.xlib.image);
#ifdef HAVE_LIBXXSHM
	}
#endif
	
      } else {
		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 IDirectDrawSurface4_GetAttachedSurface(
	LPDIRECTDRAWSURFACE4 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *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 IDirectDrawSurface4_Initialize(
	LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
) {
	TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);

	return DDERR_ALREADYINITIALIZED;
}

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

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

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

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

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

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

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

static HRESULT WINAPI IDirectDrawSurface4_GetDC(LPDIRECTDRAWSURFACE4 this,HDC* lphdc) {
	FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
	*lphdc = BeginPaint(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4_ReleaseDC(LPDIRECTDRAWSURFACE4 this,HDC hdc) {
  	DDSURFACEDESC	desc;
	DWORD x, y;
	
	FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
	EndPaint(this->s.ddraw->d.window,&this->s.ddraw->d.ps);

	/* Well, as what the application did paint in this DC is NOT saved in the surface,
	   I fill it with 'dummy' values to have something on the screen */
	this->lpvtbl->fnLock(this,NULL,&desc,0,0);
	for (y = 0; y < desc.dwHeight; y++) {
	  for (x = 0; x < desc.dwWidth; x++) {
	    ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) this + x + y;
	  }
	}
	this->lpvtbl->fnUnlock(this,NULL);
	
	return DD_OK;
}


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

        WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
        TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
	
	/* All DirectDrawSurface versions (1, 2, 3 and 4) use
	 * the same interface. And IUnknown does that too of course.
	 */
	if (    !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID))	||
	        !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 IDirectDrawSurface 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 IDirectDrawSurface4_IsLost(LPDIRECTDRAWSURFACE4 this) {
	TRACE(ddraw,"(%p)->(), stub!\n",this);
	return DD_OK; /* hmm */
}

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

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

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

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

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

        if( dwFlags & DDCKEY_SRCOVERLAY )
        {
           dwFlags &= ~DDCKEY_SRCOVERLAY;
	   this->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
           memcpy( &(this->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );	   
        }
	
        if( dwFlags & DDCKEY_DESTOVERLAY )
        {
           dwFlags &= ~DDCKEY_DESTOVERLAY;
	   this->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
           memcpy( &(this->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );	   
        }

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

        return DD_OK;

}

static HRESULT WINAPI IDirectDrawSurface4_AddOverlayDirtyRect(
        LPDIRECTDRAWSURFACE4 this, 
        LPRECT lpRect )
{
  FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect); 

  return DD_OK;
}

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

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4_EnumOverlayZOrders(
        LPDIRECTDRAWSURFACE4 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 IDirectDrawSurface4_GetClipper(
        LPDIRECTDRAWSURFACE4 this,
        LPDIRECTDRAWCLIPPER* lplpDDClipper )
{
  FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4_GetColorKey(
        LPDIRECTDRAWSURFACE4 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.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
  }

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

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

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

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

  return DD_OK;
}

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

  return DD_OK;
}

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

  return DD_OK;
}

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

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlay(
        LPDIRECTDRAWSURFACE4 this,
        LPRECT lpSrcRect,
        LPDIRECTDRAWSURFACE4 lpDDDestSurface,
        LPRECT 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 IDirectDrawSurface4_UpdateOverlayDisplay(
        LPDIRECTDRAWSURFACE4 this,
        DWORD dwFlags )
{
  FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags); 

  return DD_OK;
}

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

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4_GetDDInterface(
        LPDIRECTDRAWSURFACE4 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 IDirectDrawSurface4_PageLock(
        LPDIRECTDRAWSURFACE4 this,
        DWORD dwFlags )
{
  FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);

  return DD_OK;
}

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

  return DD_OK;
}

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

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4_SetPrivateData(LPDIRECTDRAWSURFACE4 this,
							 REFGUID guidTag,
							 LPVOID lpData,
							 DWORD cbSize,
							 DWORD dwFlags) {
  FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", this, guidTag, lpData, cbSize, dwFlags);
  
  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4_GetPrivateData(LPDIRECTDRAWSURFACE4 this,
							 REFGUID guidTag,
							 LPVOID lpBuffer,
							 LPDWORD lpcbBufferSize) {
  FIXME(ddraw, "(%p)->(%p,%p,%p)\n", this, guidTag, lpBuffer, lpcbBufferSize);
  
  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4_FreePrivateData(LPDIRECTDRAWSURFACE4 this,
							  REFGUID guidTag)  {
  FIXME(ddraw, "(%p)->(%p)\n", this, guidTag);
  
  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4_GetUniquenessValue(LPDIRECTDRAWSURFACE4 this,
							     LPDWORD lpValue)  {
  FIXME(ddraw, "(%p)->(%p)\n", this, lpValue);
  
  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 this) {
  FIXME(ddraw, "(%p)\n", this);
  
  return DD_OK;
}

static struct IDirectDrawSurface4_VTable dga_dds4vt = {
	IDirectDrawSurface4_QueryInterface,
	IDirectDrawSurface4_AddRef,
	DGA_IDirectDrawSurface4_Release,
	IDirectDrawSurface4_AddAttachedSurface,
	IDirectDrawSurface4_AddOverlayDirtyRect,
	IDirectDrawSurface4_Blt,
	IDirectDrawSurface4_BltBatch,
	IDirectDrawSurface4_BltFast,
	IDirectDrawSurface4_DeleteAttachedSurface,
	IDirectDrawSurface4_EnumAttachedSurfaces,
	IDirectDrawSurface4_EnumOverlayZOrders,
	DGA_IDirectDrawSurface4_Flip,
	IDirectDrawSurface4_GetAttachedSurface,
	IDirectDrawSurface4_GetBltStatus,
	IDirectDrawSurface4_GetCaps,
	IDirectDrawSurface4_GetClipper,
	IDirectDrawSurface4_GetColorKey,
	IDirectDrawSurface4_GetDC,
	IDirectDrawSurface4_GetFlipStatus,
	IDirectDrawSurface4_GetOverlayPosition,
	IDirectDrawSurface4_GetPalette,
	IDirectDrawSurface4_GetPixelFormat,
	IDirectDrawSurface4_GetSurfaceDesc,
	IDirectDrawSurface4_Initialize,
	IDirectDrawSurface4_IsLost,
	IDirectDrawSurface4_Lock,
	IDirectDrawSurface4_ReleaseDC,
	IDirectDrawSurface4_Restore,
	IDirectDrawSurface4_SetClipper,
	IDirectDrawSurface4_SetColorKey,
	IDirectDrawSurface4_SetOverlayPosition,
	DGA_IDirectDrawSurface4_SetPalette,
	DGA_IDirectDrawSurface4_Unlock,
	IDirectDrawSurface4_UpdateOverlay,
	IDirectDrawSurface4_UpdateOverlayDisplay,
	IDirectDrawSurface4_UpdateOverlayZOrder,
	IDirectDrawSurface4_GetDDInterface,
	IDirectDrawSurface4_PageLock,
	IDirectDrawSurface4_PageUnlock,
	IDirectDrawSurface4_SetSurfaceDesc,
	IDirectDrawSurface4_SetPrivateData,
	IDirectDrawSurface4_GetPrivateData,
	IDirectDrawSurface4_FreePrivateData,
	IDirectDrawSurface4_GetUniquenessValue,
	IDirectDrawSurface4_ChangeUniquenessValue
};

static struct IDirectDrawSurface4_VTable xlib_dds4vt = {
	IDirectDrawSurface4_QueryInterface,
	IDirectDrawSurface4_AddRef,
	Xlib_IDirectDrawSurface4_Release,
	IDirectDrawSurface4_AddAttachedSurface,
	IDirectDrawSurface4_AddOverlayDirtyRect,
	IDirectDrawSurface4_Blt,
	IDirectDrawSurface4_BltBatch,
	IDirectDrawSurface4_BltFast,
	IDirectDrawSurface4_DeleteAttachedSurface,
	IDirectDrawSurface4_EnumAttachedSurfaces,
	IDirectDrawSurface4_EnumOverlayZOrders,
	Xlib_IDirectDrawSurface4_Flip,
	IDirectDrawSurface4_GetAttachedSurface,
	IDirectDrawSurface4_GetBltStatus,
	IDirectDrawSurface4_GetCaps,
	IDirectDrawSurface4_GetClipper,
	IDirectDrawSurface4_GetColorKey,
	IDirectDrawSurface4_GetDC,
	IDirectDrawSurface4_GetFlipStatus,
	IDirectDrawSurface4_GetOverlayPosition,
	IDirectDrawSurface4_GetPalette,
	IDirectDrawSurface4_GetPixelFormat,
	IDirectDrawSurface4_GetSurfaceDesc,
	IDirectDrawSurface4_Initialize,
	IDirectDrawSurface4_IsLost,
	IDirectDrawSurface4_Lock,
	IDirectDrawSurface4_ReleaseDC,
	IDirectDrawSurface4_Restore,
	IDirectDrawSurface4_SetClipper,
	IDirectDrawSurface4_SetColorKey,
	IDirectDrawSurface4_SetOverlayPosition,
	Xlib_IDirectDrawSurface4_SetPalette,
	Xlib_IDirectDrawSurface4_Unlock,
	IDirectDrawSurface4_UpdateOverlay,
	IDirectDrawSurface4_UpdateOverlayDisplay,
	IDirectDrawSurface4_UpdateOverlayZOrder,
	IDirectDrawSurface4_GetDDInterface,
	IDirectDrawSurface4_PageLock,
	IDirectDrawSurface4_PageUnlock,
	IDirectDrawSurface4_SetSurfaceDesc,
	IDirectDrawSurface4_SetPrivateData,
	IDirectDrawSurface4_GetPrivateData,
	IDirectDrawSurface4_FreePrivateData,
	IDirectDrawSurface4_GetUniquenessValue,
	IDirectDrawSurface4_ChangeUniquenessValue
};

/******************************************************************************
 *			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,HWND 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,LPRECT 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,
         HWND* 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,
         BOOL* 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;
	}

	/* Now, if we are in 'depth conversion mode', update the screen palette */
	if (this->ddraw->d.palette_convert != NULL)
	  this->ddraw->d.palette_convert(palent, this->screen_palents, start, count);
	  
	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_IDirect3D2))) {
                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 INT 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 */
    TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
    bpp = lpddsd->x.dwZBufferBitDepth / 8;
  } else {
    /* This is a standard image */
  if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
    /* No pixel format => use DirectDraw's format */
    lpddsd->ddpfPixelFormat = this->d.directdraw_pixelformat;
    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);
		DUMP("   caps ");
		_dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
	}

	*lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
	this->lpvtbl->fnAddRef(this);
        
	(*lpdsf)->ref = 1;
	(*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds4vt;
	(*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.directdraw_pixelformat.x.dwRGBBitCount/8);
		(*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
	  (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/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|DDSD_PIXELFORMAT;
	  (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
	  (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
	  TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",this->d.width,this->d.height,lpddsd->lPitch);
	  /* We put our surface always in video memory */
	  (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
	  (*lpdsf)->s.surface_desc.ddpfPixelFormat = this->d.directdraw_pixelformat;
	(*lpdsf)->s.backbuffer = NULL;
	  
	if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
		LPDIRECTDRAWSURFACE4	back;

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

	    (*lpdsf)->s.backbuffer = back =
	      (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
		this->lpvtbl->fnAddRef(this);
		back->ref = 1;
		back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&dga_dds4vt;
		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.directdraw_pixelformat.x.dwRGBBitCount/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;
	    back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
	  }
	} 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) */
}

#ifdef HAVE_LIBXXSHM
/* Error handlers for Image creation */
static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
  XShmErrorFlag = 1;
  return 0;
}

static XImage *create_xshmimage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
  XImage *img;
  int (*WineXHandler)(Display *, XErrorEvent *);

    img = TSXShmCreateImage(display,
			    DefaultVisualOfScreen(X11DRV_GetXScreen()),
			    this->d.pixmap_depth,
			    ZPixmap,
			    NULL,
			    &(lpdsf->t.xlib.shminfo),
			    lpdsf->s.surface_desc.dwWidth,
			    lpdsf->s.surface_desc.dwHeight);
    
  if (img == NULL) {
    MSG("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
    this->e.xlib.xshm_active = 0;
      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) {
    MSG("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
    this->e.xlib.xshm_active = 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) {
    MSG("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
    this->e.xlib.xshm_active = 0;
      TSXDestroyImage(img);
      shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
      return NULL;
    }
    lpdsf->t.xlib.shminfo.readOnly = False;
      
  /* This is where things start to get trickier....
     First, we flush the current X connections to be sure to catch all non-XShm related
     errors */
    TSXSync(display, False);
  /* Then we enter in the non-thread safe part of the tests */
  EnterCriticalSection( &X11DRV_CritSection );
  
  /* Reset the error flag, sets our new error handler and try to attach the surface */
  XShmErrorFlag = 0;
  WineXHandler = XSetErrorHandler(XShmErrorHandler);
  XShmAttach(display, &(lpdsf->t.xlib.shminfo));
  XSync(display, False);

  /* Check the error flag */
  if (XShmErrorFlag) {
    /* An error occured */
    XFlush(display);
    XShmErrorFlag = 0;
    XDestroyImage(img);
    shmdt(lpdsf->t.xlib.shminfo.shmaddr);
    shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
    XSetErrorHandler(WineXHandler);

    MSG("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
    this->e.xlib.xshm_active = 0;
    
    /* Leave the critical section */
    LeaveCriticalSection( &X11DRV_CritSection );

    return NULL;
  }

  /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
     but it may be a bit overkill.... */
  XSetErrorHandler(WineXHandler);
  LeaveCriticalSection( &X11DRV_CritSection );
  
    shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);

    if (this->d.pixel_convert != NULL) {
      lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
						    lpdsf->s.surface_desc.dwWidth *
						    lpdsf->s.surface_desc.dwHeight *
						    (this->d.directdraw_pixelformat.x.dwRGBBitCount));
    } else {
    lpdsf->s.surface_desc.y.lpSurface = img->data;
    }

  return img;
}
#endif /* HAVE_LIBXXSHM */

static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
  XImage *img = NULL;
  void *img_data;

#ifdef HAVE_LIBXXSHM
  if (this->e.xlib.xshm_active) {
    img = create_xshmimage(this, lpdsf);
  }
    
  if (img == NULL) {
#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.directdraw_pixelformat.x.dwRGBBitCount / 8));
    
    if (this->d.pixel_convert != NULL) {
      img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
			   lpdsf->s.surface_desc.dwWidth *
			   lpdsf->s.surface_desc.dwHeight *
			   (this->d.screen_pixelformat.x.dwRGBBitCount / 8));
    } else {
      img_data = lpdsf->s.surface_desc.y.lpSurface;
    }
      
    /* In this case, create an XImage */
    img =
      TSXCreateImage(display,
		     DefaultVisualOfScreen(X11DRV_GetXScreen()),
		     this->d.pixmap_depth,
		     ZPixmap,
		     0,
		     img_data,
		     lpdsf->s.surface_desc.dwWidth,
		     lpdsf->s.surface_desc.dwHeight,
		     32,
		     lpdsf->s.surface_desc.dwWidth * (this->d.screen_pixelformat.x.dwRGBBitCount / 8)
		     );
    
#ifdef HAVE_LIBXXSHM
  }
#endif
  if (this->d.pixel_convert != NULL) {
    lpdsf->s.surface_desc.lPitch = (this->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
  } else {
  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)) {
		DUMP("   w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
		_dump_DDSD(lpddsd->dwFlags);
		DUMP("   caps ");
		_dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
	}

	*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_dds4vt;
	(*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, (LPDIRECTDRAWSURFACE4) *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|DDSD_PIXELFORMAT;
	  (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
	  (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
	  (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
	  (*lpdsf)->s.surface_desc.ddpfPixelFormat = this->d.directdraw_pixelformat;
	  (*lpdsf)->s.backbuffer = NULL;
    
    /* Check for backbuffers */
	if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
		LPDIRECTDRAWSURFACE4	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 =
	(LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));

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

		back->ref = 1;
		back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&xlib_dds4vt;
	    /* 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;
	    back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
	}
	} 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,HWND 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_GetXWindow(WIN_FindWndPtr(hwnd));

	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) {
	RECT	rect;

	/* Do not destroy the application supplied cooperative window */
	if (this->d.window && this->d.window != this->d.mainWindow) {
		DestroyWindow(this->d.window);
		this->d.window = 0;
	}
	/* Sanity check cooperative window before assigning it to drawing. */
	if (	IsWindow(this->d.mainWindow) &&
		IsWindowVisible(this->d.mainWindow)
	) {
		GetWindowRect(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 = CreateWindowExA(
		    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*/
	    SetWindowLongA(this->d.window,ddrawXlibThisOffset,(LONG)this);
	    ShowWindow(this->d.window,TRUE);
	    UpdateWindow(this->d.window);
	}
	SetFocus(this->d.window);
}

static int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat, DDPIXELFORMAT *screen_pixelformat, int *pix_depth) {
  XVisualInfo *vi;
  XPixmapFormatValues *pf;
  XVisualInfo vt;
  int nvisuals, npixmap, i;
  int match = 0;

  vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
  pf = XListPixmapFormats(display, &npixmap);
  
  for (i = 0; i < npixmap; i++) {
    if (pf[i].bits_per_pixel == depth) {
      int j;
      
      for (j = 0; j < nvisuals; j++) {
	if (vi[j].depth == pf[i].depth) {
	  pixelformat->dwSize = sizeof(*pixelformat);
	  if (depth == 8) {
	    pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
	    pixelformat->y.dwRBitMask = 0;
	    pixelformat->z.dwGBitMask = 0;
	    pixelformat->xx.dwBBitMask = 0;
	  } else {
	    pixelformat->dwFlags = DDPF_RGB;
	    pixelformat->y.dwRBitMask = vi[j].red_mask;
	    pixelformat->z.dwGBitMask = vi[j].green_mask;
	    pixelformat->xx.dwBBitMask = vi[j].blue_mask;
	  }
	  pixelformat->dwFourCC = 0;
	  pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
	  pixelformat->xy.dwRGBAlphaBitMask= 0;

	  *screen_pixelformat = *pixelformat;
	  
	  if (pix_depth != NULL)
	    *pix_depth = vi[j].depth;
	  
	  match = 1;
	  
	  break;
	}
      }

      if (j == nvisuals)
	ERR(ddraw, "No visual corresponding to pixmap format !\n");
    }
  }

  if ((match == 0) && (depth == 8)) {
    pixelformat->dwSize = sizeof(*pixelformat);
    pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
    pixelformat->dwFourCC = 0;
    pixelformat->x.dwRGBBitCount = 8;
    pixelformat->y.dwRBitMask = 0;
    pixelformat->z.dwGBitMask = 0;
    pixelformat->xx.dwBBitMask = 0;
    pixelformat->xy.dwRGBAlphaBitMask= 0;    
    
    /* In that case, find a visual to emulate the 8 bpp format */
    for (i = 0; i < npixmap; i++) {
      if (pf[i].bits_per_pixel >= depth) {
	int j;
	
	for (j = 0; j < nvisuals; j++) {
	  if (vi[j].depth == pf[i].depth) {
	    screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
	    screen_pixelformat->dwFlags = DDPF_RGB;
	    screen_pixelformat->dwFourCC = 0;
	    screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
	    screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
	    screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
	    screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
	    screen_pixelformat->xy.dwRGBAlphaBitMask= 0;

	    if (pix_depth != NULL)
	      *pix_depth = vi[j].depth;
	    
	    match = 2;
	    
	    break;
	  }
	}
	
	if (j == nvisuals)
	  ERR(ddraw, "No visual corresponding to pixmap format !\n");
      }
    }
  }
  
  TSXFree(vi);
  TSXFree(pf);

  return match;
}

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

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

	/* We hope getting the asked for depth */
	if (_common_depth_to_pixelformat(depth, &(this->d.directdraw_pixelformat), &(this->d.screen_pixelformat), NULL) != 1) {
	  /* I.e. no visual found or emulated */
		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;

	/* 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);
            }
	    for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
            TSXFree(all_modes);

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

            if (vidmode)
	      {
	        TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
                TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
#if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
		TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
#endif
	      }
        }
#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);
#else
	TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
#endif

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

/* *************************************
      16 / 15 bpp to palettized 8 bpp
   ************************************* */
static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, LPDIRECTDRAWPALETTE palette) {
  unsigned char  *c_src = (unsigned char  *) src;
  unsigned short *c_dst = (unsigned short *) dst;
  int x, y;

  if (palette != NULL) {
    unsigned short *pal = (unsigned short *) palette->screen_palents;

    for (y = 0; y < height; y++) {
      for (x = 0; x < width; x++) {
	c_dst[x + y * width] = pal[c_src[x + y * pitch]];
      }
    }
  } else {
    WARN(ddraw, "No palette set...\n");
    memset(dst, 0, width * height * 2);
  }
}
static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
  int i;
  unsigned short *pal = (unsigned short *) screen_palette;
  
  for (i = 0; i < count; i++)
    pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
		      ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
		      ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
}
static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
  int i;
  unsigned short *pal = (unsigned short *) screen_palette;
  
  for (i = 0; i < count; i++)
    pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
		      ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
		      ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
}

/* *************************************
      24 / 32 bpp to palettized 8 bpp
   ************************************* */
static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, LPDIRECTDRAWPALETTE palette) {
  unsigned char  *c_src = (unsigned char  *) src;
  unsigned int *c_dst = (unsigned int *) dst;
  int x, y;

  if (palette != NULL) {
    unsigned int *pal = (unsigned int *) palette->screen_palents;
    
    for (y = 0; y < height; y++) {
      for (x = 0; x < width; x++) {
	c_dst[x + y * width] = pal[c_src[x + y * pitch]];
      }
    }
  } else {
    WARN(ddraw, "No palette set...\n");
    memset(dst, 0, width * height * 4);
  }
}
static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
  int i;
  unsigned int *pal = (unsigned int *) screen_palette;
  
  for (i = 0; i < count; i++)
    pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
		      (((unsigned int) palent[i].peGreen) << 8) |
		      ((unsigned int) palent[i].peBlue));
}

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

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

	switch (_common_depth_to_pixelformat(depth,
					     &(this->d.directdraw_pixelformat),
					     &(this->d.screen_pixelformat),
					     &(this->d.pixmap_depth))) {
	case 0:
	  sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
	  MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
	  return DDERR_UNSUPPORTEDMODE;

	case 1:
	  /* No convertion */
	  this->d.pixel_convert = NULL;
	  this->d.palette_convert = NULL;
	  break;

	case 2: {
	  int found = 0;

	  WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
	  
	  /* Set the depth convertion routines */
	  switch (this->d.screen_pixelformat.x.dwRGBBitCount) {
	  case 16:
	    if ((this->d.screen_pixelformat.y.dwRBitMask == 0xF800) &&
		(this->d.screen_pixelformat.z.dwGBitMask == 0x07E0) &&
		(this->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
	      /* 16 bpp */
	      found = 1;
	      
	      this->d.pixel_convert = pixel_convert_16_to_8;
	      this->d.palette_convert = palette_convert_16_to_8;
	    } else if ((this->d.screen_pixelformat.y.dwRBitMask == 0x7C00) &&
		       (this->d.screen_pixelformat.z.dwGBitMask == 0x03E0) &&
		       (this->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
	      /* 15 bpp */
	      found = 1;

	      this->d.pixel_convert = pixel_convert_16_to_8;
	      this->d.palette_convert = palette_convert_15_to_8;
	    }
	    break;
	    
	  case 24:
	    /* Not handled yet :/ */
	    found = 0;
			break;
	    
	  case 32:
	    if ((this->d.screen_pixelformat.y.dwRBitMask ==  0xFF0000) &&
		(this->d.screen_pixelformat.z.dwGBitMask ==  0x00FF00) &&
		(this->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) {
	      /* 24 bpp */
	      found = 1;

	      this->d.pixel_convert = pixel_convert_32_to_8;
	      this->d.palette_convert = palette_convert_24_to_8;
	    }
	      break;
	  }

	  if (!found) {
		sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
		MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
		return DDERR_UNSUPPORTEDMODE;
	  }
	} break;
	}

	this->d.width	= width;
	this->d.height	= height;

	_common_IDirectDraw_SetDisplayMode(this);

	this->d.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_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
    DDCAPS_CANBLTSYSMEM |  DDCAPS_COLORKEY | DDCAPS_PALETTE;
  caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
  caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
  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_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
    DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
      DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
	DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
#ifdef HAVE_MESAGL
  caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
  caps->dwCaps2 |=  DDCAPS2_NO2DDURING3DSCENE;
  caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
#endif
}

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,int *psize
) {
	int size = 0;
	  
	if (TRACE_ON(ddraw))
	  _dump_paletteformat(dwFlags);
	
	*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 (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");
	*psize = size;
	
        if (palent)
        {
	  /* Now, if we are in 'depth conversion mode', create the screen palette */
	  if (this->d.palette_convert != NULL)	    
	    this->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);

	  memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
        } else if (this->d.palette_convert != NULL) {
	  /* In that case, put all 0xFF */
	  memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
	}
	
	return DD_OK;
}

static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
	LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
) {
	HRESULT res;
	int xsize = 0,i;

	TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
	res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
	if (res != 0) return res;
	(*lpddpal)->lpvtbl = &dga_ddpalvt;
	if (this->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
		(*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
	} else {
		FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
		(*lpddpal)->cm = 0;
	}
	if (((*lpddpal)->cm)&&xsize) {
	  for (i=0;i<xsize;i++) {
		  XColor xc;

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

static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
	LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
) {
	int xsize;
	HRESULT res;

	TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
	res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
	if (res != 0) return res;
	(*lpddpal)->lpvtbl = &xlib_ddpalvt;
	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_InitHandlers();
#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,HANDLE 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);
		if (this->d.window && (this->d.mainWindow != this->d.window))
			DestroyWindow(this->d.window);
#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_InitHandlers();
#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)) {
		if (this->d.window && (this->d.mainWindow != this->d.window))
			DestroyWindow(this->d.window);
		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_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd4vt;
		this->lpvtbl->fnAddRef(this);
		*obj = this;

		TRACE(ddraw, "  Creating IDirectDraw4 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_IDirect3D2))) {
		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_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd4vt;
		this->lpvtbl->fnAddRef(this);
		*obj = this;

		TRACE(ddraw, "  Creating IDirectDraw4 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,BOOL *status
) {
        TRACE(ddraw,"(%p)->(%p)\n",this,status);
	*status = TRUE;
	return DD_OK;
}

static HRESULT WINAPI DGA_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 = 0xF800;
		    ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
		    ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
		    break;
		  case 24:
		    ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
		    ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
		    ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
		    break;
		  case 32:
		    ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
		    ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
		    ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
		    break;
		  }
		}

		ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
		ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
		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 Xlib_IDirectDraw2_EnumDisplayModes(
	LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
) {
  XVisualInfo *vi;
  XPixmapFormatValues *pf;
  XVisualInfo vt;
  int nvisuals, npixmap, i;
  int send_mode;
  int has_8bpp = 0;
  DDSURFACEDESC	ddsfd;
  static struct {
    int w,h;
  } modes[] = { /* some of the usual modes */
    {512,384},
    {640,400},
    {640,480},
    {800,600},
    {1024,768},
    {1280,1024}
  };
  DWORD maxWidth, maxHeight;

  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_PIXELFORMAT|DDSD_CAPS;
  if (dwFlags & DDEDM_REFRESHRATES) {
    ddsfd.dwFlags |= DDSD_REFRESHRATE;
    ddsfd.x.dwRefreshRate = 60;
  }
  maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
  maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
  
  vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
  pf = XListPixmapFormats(display, &npixmap);

  i = 0;
  send_mode = 0;
  while (i < npixmap) {
    if ((has_8bpp == 0) && (pf[i].depth == 8)) {
      /* Special case of a 8bpp depth */
      has_8bpp = 1;
      send_mode = 1;

      ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
      ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
      ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
      ddsfd.ddpfPixelFormat.dwFourCC = 0;
      ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
      ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
      ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
      ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
      ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
    } else if (pf[i].depth > 8) {
      int j;
      
      /* All the 'true color' depths (15, 16 and 24)
	 First, find the corresponding visual to extract the bit masks */
      for (j = 0; j < nvisuals; j++) {
	if (vi[j].depth == pf[i].depth) {
	  ddsfd.ddsCaps.dwCaps = 0;
	  ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
	  ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
	  ddsfd.ddpfPixelFormat.dwFourCC = 0;
	  ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
	  ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
	  ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
	  ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
	  ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;

	  send_mode = 1;
	  break;
	}
      }
      
      if (j == nvisuals)
	ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n");
    } else {
      send_mode = 0;
    }

    if (send_mode) {
      int mode;

      if (TRACE_ON(ddraw)) {
	TRACE(ddraw, "Enumerating with pixel format : \n");
	_dump_pixelformat(&(ddsfd.ddpfPixelFormat));
      }
      
      for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
	/* Do not enumerate modes we cannot handle anyway */
	if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
	  break;

	ddsfd.dwWidth = modes[mode].w;
	ddsfd.dwHeight = modes[mode].h;
	
	/* Now, send the mode description to the application */
	TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
	if (!modescb(&ddsfd, context))
	  goto exit_enum;
      }

      if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
	/* modeX is not standard VGA */
	ddsfd.dwWidth = 320;
	ddsfd.dwHeight = 200;
	if (!modescb(&ddsfd, context))
	  goto exit_enum;
      }
    }

    /* Hack to always enumerate a 8bpp depth */
    i++;
    if ((i == npixmap) && (has_8bpp == 0)) {
      i--;
      pf[i].depth = 8;
    }
  }
  
 exit_enum:
  TSXFree(vi);
  TSXFree(pf);

  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 = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
	lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
	lpddsfd->lPitch = this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8;
	lpddsfd->dwBackBufferCount = 1;
	lpddsfd->x.dwRefreshRate = 60;
	lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
	lpddsfd->ddpfPixelFormat = this->d.directdraw_pixelformat;
	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 = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
	lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
	lpddsfd->lPitch = lpddsfd->dwWidth * this->d.directdraw_pixelformat.x.dwRGBBitCount/8;
	lpddsfd->dwBackBufferCount = 1;
	lpddsfd->x.dwRefreshRate = 60;
	lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
	lpddsfd->ddpfPixelFormat = this->d.directdraw_pixelformat;
	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;
}

static HRESULT WINAPI IDirectDraw2_GetGDISurface(LPDIRECTDRAW2 this,
						 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
  FIXME(ddraw,"(%p)->(%p)\n", this, lplpGDIDDSSurface);

  return DD_OK;
}

static HRESULT WINAPI IDirectDraw2_GetScanLine(LPDIRECTDRAW2 this,
					       LPDWORD lpdwScanLine) {
  FIXME(ddraw,"(%p)->(%p)\n", this, lpdwScanLine);

  return DD_OK;
}

static HRESULT WINAPI IDirectDraw2_Initialize(LPDIRECTDRAW2 this,
					      GUID *lpGUID) {
  FIXME(ddraw,"(%p)->(%p)\n", this, lpGUID);
  
  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)DGA_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)IDirectDraw2_GetGDISurface,
	XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
	XCAST(GetScanLine)IDirectDraw2_GetScanLine,
	XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
	XCAST(Initialize)IDirectDraw2_Initialize,
	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)Xlib_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)IDirectDraw2_GetGDISurface,
	XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
	XCAST(GetScanLine)IDirectDraw2_GetScanLine,
	XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
	XCAST(Initialize)IDirectDraw2_Initialize,
	XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
	XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
	Xlib_IDirectDraw_SetDisplayMode,
	XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
};

#undef XCAST

/*****************************************************************************
 * 	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,
	IDirectDraw2_DuplicateSurface,
	DGA_IDirectDraw2_EnumDisplayModes,
	IDirectDraw2_EnumSurfaces,
	IDirectDraw2_FlipToGDISurface,
	DGA_IDirectDraw2_GetCaps,
	DGA_IDirectDraw2_GetDisplayMode,
	IDirectDraw2_GetFourCCCodes,
	IDirectDraw2_GetGDISurface,
	IDirectDraw2_GetMonitorFrequency,
	IDirectDraw2_GetScanLine,
	IDirectDraw2_GetVerticalBlankStatus,
	IDirectDraw2_Initialize,
	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,
	IDirectDraw2_DuplicateSurface,
	Xlib_IDirectDraw2_EnumDisplayModes,
	IDirectDraw2_EnumSurfaces,
	IDirectDraw2_FlipToGDISurface,
	Xlib_IDirectDraw2_GetCaps,
	Xlib_IDirectDraw2_GetDisplayMode,
	IDirectDraw2_GetFourCCCodes,
	IDirectDraw2_GetGDISurface,
	IDirectDraw2_GetMonitorFrequency,
	IDirectDraw2_GetScanLine,
	IDirectDraw2_GetVerticalBlankStatus,
	IDirectDraw2_Initialize,
	Xlib_IDirectDraw2_RestoreDisplayMode,
	IDirectDraw2_SetCooperativeLevel,
	Xlib_IDirectDraw2_SetDisplayMode,
	IDirectDraw2_WaitForVerticalBlank,
	Xlib_IDirectDraw2_GetAvailableVidMem	
};

/*****************************************************************************
 * 	IDirectDraw4
 *
 */

static HRESULT WINAPI IDirectDraw4_GetSurfaceFromDC(LPDIRECTDRAW4 this,
						    HDC hdc,
						    LPDIRECTDRAWSURFACE *lpDDS) {
  FIXME(ddraw, "(%p)->(%08ld,%p)\n", this, (DWORD) hdc, lpDDS);

  return DD_OK;
}

static HRESULT WINAPI IDirectDraw4_RestoreAllSurfaces(LPDIRECTDRAW4 this) {
  FIXME(ddraw, "(%p)->()\n", this);

  return DD_OK;
}

static HRESULT WINAPI IDirectDraw4_TestCooperativeLevel(LPDIRECTDRAW4 this) {
  FIXME(ddraw, "(%p)->()\n", this);

  return DD_OK;
}

static HRESULT WINAPI IDirectDraw4_GetDeviceIdentifier(LPDIRECTDRAW4 this,
						       LPDDDEVICEIDENTIFIER lpdddi,
						       DWORD dwFlags) {
  FIXME(ddraw, "(%p)->(%p,%08lx)\n", this, lpdddi, dwFlags);
  
  return DD_OK;
}

#ifdef __GNUC__
# define XCAST(fun)	(typeof(dga_dd4vt.fn##fun))
#else
# define XCAST(fun)	(void*)
#endif


static struct IDirectDraw4_VTable dga_dd4vt = {
	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)DGA_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)IDirectDraw2_GetGDISurface,
	XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
	XCAST(GetScanLine)IDirectDraw2_GetScanLine,
	XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
	XCAST(Initialize)IDirectDraw2_Initialize,
	XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
	XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
	XCAST(SetDisplayMode)DGA_IDirectDraw_SetDisplayMode,
	XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
	XCAST(GetAvailableVidMem)DGA_IDirectDraw2_GetAvailableVidMem,
	IDirectDraw4_GetSurfaceFromDC,
	IDirectDraw4_RestoreAllSurfaces,
	IDirectDraw4_TestCooperativeLevel,
	IDirectDraw4_GetDeviceIdentifier
};

static struct IDirectDraw4_VTable xlib_dd4vt = {
	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)Xlib_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)IDirectDraw2_GetGDISurface,
	XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
	XCAST(GetScanLine)IDirectDraw2_GetScanLine,
	XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
	XCAST(Initialize)IDirectDraw2_Initialize,
	XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
	XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
	XCAST(SetDisplayMode)Xlib_IDirectDraw_SetDisplayMode,
	XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
	XCAST(GetAvailableVidMem)Xlib_IDirectDraw2_GetAvailableVidMem,
	IDirectDraw4_GetSurfaceFromDC,
	IDirectDraw4_RestoreAllSurfaces,
	IDirectDraw4_TestCooperativeLevel,
	IDirectDraw4_GetDeviceIdentifier
};

#undef XCAST

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

LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM 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)GetWindowLongA( 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->d.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 = DefWindowProcA( 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 = CallWindowProcA( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
               	                   ddraw->d.mainWindow, msg, wParam, lParam );
	  }
        }
        
      } else {
        ret = DefWindowProcA(hwnd, msg, wParam, lParam );
      } 

    }
    else
    {
	ret = DefWindowProcA(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;             	
	int     depth;

        /* 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");
	  MessageBoxA(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 = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
#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 */
	depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
	_common_depth_to_pixelformat(depth, &((*lplpDD)->d.directdraw_pixelformat), &((*lplpDD)->d.screen_pixelformat), NULL);
#ifdef RESTORE_SIGNALS
	SIGNAL_InitHandlers();
#endif

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

BOOL
DDRAW_XSHM_Available(void)
   {
#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) {
	int depth;

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

	/* At DirectDraw creation, the depth is the default depth */
	depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
	_common_depth_to_pixelformat(depth, &((*lplpDD)->d.directdraw_pixelformat), &((*lplpDD)->d.screen_pixelformat), NULL);
	(*lplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
	(*lplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);

#ifdef HAVE_LIBXXSHM
	/* Test if XShm is available. */
	if (((*lplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
	  TRACE(ddraw, "Using XShm extension.\n");
#endif
	
	return DD_OK;
}

HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
	char	xclsid[50];
	WNDCLASSA	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	= (HCURSOR)IDC_ARROWA;
	wc.hbrBackground= NULL_BRUSH;
	wc.lpszMenuName	= 0;
	wc.lpszClassName= "WINE_DirectDraw";
	RegisterClassA(&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 = RegisterClassA(&wc);
	return ret;

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


#else /* !defined(X_DISPLAY_MISSING) */

#include "windef.h"

#define DD_OK 0

typedef void *LPGUID;
typedef void *LPUNKNOWN;
typedef void *LPDIRECTDRAW;
typedef void *LPDIRECTDRAWCLIPPER;
typedef void *LPDDENUMCALLBACKA;
typedef void *LPDDENUMCALLBACKEXA;
typedef void *LPDDENUMCALLBACKEXW;
typedef void *LPDDENUMCALLBACKW;

HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z) 
{
  return DD_OK;
}

HRESULT WINAPI DirectDrawCreate(
  LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) 
{
  return DD_OK;
}

HRESULT WINAPI DirectDrawCreateClipper(
  DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
{
  return DD_OK;
}

HRESULT WINAPI DirectDrawEnumerateA(
  LPDDENUMCALLBACKA lpCallback, LPVOID lpContext) 
{
  return DD_OK;
}

HRESULT WINAPI DirectDrawEnumerateExA(
  LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
{
  return DD_OK;
}

HRESULT WINAPI DirectDrawEnumerateExW(
  LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
{
  return DD_OK;
}

HRESULT WINAPI DirectDrawEnumerateW(
  LPDDENUMCALLBACKW lpCallback, LPVOID lpContext) 
{
  return DD_OK;
}

#endif /* !defined(X_DISPLAY_MISSING) */
