/*
 * 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 "windef.h"
#include "bitmap.h"
#include "x11drv.h"
#include "debugtools.h"
#include "gdi.h"
#include "color.h"
#include "callback.h"
#include "selectors.h"
#include "global.h"

DEFAULT_DEBUG_CHANNEL(bitmap);
DECLARE_DEBUG_CHANNEL(x11drv);

static int bitmapDepthTable[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
static int ximageDepthTable[] = { 0, 0, 0,  0,  0,  0,  0 };

static int XShmErrorFlag = 0;

/***********************************************************************
 *           X11DRV_DIB_Init
 */
BOOL X11DRV_DIB_Init(void)
{
    int		i;
    XImage*	testimage;

    for( i = 0; bitmapDepthTable[i]; i++ )
    {
	 testimage = TSXCreateImage(display, X11DRV_GetVisual(),
			 bitmapDepthTable[i], ZPixmap, 0, NULL, 1, 1, 32, 20 );
	 if( testimage ) ximageDepthTable[i] = testimage->bits_per_pixel;
	 else return FALSE;
	 TSXDestroyImage(testimage);
    }
    return TRUE;
}


/***********************************************************************
 *           X11DRV_DIB_GetXImageWidthBytes
 *
 * Return the width of an X image in bytes
 */
int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
{
    int		i;

    if (!ximageDepthTable[0]) {
	    X11DRV_DIB_Init();
    }
    for( i = 0; bitmapDepthTable[i] ; i++ )
	 if( bitmapDepthTable[i] == depth )
	     return (4 * ((width * ximageDepthTable[i] + 31)/32));
    
    WARN("(%d): Unsupported depth\n", depth );
    return (4 * width);
}

/***********************************************************************
 *           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 i, colors;
    BOOL isInfo;
    WORD *colorPtr;
    int *colorMapping;

    if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
    {
        colors = info->bmiHeader.biClrUsed;
        if (!colors) colors = 1 << info->bmiHeader.biBitCount;
        colorPtr = (WORD *)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;
    }

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

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

            if (depth == 1)  /* Monochrome */
                for (i = 0; i < colors; i++, rgb++)
                    colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
                                       rgb->rgbBlue > 255*3/2);
            else
                for (i = 0; i < colors; 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 = 0; i < colors; i++, rgb++)
                    colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
                                       rgb->rgbtBlue > 255*3/2);
            else
                for (i = 0; i < colors; i++, rgb++)
                    colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbtRed,
                                                               rgb->rgbtGreen,
                                                               rgb->rgbtBlue));
        }
    }
    else  /* DIB_PAL_COLORS */
    {
        for (i = 0; i < colors; i++, colorPtr++)
            colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*colorPtr) );
    }

    *nColors = colors;
    return colorMapping;
}


