/*
 * X11DRV device-independent bitmaps
 *
 * Copyright 1993,1994  Alexandre Julliard
 */

#include "config.h"

#include "ts_xlib.h"
#include "ts_xutil.h"
#ifdef HAVE_LIBXXSHM
# include "ts_xshm.h"
# ifdef HAVE_SYS_SHM_H
#  include <sys/shm.h>
# endif
# ifdef HAVE_SYS_IPC_H
#  include <sys/ipc.h>
# endif
#endif /* defined(HAVE_LIBXXSHM) */

#include <stdlib.h>
#include <string.h>
#include "windef.h"
#include "bitmap.h"
#include "x11drv.h"
#include "debugtools.h"
#include "gdi.h"
#include "color.h"
#include "selectors.h"
#include "global.h"

DEFAULT_DEBUG_CHANNEL(bitmap);
DECLARE_DEBUG_CHANNEL(x11drv);

static int ximageDepthTable[32];

#ifdef HAVE_LIBXXSHM
static int XShmErrorFlag = 0;
#endif

/* This structure holds the arguments for DIB_SetImageBits() */
typedef struct
{
    struct tagDC   *dc;
    LPCVOID         bits;
    XImage         *image;
    PALETTEENTRY   *palentry;
    int             lines;
    DWORD           infoWidth;
    WORD            depth;
    WORD            infoBpp;
    WORD            compression;
    RGBQUAD        *colorMap;
    int             nColorMap;
    Drawable        drawable;
    GC              gc;
    int             xSrc;
    int             ySrc;
    int             xDest;
    int             yDest;
    int             width;
    int             height;
    DWORD           rMask;
    DWORD           gMask;
    DWORD           bMask;
    BOOL            useShm;
    int             dibpitch;
} X11DRV_DIB_IMAGEBITS_DESCR;


/***********************************************************************
 *           X11DRV_DIB_GetXImageWidthBytes
 *
 * Return the width of an X image in bytes
 */
inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
{
    if (!depth || depth > 32) goto error;

    if (!ximageDepthTable[depth-1])
    {
        XImage *testimage = XCreateImage( gdi_display, visual, depth,
                                          ZPixmap, 0, NULL, 1, 1, 32, 20 );
        if (testimage)
        {
            ximageDepthTable[depth-1] = testimage->bits_per_pixel;
            XDestroyImage( testimage );
        }
        else ximageDepthTable[depth-1] = -1;
    }
    if (ximageDepthTable[depth-1] != -1)
        return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));

 error:
    WARN( "(%d): Unsupported depth\n", depth );
    return 4 * width;
}


/***********************************************************************
 *           X11DRV_DIB_CreateXImage
 *
 * Create an X image.
 */
XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
{
    int width_bytes;
    XImage *image;

    wine_tsx11_lock();
    width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
    image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
                          calloc( height, width_bytes ),
                          width, height, 32, width_bytes );
    wine_tsx11_unlock();
    return image;
}


/***********************************************************************
 *           X11DRV_DIB_GenColorMap
 *
 * Fills the color map of a bitmap palette. Should not be called
 * for a >8-bit deep bitmap.
 */
int *X11DRV_DIB_GenColorMap( DC *dc, int *colorMapping,
                             WORD coloruse, WORD depth, BOOL quads,
                             const void *colorPtr, int start, int end )
{
    int i;

    if (coloruse == DIB_RGB_COLORS)
    {
        if (quads)
        {
            RGBQUAD * rgb = (RGBQUAD *)colorPtr;

            if (depth == 1)  /* Monochrome */
                for (i = start; i < end; i++, rgb++)
                    colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
                                       rgb->rgbBlue > 255*3/2);
            else
                for (i = start; i < end; i++, rgb++)
                    colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbRed,
                                                                rgb->rgbGreen,
                                                                rgb->rgbBlue));
        }
        else
        {
            RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;

            if (depth == 1)  /* Monochrome */
                for (i = start; i < end; i++, rgb++)
                    colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
                                       rgb->rgbtBlue > 255*3/2);
            else
                for (i = start; i < end; i++, rgb++)
                    colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbtRed,
                                                               rgb->rgbtGreen,
                                                               rgb->rgbtBlue));
        }
    }
    else  /* DIB_PAL_COLORS */
    {
        if (colorPtr) {
            WORD * index = (WORD *)colorPtr;

            for (i = start; i < end; i++, index++)
                colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) );
        } else {
            for (i = start; i < end; i++)
                colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(i) );
        }
    }

    return colorMapping;
}

/***********************************************************************
 *           X11DRV_DIB_BuildColorMap
 *
 * Build the color map from the bitmap palette. Should not be called
 * for a >8-bit deep bitmap.
 */
int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth, 
                               const BITMAPINFO *info, int *nColors )
{
    int colors;
    BOOL isInfo;
    const void *colorPtr;
    int *colorMapping;

    if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
    {
        colors = info->bmiHeader.biClrUsed;
        if (!colors) colors = 1 << info->bmiHeader.biBitCount;
        colorPtr = info->bmiColors;
    }
    else  /* assume BITMAPCOREINFO */
    {
        colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
        colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
    }

    if (colors > 256)
    {
        ERR("called with >256 colors!\n");
        return NULL;
    }

    /* just so CopyDIBSection doesn't have to create an identity palette */
    if (coloruse == (WORD)-1) colorPtr = NULL;

    if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
                                          colors * sizeof(int) ))) 
	return NULL;

    *nColors = colors;
    return X11DRV_DIB_GenColorMap( dc, colorMapping, coloruse, depth,
                                   isInfo, colorPtr, 0, colors);
}


/***********************************************************************
 *           X11DRV_DIB_MapColor
 */
int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
{
    int color;

    if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
        return oldcol;

    for (color = 0; color < nPhysMap; color++)
        if (physMap[color] == phys)
            return color;

    WARN("Strange color %08x\n", phys);
    return 0;
}


/*********************************************************************
 *         X11DRV_DIB_GetNearestIndex
 *
 * Helper for X11DRV_DIB_GetDIBits.
 * Returns the nearest colour table index for a given RGB.
 * Nearest is defined by minimizing the sum of the squares.
 */
static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
{
    INT i, best = -1, diff, bestdiff = -1;
    RGBQUAD *color;

    for(color = colormap, i = 0; i < numColors; color++, i++) {
        diff = (r - color->rgbRed) * (r - color->rgbRed) +
	       (g - color->rgbGreen) * (g - color->rgbGreen) +
	       (b - color->rgbBlue) * (b - color->rgbBlue);
	if(diff == 0)
	    return i;
	if(best == -1 || diff < bestdiff) {
	    best = i;
	    bestdiff = diff;
	}
    }
    return best;
}

/***********************************************************************
 *           X11DRV_DIB_SetImageBits_1_Line
 *
 * Handles a single line of 1 bit data.
 */
static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
				    XImage *bmpImage, int h, const BYTE *bits)
{
    BYTE pix, extra;
    DWORD i, x;

    if((extra = (left & 7)) != 0) {
        left &= ~7;
	dstwidth += extra;
    }

    bits += left >> 3;

    /* FIXME: should avoid putting x<left pixels (minor speed issue) */
    for (i = dstwidth/8, x = left; i > 0; i--)
    {
	pix = *bits++;
	XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
	XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
	XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
	XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
	XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
	XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
	XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
	XPutPixel( bmpImage, x++, h, colors[pix & 1] );
    }
    pix = *bits;
    switch(dstwidth & 7)
    {
    case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
    case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
    case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
    case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
    case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
    case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
    case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
    }
}

/***********************************************************************
 *           X11DRV_DIB_SetImageBits_1
 *
 * SetDIBits for a 1-bit deep DIB.
 */
static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
                                DWORD srcwidth, DWORD dstwidth, int left,
                                int *colors, XImage *bmpImage, DWORD linebytes)
{
    int h;

    if (lines > 0) {
	for (h = lines-1; h >=0; h--) {
	    X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
					   srcbits);
	    srcbits += linebytes;
	}
    } else {
	lines = -lines;
	for (h = 0; h < lines; h++) {
	    X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
					   srcbits);
	    srcbits += linebytes;
	}
    }
}

/***********************************************************************
 *           X11DRV_DIB_GetImageBits_1
 *
 * GetDIBits for a 1-bit deep DIB.
 */
static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
				       DWORD dstwidth, DWORD srcwidth,
				       RGBQUAD *colors, PALETTEENTRY *srccolors, 
                                XImage *bmpImage, DWORD linebytes )
{
    DWORD x;
    int h;
    BYTE *bits;

    if (lines < 0 ) {
        lines = -lines;
	dstbits = dstbits + linebytes * (lines - 1);
	linebytes = -linebytes;
    }

    bits = dstbits;

    switch(bmpImage->depth) {

    case 1:
       /* ==== monochrome bitmap to monochrome dib ==== */
    case 4:
       /* ==== 4 colormap bitmap to monochrome dib ==== */
       if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
	 { 
	   PALETTEENTRY val;

	   for (h = lines - 1; h >= 0; h--) {
	     for (x = 0; x < dstwidth; x++) {
	       val = srccolors[XGetPixel(bmpImage, x, h)];
	       if (!(x&7)) *bits = 0;
	       *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, 
						    val.peRed,
						    val.peGreen, 
						    val.peBlue) << (7 - (x & 7)));
	       if ((x&7)==7) bits++;
	     }
	     bits = (dstbits += linebytes);
	   }
	 }
       else goto notsupported;
       
       break;
      
    case 8:
      /* ==== 8 colormap bitmap to monochrome dib ==== */
      if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
      {
	BYTE *srcpixel;
	PALETTEENTRY val;

       for( h = lines- 1; h >= 0; h-- ) {
	  srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
	  for( x = 0; x < dstwidth; x++ ) {
	    if (!(x&7)) *bits = 0;
	    val = srccolors[(int)*srcpixel++];
	    *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 2,
						  val.peRed,
						  val.peGreen,
						  val.peBlue) << (7-(x&7)) );
	    if ((x&7)==7) bits++;
	  }
	  bits = (dstbits += linebytes);
	}
      }
      else goto notsupported;

      break;
      
    case 15:
      {
	LPWORD srcpixel;
	WORD val;
	
	/* ==== 555 BGR bitmap to monochrome dib ==== */
	if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
	{
	  for( h = lines - 1; h >= 0; h--) {
		srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
		for( x = 0; x < dstwidth; x++) {
		  if (!(x&7)) *bits = 0;
		  val = *srcpixel++;
		  *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2, 
							((val >> 7) & 0xf8) |
							((val >> 12) & 0x7),
							((val >> 2) & 0xf8) |
							((val >> 7) & 0x3),
							((val << 3) & 0xf8) |
							((val >> 2) & 0x7) ) << (7-(x&7)) );
		  if ((x&7)==7) bits++;
		}
		bits = (dstbits += linebytes);
	    }
	}
	/* ==== 555 RGB bitmap to monochrome dib ==== */
	else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
	{
	    for( h = lines - 1; h >= 0; h--) 
	    {
		srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
		for( x = 0; x < dstwidth; x++) {
		  if (!(x&1)) *bits = 0;
		  val = *srcpixel++;
		  *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2, 
							((val << 3) & 0xf8) |
							((val >> 2) & 0x7),
							((val >> 2) & 0xf8) |
							((val >> 7) & 0x3),
							((val >> 7) & 0xf8) |
							((val >> 12) &  0x7) ) << (7-(x&7)) );
		  if ((x&7)==7) bits++;
		}
		bits = (dstbits += linebytes);
	    }
        }
	else goto notsupported;
      }
      break;
 
    case 16:
      {
	LPWORD srcpixel;
	WORD val;

	/* ==== 565 BGR bitmap to monochrome dib ==== */
	if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f) 
	{
	    for( h = lines - 1; h >= 0; h--) 
	    {
		srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
		for( x = 0; x < dstwidth; x++) {
		  if (!(x&7)) *bits = 0;
		  val = *srcpixel++;
		  *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2, 
							((val >> 8) & 0xf8) |
							((val >> 13) & 0x7),
							((val >> 3) & 0xfc) |
							((val >> 9) & 0x3),
							((val << 3) & 0xf8) |
							((val >> 2) & 0x7) ) << (7-(x&7)) );
		  if ((x&7)==7) bits++;
		}
		bits = (dstbits += linebytes);
	    }
	}
	/* ==== 565 RGB bitmap to monochrome dib ==== */
	else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
	{
	    for( h = lines - 1; h >= 0; h--) 
	    {
		srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
		for( x = 0; x < dstwidth; x++) {
		  if (!(x&7)) *bits = 0;
		  val = *srcpixel++;
		  *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2, 
							((val << 3) & 0xf8) |
							((val >> 2) & 0x7),
							((val >> 3) & 0xfc) |
							((val >> 9) & 0x3),
							((val >> 8) & 0xf8) |
							((val >> 13) &  0x7) ) << (7-(x&7)) );
		  if ((x&7)==7) bits++;
		}
		bits = (dstbits += linebytes);
	    }
        }
	else goto notsupported;
      }
      break;
      
    case 24: 
    case 32:
      {
	BYTE *srcpixel;
 	
	/* ==== 24/32 BGR bitmap to monochrome dib ==== */
	if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
	{	 
	  for (h = lines - 1; h >= 0; h--)
	  {
	    srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
	    for (x = 0; x < dstwidth; x++, srcpixel+=4) {
	      if (!(x&7)) *bits = 0;
	      *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[2] , srcpixel[1], srcpixel[0]) << (7-(x&7)) );
	      if ((x&7)==7) bits++;
	    }
	    bits = (dstbits += linebytes);
	  }
	} 
	/* ==== 24/32 RGB bitmap to monochrome dib ==== */
	else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
	{
	  for (h = lines - 1; h >= 0; h--)
	  {
	    srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
	    for (x = 0; x < dstwidth; x++, srcpixel+=4) { 
                       if (!(x & 7)) *bits = 0;
		       *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[0] , srcpixel[1], srcpixel[2]) << (7-(x&7)) );
                       if ((x & 7) == 7) bits++;
	    }
	    bits = (dstbits += linebytes);
	  }
	}
	else goto notsupported;
      }
      break;

    default: /* ? bit bmp -> monochrome DIB */
    notsupported:
      {
	unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;

	FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
              bmpImage->bits_per_pixel, (int)bmpImage->red_mask, 
              (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
      
	for( h = lines - 1; h >= 0; h-- ) {
	  for( x = 0; x < dstwidth; x++ ) {
	    if (!(x&7)) *bits = 0;
	    *bits |= (XGetPixel( bmpImage, x, h) >= white) 
	      << (7 - (x&7));
	    if ((x&7)==7) bits++;
	  }
	  bits = (dstbits += linebytes);
	}
      }
      break;
    }
}

/***********************************************************************
 *           X11DRV_DIB_SetImageBits_4
 *
 * SetDIBits for a 4-bit deep DIB.
 */
