|  | /* | 
|  | * X11DRV device-independent bitmaps | 
|  | * | 
|  | * Copyright 1993,1994  Alexandre Julliard | 
|  | */ | 
|  |  | 
|  | #include "config.h" | 
|  |  | 
|  | #include "ts_xlib.h" | 
|  | #include "ts_xutil.h" | 
|  | #ifdef HAVE_LIBXXSHM | 
|  | # include "ts_xshm.h" | 
|  | # ifdef HAVE_SYS_SHM_H | 
|  | #  include <sys/shm.h> | 
|  | # endif | 
|  | # ifdef HAVE_SYS_IPC_H | 
|  | #  include <sys/ipc.h> | 
|  | # endif | 
|  | #endif /* defined(HAVE_LIBXXSHM) */ | 
|  |  | 
|  | #include <stdlib.h> | 
|  | #include <string.h> | 
|  | #include "windef.h" | 
|  | #include "bitmap.h" | 
|  | #include "x11drv.h" | 
|  | #include "debugtools.h" | 
|  | #include "gdi.h" | 
|  | #include "color.h" | 
|  | #include "selectors.h" | 
|  | #include "global.h" | 
|  |  | 
|  | DEFAULT_DEBUG_CHANNEL(bitmap); | 
|  | DECLARE_DEBUG_CHANNEL(x11drv); | 
|  |  | 
|  | static int ximageDepthTable[32]; | 
|  |  | 
|  | #ifdef HAVE_LIBXXSHM | 
|  | static int XShmErrorFlag = 0; | 
|  | #endif | 
|  |  | 
|  | /* This structure holds the arguments for DIB_SetImageBits() */ | 
|  | typedef struct | 
|  | { | 
|  | struct tagDC   *dc; | 
|  | LPCVOID         bits; | 
|  | XImage         *image; | 
|  | PALETTEENTRY   *palentry; | 
|  | int             lines; | 
|  | DWORD           infoWidth; | 
|  | WORD            depth; | 
|  | WORD            infoBpp; | 
|  | WORD            compression; | 
|  | RGBQUAD        *colorMap; | 
|  | int             nColorMap; | 
|  | Drawable        drawable; | 
|  | GC              gc; | 
|  | int             xSrc; | 
|  | int             ySrc; | 
|  | int             xDest; | 
|  | int             yDest; | 
|  | int             width; | 
|  | int             height; | 
|  | DWORD           rMask; | 
|  | DWORD           gMask; | 
|  | DWORD           bMask; | 
|  | BOOL            useShm; | 
|  | int             dibpitch; | 
|  | } X11DRV_DIB_IMAGEBITS_DESCR; | 
|  |  | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_GetXImageWidthBytes | 
|  | * | 
|  | * Return the width of an X image in bytes | 
|  | */ | 
|  | inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth ) | 
|  | { | 
|  | if (!depth || depth > 32) goto error; | 
|  |  | 
|  | if (!ximageDepthTable[depth-1]) | 
|  | { | 
|  | XImage *testimage = XCreateImage( gdi_display, visual, depth, | 
|  | ZPixmap, 0, NULL, 1, 1, 32, 20 ); | 
|  | if (testimage) | 
|  | { | 
|  | ximageDepthTable[depth-1] = testimage->bits_per_pixel; | 
|  | XDestroyImage( testimage ); | 
|  | } | 
|  | else ximageDepthTable[depth-1] = -1; | 
|  | } | 
|  | if (ximageDepthTable[depth-1] != -1) | 
|  | return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32)); | 
|  |  | 
|  | error: | 
|  | WARN( "(%d): Unsupported depth\n", depth ); | 
|  | return 4 * width; | 
|  | } | 
|  |  | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_CreateXImage | 
|  | * | 
|  | * Create an X image. | 
|  | */ | 
|  | XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth ) | 
|  | { | 
|  | int width_bytes; | 
|  | XImage *image; | 
|  |  | 
|  | wine_tsx11_lock(); | 
|  | width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth ); | 
|  | image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0, | 
|  | calloc( height, width_bytes ), | 
|  | width, height, 32, width_bytes ); | 
|  | wine_tsx11_unlock(); | 
|  | return image; | 
|  | } | 
|  |  | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_GenColorMap | 
|  | * | 
|  | * Fills the color map of a bitmap palette. Should not be called | 
|  | * for a >8-bit deep bitmap. | 
|  | */ | 
|  | int *X11DRV_DIB_GenColorMap( DC *dc, int *colorMapping, | 
|  | WORD coloruse, WORD depth, BOOL quads, | 
|  | const void *colorPtr, int start, int end ) | 
|  | { | 
|  | int i; | 
|  |  | 
|  | if (coloruse == DIB_RGB_COLORS) | 
|  | { | 
|  | if (quads) | 
|  | { | 
|  | RGBQUAD * rgb = (RGBQUAD *)colorPtr; | 
|  |  | 
|  | if (depth == 1)  /* Monochrome */ | 
|  | for (i = start; i < end; i++, rgb++) | 
|  | colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen + | 
|  | rgb->rgbBlue > 255*3/2); | 
|  | else | 
|  | for (i = start; i < end; i++, rgb++) | 
|  | colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbRed, | 
|  | rgb->rgbGreen, | 
|  | rgb->rgbBlue)); | 
|  | } | 
|  | else | 
|  | { | 
|  | RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr; | 
|  |  | 
|  | if (depth == 1)  /* Monochrome */ | 
|  | for (i = start; i < end; i++, rgb++) | 
|  | colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen + | 
|  | rgb->rgbtBlue > 255*3/2); | 
|  | else | 
|  | for (i = start; i < end; i++, rgb++) | 
|  | colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbtRed, | 
|  | rgb->rgbtGreen, | 
|  | rgb->rgbtBlue)); | 
|  | } | 
|  | } | 
|  | else  /* DIB_PAL_COLORS */ | 
|  | { | 
|  | if (colorPtr) { | 
|  | WORD * index = (WORD *)colorPtr; | 
|  |  | 
|  | for (i = start; i < end; i++, index++) | 
|  | colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) ); | 
|  | } else { | 
|  | for (i = start; i < end; i++) | 
|  | colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(i) ); | 
|  | } | 
|  | } | 
|  |  | 
|  | return colorMapping; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_BuildColorMap | 
|  | * | 
|  | * Build the color map from the bitmap palette. Should not be called | 
|  | * for a >8-bit deep bitmap. | 
|  | */ | 
|  | int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth, | 
|  | const BITMAPINFO *info, int *nColors ) | 
|  | { | 
|  | int colors; | 
|  | BOOL isInfo; | 
|  | const void *colorPtr; | 
|  | int *colorMapping; | 
|  |  | 
|  | if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER)))) | 
|  | { | 
|  | colors = info->bmiHeader.biClrUsed; | 
|  | if (!colors) colors = 1 << info->bmiHeader.biBitCount; | 
|  | colorPtr = info->bmiColors; | 
|  | } | 
|  | else  /* assume BITMAPCOREINFO */ | 
|  | { | 
|  | colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount; | 
|  | colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors; | 
|  | } | 
|  |  | 
|  | if (colors > 256) | 
|  | { | 
|  | ERR("called with >256 colors!\n"); | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | /* just so CopyDIBSection doesn't have to create an identity palette */ | 
|  | if (coloruse == (WORD)-1) colorPtr = NULL; | 
|  |  | 
|  | if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0, | 
|  | colors * sizeof(int) ))) | 
|  | return NULL; | 
|  |  | 
|  | *nColors = colors; | 
|  | return X11DRV_DIB_GenColorMap( dc, colorMapping, coloruse, depth, | 
|  | isInfo, colorPtr, 0, colors); | 
|  | } | 
|  |  | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_MapColor | 
|  | */ | 
|  | int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol ) | 
|  | { | 
|  | int color; | 
|  |  | 
|  | if ((oldcol < nPhysMap) && (physMap[oldcol] == phys)) | 
|  | return oldcol; | 
|  |  | 
|  | for (color = 0; color < nPhysMap; color++) | 
|  | if (physMap[color] == phys) | 
|  | return color; | 
|  |  | 
|  | WARN("Strange color %08x\n", phys); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  | /********************************************************************* | 
|  | *         X11DRV_DIB_GetNearestIndex | 
|  | * | 
|  | * Helper for X11DRV_DIB_GetDIBits. | 
|  | * Returns the nearest colour table index for a given RGB. | 
|  | * Nearest is defined by minimizing the sum of the squares. | 
|  | */ | 
|  | static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b) | 
|  | { | 
|  | INT i, best = -1, diff, bestdiff = -1; | 
|  | RGBQUAD *color; | 
|  |  | 
|  | for(color = colormap, i = 0; i < numColors; color++, i++) { | 
|  | diff = (r - color->rgbRed) * (r - color->rgbRed) + | 
|  | (g - color->rgbGreen) * (g - color->rgbGreen) + | 
|  | (b - color->rgbBlue) * (b - color->rgbBlue); | 
|  | if(diff == 0) | 
|  | return i; | 
|  | if(best == -1 || diff < bestdiff) { | 
|  | best = i; | 
|  | bestdiff = diff; | 
|  | } | 
|  | } | 
|  | return best; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_SetImageBits_1_Line | 
|  | * | 
|  | * Handles a single line of 1 bit data. | 
|  | */ | 
|  | static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors, | 
|  | XImage *bmpImage, int h, const BYTE *bits) | 
|  | { | 
|  | BYTE pix, extra; | 
|  | DWORD i, x; | 
|  |  | 
|  | if((extra = (left & 7)) != 0) { | 
|  | left &= ~7; | 
|  | dstwidth += extra; | 
|  | } | 
|  |  | 
|  | bits += left >> 3; | 
|  |  | 
|  | /* FIXME: should avoid putting x<left pixels (minor speed issue) */ | 
|  | for (i = dstwidth/8, x = left; i > 0; i--) | 
|  | { | 
|  | pix = *bits++; | 
|  | XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); | 
|  | XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] ); | 
|  | XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] ); | 
|  | XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] ); | 
|  | XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] ); | 
|  | XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] ); | 
|  | XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] ); | 
|  | XPutPixel( bmpImage, x++, h, colors[pix & 1] ); | 
|  | } | 
|  | pix = *bits; | 
|  | switch(dstwidth & 7) | 
|  | { | 
|  | case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1; | 
|  | case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1; | 
|  | case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1; | 
|  | case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1; | 
|  | case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1; | 
|  | case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1; | 
|  | case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_SetImageBits_1 | 
|  | * | 
|  | * SetDIBits for a 1-bit deep DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits, | 
|  | DWORD srcwidth, DWORD dstwidth, int left, | 
|  | int *colors, XImage *bmpImage, DWORD linebytes) | 
|  | { | 
|  | int h; | 
|  |  | 
|  | if (lines > 0) { | 
|  | for (h = lines-1; h >=0; h--) { | 
|  | X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h, | 
|  | srcbits); | 
|  | srcbits += linebytes; | 
|  | } | 
|  | } else { | 
|  | lines = -lines; | 
|  | for (h = 0; h < lines; h++) { | 
|  | X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h, | 
|  | srcbits); | 
|  | srcbits += linebytes; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_GetImageBits_1 | 
|  | * | 
|  | * GetDIBits for a 1-bit deep DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits, | 
|  | DWORD dstwidth, DWORD srcwidth, | 
|  | RGBQUAD *colors, PALETTEENTRY *srccolors, | 
|  | XImage *bmpImage, DWORD linebytes ) | 
|  | { | 
|  | DWORD x; | 
|  | int h; | 
|  | BYTE *bits; | 
|  |  | 
|  | if (lines < 0 ) { | 
|  | lines = -lines; | 
|  | dstbits = dstbits + linebytes * (lines - 1); | 
|  | linebytes = -linebytes; | 
|  | } | 
|  |  | 
|  | bits = dstbits; | 
|  |  | 
|  | switch(bmpImage->depth) { | 
|  |  | 
|  | case 1: | 
|  | /* ==== monochrome bitmap to monochrome dib ==== */ | 
|  | case 4: | 
|  | /* ==== 4 colormap bitmap to monochrome dib ==== */ | 
|  | if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) | 
|  | { | 
|  | PALETTEENTRY val; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  | val = srccolors[XGetPixel(bmpImage, x, h)]; | 
|  | if (!(x&7)) *bits = 0; | 
|  | *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, | 
|  | val.peRed, | 
|  | val.peGreen, | 
|  | val.peBlue) << (7 - (x & 7))); | 
|  | if ((x&7)==7) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 8: | 
|  | /* ==== 8 colormap bitmap to monochrome dib ==== */ | 
|  | if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) | 
|  | { | 
|  | BYTE *srcpixel; | 
|  | PALETTEENTRY val; | 
|  |  | 
|  | for( h = lines- 1; h >= 0; h-- ) { | 
|  | srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++ ) { | 
|  | if (!(x&7)) *bits = 0; | 
|  | val = srccolors[(int)*srcpixel++]; | 
|  | *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 2, | 
|  | val.peRed, | 
|  | val.peGreen, | 
|  | val.peBlue) << (7-(x&7)) ); | 
|  | if ((x&7)==7) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 15: | 
|  | { | 
|  | LPWORD srcpixel; | 
|  | WORD val; | 
|  |  | 
|  | /* ==== 555 BGR bitmap to monochrome dib ==== */ | 
|  | if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f) | 
|  | { | 
|  | for( h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++) { | 
|  | if (!(x&7)) *bits = 0; | 
|  | val = *srcpixel++; | 
|  | *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2, | 
|  | ((val >> 7) & 0xf8) | | 
|  | ((val >> 12) & 0x7), | 
|  | ((val >> 2) & 0xf8) | | 
|  | ((val >> 7) & 0x3), | 
|  | ((val << 3) & 0xf8) | | 
|  | ((val >> 2) & 0x7) ) << (7-(x&7)) ); | 
|  | if ((x&7)==7) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 555 RGB bitmap to monochrome dib ==== */ | 
|  | else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800) | 
|  | { | 
|  | for( h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++) { | 
|  | if (!(x&1)) *bits = 0; | 
|  | val = *srcpixel++; | 
|  | *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2, | 
|  | ((val << 3) & 0xf8) | | 
|  | ((val >> 2) & 0x7), | 
|  | ((val >> 2) & 0xf8) | | 
|  | ((val >> 7) & 0x3), | 
|  | ((val >> 7) & 0xf8) | | 
|  | ((val >> 12) &  0x7) ) << (7-(x&7)) ); | 
|  | if ((x&7)==7) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 16: | 
|  | { | 
|  | LPWORD srcpixel; | 
|  | WORD val; | 
|  |  | 
|  | /* ==== 565 BGR bitmap to monochrome dib ==== */ | 
|  | if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f) | 
|  | { | 
|  | for( h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++) { | 
|  | if (!(x&7)) *bits = 0; | 
|  | val = *srcpixel++; | 
|  | *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2, | 
|  | ((val >> 8) & 0xf8) | | 
|  | ((val >> 13) & 0x7), | 
|  | ((val >> 3) & 0xfc) | | 
|  | ((val >> 9) & 0x3), | 
|  | ((val << 3) & 0xf8) | | 
|  | ((val >> 2) & 0x7) ) << (7-(x&7)) ); | 
|  | if ((x&7)==7) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 565 RGB bitmap to monochrome dib ==== */ | 
|  | else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800) | 
|  | { | 
|  | for( h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++) { | 
|  | if (!(x&7)) *bits = 0; | 
|  | val = *srcpixel++; | 
|  | *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2, | 
|  | ((val << 3) & 0xf8) | | 
|  | ((val >> 2) & 0x7), | 
|  | ((val >> 3) & 0xfc) | | 
|  | ((val >> 9) & 0x3), | 
|  | ((val >> 8) & 0xf8) | | 
|  | ((val >> 13) &  0x7) ) << (7-(x&7)) ); | 
|  | if ((x&7)==7) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 24: | 
|  | case 32: | 
|  | { | 
|  | BYTE *srcpixel; | 
|  |  | 
|  | /* ==== 24/32 BGR bitmap to monochrome dib ==== */ | 
|  | if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = bmpImage->data + h*bmpImage->bytes_per_line; | 
|  | for (x = 0; x < dstwidth; x++, srcpixel+=4) { | 
|  | if (!(x&7)) *bits = 0; | 
|  | *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[2] , srcpixel[1], srcpixel[0]) << (7-(x&7)) ); | 
|  | if ((x&7)==7) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 24/32 RGB bitmap to monochrome dib ==== */ | 
|  | else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = bmpImage->data + h*bmpImage->bytes_per_line; | 
|  | for (x = 0; x < dstwidth; x++, srcpixel+=4) { | 
|  | if (!(x & 7)) *bits = 0; | 
|  | *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[0] , srcpixel[1], srcpixel[2]) << (7-(x&7)) ); | 
|  | if ((x & 7) == 7) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | default: /* ? bit bmp -> monochrome DIB */ | 
|  | notsupported: | 
|  | { | 
|  | unsigned long white = (1 << bmpImage->bits_per_pixel) - 1; | 
|  |  | 
|  | FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n", | 
|  | bmpImage->bits_per_pixel, (int)bmpImage->red_mask, | 
|  | (int)bmpImage->green_mask, (int)bmpImage->blue_mask ); | 
|  |  | 
|  | for( h = lines - 1; h >= 0; h-- ) { | 
|  | for( x = 0; x < dstwidth; x++ ) { | 
|  | if (!(x&7)) *bits = 0; | 
|  | *bits |= (XGetPixel( bmpImage, x, h) >= white) | 
|  | << (7 - (x&7)); | 
|  | if ((x&7)==7) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_SetImageBits_4 | 
|  | * | 
|  | * SetDIBits for a 4-bit deep DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits, | 
|  | DWORD srcwidth, DWORD dstwidth, int left, | 
|  | int *colors, XImage *bmpImage, DWORD linebytes) | 
|  | { | 
|  | DWORD i, x; | 
|  | int h; | 
|  | const BYTE *bits = srcbits + (left >> 1); | 
|  |  | 
|  | if(left & 1) { | 
|  | left--; | 
|  | dstwidth++; | 
|  | } | 
|  |  | 
|  | if (lines > 0) { | 
|  | for (h = lines-1; h >= 0; h--) { | 
|  | for (i = dstwidth/2, x = left; i > 0; i--) { | 
|  | BYTE pix = *bits++; | 
|  | XPutPixel( bmpImage, x++, h, colors[pix >> 4] ); | 
|  | XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] ); | 
|  | } | 
|  | if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] ); | 
|  | srcbits += linebytes; | 
|  | bits	 = srcbits + (left >> 1); | 
|  | } | 
|  | } else { | 
|  | lines = -lines; | 
|  | for (h = 0; h < lines; h++) { | 
|  | for (i = dstwidth/2, x = left; i > 0; i--) { | 
|  | BYTE pix = *bits++; | 
|  | XPutPixel( bmpImage, x++, h, colors[pix >> 4] ); | 
|  | XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] ); | 
|  | } | 
|  | if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] ); | 
|  | srcbits += linebytes; | 
|  | bits	 = srcbits + (left >> 1); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_GetImageBits_4 | 
|  | * | 
|  | * GetDIBits for a 4-bit deep DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits, | 
|  | DWORD srcwidth, DWORD dstwidth, | 
|  | RGBQUAD *colors, PALETTEENTRY *srccolors, | 
|  | XImage *bmpImage, DWORD linebytes ) | 
|  | { | 
|  | DWORD x; | 
|  | int h; | 
|  | BYTE *bits; | 
|  | LPBYTE srcpixel; | 
|  |  | 
|  | if (lines < 0 ) | 
|  | { | 
|  | lines = -lines; | 
|  | dstbits = dstbits + ( linebytes * (lines-1) ); | 
|  | linebytes = -linebytes; | 
|  | } | 
|  |  | 
|  | bits = dstbits; | 
|  |  | 
|  | switch(bmpImage->depth) { | 
|  |  | 
|  | case 1: | 
|  | /* ==== monochrome bitmap to 4 colormap dib ==== */ | 
|  | case 4: | 
|  | /* ==== 4 colormap bitmap to 4 colormap dib ==== */ | 
|  | if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) | 
|  | { | 
|  | PALETTEENTRY val; | 
|  |  | 
|  | for (h = lines-1; h >= 0; h--) { | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  | if (!(x&1)) *bits = 0; | 
|  | val = srccolors[XGetPixel(bmpImage, x, h)]; | 
|  | *bits |= (X11DRV_DIB_GetNearestIndex(colors, 16, | 
|  | val.peRed, | 
|  | val.peGreen, | 
|  | val.peBlue) << (4-((x&1)<<2))); | 
|  | if ((x&1)==1) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 8: | 
|  | /* ==== 8 colormap bitmap to 4 colormap dib ==== */ | 
|  | if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) | 
|  | { | 
|  | PALETTEENTRY val; | 
|  |  | 
|  | for( h = lines - 1; h >= 0; h-- ) { | 
|  | srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++ ) { | 
|  | if (!(x&1)) *bits = 0; | 
|  | val = srccolors[(int)*srcpixel++]; | 
|  | *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 16, | 
|  | val.peRed, | 
|  | val.peGreen, | 
|  | val.peBlue) << (4*(1-(x&1))) ); | 
|  | if ((x&1)==1) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 15: | 
|  | { | 
|  | LPWORD srcpixel; | 
|  | WORD val; | 
|  |  | 
|  | /* ==== 555 BGR bitmap to 4 colormap dib ==== */ | 
|  | if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f) | 
|  | { | 
|  | for( h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++) { | 
|  | if (!(x&1)) *bits = 0; | 
|  | val = *srcpixel++; | 
|  | *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16, | 
|  | ((val >> 7) & 0xf8) | | 
|  | ((val >> 12) & 0x7), | 
|  | ((val >> 2) & 0xf8) | | 
|  | ((val >> 7) & 0x3), | 
|  | ((val << 3) & 0xf8) | | 
|  | ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) ); | 
|  | if ((x&1)==1) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 555 RGB bitmap to 4 colormap dib ==== */ | 
|  | else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00) | 
|  | { | 
|  | for( h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++) { | 
|  | if (!(x&1)) *bits = 0; | 
|  | val = *srcpixel++; | 
|  | *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16, | 
|  | ((val << 3) & 0xf8) | | 
|  | ((val >> 2) & 0x7), | 
|  | ((val >> 2) & 0xfc) | | 
|  | ((val >> 7) & 0x3), | 
|  | ((val >> 7) & 0xf8) | | 
|  | ((val >> 12) &  0x7) ) << ((1-(x&1))<<2) ); | 
|  | if ((x&1)==1) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 16: | 
|  | { | 
|  | LPWORD srcpixel; | 
|  | WORD val; | 
|  |  | 
|  | /* ==== 565 BGR bitmap to 4 colormap dib ==== */ | 
|  | if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f) | 
|  | { | 
|  | for( h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++) { | 
|  | if (!(x&1)) *bits = 0; | 
|  | val = *srcpixel++; | 
|  | *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16, | 
|  | ((val >> 8) & 0xf8) | | 
|  | ((val >> 13) & 0x7), | 
|  | ((val >> 3) & 0xfc) | | 
|  | ((val >> 9) & 0x3), | 
|  | ((val << 3) & 0xf8) | | 
|  | ((val >> 2) & 0x7) )  << ((1-(x&1))<<2) ); | 
|  | if ((x&1)==1) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 565 RGB bitmap to 4 colormap dib ==== */ | 
|  | else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800) | 
|  | { | 
|  | for( h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++) { | 
|  | if (!(x&1)) *bits = 0; | 
|  | val = *srcpixel++; | 
|  | *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16, | 
|  | ((val << 3) & 0xf8) | | 
|  | ((val >> 2) & 0x7), | 
|  | ((val >> 3) & 0xfc) | | 
|  | ((val >> 9) & 0x3), | 
|  | ((val >> 8) & 0xf8) | | 
|  | ((val >> 13) &  0x7) ) << ((1-(x&1))<<2) ); | 
|  | if ((x&1)==1) bits++; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 24: | 
|  | case 32: | 
|  | { | 
|  | BYTE *srcpixel; | 
|  |  | 
|  | /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */ | 
|  | if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = bmpImage->data + h*bmpImage->bytes_per_line; | 
|  | for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */ | 
|  | *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[2] , srcpixel[1], srcpixel[0]) << 4) | | 
|  | X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[6] , srcpixel[5], srcpixel[4]); | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */ | 
|  | else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = bmpImage->data + h*bmpImage->bytes_per_line; | 
|  | for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */ | 
|  | *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[0] , srcpixel[1], srcpixel[2]) << 4) | | 
|  | X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[4] , srcpixel[5], srcpixel[6]); | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | default: /* ? bit bmp -> 4 bit DIB */ | 
|  | notsupported: | 
|  | FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n", | 
|  | bmpImage->bits_per_pixel, (int)bmpImage->red_mask, | 
|  | (int)bmpImage->green_mask, (int)bmpImage->blue_mask ); | 
|  | for (h = lines-1; h >= 0; h--) { | 
|  | for (x = 0; x < dstwidth-1; x += 2) | 
|  | { | 
|  | *bits++ = (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x, h ), 0) << 4) | 
|  | | (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x+1, h ), 0) & 0x0f); | 
|  | } | 
|  | if (dstwidth & 1) | 
|  | *bits = (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x, h ), 0) << 4); | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_SetImageBits_RLE4 | 
|  | * | 
|  | * SetDIBits for a 4-bit deep compressed DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits, | 
|  | DWORD width, DWORD dstwidth, | 
|  | int left, int *colors, | 
|  | XImage *bmpImage ) | 
|  | { | 
|  | int x = 0, c, length; | 
|  | const BYTE *begin = bits; | 
|  |  | 
|  | lines--; | 
|  |  | 
|  | while ((int)lines >= 0) { | 
|  | length = *bits++; | 
|  | if (length) {	/* encoded */ | 
|  | c = *bits++; | 
|  | while (length--) { | 
|  | if(x >= width) { | 
|  | x = 0; | 
|  | if(--lines < 0) | 
|  | return; | 
|  | } | 
|  | XPutPixel(bmpImage, x++, lines, colors[c >>4]); | 
|  | if (length) { | 
|  | length--; | 
|  | if(x >= width) { | 
|  | x = 0; | 
|  | if(--lines < 0) | 
|  | return; | 
|  | } | 
|  | XPutPixel(bmpImage, x++, lines, colors[c & 0xf]); | 
|  | } | 
|  | } | 
|  | } else { | 
|  | length = *bits++; | 
|  | switch (length) { | 
|  | case 0: /* eol */ | 
|  | x = 0; | 
|  | lines--; | 
|  | continue; | 
|  |  | 
|  | case 1: /* eopicture */ | 
|  | return; | 
|  |  | 
|  | case 2: /* delta */ | 
|  | x += *bits++; | 
|  | if(x >= width) { | 
|  | FIXME_(x11drv)("x-delta is too large?\n"); | 
|  | return; | 
|  | } | 
|  | lines -= *bits++; | 
|  | continue; | 
|  |  | 
|  | default: /* absolute */ | 
|  | while (length--) { | 
|  | c = *bits++; | 
|  | if(x >= width) { | 
|  | x = 0; | 
|  | if(--lines < 0) | 
|  | return; | 
|  | } | 
|  | XPutPixel(bmpImage, x++, lines, colors[c >> 4]); | 
|  | if (length) { | 
|  | length--; | 
|  | if(x >= width) { | 
|  | x = 0; | 
|  | if(--lines < 0) | 
|  | return; | 
|  | } | 
|  | XPutPixel(bmpImage, x++, lines, colors[c & 0xf]); | 
|  | } | 
|  | } | 
|  | if ((bits - begin) & 1) | 
|  | bits++; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_SetImageBits_8 | 
|  | * | 
|  | * SetDIBits for an 8-bit deep DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits, | 
|  | DWORD srcwidth, DWORD dstwidth, int left, | 
|  | const int *colors, XImage *bmpImage, | 
|  | DWORD linebytes ) | 
|  | { | 
|  | DWORD x; | 
|  | int h, color; | 
|  | const BYTE *bits; | 
|  |  | 
|  | dstwidth += left; | 
|  |  | 
|  | if (lines < 0 ) | 
|  | { | 
|  | lines = -lines; | 
|  | srcbits = srcbits + ( linebytes * (lines-1) ); | 
|  | linebytes = -linebytes; | 
|  | } | 
|  |  | 
|  | bits = srcbits + left; | 
|  |  | 
|  | switch (bmpImage->depth) { | 
|  | case 15: | 
|  | case 16: | 
|  | #if defined(__i386__) && defined(__GNUC__) | 
|  | /* Some X servers might have 32 bit/ 16bit deep pixel */ | 
|  | if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 16)) | 
|  | { | 
|  | for (h = lines ; h--; ) { | 
|  | int _cl1,_cl2; /* temp outputs for asm below */ | 
|  | /* Borrowed from DirectDraw */ | 
|  | __asm__ __volatile__( | 
|  | "xor %%eax,%%eax\n" | 
|  | "cld\n" | 
|  | "1:\n" | 
|  | "    lodsb\n" | 
|  | "    movw (%%edx,%%eax,4),%%ax\n" | 
|  | "    stosw\n" | 
|  | "      xor %%eax,%%eax\n" | 
|  | "    loop 1b\n" | 
|  | :"=S" (bits), "=D" (_cl1), "=c" (_cl2) | 
|  | :"S" (bits), | 
|  | "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*2), | 
|  | "c" (dstwidth-left), | 
|  | "d" (colors) | 
|  | :"eax", "cc", "memory" | 
|  | ); | 
|  | bits = (srcbits += linebytes) + left; | 
|  | } | 
|  | return; | 
|  | } | 
|  | break; | 
|  | #endif | 
|  | case 24: | 
|  | #if defined(__i386__) && defined(__GNUC__) | 
|  | if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 32)) | 
|  | { | 
|  | for (h = lines ; h--; ) { | 
|  | int _cl1,_cl2; /* temp outputs for asm below */ | 
|  | /* Borrowed from DirectDraw */ | 
|  | __asm__ __volatile__( | 
|  | "xor %%eax,%%eax\n" | 
|  | "cld\n" | 
|  | "1:\n" | 
|  | "    lodsb\n" | 
|  | "    movl (%%edx,%%eax,4),%%eax\n" | 
|  | "    stosl\n" | 
|  | "      xor %%eax,%%eax\n" | 
|  | "    loop 1b\n" | 
|  | :"=S" (bits), "=D" (_cl1), "=c" (_cl2) | 
|  | :"S" (bits), | 
|  | "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*4), | 
|  | "c" (dstwidth-left), | 
|  | "d" (colors) | 
|  | :"eax", "cc", "memory" | 
|  | ); | 
|  | bits = (srcbits += linebytes) + left; | 
|  | } | 
|  | return; | 
|  | } | 
|  | break; | 
|  | #endif | 
|  | default: | 
|  | break; /* use slow generic case below */ | 
|  | } | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | for (x = left; x < dstwidth; x++, bits++) { | 
|  | color = colors[*bits]; | 
|  | XPutPixel( bmpImage, x, h, colors[*bits] ); | 
|  | } | 
|  | bits = (srcbits += linebytes) + left; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_GetImageBits_8 | 
|  | * | 
|  | * GetDIBits for an 8-bit deep DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits, | 
|  | DWORD srcwidth, DWORD dstwidth, | 
|  | RGBQUAD *colors, PALETTEENTRY *srccolors, | 
|  | XImage *bmpImage, DWORD linebytes ) | 
|  | { | 
|  | DWORD x; | 
|  | int h; | 
|  | BYTE *bits; | 
|  |  | 
|  | if (lines < 0 ) | 
|  | { | 
|  | lines = -lines; | 
|  | dstbits = dstbits + ( linebytes * (lines-1) ); | 
|  | linebytes = -linebytes; | 
|  | } | 
|  |  | 
|  | bits = dstbits; | 
|  |  | 
|  | /* | 
|  | Hack for now | 
|  | This condition is true when GetImageBits has been called by UpdateDIBSection. | 
|  | For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for | 
|  | for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too) | 
|  | */ | 
|  | if (!srccolors) goto updatesection; | 
|  |  | 
|  | switch(bmpImage->depth) { | 
|  |  | 
|  | case 1: | 
|  | /* ==== monochrome bitmap to 8 colormap dib ==== */ | 
|  | case 4: | 
|  | /* ==== 4 colormap bitmap to 8 colormap dib ==== */ | 
|  | if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) | 
|  | { | 
|  | PALETTEENTRY val; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  | val = srccolors[XGetPixel(bmpImage, x, h)]; | 
|  | *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed, | 
|  | val.peGreen, val.peBlue); | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 8: | 
|  | /* ==== 8 colormap bitmap to 8 colormap dib ==== */ | 
|  | if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) | 
|  | { | 
|  | BYTE *srcpixel; | 
|  | PALETTEENTRY val; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = bmpImage->data + h*bmpImage->bytes_per_line; | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  | val = srccolors[(int)*srcpixel++]; | 
|  | *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed, | 
|  | val.peGreen, val.peBlue); | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 15: | 
|  | { | 
|  | LPWORD srcpixel; | 
|  | WORD val; | 
|  |  | 
|  | /* ==== 555 BGR bitmap to 8 colormap dib ==== */ | 
|  | if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f) | 
|  | { | 
|  | for( h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++ ) | 
|  | { | 
|  | val = *srcpixel++; | 
|  | *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256, | 
|  | ((val >> 7) & 0xf8) | | 
|  | ((val >> 12) & 0x7), | 
|  | ((val >> 2) & 0xf8) | | 
|  | ((val >> 7) & 0x3), | 
|  | ((val << 3) & 0xf8) | | 
|  | ((val >> 2) & 0x7) ); | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 555 RGB bitmap to 8 colormap dib ==== */ | 
|  | else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00) | 
|  | { | 
|  | for( h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++ ) | 
|  | { | 
|  | val = *srcpixel++; | 
|  | *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256, | 
|  | ((val << 3) & 0xf8) | | 
|  | ((val >> 2) & 0x7), | 
|  | ((val >> 2) & 0xf8) | | 
|  | ((val >> 7) & 0x3), | 
|  | ((val >> 7) & 0xf8) | | 
|  | ((val >> 12) &  0x7) ); | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 16: | 
|  | { | 
|  | LPWORD srcpixel; | 
|  | WORD val; | 
|  |  | 
|  | /* ==== 565 BGR bitmap to 8 colormap dib ==== */ | 
|  | if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f) | 
|  | { | 
|  | for( h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++ ) | 
|  | { | 
|  | val = *srcpixel++; | 
|  | *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256, | 
|  | ((val >> 8) & 0xf8) | | 
|  | ((val >> 13) & 0x7), | 
|  | ((val >> 3) & 0xfc) | | 
|  | ((val >> 9) & 0x3), | 
|  | ((val << 3) & 0xf8) | | 
|  | ((val >> 2) & 0x7) ); | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 565 RGB bitmap to 8 colormap dib ==== */ | 
|  | else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800) | 
|  | { | 
|  | for( h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line); | 
|  | for( x = 0; x < dstwidth; x++ ) | 
|  | { | 
|  | val = *srcpixel++; | 
|  | *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256, | 
|  | ((val << 3) & 0xf8) | | 
|  | ((val >> 2) & 0x7), | 
|  | ((val >> 3) & 0x00fc) | | 
|  | ((val >> 9) & 0x3), | 
|  | ((val >> 8) & 0x00f8) | | 
|  | ((val >> 13) &  0x7) ); | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 24: | 
|  | case 32: | 
|  | { | 
|  | BYTE *srcpixel; | 
|  |  | 
|  | /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */ | 
|  | if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = bmpImage->data + h*bmpImage->bytes_per_line; | 
|  | for (x = 0; x < dstwidth; x++, srcpixel+=4) | 
|  | *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, | 
|  | srcpixel[2] , srcpixel[1], *srcpixel); | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */ | 
|  | else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = bmpImage->data + h*bmpImage->bytes_per_line; | 
|  | for (x = 0; x < dstwidth; x++, srcpixel+=4) | 
|  | *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, | 
|  | *srcpixel, srcpixel[1], srcpixel[2]); | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  |  | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | default: /* ? bit bmp -> 8 bit DIB */ | 
|  | notsupported: | 
|  | FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n", | 
|  | bmpImage->depth, (int)bmpImage->red_mask, | 
|  | (int)bmpImage->green_mask, (int)bmpImage->blue_mask ); | 
|  | updatesection: | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | for (x = 0; x < dstwidth; x++, bits++) { | 
|  | *bits = X11DRV_DIB_MapColor((int *)colors, 256, | 
|  | XGetPixel( bmpImage, x, h ), *bits); | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *	      X11DRV_DIB_SetImageBits_RLE8 | 
|  | * | 
|  | * SetDIBits for an 8-bit deep compressed DIB. | 
|  | * | 
|  | * This function rewritten 941113 by James Youngman.  WINE blew out when I | 
|  | * first ran it because my desktop wallpaper is a (large) RLE8 bitmap. | 
|  | * | 
|  | * This was because the algorithm assumed that all RLE8 bitmaps end with the | 
|  | * 'End of bitmap' escape code.  This code is very much laxer in what it | 
|  | * allows to end the expansion.  Possibly too lax.  See the note by | 
|  | * case RleDelta.  BTW, MS's documentation implies that a correct RLE8 | 
|  | * bitmap should end with RleEnd, but on the other hand, software exists | 
|  | * that produces ones that don't and Windows 3.1 doesn't complain a bit | 
|  | * about it. | 
|  | * | 
|  | * (No) apologies for my English spelling.  [Emacs users: c-indent-level=4]. | 
|  | *			James A. Youngman <mbcstjy@afs.man.ac.uk> | 
|  | *						[JAY] | 
|  | */ | 
|  |  | 
|  | enum Rle8_EscapeCodes | 
|  | { | 
|  | /* | 
|  | * Apologies for polluting your file's namespace... | 
|  | */ | 
|  | RleEol 	= 0,		/* End of line */ | 
|  | RleEnd 	= 1,		/* End of bitmap */ | 
|  | RleDelta	= 2		/* Delta */ | 
|  | }; | 
|  |  | 
|  | static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits, | 
|  | DWORD width, DWORD dstwidth, | 
|  | int left, int *colors, | 
|  | XImage *bmpImage ) | 
|  | { | 
|  | int x;			/* X-positon on each line.  Increases. */ | 
|  | int line;			/* Line #.  Starts at lines-1, decreases */ | 
|  | const BYTE *pIn = bits;     /* Pointer to current position in bits */ | 
|  | BYTE length;		/* The length pf a run */ | 
|  | BYTE color_index;		/* index into colors[] as read from bits */ | 
|  | BYTE escape_code;		/* See enum Rle8_EscapeCodes.*/ | 
|  | int color;			/* value of colour[color_index] */ | 
|  |  | 
|  | if (lines == 0)		/* Let's hope this doesn't happen. */ | 
|  | return; | 
|  |  | 
|  | /* | 
|  | * Note that the bitmap data is stored by Windows starting at the | 
|  | * bottom line of the bitmap and going upwards.  Within each line, | 
|  | * the data is stored left-to-right.  That's the reason why line | 
|  | * goes from lines-1 to 0.			[JAY] | 
|  | */ | 
|  |  | 
|  | x = 0; | 
|  | line = lines-1; | 
|  | do | 
|  | { | 
|  | length = *pIn++; | 
|  |  | 
|  | /* | 
|  | * If the length byte is not zero (which is the escape value), | 
|  | * We have a run of length pixels all the same colour.  The colour | 
|  | * index is stored next. | 
|  | * | 
|  | * If the length byte is zero, we need to read the next byte to | 
|  | * know what to do.			[JAY] | 
|  | */ | 
|  | if (length != 0) | 
|  | { | 
|  | /* | 
|  | * [Run-Length] Encoded mode | 
|  | */ | 
|  | color_index = (*pIn++); /* Get the colour index. */ | 
|  | color = colors[color_index]; | 
|  |  | 
|  | while(length--) | 
|  | { | 
|  | if (x>=dstwidth) | 
|  | { | 
|  | x=0; | 
|  | line--; | 
|  | } | 
|  | XPutPixel(bmpImage, x++, line, color); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | /* | 
|  | * Escape codes (may be an absolute sequence though) | 
|  | */ | 
|  | escape_code = (*pIn++); | 
|  | switch(escape_code) | 
|  | { | 
|  | case RleEol: /* =0, end of line */ | 
|  | { | 
|  | x = 0; | 
|  | line--; | 
|  | break; | 
|  | } | 
|  |  | 
|  | case RleEnd: /* =1, end of bitmap */ | 
|  | { | 
|  | /* | 
|  | * Not all RLE8 bitmaps end with this | 
|  | * code.  For example, Paint Shop Pro | 
|  | * produces some that don't.  That's (I think) | 
|  | * what caused the previous implementation to | 
|  | * fail.			[JAY] | 
|  | */ | 
|  | line=-1; /* Cause exit from do loop. */ | 
|  | break; | 
|  | } | 
|  |  | 
|  | case RleDelta: /* =2, a delta */ | 
|  | { | 
|  | /* | 
|  | * Note that deltaing to line 0 | 
|  | * will cause an exit from the loop, | 
|  | * which may not be what is intended. | 
|  | * The fact that there is a delta in the bits | 
|  | * almost certainly implies that there is data | 
|  | * to follow.  You may feel that we should | 
|  | * jump to the top of the loop to avoid exiting | 
|  | * in this case. | 
|  | * | 
|  | * TODO: Decide what to do here in that case. [JAY] | 
|  | */ | 
|  | x 	+= (*pIn++); | 
|  | line 	-= (*pIn++); | 
|  | if (line == 0) | 
|  | { | 
|  | TRACE("Delta to last line of bitmap " | 
|  | "(wrongly?) causes loop exit\n"); | 
|  | } | 
|  | break; | 
|  | } | 
|  |  | 
|  | default:	/* >2, switch to absolute mode */ | 
|  | { | 
|  | /* | 
|  | * Absolute Mode | 
|  | */ | 
|  | length = escape_code; | 
|  | while(length--) | 
|  | { | 
|  | color_index = (*pIn++); | 
|  | if (x>=dstwidth) | 
|  | { | 
|  | x=0; | 
|  | line--; | 
|  | } | 
|  | XPutPixel(bmpImage, x++, line, | 
|  | colors[color_index]); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * If you think for a moment you'll realise that the | 
|  | * only time we could ever possibly read an odd | 
|  | * number of bytes is when there is a 0x00 (escape), | 
|  | * a value >0x02 (absolute mode) and then an odd- | 
|  | * length run.  Therefore this is the only place we | 
|  | * need to worry about it.  Everywhere else the | 
|  | * bytes are always read in pairs.  [JAY] | 
|  | */ | 
|  | if (escape_code & 1) | 
|  | pIn++; /* Throw away the pad byte. */ | 
|  | break; | 
|  | } | 
|  | } /* switch (escape_code) : Escape sequence */ | 
|  | }  /* process either an encoded sequence or an escape sequence */ | 
|  |  | 
|  | /* We expect to come here more than once per line. */ | 
|  | } while (line >= 0);  /* Do this until the bitmap is filled */ | 
|  |  | 
|  | /* | 
|  | * Everybody comes here at the end. | 
|  | * Check how we exited the loop and print a message if it's a bit odd. | 
|  | *						[JAY] | 
|  | */ | 
|  | if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) ) | 
|  | { | 
|  | TRACE("End-of-bitmap without (strictly) proper escape code.  Last two " | 
|  | "bytes were: %02X %02X.\n", (int)*(pIn-2),(int)*(pIn-1)); | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_SetImageBits_16 | 
|  | * | 
|  | * SetDIBits for a 16-bit deep DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits, | 
|  | DWORD srcwidth, DWORD dstwidth, int left, | 
|  | DC *dc, DWORD rSrc, DWORD gSrc, DWORD bSrc, | 
|  | XImage *bmpImage, DWORD linebytes ) | 
|  | { | 
|  | DWORD x; | 
|  | int h; | 
|  |  | 
|  | if (lines < 0 ) | 
|  | { | 
|  | lines = -lines; | 
|  | srcbits = srcbits + ( linebytes * (lines-1)); | 
|  | linebytes = -linebytes; | 
|  | } | 
|  |  | 
|  | switch ( bmpImage->depth ) | 
|  | { | 
|  | case 15: | 
|  | /* using same format as XImage */ | 
|  | if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask) | 
|  | for (h = lines - 1; h >= 0; h--, srcbits += linebytes) | 
|  | memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 ); | 
|  | else     /* We need to do a conversion from a 565 dib */ | 
|  | { | 
|  | LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2); | 
|  | DWORD val; | 
|  | int div = dstwidth % 2; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2); | 
|  | for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */ | 
|  | val = *ptr++; | 
|  | *dstpixel++ =   ((val >> 1) & 0x7fe07fe0) | (val & 0x001f001f); /* Red & Green & Blue */ | 
|  | } | 
|  | if (div != 0) /* Odd width? */ | 
|  | *dstpixel = ((*(WORD *)ptr >> 1) & 0x7fe0) | (*(WORD *)ptr & 0x001f); | 
|  | ptr = (LPDWORD) ((srcbits += linebytes) + left*2); | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 16: | 
|  | /* using same format as XImage */ | 
|  | if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask) | 
|  | for (h = lines - 1; h >= 0; h--, srcbits += linebytes) | 
|  | memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 ); | 
|  | else     /* We need to do a conversion from a 555 dib */ | 
|  | { | 
|  | LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2); | 
|  | DWORD val; | 
|  | int div = dstwidth % 2; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2); | 
|  | for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */ | 
|  | val = *ptr++; | 
|  | *dstpixel++ = ((val << 1) & 0xffc0ffc0) | ((val >> 4) & 0x00200020) | /* Red & Green */ | 
|  | (val & 0x001f001f);                             /* Blue */ | 
|  | } | 
|  | if (div != 0) /* Odd width? */ | 
|  | *dstpixel = ((*(WORD *)ptr << 1) & 0xffc0) | ((*(WORD *)ptr >> 4) & 0x0020) | 
|  | | (*(WORD *)ptr & 0x001f); | 
|  | ptr = (LPDWORD) ((srcbits += linebytes) + left*2); | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 24: | 
|  | case 32: | 
|  | { | 
|  | DWORD  *dstpixel; | 
|  | LPWORD ptr = (LPWORD)srcbits + left; | 
|  | DWORD val; | 
|  |  | 
|  | if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) | 
|  | { | 
|  | if ((rSrc == 0xF800) && (gSrc == 0x07E0) && (bSrc == 0x001F)) { | 
|  | /* ==== 555 RGB dib to 24/32 RGB bitmap ==== */ | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4); | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  | val = *ptr++; | 
|  | *dstpixel++ = ((val << 8) & 0xF80000) | /* Red */ | 
|  | ((val << 5) & 0x00FC00) | /* Green */ | 
|  | ((val << 3) & 0x0000FF);  /* Blue */ | 
|  | } | 
|  | ptr = (LPWORD)(srcbits += linebytes) + left; | 
|  | } | 
|  | } else { | 
|  | /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */ | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4); | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  |  | 
|  | val = *ptr++; | 
|  | *dstpixel++ = ((val << 9) & 0xf80000) | ((val << 4) & 0x070000) | /* Red */ | 
|  | ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */ | 
|  | ((val << 3) & 0x0000f8) | ((val >> 2) & 0x000007);      /* Blue */ | 
|  | } | 
|  | ptr = (LPWORD)(srcbits += linebytes) + left; | 
|  | } | 
|  | } | 
|  | } | 
|  | /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */ | 
|  | else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4); | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  |  | 
|  | val = *ptr++; | 
|  | *dstpixel++ = ((val >> 7) & 0x0000f8) | ((val >> 12) & 0x000007) | /* Red */ | 
|  | ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */ | 
|  | ((val << 19) & 0xf80000) | ((val >> 14) & 0x070000);      /* Blue */ | 
|  | } | 
|  | ptr = (LPWORD)(srcbits += linebytes) + left; | 
|  | } | 
|  | } | 
|  |  | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 1: | 
|  | case 4: | 
|  | case 8: | 
|  | { | 
|  | LPWORD ptr = (LPWORD)srcbits + left; | 
|  | WORD val; | 
|  | int sc1, sc2; | 
|  |  | 
|  | /* Set color scaling values */ | 
|  | if ( rSrc == 0x7c00 ) { sc1 = 7; sc2 = 2; }             /* 555 dib */ | 
|  | else { sc1 = 8; sc2 = 3; }                              /* 565 dib */ | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | for (x = left; x < dstwidth+left; x++) { | 
|  | val = *ptr++; | 
|  | XPutPixel( bmpImage, x, h, | 
|  | X11DRV_PALETTE_ToPhysical(dc, RGB(((val & rSrc) >> sc1),  /* Red */ | 
|  | ((val & gSrc) >> sc2),  /* Green */ | 
|  | ((val & bSrc) << 3)))); /* Blue */ | 
|  | } | 
|  | ptr = (LPWORD) (srcbits += linebytes) + left; | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | default: | 
|  | FIXME("16 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel); | 
|  | break; | 
|  |  | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_GetImageBits_16 | 
|  | * | 
|  | * GetDIBits for an 16-bit deep DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits, | 
|  | DWORD dstwidth, DWORD srcwidth, | 
|  | PALETTEENTRY *srccolors, | 
|  | DWORD rDst, DWORD gDst, DWORD bDst, | 
|  | XImage *bmpImage, DWORD dibpitch ) | 
|  | { | 
|  | DWORD x; | 
|  | int h, rsc, gsc; | 
|  |  | 
|  | DWORD linebytes = dibpitch; | 
|  |  | 
|  | if (lines < 0 ) | 
|  | { | 
|  | lines = -lines; | 
|  | dstbits = dstbits + ( linebytes * (lines-1)); | 
|  | linebytes = -linebytes; | 
|  | } | 
|  |  | 
|  | /* Set color scaling values */ | 
|  | if ( rDst == 0x7c00 ) { rsc = 7; gsc = 2; }             /* 555 dib */ | 
|  | else { rsc = 8; gsc = 3; }                              /* 565 dib */ | 
|  |  | 
|  | switch ( bmpImage->depth ) | 
|  | { | 
|  | case 15: | 
|  | /* using same format as XImage */ | 
|  | if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask) | 
|  | for (h = lines - 1; h >= 0; h--, dstbits += linebytes) | 
|  | memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 ); | 
|  | /* reversed format (BGR <=> RGB) */ | 
|  | else if (rDst == bmpImage->blue_mask && bDst == bmpImage->red_mask) | 
|  | { | 
|  | LPDWORD srcpixel, ptr = (LPDWORD)dstbits; | 
|  | DWORD val; | 
|  | int div = srcwidth % 2; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < srcwidth/2; x++) {  /* Do 2 pixels at a time */ | 
|  | val = *srcpixel++; | 
|  | *ptr++ = ((val << 10) & 0xf800f800) | (val & 0x03e003e0) |        /* Red & Green */ | 
|  | ((val >> 10) & 0x001f001f);                                     /* Blue */ | 
|  | } | 
|  | if (div != 0) /* Odd width? */ | 
|  | *ptr = ((*(WORD *)srcpixel << 1) & 0xffc0) | ((*(WORD *)srcpixel >> 4) & 0x0020) | | 
|  | (*(WORD *)srcpixel & 0x001f); | 
|  | ptr = (LPDWORD)(dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 16: | 
|  | { | 
|  | LPDWORD srcpixel, ptr = (LPDWORD)dstbits; | 
|  | DWORD val; | 
|  | int div = srcwidth % 2; | 
|  |  | 
|  | /* using same format as XImage */ | 
|  | if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask) | 
|  | for (h = lines - 1; h >= 0; h--, dstbits += linebytes) | 
|  | memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 ); | 
|  | /* ==== 565 BGR bitmap to 555 BGR dib ==== */ | 
|  | else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f && | 
|  | rDst == 0x7c00 && bDst == 0x001f) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < srcwidth/2; x++) {  /* Do 2 pixels at a time */ | 
|  | val = *srcpixel++; | 
|  | *ptr++ = ((val >> 1) & 0x7fe07fe0) |                    /* Red & Green */ | 
|  | (val & 0x001f001f);                                   /* Blue */ | 
|  | } | 
|  | if (div != 0) /* Odd width? */ | 
|  | *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f); | 
|  | ptr = (LPDWORD) (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 565 RGB bitmap to 555 BGR dib ==== */ | 
|  | else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800 && | 
|  | rDst == 0x7c00 && bDst == 0x001f) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < srcwidth/2; x++) {  /* Do 2 pixels at a time */ | 
|  | val = *srcpixel++; | 
|  | *ptr++ = ((val << 10) & 0x7c007c00) | ((val >> 1) & 0x03e003e0) |   /* Red & Green */ | 
|  | ((val >> 11) & 0x001f001f);                                       /* Blue */ | 
|  | } | 
|  | if (div != 0) /* Odd width? */ | 
|  | *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f); | 
|  | ptr = (LPDWORD) (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 24: | 
|  | case 32: | 
|  | { | 
|  | DWORD  *srcpixel; | 
|  | LPWORD ptr = (LPWORD)dstbits; | 
|  | DWORD val; | 
|  |  | 
|  | /* ==== 24/32 BGR bitmap ==== */ | 
|  | if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) | 
|  | { | 
|  | int rsc2 = 16-rsc, gsc2 = 8-gsc; | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < srcwidth; x++, ptr++) { | 
|  | val = *srcpixel++; | 
|  | *ptr = ((val >> rsc2) & rDst) | | 
|  | ((val >> gsc2) & gDst) | | 
|  | ((val >> 3) & bDst); | 
|  | } | 
|  | ptr = (LPWORD)(dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 24/32 RGB bitmap ==== */ | 
|  | else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000) | 
|  | { | 
|  | int gsc2 = 8-gsc; | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < srcwidth; x++, ptr++) { | 
|  | val = *srcpixel++; | 
|  | *ptr = ((val << rsc) & rDst) | | 
|  | ((val >> gsc2) & gDst) | | 
|  | ((val >> 19) & bDst); | 
|  | } | 
|  | ptr = (LPWORD) (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 1: | 
|  | /* ==== monochrome bitmap ==== */ | 
|  | case 4: | 
|  | /* ==== 4 colormap bitmap ==== */ | 
|  | if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) | 
|  | { | 
|  | LPWORD ptr = (LPWORD)dstbits; | 
|  | PALETTEENTRY val; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  | val = srccolors[XGetPixel(bmpImage, x, h)]; | 
|  | *ptr++ = ((val.peRed << rsc) & rDst) | | 
|  | ((val.peGreen << gsc) & gDst) | | 
|  | ((val.peBlue >> 3) & bDst); | 
|  | } | 
|  | ptr = (LPWORD)(dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 8: | 
|  | /* ==== 8 colormap bitmap ==== */ | 
|  | if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) | 
|  | { | 
|  | LPWORD ptr = (LPWORD)dstbits; | 
|  | BYTE *srcpixel; | 
|  | PALETTEENTRY val; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = bmpImage->data + h*bmpImage->bytes_per_line; | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  | val = srccolors[(int)*srcpixel++]; | 
|  | *ptr++ = ((val.peRed << rsc) & rDst) | | 
|  | ((val.peGreen << gsc) & gDst) | | 
|  | ((val.peBlue >> 3) & bDst); | 
|  | } | 
|  | ptr = (LPWORD)(dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | default: | 
|  | notsupported: | 
|  | { | 
|  | BYTE r,g, b; | 
|  | LPWORD ptr = (LPWORD)dstbits; | 
|  |  | 
|  | FIXME("from %d bit bitmap with mask R,G,B %lx,%lx,%lx to 16 bit DIB %lx,%lx,%lx\n", | 
|  | bmpImage->depth, bmpImage->red_mask, | 
|  | bmpImage->green_mask, bmpImage->blue_mask, | 
|  | rDst, gDst, bDst); | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | for (x = 0; x < dstwidth; x++, ptr++) | 
|  | { | 
|  | COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) ); | 
|  | r = (BYTE) GetRValue(pixel); | 
|  | g = (BYTE) GetGValue(pixel); | 
|  | b = (BYTE) GetBValue(pixel); | 
|  | *ptr = ( ((r << rsc) & rDst) | ((g << gsc) & gDst) | ((b >> 3) & bDst) ); | 
|  | } | 
|  | ptr = (LPWORD) (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_SetImageBits_24 | 
|  | * | 
|  | * SetDIBits for a 24-bit deep DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits, | 
|  | DWORD srcwidth, DWORD dstwidth, int left, | 
|  | DC *dc, XImage *bmpImage, DWORD linebytes ) | 
|  | { | 
|  | DWORD x; | 
|  | int h; | 
|  |  | 
|  | if (lines < 0 ) | 
|  | { | 
|  | lines = -lines; | 
|  | srcbits = srcbits + linebytes * (lines - 1); | 
|  | linebytes = -linebytes; | 
|  | } | 
|  |  | 
|  | switch ( bmpImage->depth ) | 
|  | { | 
|  | case 24: | 
|  | { | 
|  | if (bmpImage->bits_per_pixel == 24) { | 
|  | int dstlinebytes = linebytes; | 
|  | BYTE *dstpixel; | 
|  | BYTE *ptr = (BYTE *)(srcbits+left*3); | 
|  |  | 
|  | if (dstlinebytes < 0 ) dstlinebytes = -dstlinebytes; | 
|  | dstpixel = bmpImage->data + lines*dstlinebytes + left*3; | 
|  | for(h = lines ; h-- ; ) { | 
|  | dstpixel-=dstlinebytes; | 
|  | memcpy(dstpixel,ptr,dstwidth*3); | 
|  | ptr +=linebytes; | 
|  | } | 
|  | break; | 
|  | } | 
|  | } | 
|  | case 32: | 
|  | { | 
|  | if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 )  /* packed BGR to unpacked BGR */ | 
|  | { | 
|  | DWORD *dstpixel, val, buf; | 
|  | DWORD *ptr = (DWORD *)(srcbits + left*3); | 
|  | BYTE *bits; | 
|  | int div = dstwidth % 4; | 
|  | int divk; | 
|  |  | 
|  | for(h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4); | 
|  |  | 
|  | for (x = 0; x < dstwidth/4; x++) {   /* do 3 dwords source, 4 dwords dest at a time */ | 
|  | buf = *ptr++; | 
|  | *dstpixel++ = buf&0x00ffffff;                  /* b1, g1, r1 */ | 
|  | val = (buf >> 24);                             /* b2 */ | 
|  | buf = *ptr++; | 
|  | *dstpixel++ = (val | (buf<<8)) &0x00ffffff;    /* g2, r2 */ | 
|  | val = (buf >> 16);                             /* b3, g3 */ | 
|  | buf = *ptr++; | 
|  | *dstpixel++ = (val | (buf<<16)) &0x00ffffff;   /* r3 */ | 
|  | *dstpixel++ = (buf >> 8);                      /* b4, g4, r4 */ | 
|  | } | 
|  | for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */ | 
|  | { | 
|  | *dstpixel++ = *(DWORD*)bits & 0x00ffffff;      /* b, g, r */ | 
|  | } | 
|  | ptr = (DWORD*)((srcbits+=linebytes)+left*3); | 
|  | } | 
|  | } | 
|  | else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff )  /* packed BGR to unpacked RGB */ | 
|  | { | 
|  | DWORD *dstpixel, val, buf; | 
|  | DWORD *ptr = (DWORD *)(srcbits + left*3); | 
|  | BYTE *bits; | 
|  | int div = dstwidth % 4; | 
|  | int divk; | 
|  |  | 
|  | for(h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4); | 
|  |  | 
|  | for (x = 0; x < dstwidth/4; x++) {   /* do 3 dwords source, 4 dwords dest at a time */ | 
|  | buf = *ptr++; | 
|  | *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16);  /* b1, g1, r1 */ | 
|  | val = ((buf&0xff000000)>>8);                                           /* b2 */ | 
|  | buf = *ptr++; | 
|  | *dstpixel++ = val | ((buf&0xff)<<8) | ((buf&0xff00)>>8);               /* g2, r2 */ | 
|  | val = (buf&0xff0000) | ((buf&0xff000000)>>16);                         /* b3, g3 */ | 
|  | buf = *ptr++; | 
|  | *dstpixel++ = val | (buf&0xff);                                        /* r3 */ | 
|  | *dstpixel++ = ((buf&0xff00)<<8) | ((buf&0xff0000)>>8) | (buf>>24);     /* b4, g4, r4 */ | 
|  | } | 
|  | for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */ | 
|  | { | 
|  | buf = *(DWORD*)bits; | 
|  | *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16);  /* b, g, r */ | 
|  | } | 
|  | ptr = (DWORD*)((srcbits+=linebytes)+left*3); | 
|  | } | 
|  | } | 
|  | else | 
|  | goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 15: | 
|  | { | 
|  | if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f )   /* BGR888 to RGB555 */ | 
|  | { | 
|  | DWORD  *ptr = (DWORD *)(srcbits + left*3); | 
|  | LPBYTE bits; | 
|  | LPWORD dstpixel; | 
|  | int div = dstwidth % 4; | 
|  | int divk; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) {              /* Do 4 pixels at a time */ | 
|  | dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2); | 
|  | for (x = 0; x < dstwidth/4; x++, ptr += 3) { | 
|  | *dstpixel++ = ((ptr[0] << 7) & 0x7c00)  | ((ptr[0] >> 6) & 0x03e0)  | ((ptr[0] >> 19) & 0x1f); | 
|  | *dstpixel++ = ((ptr[0] >> 17) & 0x7c00) | ((ptr[1] << 2) & 0x03e0)  | ((ptr[1] >> 11) & 0x1f); | 
|  | *dstpixel++ = ((ptr[1] >> 9) & 0x07c00) | ((ptr[1] >> 22) & 0x03e0) | ((ptr[2] >> 3) & 0x1f); | 
|  | *dstpixel++ = ((ptr[2] >> 1) & 0x07c00) | ((ptr[2] >> 14) & 0x03e0) | ((ptr[2] >> 27) & 0x1f); | 
|  | } | 
|  | for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3)  /* dstwidth not divisible by 4? */ | 
|  | *dstpixel++ = (((WORD)bits[0] << 7) & 0x07c00) | | 
|  | (((WORD)bits[1] << 2) & 0x03e0) | | 
|  | (((WORD)bits[2] >> 3) & 0x001f); | 
|  | ptr = (DWORD *)((srcbits += linebytes) + left * 3); | 
|  | } | 
|  | } | 
|  | else if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 )   /* BGR888 to BGR555 */ | 
|  | { | 
|  | DWORD  *ptr = (DWORD *)(srcbits + left*3); | 
|  | LPBYTE bits; | 
|  | LPWORD dstpixel; | 
|  | int div = dstwidth % 4; | 
|  | int divk; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) {              /* Do 4 pixels at a time */ | 
|  | dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2); | 
|  | for (x = 0; x < dstwidth/4; x++, ptr += 3) { | 
|  | *dstpixel++ = ((ptr[0] >> 3) & 0x1f)  | ((ptr[0] >> 6) & 0x03e0)  | ((ptr[0] >> 9) & 0x7c00); | 
|  | *dstpixel++ = ((ptr[0] >> 27) & 0x1f) | ((ptr[1] << 2) & 0x03e0)  | ((ptr[1] >> 1) & 0x7c00); | 
|  | *dstpixel++ = ((ptr[1] >> 19) & 0x1f) | ((ptr[1] >> 22) & 0x03e0) | ((ptr[2] << 7) & 0x7c00); | 
|  | *dstpixel++ = ((ptr[2] >> 11) & 0x1f) | ((ptr[2] >> 14) & 0x03e0) | ((ptr[2] >> 17) & 0x7c00); | 
|  | } | 
|  | for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3)  /* dstwidth not divisible by 4? */ | 
|  | *dstpixel++ = (((WORD)bits[2] << 7) & 0x07c00) | | 
|  | (((WORD)bits[1] << 2) & 0x03e0) | | 
|  | (((WORD)bits[0] >> 3) & 0x001f); | 
|  | ptr = (DWORD *)((srcbits += linebytes) + left * 3); | 
|  | } | 
|  | } | 
|  | else | 
|  | goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 16: | 
|  | { | 
|  | DWORD  *ptr = (DWORD *)(srcbits + left*3); | 
|  | LPBYTE bits; | 
|  | LPWORD dstpixel; | 
|  | int div = dstwidth % 4; | 
|  | int divk; | 
|  |  | 
|  | if( bmpImage->blue_mask == 0x001f && bmpImage->red_mask == 0xf800 )    /* BGR888 to BGR565 */ | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) {              /* Do 4 pixels at a time */ | 
|  | dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2); | 
|  | for (x = 0; x < dstwidth/4; x++, ptr += 3) { | 
|  | *dstpixel++ = ((ptr[0] >> 3) & 0x1f)  | ((ptr[0] >> 5) & 0x07e0)  | ((ptr[0] >> 8) & 0xf800); | 
|  | *dstpixel++ = ((ptr[0] >> 27) & 0x1f) | ((ptr[1] << 3) & 0x07e0)  | (ptr[1] & 0xf800); | 
|  | *dstpixel++ = ((ptr[1] >> 19) & 0x1f) | ((ptr[1] >> 21) & 0x07e0) | ((ptr[2] << 8) & 0xf800); | 
|  | *dstpixel++ = ((ptr[2] >> 11) & 0x1f) | ((ptr[2] >> 13) & 0x07e0) | ((ptr[2] >> 16) & 0xf800); | 
|  | } | 
|  | for (   bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3)  /* dstwidth is not divisible by 4? */ | 
|  | *dstpixel++ = (((WORD)bits[2] << 8) & 0xf800) | | 
|  | (((WORD)bits[1] << 3) & 0x07e0) | | 
|  | (((WORD)bits[0] >> 3) & 0x001f); | 
|  | ptr = (DWORD *)((srcbits += linebytes) + left * 3); | 
|  | } | 
|  | } | 
|  | else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x001f ) /* BGR888 to RGB565 */ | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) {              /* Do 4 pixels at a time */ | 
|  | dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2); | 
|  | for (x = 0; x < dstwidth/4; x++, ptr += 3) { | 
|  | *dstpixel++ = ((ptr[0] << 8) & 0xf800)  | ((ptr[0] >> 5) & 0x07e0)  | ((ptr[0] >> 19) & 0x1f); | 
|  | *dstpixel++ = ((ptr[0] >> 16) & 0xf800) | ((ptr[1] << 3) & 0x07e0)  | ((ptr[1] >> 11) & 0x1f); | 
|  | *dstpixel++ = ((ptr[1] >> 8) & 0xf800)  | ((ptr[1] >> 21) & 0x07e0) | ((ptr[2] >> 3) & 0x1f); | 
|  | *dstpixel++ = (ptr[2] & 0xf800)         | ((ptr[2] >> 13) & 0x07e0) | ((ptr[2] >> 27) & 0x1f); | 
|  | } | 
|  | for (   bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3)  /* dstwidth is not divisible by 4? */ | 
|  | *dstpixel++ = (((WORD)bits[0] << 8) & 0xf800) | | 
|  | (((WORD)bits[1] << 3) & 0x07e0) | | 
|  | (((WORD)bits[2] >> 3) & 0x001f); | 
|  | ptr = (DWORD *)((srcbits += linebytes) + left * 3); | 
|  | } | 
|  | } | 
|  | else | 
|  | goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 1: | 
|  | case 4: | 
|  | case 8: | 
|  | { | 
|  | LPBYTE bits = (LPBYTE)srcbits + left*3; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | for (x = left; x < dstwidth+left; x++, bits+=3) | 
|  | XPutPixel( bmpImage, x, h, | 
|  | X11DRV_PALETTE_ToPhysical(dc, RGB(bits[2], bits[1], bits[0]))); | 
|  | bits = (LPBYTE)(srcbits += linebytes) + left * 3; | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | default: | 
|  | notsupported: | 
|  | FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n", | 
|  | bmpImage->bits_per_pixel, (int)bmpImage->red_mask, | 
|  | (int)bmpImage->green_mask, (int)bmpImage->blue_mask ); | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_GetImageBits_24 | 
|  | * | 
|  | * GetDIBits for an 24-bit deep DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits, | 
|  | DWORD dstwidth, DWORD srcwidth, | 
|  | PALETTEENTRY *srccolors, | 
|  | XImage *bmpImage, DWORD linebytes ) | 
|  | { | 
|  | DWORD x, val; | 
|  | int h; | 
|  |  | 
|  | if (lines < 0 ) | 
|  | { | 
|  | lines = -lines; | 
|  | dstbits = dstbits + ( linebytes * (lines-1) ); | 
|  | linebytes = -linebytes; | 
|  | } | 
|  |  | 
|  | switch ( bmpImage->depth ) | 
|  | { | 
|  | case 24: | 
|  | { | 
|  | if (bmpImage->bits_per_pixel == 24) { | 
|  | int tocopy = linebytes; | 
|  | BYTE *srcpixel; | 
|  | BYTE *ptr = (LPBYTE)dstbits; | 
|  |  | 
|  | if (tocopy < 0 ) tocopy = -tocopy; | 
|  | srcpixel = bmpImage->data + lines*tocopy; | 
|  | for(h = lines ; h-- ; ) { | 
|  | srcpixel-=tocopy; | 
|  | memcpy(ptr,srcpixel,tocopy); | 
|  | ptr = (LPBYTE)(dstbits+=linebytes); | 
|  | } | 
|  | break; | 
|  | } | 
|  | } | 
|  | case 32: | 
|  | { | 
|  | DWORD  *srcpixel, buf; | 
|  | LPBYTE bits; | 
|  | DWORD *ptr=(DWORD *)dstbits; | 
|  | int quotient = dstwidth / 4; | 
|  | int remainder = dstwidth % 4; | 
|  | int remk; | 
|  |  | 
|  | /* ==== 24/32 BGR bitmap to 24 BGR dib==== */ | 
|  | if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 ) | 
|  | { | 
|  | for(h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  |  | 
|  | for (x = 0; x < quotient; x++) {     /* do 4 dwords source, 3 dwords dest at a time */ | 
|  | buf = ((*srcpixel++)&0x00ffffff);      /* b1, g1, r1*/ | 
|  | *ptr++ = buf | ((*srcpixel)<<24);      /* b2 */ | 
|  | buf = ((*srcpixel++>>8)&0x0000ffff);   /* g2, r2 */ | 
|  | *ptr++ = buf | ((*srcpixel)<<16);      /* b3, g3 */ | 
|  | buf = ((*srcpixel++>>16)&0x000000ff);  /* r3 */ | 
|  | *ptr++ = buf | ((*srcpixel++)<<8);     /* b4, g4, r4 */ | 
|  | } | 
|  | for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */ | 
|  | { | 
|  | buf=*srcpixel++; | 
|  | *(WORD*)bits = buf;                    /* b, g */ | 
|  | *(bits+2) = buf>>16;                   /* r */ | 
|  | } | 
|  | ptr = (DWORD*)(dstbits+=linebytes); | 
|  | } | 
|  |  | 
|  | } | 
|  | /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */ | 
|  | else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff ) | 
|  | { | 
|  | for(h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  |  | 
|  | for (x = 0; x < quotient; x++) {     /* do 4 dwords source, 3 dwords dest at a time */ | 
|  | buf = *srcpixel++; | 
|  | val = ((buf&0xff0000)>>16) | (buf&0xff00) | ((buf&0xff)<<16);       /* b1, g1, r1 */ | 
|  | buf = *srcpixel++; | 
|  | *ptr++ = val | ((buf&0xff0000)<<8);                                 /* b2 */ | 
|  | val = ((buf&0xff00)>>8) | ((buf&0xff)<<8);                          /* g2, r2 */ | 
|  | buf = *srcpixel++; | 
|  | *ptr++ = val | (buf&0xff0000) | ((buf&0xff00)<<16);                 /* b3, g3 */ | 
|  | val = (buf&0xff);                                                   /* r3 */ | 
|  | buf = *srcpixel++; | 
|  | *ptr++ = val | ((buf&0xff0000)>>8) | ((buf&0xff00)<<8) | (buf<<24); /* b4, g4, r4 */ | 
|  | } | 
|  | for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */ | 
|  | { | 
|  | buf=*srcpixel++; | 
|  | *(WORD*)bits = (buf&0xff00) | ((buf&0xff0000)>>16) ;                /* b, g */ | 
|  | *(bits+2) = buf;                                                    /* r */ | 
|  | } | 
|  | ptr = (DWORD*)(dstbits+=linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 15: | 
|  | { | 
|  | LPWORD srcpixel; | 
|  | LPBYTE bits = dstbits; | 
|  | WORD val; | 
|  |  | 
|  | /* ==== 555 BGR bitmap to 24 BGR dib ==== */ | 
|  | if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 ) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < srcwidth; x++, bits += 3) { | 
|  | val = *srcpixel++; | 
|  | bits[2] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));           /*Red*/ | 
|  | bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));            /*Green*/ | 
|  | bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));            /*Blue*/ | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 555 RGB bitmap to 24 RGB dib==== */ | 
|  | else if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f ) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < srcwidth; x++, bits += 3) { | 
|  | val = *srcpixel++; | 
|  | bits[0] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));           /*Red*/ | 
|  | bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));            /*Green*/ | 
|  | bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));            /*Blue*/ | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 16: | 
|  | { | 
|  | LPWORD srcpixel; | 
|  | LPBYTE bits = dstbits; | 
|  | WORD val; | 
|  |  | 
|  | /* ==== 565 BGR bitmap to 24 BGR dib ==== */ | 
|  | if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0xf800 ) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < srcwidth; x++, bits += 3) { | 
|  | val = *srcpixel++; | 
|  | bits[2] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));           /*Red*/ | 
|  | bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03));            /*Green*/ | 
|  | bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));            /*Blue*/ | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 565 RGB bitmap to 24 BGR dib ==== */ | 
|  | else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x1f ) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < srcwidth; x++, bits += 3) { | 
|  | val = *srcpixel++; | 
|  | bits[0] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));           /*Red*/ | 
|  | bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03));            /*Green*/ | 
|  | bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));            /*Blue*/ | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else  goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 1: | 
|  | /* ==== monochrome bitmap to 24 BGR dib ==== */ | 
|  | case 4: | 
|  | /* ==== 4 colormap bitmap to 24 BGR dib ==== */ | 
|  | if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) | 
|  | { | 
|  | LPBYTE bits = dstbits; | 
|  | PALETTEENTRY val; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  | val = srccolors[XGetPixel(bmpImage, x, h)]; | 
|  | *bits++ = val.peBlue; | 
|  | *bits++ = val.peGreen; | 
|  | *bits++ = val.peRed; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 8: | 
|  | /* ==== 8 colormap bitmap to 24 BGR dib ==== */ | 
|  | if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors) | 
|  | { | 
|  | BYTE *srcpixel; | 
|  | LPBYTE bits = dstbits; | 
|  | PALETTEENTRY val; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = bmpImage->data + h*bmpImage->bytes_per_line; | 
|  | for (x = 0; x < dstwidth; x++ ) { | 
|  | val = srccolors[(int)*srcpixel++]; | 
|  | *bits++ = val.peBlue;               /*Blue*/ | 
|  | *bits++ = val.peGreen;              /*Green*/ | 
|  | *bits++ = val.peRed;                /*Red*/ | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | default: | 
|  | notsupported: | 
|  | { | 
|  | LPBYTE bits = dstbits; | 
|  |  | 
|  | FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n", | 
|  | bmpImage->depth, (int)bmpImage->red_mask, | 
|  | (int)bmpImage->green_mask, (int)bmpImage->blue_mask ); | 
|  | for (h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | for (x = 0; x < dstwidth; x++, bits += 3) | 
|  | { | 
|  | COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) ); | 
|  | bits[0] = GetBValue(pixel); | 
|  | bits[1] = GetGValue(pixel); | 
|  | bits[2] = GetRValue(pixel); | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_SetImageBits_32 | 
|  | * | 
|  | * SetDIBits for a 32-bit deep DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits, | 
|  | DWORD srcwidth, DWORD dstwidth, int left, | 
|  | DC *dc, XImage *bmpImage, | 
|  | DWORD linebytes ) | 
|  | { | 
|  | DWORD x, *ptr; | 
|  | int h; | 
|  |  | 
|  | if (lines < 0 ) | 
|  | { | 
|  | lines = -lines; | 
|  | srcbits = srcbits + ( linebytes * (lines-1) ); | 
|  | linebytes = -linebytes; | 
|  | } | 
|  |  | 
|  | ptr = (DWORD *) srcbits + left; | 
|  |  | 
|  | switch ( bmpImage->depth ) | 
|  | { | 
|  | case 32: | 
|  | /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */ | 
|  | if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) { | 
|  | for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) { | 
|  | memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */ | 
|  | else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000) | 
|  | { | 
|  | DWORD *dstpixel; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < dstwidth; x++, ptr++) { | 
|  | *dstpixel++ =   ((*ptr << 16) & 0xff0000) | (*ptr & 0xff00) | ((*ptr >> 16) & 0xff); | 
|  | } | 
|  | ptr = (DWORD *) (srcbits += linebytes) + left; | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 24: | 
|  | /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */ | 
|  | /* we need to check that source mask matches destination */ | 
|  | if (bmpImage->bits_per_pixel == 32) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) { | 
|  | memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 ); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | BYTE  *bptr; | 
|  |  | 
|  | ptr = (DWORD *) srcbits + left; | 
|  | bptr = bmpImage->data; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  | /* *ptr is a 32bit value */ | 
|  | /* bptr points to first of 3 bytes */ | 
|  | *bptr++ = (*ptr >> 16) & 0xff; | 
|  | *bptr++ = (*ptr >>  8) & 0xff; | 
|  | *bptr++ = (*ptr      ) & 0xff; | 
|  | ptr++; | 
|  | } | 
|  | ptr = (DWORD *) (srcbits += linebytes) + left; | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 15: | 
|  | /* ==== 32 BGR dib to 555 BGR bitmap ==== */ | 
|  | if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f) { | 
|  | LPWORD  dstpixel; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < dstwidth; x++, ptr++) { | 
|  | *dstpixel++ = (WORD) (((*ptr >> 9) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 3) & 0x001f)); | 
|  | } | 
|  | ptr = (DWORD *) (srcbits += linebytes) + left; | 
|  | } | 
|  | } | 
|  | /* ==== 32 BGR dib to 555 RGB bitmap ==== */ | 
|  | else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00) | 
|  | { | 
|  | LPWORD  dstpixel; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < dstwidth; x++, ptr++) { | 
|  | *dstpixel++ = (WORD) (((*ptr << 7) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 19) & 0x001f)); | 
|  | } | 
|  | ptr = (DWORD *) (srcbits += linebytes) + left; | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 16: | 
|  | /* ==== 32 BGR dib to 565 BGR bitmap ==== */ | 
|  | if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f) | 
|  | { | 
|  | LPWORD  dstpixel; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < dstwidth; x++, ptr++) { | 
|  | *dstpixel++ = (WORD) (((*ptr >> 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 3) & 0x001f)); | 
|  | } | 
|  | ptr = (DWORD *) (srcbits += linebytes) + left; | 
|  | } | 
|  | } | 
|  | /* ==== 32 BGR dib to 565 RGB bitmap ==== */ | 
|  | else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800) | 
|  | { | 
|  | LPWORD dstpixel; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < dstwidth; x++, ptr++) { | 
|  | *dstpixel++ = (WORD) (((*ptr << 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 19) & 0x001f)); | 
|  | } | 
|  | ptr = (DWORD *) (srcbits += linebytes) + left; | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 1: | 
|  | case 4: | 
|  | case 8: | 
|  | { | 
|  | LPBYTE bits = (LPBYTE)srcbits + left*4; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | for (x = left; x < dstwidth+left; x++, bits += 4) | 
|  | XPutPixel( bmpImage, x, h, | 
|  | X11DRV_PALETTE_ToPhysical(dc, RGB( bits[2],  bits[1], *bits ))); | 
|  | bits = (LPBYTE)(srcbits += linebytes) + left * 4; | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | default: | 
|  | notsupported: | 
|  | FIXME("32 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel); | 
|  | break; | 
|  | } | 
|  |  | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_GetImageBits_32 | 
|  | * | 
|  | * GetDIBits for an 32-bit deep DIB. | 
|  | */ | 
|  | static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits, | 
|  | DWORD dstwidth, DWORD srcwidth, | 
|  | PALETTEENTRY *srccolors, | 
|  | XImage *bmpImage, DWORD linebytes ) | 
|  | { | 
|  | DWORD x; | 
|  | int h; | 
|  | BYTE *bits; | 
|  |  | 
|  | DWORD copybytes = srcwidth * 4; | 
|  |  | 
|  | if (lines < 0 ) | 
|  | { | 
|  | lines = -lines; | 
|  | dstbits = dstbits + ( linebytes * (lines-1) ); | 
|  | linebytes = -linebytes; | 
|  | } | 
|  |  | 
|  | bits = dstbits; | 
|  |  | 
|  | switch ( bmpImage->depth ) | 
|  | { | 
|  | case 32: | 
|  | /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */ | 
|  | if ( bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff ) | 
|  | for (h = lines - 1; h >= 0; h--, dstbits+=linebytes) | 
|  | memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, copybytes ); | 
|  |  | 
|  | /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */ | 
|  | else if ( bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000 ) | 
|  | { | 
|  | LPBYTE srcbits; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcbits = bmpImage->data + h * bmpImage->bytes_per_line; | 
|  | for (x = 0; x < dstwidth; x++, bits+=4, srcbits+=2) { | 
|  | *(bits + 2) = *srcbits++; | 
|  | *(bits + 1) = *srcbits++; | 
|  | *bits = *srcbits; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | break; | 
|  |  | 
|  | case 24: | 
|  | /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */ | 
|  | /* we need to check that source mask matches destination */ | 
|  | { | 
|  | DWORD *srcpixel; | 
|  | BYTE  *bptr; | 
|  | DWORD srcdata; | 
|  |  | 
|  | srcpixel = (DWORD *) dstbits; | 
|  | bptr = bmpImage->data; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  | /* *srcpixel is a 32bit value */ | 
|  | /* bptr points to first of 3 bytes */ | 
|  | srcdata = 0; | 
|  | srcdata	= srcdata << 8 | *bptr++; | 
|  | srcdata = srcdata << 8 | *bptr++; | 
|  | srcdata = srcdata << 8 | *bptr++; | 
|  |  | 
|  | *srcpixel++ = srcdata; | 
|  | } | 
|  | srcpixel = (DWORD *) (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 15: | 
|  | { | 
|  | LPWORD srcpixel; | 
|  | WORD val; | 
|  |  | 
|  | /* ==== 555 BGR bitmap to 32 BGR dib ==== */ | 
|  | if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < dstwidth; x++, bits+=2) { | 
|  | val = *srcpixel++; | 
|  | *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/ | 
|  | *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/ | 
|  | *bits = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));  /*Red*/ | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 555 RGB bitmap to 32 BGR dib ==== */ | 
|  | else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < dstwidth; x++, bits+=2) { | 
|  | val = *srcpixel++; | 
|  | *bits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));/*Blue*/ | 
|  | *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/ | 
|  | *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03));   /*Red*/ | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 16: | 
|  | { | 
|  | LPWORD srcpixel; | 
|  | WORD val; | 
|  |  | 
|  | /* ==== 565 BGR bitmap to 32 BGR dib ==== */ | 
|  | if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < srcwidth; x++, bits+=2) { | 
|  | val = *srcpixel++; | 
|  | *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/ | 
|  | *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/ | 
|  | *bits = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));  /*Red*/ | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | /* ==== 565 RGB bitmap to 32 BGR dib ==== */ | 
|  | else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f) | 
|  | { | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line); | 
|  | for (x = 0; x < srcwidth; x++, bits+=2) { | 
|  | val = *srcpixel++; | 
|  | *bits++ = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));/*Blue*/ | 
|  | *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/ | 
|  | *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03));   /*Red*/ | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 1: | 
|  | /* ==== monochrome bitmap to 32 BGR dib ==== */ | 
|  | case 4: | 
|  | /* ==== 4 colormap bitmap to 32 BGR dib ==== */ | 
|  | if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) | 
|  | { | 
|  | PALETTEENTRY val; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  | val = srccolors[XGetPixel(bmpImage, x, h)]; | 
|  | *bits++ = val.peBlue; | 
|  | *bits++ = val.peGreen; | 
|  | *bits++ = val.peRed; | 
|  | *bits++ = 0; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  |  | 
|  | break; | 
|  |  | 
|  | case 8: | 
|  | /* ==== 8 colormap bitmap to 32 BGR dib ==== */ | 
|  | if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) | 
|  | { | 
|  | BYTE *srcpixel; | 
|  | PALETTEENTRY val; | 
|  |  | 
|  | for (h = lines - 1; h >= 0; h--) { | 
|  | srcpixel = bmpImage->data + h*bmpImage->bytes_per_line; | 
|  | for (x = 0; x < dstwidth; x++) { | 
|  | val = srccolors[(int)*srcpixel++]; | 
|  | *bits++ = val.peBlue;               /*Blue*/ | 
|  | *bits++ = val.peGreen;              /*Green*/ | 
|  | *bits++ = val.peRed;                /*Red*/ | 
|  | *bits++ = 0; | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | } | 
|  | else goto notsupported; | 
|  | break; | 
|  |  | 
|  | default: | 
|  | notsupported: | 
|  | FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n", | 
|  | bmpImage->depth, (int)bmpImage->red_mask, | 
|  | (int)bmpImage->green_mask, (int)bmpImage->blue_mask ); | 
|  | for (h = lines - 1; h >= 0; h--) | 
|  | { | 
|  | for (x = 0; x < dstwidth; x++, bits += 4) | 
|  | { | 
|  | COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) ); | 
|  | bits[0] = GetBValue(pixel); | 
|  | bits[1] = GetGValue(pixel); | 
|  | bits[2] = GetRValue(pixel); | 
|  | } | 
|  | bits = (dstbits += linebytes); | 
|  | } | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_SetImageBits | 
|  | * | 
|  | * Transfer the bits to an X image. | 
|  | * Helper function for SetDIBits() and SetDIBitsToDevice(). | 
|  | */ | 
|  | static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr ) | 
|  | { | 
|  | int lines = descr->lines >= 0 ? descr->lines : -descr->lines; | 
|  | XImage *bmpImage; | 
|  |  | 
|  | wine_tsx11_lock(); | 
|  | if (descr->image) | 
|  | bmpImage = descr->image; | 
|  | else { | 
|  | bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL, | 
|  | descr->infoWidth, lines, 32, 0 ); | 
|  | bmpImage->data = calloc( lines, bmpImage->bytes_per_line ); | 
|  | if(bmpImage->data == NULL) { | 
|  | ERR("Out of memory!\n"); | 
|  | XDestroyImage( bmpImage ); | 
|  | wine_tsx11_unlock(); | 
|  | return lines; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Transfer the pixels */ | 
|  | switch(descr->infoBpp) | 
|  | { | 
|  | case 1: | 
|  | X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth, | 
|  | descr->width, descr->xSrc, (int *)(descr->colorMap), | 
|  | bmpImage, descr->dibpitch ); | 
|  | break; | 
|  | case 4: | 
|  | if (descr->compression) { | 
|  | XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest, | 
|  | descr->width, descr->height, AllPlanes, ZPixmap, | 
|  | bmpImage, descr->xSrc, descr->ySrc ); | 
|  |  | 
|  | X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits, | 
|  | descr->infoWidth, descr->width, | 
|  | descr->xSrc, (int *)(descr->colorMap), | 
|  | bmpImage ); | 
|  | } else | 
|  | X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits, | 
|  | descr->infoWidth, descr->width, | 
|  | descr->xSrc, (int*)(descr->colorMap), | 
|  | bmpImage, descr->dibpitch ); | 
|  | break; | 
|  | case 8: | 
|  | if (descr->compression) { | 
|  | XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest, | 
|  | descr->width, descr->height, AllPlanes, ZPixmap, | 
|  | bmpImage, descr->xSrc, descr->ySrc ); | 
|  | X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits, | 
|  | descr->infoWidth, descr->width, | 
|  | descr->xSrc, (int *)(descr->colorMap), | 
|  | bmpImage ); | 
|  | } else | 
|  | X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits, | 
|  | descr->infoWidth, descr->width, | 
|  | descr->xSrc, (int *)(descr->colorMap), | 
|  | bmpImage, descr->dibpitch ); | 
|  | break; | 
|  | case 15: | 
|  | case 16: | 
|  | X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits, | 
|  | descr->infoWidth, descr->width, | 
|  | descr->xSrc, descr->dc, | 
|  | descr->rMask, descr->gMask, descr->bMask, | 
|  | bmpImage, descr->dibpitch); | 
|  | break; | 
|  | case 24: | 
|  | X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits, | 
|  | descr->infoWidth, descr->width, | 
|  | descr->xSrc, descr->dc, bmpImage, | 
|  | descr->dibpitch); | 
|  | break; | 
|  | case 32: | 
|  | X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits, | 
|  | descr->infoWidth, descr->width, | 
|  | descr->xSrc, descr->dc, | 
|  | bmpImage, descr->dibpitch); | 
|  | break; | 
|  | default: | 
|  | WARN("(%d): Invalid depth\n", descr->infoBpp ); | 
|  | break; | 
|  | } | 
|  |  | 
|  | TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n", | 
|  | descr->drawable, descr->gc, bmpImage, | 
|  | descr->xSrc, descr->ySrc, descr->xDest, descr->yDest, | 
|  | descr->width, descr->height); | 
|  | #ifdef HAVE_LIBXXSHM | 
|  | if (descr->useShm) | 
|  | { | 
|  | XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage, | 
|  | descr->xSrc, descr->ySrc, descr->xDest, descr->yDest, | 
|  | descr->width, descr->height, FALSE ); | 
|  | XSync( gdi_display, 0 ); | 
|  | } | 
|  | else | 
|  | #endif | 
|  | XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage, | 
|  | descr->xSrc, descr->ySrc, descr->xDest, descr->yDest, | 
|  | descr->width, descr->height ); | 
|  |  | 
|  | if (!descr->image) XDestroyImage( bmpImage ); | 
|  | wine_tsx11_unlock(); | 
|  | return lines; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_GetImageBits | 
|  | * | 
|  | * Transfer the bits from an X image. | 
|  | */ | 
|  | static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr ) | 
|  | { | 
|  | int lines = descr->lines >= 0 ? descr->lines : -descr->lines; | 
|  | XImage *bmpImage; | 
|  |  | 
|  | wine_tsx11_lock(); | 
|  | if (descr->image) | 
|  | bmpImage = descr->image; | 
|  | else { | 
|  | bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL, | 
|  | descr->infoWidth, lines, 32, 0 ); | 
|  | bmpImage->data = calloc( lines, bmpImage->bytes_per_line ); | 
|  | if(bmpImage->data == NULL) { | 
|  | ERR("Out of memory!\n"); | 
|  | XDestroyImage( bmpImage ); | 
|  | wine_tsx11_unlock(); | 
|  | return lines; | 
|  | } | 
|  | } | 
|  |  | 
|  | TRACE("XGetSubImage(%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n", | 
|  | descr->drawable, descr->xSrc, descr->ySrc, descr->width, | 
|  | lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest); | 
|  | XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc, | 
|  | descr->width, lines, AllPlanes, ZPixmap, | 
|  | bmpImage, descr->xDest, descr->yDest ); | 
|  |  | 
|  | /* Transfer the pixels */ | 
|  | switch(descr->infoBpp) | 
|  | { | 
|  | case 1: | 
|  | X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits, | 
|  | descr->infoWidth, descr->width, | 
|  | descr->colorMap, descr->palentry, | 
|  | bmpImage, descr->dibpitch ); | 
|  | break; | 
|  |  | 
|  | case 4: | 
|  | if (descr->compression) | 
|  | FIXME("Compression not yet supported!\n"); | 
|  | else | 
|  | X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits, | 
|  | descr->infoWidth, descr->width, | 
|  | descr->colorMap, descr->palentry, | 
|  | bmpImage, descr->dibpitch ); | 
|  | break; | 
|  |  | 
|  | case 8: | 
|  | if (descr->compression) | 
|  | FIXME("Compression not yet supported!\n"); | 
|  | else | 
|  | X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits, | 
|  | descr->infoWidth, descr->width, | 
|  | descr->colorMap, descr->palentry, | 
|  | bmpImage, descr->dibpitch ); | 
|  | break; | 
|  | case 15: | 
|  | case 16: | 
|  | X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits, | 
|  | descr->infoWidth,descr->width, | 
|  | descr->palentry, | 
|  | descr->rMask, descr->gMask, descr->bMask, | 
|  | bmpImage, descr->dibpitch ); | 
|  | break; | 
|  |  | 
|  | case 24: | 
|  | X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits, | 
|  | descr->infoWidth,descr->width, | 
|  | descr->palentry, bmpImage, descr->dibpitch); | 
|  | break; | 
|  |  | 
|  | case 32: | 
|  | X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits, | 
|  | descr->infoWidth, descr->width, | 
|  | descr->palentry, bmpImage, descr->dibpitch); | 
|  | break; | 
|  |  | 
|  | default: | 
|  | WARN("(%d): Invalid depth\n", descr->infoBpp ); | 
|  | break; | 
|  | } | 
|  |  | 
|  | if (!descr->image) XDestroyImage( bmpImage ); | 
|  | wine_tsx11_unlock(); | 
|  | return lines; | 
|  | } | 
|  |  | 
|  | /************************************************************************* | 
|  | *		X11DRV_SetDIBitsToDevice | 
|  | * | 
|  | */ | 
|  | INT X11DRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx, | 
|  | DWORD cy, INT xSrc, INT ySrc, | 
|  | UINT startscan, UINT lines, LPCVOID bits, | 
|  | const BITMAPINFO *info, UINT coloruse ) | 
|  | { | 
|  | X11DRV_DIB_IMAGEBITS_DESCR descr; | 
|  | DWORD width, oldcy = cy; | 
|  | INT result; | 
|  | int height, tmpheight; | 
|  | X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev; | 
|  |  | 
|  |  | 
|  | if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, | 
|  | &descr.infoBpp, &descr.compression ) == -1) | 
|  | return 0; | 
|  | tmpheight = height; | 
|  | if (height < 0) height = -height; | 
|  | if (!lines || (startscan >= height)) return 0; | 
|  | if (startscan + lines > height) lines = height - startscan; | 
|  | if (ySrc < startscan) ySrc = startscan; | 
|  | else if (ySrc >= startscan + lines) return 0; | 
|  | if (xSrc >= width) return 0; | 
|  | if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc; | 
|  | if (xSrc + cx >= width) cx = width - xSrc; | 
|  | if (!cx || !cy) return 0; | 
|  |  | 
|  | X11DRV_SetupGCForText( dc );  /* To have the correct colors */ | 
|  | TSXSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]); | 
|  |  | 
|  | switch (descr.infoBpp) | 
|  | { | 
|  | case 1: | 
|  | case 4: | 
|  | case 8: | 
|  | descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap( | 
|  | coloruse == DIB_PAL_COLORS ? dc : NULL, coloruse, | 
|  | dc->bitsPerPixel, info, &descr.nColorMap ); | 
|  | if (!descr.colorMap) return 0; | 
|  | descr.rMask = descr.gMask = descr.bMask = 0; | 
|  | break; | 
|  | case 15: | 
|  | case 16: | 
|  | descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00; | 
|  | descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0x03e0; | 
|  | descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0x001f; | 
|  | descr.colorMap = 0; | 
|  | break; | 
|  |  | 
|  | case 24: | 
|  | descr.rMask = descr.gMask = descr.bMask = 0; | 
|  | descr.colorMap = 0; | 
|  | break; | 
|  |  | 
|  | case 32: | 
|  | descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000; | 
|  | descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0xff00; | 
|  | descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0xff; | 
|  | descr.colorMap = 0; | 
|  | break; | 
|  | } | 
|  |  | 
|  | descr.dc        = dc; | 
|  | descr.bits      = bits; | 
|  | descr.image     = NULL; | 
|  | descr.palentry  = NULL; | 
|  | descr.lines     = tmpheight >= 0 ? lines : -lines; | 
|  | descr.infoWidth = width; | 
|  | descr.depth     = dc->bitsPerPixel; | 
|  | descr.drawable  = physDev->drawable; | 
|  | descr.gc        = physDev->gc; | 
|  | descr.xSrc      = xSrc; | 
|  | descr.ySrc      = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy) | 
|  | : ySrc - startscan; | 
|  | descr.xDest     = dc->DCOrgX + XLPTODP( dc, xDest ); | 
|  | descr.yDest     = dc->DCOrgY + YLPTODP( dc, yDest ) + | 
|  | (tmpheight >= 0 ? oldcy-cy : 0); | 
|  | descr.width     = cx; | 
|  | descr.height    = cy; | 
|  | descr.useShm    = FALSE; | 
|  | descr.dibpitch  = ((width * descr.infoBpp + 31) &~31) / 8; | 
|  |  | 
|  | result = X11DRV_DIB_SetImageBits( &descr ); | 
|  |  | 
|  | if (descr.infoBpp <= 8) | 
|  | HeapFree(GetProcessHeap(), 0, descr.colorMap); | 
|  | return result; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_SetDIBits | 
|  | */ | 
|  | INT X11DRV_DIB_SetDIBits( | 
|  | BITMAPOBJ *bmp, DC *dc, UINT startscan, | 
|  | UINT lines, LPCVOID bits, const BITMAPINFO *info, | 
|  | UINT coloruse, HBITMAP hbitmap) | 
|  | { | 
|  | X11DRV_DIB_IMAGEBITS_DESCR descr; | 
|  | int height, tmpheight; | 
|  | INT result; | 
|  |  | 
|  | descr.dc = dc; | 
|  |  | 
|  | if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height, | 
|  | &descr.infoBpp, &descr.compression ) == -1) | 
|  | return 0; | 
|  |  | 
|  | tmpheight = height; | 
|  | if (height < 0) height = -height; | 
|  | if (!lines || (startscan >= height)) | 
|  | return 0; | 
|  |  | 
|  | if (startscan + lines > height) lines = height - startscan; | 
|  |  | 
|  | switch (descr.infoBpp) | 
|  | { | 
|  | case 1: | 
|  | case 4: | 
|  | case 8: | 
|  | descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap( | 
|  | coloruse == DIB_PAL_COLORS ? descr.dc : NULL, coloruse, | 
|  | bmp->bitmap.bmBitsPixel, | 
|  | info, &descr.nColorMap ); | 
|  | if (!descr.colorMap) return 0; | 
|  | descr.rMask = descr.gMask = descr.bMask = 0; | 
|  | break; | 
|  | case 15: | 
|  | case 16: | 
|  | descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00; | 
|  | descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0x03e0; | 
|  | descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0x001f; | 
|  | descr.colorMap = 0; | 
|  | break; | 
|  |  | 
|  | case 24: | 
|  | descr.rMask = descr.gMask = descr.bMask = 0; | 
|  | descr.colorMap = 0; | 
|  | break; | 
|  |  | 
|  | case 32: | 
|  | descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000; | 
|  | descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0xff00; | 
|  | descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0xff; | 
|  | descr.colorMap = 0; | 
|  | break; | 
|  |  | 
|  | default: break; | 
|  | } | 
|  |  | 
|  | /* HACK for now */ | 
|  | if(!bmp->physBitmap) | 
|  | X11DRV_CreateBitmap(hbitmap); | 
|  |  | 
|  | descr.bits      = bits; | 
|  | descr.image     = NULL; | 
|  | descr.palentry  = NULL; | 
|  | descr.lines     = tmpheight >= 0 ? lines : -lines; | 
|  | descr.depth     = bmp->bitmap.bmBitsPixel; | 
|  | descr.drawable  = (Pixmap)bmp->physBitmap; | 
|  | descr.gc        = BITMAP_GC(bmp); | 
|  | descr.xSrc      = 0; | 
|  | descr.ySrc      = 0; | 
|  | descr.xDest     = 0; | 
|  | descr.yDest     = height - startscan - lines; | 
|  | descr.width     = bmp->bitmap.bmWidth; | 
|  | descr.height    = lines; | 
|  | descr.useShm    = FALSE; | 
|  | descr.dibpitch  = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8; | 
|  | result = X11DRV_DIB_SetImageBits( &descr ); | 
|  |  | 
|  | if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap); | 
|  |  | 
|  | return result; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_GetDIBits | 
|  | */ | 
|  | INT X11DRV_DIB_GetDIBits( | 
|  | BITMAPOBJ *bmp, DC *dc, UINT startscan, | 
|  | UINT lines, LPVOID bits, BITMAPINFO *info, | 
|  | UINT coloruse, HBITMAP hbitmap) | 
|  | { | 
|  | X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib; | 
|  | X11DRV_DIB_IMAGEBITS_DESCR descr; | 
|  | PALETTEOBJ * palette; | 
|  | int height; | 
|  |  | 
|  | TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n", | 
|  | lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, | 
|  | (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight, | 
|  | startscan ); | 
|  |  | 
|  | if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC ))) | 
|  | return 0; | 
|  |  | 
|  | if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight; | 
|  |  | 
|  | height = info->bmiHeader.biHeight; | 
|  | if (height < 0) height = -height; | 
|  | if( lines > height ) lines = height; | 
|  | /* Top-down images have a negative biHeight, the scanlines of theses images | 
|  | * were inverted in X11DRV_DIB_GetImageBits_xx | 
|  | * To prevent this we simply change the sign of lines | 
|  | * (the number of scan lines to copy). | 
|  | * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx. | 
|  | */ | 
|  | if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines; | 
|  |  | 
|  | if( startscan >= bmp->bitmap.bmHeight ) | 
|  | { | 
|  | lines = 0; | 
|  | goto done; | 
|  | } | 
|  |  | 
|  | if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines, | 
|  | &descr.infoBpp, &descr.compression ) == -1) | 
|  | { | 
|  | lines = 0; | 
|  | goto done; | 
|  | } | 
|  |  | 
|  | switch (descr.infoBpp) | 
|  | { | 
|  | case 1: | 
|  | case 4: | 
|  | case 8: | 
|  | case 24: | 
|  | descr.rMask = descr.gMask = descr.bMask = 0; | 
|  | break; | 
|  | case 15: | 
|  | case 16: | 
|  | descr.rMask = 0x7c00; | 
|  | descr.gMask = 0x03e0; | 
|  | descr.bMask = 0x001f; | 
|  | break; | 
|  |  | 
|  | case 32: | 
|  | descr.rMask = 0xff0000; | 
|  | descr.gMask = 0xff00; | 
|  | descr.bMask = 0xff; | 
|  | break; | 
|  | } | 
|  |  | 
|  | /* Hack for now */ | 
|  | if(!bmp->physBitmap) | 
|  | X11DRV_CreateBitmap(hbitmap); | 
|  |  | 
|  |  | 
|  | descr.dc        = dc; | 
|  | descr.palentry  = palette->logpalette.palPalEntry; | 
|  | descr.bits      = bits; | 
|  | descr.image     = NULL; | 
|  | descr.lines     = lines; | 
|  | descr.depth     = bmp->bitmap.bmBitsPixel; | 
|  | descr.drawable  = (Pixmap)bmp->physBitmap; | 
|  | descr.gc        = BITMAP_GC(bmp); | 
|  | descr.width     = bmp->bitmap.bmWidth; | 
|  | descr.height    = bmp->bitmap.bmHeight; | 
|  | descr.colorMap  = info->bmiColors; | 
|  | descr.xDest     = 0; | 
|  | descr.yDest     = 0; | 
|  | descr.xSrc      = 0; | 
|  |  | 
|  | if (descr.lines > 0) | 
|  | { | 
|  | descr.ySrc = (descr.height-1) - (startscan + (lines-1)); | 
|  | } | 
|  | else | 
|  | { | 
|  | descr.ySrc = startscan; | 
|  | } | 
|  | #ifdef HAVE_LIBXXSHM | 
|  | descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE; | 
|  | #else | 
|  | descr.useShm = FALSE; | 
|  | #endif | 
|  | descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes) | 
|  | : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8); | 
|  |  | 
|  | X11DRV_DIB_GetImageBits( &descr ); | 
|  |  | 
|  | if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */ | 
|  | info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( | 
|  | info->bmiHeader.biWidth, | 
|  | info->bmiHeader.biHeight, | 
|  | info->bmiHeader.biBitCount ); | 
|  |  | 
|  | info->bmiHeader.biCompression = 0; | 
|  | if (descr.compression == BI_BITFIELDS) | 
|  | { | 
|  | *(DWORD *)info->bmiColors = descr.rMask; | 
|  | *((DWORD *)info->bmiColors+1) = descr.gMask; | 
|  | *((DWORD *)info->bmiColors+2) = descr.bMask; | 
|  | } | 
|  |  | 
|  | done: | 
|  | GDI_ReleaseObj( dc->hPalette ); | 
|  |  | 
|  | return lines; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           DIB_DoProtectDIBSection | 
|  | */ | 
|  | static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot ) | 
|  | { | 
|  | DIBSECTION *dib = bmp->dib; | 
|  | INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight | 
|  | : -dib->dsBm.bmHeight; | 
|  | /* use the biSizeImage data as the memory size only if we're dealing with a | 
|  | compressed image where the value is set.  Otherwise, calculate based on | 
|  | width * height */ | 
|  | INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB | 
|  | ? dib->dsBmih.biSizeImage | 
|  | : dib->dsBm.bmWidthBytes * effHeight; | 
|  | DWORD old_prot; | 
|  |  | 
|  | VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot); | 
|  | TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot); | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_DoUpdateDIBSection | 
|  | */ | 
|  | static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB, | 
|  | void *colorMap, int nColorMap, | 
|  | Drawable dest, | 
|  | DWORD xSrc, DWORD ySrc, | 
|  | DWORD xDest, DWORD yDest, | 
|  | DWORD width, DWORD height) | 
|  | { | 
|  | X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib; | 
|  | X11DRV_DIB_IMAGEBITS_DESCR descr; | 
|  |  | 
|  | if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines, | 
|  | &descr.infoBpp, &descr.compression ) == -1) | 
|  | return; | 
|  |  | 
|  | descr.dc        = NULL; | 
|  | descr.palentry  = NULL; | 
|  | descr.image     = dib->image; | 
|  | descr.colorMap  = colorMap; | 
|  | descr.nColorMap = nColorMap; | 
|  | descr.bits      = dib->dibSection.dsBm.bmBits; | 
|  | descr.depth     = bmp->bitmap.bmBitsPixel; | 
|  |  | 
|  | switch (descr.infoBpp) | 
|  | { | 
|  | case 1: | 
|  | case 4: | 
|  | case 8: | 
|  | case 24: | 
|  | descr.rMask = descr.gMask = descr.bMask = 0; | 
|  | break; | 
|  | case 15: | 
|  | case 16: | 
|  | descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00; | 
|  | descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0; | 
|  | descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f; | 
|  | break; | 
|  |  | 
|  | case 32: | 
|  | descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff; | 
|  | descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0xff00; | 
|  | descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0xff0000; | 
|  | break; | 
|  | } | 
|  |  | 
|  | /* Hack for now */ | 
|  | descr.drawable  = dest; | 
|  | descr.gc        = BITMAP_GC(bmp); | 
|  | descr.xSrc      = xSrc; | 
|  | descr.ySrc      = ySrc; | 
|  | descr.xDest     = xDest; | 
|  | descr.yDest     = yDest; | 
|  | descr.width     = width; | 
|  | descr.height    = height; | 
|  | #ifdef HAVE_LIBXXSHM | 
|  | descr.useShm = (dib->shminfo.shmid != -1); | 
|  | #else | 
|  | descr.useShm = FALSE; | 
|  | #endif | 
|  | descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes; | 
|  |  | 
|  | if (toDIB) | 
|  | { | 
|  | TRACE("Copying from Pixmap to DIB bits\n"); | 
|  | X11DRV_DIB_GetImageBits( &descr ); | 
|  | } | 
|  | else | 
|  | { | 
|  | TRACE("Copying from DIB bits to Pixmap\n"); | 
|  | X11DRV_DIB_SetImageBits( &descr ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_CopyDIBSection | 
|  | */ | 
|  | void X11DRV_DIB_CopyDIBSection(DC *dcSrc, DC *dcDst, | 
|  | DWORD xSrc, DWORD ySrc, | 
|  | DWORD xDest, DWORD yDest, | 
|  | DWORD width, DWORD height) | 
|  | { | 
|  | BITMAPOBJ *bmp; | 
|  | X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcDst->physDev; | 
|  | int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE; | 
|  |  | 
|  | TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst, | 
|  | xSrc, ySrc, xDest, yDest, width, height); | 
|  | /* this function is meant as an optimization for BitBlt, | 
|  | * not to be called otherwise */ | 
|  | if (!(dcSrc->flags & DC_MEMORY)) { | 
|  | ERR("called for non-memory source DC!?\n"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC ); | 
|  | if (!(bmp && bmp->dib)) { | 
|  | ERR("called for non-DIBSection!?\n"); | 
|  | GDI_ReleaseObj( dcSrc->hBitmap ); | 
|  | return; | 
|  | } | 
|  | /* while BitBlt should already have made sure we only get | 
|  | * positive values, we should check for oversize values */ | 
|  | if ((xSrc < bmp->bitmap.bmWidth) && | 
|  | (ySrc < bmp->bitmap.bmHeight)) { | 
|  | if (xSrc + width > bmp->bitmap.bmWidth) | 
|  | width = bmp->bitmap.bmWidth - xSrc; | 
|  | if (ySrc + height > bmp->bitmap.bmHeight) | 
|  | height = bmp->bitmap.bmHeight - ySrc; | 
|  | /* if the source bitmap is 8bpp or less, we're supposed to use the | 
|  | * DC's palette for color conversion (not the DIB color table) */ | 
|  | if (bmp->dib->dsBm.bmBitsPixel <= 8) { | 
|  | X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib; | 
|  | if ((!dcSrc->hPalette) || | 
|  | (dcSrc->hPalette == GetStockObject(DEFAULT_PALETTE))) { | 
|  | /* HACK: no palette has been set in the source DC, | 
|  | * use the DIB colormap instead - this is necessary in some | 
|  | * cases since we need to do depth conversion in some places | 
|  | * where real Windows can just copy data straight over */ | 
|  | colorMap = dib->colorMap; | 
|  | nColorMap = dib->nColorMap; | 
|  | } else { | 
|  | colorMap = X11DRV_DIB_BuildColorMap( dcSrc, (WORD)-1, | 
|  | bmp->dib->dsBm.bmBitsPixel, | 
|  | (BITMAPINFO*)&(bmp->dib->dsBmih), | 
|  | &nColorMap ); | 
|  | if (colorMap) aColorMap = TRUE; | 
|  | } | 
|  | } | 
|  | /* perform the copy */ | 
|  | X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap, | 
|  | physDev->drawable, xSrc, ySrc, xDest, yDest, | 
|  | width, height); | 
|  | /* free color mapping */ | 
|  | if (aColorMap) | 
|  | HeapFree(GetProcessHeap(), 0, colorMap); | 
|  | } | 
|  | GDI_ReleaseObj( dcSrc->hBitmap ); | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_DoUpdateDIBSection | 
|  | */ | 
|  | static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB) | 
|  | { | 
|  | X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib; | 
|  | X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap, | 
|  | (Drawable)bmp->physBitmap, 0, 0, 0, 0, | 
|  | bmp->bitmap.bmWidth, bmp->bitmap.bmHeight); | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_FaultHandler | 
|  | */ | 
|  | static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr ) | 
|  | { | 
|  | BITMAPOBJ *bmp; | 
|  | INT state; | 
|  |  | 
|  | bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC ); | 
|  | if (!bmp) return FALSE; | 
|  |  | 
|  | state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE); | 
|  | if (state != DIB_Status_InSync) { | 
|  | /* no way to tell whether app needs read or write yet, | 
|  | * try read first */ | 
|  | X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE); | 
|  | } else { | 
|  | /* hm, apparently the app must have write access */ | 
|  | X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE); | 
|  | } | 
|  | X11DRV_DIB_Unlock(bmp, TRUE); | 
|  |  | 
|  | GDI_ReleaseObj( (HBITMAP)res ); | 
|  | return TRUE; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_Coerce | 
|  | */ | 
|  | INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy) | 
|  | { | 
|  | X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib; | 
|  | INT ret = DIB_Status_None; | 
|  |  | 
|  | if (dib) { | 
|  | EnterCriticalSection(&(dib->lock)); | 
|  | ret = dib->status; | 
|  | switch (req) { | 
|  | case DIB_Status_GdiMod: | 
|  | /* GDI access - request to draw on pixmap */ | 
|  | switch (dib->status) | 
|  | { | 
|  | default: | 
|  | case DIB_Status_None: | 
|  | dib->p_status = DIB_Status_GdiMod; | 
|  | X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE ); | 
|  | break; | 
|  |  | 
|  | case DIB_Status_GdiMod: | 
|  | TRACE("GdiMod requested in status GdiMod\n" ); | 
|  | break; | 
|  |  | 
|  | case DIB_Status_InSync: | 
|  | TRACE("GdiMod requested in status InSync\n" ); | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS ); | 
|  | dib->status = DIB_Status_GdiMod; | 
|  | dib->p_status = DIB_Status_InSync; | 
|  | break; | 
|  |  | 
|  | case DIB_Status_AuxMod: | 
|  | TRACE("GdiMod requested in status AuxMod\n" ); | 
|  | if (lossy) dib->status = DIB_Status_GdiMod; | 
|  | else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod); | 
|  | dib->p_status = DIB_Status_AuxMod; | 
|  | if (dib->status != DIB_Status_AppMod) { | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS ); | 
|  | break; | 
|  | } | 
|  | /* fall through if copy_aux() had to change to AppMod state */ | 
|  |  | 
|  | case DIB_Status_AppMod: | 
|  | TRACE("GdiMod requested in status AppMod\n" ); | 
|  | if (!lossy) { | 
|  | /* make it readonly to avoid app changing data while we copy */ | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY ); | 
|  | X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE ); | 
|  | } | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS ); | 
|  | dib->p_status = DIB_Status_AppMod; | 
|  | dib->status = DIB_Status_GdiMod; | 
|  | break; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case DIB_Status_InSync: | 
|  | /* App access - request access to read DIB surface */ | 
|  | /* (typically called from signal handler) */ | 
|  | switch (dib->status) | 
|  | { | 
|  | default: | 
|  | case DIB_Status_None: | 
|  | /* shouldn't happen from signal handler */ | 
|  | break; | 
|  |  | 
|  | case DIB_Status_AuxMod: | 
|  | TRACE("InSync requested in status AuxMod\n" ); | 
|  | if (lossy) dib->status = DIB_Status_InSync; | 
|  | else { | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE ); | 
|  | (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync); | 
|  | } | 
|  | if (dib->status != DIB_Status_GdiMod) { | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY ); | 
|  | break; | 
|  | } | 
|  | /* fall through if copy_aux() had to change to GdiMod state */ | 
|  |  | 
|  | case DIB_Status_GdiMod: | 
|  | TRACE("InSync requested in status GdiMod\n" ); | 
|  | if (!lossy) { | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE ); | 
|  | X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE ); | 
|  | } | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY ); | 
|  | dib->status = DIB_Status_InSync; | 
|  | break; | 
|  |  | 
|  | case DIB_Status_InSync: | 
|  | TRACE("InSync requested in status InSync\n" ); | 
|  | /* shouldn't happen from signal handler */ | 
|  | break; | 
|  |  | 
|  | case DIB_Status_AppMod: | 
|  | TRACE("InSync requested in status AppMod\n" ); | 
|  | /* no reason to do anything here, and this | 
|  | * shouldn't happen from signal handler */ | 
|  | break; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case DIB_Status_AppMod: | 
|  | /* App access - request access to write DIB surface */ | 
|  | /* (typically called from signal handler) */ | 
|  | switch (dib->status) | 
|  | { | 
|  | default: | 
|  | case DIB_Status_None: | 
|  | /* shouldn't happen from signal handler */ | 
|  | break; | 
|  |  | 
|  | case DIB_Status_AuxMod: | 
|  | TRACE("AppMod requested in status AuxMod\n" ); | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE ); | 
|  | if (lossy) dib->status = DIB_Status_AppMod; | 
|  | else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod); | 
|  | if (dib->status != DIB_Status_GdiMod) | 
|  | break; | 
|  | /* fall through if copy_aux() had to change to GdiMod state */ | 
|  |  | 
|  | case DIB_Status_GdiMod: | 
|  | TRACE("AppMod requested in status GdiMod\n" ); | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE ); | 
|  | if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE ); | 
|  | dib->status = DIB_Status_AppMod; | 
|  | break; | 
|  |  | 
|  | case DIB_Status_InSync: | 
|  | TRACE("AppMod requested in status InSync\n" ); | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE ); | 
|  | dib->status = DIB_Status_AppMod; | 
|  | break; | 
|  |  | 
|  | case DIB_Status_AppMod: | 
|  | TRACE("AppMod requested in status AppMod\n" ); | 
|  | /* shouldn't happen from signal handler */ | 
|  | break; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case DIB_Status_AuxMod: | 
|  | if (dib->status == DIB_Status_None) { | 
|  | dib->p_status = req; | 
|  | } else { | 
|  | if (dib->status != DIB_Status_AuxMod) | 
|  | dib->p_status = dib->status; | 
|  | dib->status = DIB_Status_AuxMod; | 
|  | } | 
|  | break; | 
|  | /* it is up to the caller to do the copy/conversion, probably | 
|  | * using the return value to decide where to copy from */ | 
|  | } | 
|  | LeaveCriticalSection(&(dib->lock)); | 
|  | } | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_Lock | 
|  | */ | 
|  | INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy) | 
|  | { | 
|  | X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib; | 
|  | INT ret = DIB_Status_None; | 
|  |  | 
|  | if (dib) { | 
|  | TRACE("Locking %p from thread %08lx\n", bmp, GetCurrentThreadId()); | 
|  | EnterCriticalSection(&(dib->lock)); | 
|  | ret = dib->status; | 
|  | if (req != DIB_Status_None) | 
|  | X11DRV_DIB_Coerce(bmp, req, lossy); | 
|  | } | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_Unlock | 
|  | */ | 
|  | void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit) | 
|  | { | 
|  | X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib; | 
|  |  | 
|  | if (dib) { | 
|  | switch (dib->status) | 
|  | { | 
|  | default: | 
|  | case DIB_Status_None: | 
|  | /* in case anyone is wondering, this is the "signal handler doesn't | 
|  | * work" case, where we always have to be ready for app access */ | 
|  | if (commit) { | 
|  | switch (dib->p_status) | 
|  | { | 
|  | case DIB_Status_AuxMod: | 
|  | TRACE("Unlocking and syncing from AuxMod\n" ); | 
|  | (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod); | 
|  | if (dib->status != DIB_Status_None) { | 
|  | dib->p_status = dib->status; | 
|  | dib->status = DIB_Status_None; | 
|  | } | 
|  | if (dib->p_status != DIB_Status_GdiMod) | 
|  | break; | 
|  | /* fall through if copy_aux() had to change to GdiMod state */ | 
|  |  | 
|  | case DIB_Status_GdiMod: | 
|  | TRACE("Unlocking and syncing from GdiMod\n" ); | 
|  | X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE ); | 
|  | break; | 
|  |  | 
|  | default: | 
|  | TRACE("Unlocking without needing to sync\n" ); | 
|  | break; | 
|  | } | 
|  | } | 
|  | else TRACE("Unlocking with no changes\n"); | 
|  | dib->p_status = DIB_Status_None; | 
|  | break; | 
|  |  | 
|  | case DIB_Status_GdiMod: | 
|  | TRACE("Unlocking in status GdiMod\n" ); | 
|  | /* DIB was protected in Coerce */ | 
|  | if (!commit) { | 
|  | /* no commit, revert to InSync if applicable */ | 
|  | if ((dib->p_status == DIB_Status_InSync) || | 
|  | (dib->p_status == DIB_Status_AppMod)) { | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY ); | 
|  | dib->status = DIB_Status_InSync; | 
|  | } | 
|  | } | 
|  | break; | 
|  |  | 
|  | case DIB_Status_InSync: | 
|  | TRACE("Unlocking in status InSync\n" ); | 
|  | /* DIB was already protected in Coerce */ | 
|  | break; | 
|  |  | 
|  | case DIB_Status_AppMod: | 
|  | TRACE("Unlocking in status AppMod\n" ); | 
|  | /* DIB was already protected in Coerce */ | 
|  | /* this case is ordinary only called from the signal handler, | 
|  | * so we don't bother to check for !commit */ | 
|  | break; | 
|  |  | 
|  | case DIB_Status_AuxMod: | 
|  | TRACE("Unlocking in status AuxMod\n" ); | 
|  | if (commit) { | 
|  | /* DIB may need protection now */ | 
|  | if ((dib->p_status == DIB_Status_InSync) || | 
|  | (dib->p_status == DIB_Status_AppMod)) | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS ); | 
|  | } else { | 
|  | /* no commit, revert to previous state */ | 
|  | if (dib->p_status != DIB_Status_None) | 
|  | dib->status = dib->p_status; | 
|  | /* no protections changed */ | 
|  | } | 
|  | dib->p_status = DIB_Status_None; | 
|  | break; | 
|  | } | 
|  | LeaveCriticalSection(&(dib->lock)); | 
|  | TRACE("Unlocked %p\n", bmp); | 
|  | } | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_CoerceDIBSection2 | 
|  | */ | 
|  | INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy) | 
|  | { | 
|  | BITMAPOBJ *bmp; | 
|  | INT ret; | 
|  |  | 
|  | bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC ); | 
|  | if (!bmp) return DIB_Status_None; | 
|  | ret = X11DRV_DIB_Coerce(bmp, req, lossy); | 
|  | GDI_ReleaseObj( hBmp ); | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_LockDIBSection2 | 
|  | */ | 
|  | INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy) | 
|  | { | 
|  | BITMAPOBJ *bmp; | 
|  | INT ret; | 
|  |  | 
|  | bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC ); | 
|  | if (!bmp) return DIB_Status_None; | 
|  | ret = X11DRV_DIB_Lock(bmp, req, lossy); | 
|  | GDI_ReleaseObj( hBmp ); | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_UnlockDIBSection2 | 
|  | */ | 
|  | void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit) | 
|  | { | 
|  | BITMAPOBJ *bmp; | 
|  |  | 
|  | bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC ); | 
|  | if (!bmp) return; | 
|  | X11DRV_DIB_Unlock(bmp, commit); | 
|  | GDI_ReleaseObj( hBmp ); | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_CoerceDIBSection | 
|  | */ | 
|  | INT X11DRV_CoerceDIBSection(DC *dc, INT req, BOOL lossy) | 
|  | { | 
|  | if (!dc) return DIB_Status_None; | 
|  | return X11DRV_CoerceDIBSection2( dc->hBitmap, req, lossy ); | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_LockDIBSection | 
|  | */ | 
|  | INT X11DRV_LockDIBSection(DC *dc, INT req, BOOL lossy) | 
|  | { | 
|  | if (!dc) return DIB_Status_None; | 
|  | if (!(dc->flags & DC_MEMORY)) return DIB_Status_None; | 
|  |  | 
|  | return X11DRV_LockDIBSection2( dc->hBitmap, req, lossy ); | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_UnlockDIBSection | 
|  | */ | 
|  | void X11DRV_UnlockDIBSection(DC *dc, BOOL commit) | 
|  | { | 
|  | if (!dc) return; | 
|  | if (!(dc->flags & DC_MEMORY)) return; | 
|  |  | 
|  | X11DRV_UnlockDIBSection2( dc->hBitmap, commit ); | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_CreateDIBSection16 | 
|  | */ | 
|  | HBITMAP16 X11DRV_DIB_CreateDIBSection16( | 
|  | DC *dc, BITMAPINFO *bmi, UINT16 usage, | 
|  | SEGPTR *bits, HANDLE section, | 
|  | DWORD offset, DWORD ovr_pitch) | 
|  | { | 
|  | HBITMAP res = X11DRV_DIB_CreateDIBSection(dc, bmi, usage, NULL, | 
|  | section, offset, ovr_pitch); | 
|  | if ( res ) | 
|  | { | 
|  | BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC); | 
|  | if ( bmp && bmp->dib ) | 
|  | { | 
|  | DIBSECTION *dib = bmp->dib; | 
|  | INT height = dib->dsBm.bmHeight >= 0 ? | 
|  | dib->dsBm.bmHeight : -dib->dsBm.bmHeight; | 
|  | /* same as above - only use biSizeImage as the correct size if it a | 
|  | compressed image and it's currently non-zero.  In other cases, use | 
|  | width * height as the value. */ | 
|  | INT size = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB | 
|  | ? dib->dsBmih.biSizeImage | 
|  | : dib->dsBm.bmWidthBytes * height; | 
|  | if ( dib->dsBm.bmBits ) | 
|  | { | 
|  | ((X11DRV_DIBSECTION *) bmp->dib)->selector = | 
|  | SELECTOR_AllocBlock( dib->dsBm.bmBits, size, WINE_LDT_FLAGS_DATA ); | 
|  | } | 
|  | TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n", | 
|  | dib->dsBm.bmBits, size, ((X11DRV_DIBSECTION *) bmp->dib)->selector, | 
|  | MAKESEGPTR(((X11DRV_DIBSECTION *) bmp->dib)->selector, 0)); | 
|  | if ( bits ) | 
|  | *bits = MAKESEGPTR( ((X11DRV_DIBSECTION *) bmp->dib)->selector, 0 ); | 
|  | } | 
|  | if (bmp) GDI_ReleaseObj( res ); | 
|  | } | 
|  |  | 
|  | return res; | 
|  | } | 
|  |  | 
|  | #ifdef HAVE_LIBXXSHM | 
|  | /*********************************************************************** | 
|  | *           X11DRV_XShmErrorHandler | 
|  | * | 
|  | */ | 
|  | static int XShmErrorHandler(Display *dpy, XErrorEvent *event) | 
|  | { | 
|  | XShmErrorFlag = 1; | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_XShmCreateImage | 
|  | * | 
|  | */ | 
|  | static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp, | 
|  | XShmSegmentInfo* shminfo) | 
|  | { | 
|  | int (*WineXHandler)(Display *, XErrorEvent *); | 
|  | XImage *image; | 
|  |  | 
|  | wine_tsx11_lock(); | 
|  | image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height); | 
|  | if (image) | 
|  | { | 
|  | shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height, | 
|  | IPC_CREAT|0700); | 
|  | if( shminfo->shmid != -1 ) | 
|  | { | 
|  | shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0); | 
|  | if( shminfo->shmaddr != (char*)-1 ) | 
|  | { | 
|  | shminfo->readOnly = FALSE; | 
|  | if( XShmAttach( gdi_display, shminfo ) != 0) | 
|  | { | 
|  | /* Reset the error flag */ | 
|  | XShmErrorFlag = 0; | 
|  | WineXHandler = XSetErrorHandler(XShmErrorHandler); | 
|  | XSync( gdi_display, 0 ); | 
|  |  | 
|  | if (!XShmErrorFlag) | 
|  | { | 
|  | shmctl(shminfo->shmid, IPC_RMID, 0); | 
|  |  | 
|  | XSetErrorHandler(WineXHandler); | 
|  | wine_tsx11_unlock(); | 
|  | return image; /* Success! */ | 
|  | } | 
|  | /* An error occured */ | 
|  | XShmErrorFlag = 0; | 
|  | XSetErrorHandler(WineXHandler); | 
|  | } | 
|  | shmdt(shminfo->shmaddr); | 
|  | } | 
|  | shmctl(shminfo->shmid, IPC_RMID, 0); | 
|  | } | 
|  | XFlush(gdi_display); | 
|  | XDestroyImage(image); | 
|  | image = NULL; | 
|  | } | 
|  | wine_tsx11_unlock(); | 
|  | return image; | 
|  | } | 
|  | #endif /* HAVE_LIBXXSHM */ | 
|  |  | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_CreateDIBSection | 
|  | */ | 
|  | HBITMAP X11DRV_DIB_CreateDIBSection( | 
|  | DC *dc, BITMAPINFO *bmi, UINT usage, | 
|  | LPVOID *bits, HANDLE section, | 
|  | DWORD offset, DWORD ovr_pitch) | 
|  | { | 
|  | HBITMAP res = 0; | 
|  | BITMAPOBJ *bmp = NULL; | 
|  | X11DRV_DIBSECTION *dib = NULL; | 
|  | int *colorMap = NULL; | 
|  | int nColorMap; | 
|  |  | 
|  | /* Fill BITMAP32 structure with DIB data */ | 
|  | BITMAPINFOHEADER *bi = &bmi->bmiHeader; | 
|  | INT effHeight, totalSize; | 
|  | BITMAP bm; | 
|  | LPVOID mapBits = NULL; | 
|  |  | 
|  | TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n", | 
|  | bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount, | 
|  | bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB"); | 
|  |  | 
|  | effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight; | 
|  | bm.bmType = 0; | 
|  | bm.bmWidth = bi->biWidth; | 
|  | bm.bmHeight = effHeight; | 
|  | bm.bmWidthBytes = ovr_pitch ? ovr_pitch | 
|  | : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount); | 
|  | bm.bmPlanes = bi->biPlanes; | 
|  | bm.bmBitsPixel = bi->biBitCount; | 
|  | bm.bmBits = NULL; | 
|  |  | 
|  | /* Get storage location for DIB bits.  Only use biSizeImage if it's valid and | 
|  | we're dealing with a compressed bitmap.  Otherwise, use width * height. */ | 
|  | totalSize = bi->biSizeImage && bi->biCompression != BI_RGB | 
|  | ? bi->biSizeImage : bm.bmWidthBytes * effHeight; | 
|  |  | 
|  | if (section) | 
|  | { | 
|  | SYSTEM_INFO SystemInfo; | 
|  | DWORD mapOffset; | 
|  | INT mapSize; | 
|  |  | 
|  | GetSystemInfo( &SystemInfo ); | 
|  | mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity); | 
|  | mapSize = totalSize + (offset - mapOffset); | 
|  | mapBits = MapViewOfFile( section, | 
|  | FILE_MAP_ALL_ACCESS, | 
|  | 0L, | 
|  | mapOffset, | 
|  | mapSize ); | 
|  | bm.bmBits = (char *)mapBits + (offset - mapOffset); | 
|  | } | 
|  | else if (ovr_pitch && offset) | 
|  | bm.bmBits = (LPVOID) offset; | 
|  | else { | 
|  | offset = 0; | 
|  | bm.bmBits = VirtualAlloc(NULL, totalSize, | 
|  | MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); | 
|  | } | 
|  |  | 
|  | /* Create Color Map */ | 
|  | if (bm.bmBits && bm.bmBitsPixel <= 8) | 
|  | colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? dc : NULL, | 
|  | usage, bm.bmBitsPixel, bmi, &nColorMap ); | 
|  |  | 
|  | /* Allocate Memory for DIB and fill structure */ | 
|  | if (bm.bmBits) | 
|  | dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION)); | 
|  | if (dib) | 
|  | { | 
|  | dib->dibSection.dsBm = bm; | 
|  | dib->dibSection.dsBmih = *bi; | 
|  | dib->dibSection.dsBmih.biSizeImage = totalSize; | 
|  |  | 
|  | /* Set dsBitfields values */ | 
|  | if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8) | 
|  | { | 
|  | dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0; | 
|  | } | 
|  | else switch( bi->biBitCount ) | 
|  | { | 
|  | case 16: | 
|  | dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00; | 
|  | dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0; | 
|  | dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f; | 
|  | break; | 
|  |  | 
|  | case 24: | 
|  | dib->dibSection.dsBitfields[0] = 0xff; | 
|  | dib->dibSection.dsBitfields[1] = 0xff00; | 
|  | dib->dibSection.dsBitfields[2] = 0xff0000; | 
|  | break; | 
|  |  | 
|  | case 32: | 
|  | dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff; | 
|  | dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00; | 
|  | dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000; | 
|  | break; | 
|  | } | 
|  | dib->dibSection.dshSection = section; | 
|  | dib->dibSection.dsOffset = offset; | 
|  |  | 
|  | dib->status    = DIB_Status_None; | 
|  | dib->selector  = 0; | 
|  |  | 
|  | dib->nColorMap = nColorMap; | 
|  | dib->colorMap  = colorMap; | 
|  | } | 
|  |  | 
|  | /* Create Device Dependent Bitmap and add DIB pointer */ | 
|  | if (dib) | 
|  | { | 
|  | res = CreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage); | 
|  | if (res) | 
|  | { | 
|  | bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC); | 
|  | if (bmp) | 
|  | { | 
|  | bmp->dib = (DIBSECTION *) dib; | 
|  | /* HACK for now */ | 
|  | if(!bmp->physBitmap) | 
|  | X11DRV_CreateBitmap(res); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Create XImage */ | 
|  | if (dib && bmp) | 
|  | { | 
|  | #ifdef HAVE_LIBXXSHM | 
|  | if (TSXShmQueryExtension(gdi_display) && | 
|  | (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight, | 
|  | bmp->bitmap.bmBitsPixel, &dib->shminfo )) ) | 
|  | { | 
|  | ; /* Created Image */ | 
|  | } else { | 
|  | dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel ); | 
|  | dib->shminfo.shmid = -1; | 
|  | } | 
|  | #else | 
|  | dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel ); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | /* Clean up in case of errors */ | 
|  | if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap)) | 
|  | { | 
|  | TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n", | 
|  | res, bmp, dib, bm.bmBits); | 
|  | if (bm.bmBits) | 
|  | { | 
|  | if (section) | 
|  | UnmapViewOfFile(mapBits), bm.bmBits = NULL; | 
|  | else if (!offset) | 
|  | VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL; | 
|  | } | 
|  |  | 
|  | if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; } | 
|  | if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; } | 
|  | if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; } | 
|  | if (bmp) { GDI_ReleaseObj(res); bmp = NULL; } | 
|  | if (res) { DeleteObject(res); res = 0; } | 
|  | } | 
|  | else if (bm.bmBits) | 
|  | { | 
|  | /* Install fault handler, if possible */ | 
|  | InitializeCriticalSection(&(dib->lock)); | 
|  | if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res)) | 
|  | { | 
|  | if (section || offset) | 
|  | { | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE ); | 
|  | if (dib) dib->status = DIB_Status_AppMod; | 
|  | } | 
|  | else | 
|  | { | 
|  | X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY ); | 
|  | if (dib) dib->status = DIB_Status_InSync; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Return BITMAP handle and storage location */ | 
|  | if (bmp) GDI_ReleaseObj(res); | 
|  | if (bm.bmBits && bits) *bits = bm.bmBits; | 
|  | return res; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_DeleteDIBSection | 
|  | */ | 
|  | void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp) | 
|  | { | 
|  | X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib; | 
|  |  | 
|  | if (dib->image) | 
|  | { | 
|  | #ifdef HAVE_LIBXXSHM | 
|  | if (dib->shminfo.shmid != -1) | 
|  | { | 
|  | TSXShmDetach (gdi_display, &(dib->shminfo)); | 
|  | XDestroyImage (dib->image); | 
|  | shmdt (dib->shminfo.shmaddr); | 
|  | dib->shminfo.shmid = -1; | 
|  | } | 
|  | else | 
|  | #endif | 
|  | XDestroyImage( dib->image ); | 
|  | } | 
|  |  | 
|  | if (dib->colorMap) | 
|  | HeapFree(GetProcessHeap(), 0, dib->colorMap); | 
|  |  | 
|  | if (dib->selector) SELECTOR_FreeBlock( dib->selector ); | 
|  | DeleteCriticalSection(&(dib->lock)); | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_SetDIBColorTable | 
|  | */ | 
|  | UINT X11DRV_DIB_SetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, const RGBQUAD *colors) | 
|  | { | 
|  | X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib; | 
|  |  | 
|  | if (dib && dib->colorMap) { | 
|  | X11DRV_DIB_GenColorMap( dc, dib->colorMap, DIB_RGB_COLORS, dib->dibSection.dsBm.bmBitsPixel, | 
|  | TRUE, colors, start, count + start ); | 
|  | return count; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *           X11DRV_DIB_GetDIBColorTable | 
|  | */ | 
|  | UINT X11DRV_DIB_GetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, RGBQUAD *colors) | 
|  | { | 
|  | X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib; | 
|  |  | 
|  | if (dib && dib->colorMap) { | 
|  | int i, end = count + start; | 
|  | if (end > dib->nColorMap) end = dib->nColorMap; | 
|  | for (i = start; i < end; i++,colors++) { | 
|  | COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] ); | 
|  | colors->rgbBlue  = GetBValue(col); | 
|  | colors->rgbGreen = GetGValue(col); | 
|  | colors->rgbRed   = GetRValue(col); | 
|  | colors->rgbReserved = 0; | 
|  | } | 
|  | return end-start; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  | /************************************************************************** | 
|  | *	        X11DRV_DIB_CreateDIBFromPixmap | 
|  | * | 
|  | *  Allocates a packed DIB and copies the Pixmap data into it. | 
|  | *  If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion. | 
|  | */ | 
|  | HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap) | 
|  | { | 
|  | HBITMAP hBmp = 0; | 
|  | BITMAPOBJ *pBmp = NULL; | 
|  | HGLOBAL hPackedDIB = 0; | 
|  |  | 
|  | /* Allocates an HBITMAP which references the Pixmap passed to us */ | 
|  | hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap); | 
|  | if (!hBmp) | 
|  | { | 
|  | TRACE("\tCould not create bitmap header for Pixmap\n"); | 
|  | goto END; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Create a packed DIB from the Pixmap wrapper bitmap created above. | 
|  | * A packed DIB contains a BITMAPINFO structure followed immediately by | 
|  | * an optional color palette and the pixel data. | 
|  | */ | 
|  | hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp); | 
|  |  | 
|  | /* Get a pointer to the BITMAPOBJ structure */ | 
|  | pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC ); | 
|  |  | 
|  | /* We can now get rid of the HBITMAP wrapper we created earlier. | 
|  | * Note: Simply calling DeleteObject will free the embedded Pixmap as well. | 
|  | */ | 
|  | if (!bDeletePixmap) | 
|  | { | 
|  | /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */ | 
|  | pBmp->physBitmap = NULL; | 
|  | pBmp->funcs = NULL; | 
|  | } | 
|  | GDI_ReleaseObj( hBmp ); | 
|  | DeleteObject(hBmp); | 
|  |  | 
|  | END: | 
|  | TRACE("\tReturning packed DIB %x\n", hPackedDIB); | 
|  | return hPackedDIB; | 
|  | } | 
|  |  | 
|  |  | 
|  | /************************************************************************** | 
|  | *	           X11DRV_DIB_CreatePixmapFromDIB | 
|  | * | 
|  | *    Creates a Pixmap from a packed DIB | 
|  | */ | 
|  | Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc ) | 
|  | { | 
|  | Pixmap pixmap = None; | 
|  | HBITMAP hBmp = 0; | 
|  | BITMAPOBJ *pBmp = NULL; | 
|  | LPBYTE pPackedDIB = NULL; | 
|  | LPBITMAPINFO pbmi = NULL; | 
|  | LPBITMAPINFOHEADER pbmiHeader = NULL; | 
|  | LPBYTE pbits = NULL; | 
|  |  | 
|  | /* Get a pointer to the packed DIB's data  */ | 
|  | pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB); | 
|  | pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB; | 
|  | pbmi = (LPBITMAPINFO)pPackedDIB; | 
|  | pbits = (LPBYTE)(pPackedDIB | 
|  | + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS )); | 
|  |  | 
|  | /* Create a DDB from the DIB */ | 
|  |  | 
|  | hBmp = CreateDIBitmap(hdc, | 
|  | pbmiHeader, | 
|  | CBM_INIT, | 
|  | (LPVOID)pbits, | 
|  | pbmi, | 
|  | DIB_RGB_COLORS); | 
|  |  | 
|  | GlobalUnlock(hPackedDIB); | 
|  |  | 
|  | TRACE("CreateDIBitmap returned %x\n", hBmp); | 
|  |  | 
|  | /* Retrieve the internal Pixmap from the DDB */ | 
|  |  | 
|  | pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC ); | 
|  |  | 
|  | pixmap = (Pixmap)pBmp->physBitmap; | 
|  | /* clear the physBitmap so that we can steal its pixmap */ | 
|  | pBmp->physBitmap = NULL; | 
|  | pBmp->funcs = NULL; | 
|  |  | 
|  | /* Delete the DDB we created earlier now that we have stolen its pixmap */ | 
|  | GDI_ReleaseObj( hBmp ); | 
|  | DeleteObject(hBmp); | 
|  |  | 
|  | TRACE("\tReturning Pixmap %ld\n", pixmap); | 
|  | return pixmap; | 
|  | } |