/* Direct3D Texture
 * Copyright (c) 1998 Lionel ULMER
 *
 * This file contains the implementation of interface Direct3DTexture2.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <string.h>

#include "windef.h"
#include "winerror.h"
#include "wine/obj_base.h"
#include "ddraw.h"
#include "d3d.h"
#include "wine/debug.h"

#include "mesa_private.h"

#define D3DDPRIVATE(x) mesa_d3dd_private*odev=(mesa_d3dd_private*)(x)->private
#define D3DTPRIVATE(x) mesa_d3dt_private*dtpriv=(mesa_d3dt_private*)(x)->private

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);

/* Define this if you want to save to a file all the textures used by a game
   (can be funny to see how they managed to cram all the pictures in
   texture memory) */
#undef TEXTURE_SNOOP

#ifdef TEXTURE_SNOOP
#include <stdio.h>

#define SNOOP_PALETTED() 									\
      {												\
	FILE *f;										\
	char buf[32];										\
	int x, y;										\
												\
	sprintf(buf, "%ld.pnm", dtpriv->tex_name);							\
	f = fopen(buf, "wb");									\
	fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);			\
	for (y = 0; y < src_d->dwHeight; y++) {							\
	  for (x = 0; x < src_d->dwWidth; x++) {						\
	    unsigned char c = ((unsigned char *) src_d->y.lpSurface)[y * src_d->dwWidth + x];	\
	    fputc(table[c][0], f);								\
	    fputc(table[c][1], f);								\
	    fputc(table[c][2], f);								\
	  }											\
	}											\
	fclose(f);										\
      }

#define SNOOP_5650()											\
	  {												\
	    FILE *f;											\
	    char buf[32];										\
	    int x, y;											\
	    												\
	    sprintf(buf, "%ld.pnm", dtpriv->tex_name);							\
	    f = fopen(buf, "wb");									\
	    fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);				\
	    for (y = 0; y < src_d->dwHeight; y++) {							\
	      for (x = 0; x < src_d->dwWidth; x++) {							\
		unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x];	\
		fputc((c & 0xF800) >> 8, f);								\
		fputc((c & 0x07E0) >> 3, f);								\
		fputc((c & 0x001F) << 3, f);								\
	      }												\
	    }												\
	    fclose(f);											\
	  }

#define SNOOP_5551()											\
	  {												\
	    FILE *f;											\
	    char buf[32];										\
	    int x, y;											\
	    												\
	    sprintf(buf, "%ld.pnm", dtpriv->tex_name);							\
	    f = fopen(buf, "wb");									\
	    fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);				\
	    for (y = 0; y < src_d->dwHeight; y++) {							\
	      for (x = 0; x < src_d->dwWidth; x++) {							\
		unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x];	\
		fputc((c & 0xF800) >> 8, f);								\
		fputc((c & 0x07C0) >> 3, f);								\
		fputc((c & 0x003E) << 2, f);								\
	      }												\
	    }												\
	    fclose(f);											\
	  }
#else
#define SNOOP_PALETTED()
#define SNOOP_5650()
#define SNOOP_5551()
#endif

extern ICOM_VTABLE(IDirect3DTexture2) mesa_texture2_vtable;
extern ICOM_VTABLE(IDirect3DTexture) mesa_texture_vtable;

/*******************************************************************************
 *				Texture2 Creation functions
 */
LPDIRECT3DTEXTURE2 d3dtexture2_create(IDirectDrawSurfaceImpl* surf)
{
  IDirect3DTexture2Impl* tex;

  tex = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2Impl));
  tex->ref = 1;
  ICOM_VTBL(tex) = &mesa_texture2_vtable;
  tex->surface = surf;

  tex->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dt_private));

  return (LPDIRECT3DTEXTURE2)tex;
}

/*******************************************************************************
 *				Texture Creation functions
 */
LPDIRECT3DTEXTURE d3dtexture_create(IDirectDrawSurfaceImpl* surf)
{
  IDirect3DTexture2Impl* tex;

  tex = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2Impl));
  tex->ref = 1;
  ICOM_VTBL(tex) = (ICOM_VTABLE(IDirect3DTexture2)*)&mesa_texture_vtable;
  tex->surface = surf;

  tex->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dt_private));

  return (LPDIRECT3DTEXTURE)tex;
}

/*******************************************************************************
 *			   IDirectSurface callback methods
 */