static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
                                DWORD srcwidth, DWORD dstwidth, int left,
                                int *colors, XImage *bmpImage, DWORD linebytes)
{
    DWORD i, x;
    int h;
    const BYTE *bits = srcbits + (left >> 1);
  
    if(left & 1) {
        left--;
	dstwidth++;
    }

    if (lines > 0) {
	for (h = lines-1; h >= 0; h--) {
	    for (i = dstwidth/2, x = left; i > 0; i--) {
		BYTE pix = *bits++;
		XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
		XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
	    }
	    if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
	    srcbits += linebytes;
	    bits	 = srcbits + (left >> 1);
	}
    } else {
	lines = -lines;
	for (h = 0; h < lines; h++) {
	    for (i = dstwidth/2, x = left; i > 0; i--) {
		BYTE pix = *bits++;
		XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
		XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
	    }
	    if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
	    srcbits += linebytes;
	    bits	 = srcbits + (left >> 1);
	}
    }
}



/***********************************************************************
 *           X11DRV_DIB_GetImageBits_4
 *
 * GetDIBits for a 4-bit deep DIB.
 */
static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
				       DWORD srcwidth, DWORD dstwidth,
				       RGBQUAD *colors, PALETTEENTRY *srccolors, 
				       XImage *bmpImage, DWORD linebytes )
{
    DWORD x;
    int h;
    BYTE *bits;
    LPBYTE srcpixel;

    if (lines < 0 )
    {
       lines = -lines;
       dstbits = dstbits + ( linebytes * (lines-1) );
       linebytes = -linebytes;
    }

    bits = dstbits;

    switch(bmpImage->depth) {

     case 1:
	/* ==== monochrome bitmap to 4 colormap dib ==== */
     case 4:
       /* ==== 4 colormap bitmap to 4 colormap dib ==== */
       if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
	 {
	   PALETTEENTRY val;
	   
       for (h = lines-1; h >= 0; h--) {
	     for (x = 0; x < dstwidth; x++) {
	       if (!(x&1)) *bits = 0;
	       val = srccolors[XGetPixel(bmpImage, x, h)];
	       *bits |= (X11DRV_DIB_GetNearestIndex(colors, 16, 
						    val.peRed,
						    val.peGreen, 
						    val.peBlue) << (4-((x&1)<<2)));
	       if ((x&1)==1) bits++;
           }
	     bits = (dstbits += linebytes);
       }
	 }
       else goto notsupported;
       
       break;
      
    case 8:
      /* ==== 8 colormap bitmap to 4 colormap dib ==== */
      if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
      {
	PALETTEENTRY val;

	for( h = lines - 1; h >= 0; h-- ) {
	  srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
	  for( x = 0; x < dstwidth; x++ ) {
	    if (!(x&1)) *bits = 0;
	    val = srccolors[(int)*srcpixel++];
	    *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 16,
						  val.peRed,
						  val.peGreen,
						  val.peBlue) << (4*(1-(x&1))) );
	    if ((x&1)==1) bits++;
	  }
	  bits = (dstbits += linebytes);
	}
      }
      else goto notsupported;

      break;
      
    case 15:
      {
	LPWORD srcpixel;
	WORD val;
	
	/* ==== 555 BGR bitmap to 4 colormap dib ==== */
	if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
	{
	  for( h = lines - 1; h >= 0; h--) {
		srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
		for( x = 0; x < dstwidth; x++) {
		  if (!(x&1)) *bits = 0;
		  val = *srcpixel++;
		  *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16, 
							((val >> 7) & 0xf8) |
							((val >> 12) & 0x7),
							((val >> 2) & 0xf8) |
							((val >> 7) & 0x3),
							((val << 3) & 0xf8) |
							((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
		  if ((x&1)==1) bits++;
		}
		bits = (dstbits += linebytes);
	    }
	}
	/* ==== 555 RGB bitmap to 4 colormap dib ==== */
	else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
	{
	    for( h = lines - 1; h >= 0; h--) 
	    {
		srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
		for( x = 0; x < dstwidth; x++) {
		  if (!(x&1)) *bits = 0;
		  val = *srcpixel++;
		  *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16, 
							((val << 3) & 0xf8) |
							((val >> 2) & 0x7),
							((val >> 2) & 0xfc) |
							((val >> 7) & 0x3),
							((val >> 7) & 0xf8) |
							((val >> 12) &  0x7) ) << ((1-(x&1))<<2) );
		  if ((x&1)==1) bits++;
		}
		bits = (dstbits += linebytes);
	    }
        }
	else goto notsupported;
      }
      break;
 
    case 16:
      {
	LPWORD srcpixel;
	WORD val;

	/* ==== 565 BGR bitmap to 4 colormap dib ==== */
	if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f) 
	{
	    for( h = lines - 1; h >= 0; h--) 
	    {
		srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
		for( x = 0; x < dstwidth; x++) {
		  if (!(x&1)) *bits = 0;
		  val = *srcpixel++;
		  *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16, 
							((val >> 8) & 0xf8) |
							((val >> 13) & 0x7),
							((val >> 3) & 0xfc) |
							((val >> 9) & 0x3),
							((val << 3) & 0xf8) |
							((val >> 2) & 0x7) )  << ((1-(x&1))<<2) );
		  if ((x&1)==1) bits++;
		}
		bits = (dstbits += linebytes);
	    }
	}
	/* ==== 565 RGB bitmap to 4 colormap dib ==== */
	else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
	{
	    for( h = lines - 1; h >= 0; h--) 
	    {
		srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
		for( x = 0; x < dstwidth; x++) {
		  if (!(x&1)) *bits = 0;
		  val = *srcpixel++;
		  *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16, 
							((val << 3) & 0xf8) |
							((val >> 2) & 0x7),
							((val >> 3) & 0xfc) |
							((val >> 9) & 0x3),
							((val >> 8) & 0xf8) |
							((val >> 13) &  0x7) ) << ((1-(x&1))<<2) );
		  if ((x&1)==1) bits++;
		}
		bits = (dstbits += linebytes);
	    }
        }
	else goto notsupported;
      }
      break;
      
    case 24: 
    case 32:
      {
	BYTE *srcpixel;
 	
	/* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
	if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
	{	 
	  for (h = lines - 1; h >= 0; h--)
	  {
	    srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
	    for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
	      *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[2] , srcpixel[1], srcpixel[0]) << 4) |
		         X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[6] , srcpixel[5], srcpixel[4]);
	    bits = (dstbits += linebytes);
	  }
	} 
	/* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
	else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
	{
	  for (h = lines - 1; h >= 0; h--)
	  {
	    srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
	    for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
	      *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[0] , srcpixel[1], srcpixel[2]) << 4) |
		         X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[4] , srcpixel[5], srcpixel[6]);
	    bits = (dstbits += linebytes);
	  }
	}
	else goto notsupported;
      }
      break;

    default: /* ? bit bmp -> 4 bit DIB */
    notsupported:
      FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
            bmpImage->bits_per_pixel, (int)bmpImage->red_mask, 
            (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
      for (h = lines-1; h >= 0; h--) {
          for (x = 0; x < dstwidth-1; x += 2)
          {
              *bits++ = (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x, h ), 0) << 4)
                  | (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x+1, h ), 0) & 0x0f);
          }
          if (dstwidth & 1)
              *bits = (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x, h ), 0) << 4);
          bits = (dstbits += linebytes);
       }
      break;
    }
}

/***********************************************************************
 *           X11DRV_DIB_SetImageBits_RLE4
 *
 * SetDIBits for a 4-bit deep compressed DIB.
 */
static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
					  DWORD width, DWORD dstwidth,
					  int left, int *colors,
					  XImage *bmpImage )
{
    int x = 0, c, length;
    const BYTE *begin = bits;

    lines--;

    while ((int)lines >= 0) {
        length = *bits++;
	if (length) {	/* encoded */
	    c = *bits++;
	    while (length--) {
		if(x >= width) {
		    x = 0;
		    if(--lines < 0)
		        return;
		}
	        XPutPixel(bmpImage, x++, lines, colors[c >>4]);
		if (length) {
		    length--;
		    if(x >= width) {
		        x = 0;
			if(--lines < 0)
			    return;
		    }
		    XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
		}
	    }
	} else {
	    length = *bits++;
	    switch (length) {
	    case 0: /* eol */
	        x = 0;
		lines--;
		continue;

	    case 1: /* eopicture */
	        return;

	    case 2: /* delta */
	        x += *bits++;
		if(x >= width) {
		   FIXME_(x11drv)("x-delta is too large?\n");
		   return;
		}
		lines -= *bits++;
		continue;

	    default: /* absolute */
	        while (length--) {
		    c = *bits++;
		    if(x >= width) {
		        x = 0;
			if(--lines < 0)
			    return;
		    }
		    XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
		    if (length) {
		        length--;
			if(x >= width) {
			    x = 0;
			    if(--lines < 0)
			        return;
			}
			XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
		    }
		}
		if ((bits - begin) & 1)
		    bits++;
	    }
	}
    }
}



/***********************************************************************
 *           X11DRV_DIB_SetImageBits_8
 *
 * SetDIBits for an 8-bit deep DIB.
 */
static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
				DWORD srcwidth, DWORD dstwidth, int left,
                                const int *colors, XImage *bmpImage,
				DWORD linebytes )
{
    DWORD x;
    int h, color;
    const BYTE *bits;

    dstwidth += left;

    if (lines < 0 )
    {
        lines = -lines;
        srcbits = srcbits + ( linebytes * (lines-1) );
        linebytes = -linebytes;
    }

    bits = srcbits + left;

    switch (bmpImage->depth) {
    case 15:
    case 16:
#if defined(__i386__) && defined(__GNUC__)
	/* Some X servers might have 32 bit/ 16bit deep pixel */
	if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 16))
	{
	    for (h = lines ; h--; ) {
		int _cl1,_cl2; /* temp outputs for asm below */
		/* Borrowed from DirectDraw */
		__asm__ __volatile__(
		"xor %%eax,%%eax\n"
		"cld\n"
		"1:\n"
		"    lodsb\n"
		"    movw (%%edx,%%eax,4),%%ax\n"
		"    stosw\n"
		"      xor %%eax,%%eax\n"
		"    loop 1b\n"
		:"=S" (bits), "=D" (_cl1), "=c" (_cl2)
		:"S" (bits),
		 "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*2),
		 "c" (dstwidth-left),
		 "d" (colors)
		:"eax", "cc", "memory"
		);
		bits = (srcbits += linebytes) + left;
	    }
	    return;
	}
	break;
#endif
    case 24:
#if defined(__i386__) && defined(__GNUC__)
	if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 32))
	{
	    for (h = lines ; h--; ) {
		int _cl1,_cl2; /* temp outputs for asm below */
		/* Borrowed from DirectDraw */
		__asm__ __volatile__(
		"xor %%eax,%%eax\n"
		"cld\n"
		"1:\n"
		"    lodsb\n"
		"    movl (%%edx,%%eax,4),%%eax\n"
		"    stosl\n"
		"      xor %%eax,%%eax\n"
		"    loop 1b\n"
		:"=S" (bits), "=D" (_cl1), "=c" (_cl2)
		:"S" (bits),
		 "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*4),
		 "c" (dstwidth-left),
		 "d" (colors)
		:"eax", "cc", "memory"
		);
		bits = (srcbits += linebytes) + left;
	    }
	    return;
	}
	break;
#endif
    default:
    	break; /* use slow generic case below */
    }

    for (h = lines - 1; h >= 0; h--) {
        for (x = left; x < dstwidth; x++, bits++) {
	    color = colors[*bits];	    
            XPutPixel( bmpImage, x, h, colors[*bits] );
        }
        bits = (srcbits += linebytes) + left;
    }
}

/***********************************************************************
 *           X11DRV_DIB_GetImageBits_8
 *
 * GetDIBits for an 8-bit deep DIB.
 */
static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
				       DWORD srcwidth, DWORD dstwidth,
				       RGBQUAD *colors, PALETTEENTRY *srccolors, 
				       XImage *bmpImage, DWORD linebytes )
{
    DWORD x;
    int h;
    BYTE *bits;

    if (lines < 0 )
    {
       lines = -lines;
       dstbits = dstbits + ( linebytes * (lines-1) );
       linebytes = -linebytes;
    }

    bits = dstbits;

    /* 
       Hack for now 
       This condition is true when GetImageBits has been called by UpdateDIBSection.
       For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
       for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
    */
    if (!srccolors) goto updatesection;

    switch(bmpImage->depth) {

    case 1:
	/* ==== monochrome bitmap to 8 colormap dib ==== */
    case 4:
       /* ==== 4 colormap bitmap to 8 colormap dib ==== */
       if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
	 {
	   PALETTEENTRY val;

    for (h = lines - 1; h >= 0; h--) {
	     for (x = 0; x < dstwidth; x++) {
	       val = srccolors[XGetPixel(bmpImage, x, h)];
	       *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
						    val.peGreen, val.peBlue);
	     }
	     bits = (dstbits += linebytes);
	   }
	 }
       else goto notsupported;
       
       break;
    
     case 8:
       /* ==== 8 colormap bitmap to 8 colormap dib ==== */
       if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
	 {
	   BYTE *srcpixel;
	   PALETTEENTRY val;
	   
	   for (h = lines - 1; h >= 0; h--) {
	     srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
	     for (x = 0; x < dstwidth; x++) {
	       val = srccolors[(int)*srcpixel++];
	       *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed, 
						    val.peGreen, val.peBlue);
	     }
	     bits = (dstbits += linebytes);
	   }
	 }
       else goto notsupported;
       
       break;

      case 15:
      {
	LPWORD srcpixel;
	WORD val;
	
	/* ==== 555 BGR bitmap to 8 colormap dib ==== */
	if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
	{
	    for( h = lines - 1; h >= 0; h--) 
	    {
		srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
		for( x = 0; x < dstwidth; x++ )
		{
		  val = *srcpixel++;
		  *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256, 
							((val >> 7) & 0xf8) |
							((val >> 12) & 0x7),
							((val >> 2) & 0xf8) |
							((val >> 7) & 0x3),
							((val << 3) & 0xf8) |
							((val >> 2) & 0x7) );
		}
		bits = (dstbits += linebytes);
	    }
	}
	/* ==== 555 RGB bitmap to 8 colormap dib ==== */
	else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
	{
	    for( h = lines - 1; h >= 0; h--) 
	    {
		srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
		for( x = 0; x < dstwidth; x++ )
		{
		  val = *srcpixel++;
		  *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256, 
							((val << 3) & 0xf8) |
							((val >> 2) & 0x7),
							((val >> 2) & 0xf8) |
							((val >> 7) & 0x3),
							((val >> 7) & 0xf8) |
							((val >> 12) &  0x7) );
		}
		bits = (dstbits += linebytes);
	    }
	}
	else goto notsupported;
      }
      break;

      case 16:
      {
	LPWORD srcpixel;
	WORD val;
	
	/* ==== 565 BGR bitmap to 8 colormap dib ==== */
	if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
	{
	    for( h = lines - 1; h >= 0; h--) 
	    {
		srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
		for( x = 0; x < dstwidth; x++ )
		{
		  val = *srcpixel++;
		  *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256, 
							((val >> 8) & 0xf8) |
							((val >> 13) & 0x7),
							((val >> 3) & 0xfc) |
							((val >> 9) & 0x3),
							((val << 3) & 0xf8) |
							((val >> 2) & 0x7) );
		}
		bits = (dstbits += linebytes);
	    }
	}
	/* ==== 565 RGB bitmap to 8 colormap dib ==== */
	else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
	{
	    for( h = lines - 1; h >= 0; h--) 
	    {
		srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
		for( x = 0; x < dstwidth; x++ )
		{
		  val = *srcpixel++;
		  *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256, 
							((val << 3) & 0xf8) |
							((val >> 2) & 0x7),
							((val >> 3) & 0x00fc) |
							((val >> 9) & 0x3),
							((val >> 8) & 0x00f8) |
							((val >> 13) &  0x7) );
		}
		bits = (dstbits += linebytes);
	    }
	}
	else goto notsupported;
      }
      break;
      
      case 24: 
      case 32:
      {
	BYTE *srcpixel;
	
	/* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
	if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
	{
	  for (h = lines - 1; h >= 0; h--)
	    {
	      srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
	      for (x = 0; x < dstwidth; x++, srcpixel+=4)
		*bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, 
						     srcpixel[2] , srcpixel[1], *srcpixel);
	      bits = (dstbits += linebytes);
	    }
	}
	/* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
	else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
	{
	  for (h = lines - 1; h >= 0; h--)
	    {
	      srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
	      for (x = 0; x < dstwidth; x++, srcpixel+=4)
		*bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, 
						     *srcpixel, srcpixel[1], srcpixel[2]);
	      bits = (dstbits += linebytes);
	    }
	  
	}
	else goto notsupported;
      }
      break;

    default: /* ? bit bmp -> 8 bit DIB */
    notsupported:
      FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
            bmpImage->depth, (int)bmpImage->red_mask, 
            (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
    updatesection:
      for (h = lines - 1; h >= 0; h--) {
	for (x = 0; x < dstwidth; x++, bits++) {
	  *bits = X11DRV_DIB_MapColor((int *)colors, 256,
                                         XGetPixel( bmpImage, x, h ), *bits);
        }
	bits = (dstbits += linebytes);
      }
      break;
    }
}

