/*		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 "wine/exception.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 "ddraw_private.h"
#include "d3d_private.h"

DEFAULT_DEBUG_CHANNEL(ddraw)

/* Restore signal handlers overwritten by XF86DGA 
 */
#define RESTORE_SIGNALS

/* Get the number of bytes per pixel for a given surface */
#define GET_BPP(desc) (desc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ? \
		       1 :                                                                    \
		       desc.ddpfPixelFormat.x.dwRGBBitCount / 8)

/* 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}
};

#ifdef HAVE_LIBXXF86DGA
static struct ICOM_VTABLE(IDirectDrawSurface4)	dga_dds4vt;
static struct ICOM_VTABLE(IDirectDraw)		dga_ddvt;
static struct ICOM_VTABLE(IDirectDraw2)		dga_dd2vt;
static struct ICOM_VTABLE(IDirectDraw4)		dga_dd4vt;
static struct ICOM_VTABLE(IDirectDrawPalette)	dga_ddpalvt;
#endif /* defined(HAVE_LIBXXF86DGA) */

static struct ICOM_VTABLE(IDirectDrawSurface4)	xlib_dds4vt;
static struct ICOM_VTABLE(IDirectDraw)		xlib_ddvt;
static struct ICOM_VTABLE(IDirectDraw2)		xlib_dd2vt;
static struct ICOM_VTABLE(IDirectDraw4)		xlib_dd4vt;
static struct ICOM_VTABLE(IDirectDrawPalette)	xlib_ddpalvt;

static struct ICOM_VTABLE(IDirectDrawClipper)	ddclipvt;
static struct ICOM_VTABLE(IDirect3D)		d3dvt;
static struct ICOM_VTABLE(IDirect3D2)		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, 0))
      return DD_OK;
  }

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

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

static BOOL CALLBACK 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 = (LPVOID) lpCallback;
  epd.lpContext = lpContext;

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

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

static BOOL CALLBACK 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 = (LPVOID) lpCallback;
  epd.lpContext = lpContext;

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

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

static BOOL WINAPI 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 = (LPVOID) 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)
#undef FE
	};
	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)
#undef FE
	};
	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)
#undef FE
	};
	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(void *in) {
	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)
#undef FE
	};
	DWORD flagmask = *((DWORD *) in);
	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
		if (flags[i].mask & flagmask)
			DUMP("%s ",flags[i].name);
}

static void _dump_pixelformat_flag(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)
#undef FE
	};
	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
		if (flags[i].mask & flagmask)
			DUMP("%s ",flags[i].name);
}

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)
#undef FE
  };
  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(void *in) {
  LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
  char *cmd;
  
  DUMP("( ");
  _dump_pixelformat_flag(pf->dwFlags);
  if (pf->dwFlags & DDPF_FOURCC) {
    DUMP(", dwFourCC : %ld", pf->dwFourCC);
  }
  if (pf->dwFlags & DDPF_RGB) {
    DUMP(", RGB bits: %ld, ", pf->x.dwRGBBitCount);
    switch (pf->x.dwRGBBitCount) {
    case 4:
      cmd = "%1lx";
      break;
    case 8:
      cmd = "%02lx";
      break;
    case 16:
      cmd = "%04lx";
      break;
    case 24:
      cmd = "%06lx";
      break;
    case 32:
      cmd = "%08lx";
      break;
    default:
      ERR(ddraw, "Unexpected bit depth !\n");
      cmd = "%d";
    }
    DUMP(" R "); DUMP(cmd, pf->y.dwRBitMask);
    DUMP(" G "); DUMP(cmd, pf->z.dwGBitMask);
    DUMP(" B "); DUMP(cmd, pf->xx.dwBBitMask);
    if (pf->dwFlags & DDPF_ALPHAPIXELS) {
      DUMP(" A "); DUMP(cmd, pf->xy.dwRGBAlphaBitMask);
    }
    if (pf->dwFlags & DDPF_ZPIXELS) {
      DUMP(" Z "); DUMP(cmd, pf->xy.dwRGBZBitMask);
}
  }
  if (pf->dwFlags & DDPF_ZBUFFER) {
    DUMP(", Z bits : %ld", pf->x.dwZBufferBitDepth);
  }
  if (pf->dwFlags & DDPF_ALPHA) {
    DUMP(", Alpha bits : %ld", pf->x.dwAlphaBitDepth);
  }
  DUMP(")");
}

static void _dump_colorkeyflag(DWORD ck) {
	int	i;
	const struct {
		DWORD	mask;
		char	*name;
	} flags[] = {
#define FE(x) { x, #x},
	  FE(DDCKEY_COLORSPACE)
	  FE(DDCKEY_DESTBLT)
	  FE(DDCKEY_DESTOVERLAY)
	  FE(DDCKEY_SRCBLT)
	  FE(DDCKEY_SRCOVERLAY)
#undef FE
	};
	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
		if (flags[i].mask & ck)
			DUMP("%s ",flags[i].name);
}

static void _dump_DWORD(void *in) {
  DUMP("%ld", *((DWORD *) in));
}
static void _dump_PTR(void *in) {
  DUMP("%p", *((void **) in));
}
static void _dump_DDCOLORKEY(void *in) {
  DDCOLORKEY *ddck = (DDCOLORKEY *) in;

  DUMP(" Low : %ld  - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
}

static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
  int	i;
  const struct {
    DWORD	mask;
    char	*name;
    void (*func)(void *);
    void        *elt;
  } flags[] = {
#define FE(x,func,elt) { x, #x, func, (void *) &(lpddsd->elt)}
    FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps),
    FE(DDSD_HEIGHT, _dump_DWORD, dwHeight),
    FE(DDSD_WIDTH, _dump_DWORD, dwWidth),
    FE(DDSD_PITCH, _dump_DWORD, lPitch),
    FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount),
    FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, x.dwZBufferBitDepth),
    FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth),
    FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat),
    FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay),
    FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt),
    FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay),
    FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt),
    FE(DDSD_MIPMAPCOUNT, _dump_DWORD, x.dwMipMapCount),
    FE(DDSD_REFRESHRATE, _dump_DWORD, x.dwRefreshRate),
    FE(DDSD_LINEARSIZE, _dump_DWORD, y.dwLinearSize),
    FE(DDSD_LPSURFACE, _dump_PTR, y.lpSurface)
#undef FE
  };
  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
    if (flags[i].mask & lpddsd->dwFlags) {
      DUMP(" - %s : ",flags[i].name);
      flags[i].func(flags[i].elt);
	DUMP("\n");  
}
}


/******************************************************************************
 *		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 IDirectDrawSurface4Impl_Lock(
    LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
        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 = (LPVOID) ((char *) 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;
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
	LPDIRECTDRAWSURFACE4 iface,LPVOID surface
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	TRACE(ddraw,"(%p)->Unlock(%p)\n",This,surface);
	return DD_OK;
}
#endif /* defined(HAVE_LIBXXF86DGA) */

static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* 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_IDirectDrawSurface4Impl_Unlock(
	LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
{
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	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;
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
        IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
	TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
	if (!iflipto) {
		if (This->s.backbuffer)
			iflipto = This->s.backbuffer;
		else
			iflipto = This;
	}
	TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);

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

		tmp = This->t.dga.fb_height;
		This->t.dga.fb_height = iflipto->t.dga.fb_height;
		iflipto->t.dga.fb_height = tmp;

		ptmp = This->s.surface_desc.y.lpSurface;
		This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
		iflipto->s.surface_desc.y.lpSurface = ptmp;
	}
	return DD_OK;
}
#endif /* defined(HAVE_LIBXXF86DGA) */

static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
        IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
	TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);

#ifdef HAVE_MESAGL
	if ((This->s.d3d_device != NULL) ||
	    ((This->s.backbuffer != NULL) && (This->s.backbuffer->s.d3d_device != NULL))) {
	  TRACE(ddraw," - OpenGL flip\n");
	  ENTER_GL();
	  glXSwapBuffers(display,
			 This->s.ddraw->d.drawable);
	  LEAVE_GL();

	  return DD_OK;
	}