HRESULT WINAPI  SetColorKey_cb(IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey )
{
  DDSURFACEDESC	*tex_d;
  D3DTPRIVATE(texture);
  int bpp;
  GLuint current_texture;

  TRACE("(%p) : colorkey callback\n", texture);

  /* Get the texture description */
  tex_d = (DDSURFACEDESC *)&(texture->surface->surface_desc);
  bpp = (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ?
	 1 /* 8 bit of palette index */:
	 tex_d->ddpfPixelFormat.u1.dwRGBBitCount / 8 /* RGB bits for each colors */ );

  /* Now, save the current texture */
  ENTER_GL();
  glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);

  /* If the GetHandle was not done yet, it's an error */
  if (dtpriv->tex_name == 0) {
    ERR("Unloaded texture !\n");
    LEAVE_GL();
    return DD_OK;
  }
  glBindTexture(GL_TEXTURE_2D, dtpriv->tex_name);

  if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
    FIXME("Todo Paletted\n");
  } else if (tex_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
    if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
      FIXME("Todo 3_3_2_0\n");
    } else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
      if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
	/* Now transform the 5_6_5 into a 5_5_5_1 surface to support color keying */
	unsigned short *dest = (unsigned short *) HeapAlloc(GetProcessHeap(),
							    HEAP_ZERO_MEMORY,
							    tex_d->dwWidth * tex_d->dwHeight * bpp);
	unsigned short *src = (unsigned short *) tex_d->lpSurface;
	int x, y;

	for (y = 0; y < tex_d->dwHeight; y++) {
	  for (x = 0; x < tex_d->dwWidth; x++) {
	    unsigned short cpixel = src[x + y * tex_d->dwWidth];

	    if ((dwFlags & DDCKEY_SRCBLT) &&
		(cpixel >= ckey->dwColorSpaceLowValue) &&
		(cpixel <= ckey->dwColorSpaceHighValue)) /* No alpha bit => this pixel is transparent */
	      dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0000;
	    else                                         /* Alpha bit is set => this pixel will be seen */
	      dest[x + y * tex_d->dwWidth] = (cpixel & ~0x003F) | ((cpixel & 0x001F) << 1) | 0x0001;
	  }
	}

	glTexImage2D(GL_TEXTURE_2D,
		     0,
		     GL_RGBA,
		     tex_d->dwWidth, tex_d->dwHeight,
		     0,
		     GL_RGBA,
		     GL_UNSIGNED_SHORT_5_5_5_1,
		     dest);

	/* Frees the temporary surface */
	HeapFree(GetProcessHeap(),0,dest);
      } else if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
	FIXME("Todo 5_5_5_1\n");
      } else if (tex_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
	FIXME("Todo 4_4_4_4\n");
      } else {
	ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
      }
    } else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
      FIXME("Todo 8_8_8_0\n");
    } else if (tex_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
      FIXME("Todo 8_8_8_8\n");
    } else {
      ERR("Unhandled texture format (bad RGB count)\n");
    }
  } else {
    ERR("Unhandled texture format (neither RGB nor INDEX)\n");
  }
  LEAVE_GL();

  return DD_OK;
}

/*******************************************************************************
 *				IDirect3DTexture2 methods
 */

HRESULT WINAPI IDirect3DTexture2Impl_QueryInterface(LPDIRECT3DTEXTURE2 iface,
							REFIID riid,
							LPVOID* ppvObj)
{
  ICOM_THIS(IDirect3DTexture2Impl,iface);

  FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);

  return S_OK;
}



ULONG WINAPI IDirect3DTexture2Impl_AddRef(LPDIRECT3DTEXTURE2 iface)
{
  ICOM_THIS(IDirect3DTexture2Impl,iface);
  TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );

  return ++(This->ref);
}



ULONG WINAPI IDirect3DTexture2Impl_Release(LPDIRECT3DTEXTURE2 iface)
{
  ICOM_THIS(IDirect3DTexture2Impl,iface);
  D3DTPRIVATE(This);
  FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );

  if (!--(This->ref)) {
    /* Delete texture from OpenGL */
    ENTER_GL();
    glDeleteTextures(1, &(dtpriv->tex_name));
    LEAVE_GL();

    /* Release surface */
    IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->surface);

    HeapFree(GetProcessHeap(),0,This);
    return 0;
  }

  return This->ref;
}