/***********************************************************************
 *	      X11DRV_DIB_SetImageBits_RLE8
 *
 * SetDIBits for an 8-bit deep compressed DIB.
 *
 * This function rewritten 941113 by James Youngman.  WINE blew out when I
 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.  
 *
 * This was because the algorithm assumed that all RLE8 bitmaps end with the  
 * 'End of bitmap' escape code.  This code is very much laxer in what it
 * allows to end the expansion.  Possibly too lax.  See the note by 
 * case RleDelta.  BTW, MS's documentation implies that a correct RLE8
 * bitmap should end with RleEnd, but on the other hand, software exists 
 * that produces ones that don't and Windows 3.1 doesn't complain a bit
 * about it.
 *
 * (No) apologies for my English spelling.  [Emacs users: c-indent-level=4].
 *			James A. Youngman <mbcstjy@afs.man.ac.uk>
 *						[JAY]
 */

enum Rle8_EscapeCodes		
{
  /* 
   * Apologies for polluting your file's namespace...
   */
  RleEol 	= 0,		/* End of line */
  RleEnd 	= 1,		/* End of bitmap */
  RleDelta	= 2		/* Delta */
};
  
static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
					  DWORD width, DWORD dstwidth,
					  int left, int *colors,
					  XImage *bmpImage )
{
    int x;			/* X-positon on each line.  Increases. */
    int line;			/* Line #.  Starts at lines-1, decreases */
    const BYTE *pIn = bits;     /* Pointer to current position in bits */
    BYTE length;		/* The length pf a run */
    BYTE color_index;		/* index into colors[] as read from bits */
    BYTE escape_code;		/* See enum Rle8_EscapeCodes.*/
    int color;			/* value of colour[color_index] */
    
    if (lines == 0)		/* Let's hope this doesn't happen. */
      return;
    
    /*
     * Note that the bitmap data is stored by Windows starting at the
     * bottom line of the bitmap and going upwards.  Within each line,
     * the data is stored left-to-right.  That's the reason why line
     * goes from lines-1 to 0.			[JAY]
     */
    
    x = 0;
    line = lines-1;
    do
      {
	  length = *pIn++;
	  
	  /* 
	   * If the length byte is not zero (which is the escape value),
	   * We have a run of length pixels all the same colour.  The colour 
	   * index is stored next. 
	   *
	   * If the length byte is zero, we need to read the next byte to
	   * know what to do.			[JAY]
	   */
	  if (length != 0) 
	    {                                   
		/* 
		 * [Run-Length] Encoded mode 
		 */
		color_index = (*pIn++); /* Get the colour index. */
		color = colors[color_index];

		while(length--)
		  {
		    if (x>=dstwidth)
		      {
			x=0;
			line--;
		      }
		    XPutPixel(bmpImage, x++, line, color);
		  }
	    }
	  else 
	    {    
		/* 
		 * Escape codes (may be an absolute sequence though)
		 */
		escape_code = (*pIn++);
		switch(escape_code)
		  {
		    case RleEol: /* =0, end of line */
		      {
			  x = 0;  
			  line--;  
			  break;
		      }
		      
		    case RleEnd: /* =1, end of bitmap */
		      {
			  /*
			   * Not all RLE8 bitmaps end with this 
			   * code.  For example, Paint Shop Pro 
			   * produces some that don't.  That's (I think)
			   * what caused the previous implementation to 
			   * fail.			[JAY]
			   */
			  line=-1; /* Cause exit from do loop. */
			  break;
		      }
		      
		    case RleDelta: /* =2, a delta */
		      {
			  /* 
			   * Note that deltaing to line 0 
			   * will cause an exit from the loop, 
			   * which may not be what is intended. 
			   * The fact that there is a delta in the bits
			   * almost certainly implies that there is data
			   * to follow.  You may feel that we should 
			   * jump to the top of the loop to avoid exiting
			   * in this case.  
			   *
			   * TODO: Decide what to do here in that case. [JAY]
			   */
			  x 	+= (*pIn++); 
			  line 	-= (*pIn++);
			  if (line == 0)
			    {
			      TRACE("Delta to last line of bitmap "
                                    "(wrongly?) causes loop exit\n");
			    }
			  break;
		      }
		      
		    default:	/* >2, switch to absolute mode */
		      {
			  /* 
			   * Absolute Mode 
			   */
			  length = escape_code;
			  while(length--)
			    {
				color_index = (*pIn++);
				if (x>=dstwidth)
				  {
				    x=0;
				    line--;
				  }
				XPutPixel(bmpImage, x++, line, 
					  colors[color_index]);
			    }
			  
			  /*
			   * If you think for a moment you'll realise that the
			   * only time we could ever possibly read an odd
			   * number of bytes is when there is a 0x00 (escape),
			   * a value >0x02 (absolute mode) and then an odd-
			   * length run.  Therefore this is the only place we
			   * need to worry about it.  Everywhere else the
			   * bytes are always read in pairs.  [JAY]
			   */
			  if (escape_code & 1) 
			    pIn++; /* Throw away the pad byte. */
			  break;
		      }
		  } /* switch (escape_code) : Escape sequence */
	    }  /* process either an encoded sequence or an escape sequence */
	  
	  /* We expect to come here more than once per line. */
      } while (line >= 0);  /* Do this until the bitmap is filled */
    
    /*
     * Everybody comes here at the end.
     * Check how we exited the loop and print a message if it's a bit odd.
     *						[JAY]
     */
    if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
      {
	TRACE("End-of-bitmap without (strictly) proper escape code.  Last two "
              "bytes were: %02X %02X.\n", (int)*(pIn-2),(int)*(pIn-1));
      }
}  


/***********************************************************************
 *           X11DRV_DIB_SetImageBits_16
 *
 * SetDIBits for a 16-bit deep DIB.
 */
static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
                                 DWORD srcwidth, DWORD dstwidth, int left,
                                       DC *dc, DWORD rSrc, DWORD gSrc, DWORD bSrc,
                                       XImage *bmpImage, DWORD linebytes )
{
    DWORD x;
    int h;
  
    if (lines < 0 )
    {
        lines = -lines;
        srcbits = srcbits + ( linebytes * (lines-1));
        linebytes = -linebytes;
    }
    	
    switch ( bmpImage->depth )
    {
        case 15:
            /* using same format as XImage */
            if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
                for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
                    memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
            else     /* We need to do a conversion from a 565 dib */
            {
                LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
                DWORD val;
                int div = dstwidth % 2;

                for (h = lines - 1; h >= 0; h--) {
                    dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
                    for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
                        val = *ptr++;
                        *dstpixel++ =   ((val >> 1) & 0x7fe07fe0) | (val & 0x001f001f); /* Red & Green & Blue */
                    }
                    if (div != 0) /* Odd width? */
                        *dstpixel = ((*(WORD *)ptr >> 1) & 0x7fe0) | (*(WORD *)ptr & 0x001f);
                    ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
                }
            }
            break;

        case 16:
            /* using same format as XImage */
            if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
                for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
                    memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
            else     /* We need to do a conversion from a 555 dib */
            {
                LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
                DWORD val;
                int div = dstwidth % 2;

                for (h = lines - 1; h >= 0; h--) {
                    dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
                    for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
                        val = *ptr++;
                        *dstpixel++ = ((val << 1) & 0xffc0ffc0) | ((val >> 4) & 0x00200020) | /* Red & Green */
			  (val & 0x001f001f);                             /* Blue */
                    }
                    if (div != 0) /* Odd width? */
                        *dstpixel = ((*(WORD *)ptr << 1) & 0xffc0) | ((*(WORD *)ptr >> 4) & 0x0020)
                                    | (*(WORD *)ptr & 0x001f);
                    ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
                }
            }
            break;

        case 24:
        case 32:
            {
                DWORD  *dstpixel;
                LPWORD ptr = (LPWORD)srcbits + left;
                DWORD val;

		if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
                {
		  if ((rSrc == 0xF800) && (gSrc == 0x07E0) && (bSrc == 0x001F)) {
		    /* ==== 555 RGB dib to 24/32 RGB bitmap ==== */
		    for (h = lines - 1; h >= 0; h--) {
		      dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
		      for (x = 0; x < dstwidth; x++) {
                        val = *ptr++;
			*dstpixel++ = ((val << 8) & 0xF80000) | /* Red */
			              ((val << 5) & 0x00FC00) | /* Green */
			              ((val << 3) & 0x0000FF);  /* Blue */
		      }
		      ptr = (LPWORD)(srcbits += linebytes) + left;
		    }
		  } else {
		    /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
		    for (h = lines - 1; h >= 0; h--) {
		      dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
		      for (x = 0; x < dstwidth; x++) {
			
                        val = *ptr++;
                        *dstpixel++ = ((val << 9) & 0xf80000) | ((val << 4) & 0x070000) | /* Red */
			  ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
			  ((val << 3) & 0x0000f8) | ((val >> 2) & 0x000007);      /* Blue */
		      }
		      ptr = (LPWORD)(srcbits += linebytes) + left;
		    }
		  }
		}
		/* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
		else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
                {
		  for (h = lines - 1; h >= 0; h--) {
                    dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
                    for (x = 0; x < dstwidth; x++) {

                        val = *ptr++;
                        *dstpixel++ = ((val >> 7) & 0x0000f8) | ((val >> 12) & 0x000007) | /* Red */
			  ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
			  ((val << 19) & 0xf80000) | ((val >> 14) & 0x070000);      /* Blue */
                    }
                    ptr = (LPWORD)(srcbits += linebytes) + left;
		  }
		}

	    }
            break;

        case 1:
        case 4:
        case 8:
            {
                LPWORD ptr = (LPWORD)srcbits + left;
                WORD val;
                int sc1, sc2;

                /* Set color scaling values */
                if ( rSrc == 0x7c00 ) { sc1 = 7; sc2 = 2; }             /* 555 dib */
                else { sc1 = 8; sc2 = 3; }                              /* 565 dib */

	        for (h = lines - 1; h >= 0; h--) {
                    for (x = left; x < dstwidth+left; x++) {
                        val = *ptr++;
		        XPutPixel( bmpImage, x, h,
                                   X11DRV_PALETTE_ToPhysical(dc, RGB(((val & rSrc) >> sc1),  /* Red */
                                                                     ((val & gSrc) >> sc2),  /* Green */
                                                                     ((val & bSrc) << 3)))); /* Blue */
	            }
	            ptr = (LPWORD) (srcbits += linebytes) + left;
	        }
	    }
            break;

        default:
            FIXME("16 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
        break;

    }
}


/***********************************************************************
 *           X11DRV_DIB_GetImageBits_16
 *
 * GetDIBits for an 16-bit deep DIB.
 */