#endif /* defined(HAVE_MESAGL) */
	
	if (!This->s.ddraw->d.paintable)
		return DD_OK;

	if (!iflipto) {
		if (This->s.backbuffer)
			iflipto = This->s.backbuffer;
		else
			iflipto = This;
	}
  
	Xlib_copy_surface_on_screen(iflipto);
	
	if (iflipto->s.palette && iflipto->s.palette->cm) {
	  TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
	}
	if (iflipto!=This) {
		XImage *tmp;
		LPVOID	*surf;
		tmp = This->t.xlib.image;
		This->t.xlib.image = iflipto->t.xlib.image;
		iflipto->t.xlib.image = tmp;
		surf = This->s.surface_desc.y.lpSurface;
		This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
		iflipto->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_IDirectDrawSurface4Impl_SetPalette(
	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
        IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
	int i;
	TRACE(ddraw,"(%p)->(%p)\n",This,ipal);

	if (ipal == NULL) {
          if( This->s.palette != NULL )
            IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
	  This->s.palette = ipal;

	  return DD_OK;
	}
	
	if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8)) 
	{
		ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
					    DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);

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

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

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

        /* According to spec, we are only supposed to 
         * AddRef if this is not the same palette.
         */
        if( This->s.palette != ipal )
        {
          if( ipal != NULL )
            IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
          if( This->s.palette != NULL )
            IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
	  This->s.palette = ipal; 

          /* I think that we need to attach it to all backbuffers...*/
          if( This->s.backbuffer ) {
             if( This->s.backbuffer->s.palette )
               IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
             This->s.backbuffer->s.palette = ipal;
             if( ipal )
                IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
           }
          /* Perform the refresh */
          TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
        }
	return DD_OK;
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
        IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
	TRACE(ddraw,"(%p)->(%p)\n",This,ipal);

        /* According to spec, we are only supposed to 
         * AddRef if this is not the same palette.
         */
        if( This->s.palette != ipal )
        {
          if( ipal != NULL ) 
	  	IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
          if( This->s.palette != NULL )
            IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
	  This->s.palette = ipal; 

          /* I think that we need to attach it to all backbuffers...*/
          if( This->s.backbuffer ) {
             if( This->s.backbuffer->s.palette )
               IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
             This->s.backbuffer->s.palette = ipal;
             if ( ipal )
               IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
          }
	  TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
        }
	return DD_OK;
}
#endif /* defined(HAVE_LIBXXF86DGA) */

static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
{
	int x, y;
	LPBYTE first;

	/* Do first row */

#define COLORFILL_ROW(type) { \
	type *d = (type *) buf; \
	for (x = 0; x < width; x++) \
		d[x] = (type) color; \
	break; \
}

	switch(bpp) {
	case 1: COLORFILL_ROW(BYTE)
	case 2: COLORFILL_ROW(WORD)
	case 4: COLORFILL_ROW(DWORD)
	default:
	FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
	return DDERR_UNSUPPORTED;
	}

#undef COLORFILL_ROW

	/* Now copy first row */
	first = buf;
	for (y = 1; y < height; y++) {
		buf += lPitch;
		memcpy(buf, first, width * bpp);
	}

	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
	LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	RECT	xdst,xsrc;
	DDSURFACEDESC	ddesc,sdesc;
	HRESULT			ret = DD_OK;
	int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
	int x, y;
	LPBYTE dbuf, sbuf;

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

	if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
	IDirectDrawSurface4_Lock(iface,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));
		}
	}

	bpp = GET_BPP(ddesc);
	srcheight = xsrc.bottom - xsrc.top;
	srcwidth = xsrc.right - xsrc.left;
	dstheight = xdst.bottom - xdst.top;
	dstwidth = xdst.right - xdst.left;
	width = (xdst.right - xdst.left) * bpp;
	dbuf = (BYTE *) ddesc.y.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);

	dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
	
	/* First, all the 'source-less' blits */
	if (dwFlags & DDBLT_COLORFILL) {
		ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
		                     ddesc.lPitch, lpbltfx->b.dwFillColor);
		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 /* defined(HAVE_MESAGL) */
	}
	
	if (dwFlags & DDBLT_ROP) {
		/* Catch some degenerate cases here */
		switch(lpbltfx->dwROP) {
			case BLACKNESS:
				ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
				break;
			case 0xAA0029: /* No-op */
				break;
			case WHITENESS:
				ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
				break;
			default: 
				FIXME(ddraw, "Unsupported raster op: %08lx  Pattern: %p\n", lpbltfx->dwROP, lpbltfx->b.lpDDSPattern);
				goto error;
	    }
		dwFlags &= ~DDBLT_ROP;
	}

    if (dwFlags & DDBLT_DDROPS) {
		FIXME(ddraw, "\tDdraw Raster Ops: %08lx  Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->b.lpDDSPattern);
	}

	/* Now the 'with source' blits */
	if (src) {
		LPBYTE sbase;
		int sx, xinc, sy, yinc;

		sbase = (BYTE *) sdesc.y.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
		xinc = (srcwidth << 16) / dstwidth;
		yinc = (srcheight << 16) / dstheight;

		if (!dwFlags) {

			/* No effects, we can cheat here */
			if (dstwidth == srcwidth) {
				if (dstheight == srcheight) {
					/* No stretching in either direction.  This needs to be as fast as possible */
					sbuf = sbase;
					for (y = 0; y < dstheight; y++) {
						memcpy(dbuf, sbuf, width);
						sbuf += sdesc.lPitch;
						dbuf += ddesc.lPitch;
					}
	} else {
					/* Stretching in Y direction only */
					for (y = sy = 0; y < dstheight; y++, sy += yinc) {
						sbuf = sbase + (sy >> 16) * sdesc.lPitch;
						memcpy(dbuf, sbuf, width);
						dbuf += ddesc.lPitch;
		  }
		}
			} else {
				/* Stretching in X direction */
				int last_sy = -1;
				for (y = sy = 0; y < dstheight; y++, sy += yinc) {
					sbuf = sbase + (sy >> 16) * sdesc.lPitch;

					if ((sy >> 16) == (last_sy >> 16)) {
						/* Same as last row - copy already stretched row */
						memcpy(dbuf, dbuf - ddesc.lPitch, width);
	      } else {

#define STRETCH_ROW(type) { \
	type *s = (type *) sbuf, *d = (type *) dbuf; \
	for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
		d[x] = s[sx >> 16]; \
	break; \
}
		  
						switch(bpp) {
							case 1: STRETCH_ROW(BYTE)
							case 2: STRETCH_ROW(WORD)
							case 4: STRETCH_ROW(DWORD)
							default:
								FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
								ret = DDERR_UNSUPPORTED;
								goto error;
		}

#undef STRETCH_ROW

	      }
					last_sy = sy;
					dbuf += ddesc.lPitch;
	      }
	    }
		} else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
			DWORD keylow, keyhigh;

	    if (dwFlags & DDBLT_KEYSRC) {
				keylow  = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
				keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
			} else {
				/* I'm not sure if this is correct */
				FIXME(ddraw, "DDBLT_KEYDEST not fully supported yet.\n");
				keylow  = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
				keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
			}

#define COPYROW_COLORKEY(type) { \
	type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
	for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
		tmp = s[sx >> 16]; \
		if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
	} \
	break; \
		}
		
			for (y = sy = 0; y < dstheight; y++, sy += yinc) {
				sbuf = sbase + (sy >> 16) * sdesc.lPitch;

				switch (bpp) {
					case 1: COPYROW_COLORKEY(BYTE)
					case 2: COPYROW_COLORKEY(WORD)
					case 4: COPYROW_COLORKEY(DWORD)
	      default:
						FIXME(ddraw, "%s color-keyed blit not implemented for bpp %d!\n",
							(dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
						ret = DDERR_UNSUPPORTED;
						goto error;
	      }
				dbuf += ddesc.lPitch;
	  }

#undef COPYROW_COLORKEY
			
			dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);

	}
	}
	
error:
	
	if (dwFlags && FIXME_ON(ddraw)) {
	  FIXME(ddraw,"\tUnsupported flags: ");
	  _dump_DDBLT(dwFlags);
	}

	IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
	if (src) IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);

	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
	LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	int				bpp, w, h, x, y;
	DDSURFACEDESC	ddesc,sdesc;
	HRESULT			ret = DD_OK;
	LPBYTE			sbuf, dbuf;


	if (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. */
	IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
	IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);

	bpp = GET_BPP(This->s.surface_desc);
	sbuf = (BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
	dbuf = (BYTE *) ddesc.y.lpSurface + (dsty      * ddesc.lPitch) + dstx       * bpp;


	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;

	if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
		DWORD keylow, keyhigh;
		if (trans & DDBLTFAST_SRCCOLORKEY) {
			keylow  = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
			keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
		} else {
			/* I'm not sure if this is correct */
			FIXME(ddraw, "DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
			keylow  = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
			keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
		}

#define COPYBOX_COLORKEY(type) { \
	type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
	s = (type *) ((BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
	d = (type *) ((BYTE *) ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
	for (y = 0; y < h; y++) { \
		for (x = 0; x < w; x++) { \
			tmp = s[x]; \
			if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
		} \
		(LPBYTE)s += sdesc.lPitch; \
		(LPBYTE)d += ddesc.lPitch; \
	} \
	break; \
}

		switch (bpp) {
			case 1: COPYBOX_COLORKEY(BYTE)
			case 2: COPYBOX_COLORKEY(WORD)
			case 4: COPYBOX_COLORKEY(DWORD)
			default:
				FIXME(ddraw, "Source color key blitting not supported for bpp %d\n", bpp*8);
				ret = DDERR_UNSUPPORTED;
				goto error;
	}

#undef COPYBOX_COLORKEY

	} else {
		int width = w * bpp;

		for (y = 0; y < h; y++) {
			memcpy(dbuf, sbuf, width);
			sbuf += sdesc.lPitch;
			dbuf += ddesc.lPitch;
		}
	}

error:

	IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
	IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
	return ret;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
	LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
		This,ddbltbatch,x,y
	);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
	LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	TRACE(ddraw,"(%p)->GetCaps(%p)\n",This,caps);
	caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
	LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
) { 
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
		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_surface_desc(ddsd);
	}

	return DD_OK;
}