/***********************************************************************
 *           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 )
{
    int h;

    /* 32 bit aligned */
    DWORD linebytes = ((srcwidth + 31) & ~31) / 8;

    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 x;
    int h;
    BYTE *bits;

       /* 32 bit aligned */
    DWORD linebytes = ((dstwidth + 31) & ~31) / 8;

    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 i, x;
    int h;
    const BYTE *bits = srcbits + (left >> 1);
  
    /* 32 bit aligned */
    DWORD linebytes = ((srcwidth+7)&~7)/2;

    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 x;
    int h;
    BYTE *bits;
    LPBYTE srcpixel;

    /* 32 bit aligned */
    DWORD linebytes = ((srcwidth+7)&~7)/2;

    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/2; x++) {
	  *bits++ = (X11DRV_DIB_MapColor((int *)colors, 16, 
					  XGetPixel( bmpImage, x++, h ), 0) << 4)
	    | (X11DRV_DIB_MapColor((int *)colors, 16,
					XGetPixel( bmpImage, x++, 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 x;
    int h, color;
    const BYTE *bits;

    /* align to 32 bit */
    DWORD linebytes = (srcwidth + 3) & ~3;

    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
    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 x;
    int h;
    BYTE *bits;

    /* align to 32 bit */
    DWORD linebytes = (srcwidth + 3) & ~3;

    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 x;
    int h;
  
    /* align to 32 bit */
    DWORD linebytes = (srcwidth * 2 + 3) & ~3;

    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;

		/* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
		if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
                {
                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, XImage *bmpImage )
{
    DWORD x;
    int h;

    /* align to 32 bit */
    DWORD linebytes = (dstwidth * 2 + 3) & ~3;

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

    switch ( bmpImage->depth )
    {
        case 15:
            /* ==== 555 BGR bitmap to 555 BGR dib ==== */
            if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
                for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
                    memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );

	    /* ==== 555 RGB bitmap to 555 BGR dib ==== */
            else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
            {
                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;

           /* ==== 565 BGR bitmap to 555 BGR dib ==== */
           if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 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)
           {
               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 to 555 BGR dib ==== */
	       if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
	       {
               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 >> 9) & 0x7c00) |                               /* Red */
			      ((val >> 6) & 0x03e0) |                               /* Green */
			      ((val >> 3) & 0x001f);                                /* Blue */
                   }
                   ptr = (LPWORD)(dstbits += linebytes);
		   }
	       }
	       /* ==== 24/32 RGB bitmap to 555 BGR dib ==== */
	       else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
	       {
		 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 << 7) & 0x7c00) |                              /* Red */
			      ((val >> 6) & 0x03e0) |                              /* Green */
			      ((val >> 19) & 0x001f);                              /* Blue */
                   }
                   ptr = (LPWORD) (dstbits += linebytes);
               }
           }
	       else goto notsupported;
           }
           break;

       case 1:
	    /* ==== monochrome bitmap to 16 BGR dib ==== */
       case 4:
	    /* ==== 4 colormap bitmap to 16 BGR dib ==== */
	    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 << 7) & 0x7c00) | 
		             ((val.peGreen << 2) & 0x03e0) |
		             ((val.peBlue >> 3) & 0x001f);
		  }
		  ptr = (LPWORD)(dstbits += linebytes);
                }
            }
	    else goto notsupported;

            break;

        case 8:
	    /* ==== 8 colormap bitmap to 16 BGR dib ==== */
	    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 << 7) & 0x7c00) | 
		             ((val.peGreen << 2) & 0x03e0) |
		             ((val.peBlue >> 3) & 0x001f);
                   }
		  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 %x,%x,%x to 16 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++, ptr++)
		    {
		      COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
		      r = (BYTE) GetRValue(pixel);
		      g = (BYTE) GetGValue(pixel);
		      b = (BYTE) GetBValue(pixel);
		      *ptr = ( ((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((b >> 3) & 0x001f) );
		    }
		  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 x;
    int h;
  
    /* align to 32 bit */
    DWORD linebytes = (srcwidth * 3 + 3) & ~3;
      	
    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), val;
                    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++) {
                            *dstpixel++ = (WORD)((((val = *ptr++) << 7) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 19) & 0x1f));
                            *dstpixel++ = (WORD)(((val >> 17) & 0x7c00) | (((val = *ptr++) << 2) & 0x03e0) | ((val >> 11) & 0x1f));
                            *dstpixel++ = (WORD)(((val >> 9) & 0x07c00) | ((val >> 22) & 0x03e0) | (((val = *ptr++) >> 3) & 0x1f));
                            *dstpixel++ = (WORD)(((val >> 1) & 0x07c00) | ((val >> 14) & 0x03e0) | ((val >> 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), val;
                    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++) {
                            *dstpixel++ = (WORD)((((val = *ptr++) >> 3) & 0x1f) | ((val >> 6) & 0x03e0) | ((val >> 9) & 0x7c00));
                            *dstpixel++ = (WORD)(((val >> 27) & 0x1f) | (((val = *ptr++) << 2) & 0x03e0) | ((val >> 1) & 0x7c00));
                            *dstpixel++ = (WORD)(((val >> 19) & 0x1f) | ((val >> 22) & 0x03e0) | (((val = *ptr++) << 7) & 0x7c00));
                            *dstpixel++ = (WORD)(((val >> 11) & 0x1f) | ((val >> 14) & 0x03e0) | ((val >> 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), val;
                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++) {
                            *dstpixel++ = (WORD)((((val = *ptr++) >> 3) & 0x1f) | ((val >> 5) & 0x07e0) | ((val >> 8) & 0xf800));
                            *dstpixel++ = (WORD)(((val >> 27) & 0x1f) | (((val = *ptr++) << 3) & 0x07e0) | ((val) & 0xf800));
                            *dstpixel++ = (WORD)(((val >> 19) & 0x1f) | ((val >> 21) & 0x07e0) | (((val = *ptr++) << 8) & 0xf800));
                            *dstpixel++ = (WORD)(((val >> 11) & 0x1f) | ((val >> 13) & 0x07e0) | ((val >> 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++) {
                            *dstpixel++ = (WORD)((((val = *ptr++) << 8) & 0xf800) | ((val >> 5) & 0x07e0) | ((val >> 19) & 0x1f));
                            *dstpixel++ = (WORD)(((val >> 16) & 0xf800) | (((val = *ptr++) << 3) & 0x07e0) | ((val >> 11) & 0x1f));
                            *dstpixel++ = (WORD)(((val >> 8) & 0xf800) | ((val >> 21) & 0x07e0) | (((val = *ptr++) >> 3) & 0x1f));
                            *dstpixel++ = (WORD)((val & 0xf800) | ((val >> 13) & 0x07e0) | ((val >> 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 x, val;
    int h;

    /* align to 32 bit */
    DWORD linebytes = (dstwidth * 3 + 3) & ~3;

    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 x, *ptr;
    int h;
  
    DWORD linebytes = (srcwidth * 4);

    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 */
            {
                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 x;
    int h;
    BYTE *bits;

    /* align to 32 bit */
    DWORD linebytes = (srcwidth * 4);
    DWORD copybytes = linebytes;

    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().
 * The Xlib critical section must be entered before calling this function.
 */
int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
{
    int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
    XImage *bmpImage;

    if (descr->image)
        bmpImage = descr->image;
    else {
        bmpImage = XCreateImage( display, X11DRV_GetVisual(), 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 );
            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 );
	break;
    case 4:
        if (descr->compression) {
	    XGetSubImage( 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 );
	break;
    case 8:
        if (descr->compression) {
	    XGetSubImage( 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 );
	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);
	break;
    case 24:
	X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
				    descr->infoWidth, descr->width,
				    descr->xSrc, descr->dc, bmpImage );
	break;
    case 32:
	X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
				    descr->infoWidth, descr->width,
                                   descr->xSrc, descr->dc,
                                   bmpImage);
	break;
    default:
        WARN("(%d): Invalid depth\n", descr->infoBpp );
        break;
    }

    if (descr->useShm)
    {
        XShmPutImage( display, descr->drawable, descr->gc, bmpImage,
                      descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
                      descr->width, descr->height, FALSE );
        XSync( display, 0 );
    }
    else
        XPutImage( display, descr->drawable, descr->gc, bmpImage,
		   descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
		   descr->width, descr->height );

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

/***********************************************************************
 *           X11DRV_DIB_GetImageBits
 *
 * Transfer the bits from an X image.
 * The Xlib critical section must be entered before calling this function.
 */
int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
{
    int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
    XImage *bmpImage;

    if (descr->image)
        bmpImage = descr->image;
    else {
        bmpImage = XCreateImage( display, X11DRV_GetVisual(), 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 );
            return lines;
        }                                                                           }

    XGetSubImage( 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 );
       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 );
       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 );
       break;
    case 15:
    case 16:
       X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
				   descr->infoWidth,descr->width,
				   descr->palentry, bmpImage );
       break;

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

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

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

    if (!descr->image) XDestroyImage( bmpImage );
    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(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;

    EnterCriticalSection( &X11DRV_CritSection );
    result = CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
    LeaveCriticalSection( &X11DRV_CritSection );

    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;
  
  EnterCriticalSection( &X11DRV_CritSection );
  result = CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
  LeaveCriticalSection( &X11DRV_CritSection );
  
  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;
  
  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 > info->bmiHeader.biHeight )  lines = info->bmiHeader.biHeight;
  /* 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 = (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;
          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;
          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;
  }

  if (dib)
    descr.useShm = (dib->shminfo.shmid != -1);
  else
    descr.useShm = FALSE;

  EnterCriticalSection( &X11DRV_CritSection );

  CALL_LARGE_STACK( X11DRV_DIB_GetImageBits, &descr );

  LeaveCriticalSection( &X11DRV_CritSection );
  
  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;

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_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
{
  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  = (RGBQUAD *)dib->colorMap;
  descr.nColorMap = dib->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  = (Pixmap)bmp->physBitmap;
  descr.gc        = BITMAP_GC(bmp);
  descr.xSrc      = 0;
  descr.ySrc      = 0;
  descr.xDest     = 0;
  descr.yDest     = 0;
  descr.width     = bmp->bitmap.bmWidth;
  descr.height    = bmp->bitmap.bmHeight;
  descr.useShm = (dib->shminfo.shmid != -1);

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

/***********************************************************************
 *           X11DRV_DIB_FaultHandler
 */
static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
{
  BOOL handled = FALSE;
  BITMAPOBJ *bmp;
  
  bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
  if (!bmp) return FALSE;
  
  if (bmp->dib)
    switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
      {
      case X11DRV_DIB_GdiMod:
	TRACE("called in status DIB_GdiMod\n" );
	X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
	X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
	X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
	((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_InSync;
	handled = TRUE;
	break;
	
      case X11DRV_DIB_InSync:
	TRACE("called in status X11DRV_DIB_InSync\n" );
	X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
	((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_AppMod;
	handled = TRUE;
	break;
	
      case X11DRV_DIB_AppMod:
	FIXME("called in status X11DRV_DIB_AppMod: this can't happen!\n" );
	break;
	
      case X11DRV_DIB_NoHandler:
	FIXME("called in status DIB_NoHandler: this can't happen!\n" );
	break;
      }
  
  GDI_ReleaseObj( (HBITMAP)res );
  return handled;
}

/***********************************************************************
 *           X11DRV_DIB_CmnUpdateDIBSection
 */
static void X11DRV_DIB_CmnUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
{
  if (!bmp) return;
  if (!bmp->dib) return;
  
  if (!toDIB)
    {
      /* Prepare for access to the DIB by GDI functions */
      
      switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
        {
        default:
        case X11DRV_DIB_NoHandler:
	  X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
	  break;
	  
        case X11DRV_DIB_GdiMod:
	  TRACE("fromDIB called in status X11DRV_DIB_GdiMod\n" );
	  /* nothing to do */
	  break;
	  
        case X11DRV_DIB_InSync:
	  TRACE("fromDIB called in status X11DRV_DIB_InSync\n" );
	  /* nothing to do */
	  break;
	  
        case X11DRV_DIB_AppMod:
	  TRACE("fromDIB called in status X11DRV_DIB_AppMod\n" );
	  X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
	  X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
	  ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_InSync;
	  break;
        }
    }
  else
    {
      /* Acknowledge write access to the DIB by GDI functions */
      
      switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
        {
        default:
        case X11DRV_DIB_NoHandler:
	  X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
	  break;
	  
        case X11DRV_DIB_GdiMod:
	  TRACE("  toDIB called in status X11DRV_DIB_GdiMod\n" );
	  /* nothing to do */
	  break;
	  
        case X11DRV_DIB_InSync:
	  TRACE("  toDIB called in status X11DRV_DIB_InSync\n" );
	  X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
	  ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_GdiMod;
	  break;
	  
        case X11DRV_DIB_AppMod:
	  FIXME("  toDIB called in status X11DRV_DIB_AppMod: "
                "this can't happen!\n" );
	  break;
        }
    }
}

/***********************************************************************
 *           X11DRV_DIB_UpdateDIBSection2
 */
void X11DRV_DIB_UpdateDIBSection2(HBITMAP hbmp, BOOL toDIB)
{
  BITMAPOBJ *bmp;
  
  bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbmp, BITMAP_MAGIC );
  if (!bmp) return;

  X11DRV_DIB_CmnUpdateDIBSection(bmp, toDIB);

  GDI_ReleaseObj(hbmp);
}

/***********************************************************************
 *           X11DRV_DIB_UpdateDIBSection
 */
void X11DRV_DIB_UpdateDIBSection(DC *dc, BOOL toDIB)
{
  /* Ensure this is a Compatible DC that has a DIB section selected */
  
  if (!dc) return;
  if (!(dc->flags & DC_MEMORY)) return;
  
  X11DRV_DIB_UpdateDIBSection2(dc->hBitmap, toDIB);
}

/***********************************************************************
 *           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, 
				     SEGMENT_DATA, FALSE, FALSE );
	    }
	  TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
			 dib->dsBm.bmBits, size, ((X11DRV_DIBSECTION *) bmp->dib)->selector,
			 PTR_SEG_OFF_TO_SEGPTR(((X11DRV_DIBSECTION *) bmp->dib)->selector, 0));
      if ( bits ) 
	*bits = PTR_SEG_OFF_TO_SEGPTR( ((X11DRV_DIBSECTION *) bmp->dib)->selector, 0 );
    }
      if (bmp) GDI_ReleaseObj( res );
    }

    return res;
}

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

/***********************************************************************
 *           X11DRV_XShmCreateImage
 *
 */

extern BOOL X11DRV_XShmCreateImage(XImage** image, int width, int height, int bpp,
		                                   XShmSegmentInfo* shminfo)
{
    int (*WineXHandler)(Display *, XErrorEvent *);
     
    *image = TSXShmCreateImage(display, X11DRV_GetVisual(), bpp, ZPixmap, NULL, shminfo, width, height);
    if( *image != NULL ) 
    {
        EnterCriticalSection( &X11DRV_CritSection );
        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( TSXShmAttach( display, shminfo ) != 0)
                {
		  /* Reset the error flag */
                    XShmErrorFlag = 0;
                    WineXHandler = XSetErrorHandler(XShmErrorHandler);
                    XSync( display, 0 );

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

                        XSetErrorHandler(WineXHandler);
                        LeaveCriticalSection( &X11DRV_CritSection );

                        return TRUE; /* Success! */
                    }    
                    /* An error occured */
                    XShmErrorFlag = 0;
                    XSetErrorHandler(WineXHandler);
                }
                shmdt(shminfo->shmaddr);
            }
            shmctl(shminfo->shmid, IPC_RMID, 0);
        }        
        XFlush(display);
        XDestroyImage(*image);
        LeaveCriticalSection( &X11DRV_CritSection );
    }
    return FALSE;
}


 

/***********************************************************************
 *           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;
  
  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)
    bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS, 
			      0L, offset, totalSize);
  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    = X11DRV_DIB_NoHandler;
      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)
  {
      if (TSXShmQueryExtension(display) &&
          X11DRV_XShmCreateImage( &dib->image, bm.bmWidth, effHeight,
                                  bmp->bitmap.bmBitsPixel, &dib->shminfo ) )
      {
	; /* Created Image */
      } else {
          XCREATEIMAGE( dib->image, bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
          dib->shminfo.shmid = -1;
      }
  }
  
  /* 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(bm.bmBits), 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; }
    }
  
  /* Install fault handler, if possible */
  if (bm.bmBits)
    {
      if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
        {
          if (section || offset)
            {
              X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
              if (dib) dib->status = X11DRV_DIB_AppMod;
            }
          else
            {
	      X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
	      if (dib) dib->status = X11DRV_DIB_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) 
  {
      if (dib->shminfo.shmid != -1)
      {
          TSXShmDetach (display, &(dib->shminfo));
          XDestroyImage (dib->image);
          shmdt (dib->shminfo.shmaddr);
          dib->shminfo.shmid = -1;
      }
      else
          XDestroyImage( dib->image );
  }
  
  if (dib->colorMap)
    HeapFree(GetProcessHeap(), 0, dib->colorMap);
  
  if (dib->selector)
    {
      WORD count = (GET_SEL_LIMIT( dib->selector ) >> 16) + 1;
      SELECTOR_FreeBlock( dib->selector, count );
    }
}


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