static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
					DWORD dstwidth, DWORD srcwidth,
					PALETTEENTRY *srccolors,
					DWORD rDst, DWORD gDst, DWORD bDst,
					XImage *bmpImage, DWORD dibpitch )
{
    DWORD x;
    int h, rsc, gsc;

    DWORD linebytes = dibpitch;

    if (lines < 0 )
    {
        lines = -lines;
        dstbits = dstbits + ( linebytes * (lines-1));
        linebytes = -linebytes;
    }

    /* Set color scaling values */
    if ( rDst == 0x7c00 ) { rsc = 7; gsc = 2; }             /* 555 dib */
    else { rsc = 8; gsc = 3; }                              /* 565 dib */

    switch ( bmpImage->depth )
    {
        case 15:
	    /* using same format as XImage */
	    if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
                for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
                    memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
	    /* reversed format (BGR <=> RGB) */
            else if (rDst == bmpImage->blue_mask && bDst == bmpImage->red_mask)
            {
                LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
                DWORD val;
                int div = srcwidth % 2;

                for (h = lines - 1; h >= 0; h--) {
                    srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
                    for (x = 0; x < srcwidth/2; x++) {  /* Do 2 pixels at a time */
                        val = *srcpixel++;
                        *ptr++ = ((val << 10) & 0xf800f800) | (val & 0x03e003e0) |        /* Red & Green */
			  ((val >> 10) & 0x001f001f);                                     /* Blue */
                    }
                    if (div != 0) /* Odd width? */
                        *ptr = ((*(WORD *)srcpixel << 1) & 0xffc0) | ((*(WORD *)srcpixel >> 4) & 0x0020) |
                               (*(WORD *)srcpixel & 0x001f);
                    ptr = (LPDWORD)(dstbits += linebytes);
               }
           }
	   else goto notsupported;

           break;

       case 16:
           {
	   LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
	   DWORD val;
	   int div = srcwidth % 2;

	   /* using same format as XImage */
	   if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
	       for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
		   memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
           /* ==== 565 BGR bitmap to 555 BGR dib ==== */
           else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f &&
		    rDst == 0x7c00 && bDst == 0x001f)
	   {
               for (h = lines - 1; h >= 0; h--) {
                   srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
                   for (x = 0; x < srcwidth/2; x++) {  /* Do 2 pixels at a time */
                       val = *srcpixel++;
                       *ptr++ = ((val >> 1) & 0x7fe07fe0) |                    /* Red & Green */
			 (val & 0x001f001f);                                   /* Blue */
                   }
                   if (div != 0) /* Odd width? */
                       *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
                   ptr = (LPDWORD) (dstbits += linebytes);
               }
	   }
	   /* ==== 565 RGB bitmap to 555 BGR dib ==== */
           else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800 &&
		    rDst == 0x7c00 && bDst == 0x001f)
           {
               for (h = lines - 1; h >= 0; h--) {
                   srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
                   for (x = 0; x < srcwidth/2; x++) {  /* Do 2 pixels at a time */
                       val = *srcpixel++;
                       *ptr++ = ((val << 10) & 0x7c007c00) | ((val >> 1) & 0x03e003e0) |   /* Red & Green */
			 ((val >> 11) & 0x001f001f);                                       /* Blue */
                   }
                   if (div != 0) /* Odd width? */
                       *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
                   ptr = (LPDWORD) (dstbits += linebytes);
               }
               }
	   else goto notsupported;
           }
           break;

       case 24:
       case 32:
           {
               DWORD  *srcpixel;
               LPWORD ptr = (LPWORD)dstbits;
               DWORD val;

	       /* ==== 24/32 BGR bitmap ==== */
	       if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
	       {
		   int rsc2 = 16-rsc, gsc2 = 8-gsc;
		   for (h = lines - 1; h >= 0; h--) {
		       srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
		       for (x = 0; x < srcwidth; x++, ptr++) {
			   val = *srcpixel++;
			   *ptr = ((val >> rsc2) & rDst) |
			          ((val >> gsc2) & gDst) |
			          ((val >> 3) & bDst);
		       }
		       ptr = (LPWORD)(dstbits += linebytes);
		   }
	       }
	       /* ==== 24/32 RGB bitmap ==== */
	       else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
	       {
		   int gsc2 = 8-gsc;
		   for (h = lines - 1; h >= 0; h--) {
		       srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
		       for (x = 0; x < srcwidth; x++, ptr++) {
			   val = *srcpixel++;
			   *ptr = ((val << rsc) & rDst) |
			          ((val >> gsc2) & gDst) |
			          ((val >> 19) & bDst);
		       }
		       ptr = (LPWORD) (dstbits += linebytes);
		   }
               }
	       else goto notsupported;
           }
           break;

       case 1:
	    /* ==== monochrome bitmap ==== */
       case 4:
	    /* ==== 4 colormap bitmap ==== */
	    if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
            {
	        LPWORD ptr = (LPWORD)dstbits;
		PALETTEENTRY val;

                for (h = lines - 1; h >= 0; h--) {
		  for (x = 0; x < dstwidth; x++) {
		    val = srccolors[XGetPixel(bmpImage, x, h)];
		    *ptr++ = ((val.peRed << rsc) & rDst) | 
		             ((val.peGreen << gsc) & gDst) |
		             ((val.peBlue >> 3) & bDst);
		  }
		  ptr = (LPWORD)(dstbits += linebytes);
                }
            }
	    else goto notsupported;

            break;

        case 8:
	    /* ==== 8 colormap bitmap ==== */
	    if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
            {
	        LPWORD ptr = (LPWORD)dstbits;
                BYTE *srcpixel;
		PALETTEENTRY val;

               for (h = lines - 1; h >= 0; h--) {
		  srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
		  for (x = 0; x < dstwidth; x++) {
		    val = srccolors[(int)*srcpixel++];
		    *ptr++ = ((val.peRed << rsc) & rDst) | 
		             ((val.peGreen << gsc) & gDst) |
		             ((val.peBlue >> 3) & bDst);
                   }
		  ptr = (LPWORD)(dstbits += linebytes);
               }
           }
	    else goto notsupported;

           break;

       default:
       notsupported:
	    {
	      BYTE r,g, b;
	      LPWORD ptr = (LPWORD)dstbits;

	      FIXME("from %d bit bitmap with mask R,G,B %lx,%lx,%lx to 16 bit DIB %lx,%lx,%lx\n",
                    bmpImage->depth, bmpImage->red_mask, 
                    bmpImage->green_mask, bmpImage->blue_mask,
		    rDst, gDst, bDst);

	      for (h = lines - 1; h >= 0; h--)
		{
		  for (x = 0; x < dstwidth; x++, ptr++)
		    {
		      COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
		      r = (BYTE) GetRValue(pixel);
		      g = (BYTE) GetGValue(pixel);
		      b = (BYTE) GetBValue(pixel);
		      *ptr = ( ((r << rsc) & rDst) | ((g << gsc) & gDst) | ((b >> 3) & bDst) );
		    }
		  ptr = (LPWORD) (dstbits += linebytes);
		}
	    }
           break;
   }
}


/***********************************************************************
 *           X11DRV_DIB_SetImageBits_24
 *
 * SetDIBits for a 24-bit deep DIB.
 */
static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
                                 DWORD srcwidth, DWORD dstwidth, int left,
				 DC *dc, XImage *bmpImage, DWORD linebytes )
{
    DWORD x;
    int h;
  
    if (lines < 0 )
    {
        lines = -lines;
        srcbits = srcbits + linebytes * (lines - 1);
        linebytes = -linebytes;
    }

    switch ( bmpImage->depth )
    {
        case 24:
	    {
		if (bmpImage->bits_per_pixel == 24) {
			int dstlinebytes = linebytes;
			BYTE *dstpixel;
			BYTE *ptr = (BYTE *)(srcbits+left*3);

			if (dstlinebytes < 0 ) dstlinebytes = -dstlinebytes;
			dstpixel = bmpImage->data + lines*dstlinebytes + left*3;
                        for(h = lines ; h-- ; ) {
				dstpixel-=dstlinebytes;
				memcpy(dstpixel,ptr,dstwidth*3);
				ptr +=linebytes;
			}
			break;
		}
	    }
        case 32:
            {
	        if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 )  /* packed BGR to unpacked BGR */
                {
                    DWORD *dstpixel, val, buf;
                    DWORD *ptr = (DWORD *)(srcbits + left*3);
                    BYTE *bits;
                    int div = dstwidth % 4;
                    int divk;

                    for(h = lines - 1; h >= 0; h--)
                    {
                        dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);

                        for (x = 0; x < dstwidth/4; x++) {   /* do 3 dwords source, 4 dwords dest at a time */
                            buf = *ptr++;
                            *dstpixel++ = buf&0x00ffffff;                  /* b1, g1, r1 */
                            val = (buf >> 24);                             /* b2 */
                            buf = *ptr++;
                            *dstpixel++ = (val | (buf<<8)) &0x00ffffff;    /* g2, r2 */
                            val = (buf >> 16);                             /* b3, g3 */
                            buf = *ptr++;
                            *dstpixel++ = (val | (buf<<16)) &0x00ffffff;   /* r3 */
                            *dstpixel++ = (buf >> 8);                      /* b4, g4, r4 */
                        }
                        for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
                        {
			    *dstpixel++ = *(DWORD*)bits & 0x00ffffff;      /* b, g, r */
                        }
                        ptr = (DWORD*)((srcbits+=linebytes)+left*3);
                    }
                }
		else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff )  /* packed BGR to unpacked RGB */
                {
                    DWORD *dstpixel, val, buf;
                    DWORD *ptr = (DWORD *)(srcbits + left*3);
                    BYTE *bits;
                    int div = dstwidth % 4;
                    int divk;

                    for(h = lines - 1; h >= 0; h--)
                    {
                        dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);

                        for (x = 0; x < dstwidth/4; x++) {   /* do 3 dwords source, 4 dwords dest at a time */
                            buf = *ptr++;
                            *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16);  /* b1, g1, r1 */
                            val = ((buf&0xff000000)>>8);                                           /* b2 */
                            buf = *ptr++;
                            *dstpixel++ = val | ((buf&0xff)<<8) | ((buf&0xff00)>>8);               /* g2, r2 */
                            val = (buf&0xff0000) | ((buf&0xff000000)>>16);                         /* b3, g3 */
                            buf = *ptr++;
                            *dstpixel++ = val | (buf&0xff);                                        /* r3 */
                            *dstpixel++ = ((buf&0xff00)<<8) | ((buf&0xff0000)>>8) | (buf>>24);     /* b4, g4, r4 */
                        }
                        for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
                        {
                            buf = *(DWORD*)bits;
                            *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16);  /* b, g, r */
                        }
                        ptr = (DWORD*)((srcbits+=linebytes)+left*3);
                    }
                }
                else
                    goto notsupported;
            }
            break;

        case 15:
            {
	        if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f )   /* BGR888 to RGB555 */
                {
                    DWORD  *ptr = (DWORD *)(srcbits + left*3);
                    LPBYTE bits;
                    LPWORD dstpixel;
                    int div = dstwidth % 4;
                    int divk;

                    for (h = lines - 1; h >= 0; h--) {              /* Do 4 pixels at a time */
                        dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
                        for (x = 0; x < dstwidth/4; x++, ptr += 3) {
                            *dstpixel++ = ((ptr[0] << 7) & 0x7c00)  | ((ptr[0] >> 6) & 0x03e0)  | ((ptr[0] >> 19) & 0x1f);
                            *dstpixel++ = ((ptr[0] >> 17) & 0x7c00) | ((ptr[1] << 2) & 0x03e0)  | ((ptr[1] >> 11) & 0x1f);
                            *dstpixel++ = ((ptr[1] >> 9) & 0x07c00) | ((ptr[1] >> 22) & 0x03e0) | ((ptr[2] >> 3) & 0x1f);
                            *dstpixel++ = ((ptr[2] >> 1) & 0x07c00) | ((ptr[2] >> 14) & 0x03e0) | ((ptr[2] >> 27) & 0x1f);
                        }
                        for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3)  /* dstwidth not divisible by 4? */
                            *dstpixel++ = (((WORD)bits[0] << 7) & 0x07c00) |
                                            (((WORD)bits[1] << 2) & 0x03e0) |
                                            (((WORD)bits[2] >> 3) & 0x001f);
                        ptr = (DWORD *)((srcbits += linebytes) + left * 3);
                    }
                }
                else if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 )   /* BGR888 to BGR555 */
                {
                    DWORD  *ptr = (DWORD *)(srcbits + left*3);
                    LPBYTE bits;
                    LPWORD dstpixel;
                    int div = dstwidth % 4;
                    int divk;

                    for (h = lines - 1; h >= 0; h--) {              /* Do 4 pixels at a time */
                        dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
                        for (x = 0; x < dstwidth/4; x++, ptr += 3) {
                            *dstpixel++ = ((ptr[0] >> 3) & 0x1f)  | ((ptr[0] >> 6) & 0x03e0)  | ((ptr[0] >> 9) & 0x7c00);
                            *dstpixel++ = ((ptr[0] >> 27) & 0x1f) | ((ptr[1] << 2) & 0x03e0)  | ((ptr[1] >> 1) & 0x7c00);
                            *dstpixel++ = ((ptr[1] >> 19) & 0x1f) | ((ptr[1] >> 22) & 0x03e0) | ((ptr[2] << 7) & 0x7c00);
                            *dstpixel++ = ((ptr[2] >> 11) & 0x1f) | ((ptr[2] >> 14) & 0x03e0) | ((ptr[2] >> 17) & 0x7c00);
                        }
                        for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3)  /* dstwidth not divisible by 4? */
                            *dstpixel++ = (((WORD)bits[2] << 7) & 0x07c00) |
                                            (((WORD)bits[1] << 2) & 0x03e0) |
                                            (((WORD)bits[0] >> 3) & 0x001f);
                        ptr = (DWORD *)((srcbits += linebytes) + left * 3);
                    }
                }
                else
                    goto notsupported;
            }
            break;

        case 16:
            {
                DWORD  *ptr = (DWORD *)(srcbits + left*3);
                LPBYTE bits;
                LPWORD dstpixel;
                int div = dstwidth % 4;
                int divk;

                if( bmpImage->blue_mask == 0x001f && bmpImage->red_mask == 0xf800 )    /* BGR888 to BGR565 */
                {
		    for (h = lines - 1; h >= 0; h--) {              /* Do 4 pixels at a time */
                        dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
                        for (x = 0; x < dstwidth/4; x++, ptr += 3) {
                            *dstpixel++ = ((ptr[0] >> 3) & 0x1f)  | ((ptr[0] >> 5) & 0x07e0)  | ((ptr[0] >> 8) & 0xf800);
                            *dstpixel++ = ((ptr[0] >> 27) & 0x1f) | ((ptr[1] << 3) & 0x07e0)  | (ptr[1] & 0xf800);
                            *dstpixel++ = ((ptr[1] >> 19) & 0x1f) | ((ptr[1] >> 21) & 0x07e0) | ((ptr[2] << 8) & 0xf800);
                            *dstpixel++ = ((ptr[2] >> 11) & 0x1f) | ((ptr[2] >> 13) & 0x07e0) | ((ptr[2] >> 16) & 0xf800);
                        }
                        for (   bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3)  /* dstwidth is not divisible by 4? */
                            *dstpixel++ = (((WORD)bits[2] << 8) & 0xf800) |
                                            (((WORD)bits[1] << 3) & 0x07e0) |
                                            (((WORD)bits[0] >> 3) & 0x001f);
                        ptr = (DWORD *)((srcbits += linebytes) + left * 3);
                    }
                }
                else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x001f ) /* BGR888 to RGB565 */
                {
		    for (h = lines - 1; h >= 0; h--) {              /* Do 4 pixels at a time */
                        dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
                        for (x = 0; x < dstwidth/4; x++, ptr += 3) {
                            *dstpixel++ = ((ptr[0] << 8) & 0xf800)  | ((ptr[0] >> 5) & 0x07e0)  | ((ptr[0] >> 19) & 0x1f);
                            *dstpixel++ = ((ptr[0] >> 16) & 0xf800) | ((ptr[1] << 3) & 0x07e0)  | ((ptr[1] >> 11) & 0x1f);
                            *dstpixel++ = ((ptr[1] >> 8) & 0xf800)  | ((ptr[1] >> 21) & 0x07e0) | ((ptr[2] >> 3) & 0x1f);
                            *dstpixel++ = (ptr[2] & 0xf800)         | ((ptr[2] >> 13) & 0x07e0) | ((ptr[2] >> 27) & 0x1f);
                        }
                        for (   bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3)  /* dstwidth is not divisible by 4? */
                            *dstpixel++ = (((WORD)bits[0] << 8) & 0xf800) |
                                            (((WORD)bits[1] << 3) & 0x07e0) |
                                            (((WORD)bits[2] >> 3) & 0x001f);
                        ptr = (DWORD *)((srcbits += linebytes) + left * 3);
                    }
                }
                else
                    goto notsupported;
            }
            break;
         
        case 1:
        case 4:
        case 8:
            {
                LPBYTE bits = (LPBYTE)srcbits + left*3;

                for (h = lines - 1; h >= 0; h--) {
                    for (x = left; x < dstwidth+left; x++, bits+=3)
                        XPutPixel( bmpImage, x, h, 
                                   X11DRV_PALETTE_ToPhysical(dc, RGB(bits[2], bits[1], bits[0])));
                    bits = (LPBYTE)(srcbits += linebytes) + left * 3;
                }
            }
            break;

        default:
        notsupported:
            FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
                  bmpImage->bits_per_pixel, (int)bmpImage->red_mask, 
                  (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
            break;
    }
}