static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );

	return ++(This->ref);
}

#ifdef HAVE_LIBXXF86DGA
static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );

	if (!--(This->ref)) {
		IDirectDraw2_Release((IDirectDraw2*)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)
			IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);

		/* Free the DIBSection (if any) */
		if (This->s.hdc != 0) {
		  SelectObject(This->s.hdc, This->s.holdbitmap);
		  DeleteDC(This->s.hdc);
		  DeleteObject(This->s.DIBsection);
		}
		
		HeapFree(GetProcessHeap(),0,This);
		return 0;
	}
	return This->ref;
}
#endif /* defined(HAVE_LIBXXF86DGA) */

static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );

	if (!--(This->ref)) {
		IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);

		if( This->s.backbuffer )
		  IDirectDrawSurface4_Release((IDirectDrawSurface4*)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)
                	IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);

		/* Free the DIBSection (if any) */
		if (This->s.hdc != 0) {
		  SelectObject(This->s.hdc, This->s.holdbitmap);
		  DeleteDC(This->s.hdc);
		  DeleteObject(This->s.DIBsection);
		}

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

static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
	LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
        TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
		     This, lpddsd, lpdsf);

	if (TRACE_ON(ddraw)) {
		TRACE(ddraw,"	caps ");
		_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
		DUMP("\n");
	}

	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 = (LPDIRECTDRAWSURFACE4)This->s.backbuffer;
 
        if( This->s.backbuffer )
          IDirectDrawSurface4_AddRef( (IDirectDrawSurface4*)This->s.backbuffer );

	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	TRACE(ddraw,"(%p)->(%p, %p)\n",This,ddraw,lpdsfd);

	return DDERR_ALREADYINITIALIZED;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
	LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	TRACE(ddraw,"(%p)->(%p)\n",This,pf);

	*pf = This->s.surface_desc.ddpfPixelFormat;
	
	if (TRACE_ON(ddraw)) {
	_dump_pixelformat(pf);
	  DUMP("\n");
	}
	
	return DD_OK;
}

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

static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
	LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,x1,x2);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER clipper
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	FIXME(ddraw,"(%p)->(%p),stub!\n",This,clipper);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	FIXME(ddraw,"(%p)->(%p),stub!\n",This,surf);

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

static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
  DDSURFACEDESC desc;
  BITMAPINFO *b_info;
  UINT usage;
  
	FIXME(ddraw,"(%p)->GetDC(%p)\n",This,lphdc);

  /* Creates a DIB Section of the same size / format as the surface */
  IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);

  if (This->s.hdc == 0) {
    switch (desc.ddpfPixelFormat.x.dwRGBBitCount) {
    case 16:
    case 32:
#if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
      b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
      break;
#endif
      
    case 24:
      b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
      break;
      
    default:
      b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                                        sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.x.dwRGBBitCount));
      break;
    }
    
    b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    b_info->bmiHeader.biWidth = desc.dwWidth;
    b_info->bmiHeader.biHeight = desc.dwHeight;
    b_info->bmiHeader.biPlanes = 1;
    b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.x.dwRGBBitCount;
#if 0
    if ((desc.ddpfPixelFormat.x.dwRGBBitCount != 16) &&
        (desc.ddpfPixelFormat.x.dwRGBBitCount != 32))
#endif
      b_info->bmiHeader.biCompression = BI_RGB;
#if 0
    else
      b_info->bmiHeader.biCompression = BI_BITFIELDS;
#endif
    b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.x.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
    b_info->bmiHeader.biXPelsPerMeter = 0;
    b_info->bmiHeader.biYPelsPerMeter = 0;
    b_info->bmiHeader.biClrUsed = 0;
    b_info->bmiHeader.biClrImportant = 0;
    
    switch (desc.ddpfPixelFormat.x.dwRGBBitCount) {
    case 16:
    case 32:
#if 0
      {
        DWORD *masks = (DWORD *) &(b_info->bmiColors);
        
        usage = 0;
        masks[0] = desc.ddpfPixelFormat.y.dwRBitMask;
        masks[1] = desc.ddpfPixelFormat.z.dwGBitMask;
        masks[2] = desc.ddpfPixelFormat.xx.dwBBitMask;
      } break;
#endif
      
    case 24:
      /* Nothing to do */
      usage = DIB_RGB_COLORS;
      break;
      
    default: {
      int i;
      
      /* Fill the palette */
      usage = DIB_RGB_COLORS;

      if (This->s.palette == NULL) {
        ERR(ddraw, "Bad palette !!!\n");
      } else {
        RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
        PALETTEENTRY *pent = (PALETTEENTRY *) &(This->s.palette->palents);
        
        for (i = 0; i < (2 << desc.ddpfPixelFormat.x.dwRGBBitCount); i++) {
          rgb[i].rgbBlue = pent[i].peBlue;
          rgb[i].rgbRed = pent[i].peRed;
          rgb[i].rgbGreen = pent[i].peGreen; 
        }
      }
    } break;
    }  
    
    This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
					  b_info,
					  usage,
					  &(This->s.bitmap_data),
					  (HANDLE)0,
					  0);
    EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
    TRACE(ddraw, "DIBSection at : %p\n", This->s.bitmap_data);
    
    /* b_info is not useful anymore */
    HeapFree(GetProcessHeap(), 0, b_info);
      
    /* Create the DC */
    This->s.hdc = CreateCompatibleDC(0);
    This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
  }
  
  /* Copy our surface in the DIB section */
  if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch) {
    memcpy(This->s.bitmap_data, desc.y.lpSurface, desc.lPitch * desc.dwHeight);
  } else {
    /* TODO */
    FIXME(ddraw, "This case has to be done :/\n");
  }

  TRACE(ddraw, "HDC : %08lx\n", (DWORD) This->s.hdc);
  *lphdc = This->s.hdc;
  
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	
	FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,(long)hdc);

  TRACE(ddraw, "Copying DIBSection at : %p\n", This->s.bitmap_data);
  
  /* Copy the DIB section to our surface */
  if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
    memcpy(This->s.surface_desc.y.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
  } else {
    /* TODO */
    FIXME(ddraw, "This case has to be done :/\n");
	}

  /* Unlock the surface */
  IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.y.lpSurface);
	
	return DD_OK;

}

static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
        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;
		IDirectDrawSurface4_AddRef(iface);

		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);
	    IDirectDrawSurface4_AddRef(iface);
	    
	    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);
	    IDirectDrawSurface4_AddRef(iface);
	    
	    TRACE(ddraw, "  Creating IDirect3DTexture interface (%p)\n", *obj);
	    
	    return S_OK;
	  }
	else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj))
	  {
	    /* It is the OpenGL Direct3D Device */
	    IDirectDrawSurface4_AddRef(iface);

	    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 IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	TRACE(ddraw,"(%p)->(), stub!\n",This);
	return DD_OK; /* hmm */
}

static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,context,esfcb);

	/* For the moment, only enumerating the back buffer */
	if (This->s.backbuffer != NULL) {
	  TRACE(ddraw, "Enumerating back-buffer (%p)\n", This->s.backbuffer);
	  if (esfcb((LPDIRECTDRAWSURFACE) This->s.backbuffer, &(This->s.backbuffer->s.surface_desc), context) == DDENUMRET_CANCEL)
	    return DD_OK;
	}
	
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
	FIXME(ddraw,"(%p)->(),stub!\n",This);
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
	LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey ) 
{
        ICOM_THIS(IDirectDrawSurface4Impl,iface);
        TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
	if (TRACE_ON(ddraw)) {
	  _dump_colorkeyflag(dwFlags);
	  DUMP(" : ");
	  _dump_DDCOLORKEY((void *) ckey);
	  DUMP("\n");
	}

	/* If this surface was loaded as a texture, call also the texture
	   SetColorKey callback */
	if (This->s.texture) {
	  This->s.SetColorKey_cb(This->s.texture, 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 IDirectDrawSurface4Impl_AddOverlayDirtyRect(
        LPDIRECTDRAWSURFACE4 iface, 
        LPRECT lpRect )
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpRect); 

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
        LPDIRECTDRAWSURFACE4 iface, 
        DWORD dwFlags,
        LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",This,dwFlags,lpDDSAttachedSurface);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
        LPDIRECTDRAWSURFACE4 iface,
        DWORD dwFlags,
        LPVOID lpContext,
        LPDDENUMSURFACESCALLBACK lpfnCallback )
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
          lpContext, lpfnCallback );

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
        LPDIRECTDRAWSURFACE4 iface,
        LPDIRECTDRAWCLIPPER* lplpDDClipper )
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDClipper);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
        LPDIRECTDRAWSURFACE4 iface,
        DWORD dwFlags,
        LPDDCOLORKEY lpDDColorKey )
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  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 IDirectDrawSurface4Impl_GetFlipStatus(
        LPDIRECTDRAWSURFACE4 iface,
        DWORD dwFlags ) 
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
        LPDIRECTDRAWSURFACE4 iface,
        LPDIRECTDRAWPALETTE* lplpDDPalette )
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDPalette);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
        LPDIRECTDRAWSURFACE4 iface,
        LONG lX,
        LONG lY)
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", This, lX, lY);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
        LPDIRECTDRAWSURFACE4 iface,
        LPRECT lpSrcRect,
        LPDIRECTDRAWSURFACE4 lpDDDestSurface,
        LPRECT lpDestRect,
        DWORD dwFlags,
        LPDDOVERLAYFX lpDDOverlayFx )
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
         lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );  

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

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
        LPDIRECTDRAWSURFACE4 iface,
        DWORD dwFlags,
        LPDIRECTDRAWSURFACE4 lpDDSReference )
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
        LPDIRECTDRAWSURFACE4 iface,
        LPVOID* lplpDD )
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDD);

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