/*** IDirect3DTexture methods ***/
HRESULT WINAPI IDirect3DTextureImpl_GetHandle(LPDIRECT3DTEXTURE iface,
						 LPDIRECT3DDEVICE lpD3DDevice,
						 LPD3DTEXTUREHANDLE lpHandle)
{
    ICOM_THIS(IDirect3DTexture2Impl,iface);
    D3DTPRIVATE(This);
    IDirect3DDeviceImpl* ilpD3DDevice=(IDirect3DDeviceImpl*)lpD3DDevice;
    FIXME("(%p)->(%p,%p): stub\n", This, ilpD3DDevice, lpHandle);

    *lpHandle = (D3DTEXTUREHANDLE) This;

    /* Now, bind a new texture */
    ENTER_GL();
    ilpD3DDevice->set_context(ilpD3DDevice);
    This->D3Ddevice = (void *) ilpD3DDevice;
    if (dtpriv->tex_name == 0)
	glGenTextures(1, &(dtpriv->tex_name));
    LEAVE_GL();

    TRACE("OpenGL texture handle is : %d\n", dtpriv->tex_name);

    return D3D_OK;
}

HRESULT WINAPI IDirect3DTextureImpl_Initialize(LPDIRECT3DTEXTURE iface,
						  LPDIRECT3DDEVICE lpD3DDevice,
						  LPDIRECTDRAWSURFACE lpSurface)
{
  ICOM_THIS(IDirect3DTexture2Impl,iface);
  TRACE("(%p)->(%p,%p)\n", This, lpD3DDevice, lpSurface);

  return DDERR_ALREADYINITIALIZED;
}

HRESULT WINAPI IDirect3DTextureImpl_Unload(LPDIRECT3DTEXTURE iface)
{
  ICOM_THIS(IDirect3DTexture2Impl,iface);
  FIXME("(%p)->(): stub\n", This);

  return D3D_OK;
}

/*** IDirect3DTexture2 methods ***/
HRESULT WINAPI IDirect3DTexture2Impl_GetHandle(LPDIRECT3DTEXTURE2 iface,
						  LPDIRECT3DDEVICE2 lpD3DDevice2,
						  LPD3DTEXTUREHANDLE lpHandle)
{
    ICOM_THIS(IDirect3DTexture2Impl,iface);
    D3DTPRIVATE(This);
    IDirect3DDevice2Impl* ilpD3DDevice2=(IDirect3DDevice2Impl*)lpD3DDevice2;
    TRACE("(%p)->(%p,%p)\n", This, ilpD3DDevice2, lpHandle);

    /* For 32 bits OSes, handles = pointers */
    *lpHandle = (D3DTEXTUREHANDLE) This;

    /* Now, bind a new texture */
    ENTER_GL();
    ilpD3DDevice2->set_context(ilpD3DDevice2);
    This->D3Ddevice = (void *) ilpD3DDevice2;
    if (dtpriv->tex_name == 0)
	glGenTextures(1, &(dtpriv->tex_name));
    LEAVE_GL();

    TRACE("OpenGL texture handle is : %d\n", dtpriv->tex_name);

    return D3D_OK;
}

/* Common methods */
HRESULT WINAPI IDirect3DTexture2Impl_PaletteChanged(
    LPDIRECT3DTEXTURE2 iface, DWORD dwStart, DWORD dwCount
) {
  ICOM_THIS(IDirect3DTexture2Impl,iface);
  FIXME("(%p)->(%8ld,%8ld): stub\n", This, dwStart, dwCount);

  return D3D_OK;
}

/* NOTE : if you experience crashes in this function, you must have a buggy
          version of Mesa. See the file d3dtexture.c for a cure */