/***********************************************************************
 *           X11DRV_DIB_GetImageBits_24
 *
 * GetDIBits for an 24-bit deep DIB.
 */
static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
					DWORD dstwidth, DWORD srcwidth,
					PALETTEENTRY *srccolors,
					XImage *bmpImage, DWORD linebytes )
{
    DWORD x, val;
    int h;

    if (lines < 0 )
    {
        lines = -lines;
        dstbits = dstbits + ( linebytes * (lines-1) );
        linebytes = -linebytes;
    }

    switch ( bmpImage->depth )
    {
        case 24:
	    {
		if (bmpImage->bits_per_pixel == 24) {
			int tocopy = linebytes;
			BYTE *srcpixel;
			BYTE *ptr = (LPBYTE)dstbits;

			if (tocopy < 0 ) tocopy = -tocopy;
			srcpixel = bmpImage->data + lines*tocopy;
                        for(h = lines ; h-- ; ) {
				srcpixel-=tocopy;
				memcpy(ptr,srcpixel,tocopy);
				ptr = (LPBYTE)(dstbits+=linebytes);
			}
			break;
		}
	    }
        case 32:
            {
                    DWORD  *srcpixel, buf;
                    LPBYTE bits;
	    DWORD *ptr=(DWORD *)dstbits;
                    int quotient = dstwidth / 4;
                    int remainder = dstwidth % 4;
                    int remk;

	    /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
	    if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 )
	    {
                    for(h = lines - 1; h >= 0; h--)
                    {
		  srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);

                        for (x = 0; x < quotient; x++) {     /* do 4 dwords source, 3 dwords dest at a time */
			  buf = ((*srcpixel++)&0x00ffffff);      /* b1, g1, r1*/
			  *ptr++ = buf | ((*srcpixel)<<24);      /* b2 */
			  buf = ((*srcpixel++>>8)&0x0000ffff);   /* g2, r2 */
			  *ptr++ = buf | ((*srcpixel)<<16);      /* b3, g3 */
			  buf = ((*srcpixel++>>16)&0x000000ff);  /* r3 */
			  *ptr++ = buf | ((*srcpixel++)<<8);     /* b4, g4, r4 */
                        }
                        for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
                        {
                            buf=*srcpixel++;
                            *(WORD*)bits = buf;                    /* b, g */
			  *(bits+2) = buf>>16;                   /* r */
                        }
		  ptr = (DWORD*)(dstbits+=linebytes);
                    }

                }
	    /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
	    else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff )
                {
                    for(h = lines - 1; h >= 0; h--)
                    {
		  srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);

                        for (x = 0; x < quotient; x++) {     /* do 4 dwords source, 3 dwords dest at a time */
                            buf = *srcpixel++;
                            val = ((buf&0xff0000)>>16) | (buf&0xff00) | ((buf&0xff)<<16);       /* b1, g1, r1 */
                            buf = *srcpixel++;
                            *ptr++ = val | ((buf&0xff0000)<<8);                                 /* b2 */
                            val = ((buf&0xff00)>>8) | ((buf&0xff)<<8);                          /* g2, r2 */
                            buf = *srcpixel++;
                            *ptr++ = val | (buf&0xff0000) | ((buf&0xff00)<<16);                 /* b3, g3 */
                            val = (buf&0xff);                                                   /* r3 */
                            buf = *srcpixel++;
                            *ptr++ = val | ((buf&0xff0000)>>8) | ((buf&0xff00)<<8) | (buf<<24); /* b4, g4, r4 */
                        }
                        for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
                        {
                            buf=*srcpixel++;
                            *(WORD*)bits = (buf&0xff00) | ((buf&0xff0000)>>16) ;                /* b, g */
                            *(bits+2) = buf;                                                    /* r */
                        }
		  ptr = (DWORD*)(dstbits+=linebytes);
                    }
                }
	    else goto notsupported;
            }
            break;

        case 15:
            {
                LPWORD srcpixel;
	    LPBYTE bits = dstbits;
                WORD val;

	    /* ==== 555 BGR bitmap to 24 BGR dib ==== */
	    if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 )  
                {
                    for (h = lines - 1; h >= 0; h--) {
		  srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
                        for (x = 0; x < srcwidth; x++, bits += 3) {
                            val = *srcpixel++;
                            bits[2] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));           /*Red*/
                            bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));            /*Green*/
                            bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));            /*Blue*/
			}
		  bits = (dstbits += linebytes);
                    }
                }
	    /* ==== 555 RGB bitmap to 24 RGB dib==== */
	    else if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f )
                {
                    for (h = lines - 1; h >= 0; h--) {
		  srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
                        for (x = 0; x < srcwidth; x++, bits += 3) {
                            val = *srcpixel++;
                            bits[0] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));           /*Red*/
                            bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));            /*Green*/
                            bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));            /*Blue*/
                        }
		  bits = (dstbits += linebytes);
                    }
                }
	    else goto notsupported;
            }
            break;

        case 16:
            {
                LPWORD srcpixel;
	    LPBYTE bits = dstbits;
                WORD val;

	    /* ==== 565 BGR bitmap to 24 BGR dib ==== */
	    if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0xf800 )
                {
                    for (h = lines - 1; h >= 0; h--) {
		  srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
                        for (x = 0; x < srcwidth; x++, bits += 3) {
                            val = *srcpixel++;
                            bits[2] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));           /*Red*/
                            bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03));            /*Green*/
                            bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));            /*Blue*/
                        }
		  bits = (dstbits += linebytes);
                    }
                }
	    /* ==== 565 RGB bitmap to 24 BGR dib ==== */
	    else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x1f )
                {
                    for (h = lines - 1; h >= 0; h--) {
		  srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
                        for (x = 0; x < srcwidth; x++, bits += 3) {
                            val = *srcpixel++;
                            bits[0] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));           /*Red*/
                            bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03));            /*Green*/
                            bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));            /*Blue*/
                        }
		  bits = (dstbits += linebytes);
                    }
                }
	    else  goto notsupported;
	    }
            break;

        case 1:
	    /* ==== monochrome bitmap to 24 BGR dib ==== */
        case 4:
	    /* ==== 4 colormap bitmap to 24 BGR dib ==== */
	    if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
            {
		LPBYTE bits = dstbits;
		PALETTEENTRY val;

                for (h = lines - 1; h >= 0; h--) {
		  for (x = 0; x < dstwidth; x++) {
		    val = srccolors[XGetPixel(bmpImage, x, h)];
		    *bits++ = val.peBlue;
		    *bits++ = val.peGreen;
		    *bits++ = val.peRed;
		  }
		  bits = (dstbits += linebytes);
                }
            }
	    else goto notsupported;

            break;

        case 8:
	    /* ==== 8 colormap bitmap to 24 BGR dib ==== */
	    if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors)
            {
                BYTE *srcpixel;
		LPBYTE bits = dstbits;
		PALETTEENTRY val;

                for (h = lines - 1; h >= 0; h--) {
		  srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
		  for (x = 0; x < dstwidth; x++ ) {
		    val = srccolors[(int)*srcpixel++];
		    *bits++ = val.peBlue;               /*Blue*/
		    *bits++ = val.peGreen;              /*Green*/
		    *bits++ = val.peRed;                /*Red*/
                    }
		  bits = (dstbits += linebytes);
                }
            }
	    else goto notsupported;

            break;

        default:
        notsupported:
	    {
	      LPBYTE bits = dstbits;

            FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
                  bmpImage->depth, (int)bmpImage->red_mask, 
                  (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
	      for (h = lines - 1; h >= 0; h--)
		{
		  for (x = 0; x < dstwidth; x++, bits += 3)
		    {
		      COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
		      bits[0] = GetBValue(pixel);
		      bits[1] = GetGValue(pixel);
		      bits[2] = GetRValue(pixel);
		    }
		  bits = (dstbits += linebytes);
		}
	    }
            break;
    }
}


/***********************************************************************
 *           X11DRV_DIB_SetImageBits_32
 *
 * SetDIBits for a 32-bit deep DIB.
 */
static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
                                 DWORD srcwidth, DWORD dstwidth, int left,
					DC *dc, XImage *bmpImage,
					DWORD linebytes )
{
    DWORD x, *ptr;
    int h;
  
    if (lines < 0 )
    {
       lines = -lines;
       srcbits = srcbits + ( linebytes * (lines-1) );
       linebytes = -linebytes;
    }

    ptr = (DWORD *) srcbits + left;

    switch ( bmpImage->depth )
    {
        case 32:
            /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
            if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) {
                for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
                    memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
                }
            }

	    /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
            else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
            {
                DWORD *dstpixel;

                for (h = lines - 1; h >= 0; h--) {
                    dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
                    for (x = 0; x < dstwidth; x++, ptr++) {
                        *dstpixel++ =   ((*ptr << 16) & 0xff0000) | (*ptr & 0xff00) | ((*ptr >> 16) & 0xff);
                    }
                    ptr = (DWORD *) (srcbits += linebytes) + left;
                }
            }
	    else goto notsupported;

            break;

        case 24:
	    /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
	    /* we need to check that source mask matches destination */
	    if (bmpImage->bits_per_pixel == 32)
	    {
                for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
                    memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
		}
	    }
	    else
            {
                BYTE  *bptr;

                ptr = (DWORD *) srcbits + left;
                bptr = bmpImage->data;

                for (h = lines - 1; h >= 0; h--) {
                    for (x = 0; x < dstwidth; x++) {
                         /* *ptr is a 32bit value */
                         /* bptr points to first of 3 bytes */
                        *bptr++ = (*ptr >> 16) & 0xff;
                        *bptr++ = (*ptr >>  8) & 0xff;
                        *bptr++ = (*ptr      ) & 0xff;
                        ptr++;
                    }
                    ptr = (DWORD *) (srcbits += linebytes) + left;
                }
            }
	    break;
	
        case 15:
	    /* ==== 32 BGR dib to 555 BGR bitmap ==== */
	    if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f) {
                LPWORD  dstpixel;

                for (h = lines - 1; h >= 0; h--) {
                    dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
                    for (x = 0; x < dstwidth; x++, ptr++) {
                        *dstpixel++ = (WORD) (((*ptr >> 9) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 3) & 0x001f));
                    }
                    ptr = (DWORD *) (srcbits += linebytes) + left;
                }
            }
	    /* ==== 32 BGR dib to 555 RGB bitmap ==== */
	    else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
            {
                LPWORD  dstpixel;

                for (h = lines - 1; h >= 0; h--) {
                    dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
                    for (x = 0; x < dstwidth; x++, ptr++) {
                        *dstpixel++ = (WORD) (((*ptr << 7) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 19) & 0x001f));
                    }
                    ptr = (DWORD *) (srcbits += linebytes) + left;
                }
            }
	    else goto notsupported;

            break;

        case 16:
	    /* ==== 32 BGR dib to 565 BGR bitmap ==== */
	    if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
            {
                LPWORD  dstpixel;

                for (h = lines - 1; h >= 0; h--) {
                    dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
                    for (x = 0; x < dstwidth; x++, ptr++) {
                        *dstpixel++ = (WORD) (((*ptr >> 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 3) & 0x001f));
                    }
                    ptr = (DWORD *) (srcbits += linebytes) + left;
                }
	    }
	    /* ==== 32 BGR dib to 565 RGB bitmap ==== */
	    else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
            {
                LPWORD dstpixel;

                for (h = lines - 1; h >= 0; h--) {
                    dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
                    for (x = 0; x < dstwidth; x++, ptr++) {
                        *dstpixel++ = (WORD) (((*ptr << 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 19) & 0x001f));
                    }
                    ptr = (DWORD *) (srcbits += linebytes) + left;
                }
            }
	    else goto notsupported;

            break;

        case 1:
        case 4:
        case 8:
            {
                LPBYTE bits = (LPBYTE)srcbits + left*4;

                for (h = lines - 1; h >= 0; h--) {
                    for (x = left; x < dstwidth+left; x++, bits += 4)
                        XPutPixel( bmpImage, x, h,
                                   X11DRV_PALETTE_ToPhysical(dc, RGB( bits[2],  bits[1], *bits )));
                    bits = (LPBYTE)(srcbits += linebytes) + left * 4;
                }
            }
            break;

       default:
       notsupported:
            FIXME("32 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
            break;
    }

}

/***********************************************************************
 *           X11DRV_DIB_GetImageBits_32
 *
 * GetDIBits for an 32-bit deep DIB.
 */