static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
        LPDIRECTDRAWSURFACE4 iface,
        DWORD dwFlags )
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);

  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
        LPDIRECTDRAWSURFACE4 iface,
        DWORD dwFlags )
{
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);

  return DD_OK;
}

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

  return DD_OK;
}

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

static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
							 REFGUID guidTag,
							 LPVOID lpBuffer,
							 LPDWORD lpcbBufferSize) {
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw, "(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
  
  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
							  REFGUID guidTag)  {
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw, "(%p)->(%p)\n", This, guidTag);
  
  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
							     LPDWORD lpValue)  {
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw, "(%p)->(%p)\n", This, lpValue);
  
  return DD_OK;
}

static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
  ICOM_THIS(IDirectDrawSurface4Impl,iface);
  FIXME(ddraw, "(%p)\n", This);
  
  return DD_OK;
}

#ifdef HAVE_LIBXXF86DGA
static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	IDirectDrawSurface4Impl_QueryInterface,
	IDirectDrawSurface4Impl_AddRef,
	DGA_IDirectDrawSurface4Impl_Release,
	IDirectDrawSurface4Impl_AddAttachedSurface,
	IDirectDrawSurface4Impl_AddOverlayDirtyRect,
	IDirectDrawSurface4Impl_Blt,
	IDirectDrawSurface4Impl_BltBatch,
	IDirectDrawSurface4Impl_BltFast,
	IDirectDrawSurface4Impl_DeleteAttachedSurface,
	IDirectDrawSurface4Impl_EnumAttachedSurfaces,
	IDirectDrawSurface4Impl_EnumOverlayZOrders,
	DGA_IDirectDrawSurface4Impl_Flip,
	IDirectDrawSurface4Impl_GetAttachedSurface,
	IDirectDrawSurface4Impl_GetBltStatus,
	IDirectDrawSurface4Impl_GetCaps,
	IDirectDrawSurface4Impl_GetClipper,
	IDirectDrawSurface4Impl_GetColorKey,
	IDirectDrawSurface4Impl_GetDC,
	IDirectDrawSurface4Impl_GetFlipStatus,
	IDirectDrawSurface4Impl_GetOverlayPosition,
	IDirectDrawSurface4Impl_GetPalette,
	IDirectDrawSurface4Impl_GetPixelFormat,
	IDirectDrawSurface4Impl_GetSurfaceDesc,
	IDirectDrawSurface4Impl_Initialize,
	IDirectDrawSurface4Impl_IsLost,
	IDirectDrawSurface4Impl_Lock,
	IDirectDrawSurface4Impl_ReleaseDC,
	IDirectDrawSurface4Impl_Restore,
	IDirectDrawSurface4Impl_SetClipper,
	IDirectDrawSurface4Impl_SetColorKey,
	IDirectDrawSurface4Impl_SetOverlayPosition,
	DGA_IDirectDrawSurface4Impl_SetPalette,
	DGA_IDirectDrawSurface4Impl_Unlock,
	IDirectDrawSurface4Impl_UpdateOverlay,
	IDirectDrawSurface4Impl_UpdateOverlayDisplay,
	IDirectDrawSurface4Impl_UpdateOverlayZOrder,
	IDirectDrawSurface4Impl_GetDDInterface,
	IDirectDrawSurface4Impl_PageLock,
	IDirectDrawSurface4Impl_PageUnlock,
	IDirectDrawSurface4Impl_SetSurfaceDesc,
	IDirectDrawSurface4Impl_SetPrivateData,
	IDirectDrawSurface4Impl_GetPrivateData,
	IDirectDrawSurface4Impl_FreePrivateData,
	IDirectDrawSurface4Impl_GetUniquenessValue,
	IDirectDrawSurface4Impl_ChangeUniquenessValue
};
#endif /* defined(HAVE_LIBXXF86DGA) */

static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	IDirectDrawSurface4Impl_QueryInterface,
	IDirectDrawSurface4Impl_AddRef,
	Xlib_IDirectDrawSurface4Impl_Release,
	IDirectDrawSurface4Impl_AddAttachedSurface,
	IDirectDrawSurface4Impl_AddOverlayDirtyRect,
	IDirectDrawSurface4Impl_Blt,
	IDirectDrawSurface4Impl_BltBatch,
	IDirectDrawSurface4Impl_BltFast,
	IDirectDrawSurface4Impl_DeleteAttachedSurface,
	IDirectDrawSurface4Impl_EnumAttachedSurfaces,
	IDirectDrawSurface4Impl_EnumOverlayZOrders,
	Xlib_IDirectDrawSurface4Impl_Flip,
	IDirectDrawSurface4Impl_GetAttachedSurface,
	IDirectDrawSurface4Impl_GetBltStatus,
	IDirectDrawSurface4Impl_GetCaps,
	IDirectDrawSurface4Impl_GetClipper,
	IDirectDrawSurface4Impl_GetColorKey,
	IDirectDrawSurface4Impl_GetDC,
	IDirectDrawSurface4Impl_GetFlipStatus,
	IDirectDrawSurface4Impl_GetOverlayPosition,
	IDirectDrawSurface4Impl_GetPalette,
	IDirectDrawSurface4Impl_GetPixelFormat,
	IDirectDrawSurface4Impl_GetSurfaceDesc,
	IDirectDrawSurface4Impl_Initialize,
	IDirectDrawSurface4Impl_IsLost,
	IDirectDrawSurface4Impl_Lock,
	IDirectDrawSurface4Impl_ReleaseDC,
	IDirectDrawSurface4Impl_Restore,
	IDirectDrawSurface4Impl_SetClipper,
	IDirectDrawSurface4Impl_SetColorKey,
	IDirectDrawSurface4Impl_SetOverlayPosition,
	Xlib_IDirectDrawSurface4Impl_SetPalette,
	Xlib_IDirectDrawSurface4Impl_Unlock,
	IDirectDrawSurface4Impl_UpdateOverlay,
	IDirectDrawSurface4Impl_UpdateOverlayDisplay,
	IDirectDrawSurface4Impl_UpdateOverlayZOrder,
	IDirectDrawSurface4Impl_GetDDInterface,
	IDirectDrawSurface4Impl_PageLock,
	IDirectDrawSurface4Impl_PageUnlock,
	IDirectDrawSurface4Impl_SetSurfaceDesc,
	IDirectDrawSurface4Impl_SetPrivateData,
	IDirectDrawSurface4Impl_GetPrivateData,
	IDirectDrawSurface4Impl_FreePrivateData,
	IDirectDrawSurface4Impl_GetUniquenessValue,
	IDirectDrawSurface4Impl_ChangeUniquenessValue
};

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

  *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
  (*ilplpDDClipper)->lpvtbl = &ddclipvt;
  (*ilplpDDClipper)->ref = 1;

  return DD_OK;
}

/******************************************************************************
 *			IDirectDrawClipper
 */
static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
	LPDIRECTDRAWCLIPPER iface,DWORD x,HWND hwnd
) {
        ICOM_THIS(IDirectDrawClipperImpl,iface);
	FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This,x,(DWORD)hwnd);
	return DD_OK;
}

static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
        ICOM_THIS(IDirectDrawClipperImpl,iface);
        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 IDirectDrawClipperImpl_GetClipList(
	LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
) {
        ICOM_THIS(IDirectDrawClipperImpl,iface);
	FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
	if (hmm) *hmm=0;
	return DD_OK;
}

static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
	LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
) {
        ICOM_THIS(IDirectDrawClipperImpl,iface);
	FIXME(ddraw,"(%p,%p,%ld),stub!\n",This,lprgn,hmm);
	return DD_OK;
}

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

static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
{
  ICOM_THIS(IDirectDrawClipperImpl,iface);
  TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
  return ++(This->ref);
}

static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
         LPDIRECTDRAWCLIPPER iface,
         HWND* HWndPtr )
{
   ICOM_THIS(IDirectDrawClipperImpl,iface);
   FIXME(ddraw,"(%p)->(%p),stub!\n",This,HWndPtr);
   return DD_OK;
}

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

static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
         LPDIRECTDRAWCLIPPER iface,
         BOOL* lpbChanged )
{
   ICOM_THIS(IDirectDrawClipperImpl,iface);
   FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpbChanged);
   return DD_OK;
}