HRESULT WINAPI IDirect3DTexture2Impl_Load(
    LPDIRECT3DTEXTURE2 iface, LPDIRECT3DTEXTURE2 lpD3DTexture2
) {
  ICOM_THIS(IDirect3DTexture2Impl,iface);
  D3DTPRIVATE(This);
  IDirect3DTexture2Impl* ilpD3DTexture2=(IDirect3DTexture2Impl*)lpD3DTexture2;
  DDSURFACEDESC	*src_d, *dst_d;
  static void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
				    GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
#if 0
  static BOOL color_table_queried = FALSE;
#endif

  TRACE("(%p)->(%p)\n", This, ilpD3DTexture2);
  TRACE("Copied surface %p to surface %p\n", ilpD3DTexture2->surface, This->surface);

  /* Suppress the ALLOCONLOAD flag */
  This->surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;

  /* Copy one surface on the other */
  dst_d = (DDSURFACEDESC *)&(This->surface->surface_desc);
  src_d = (DDSURFACEDESC *)&(ilpD3DTexture2->surface->surface_desc);

  /* Install the callbacks to the destination surface */
  This->surface->texture = This;
  This->surface->SetColorKey_cb = SetColorKey_cb;

  if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
    /* Should also check for same pixel format, lPitch, ... */
    ERR("Error in surface sizes\n");
    return D3DERR_TEXTURE_LOAD_FAILED;
  } else {
    /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
    /* I should put a macro for the calculus of bpp */
    int bpp = (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ?
	       1 /* 8 bit of palette index */:
	       src_d->ddpfPixelFormat.u1.dwRGBBitCount / 8 /* RGB bits for each colors */ );
    GLuint current_texture;

    /* Copy the main memry texture into the surface that corresponds to the OpenGL
       texture object. */
    memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->dwWidth * src_d->dwHeight * bpp);

    ENTER_GL();

    /* Now, load the texture */
    /* d3dd->set_context(d3dd); We need to set the context somehow.... */
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);

    /* If the GetHandle was not done, get the texture name here */
    if (dtpriv->tex_name == 0)
      glGenTextures(1, &(dtpriv->tex_name));
    glBindTexture(GL_TEXTURE_2D, dtpriv->tex_name);

    if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
      /* ****************
	 Paletted Texture
	 **************** */
      IDirectDrawPaletteImpl* pal = This->surface->palette;
      BYTE table[256][4];
      int i;