static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
					DWORD dstwidth, DWORD srcwidth,
					PALETTEENTRY *srccolors,
					XImage *bmpImage, DWORD linebytes )
{
    DWORD x;
    int h;
    BYTE *bits;

    DWORD copybytes = srcwidth * 4;

    if (lines < 0 )
    {
        lines = -lines;
        dstbits = dstbits + ( linebytes * (lines-1) );
        linebytes = -linebytes;
    }

    bits = dstbits;

    switch ( bmpImage->depth )
    {
        case 32:
            /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
            if ( bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff )
                for (h = lines - 1; h >= 0; h--, dstbits+=linebytes)
                    memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, copybytes );

	    /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
            else if ( bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000 )
            {
                LPBYTE srcbits;

                for (h = lines - 1; h >= 0; h--) {
                    srcbits = bmpImage->data + h * bmpImage->bytes_per_line;
                    for (x = 0; x < dstwidth; x++, bits+=4, srcbits+=2) {
                        *(bits + 2) = *srcbits++;
                        *(bits + 1) = *srcbits++;
                        *bits = *srcbits;
                    }
                    bits = (dstbits += linebytes);
                }
            }
            else goto notsupported;
            break;

        case 24:
	    /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */
	    /* we need to check that source mask matches destination */
            {
                DWORD *srcpixel;
                BYTE  *bptr;
                DWORD srcdata;

                srcpixel = (DWORD *) dstbits;
                bptr = bmpImage->data;

                for (h = lines - 1; h >= 0; h--) {
                    for (x = 0; x < dstwidth; x++) {
                        /* *srcpixel is a 32bit value */
						/* bptr points to first of 3 bytes */
                        srcdata = 0;
						srcdata	= srcdata << 8 | *bptr++;
						srcdata = srcdata << 8 | *bptr++;	
                        srcdata = srcdata << 8 | *bptr++;	

                        *srcpixel++ = srcdata;
                    }
                    srcpixel = (DWORD *) (dstbits += linebytes);
				}
            }
	    break;

        case 15:
            {
                LPWORD srcpixel;
                WORD val;

	    /* ==== 555 BGR bitmap to 32 BGR dib ==== */
	    if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
	    {
	      for (h = lines - 1; h >= 0; h--) {
		srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
		for (x = 0; x < dstwidth; x++, bits+=2) {
		  val = *srcpixel++;
		  *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
		  *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
		  *bits = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));  /*Red*/
		}
		bits = (dstbits += linebytes);
	      }
            }
	    /* ==== 555 RGB bitmap to 32 BGR dib ==== */
	    else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
	    {
                for (h = lines - 1; h >= 0; h--) {
		srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
		for (x = 0; x < dstwidth; x++, bits+=2) {
                        val = *srcpixel++;
		  *bits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));/*Blue*/
		  *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
		  *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03));   /*Red*/
		}
		bits = (dstbits += linebytes);
                    }
                }
	    else goto notsupported;
            }
            break;

        case 16:
            {
                LPWORD srcpixel;
                WORD val;

	    /* ==== 565 BGR bitmap to 32 BGR dib ==== */
	    if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
	    {
                for (h = lines - 1; h >= 0; h--) {
		srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
		for (x = 0; x < srcwidth; x++, bits+=2) {
                        val = *srcpixel++;
		  *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
		  *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
		  *bits = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));  /*Red*/
		}
		bits = (dstbits += linebytes);
	      }
	    }
	    /* ==== 565 RGB bitmap to 32 BGR dib ==== */
	    else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
	    {
	      for (h = lines - 1; h >= 0; h--) {
		srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
		for (x = 0; x < srcwidth; x++, bits+=2) {
		  val = *srcpixel++;
		  *bits++ = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));/*Blue*/
		  *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
		  *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03));   /*Red*/
		}
		bits = (dstbits += linebytes);
                    }
                }
	    else goto notsupported;
            }
            break;

        case 1:
	    /* ==== monochrome bitmap to 32 BGR dib ==== */
        case 4:
	    /* ==== 4 colormap bitmap to 32 BGR dib ==== */
	    if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
            {
		PALETTEENTRY val;

                for (h = lines - 1; h >= 0; h--) {
		  for (x = 0; x < dstwidth; x++) {
		    val = srccolors[XGetPixel(bmpImage, x, h)];
		    *bits++ = val.peBlue;
		    *bits++ = val.peGreen;
		    *bits++ = val.peRed;
		    *bits++ = 0;
		  }
		  bits = (dstbits += linebytes);
                }
            }
	    else goto notsupported;

            break;

        case 8:
	    /* ==== 8 colormap bitmap to 32 BGR dib ==== */
	    if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
            {
                BYTE *srcpixel;
		PALETTEENTRY val;

                for (h = lines - 1; h >= 0; h--) {
		  srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
		  for (x = 0; x < dstwidth; x++) {
		    val = srccolors[(int)*srcpixel++];
		    *bits++ = val.peBlue;               /*Blue*/
		    *bits++ = val.peGreen;              /*Green*/
		    *bits++ = val.peRed;                /*Red*/
		    *bits++ = 0;
                    }
		  bits = (dstbits += linebytes);
                }
            }
	    else goto notsupported;
            break;

        default:
        notsupported:
	    FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
                  bmpImage->depth, (int)bmpImage->red_mask, 
                  (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
	    for (h = lines - 1; h >= 0; h--)
	      {
		for (x = 0; x < dstwidth; x++, bits += 4)
		  {
		    COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
		    bits[0] = GetBValue(pixel);
		    bits[1] = GetGValue(pixel);
		    bits[2] = GetRValue(pixel);
		  }
		bits = (dstbits += linebytes);
	      }
            break;
    }
}

/***********************************************************************
 *           X11DRV_DIB_SetImageBits
 *
 * Transfer the bits to an X image.
 * Helper function for SetDIBits() and SetDIBitsToDevice().
 */
static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
{
    int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
    XImage *bmpImage;

    wine_tsx11_lock();
    if (descr->image)
        bmpImage = descr->image;
    else {
        bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
				 descr->infoWidth, lines, 32, 0 );
	bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
        if(bmpImage->data == NULL) {
            ERR("Out of memory!\n");
            XDestroyImage( bmpImage );
            wine_tsx11_unlock();
            return lines;
        }
    }

      /* Transfer the pixels */
    switch(descr->infoBpp)
    {
    case 1:
	X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
				   descr->width, descr->xSrc, (int *)(descr->colorMap),
				   bmpImage, descr->dibpitch );
	break;
    case 4:
        if (descr->compression) {
	    XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
			  descr->width, descr->height, AllPlanes, ZPixmap, 
			  bmpImage, descr->xSrc, descr->ySrc );

	    X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
					  descr->infoWidth, descr->width,
					  descr->xSrc, (int *)(descr->colorMap),
					  bmpImage );
	} else
	    X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
				       descr->infoWidth, descr->width,
				       descr->xSrc, (int*)(descr->colorMap),
				       bmpImage, descr->dibpitch );
	break;
    case 8:
        if (descr->compression) {
	    XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
			  descr->width, descr->height, AllPlanes, ZPixmap, 
			  bmpImage, descr->xSrc, descr->ySrc );
	    X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
					  descr->infoWidth, descr->width,
					  descr->xSrc, (int *)(descr->colorMap), 
					  bmpImage );
	} else
	    X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
				       descr->infoWidth, descr->width,
				       descr->xSrc, (int *)(descr->colorMap),
				       bmpImage, descr->dibpitch );
	break;
    case 15:
    case 16:
	X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
				    descr->infoWidth, descr->width,
                                   descr->xSrc, descr->dc,
                                   descr->rMask, descr->gMask, descr->bMask,
                                   bmpImage, descr->dibpitch);
	break;
    case 24:
	X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
				    descr->infoWidth, descr->width,
				    descr->xSrc, descr->dc, bmpImage,
				    descr->dibpitch);
	break;
    case 32:
	X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
				    descr->infoWidth, descr->width,
                                   descr->xSrc, descr->dc,
                                   bmpImage, descr->dibpitch);
	break;
    default:
        WARN("(%d): Invalid depth\n", descr->infoBpp );
        break;
    }

    TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
     descr->drawable, descr->gc, bmpImage,
     descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
     descr->width, descr->height);
#ifdef HAVE_LIBXXSHM
    if (descr->useShm)
    {
        XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
                      descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
                      descr->width, descr->height, FALSE );
        XSync( gdi_display, 0 );
    }
    else
#endif
        XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
		   descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
		   descr->width, descr->height );

    if (!descr->image) XDestroyImage( bmpImage );
    wine_tsx11_unlock();
    return lines;
}

/***********************************************************************
 *           X11DRV_DIB_GetImageBits
 *
 * Transfer the bits from an X image.
 */
static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
{
    int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
    XImage *bmpImage;

    wine_tsx11_lock(); 
   if (descr->image)
        bmpImage = descr->image;
    else {
        bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
				 descr->infoWidth, lines, 32, 0 );
	bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
        if(bmpImage->data == NULL) {
            ERR("Out of memory!\n");
            XDestroyImage( bmpImage );
            wine_tsx11_unlock();
            return lines;
        }
    }

    TRACE("XGetSubImage(%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
     descr->drawable, descr->xSrc, descr->ySrc, descr->width,
     lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
    XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
                  descr->width, lines, AllPlanes, ZPixmap,
                  bmpImage, descr->xDest, descr->yDest );

      /* Transfer the pixels */
    switch(descr->infoBpp)
    {
    case 1:
          X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits, 
				     descr->infoWidth, descr->width,
				     descr->colorMap, descr->palentry, 
                                     bmpImage, descr->dibpitch );
       break;

    case 4:
       if (descr->compression)
	   FIXME("Compression not yet supported!\n");
       else
	   X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits, 
				      descr->infoWidth, descr->width, 
				      descr->colorMap, descr->palentry, 
				      bmpImage, descr->dibpitch );
       break;

    case 8:
       if (descr->compression)
	   FIXME("Compression not yet supported!\n");
       else
	   X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
				      descr->infoWidth, descr->width,
				      descr->colorMap, descr->palentry,
				      bmpImage, descr->dibpitch );
       break;
    case 15:
    case 16:
       X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
				   descr->infoWidth,descr->width,
				   descr->palentry,
				   descr->rMask, descr->gMask, descr->bMask,
				   bmpImage, descr->dibpitch );
       break;

    case 24:
       X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
				   descr->infoWidth,descr->width,
				   descr->palentry, bmpImage, descr->dibpitch);
       break;

    case 32:
       X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
				   descr->infoWidth, descr->width,
				   descr->palentry, bmpImage, descr->dibpitch);
       break;

    default:
        WARN("(%d): Invalid depth\n", descr->infoBpp );
        break;
    }

    if (!descr->image) XDestroyImage( bmpImage );
    wine_tsx11_unlock();
    return lines;
}

/*************************************************************************
 *		X11DRV_SetDIBitsToDevice
 *
 */
INT X11DRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx,
				DWORD cy, INT xSrc, INT ySrc,
				UINT startscan, UINT lines, LPCVOID bits,
				const BITMAPINFO *info, UINT coloruse )
{
    X11DRV_DIB_IMAGEBITS_DESCR descr;
    DWORD width, oldcy = cy;
    INT result;
    int height, tmpheight;
    X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;


    if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, 
			   &descr.infoBpp, &descr.compression ) == -1)
        return 0;
    tmpheight = height;
    if (height < 0) height = -height;
    if (!lines || (startscan >= height)) return 0;
    if (startscan + lines > height) lines = height - startscan;
    if (ySrc < startscan) ySrc = startscan;
    else if (ySrc >= startscan + lines) return 0;
    if (xSrc >= width) return 0;
    if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
    if (xSrc + cx >= width) cx = width - xSrc;
    if (!cx || !cy) return 0;

    X11DRV_SetupGCForText( dc );  /* To have the correct colors */
    TSXSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);

    switch (descr.infoBpp)
    {
       case 1:
       case 4:
       case 8:
               descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap( 
                                            coloruse == DIB_PAL_COLORS ? dc : NULL, coloruse,
                                            dc->bitsPerPixel, info, &descr.nColorMap );
               if (!descr.colorMap) return 0;
               descr.rMask = descr.gMask = descr.bMask = 0;
               break;
       case 15:
       case 16:
               descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
               descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0x03e0;
               descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0x001f;
               descr.colorMap = 0;
               break;

       case 24:
               descr.rMask = descr.gMask = descr.bMask = 0;
               descr.colorMap = 0;
               break;

       case 32:
               descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
               descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0xff00;
               descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0xff;
               descr.colorMap = 0;
               break;
    }

    descr.dc        = dc;
    descr.bits      = bits;
    descr.image     = NULL;
    descr.palentry  = NULL;
    descr.lines     = tmpheight >= 0 ? lines : -lines;
    descr.infoWidth = width;
    descr.depth     = dc->bitsPerPixel;
    descr.drawable  = physDev->drawable;
    descr.gc        = physDev->gc;
    descr.xSrc      = xSrc;
    descr.ySrc      = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy) 
                                     : ySrc - startscan;
    descr.xDest     = dc->DCOrgX + XLPTODP( dc, xDest );
    descr.yDest     = dc->DCOrgY + YLPTODP( dc, yDest ) +
                                     (tmpheight >= 0 ? oldcy-cy : 0);
    descr.width     = cx;
    descr.height    = cy;
    descr.useShm    = FALSE;
    descr.dibpitch  = ((width * descr.infoBpp + 31) &~31) / 8;

    result = X11DRV_DIB_SetImageBits( &descr );

    if (descr.infoBpp <= 8)
       HeapFree(GetProcessHeap(), 0, descr.colorMap);
    return result;
}

/***********************************************************************
 *           X11DRV_DIB_SetDIBits
 */
INT X11DRV_DIB_SetDIBits(
  BITMAPOBJ *bmp, DC *dc, UINT startscan,
  UINT lines, LPCVOID bits, const BITMAPINFO *info,
  UINT coloruse, HBITMAP hbitmap)
{
  X11DRV_DIB_IMAGEBITS_DESCR descr;
  int height, tmpheight;
  INT result;

  descr.dc = dc;

  if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
			 &descr.infoBpp, &descr.compression ) == -1)
      return 0;

  tmpheight = height;
  if (height < 0) height = -height;
  if (!lines || (startscan >= height))
      return 0;

  if (startscan + lines > height) lines = height - startscan;

  switch (descr.infoBpp)
  {
       case 1:
       case 4:
       case 8:
	       descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
                        coloruse == DIB_PAL_COLORS ? descr.dc : NULL, coloruse,
                                                          bmp->bitmap.bmBitsPixel,
                                                          info, &descr.nColorMap );
               if (!descr.colorMap) return 0;
               descr.rMask = descr.gMask = descr.bMask = 0;
               break;
       case 15:
       case 16:
               descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
               descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0x03e0;
               descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0x001f;
               descr.colorMap = 0;
               break;

       case 24:
               descr.rMask = descr.gMask = descr.bMask = 0;
               descr.colorMap = 0;
               break;

       case 32:
               descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
               descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0xff00;
               descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0xff;
               descr.colorMap = 0;
               break;

       default: break;
  }

  /* HACK for now */
  if(!bmp->physBitmap)
    X11DRV_CreateBitmap(hbitmap);

  descr.bits      = bits;
  descr.image     = NULL;
  descr.palentry  = NULL;
  descr.lines     = tmpheight >= 0 ? lines : -lines;
  descr.depth     = bmp->bitmap.bmBitsPixel;
  descr.drawable  = (Pixmap)bmp->physBitmap;
  descr.gc        = BITMAP_GC(bmp);
  descr.xSrc      = 0;
  descr.ySrc      = 0;
  descr.xDest     = 0;
  descr.yDest     = height - startscan - lines;
  descr.width     = bmp->bitmap.bmWidth;
  descr.height    = lines;
  descr.useShm    = FALSE;
  descr.dibpitch  = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
  result = X11DRV_DIB_SetImageBits( &descr );

  if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);

  return result;
}

/***********************************************************************
 *           X11DRV_DIB_GetDIBits
 */