static ICOM_VTABLE(IDirectDrawClipper) ddclipvt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
        IDirectDrawClipperImpl_QueryInterface,
        IDirectDrawClipperImpl_AddRef,
        IDirectDrawClipperImpl_Release,
        IDirectDrawClipperImpl_GetClipList,
        IDirectDrawClipperImpl_GetHWnd,
        IDirectDrawClipperImpl_Initialize,
        IDirectDrawClipperImpl_IsClipListChanged,
        IDirectDrawClipperImpl_SetClipList,
        IDirectDrawClipperImpl_SetHwnd
};


/******************************************************************************
 *			IDirectDrawPalette
 */
static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
	LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
) {
        ICOM_THIS(IDirectDrawPaletteImpl,iface);
	int	i;

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

	/* No palette created and not in depth-convertion mode -> BUG ! */
	if ((This->cm == None) &&
	    (This->ddraw->d.palette_convert == NULL))
	{
		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_IDirectDrawPaletteImpl_SetEntries(
	LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
) {
        ICOM_THIS(IDirectDrawPaletteImpl,iface);
	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 */
	/* FIXME: we need to update the image or we won't get palette fading. */
	if (This->ddraw->d.palette_convert != NULL)
	  This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
	  
	return DD_OK;
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
	LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
) {
        ICOM_THIS(IDirectDrawPaletteImpl,iface);
	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;
}
#endif /* defined(HAVE_LIBXXF86DGA) */

static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
        ICOM_THIS(IDirectDrawPaletteImpl,iface);
        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 IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
        ICOM_THIS(IDirectDrawPaletteImpl,iface);

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

static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
	LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
) {
        ICOM_THIS(IDirectDrawPaletteImpl,iface);
        TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);

	return DDERR_ALREADYINITIALIZED;
}

static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
         LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
{
   ICOM_THIS(IDirectDrawPaletteImpl,iface);
   FIXME( ddraw, "(%p)->(%p) stub.\n", This, lpdwCaps );
   return DD_OK;
} 

static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
        LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj ) 
{
  ICOM_THIS(IDirectDrawPaletteImpl,iface);
  char    xrefiid[50];

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

  return S_OK;
}

#ifdef HAVE_LIBXXF86DGA
static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	IDirectDrawPaletteImpl_QueryInterface,
	IDirectDrawPaletteImpl_AddRef,
	IDirectDrawPaletteImpl_Release,
	IDirectDrawPaletteImpl_GetCaps,
	IDirectDrawPaletteImpl_GetEntries,
	IDirectDrawPaletteImpl_Initialize,
	DGA_IDirectDrawPaletteImpl_SetEntries
};
#endif /* defined(HAVE_LIBXXF86DGA) */

static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	IDirectDrawPaletteImpl_QueryInterface,
	IDirectDrawPaletteImpl_AddRef,
	IDirectDrawPaletteImpl_Release,
	IDirectDrawPaletteImpl_GetCaps,
	IDirectDrawPaletteImpl_GetEntries,
	IDirectDrawPaletteImpl_Initialize,
	Xlib_IDirectDrawPaletteImpl_SetEntries
};

/*******************************************************************************
 *				IDirect3D
 */
static HRESULT WINAPI IDirect3DImpl_QueryInterface(
        LPDIRECT3D iface,REFIID refiid,LPVOID *obj
) {
        ICOM_THIS(IDirect3DImpl,iface);
	/* 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_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
	    (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
	    (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
                *obj = This->ddraw;
                IDirect3D_AddRef(iface);

		TRACE(ddraw, "  Creating IDirectDrawX interface (%p)\n", *obj);
		
                return S_OK;
        }
        if ((!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) ||
	    (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
                *obj = This;
                IDirect3D_AddRef(iface);

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

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

                d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
                d3d->ref = 1;
                d3d->ddraw = This->ddraw;
                IDirect3D_AddRef(iface);
                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 IDirect3DImpl_AddRef(LPDIRECT3D iface) {
        ICOM_THIS(IDirect3DImpl,iface);
        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );

        return ++(This->ref);
}

static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
{
        ICOM_THIS(IDirect3DImpl,iface);
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );

        if (!--(This->ref)) {
                IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
                HeapFree(GetProcessHeap(),0,This);
                return 0;
        }
        return This->ref;
}

static HRESULT WINAPI IDirect3DImpl_Initialize(
         LPDIRECT3D iface, REFIID refiid )
{
  ICOM_THIS(IDirect3DImpl,iface);
  /* 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 IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
					    LPD3DENUMDEVICESCALLBACK cb,
					    LPVOID context) {
  ICOM_THIS(IDirect3DImpl,iface);
  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 IDirect3DImpl_CreateLight(LPDIRECT3D iface,
					    LPDIRECT3DLIGHT *lplight,
					    IUnknown *lpunk)
{
  ICOM_THIS(IDirect3DImpl,iface);
  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 IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
					       LPDIRECT3DMATERIAL *lpmaterial,
					       IUnknown *lpunk)
{
  ICOM_THIS(IDirect3DImpl,iface);
  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 IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
					       LPDIRECT3DVIEWPORT *lpviewport,
					       IUnknown *lpunk)
{
  ICOM_THIS(IDirect3DImpl,iface);
  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 IDirect3DImpl_FindDevice(LPDIRECT3D iface,
					   LPD3DFINDDEVICESEARCH lpfinddevsrc,
					   LPD3DFINDDEVICERESULT lpfinddevrst)
{
  ICOM_THIS(IDirect3DImpl,iface);
  TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
  
  return DD_OK;
}

static ICOM_VTABLE(IDirect3D) d3dvt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
        IDirect3DImpl_QueryInterface,
        IDirect3DImpl_AddRef,
        IDirect3DImpl_Release,
        IDirect3DImpl_Initialize,
        IDirect3DImpl_EnumDevices,
        IDirect3DImpl_CreateLight,
        IDirect3DImpl_CreateMaterial,
        IDirect3DImpl_CreateViewport,
	IDirect3DImpl_FindDevice
};

/*******************************************************************************
 *				IDirect3D2
 */
static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
        LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {  
	ICOM_THIS(IDirect3D2Impl,iface);

	/* 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_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
	    (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
	    (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
                *obj = This->ddraw;
                IDirect3D2_AddRef(iface);

		TRACE(ddraw, "  Creating IDirectDrawX interface (%p)\n", *obj);
		
                return S_OK;
        }
        if ((!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) ||
	    (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
                *obj = This;
                IDirect3D2_AddRef(iface);

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

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

                d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
                d3d->ref = 1;
                d3d->ddraw = This->ddraw;
                IDirect3D2_AddRef(iface);
                d3d->lpvtbl = &d3dvt;
                *obj = d3d;

		TRACE(ddraw, "  Creating IDirect3D 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 IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
        ICOM_THIS(IDirect3D2Impl,iface);
        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );

        return ++(This->ref);
}

static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
        ICOM_THIS(IDirect3D2Impl,iface);
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );

	if (!--(This->ref)) {
		IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
		HeapFree(GetProcessHeap(),0,This);
		return 0;
	}
	return This->ref;
}

static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
	LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
) {
        ICOM_THIS(IDirect3D2Impl,iface);
	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 IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
					     LPDIRECT3DLIGHT *lplight,
					     IUnknown *lpunk)
{
  ICOM_THIS(IDirect3D2Impl,iface);
  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 IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
						LPDIRECT3DMATERIAL2 *lpmaterial,
						IUnknown *lpunk)
{
  ICOM_THIS(IDirect3D2Impl,iface);
  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 IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
						LPDIRECT3DVIEWPORT2 *lpviewport,
						IUnknown *lpunk)
{
  ICOM_THIS(IDirect3D2Impl,iface);
  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 IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
					    LPD3DFINDDEVICESEARCH lpfinddevsrc,
					    LPD3DFINDDEVICERESULT lpfinddevrst)
{
  ICOM_THIS(IDirect3D2Impl,iface);
  TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);

  return DD_OK;
}

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

  if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
    IDirect3D2_AddRef(iface);
    return DD_OK;
}

  return DDERR_INVALIDPARAMS;
}

static ICOM_VTABLE(IDirect3D2) d3d2vt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	IDirect3D2Impl_QueryInterface,
	IDirect3D2Impl_AddRef,
        IDirect3D2Impl_Release,
        IDirect3D2Impl_EnumDevices,
	IDirect3D2Impl_CreateLight,
	IDirect3D2Impl_CreateMaterial,
	IDirect3D2Impl_CreateViewport,
	IDirect3D2Impl_FindDevice,
	IDirect3D2Impl_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(IDirectDraw2Impl* This,
					       IDirectDrawSurfaceImpl* 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 (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
    /* This is a Z Buffer */
    TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.x.dwZBufferBitDepth);
    bpp = lpdsf->s.surface_desc.x.dwZBufferBitDepth / 8;
  } else {
    /* This is a standard image */
    if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
    /* No pixel format => use DirectDraw's format */
      lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
      lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
  }

    bpp = GET_BPP(lpdsf->s.surface_desc);
  }

  if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
    /* The surface was preallocated : seems that we have nothing to do :-) */
    WARN(ddraw, "Creates a surface that is already allocated : assuming this is an application bug !\n");
  }
  
  lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
  lpdsf->s.surface_desc.y.lpSurface =
    (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
  lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
  
  return DD_OK;
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
	LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
        IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
	int	i;

	TRACE(ddraw, "(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
	if (TRACE_ON(ddraw)) {
	  _dump_surface_desc(lpddsd);
	}

	*ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
	IDirectDraw2_AddRef(iface);
        
	(*ilpdsf)->ref = 1;
	(*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
	(*ilpdsf)->s.ddraw = This;
	(*ilpdsf)->s.palette = NULL;
	(*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */

	/* Copy the surface description */
	(*ilpdsf)->s.surface_desc = *lpddsd;
	
	if (!(lpddsd->dwFlags & DDSD_WIDTH))
	  (*ilpdsf)->s.surface_desc.dwWidth  = This->d.width;
	if (!(lpddsd->dwFlags & DDSD_HEIGHT))
	  (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
	(*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_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 */
	  (*ilpdsf)->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);
	  (*ilpdsf)->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);
		(*ilpdsf)->t.dga.fb_height = i*This->e.dga.fb_height;
	  (*ilpdsf)->s.surface_desc.lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
	  lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch;

	  /* Add flags if there were not present */
	  (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
	  (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
	  (*ilpdsf)->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 */
	  (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
	  (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
	(*ilpdsf)->s.backbuffer = NULL;
	  
	if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
		IDirectDrawSurface4Impl*	back;

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

	    (*ilpdsf)->s.backbuffer = back =
	      (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
		IDirectDraw2_AddRef(iface);
		back->ref = 1;
		back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&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 = (*ilpdsf)->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 */
	    (*ilpdsf)->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, *ilpdsf);
	}
	
	return DD_OK;
}
#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(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* 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(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* 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_IDirectDraw2Impl_CreateSurface(
	LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
        IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
	TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
		     This,lpddsd,ilpdsf,lpunk);

	if (TRACE_ON(ddraw)) {
	  _dump_surface_desc(lpddsd);
	}

	*ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));

	IDirectDraw2_AddRef(iface);
	(*ilpdsf)->s.ddraw             = This;
	(*ilpdsf)->ref                 = 1;
	(*ilpdsf)->lpvtbl              = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
	(*ilpdsf)->s.palette = NULL;
	(*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */

	/* Copy the surface description */
	(*ilpdsf)->s.surface_desc = *lpddsd;
	
	if (!(lpddsd->dwFlags & DDSD_WIDTH))
	  (*ilpdsf)->s.surface_desc.dwWidth  = This->d.width;
	if (!(lpddsd->dwFlags & DDSD_HEIGHT))
	  (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
	(*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_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", *ilpdsf);

    /* Create the XImage */
    img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
    if (img == NULL)
      return DDERR_OUTOFMEMORY;
    (*ilpdsf)->t.xlib.image = img;

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

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

      (*ilpdsf)->s.backbuffer = back =
	(IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));

      TRACE(ddraw,"allocated back-buffer (%p)\n", back);
      
		IDirectDraw2_AddRef(iface);
		back->s.ddraw = This;

		back->ref = 1;
		back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
	    /* Copy the surface description from the front buffer */
	    back->s.surface_desc = (*ilpdsf)->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 */
	    (*ilpdsf)->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, *ilpdsf);
  }
  
	return DD_OK;
}

static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
	LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	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 IDirectDraw2Impl_SetCooperativeLevel(
	LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	int	i;
	const struct {
		int	mask;
		char	*name;
	} flagmap[] = {
#define FE(x) { x, #x},
		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)
#undef FE
	};

	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)
        {
            WND *tmpWnd = WIN_FindWndPtr(hwnd);
            This->d.drawable  = X11DRV_WND_GetXWindow(tmpWnd);
            WIN_ReleaseWndPtr(tmpWnd);

	    if( !This->d.drawable ) {
	      This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
	      WIN_ReleaseDesktop();
        }
	    TRACE(ddraw, "Setting drawable to %ld\n", This->d.drawable);
        }

	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_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* 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;
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
	LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
) {
        ICOM_THIS(IDirectDrawImpl,iface);
        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_IDirectDrawImpl_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);
	TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);