#if 0
      if (color_table_queried == FALSE) {
	ptr_ColorTableEXT =
	  ((Mesa_DeviceCapabilities *) ((x11_dd_private *) This->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
      }
#endif

      if (pal == NULL) {
	ERR("Palettized texture Loading with a NULL palette !\n");
	LEAVE_GL();
	return D3DERR_TEXTURE_LOAD_FAILED;
      }

      /* Get the surface's palette */
      for (i = 0; i < 256; i++) {
	table[i][0] = pal->palents[i].peRed;
	table[i][1] = pal->palents[i].peGreen;
	table[i][2] = pal->palents[i].peBlue;
	if ((This->surface->surface_desc.dwFlags & DDSD_CKSRCBLT) &&
	    (i >= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) &&
	    (i <= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
	  table[i][3] = 0x00;
	else
	table[i][3] = 0xFF;
      }

      /* Texture snooping */
      SNOOP_PALETTED();

      if (ptr_ColorTableEXT != NULL) {
	/* use Paletted Texture Extension */
	ptr_ColorTableEXT(GL_TEXTURE_2D,    /* target */
			  GL_RGBA,          /* internal format */
			  256,              /* table size */
			  GL_RGBA,          /* table format */
			  GL_UNSIGNED_BYTE, /* table type */
			  table);           /* the color table */

	glTexImage2D(GL_TEXTURE_2D,       /* target */
		     0,                   /* level */
		     GL_COLOR_INDEX8_EXT, /* internal format */
		     src_d->dwWidth, src_d->dwHeight, /* width, height */
		     0,                   /* border */
		     GL_COLOR_INDEX,      /* texture format */
		     GL_UNSIGNED_BYTE,    /* texture type */
		     src_d->lpSurface); /* the texture */
      } else {
	DWORD *surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
	DWORD i;
	BYTE *src = (BYTE *) src_d->lpSurface, *dst = (BYTE *) surface;

	for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
	  BYTE color = *src++;
	  *dst++ = table[color][0];
	  *dst++ = table[color][1];
	  *dst++ = table[color][2];
	  *dst++ = table[color][3];
	}

	glTexImage2D(GL_TEXTURE_2D,
		     0,
		     GL_RGBA,
		     src_d->dwWidth, src_d->dwHeight,
		     0,
		     GL_RGBA,
		     GL_UNSIGNED_BYTE,
		     surface);

	HeapFree(GetProcessHeap(), 0, surface);
      }
    } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
      /* ************
	 RGB Textures
	 ************ */
      if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
	/* **********************
	   GL_UNSIGNED_BYTE_3_3_2
	   ********************** */
	glTexImage2D(GL_TEXTURE_2D,
		     0,
		     GL_RGB,
		     src_d->dwWidth, src_d->dwHeight,
		     0,
		     GL_RGB,
		     GL_UNSIGNED_BYTE_3_3_2,
		     src_d->lpSurface);
      } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
	if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {

	  /* Texture snooping */
	  SNOOP_5650();

	  glTexImage2D(GL_TEXTURE_2D,
		       0,
		       GL_RGB,
		       src_d->dwWidth, src_d->dwHeight,
		       0,
		       GL_RGB,
		       GL_UNSIGNED_SHORT_5_6_5,
		       src_d->lpSurface);
	} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
	  /* Texture snooping */
	  SNOOP_5551();

	  glTexImage2D(GL_TEXTURE_2D,
		       0,
		       GL_RGBA,
		       src_d->dwWidth, src_d->dwHeight,
		       0,
		       GL_RGBA,
		       GL_UNSIGNED_SHORT_5_5_5_1,
		       src_d->lpSurface);
	} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
	  glTexImage2D(GL_TEXTURE_2D,
		       0,
		       GL_RGBA,
		       src_d->dwWidth, src_d->dwHeight,
		       0,
		       GL_RGBA,
		       GL_UNSIGNED_SHORT_4_4_4_4,
		       src_d->lpSurface);
	} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
	  /* Converting the 1555 format in 5551 packed */
	  WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
	  DWORD i;
	  WORD *src = (WORD *) src_d->lpSurface, *dst = surface;

	  for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
	    *dst++ = (((*src & 0x8000) >> 15) |
		      ((*src & 0x7FFF) <<  1));
	    src++;
	  }

	  glTexImage2D(GL_TEXTURE_2D,
		       0,
		       GL_RGBA,
		       src_d->dwWidth, src_d->dwHeight,
		       0,
		       GL_RGBA,
		       GL_UNSIGNED_SHORT_5_5_5_1,
		       surface);

	  HeapFree(GetProcessHeap(), 0, surface);
	} else {
	  ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
	}
      } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
	glTexImage2D(GL_TEXTURE_2D,
		     0,
		     GL_RGB,
		     src_d->dwWidth, src_d->dwHeight,
		     0,
		     GL_RGB,
		     GL_UNSIGNED_BYTE,
		     src_d->lpSurface);
      } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
	glTexImage2D(GL_TEXTURE_2D,
		     0,
		     GL_RGBA,
		     src_d->dwWidth, src_d->dwHeight,
		     0,
		     GL_RGBA,
		     GL_UNSIGNED_BYTE,
		     src_d->lpSurface);
      } else {
	ERR("Unhandled texture format (bad RGB count)\n");
      }
    } else {
      ERR("Unhandled texture format (neither RGB nor INDEX)\n");
    }

    glBindTexture(GL_TEXTURE_2D, current_texture);

    LEAVE_GL();
  }

  return D3D_OK;
}


/*******************************************************************************
 *				IDirect3DTexture2 VTable
 */
ICOM_VTABLE(IDirect3DTexture2) mesa_texture2_vtable =
{
  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
  /*** IUnknown methods ***/
  IDirect3DTexture2Impl_QueryInterface,
  IDirect3DTexture2Impl_AddRef,
  IDirect3DTexture2Impl_Release,
  /*** IDirect3DTexture methods ***/
  IDirect3DTexture2Impl_GetHandle,
  IDirect3DTexture2Impl_PaletteChanged,
  IDirect3DTexture2Impl_Load
};

/*******************************************************************************
 *				IDirect3DTexture VTable
 */
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun)	(typeof(mesa_texture_vtable.fun))
#else
# define XCAST(fun)	(void*)
#endif

ICOM_VTABLE(IDirect3DTexture) mesa_texture_vtable =
{
  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
  /*** IUnknown methods ***/
  XCAST(QueryInterface)IDirect3DTexture2Impl_QueryInterface,
  XCAST(AddRef)IDirect3DTexture2Impl_AddRef,
  XCAST(Release)IDirect3DTexture2Impl_Release,
  /*** IDirect3DTexture methods ***/
  IDirect3DTextureImpl_Initialize,
  IDirect3DTextureImpl_GetHandle,
  XCAST(PaletteChanged)IDirect3DTexture2Impl_PaletteChanged,
  XCAST(Load)IDirect3DTexture2Impl_Load,
  IDirect3DTextureImpl_Unload
};

#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
#undef XCAST
#endif
