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

#include "config.h"

#ifndef X_DISPLAY_MISSING

#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 "dc.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 color;

    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 )) << 4)
	    | (X11DRV_DIB_MapColor((int *)colors, 16,
					XGetPixel( bmpImage, x++, h )) & 0x0f);
           }
           if (dstwidth & 1)
	  *bits = (X11DRV_DIB_MapColor((int *)colors, 16,
					XGetPixel( bmpImage, x++, h )) << 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,
                                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;

    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 = (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--)
		  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++);
				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 24:
        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 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 24:
        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 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->dc && descr->dc->w.flags & DC_DIRTY ) 
        CLIPPING_UpdateGCRegion( descr->dc );

    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!");
            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!");
            XDestroyImage( bmpImage );
            return lines;
        }                                                                           }

    XGetSubImage( display, descr->drawable, descr->xDest, descr->yDest,
                  descr->width, descr->height, AllPlanes, ZPixmap,
                  bmpImage, descr->xSrc, descr->ySrc );

      /* 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->w.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->w.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->w.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->w.DCOrgX + XLPTODP( dc, xDest );
    descr.yDest     = dc->w.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->w.hPalette, PALETTE_MAGIC )))
      return 0;

  if( lines > info->bmiHeader.biHeight )  lines = info->bmiHeader.biHeight;
  if( startscan >= bmp->bitmap.bmHeight ) return FALSE;
  
  if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
                        &descr.infoBpp, &descr.compression ) == -1)
      return FALSE;

  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.lines     = lines;
  descr.depth     = bmp->bitmap.bmBitsPixel;
  descr.drawable  = (Pixmap)bmp->physBitmap;
  descr.gc        = BITMAP_GC(bmp);
  descr.xSrc      = 0;
  descr.ySrc      = startscan;
  descr.xDest     = 0;
  descr.yDest     = 0;
  descr.width     = bmp->bitmap.bmWidth;
  descr.height    = bmp->bitmap.bmHeight;
  descr.colorMap  = info->bmiColors;

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

  EnterCriticalSection( &X11DRV_CritSection );

  descr.image  = (XImage *)CALL_LARGE_STACK( X11DRV_BITMAP_GetXImage, bmp );
  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;

  GDI_HEAP_UNLOCK( dc->w.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;
    INT totalSize = dib->dsBmih.biSizeImage? 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_HEAP_UNLOCK( (HBITMAP)res );
  return handled;
}

/***********************************************************************
 *           X11DRV_DIB_UpdateDIBSection
 */
void X11DRV_DIB_UpdateDIBSection(DC *dc, BOOL toDIB)
{
  BITMAPOBJ *bmp;
  
  /* Ensure this is a Compatible DC that has a DIB section selected */
  
  if (!dc) return;
  if (!(dc->w.flags & DC_MEMORY)) return;
  
  bmp = (BITMAPOBJ *)GDI_GetObjPtr( dc->w.hBitmap, BITMAP_MAGIC );
  if (!bmp) return;
  
  if (!bmp->dib)
    {
      GDI_HEAP_UNLOCK(dc->w.hBitmap);
      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;
        }
    }

    GDI_HEAP_UNLOCK(dc->w.hBitmap);
}

/***********************************************************************
 *           X11DRV_DIB_CreateDIBSection16
 */
HBITMAP16 X11DRV_DIB_CreateDIBSection16(
  DC *dc, BITMAPINFO *bmi, UINT16 usage,
  SEGPTR *bits, HANDLE section,
  DWORD offset)
{
  HBITMAP res = X11DRV_DIB_CreateDIBSection(dc, bmi, usage, NULL, 
					    section, offset);
  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;
	  INT size = dib->dsBmih.biSizeImage ?
	    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));
	}
      GDI_HEAP_UNLOCK( res );
      
      if ( bits ) 
	*bits = PTR_SEG_OFF_TO_SEGPTR( ((X11DRV_DIBSECTION *) bmp->dib)->selector, 0 );
    }

    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)
{
  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 = DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
  bm.bmPlanes = bi->biPlanes;
  bm.bmBitsPixel = bi->biBitCount;
  bm.bmBits = NULL;
  
  /* Get storage location for DIB bits */
  totalSize = bi->biSizeImage? bi->biSizeImage : bm.bmWidthBytes * effHeight;
  
  if (section)
    bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS, 
			      0L, offset, totalSize);
  else
    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;

      /* 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
	    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 (res) { DeleteObject(res); res = 0; }
    }
  
  /* Install fault handler, if possible */
  if (bm.bmBits)
    {
      if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
        {
	  X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
	  if (dib) dib->status = X11DRV_DIB_InSync;
        }
    }

  /* Return BITMAP handle and storage location */
  if (res) GDI_HEAP_UNLOCK(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;
    }
    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 */
    DeleteObject(hBmp);
    
    TRACE("\tReturning Pixmap %ld\n", pixmap);
    return pixmap;
}

#endif /* !defined(X_DISPLAY_MISSING) */