#ifdef RESTORE_SIGNALS
	EXC_InitHandlers();
#endif
	return DD_OK;
}
#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, IDirectDrawPaletteImpl* palette) {
  unsigned char  *c_src = (unsigned char  *) src;
  unsigned short *c_dst = (unsigned short *) dst;
  int y;

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

    for (y = height; y--; ) {
#ifdef __i386__
      /* gcc generates slightly inefficient code for the the copy / lookup,
       * it generates one excess memory access (to pal) per pixel. Since
       * we know that pal is not modified by the memory write we can
       * put it into a register and reduce the number of memory accesses 
       * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
       * (This is not guaranteed to be the fastest method.)
       */
      __asm__ __volatile__(
      "xor %%eax,%%eax\n"
      "1:\n"
      "    lodsb\n"
      "    movw (%%edx,%%eax,2),%%ax\n"
      "    stosw\n"
      "	   xor %%eax,%%eax\n"
      "    loop 1b\n"
      : "=S" (c_src), "=D" (c_dst)
      : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
      : "eax", "cc", "memory"
      );
      c_src+=(pitch-width);
#else
      unsigned char * srclineend = c_src+width;
      while (c_src < srclineend)
        *c_dst++ = pal[*c_src++];
      c_src+=(pitch-width);
#endif
    }
  } 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 to palettized 8 bpp
   ************************************* */
static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
  unsigned char  *c_src = (unsigned char  *) src;
  unsigned char *c_dst = (unsigned char *) dst;
  int y;

  if (palette != NULL) {
    const unsigned int *pal = (unsigned int *) palette->screen_palents;
    
    for (y = height; y--; ) {
      unsigned char * srclineend = c_src+width;
      while (c_src < srclineend ) {
	register long pixel = pal[*c_src++];
	*c_dst++ = pixel;
	*c_dst++ = pixel>>8;
	*c_dst++ = pixel>>16;
      }
      c_src+=(pitch-width);
    }
  } else {
    WARN(ddraw, "No palette set...\n");
    memset(dst, 0, width * height * 4);
  }
}
/* *************************************
      32 bpp to palettized 8 bpp
   ************************************* */
static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
  unsigned char  *c_src = (unsigned char  *) src;
  unsigned int *c_dst = (unsigned int *) dst;
  int y;

  if (palette != NULL) {
    const unsigned int *pal = (unsigned int *) palette->screen_palents;
    
    for (y = height; y--; ) {
#ifdef __i386__
      /* See comment in pixel_convert_16_to_8 */
      __asm__ __volatile__(
      "xor %%eax,%%eax\n"
      "1:\n"
      "    lodsb\n"
      "    movl (%%edx,%%eax,4),%%eax\n"
      "    stosl\n"
      "	   xor %%eax,%%eax\n"
      "    loop 1b\n"
      : "=S" (c_src), "=D" (c_dst)
      : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
      : "eax", "cc", "memory"
      );
      c_src+=(pitch-width);
#else
      unsigned char * srclineend = c_src+width;
      while (c_src < srclineend )
	*c_dst++ = pal[*c_src++];
      c_src+=(pitch-width);
#endif
    }
  } 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_IDirectDrawImpl_SetDisplayMode(
	LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
) {
        ICOM_THIS(IDirectDrawImpl,iface);
	char	buf[200];
        WND *tmpWnd;

	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:
	    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_24_to_8;
	      This->d.palette_convert = palette_convert_24_to_8;
	    }
	    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_IDirectDrawImpl_SetDisplayMode(This);

        tmpWnd = WIN_FindWndPtr(This->d.window);
	This->d.paintable = 1;
        This->d.drawable  = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
        WIN_ReleaseWndPtr(tmpWnd);

        /* 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;
            WIN_ReleaseDesktop();
        }
	TRACE(ddraw, "Setting drawable to %ld\n", This->d.drawable);

	return DD_OK;
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
	LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
	if (!caps1 && !caps2)
	   return DDERR_INVALIDPARAMS;
	if (caps1) {
		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;
}
#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_IDirectDraw2Impl_GetCaps(
	LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
)  {
        ICOM_THIS(IDirectDraw2Impl,iface);
	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 IDirectDraw2Impl_CreateClipper(
	LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
        IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
	FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
		This,x,ilpddclip,lpunk
	);
	*ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
	(*ilpddclip)->ref = 1;
	(*ilpddclip)->lpvtbl = &ddclipvt;
	return DD_OK;
}

static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
	IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
) {
	int size = 0;
	  
	if (TRACE_ON(ddraw))
	  _dump_paletteformat(dwFlags);
	
	*lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
	if (*lpddpal == NULL) return E_OUTOFMEMORY;
	(*lpddpal)->ref = 1;
	(*lpddpal)->ddraw = (IDirectDrawImpl*)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;
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
	LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
        IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
	HRESULT res;
	int xsize = 0,i;

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

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

static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
	LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
        IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
	int xsize;
	HRESULT res;

	TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
	res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
	if (res != 0) return res;
	(*ilpddpal)->lpvtbl = &xlib_ddpalvt;
	return DD_OK;
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	TRACE(ddraw, "(%p)->()\n",This);
	Sleep(1000);
	TSXF86DGADirectVideo(display,DefaultScreen(display),0);
#ifdef RESTORE_SIGNALS
	EXC_InitHandlers();
#endif
	return DD_OK;
}
#endif /* defined(HAVE_LIBXXF86DGA) */