INT X11DRV_DIB_GetDIBits(
  BITMAPOBJ *bmp, DC *dc, UINT startscan, 
  UINT lines, LPVOID bits, BITMAPINFO *info,
  UINT coloruse, HBITMAP hbitmap)
{
  X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
  X11DRV_DIB_IMAGEBITS_DESCR descr;
  PALETTEOBJ * palette;
  int height;
  
  TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
	lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
	(int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
        startscan );

  if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
      return 0;

  if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;

  height = info->bmiHeader.biHeight;
  if (height < 0) height = -height;
  if( lines > height ) lines = height;
  /* Top-down images have a negative biHeight, the scanlines of theses images
   * were inverted in X11DRV_DIB_GetImageBits_xx
   * To prevent this we simply change the sign of lines
   * (the number of scan lines to copy).
   * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
   */
  if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;

  if( startscan >= bmp->bitmap.bmHeight )
  {
      lines = 0;
      goto done;
  }
  
  if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
                        &descr.infoBpp, &descr.compression ) == -1)
  {
      lines = 0;
      goto done;
  }

  switch (descr.infoBpp)
  {
      case 1:
      case 4:
      case 8:
      case 24:
          descr.rMask = descr.gMask = descr.bMask = 0;
          break;
      case 15:
      case 16:
          descr.rMask = 0x7c00;
          descr.gMask = 0x03e0;
          descr.bMask = 0x001f;
          break;
  
      case 32:
          descr.rMask = 0xff0000;
          descr.gMask = 0xff00;
          descr.bMask = 0xff;
          break;
  }

  /* Hack for now */
  if(!bmp->physBitmap)
    X11DRV_CreateBitmap(hbitmap);


  descr.dc        = dc;
  descr.palentry  = palette->logpalette.palPalEntry;
  descr.bits      = bits;
  descr.image     = NULL;
  descr.lines     = lines;
  descr.depth     = bmp->bitmap.bmBitsPixel;
  descr.drawable  = (Pixmap)bmp->physBitmap;
  descr.gc        = BITMAP_GC(bmp);
  descr.width     = bmp->bitmap.bmWidth;
  descr.height    = bmp->bitmap.bmHeight;
  descr.colorMap  = info->bmiColors;
  descr.xDest     = 0;
  descr.yDest     = 0;
  descr.xSrc      = 0;
  
  if (descr.lines > 0)
  {
     descr.ySrc = (descr.height-1) - (startscan + (lines-1));
  }
  else
  {
     descr.ySrc = startscan;
  }
#ifdef HAVE_LIBXXSHM
  descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
#else
  descr.useShm = FALSE;
#endif
  descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
		       : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);

  X11DRV_DIB_GetImageBits( &descr );

  if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
      info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
					 info->bmiHeader.biWidth,
					 info->bmiHeader.biHeight,
					 info->bmiHeader.biBitCount );

  info->bmiHeader.biCompression = 0;
  if (descr.compression == BI_BITFIELDS)
  {
    *(DWORD *)info->bmiColors = descr.rMask;
    *((DWORD *)info->bmiColors+1) = descr.gMask;
    *((DWORD *)info->bmiColors+2) = descr.bMask;
  }

done:
  GDI_ReleaseObj( dc->hPalette );
 
  return lines;
}

/***********************************************************************
 *           DIB_DoProtectDIBSection
 */
static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
{
    DIBSECTION *dib = bmp->dib;
    INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
                                             : -dib->dsBm.bmHeight;
    /* use the biSizeImage data as the memory size only if we're dealing with a
       compressed image where the value is set.  Otherwise, calculate based on
       width * height */
    INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
                         ? dib->dsBmih.biSizeImage
                         : dib->dsBm.bmWidthBytes * effHeight;
    DWORD old_prot;

    VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
    TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
}

/***********************************************************************
 *           X11DRV_DIB_DoUpdateDIBSection
 */
static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
					void *colorMap, int nColorMap,
					Drawable dest,
					DWORD xSrc, DWORD ySrc,
					DWORD xDest, DWORD yDest,
					DWORD width, DWORD height)
{
  X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
  X11DRV_DIB_IMAGEBITS_DESCR descr;
  
  if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
			 &descr.infoBpp, &descr.compression ) == -1)
    return;

  descr.dc        = NULL;
  descr.palentry  = NULL;
  descr.image     = dib->image;
  descr.colorMap  = colorMap;
  descr.nColorMap = nColorMap;
  descr.bits      = dib->dibSection.dsBm.bmBits;
  descr.depth     = bmp->bitmap.bmBitsPixel;
  
  switch (descr.infoBpp)
  {
    case 1:
    case 4:
    case 8:
    case 24:
      descr.rMask = descr.gMask = descr.bMask = 0;
      break;
    case 15:
    case 16:
      descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
      descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
      descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
      break;

    case 32:
      descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff;
      descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0xff00;
      descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0xff0000;
      break;
  }

  /* Hack for now */
  descr.drawable  = dest;
  descr.gc        = BITMAP_GC(bmp);
  descr.xSrc      = xSrc;
  descr.ySrc      = ySrc;
  descr.xDest     = xDest;
  descr.yDest     = yDest;
  descr.width     = width;
  descr.height    = height;
#ifdef HAVE_LIBXXSHM
  descr.useShm = (dib->shminfo.shmid != -1);
#else
  descr.useShm = FALSE;
#endif
  descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;

  if (toDIB)
    {
      TRACE("Copying from Pixmap to DIB bits\n");
      X11DRV_DIB_GetImageBits( &descr );
    }
  else
    {
      TRACE("Copying from DIB bits to Pixmap\n"); 
      X11DRV_DIB_SetImageBits( &descr );
    }
}

/***********************************************************************
 *           X11DRV_DIB_CopyDIBSection
 */
void X11DRV_DIB_CopyDIBSection(DC *dcSrc, DC *dcDst,
			       DWORD xSrc, DWORD ySrc,
			       DWORD xDest, DWORD yDest,
			       DWORD width, DWORD height)
{
  BITMAPOBJ *bmp;
  X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcDst->physDev;
  int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;

  TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst,
    xSrc, ySrc, xDest, yDest, width, height);
  /* this function is meant as an optimization for BitBlt,
   * not to be called otherwise */
  if (!(dcSrc->flags & DC_MEMORY)) {
    ERR("called for non-memory source DC!?\n");
    return;
  }

  bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC );
  if (!(bmp && bmp->dib)) {
    ERR("called for non-DIBSection!?\n");
    GDI_ReleaseObj( dcSrc->hBitmap );
    return;
  }
  /* while BitBlt should already have made sure we only get
   * positive values, we should check for oversize values */
  if ((xSrc < bmp->bitmap.bmWidth) &&
      (ySrc < bmp->bitmap.bmHeight)) {
    if (xSrc + width > bmp->bitmap.bmWidth)
      width = bmp->bitmap.bmWidth - xSrc;
    if (ySrc + height > bmp->bitmap.bmHeight)
      height = bmp->bitmap.bmHeight - ySrc;
    /* if the source bitmap is 8bpp or less, we're supposed to use the
     * DC's palette for color conversion (not the DIB color table) */
    if (bmp->dib->dsBm.bmBitsPixel <= 8) {
      X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
      if ((!dcSrc->hPalette) ||
	  (dcSrc->hPalette == GetStockObject(DEFAULT_PALETTE))) {
	/* HACK: no palette has been set in the source DC,
	 * use the DIB colormap instead - this is necessary in some
	 * cases since we need to do depth conversion in some places
	 * where real Windows can just copy data straight over */
	colorMap = dib->colorMap;
	nColorMap = dib->nColorMap;
      } else {
	colorMap = X11DRV_DIB_BuildColorMap( dcSrc, (WORD)-1,
					     bmp->dib->dsBm.bmBitsPixel,
					     (BITMAPINFO*)&(bmp->dib->dsBmih),
					     &nColorMap );
	if (colorMap) aColorMap = TRUE;
      }
    }
    /* perform the copy */
    X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
				physDev->drawable, xSrc, ySrc, xDest, yDest,
				width, height);
    /* free color mapping */
    if (aColorMap)
      HeapFree(GetProcessHeap(), 0, colorMap);
  }
  GDI_ReleaseObj( dcSrc->hBitmap );
}

/***********************************************************************
 *           X11DRV_DIB_DoUpdateDIBSection
 */
static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
{
  X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
  X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
			      (Drawable)bmp->physBitmap, 0, 0, 0, 0,
			      bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
}

/***********************************************************************
 *           X11DRV_DIB_FaultHandler
 */
static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
{
  BITMAPOBJ *bmp;
  INT state;
  
  bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
  if (!bmp) return FALSE;

  state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
  if (state != DIB_Status_InSync) {
    /* no way to tell whether app needs read or write yet,
     * try read first */
    X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
  } else {
    /* hm, apparently the app must have write access */
    X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
  }
  X11DRV_DIB_Unlock(bmp, TRUE);

  GDI_ReleaseObj( (HBITMAP)res );
  return TRUE;
}

/***********************************************************************
 *           X11DRV_DIB_Coerce
 */
INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
{
  X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
  INT ret = DIB_Status_None;

  if (dib) {
    EnterCriticalSection(&(dib->lock));
    ret = dib->status;
    switch (req) {
    case DIB_Status_GdiMod:
      /* GDI access - request to draw on pixmap */
      switch (dib->status)
      {
        default:
        case DIB_Status_None:
	  dib->p_status = DIB_Status_GdiMod;
	  X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
	  break;

        case DIB_Status_GdiMod:
	  TRACE("GdiMod requested in status GdiMod\n" );
	  break;

        case DIB_Status_InSync:
	  TRACE("GdiMod requested in status InSync\n" );
	  X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
	  dib->status = DIB_Status_GdiMod;
	  dib->p_status = DIB_Status_InSync;
	  break;

	case DIB_Status_AuxMod:
	  TRACE("GdiMod requested in status AuxMod\n" );
	  if (lossy) dib->status = DIB_Status_GdiMod;
	  else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
	  dib->p_status = DIB_Status_AuxMod;
	  if (dib->status != DIB_Status_AppMod) {
	    X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
	    break;
	  }
	  /* fall through if copy_aux() had to change to AppMod state */

        case DIB_Status_AppMod:
	  TRACE("GdiMod requested in status AppMod\n" );
	  if (!lossy) {
	    /* make it readonly to avoid app changing data while we copy */
	    X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
	    X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
	  }
	  X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
	  dib->p_status = DIB_Status_AppMod;
	  dib->status = DIB_Status_GdiMod;
	  break;
      }
      break;

    case DIB_Status_InSync:
      /* App access - request access to read DIB surface */
      /* (typically called from signal handler) */
      switch (dib->status)
      {
        default:
        case DIB_Status_None:
	  /* shouldn't happen from signal handler */
	  break;

	case DIB_Status_AuxMod:
	  TRACE("InSync requested in status AuxMod\n" );
	  if (lossy) dib->status = DIB_Status_InSync;
	  else {
	    X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
	    (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
	  }
	  if (dib->status != DIB_Status_GdiMod) {
	    X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
	    break;
	  }
	  /* fall through if copy_aux() had to change to GdiMod state */

	case DIB_Status_GdiMod:
	  TRACE("InSync requested in status GdiMod\n" );
	  if (!lossy) {
	    X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
	    X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
	  }
	  X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
	  dib->status = DIB_Status_InSync;
	  break;

        case DIB_Status_InSync:
	  TRACE("InSync requested in status InSync\n" );
	  /* shouldn't happen from signal handler */
	  break;

        case DIB_Status_AppMod:
	  TRACE("InSync requested in status AppMod\n" );
	  /* no reason to do anything here, and this
	   * shouldn't happen from signal handler */
	  break;
      }
      break;

    case DIB_Status_AppMod:
      /* App access - request access to write DIB surface */
      /* (typically called from signal handler) */
      switch (dib->status)
      {
        default:
        case DIB_Status_None:
	  /* shouldn't happen from signal handler */
	  break;

	case DIB_Status_AuxMod:
	  TRACE("AppMod requested in status AuxMod\n" );
	  X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
	  if (lossy) dib->status = DIB_Status_AppMod;
	  else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
	  if (dib->status != DIB_Status_GdiMod)
	    break;
	  /* fall through if copy_aux() had to change to GdiMod state */

	case DIB_Status_GdiMod:
	  TRACE("AppMod requested in status GdiMod\n" );
	  X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
	  if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
	  dib->status = DIB_Status_AppMod;
	  break;

        case DIB_Status_InSync:
	  TRACE("AppMod requested in status InSync\n" );
	  X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
	  dib->status = DIB_Status_AppMod;
	  break;

        case DIB_Status_AppMod:
	  TRACE("AppMod requested in status AppMod\n" );
	  /* shouldn't happen from signal handler */
	  break;
      }
      break;

    case DIB_Status_AuxMod:
      if (dib->status == DIB_Status_None) {
	dib->p_status = req;
      } else {
	if (dib->status != DIB_Status_AuxMod)
	  dib->p_status = dib->status;
	dib->status = DIB_Status_AuxMod;
      }
      break;
      /* it is up to the caller to do the copy/conversion, probably
       * using the return value to decide where to copy from */
    }
    LeaveCriticalSection(&(dib->lock));
  }
  return ret;
}

/***********************************************************************
 *           X11DRV_DIB_Lock
 */
INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
{
  X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
  INT ret = DIB_Status_None;

  if (dib) {
    TRACE("Locking %p from thread %08lx\n", bmp, GetCurrentThreadId());
    EnterCriticalSection(&(dib->lock));
    ret = dib->status;
    if (req != DIB_Status_None)
      X11DRV_DIB_Coerce(bmp, req, lossy);
  }
  return ret;
}

/***********************************************************************
 *           X11DRV_DIB_Unlock
 */
void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
{
  X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;

  if (dib) {
    switch (dib->status)
    {
      default:
      case DIB_Status_None:
	/* in case anyone is wondering, this is the "signal handler doesn't
	 * work" case, where we always have to be ready for app access */
	if (commit) {
	  switch (dib->p_status)
	  {
	    case DIB_Status_AuxMod:
	      TRACE("Unlocking and syncing from AuxMod\n" );
	      (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
	      if (dib->status != DIB_Status_None) {
		dib->p_status = dib->status;
		dib->status = DIB_Status_None;
	      }
	      if (dib->p_status != DIB_Status_GdiMod)
		break;
	      /* fall through if copy_aux() had to change to GdiMod state */

	    case DIB_Status_GdiMod:
	      TRACE("Unlocking and syncing from GdiMod\n" );
	      X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
	      break;

	    default:
	      TRACE("Unlocking without needing to sync\n" );
	      break;
	  }
	}
	else TRACE("Unlocking with no changes\n");
	dib->p_status = DIB_Status_None;
	break;

      case DIB_Status_GdiMod:
	TRACE("Unlocking in status GdiMod\n" );
	/* DIB was protected in Coerce */
	if (!commit) {
	  /* no commit, revert to InSync if applicable */
	  if ((dib->p_status == DIB_Status_InSync) ||
	      (dib->p_status == DIB_Status_AppMod)) {
	    X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
	    dib->status = DIB_Status_InSync;
	  }
	}
	break;

      case DIB_Status_InSync:
	TRACE("Unlocking in status InSync\n" );
	/* DIB was already protected in Coerce */
	break;

      case DIB_Status_AppMod:
	TRACE("Unlocking in status AppMod\n" );
	/* DIB was already protected in Coerce */
	/* this case is ordinary only called from the signal handler,
	 * so we don't bother to check for !commit */
	break;

      case DIB_Status_AuxMod:
	TRACE("Unlocking in status AuxMod\n" );
	if (commit) {
	  /* DIB may need protection now */
	  if ((dib->p_status == DIB_Status_InSync) ||
	      (dib->p_status == DIB_Status_AppMod))
	    X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
	} else {
	  /* no commit, revert to previous state */
	  if (dib->p_status != DIB_Status_None)
	    dib->status = dib->p_status;
	  /* no protections changed */
	}
	dib->p_status = DIB_Status_None;
	break;
    }
    LeaveCriticalSection(&(dib->lock));
    TRACE("Unlocked %p\n", bmp);
  }
}

/***********************************************************************
 *           X11DRV_CoerceDIBSection2
 */
INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
{
  BITMAPOBJ *bmp;
  INT ret;

  bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
  if (!bmp) return DIB_Status_None;
  ret = X11DRV_DIB_Coerce(bmp, req, lossy);
  GDI_ReleaseObj( hBmp );
  return ret;
}

/***********************************************************************
 *           X11DRV_LockDIBSection2
 */
INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
{
  BITMAPOBJ *bmp;
  INT ret;

  bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
  if (!bmp) return DIB_Status_None;
  ret = X11DRV_DIB_Lock(bmp, req, lossy);
  GDI_ReleaseObj( hBmp );
  return ret;
}

/***********************************************************************
 *           X11DRV_UnlockDIBSection2
 */
void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
{
  BITMAPOBJ *bmp;

  bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
  if (!bmp) return;
  X11DRV_DIB_Unlock(bmp, commit);
  GDI_ReleaseObj( hBmp );
}

/***********************************************************************
 *           X11DRV_CoerceDIBSection
 */
INT X11DRV_CoerceDIBSection(DC *dc, INT req, BOOL lossy)
{
  if (!dc) return DIB_Status_None;
  return X11DRV_CoerceDIBSection2( dc->hBitmap, req, lossy );
}

/***********************************************************************
 *           X11DRV_LockDIBSection
 */
INT X11DRV_LockDIBSection(DC *dc, INT req, BOOL lossy)
{
  if (!dc) return DIB_Status_None;
  if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;

  return X11DRV_LockDIBSection2( dc->hBitmap, req, lossy );
}

/***********************************************************************
 *           X11DRV_UnlockDIBSection
 */
void X11DRV_UnlockDIBSection(DC *dc, BOOL commit)
{
  if (!dc) return;
  if (!(dc->flags & DC_MEMORY)) return;

  X11DRV_UnlockDIBSection2( dc->hBitmap, commit );
}

/***********************************************************************
 *           X11DRV_DIB_CreateDIBSection16
 */
HBITMAP16 X11DRV_DIB_CreateDIBSection16(
  DC *dc, BITMAPINFO *bmi, UINT16 usage,
  SEGPTR *bits, HANDLE section,
  DWORD offset, DWORD ovr_pitch)
{
  HBITMAP res = X11DRV_DIB_CreateDIBSection(dc, bmi, usage, NULL, 
					    section, offset, ovr_pitch);
  if ( res )
    {
      BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
      if ( bmp && bmp->dib )
	{
	  DIBSECTION *dib = bmp->dib;
	  INT height = dib->dsBm.bmHeight >= 0 ?
	    dib->dsBm.bmHeight : -dib->dsBm.bmHeight;
	  /* same as above - only use biSizeImage as the correct size if it a
	     compressed image and it's currently non-zero.  In other cases, use
	     width * height as the value. */
	  INT size = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
	    ? dib->dsBmih.biSizeImage
	    : dib->dsBm.bmWidthBytes * height;
	  if ( dib->dsBm.bmBits )
	    {
	      ((X11DRV_DIBSECTION *) bmp->dib)->selector = 
                  SELECTOR_AllocBlock( dib->dsBm.bmBits, size, WINE_LDT_FLAGS_DATA );
	    }
	  TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
			 dib->dsBm.bmBits, size, ((X11DRV_DIBSECTION *) bmp->dib)->selector,
			 MAKESEGPTR(((X11DRV_DIBSECTION *) bmp->dib)->selector, 0));
      if ( bits ) 
	*bits = MAKESEGPTR( ((X11DRV_DIBSECTION *) bmp->dib)->selector, 0 );
    }
      if (bmp) GDI_ReleaseObj( res );
    }

    return res;
}

#ifdef HAVE_LIBXXSHM
/***********************************************************************
 *           X11DRV_XShmErrorHandler
 *
 */
static int XShmErrorHandler(Display *dpy, XErrorEvent *event) 
{
    XShmErrorFlag = 1;
    return 0;
}

/***********************************************************************
 *           X11DRV_XShmCreateImage
 *
 */
static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
                                       XShmSegmentInfo* shminfo)
{
    int (*WineXHandler)(Display *, XErrorEvent *);
    XImage *image;

    wine_tsx11_lock();
    image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
    if (image)
    {
        shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
                                  IPC_CREAT|0700);
        if( shminfo->shmid != -1 )
        {
            shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
            if( shminfo->shmaddr != (char*)-1 )
            {
                shminfo->readOnly = FALSE;
                if( XShmAttach( gdi_display, shminfo ) != 0)
                {
                    /* Reset the error flag */
                    XShmErrorFlag = 0;
                    WineXHandler = XSetErrorHandler(XShmErrorHandler);
                    XSync( gdi_display, 0 );

                    if (!XShmErrorFlag)
                    {
			shmctl(shminfo->shmid, IPC_RMID, 0);

                        XSetErrorHandler(WineXHandler);
                        wine_tsx11_unlock();
                        return image; /* Success! */
                    }
                    /* An error occured */
                    XShmErrorFlag = 0;
                    XSetErrorHandler(WineXHandler);
                }
                shmdt(shminfo->shmaddr);
            }
            shmctl(shminfo->shmid, IPC_RMID, 0);
        }
        XFlush(gdi_display);
        XDestroyImage(image);
        image = NULL;
    }
    wine_tsx11_unlock();
    return image;
}
#endif /* HAVE_LIBXXSHM */