static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", This);
	Sleep(1000);
	return DD_OK;
}

static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
	LPDIRECTDRAW2 iface,DWORD x,HANDLE h
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",This,x,h);
	return DD_OK;
}

static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
        ICOM_THIS(IDirectDraw2Impl,iface);
        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );

	return ++(This->ref);
}

#ifdef HAVE_LIBXXF86DGA
static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
        ICOM_THIS(IDirectDraw2Impl,iface);
        TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );

	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
		EXC_InitHandlers();
#endif
		HeapFree(GetProcessHeap(),0,This);
		return 0;
	}
	return This->ref;
}
#endif /* defined(HAVE_LIBXXF86DGA) */

static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
        ICOM_THIS(IDirectDraw2Impl,iface);
        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;
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
	LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	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;
		IDirectDraw2_AddRef(iface);

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

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

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

		return S_OK;
	}
	if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
		This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
		IDirectDraw2_AddRef(iface);
		*obj = This;

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

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

		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
		d3d->ref = 1;
		d3d->ddraw = (IDirectDrawImpl*)This;
		IDirectDraw2_AddRef(iface);
		d3d->lpvtbl = &d3dvt;
		*obj = d3d;

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

		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
		d3d->ref = 1;
		d3d->ddraw = (IDirectDrawImpl*)This;
		IDirectDraw2_AddRef(iface);
		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;
}
#endif /* defined(HAVE_LIBXXF86DGA) */

static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
	LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	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;
		IDirectDraw2_AddRef(iface);

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

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

		TRACE(ddraw, "  Creating IDirectDraw2 interface (%p)\n", *obj);
		
		return S_OK;
	}
	if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
		This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
		IDirectDraw2_AddRef(iface);
		*obj = This;

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

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

		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
		d3d->ref = 1;
		d3d->ddraw = (IDirectDrawImpl*)This;
		IDirectDraw2_AddRef(iface);
		d3d->lpvtbl = &d3dvt;
		*obj = d3d;

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

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

		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
		d3d->ref = 1;
		d3d->ddraw = (IDirectDrawImpl*)This;
		IDirectDraw2_AddRef(iface);
		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 IDirectDraw2Impl_GetVerticalBlankStatus(
	LPDIRECTDRAW2 iface,BOOL *status
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
        TRACE(ddraw,"(%p)->(%p)\n",This,status);
	*status = TRUE;
	return DD_OK;
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
	LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	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;
}
#endif /* defined(HAVE_LIBXXF86DGA) */

static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
	LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
) {
  ICOM_THIS(IDirectDraw2Impl,iface);
  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));
	DUMP("\n");
      }
      
      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;
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
	LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	TRACE(ddraw,"(%p)->(%p)\n",This,lpddsfd);
	lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
	lpddsfd->dwHeight = This->d.height;
	lpddsfd->dwWidth = This->d.width;
	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;
}
#endif /* defined(HAVE_LIBXXF86DGA) */

static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
	LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
	lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
	lpddsfd->dwHeight = This->d.height;
	lpddsfd->dwWidth = This->d.width;
	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 IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	TRACE(ddraw,"(%p)->()\n",This);
	return DD_OK;
}

static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
	LPDIRECTDRAW2 iface,LPDWORD freq
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	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 IDirectDraw2Impl_GetFourCCCodes(
	LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	FIXME(ddraw,"(%p,%p,%p), stub\n",This,x,y);
	return DD_OK;
}

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

static HRESULT WINAPI IDirectDraw2Impl_Compact(
          LPDIRECTDRAW2 iface )
{
  ICOM_THIS(IDirectDraw2Impl,iface);
  FIXME(ddraw,"(%p)->()\n", This );
 
  return DD_OK;
}

static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
						 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
  ICOM_THIS(IDirectDraw2Impl,iface);
  FIXME(ddraw,"(%p)->(%p)\n", This, lplpGDIDDSSurface);

  return DD_OK;
}

static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
					       LPDWORD lpdwScanLine) {
  ICOM_THIS(IDirectDraw2Impl,iface);
  FIXME(ddraw,"(%p)->(%p)\n", This, lpdwScanLine);

  return DD_OK;
}

static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
					      GUID *lpGUID) {
  ICOM_THIS(IDirectDraw2Impl,iface);
  FIXME(ddraw,"(%p)->(%p)\n", This, lpGUID);
  
  return DD_OK;
}

#ifdef HAVE_LIBXXF86DGA

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

static ICOM_VTABLE(IDirectDraw) dga_ddvt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
	XCAST(AddRef)IDirectDraw2Impl_AddRef,
	XCAST(Release)DGA_IDirectDraw2Impl_Release,
	XCAST(Compact)IDirectDraw2Impl_Compact,
	XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
	XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
	XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
	XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
	XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
	XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
	XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
	XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
	XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
	XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
	XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
	XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
	XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
	XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
	XCAST(Initialize)IDirectDraw2Impl_Initialize,
	XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
	XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
	DGA_IDirectDrawImpl_SetDisplayMode,
	XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
};

#undef XCAST

#endif /* defined(HAVE_LIBXXF86DGA) */

/* Note: Hack so we can reuse the old functions without compiler warnings */
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun)	(typeof(xlib_ddvt.fn##fun))
#else
# define XCAST(fun)	(void *)
#endif

static ICOM_VTABLE(IDirectDraw) xlib_ddvt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
	XCAST(AddRef)IDirectDraw2Impl_AddRef,
	XCAST(Release)Xlib_IDirectDraw2Impl_Release,
	XCAST(Compact)IDirectDraw2Impl_Compact,
	XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
	XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
	XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
	XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
	XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
	XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
	XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
	XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
	XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
	XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
	XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
	XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
	XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
	XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
	XCAST(Initialize)IDirectDraw2Impl_Initialize,
	XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
	XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
	Xlib_IDirectDrawImpl_SetDisplayMode,
	XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
};

#undef XCAST

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


#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
	LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
) {
	return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
}
#endif /* defined(HAVE_LIBXXF86DGA) */

static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
	LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
) {
	return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
}

#ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
	LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
) {
        ICOM_THIS(IDirectDraw2Impl,iface);
	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;
}
#endif /* defined(HAVE_LIBXXF86DGA) */

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

#ifdef HAVE_LIBXXF86DGA
static ICOM_VTABLE(IDirectDraw2) dga_dd2vt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	DGA_IDirectDraw2Impl_QueryInterface,
	IDirectDraw2Impl_AddRef,
	DGA_IDirectDraw2Impl_Release,
	IDirectDraw2Impl_Compact,
	IDirectDraw2Impl_CreateClipper,
	DGA_IDirectDraw2Impl_CreatePalette,
	DGA_IDirectDraw2Impl_CreateSurface,
	IDirectDraw2Impl_DuplicateSurface,
	DGA_IDirectDraw2Impl_EnumDisplayModes,
	IDirectDraw2Impl_EnumSurfaces,
	IDirectDraw2Impl_FlipToGDISurface,
	DGA_IDirectDraw2Impl_GetCaps,
	DGA_IDirectDraw2Impl_GetDisplayMode,
	IDirectDraw2Impl_GetFourCCCodes,
	IDirectDraw2Impl_GetGDISurface,
	IDirectDraw2Impl_GetMonitorFrequency,
	IDirectDraw2Impl_GetScanLine,
	IDirectDraw2Impl_GetVerticalBlankStatus,
	IDirectDraw2Impl_Initialize,
	DGA_IDirectDraw2Impl_RestoreDisplayMode,
	IDirectDraw2Impl_SetCooperativeLevel,
	DGA_IDirectDraw2Impl_SetDisplayMode,
	IDirectDraw2Impl_WaitForVerticalBlank,
	DGA_IDirectDraw2Impl_GetAvailableVidMem
};
#endif /* defined(HAVE_LIBXXF86DGA) */

static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	Xlib_IDirectDraw2Impl_QueryInterface,
	IDirectDraw2Impl_AddRef,
	Xlib_IDirectDraw2Impl_Release,
	IDirectDraw2Impl_Compact,
	IDirectDraw2Impl_CreateClipper,
	Xlib_IDirectDraw2Impl_CreatePalette,
	Xlib_IDirectDraw2Impl_CreateSurface,
	IDirectDraw2Impl_DuplicateSurface,
	Xlib_IDirectDraw2Impl_EnumDisplayModes,
	IDirectDraw2Impl_EnumSurfaces,
	IDirectDraw2Impl_FlipToGDISurface,
	Xlib_IDirectDraw2Impl_GetCaps,
	Xlib_IDirectDraw2Impl_GetDisplayMode,
	IDirectDraw2Impl_GetFourCCCodes,
	IDirectDraw2Impl_GetGDISurface,
	IDirectDraw2Impl_GetMonitorFrequency,
	IDirectDraw2Impl_GetScanLine,
	IDirectDraw2Impl_GetVerticalBlankStatus,
	IDirectDraw2Impl_Initialize,
	Xlib_IDirectDraw2Impl_RestoreDisplayMode,
	IDirectDraw2Impl_SetCooperativeLevel,
	Xlib_IDirectDraw2Impl_SetDisplayMode,
	IDirectDraw2Impl_WaitForVerticalBlank,
	Xlib_IDirectDraw2Impl_GetAvailableVidMem	
};

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

static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
						    HDC hdc,
						    LPDIRECTDRAWSURFACE *lpDDS) {
  ICOM_THIS(IDirectDraw4Impl,iface);
  FIXME(ddraw, "(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);

  return DD_OK;
}

static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
  ICOM_THIS(IDirectDraw4Impl,iface);
  FIXME(ddraw, "(%p)->()\n", This);

  return DD_OK;
}

static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
  ICOM_THIS(IDirectDraw4Impl,iface);
  FIXME(ddraw, "(%p)->()\n", This);

  return DD_OK;
}

static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
						       LPDDDEVICEIDENTIFIER lpdddi,
						       DWORD dwFlags) {
  ICOM_THIS(IDirectDraw4Impl,iface);
  FIXME(ddraw, "(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
  
  return DD_OK;
}

#ifdef HAVE_LIBXXF86DGA

#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun)	(typeof(dga_dd4vt.fn##fun))
#else
# define XCAST(fun)	(void*)
#endif

static ICOM_VTABLE(IDirectDraw4) dga_dd4vt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
	XCAST(AddRef)IDirectDraw2Impl_AddRef,
	XCAST(Release)DGA_IDirectDraw2Impl_Release,
	XCAST(Compact)IDirectDraw2Impl_Compact,
	XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
	XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
	XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
	XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
	XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
	XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
	XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
	XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
	XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
	XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
	XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
	XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
	XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
	XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
	XCAST(Initialize)IDirectDraw2Impl_Initialize,
	XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
	XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
	XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
	XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
	XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
	IDirectDraw4Impl_GetSurfaceFromDC,
	IDirectDraw4Impl_RestoreAllSurfaces,
	IDirectDraw4Impl_TestCooperativeLevel,
	IDirectDraw4Impl_GetDeviceIdentifier
};

#undef XCAST

#endif /* defined(HAVE_LIBXXF86DGA) */

#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun)	(typeof(xlib_dd4vt.fn##fun))
#else
# define XCAST(fun)	(void*)
#endif

static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
	XCAST(AddRef)IDirectDraw2Impl_AddRef,
	XCAST(Release)Xlib_IDirectDraw2Impl_Release,
	XCAST(Compact)IDirectDraw2Impl_Compact,
	XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
	XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
	XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
	XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
	XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
	XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
	XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
	XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
	XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
	XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
	XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
	XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
	XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
	XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
	XCAST(Initialize)IDirectDraw2Impl_Initialize,
	XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
	XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
	XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
	XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
	XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
	IDirectDraw4Impl_GetSurfaceFromDC,
	IDirectDraw4Impl_RestoreAllSurfaces,
	IDirectDraw4Impl_TestCooperativeLevel,
	IDirectDraw4Impl_GetDeviceIdentifier
};

#undef XCAST

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

LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
   LRESULT ret;
   IDirectDrawImpl* 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  = (IDirectDrawImpl*)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 )
        {
          WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
          /* We didn't handle the message - give it to the application */
          if (ddraw && ddraw->d.mainWindow && tmpWnd)
          {
          	ret = CallWindowProcA(tmpWnd->winproc,
               	                   ddraw->d.mainWindow, msg, wParam, lParam );
	  }
          WIN_ReleaseWndPtr(tmpWnd);

        }
        
      } 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
        IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
	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;
	}
	*ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
	(*ilplpDD)->lpvtbl = &dga_ddvt;
	(*ilplpDD)->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);
	(*ilplpDD)->e.dga.fb_width = width;
	TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
	TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
	(*ilplpDD)->e.dga.fb_height = height;
	TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
		addr,width,banksize,memsize
	);
	TRACE(ddraw,"viewport height: %d\n",height);

	/* Get the screen dimensions as seen by Wine.
	   In that case, it may be better to ignore the -desktop mode and return the
	   real screen size => print a warning */
	(*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
	(*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
	if (((*ilplpDD)->d.height != height) ||
	    ((*ilplpDD)->d.width != width))
	  WARN(ddraw, "You seem to be runnin in -desktop mode. This may prove dangerous in DGA mode...\n");
	(*ilplpDD)->e.dga.fb_addr = addr;
	(*ilplpDD)->e.dga.fb_memsize = memsize;
	(*ilplpDD)->e.dga.fb_banksize = banksize;
	(*ilplpDD)->e.dga.vpmask = 0;

	/* just assume the default depth is the DGA depth too */
	depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
	_common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
#ifdef RESTORE_SIGNALS
	EXC_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) {
        IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
	int depth;

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

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

#ifdef HAVE_LIBXXSHM
	/* Test if XShm is available. */
	if (((*ilplpDD)->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 ) {
        IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
	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,ilplpDD,pUnkOuter);

	if ((!lpGUID) ||
	    (!memcmp(lpGUID,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
	    (!memcmp(lpGUID,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
	    (!memcmp(lpGUID,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
		/* 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 */
        /*
         This code is not useful since hInstance is forced to 0 afterward
        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;


	(*ilplpDD)->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) */


/*******************************************************************************
 * DirectDraw ClassFactory
 *
 *  Heavily inspired (well, can you say completely copied :-) ) from DirectSound
 *
 */
typedef struct
{
    /* IUnknown fields */
    ICOM_VTABLE(IClassFactory)* lpvtbl;
    DWORD                       ref;
} IClassFactoryImpl;

static HRESULT WINAPI 
DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
	ICOM_THIS(IClassFactoryImpl,iface);
	char buf[80];

	if (HIWORD(riid))
	    WINE_StringFromCLSID(riid,buf);
	else
	    sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
	FIXME(ddraw,"(%p)->(%s,%p),stub!\n",This,buf,ppobj);
	return E_NOINTERFACE;
}

static ULONG WINAPI
DDCF_AddRef(LPCLASSFACTORY iface) {
	ICOM_THIS(IClassFactoryImpl,iface);
	return ++(This->ref);
}

static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
	ICOM_THIS(IClassFactoryImpl,iface);
	/* static class, won't be  freed */
	return --(This->ref);
}

static HRESULT WINAPI DDCF_CreateInstance(
	LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
) {
	ICOM_THIS(IClassFactoryImpl,iface);
	char buf[80];

	WINE_StringFromCLSID(riid,buf);
	TRACE(ddraw,"(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
	if ((!memcmp(riid,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
	    (!memcmp(riid,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
	    (!memcmp(riid,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
		/* FIXME: reuse already created DirectDraw if present? */
		return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
	}
	return E_NOINTERFACE;
}

static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
	ICOM_THIS(IClassFactoryImpl,iface);
	FIXME(ddraw,"(%p)->(%d),stub!\n",This,dolock);
	return S_OK;
}

static ICOM_VTABLE(IClassFactory) DDCF_Vtbl = 
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	DDCF_QueryInterface,
	DDCF_AddRef,
	DDCF_Release,
	DDCF_CreateInstance,
	DDCF_LockServer
};
static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };

/*******************************************************************************
 * DllGetClassObject [DDRAW.13]
 * Retrieves class object from a DLL object
 *
 * NOTES
 *    Docs say returns STDAPI
 *
 * PARAMS
 *    rclsid [I] CLSID for the class object
 *    riid   [I] Reference to identifier of interface for class object
 *    ppv    [O] Address of variable to receive interface pointer for riid
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
 *             E_UNEXPECTED
 */
DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
{
    char buf[80],xbuf[80];

    if (HIWORD(rclsid))
    	WINE_StringFromCLSID(rclsid,xbuf);
    else
    	sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
    if (HIWORD(riid))
    	WINE_StringFromCLSID(riid,buf);
    else
    	sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
    WINE_StringFromCLSID(riid,xbuf);
    TRACE(ddraw, "(%p,%p,%p)\n", xbuf, buf, ppv);
    if (!memcmp(riid,&IID_IClassFactory,sizeof(IID_IClassFactory))) {
    	*ppv = (LPVOID)&DDRAW_CF;
	IClassFactory_AddRef((IClassFactory*)*ppv);
    return S_OK;
    }
    FIXME(ddraw, "(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
    return E_NOINTERFACE;
}


/*******************************************************************************
 * DllCanUnloadNow [DDRAW.12]  Determines whether the DLL is in use.
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: S_FALSE
 */
DWORD WINAPI DDRAW_DllCanUnloadNow(void)
{
    FIXME(ddraw, "(void): stub\n");
    return S_FALSE;
}