/***********************************************************************
 *           X11DRV_DIB_CreateDIBSection
 */
HBITMAP X11DRV_DIB_CreateDIBSection(
  DC *dc, BITMAPINFO *bmi, UINT usage,
  LPVOID *bits, HANDLE section,
  DWORD offset, DWORD ovr_pitch)
{
  HBITMAP res = 0;
  BITMAPOBJ *bmp = NULL;
  X11DRV_DIBSECTION *dib = NULL;
  int *colorMap = NULL;
  int nColorMap;
  
  /* Fill BITMAP32 structure with DIB data */
  BITMAPINFOHEADER *bi = &bmi->bmiHeader;
  INT effHeight, totalSize;
  BITMAP bm;
  LPVOID mapBits = NULL;
  
  TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
	bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
	bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
  
  effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
  bm.bmType = 0;
  bm.bmWidth = bi->biWidth;
  bm.bmHeight = effHeight;
  bm.bmWidthBytes = ovr_pitch ? ovr_pitch
			      : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
  bm.bmPlanes = bi->biPlanes;
  bm.bmBitsPixel = bi->biBitCount;
  bm.bmBits = NULL;
  
  /* Get storage location for DIB bits.  Only use biSizeImage if it's valid and
     we're dealing with a compressed bitmap.  Otherwise, use width * height. */
  totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
    ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
  
  if (section)
  {
      SYSTEM_INFO SystemInfo;
      DWORD mapOffset;
      INT mapSize;

      GetSystemInfo( &SystemInfo );
      mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
      mapSize = totalSize + (offset - mapOffset);
      mapBits = MapViewOfFile( section,
			       FILE_MAP_ALL_ACCESS, 
			       0L,
			       mapOffset,
			       mapSize );
      bm.bmBits = (char *)mapBits + (offset - mapOffset);
  }
  else if (ovr_pitch && offset)
    bm.bmBits = (LPVOID) offset;
  else {
    offset = 0;
    bm.bmBits = VirtualAlloc(NULL, totalSize, 
			     MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
  }
  
  /* Create Color Map */
  if (bm.bmBits && bm.bmBitsPixel <= 8)
      colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? dc : NULL, 
				usage, bm.bmBitsPixel, bmi, &nColorMap );

  /* Allocate Memory for DIB and fill structure */
  if (bm.bmBits)
    dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
  if (dib)
    {
      dib->dibSection.dsBm = bm;
      dib->dibSection.dsBmih = *bi;
      dib->dibSection.dsBmih.biSizeImage = totalSize;

      /* Set dsBitfields values */
       if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
       {
           dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
       }
       else switch( bi->biBitCount )
       {
           case 16:
               dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
               dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
               dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
               break;

           case 24:
               dib->dibSection.dsBitfields[0] = 0xff;
               dib->dibSection.dsBitfields[1] = 0xff00;
               dib->dibSection.dsBitfields[2] = 0xff0000;
               break;

           case 32:
               dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
               dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
               dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
               break;
       }
      dib->dibSection.dshSection = section;
      dib->dibSection.dsOffset = offset;
      
      dib->status    = DIB_Status_None;
      dib->selector  = 0;
      
      dib->nColorMap = nColorMap;
      dib->colorMap  = colorMap;
    }
  
  /* Create Device Dependent Bitmap and add DIB pointer */
  if (dib) 
    {
      res = CreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
      if (res)
	{
	  bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
	  if (bmp)
	    {
	      bmp->dib = (DIBSECTION *) dib;
	      /* HACK for now */
	      if(!bmp->physBitmap)
		X11DRV_CreateBitmap(res); 
	    }
	}
    }
  
  /* Create XImage */
  if (dib && bmp)
  {
#ifdef HAVE_LIBXXSHM
      if (TSXShmQueryExtension(gdi_display) &&
          (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
                                                bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
      {
	; /* Created Image */
      } else {
          dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
          dib->shminfo.shmid = -1;
      }
#else
      dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
#endif
  }
  
  /* Clean up in case of errors */
  if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
    {
      TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
	    res, bmp, dib, bm.bmBits);
      if (bm.bmBits)
        {
	  if (section)
	    UnmapViewOfFile(mapBits), bm.bmBits = NULL;
	  else if (!offset)
	    VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
        }
      
      if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
      if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
      if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
      if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
      if (res) { DeleteObject(res); res = 0; }
    }
  else if (bm.bmBits)
    {
      /* Install fault handler, if possible */
      InitializeCriticalSection(&(dib->lock));
      if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
        {
          if (section || offset)
            {
              X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
              if (dib) dib->status = DIB_Status_AppMod;
            }
          else
            {
	      X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
	      if (dib) dib->status = DIB_Status_InSync;
	    }
        }
    }

  /* Return BITMAP handle and storage location */
  if (bmp) GDI_ReleaseObj(res);
  if (bm.bmBits && bits) *bits = bm.bmBits;
  return res;
}

/***********************************************************************
 *           X11DRV_DIB_DeleteDIBSection
 */
void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
{
  X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;

  if (dib->image) 
  {
#ifdef HAVE_LIBXXSHM
      if (dib->shminfo.shmid != -1)
      {
          TSXShmDetach (gdi_display, &(dib->shminfo));
          XDestroyImage (dib->image);
          shmdt (dib->shminfo.shmaddr);
          dib->shminfo.shmid = -1;
      }
      else
#endif
          XDestroyImage( dib->image );
  }
  
  if (dib->colorMap)
    HeapFree(GetProcessHeap(), 0, dib->colorMap);

  if (dib->selector) SELECTOR_FreeBlock( dib->selector );
  DeleteCriticalSection(&(dib->lock));
}

/***********************************************************************
 *           X11DRV_DIB_SetDIBColorTable
 */
UINT X11DRV_DIB_SetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, const RGBQUAD *colors)
{
  X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;

  if (dib && dib->colorMap) {
    X11DRV_DIB_GenColorMap( dc, dib->colorMap, DIB_RGB_COLORS, dib->dibSection.dsBm.bmBitsPixel,
                            TRUE, colors, start, count + start );
    return count;
  }
  return 0;
}

/***********************************************************************
 *           X11DRV_DIB_GetDIBColorTable
 */
UINT X11DRV_DIB_GetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, RGBQUAD *colors)
{
  X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;

  if (dib && dib->colorMap) {
    int i, end = count + start;
    if (end > dib->nColorMap) end = dib->nColorMap;
    for (i = start; i < end; i++,colors++) {
      COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
      colors->rgbBlue  = GetBValue(col);
      colors->rgbGreen = GetGValue(col);
      colors->rgbRed   = GetRValue(col);
      colors->rgbReserved = 0;
    }
    return end-start;
  }
  return 0;
}


/**************************************************************************
 *	        X11DRV_DIB_CreateDIBFromPixmap
 *
 *  Allocates a packed DIB and copies the Pixmap data into it.
 *  If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
 */
HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
{
    HBITMAP hBmp = 0;
    BITMAPOBJ *pBmp = NULL;
    HGLOBAL hPackedDIB = 0;

    /* Allocates an HBITMAP which references the Pixmap passed to us */
    hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
    if (!hBmp)
    {
        TRACE("\tCould not create bitmap header for Pixmap\n");
        goto END;
    }

    /*
     * Create a packed DIB from the Pixmap wrapper bitmap created above.
     * A packed DIB contains a BITMAPINFO structure followed immediately by
     * an optional color palette and the pixel data.
     */
    hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
    
    /* Get a pointer to the BITMAPOBJ structure */
    pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );

    /* We can now get rid of the HBITMAP wrapper we created earlier.
     * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
     */
    if (!bDeletePixmap)
    {
        /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
        pBmp->physBitmap = NULL;
        pBmp->funcs = NULL;
    }
    GDI_ReleaseObj( hBmp );
    DeleteObject(hBmp);  
    
END:
    TRACE("\tReturning packed DIB %x\n", hPackedDIB);
    return hPackedDIB;
}


/**************************************************************************
 *	           X11DRV_DIB_CreatePixmapFromDIB
 *
 *    Creates a Pixmap from a packed DIB
 */
Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
{
    Pixmap pixmap = None;
    HBITMAP hBmp = 0;
    BITMAPOBJ *pBmp = NULL;
    LPBYTE pPackedDIB = NULL;
    LPBITMAPINFO pbmi = NULL;
    LPBITMAPINFOHEADER pbmiHeader = NULL;
    LPBYTE pbits = NULL;
    
    /* Get a pointer to the packed DIB's data  */
    pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
    pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
    pbmi = (LPBITMAPINFO)pPackedDIB;
    pbits = (LPBYTE)(pPackedDIB
                     + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
    
    /* Create a DDB from the DIB */
     
    hBmp = CreateDIBitmap(hdc,
                          pbmiHeader,
                          CBM_INIT,
                          (LPVOID)pbits,
                          pbmi,
                          DIB_RGB_COLORS);

    GlobalUnlock(hPackedDIB);

    TRACE("CreateDIBitmap returned %x\n", hBmp);

    /* Retrieve the internal Pixmap from the DDB */
     
    pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );

    pixmap = (Pixmap)pBmp->physBitmap;
    /* clear the physBitmap so that we can steal its pixmap */
    pBmp->physBitmap = NULL;
    pBmp->funcs = NULL;

    /* Delete the DDB we created earlier now that we have stolen its pixmap */
    GDI_ReleaseObj( hBmp );
    DeleteObject(hBmp);
    
    TRACE("\tReturning Pixmap %ld\n", pixmap);
    return pixmap;
}
