2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <X11/extensions/XShm.h>
26 # ifdef HAVE_SYS_SHM_H
29 # ifdef HAVE_SYS_IPC_H
32 #endif /* defined(HAVE_LIBXXSHM) */
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
44 WINE_DECLARE_DEBUG_CHANNEL(x11drv);
46 static int ximageDepthTable[32];
48 /* This structure holds the arguments for DIB_SetImageBits() */
51 X11DRV_PDEVICE *physDev;
54 PALETTEENTRY *palentry;
76 } X11DRV_DIB_IMAGEBITS_DESCR;
81 RLE_EOL = 0, /* End of line */
82 RLE_END = 1, /* End of bitmap */
83 RLE_DELTA = 2 /* Delta */
87 static INT X11DRV_DIB_Coerce(X_PHYSBITMAP *,INT,BOOL);
88 static INT X11DRV_DIB_Lock(X_PHYSBITMAP *,INT,BOOL);
89 static void X11DRV_DIB_Unlock(X_PHYSBITMAP *,BOOL);
92 Some of the following helper functions are duplicated in
96 /***********************************************************************
97 * X11DRV_DIB_GetXImageWidthBytes
99 * Return the width of an X image in bytes
101 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
103 if (!depth || depth > 32) goto error;
105 if (!ximageDepthTable[depth-1])
107 XImage *testimage = XCreateImage( gdi_display, visual, depth,
108 ZPixmap, 0, NULL, 1, 1, 32, 20 );
111 ximageDepthTable[depth-1] = testimage->bits_per_pixel;
112 XDestroyImage( testimage );
114 else ximageDepthTable[depth-1] = -1;
116 if (ximageDepthTable[depth-1] != -1)
117 return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
120 WARN( "(%d): Unsupported depth\n", depth );
125 /***********************************************************************
126 * X11DRV_DIB_GetDIBWidthBytes
128 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
130 static int X11DRV_DIB_GetDIBWidthBytes( int width, int depth )
136 case 1: words = (width + 31) / 32; break;
137 case 4: words = (width + 7) / 8; break;
138 case 8: words = (width + 3) / 4; break;
140 case 16: words = (width + 1) / 2; break;
141 case 24: words = (width * 3 + 3) / 4; break;
143 WARN("(%d): Unsupported depth\n", depth );
152 /***********************************************************************
153 * X11DRV_DIB_GetDIBImageBytes
155 * Return the number of bytes used to hold the image in a DIB bitmap.
157 static int X11DRV_DIB_GetDIBImageBytes( int width, int height, int depth )
159 return X11DRV_DIB_GetDIBWidthBytes( width, depth ) * abs( height );
163 /***********************************************************************
164 * X11DRV_DIB_BitmapInfoSize
166 * Return the size of the bitmap info structure including color table.
168 int X11DRV_DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
172 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
174 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
175 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
176 return sizeof(BITMAPCOREHEADER) + colors *
177 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
179 else /* assume BITMAPINFOHEADER */
181 colors = info->bmiHeader.biClrUsed;
182 if (!colors && (info->bmiHeader.biBitCount <= 8))
183 colors = 1 << info->bmiHeader.biBitCount;
184 return sizeof(BITMAPINFOHEADER) + colors *
185 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
190 /***********************************************************************
191 * X11DRV_DIB_CreateXImage
195 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
201 width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
202 image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
203 calloc( height, width_bytes ),
204 width, height, 32, width_bytes );
210 /***********************************************************************
211 * DIB_GetBitmapInfoEx
213 * Get the info from a bitmap header.
214 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
216 static int DIB_GetBitmapInfoEx( const BITMAPINFOHEADER *header, LONG *width,
217 LONG *height, WORD *planes, WORD *bpp,
218 WORD *compr, DWORD *size )
220 if (header->biSize == sizeof(BITMAPCOREHEADER))
222 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
223 *width = core->bcWidth;
224 *height = core->bcHeight;
225 *planes = core->bcPlanes;
226 *bpp = core->bcBitCount;
231 if (header->biSize >= sizeof(BITMAPINFOHEADER))
233 *width = header->biWidth;
234 *height = header->biHeight;
235 *planes = header->biPlanes;
236 *bpp = header->biBitCount;
237 *compr = header->biCompression;
238 *size = header->biSizeImage;
241 ERR("(%ld): unknown/wrong size for header\n", header->biSize );
246 /***********************************************************************
249 * Get the info from a bitmap header.
250 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
252 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
253 LONG *height, WORD *bpp, WORD *compr )
258 return DIB_GetBitmapInfoEx( header, width, height, &planes, bpp, compr, &size);
262 /***********************************************************************
263 * X11DRV_DIB_GenColorMap
265 * Fills the color map of a bitmap palette. Should not be called
266 * for a >8-bit deep bitmap.
268 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
269 WORD coloruse, WORD depth, BOOL quads,
270 const void *colorPtr, int start, int end )
274 if (coloruse == DIB_RGB_COLORS)
278 const RGBQUAD * rgb = (const RGBQUAD *)colorPtr;
280 if (depth == 1) /* Monochrome */
281 for (i = start; i < end; i++, rgb++)
282 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
283 rgb->rgbBlue > 255*3/2);
285 for (i = start; i < end; i++, rgb++)
286 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbRed,
292 const RGBTRIPLE * rgb = (const RGBTRIPLE *)colorPtr;
294 if (depth == 1) /* Monochrome */
295 for (i = start; i < end; i++, rgb++)
296 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
297 rgb->rgbtBlue > 255*3/2);
299 for (i = start; i < end; i++, rgb++)
300 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbtRed,
305 else /* DIB_PAL_COLORS */
308 const WORD * index = (const WORD *)colorPtr;
310 for (i = start; i < end; i++, index++)
311 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(*index) );
313 for (i = start; i < end; i++)
314 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(i) );
321 /***********************************************************************
322 * X11DRV_DIB_BuildColorMap
324 * Build the color map from the bitmap palette. Should not be called
325 * for a >8-bit deep bitmap.
327 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
328 const BITMAPINFO *info, int *nColors )
332 const void *colorPtr;
335 isInfo = info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER);
339 colors = info->bmiHeader.biClrUsed;
340 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
344 colors = 1 << ((const BITMAPCOREHEADER *)info)->bcBitCount;
347 colorPtr = (const BYTE*) info + (WORD) info->bmiHeader.biSize;
351 ERR("called with >256 colors!\n");
355 /* just so CopyDIBSection doesn't have to create an identity palette */
356 if (coloruse == (WORD)-1) colorPtr = NULL;
358 if (!(colorMapping = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(int) )))
362 return X11DRV_DIB_GenColorMap( physDev, colorMapping, coloruse, depth,
363 isInfo, colorPtr, 0, colors);
366 /***********************************************************************
367 * X11DRV_DIB_BuildColorTable
369 * Build the dib color table. This either keeps a copy of the bmiColors array if
370 * usage is DIB_RGB_COLORS, or looks up the palette indicies if usage is
372 * Should not be called for a >8-bit deep bitmap.
374 static RGBQUAD *X11DRV_DIB_BuildColorTable( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
375 const BITMAPINFO *info )
380 BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
384 colors = 1 << ((BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
388 colors = info->bmiHeader.biClrUsed;
389 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
393 ERR("called with >256 colors!\n");
397 if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) )))
400 if(coloruse == DIB_RGB_COLORS)
404 /* Convert RGBTRIPLEs to RGBQUADs */
405 for (i=0; i < colors; i++)
407 colorTable[i].rgbRed = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
408 colorTable[i].rgbGreen = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
409 colorTable[i].rgbBlue = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
410 colorTable[i].rgbReserved = 0;
415 memcpy(colorTable, (LPBYTE) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
420 HPALETTE hpal = GetCurrentObject(physDev->hdc, OBJ_PAL);
421 PALETTEENTRY * pal_ents;
422 WORD *index = (WORD*) ((LPBYTE) info + (WORD) info->bmiHeader.biSize);
423 int logcolors, entry;
425 logcolors = GetPaletteEntries( hpal, 0, 0, NULL );
426 pal_ents = HeapAlloc(GetProcessHeap(), 0, logcolors * sizeof(*pal_ents));
427 logcolors = GetPaletteEntries( hpal, 0, logcolors, pal_ents );
429 for(i = 0; i < colors; i++, index++)
431 entry = *index % logcolors;
432 colorTable[i].rgbRed = pal_ents[entry].peRed;
433 colorTable[i].rgbGreen = pal_ents[entry].peGreen;
434 colorTable[i].rgbBlue = pal_ents[entry].peBlue;
435 colorTable[i].rgbReserved = 0;
438 HeapFree(GetProcessHeap(), 0, pal_ents);
444 /***********************************************************************
445 * X11DRV_DIB_MapColor
447 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
451 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
454 for (color = 0; color < nPhysMap; color++)
455 if (physMap[color] == phys)
458 WARN("Strange color %08x\n", phys);
463 /*********************************************************************
464 * X11DRV_DIB_GetNearestIndex
466 * Helper for X11DRV_DIB_GetDIBits.
467 * Returns the nearest colour table index for a given RGB.
468 * Nearest is defined by minimizing the sum of the squares.
470 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
472 INT i, best = -1, diff, bestdiff = -1;
475 for(color = colormap, i = 0; i < numColors; color++, i++) {
476 diff = (r - color->rgbRed) * (r - color->rgbRed) +
477 (g - color->rgbGreen) * (g - color->rgbGreen) +
478 (b - color->rgbBlue) * (b - color->rgbBlue);
481 if(best == -1 || diff < bestdiff) {
488 /*********************************************************************
489 * X11DRV_DIB_MaskToShift
491 * Helper for X11DRV_DIB_GetDIBits.
492 * Returns the by how many bits to shift a given color so that it is
493 * in the proper position.
495 INT X11DRV_DIB_MaskToShift(DWORD mask)
503 while ((mask&1)==0) {
510 /***********************************************************************
511 * X11DRV_DIB_SetImageBits_1
513 * SetDIBits for a 1-bit deep DIB.
515 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
516 DWORD srcwidth, DWORD dstwidth, int left,
517 int *colors, XImage *bmpImage, DWORD linebytes)
526 srcbits = srcbits + linebytes * (lines - 1);
527 linebytes = -linebytes;
530 if ((extra = (left & 7)) != 0) {
534 srcbits += left >> 3;
535 width = min(srcwidth, dstwidth);
537 /* ==== pal 1 dib -> any bmp format ==== */
538 for (h = lines-1; h >=0; h--) {
540 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
541 for (i = width/8, x = left; i > 0; i--) {
543 XPutPixel( bmpImage, x++, h, colors[ srcval >> 7] );
544 XPutPixel( bmpImage, x++, h, colors[(srcval >> 6) & 1] );
545 XPutPixel( bmpImage, x++, h, colors[(srcval >> 5) & 1] );
546 XPutPixel( bmpImage, x++, h, colors[(srcval >> 4) & 1] );
547 XPutPixel( bmpImage, x++, h, colors[(srcval >> 3) & 1] );
548 XPutPixel( bmpImage, x++, h, colors[(srcval >> 2) & 1] );
549 XPutPixel( bmpImage, x++, h, colors[(srcval >> 1) & 1] );
550 XPutPixel( bmpImage, x++, h, colors[ srcval & 1] );
556 case 7: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
557 case 6: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
558 case 5: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
559 case 4: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
560 case 3: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
561 case 2: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
562 case 1: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]);
565 srcbits += linebytes;
569 /***********************************************************************
570 * X11DRV_DIB_GetImageBits_1
572 * GetDIBits for a 1-bit deep DIB.
574 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
575 DWORD dstwidth, DWORD srcwidth,
576 RGBQUAD *colors, PALETTEENTRY *srccolors,
577 XImage *bmpImage, DWORD linebytes )
580 int h, width = min(dstwidth, srcwidth);
584 dstbits = dstbits + linebytes * (lines - 1);
585 linebytes = -linebytes;
588 switch (bmpImage->depth)
592 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
593 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
596 for (h=lines-1; h>=0; h--) {
600 for (x=0; x<width; x++) {
602 srcval=srccolors[XGetPixel(bmpImage, x, h)];
603 dstval|=(X11DRV_DIB_GetNearestIndex
607 srcval.peBlue) << (7 - (x & 7)));
616 dstbits += linebytes;
624 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
625 /* ==== pal 8 bmp -> pal 1 dib ==== */
627 const BYTE* srcpixel;
630 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
632 for (h=0; h<lines; h++) {
637 for (x=0; x<width; x++) {
639 srcval=srccolors[(int)*srcpixel++];
640 dstval|=(X11DRV_DIB_GetNearestIndex
644 srcval.peBlue) << (7-(x&7)) );
653 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
654 dstbits += linebytes;
665 const WORD* srcpixel;
668 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
670 if (bmpImage->green_mask==0x03e0) {
671 if (bmpImage->red_mask==0x7c00) {
672 /* ==== rgb 555 bmp -> pal 1 dib ==== */
673 for (h=0; h<lines; h++) {
678 for (x=0; x<width; x++) {
681 dstval|=(X11DRV_DIB_GetNearestIndex
683 ((srcval >> 7) & 0xf8) | /* r */
684 ((srcval >> 12) & 0x07),
685 ((srcval >> 2) & 0xf8) | /* g */
686 ((srcval >> 7) & 0x07),
687 ((srcval << 3) & 0xf8) | /* b */
688 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
697 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
698 dstbits += linebytes;
700 } else if (bmpImage->blue_mask==0x7c00) {
701 /* ==== bgr 555 bmp -> pal 1 dib ==== */
702 for (h=0; h<lines; h++) {
707 for (x=0; x<width; x++) {
710 dstval|=(X11DRV_DIB_GetNearestIndex
712 ((srcval << 3) & 0xf8) | /* r */
713 ((srcval >> 2) & 0x07),
714 ((srcval >> 2) & 0xf8) | /* g */
715 ((srcval >> 7) & 0x07),
716 ((srcval >> 7) & 0xf8) | /* b */
717 ((srcval >> 12) & 0x07) ) << (7-(x&7)) );
726 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
727 dstbits += linebytes;
732 } else if (bmpImage->green_mask==0x07e0) {
733 if (bmpImage->red_mask==0xf800) {
734 /* ==== rgb 565 bmp -> pal 1 dib ==== */
735 for (h=0; h<lines; h++) {
740 for (x=0; x<width; x++) {
743 dstval|=(X11DRV_DIB_GetNearestIndex
745 ((srcval >> 8) & 0xf8) | /* r */
746 ((srcval >> 13) & 0x07),
747 ((srcval >> 3) & 0xfc) | /* g */
748 ((srcval >> 9) & 0x03),
749 ((srcval << 3) & 0xf8) | /* b */
750 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
759 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
760 dstbits += linebytes;
762 } else if (bmpImage->blue_mask==0xf800) {
763 /* ==== bgr 565 bmp -> pal 1 dib ==== */
764 for (h=0; h<lines; h++) {
769 for (x=0; x<width; x++) {
772 dstval|=(X11DRV_DIB_GetNearestIndex
774 ((srcval << 3) & 0xf8) | /* r */
775 ((srcval >> 2) & 0x07),
776 ((srcval >> 3) & 0xfc) | /* g */
777 ((srcval >> 9) & 0x03),
778 ((srcval >> 8) & 0xf8) | /* b */
779 ((srcval >> 13) & 0x07) ) << (7-(x&7)) );
788 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
789 dstbits += linebytes;
808 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
809 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
811 if (bmpImage->green_mask!=0x00ff00 ||
812 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
814 } else if (bmpImage->blue_mask==0xff) {
815 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
816 for (h=0; h<lines; h++) {
821 for (x=0; x<width; x++) {
822 dstval|=(X11DRV_DIB_GetNearestIndex
826 srcbyte[0]) << (7-(x&7)) );
827 srcbyte+=bytes_per_pixel;
836 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
837 dstbits += linebytes;
840 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
841 for (h=0; h<lines; h++) {
846 for (x=0; x<width; x++) {
847 dstval|=(X11DRV_DIB_GetNearestIndex
851 srcbyte[2]) << (7-(x&7)) );
852 srcbyte+=bytes_per_pixel;
861 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
862 dstbits += linebytes;
872 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
874 /* ==== any bmp format -> pal 1 dib ==== */
875 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
876 bmpImage->bits_per_pixel, bmpImage->red_mask,
877 bmpImage->green_mask, bmpImage->blue_mask );
879 for (h=lines-1; h>=0; h--) {
883 for (x=0; x<width; x++) {
884 dstval|=(XGetPixel( bmpImage, x, h) >= white) << (7 - (x&7));
893 dstbits += linebytes;
900 /***********************************************************************
901 * X11DRV_DIB_SetImageBits_4
903 * SetDIBits for a 4-bit deep DIB.
905 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
906 DWORD srcwidth, DWORD dstwidth, int left,
907 int *colors, XImage *bmpImage, DWORD linebytes)
915 srcbits = srcbits + linebytes * (lines - 1);
916 linebytes = -linebytes;
923 srcbits += left >> 1;
924 width = min(srcwidth, dstwidth);
926 /* ==== pal 4 dib -> any bmp format ==== */
927 for (h = lines-1; h >= 0; h--) {
929 for (i = width/2, x = left; i > 0; i--) {
930 BYTE srcval=*srcbyte++;
931 XPutPixel( bmpImage, x++, h, colors[srcval >> 4] );
932 XPutPixel( bmpImage, x++, h, colors[srcval & 0x0f] );
935 XPutPixel( bmpImage, x, h, colors[*srcbyte >> 4] );
936 srcbits += linebytes;
942 /***********************************************************************
943 * X11DRV_DIB_GetImageBits_4
945 * GetDIBits for a 4-bit deep DIB.
947 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
948 DWORD srcwidth, DWORD dstwidth,
949 RGBQUAD *colors, PALETTEENTRY *srccolors,
950 XImage *bmpImage, DWORD linebytes )
953 int h, width = min(srcwidth, dstwidth);
959 dstbits = dstbits + ( linebytes * (lines-1) );
960 linebytes = -linebytes;
965 switch (bmpImage->depth) {
968 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
969 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
972 for (h = lines-1; h >= 0; h--) {
976 for (x = 0; x < width; x++) {
978 srcval=srccolors[XGetPixel(bmpImage, x, h)];
979 dstval|=(X11DRV_DIB_GetNearestIndex
983 srcval.peBlue) << (4-((x&1)<<2)));
992 dstbits += linebytes;
1000 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1001 /* ==== pal 8 bmp -> pal 4 dib ==== */
1002 const void* srcbits;
1003 const BYTE *srcpixel;
1006 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1007 for (h=0; h<lines; h++) {
1012 for (x=0; x<width; x++) {
1013 PALETTEENTRY srcval;
1014 srcval = srccolors[(int)*srcpixel++];
1015 dstval|=(X11DRV_DIB_GetNearestIndex
1019 srcval.peBlue) << (4*(1-(x&1))) );
1028 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1029 dstbits += linebytes;
1039 const void* srcbits;
1040 const WORD* srcpixel;
1043 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1045 if (bmpImage->green_mask==0x03e0) {
1046 if (bmpImage->red_mask==0x7c00) {
1047 /* ==== rgb 555 bmp -> pal 4 dib ==== */
1048 for (h=0; h<lines; h++) {
1053 for (x=0; x<width; x++) {
1056 dstval|=(X11DRV_DIB_GetNearestIndex
1058 ((srcval >> 7) & 0xf8) | /* r */
1059 ((srcval >> 12) & 0x07),
1060 ((srcval >> 2) & 0xf8) | /* g */
1061 ((srcval >> 7) & 0x07),
1062 ((srcval << 3) & 0xf8) | /* b */
1063 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
1072 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1073 dstbits += linebytes;
1075 } else if (bmpImage->blue_mask==0x7c00) {
1076 /* ==== bgr 555 bmp -> pal 4 dib ==== */
1077 for (h=0; h<lines; h++) {
1082 for (x=0; x<width; x++) {
1085 dstval|=(X11DRV_DIB_GetNearestIndex
1087 ((srcval << 3) & 0xf8) | /* r */
1088 ((srcval >> 2) & 0x07),
1089 ((srcval >> 2) & 0xf8) | /* g */
1090 ((srcval >> 7) & 0x07),
1091 ((srcval >> 7) & 0xf8) | /* b */
1092 ((srcval >> 12) & 0x07) ) << ((1-(x&1))<<2) );
1101 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1102 dstbits += linebytes;
1107 } else if (bmpImage->green_mask==0x07e0) {
1108 if (bmpImage->red_mask==0xf800) {
1109 /* ==== rgb 565 bmp -> pal 4 dib ==== */
1110 for (h=0; h<lines; h++) {
1115 for (x=0; x<width; x++) {
1118 dstval|=(X11DRV_DIB_GetNearestIndex
1120 ((srcval >> 8) & 0xf8) | /* r */
1121 ((srcval >> 13) & 0x07),
1122 ((srcval >> 3) & 0xfc) | /* g */
1123 ((srcval >> 9) & 0x03),
1124 ((srcval << 3) & 0xf8) | /* b */
1125 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
1134 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1135 dstbits += linebytes;
1137 } else if (bmpImage->blue_mask==0xf800) {
1138 /* ==== bgr 565 bmp -> pal 4 dib ==== */
1139 for (h=0; h<lines; h++) {
1144 for (x=0; x<width; x++) {
1147 dstval|=(X11DRV_DIB_GetNearestIndex
1149 ((srcval << 3) & 0xf8) | /* r */
1150 ((srcval >> 2) & 0x07),
1151 ((srcval >> 3) & 0xfc) | /* g */
1152 ((srcval >> 9) & 0x03),
1153 ((srcval >> 8) & 0xf8) | /* b */
1154 ((srcval >> 13) & 0x07) ) << ((1-(x&1))<<2) );
1163 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1164 dstbits += linebytes;
1176 if (bmpImage->bits_per_pixel==24) {
1177 const void* srcbits;
1178 const BYTE *srcbyte;
1181 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1183 if (bmpImage->green_mask!=0x00ff00 ||
1184 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1186 } else if (bmpImage->blue_mask==0xff) {
1187 /* ==== rgb 888 bmp -> pal 4 dib ==== */
1188 for (h=0; h<lines; h++) {
1191 for (x=0; x<width/2; x++) {
1192 /* Do 2 pixels at a time */
1193 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1198 X11DRV_DIB_GetNearestIndex
1206 /* And the the odd pixel */
1207 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1213 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1214 dstbits += linebytes;
1217 /* ==== bgr 888 bmp -> pal 4 dib ==== */
1218 for (h=0; h<lines; h++) {
1221 for (x=0; x<width/2; x++) {
1222 /* Do 2 pixels at a time */
1223 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1228 X11DRV_DIB_GetNearestIndex
1236 /* And the the odd pixel */
1237 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1243 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1244 dstbits += linebytes;
1253 const void* srcbits;
1254 const BYTE *srcbyte;
1257 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1259 if (bmpImage->green_mask!=0x00ff00 ||
1260 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1262 } else if (bmpImage->blue_mask==0xff) {
1263 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
1264 for (h=0; h<lines; h++) {
1267 for (x=0; x<width/2; x++) {
1268 /* Do 2 pixels at a time */
1269 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1274 X11DRV_DIB_GetNearestIndex
1282 /* And the the odd pixel */
1283 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1289 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1290 dstbits += linebytes;
1293 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
1294 for (h=0; h<lines; h++) {
1297 for (x=0; x<width/2; x++) {
1298 /* Do 2 pixels at a time */
1299 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1304 X11DRV_DIB_GetNearestIndex
1312 /* And the the odd pixel */
1313 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1319 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1320 dstbits += linebytes;
1331 /* ==== any bmp format -> pal 4 dib ==== */
1332 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
1333 bmpImage->bits_per_pixel, bmpImage->red_mask,
1334 bmpImage->green_mask, bmpImage->blue_mask );
1335 for (h=lines-1; h>=0; h--) {
1337 for (x=0; x<(width & ~1); x+=2) {
1338 *dstbyte++=(X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4) |
1339 X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x+1, h), 0);
1342 *dstbyte=(X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4);
1344 dstbits += linebytes;
1351 /***********************************************************************
1352 * X11DRV_DIB_SetImageBits_RLE4
1354 * SetDIBits for a 4-bit deep compressed DIB.
1356 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
1357 DWORD srcwidth, DWORD dstwidth,
1358 int left, int *colors,
1361 unsigned int x = 0, width = min(srcwidth, dstwidth);
1362 int y = lines - 1, c, length;
1363 const BYTE *begin = bits;
1368 if (length) { /* encoded */
1371 if (x >= (left + width)) break;
1372 if( x >= left) XPutPixel(bmpImage, x, y, colors[c >> 4]);
1374 if (!length--) break;
1375 if (x >= (left + width)) break;
1376 if( x >= left) XPutPixel(bmpImage, x, y, colors[c & 0xf]);
1396 default: /* absolute */
1399 if (x >= left && x < (left + width))
1400 XPutPixel(bmpImage, x, y, colors[c >> 4]);
1402 if (!length--) break;
1403 if (x >= left && x < (left + width))
1404 XPutPixel(bmpImage, x, y, colors[c & 0xf]);
1407 if ((bits - begin) & 1)
1416 /***********************************************************************
1417 * X11DRV_DIB_SetImageBits_8
1419 * SetDIBits for an 8-bit deep DIB.
1421 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
1422 DWORD srcwidth, DWORD dstwidth, int left,
1423 const int *colors, XImage *bmpImage,
1427 int h, width = min(srcwidth, dstwidth);
1428 const BYTE* srcbyte;
1434 srcbits = srcbits + linebytes * (lines-1);
1435 linebytes = -linebytes;
1440 switch (bmpImage->depth) {
1443 #if defined(__i386__) && defined(__GNUC__)
1444 /* Some X servers might have 32 bit/ 16bit deep pixel */
1445 if (lines && width && (bmpImage->bits_per_pixel == 16) &&
1446 (ImageByteOrder(gdi_display)==LSBFirst) )
1448 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
1449 /* FIXME: Does this really handle all these cases correctly? */
1450 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
1451 for (h = lines ; h--; ) {
1452 int _cl1,_cl2; /* temp outputs for asm below */
1453 /* Borrowed from DirectDraw */
1454 __asm__ __volatile__(
1459 " movw (%%edx,%%eax,4),%%ax\n"
1461 " xor %%eax,%%eax\n"
1463 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
1468 :"eax", "cc", "memory"
1470 srcbyte = (srcbits += linebytes);
1471 dstbits -= bmpImage->bytes_per_line;
1479 #if defined(__i386__) && defined(__GNUC__)
1480 if (lines && width && (bmpImage->bits_per_pixel == 32) &&
1481 (ImageByteOrder(gdi_display)==LSBFirst) )
1483 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
1484 /* FIXME: Does this really handle both cases correctly? */
1485 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
1486 for (h = lines ; h--; ) {
1487 int _cl1,_cl2; /* temp outputs for asm below */
1488 /* Borrowed from DirectDraw */
1489 __asm__ __volatile__(
1494 " movl (%%edx,%%eax,4),%%eax\n"
1496 " xor %%eax,%%eax\n"
1498 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
1503 :"eax", "cc", "memory"
1505 srcbyte = (srcbits += linebytes);
1506 dstbits -= bmpImage->bytes_per_line;
1513 break; /* use slow generic case below */
1516 /* ==== pal 8 dib -> any bmp format ==== */
1517 for (h=lines-1; h>=0; h--) {
1518 for (x=left; x<width+left; x++) {
1519 XPutPixel(bmpImage, x, h, colors[*srcbyte++]);
1521 srcbyte = (srcbits += linebytes);
1525 /***********************************************************************
1526 * X11DRV_DIB_GetImageBits_8
1528 * GetDIBits for an 8-bit deep DIB.
1530 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
1531 DWORD srcwidth, DWORD dstwidth,
1532 RGBQUAD *colors, PALETTEENTRY *srccolors,
1533 XImage *bmpImage, DWORD linebytes )
1536 int h, width = min(srcwidth, dstwidth);
1542 dstbits = dstbits + ( linebytes * (lines-1) );
1543 linebytes = -linebytes;
1548 * This condition is true when GetImageBits has been called by
1549 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
1550 * 256 colormaps, so we'll just use for for GetDIBits calls.
1551 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
1553 if (!srccolors) goto updatesection;
1555 switch (bmpImage->depth) {
1558 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1560 /* ==== pal 1 bmp -> pal 8 dib ==== */
1561 /* ==== pal 4 bmp -> pal 8 dib ==== */
1562 for (h=lines-1; h>=0; h--) {
1564 for (x=0; x<width; x++) {
1565 PALETTEENTRY srcval;
1566 srcval=srccolors[XGetPixel(bmpImage, x, h)];
1567 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
1572 dstbits += linebytes;
1580 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1581 /* ==== pal 8 bmp -> pal 8 dib ==== */
1582 const void* srcbits;
1583 const BYTE* srcpixel;
1585 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1586 for (h=0; h<lines; h++) {
1589 for (x = 0; x < width; x++) {
1590 PALETTEENTRY srcval;
1591 srcval=srccolors[(int)*srcpixel++];
1592 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
1597 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1598 dstbits += linebytes;
1608 const void* srcbits;
1609 const WORD* srcpixel;
1612 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1614 if (bmpImage->green_mask==0x03e0) {
1615 if (bmpImage->red_mask==0x7c00) {
1616 /* ==== rgb 555 bmp -> pal 8 dib ==== */
1617 for (h=0; h<lines; h++) {
1620 for (x=0; x<width; x++) {
1623 *dstbyte++=X11DRV_DIB_GetNearestIndex
1625 ((srcval >> 7) & 0xf8) | /* r */
1626 ((srcval >> 12) & 0x07),
1627 ((srcval >> 2) & 0xf8) | /* g */
1628 ((srcval >> 7) & 0x07),
1629 ((srcval << 3) & 0xf8) | /* b */
1630 ((srcval >> 2) & 0x07) );
1632 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1633 dstbits += linebytes;
1635 } else if (bmpImage->blue_mask==0x7c00) {
1636 /* ==== bgr 555 bmp -> pal 8 dib ==== */
1637 for (h=0; h<lines; h++) {
1640 for (x=0; x<width; x++) {
1643 *dstbyte++=X11DRV_DIB_GetNearestIndex
1645 ((srcval << 3) & 0xf8) | /* r */
1646 ((srcval >> 2) & 0x07),
1647 ((srcval >> 2) & 0xf8) | /* g */
1648 ((srcval >> 7) & 0x07),
1649 ((srcval >> 7) & 0xf8) | /* b */
1650 ((srcval >> 12) & 0x07) );
1652 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1653 dstbits += linebytes;
1658 } else if (bmpImage->green_mask==0x07e0) {
1659 if (bmpImage->red_mask==0xf800) {
1660 /* ==== rgb 565 bmp -> pal 8 dib ==== */
1661 for (h=0; h<lines; h++) {
1664 for (x=0; x<width; x++) {
1667 *dstbyte++=X11DRV_DIB_GetNearestIndex
1669 ((srcval >> 8) & 0xf8) | /* r */
1670 ((srcval >> 13) & 0x07),
1671 ((srcval >> 3) & 0xfc) | /* g */
1672 ((srcval >> 9) & 0x03),
1673 ((srcval << 3) & 0xf8) | /* b */
1674 ((srcval >> 2) & 0x07) );
1676 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1677 dstbits += linebytes;
1679 } else if (bmpImage->blue_mask==0xf800) {
1680 /* ==== bgr 565 bmp -> pal 8 dib ==== */
1681 for (h=0; h<lines; h++) {
1684 for (x=0; x<width; x++) {
1687 *dstbyte++=X11DRV_DIB_GetNearestIndex
1689 ((srcval << 3) & 0xf8) | /* r */
1690 ((srcval >> 2) & 0x07),
1691 ((srcval >> 3) & 0xfc) | /* g */
1692 ((srcval >> 9) & 0x03),
1693 ((srcval >> 8) & 0xf8) | /* b */
1694 ((srcval >> 13) & 0x07) );
1696 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1697 dstbits += linebytes;
1711 const void* srcbits;
1712 const BYTE *srcbyte;
1714 int bytes_per_pixel;
1716 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1717 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
1719 if (bmpImage->green_mask!=0x00ff00 ||
1720 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1722 } else if (bmpImage->blue_mask==0xff) {
1723 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
1724 for (h=0; h<lines; h++) {
1727 for (x=0; x<width; x++) {
1728 *dstbyte++=X11DRV_DIB_GetNearestIndex
1733 srcbyte+=bytes_per_pixel;
1735 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1736 dstbits += linebytes;
1739 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
1740 for (h=0; h<lines; h++) {
1743 for (x=0; x<width; x++) {
1744 *dstbyte++=X11DRV_DIB_GetNearestIndex
1749 srcbyte+=bytes_per_pixel;
1751 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1752 dstbits += linebytes;
1760 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
1761 bmpImage->depth, bmpImage->red_mask,
1762 bmpImage->green_mask, bmpImage->blue_mask );
1764 /* ==== any bmp format -> pal 8 dib ==== */
1765 for (h=lines-1; h>=0; h--) {
1767 for (x=0; x<width; x++) {
1768 *dstbyte=X11DRV_DIB_MapColor
1770 XGetPixel(bmpImage, x, h), *dstbyte);
1773 dstbits += linebytes;
1779 /***********************************************************************
1780 * X11DRV_DIB_SetImageBits_RLE8
1782 * SetDIBits for an 8-bit deep compressed DIB.
1784 * This function rewritten 941113 by James Youngman. WINE blew out when I
1785 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1787 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1788 * 'End of bitmap' escape code. This code is very much laxer in what it
1789 * allows to end the expansion. Possibly too lax. See the note by
1790 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1791 * bitmap should end with RleEnd, but on the other hand, software exists
1792 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1795 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1796 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1799 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1800 DWORD srcwidth, DWORD dstwidth,
1801 int left, int *colors,
1804 unsigned int x; /* X-position on each line. Increases. */
1805 int y; /* Line #. Starts at lines-1, decreases */
1806 const BYTE *pIn = bits; /* Pointer to current position in bits */
1807 BYTE length; /* The length pf a run */
1808 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
1811 * Note that the bitmap data is stored by Windows starting at the
1812 * bottom line of the bitmap and going upwards. Within each line,
1813 * the data is stored left-to-right. That's the reason why line
1814 * goes from lines-1 to 0. [JAY]
1824 * If the length byte is not zero (which is the escape value),
1825 * We have a run of length pixels all the same colour. The colour
1826 * index is stored next.
1828 * If the length byte is zero, we need to read the next byte to
1829 * know what to do. [JAY]
1834 * [Run-Length] Encoded mode
1836 int color = colors[*pIn++];
1837 while (length-- && x < (left + dstwidth)) {
1838 if( x >= left) XPutPixel(bmpImage, x, y, color);
1845 * Escape codes (may be an absolute sequence though)
1847 escape_code = (*pIn++);
1856 /* Not all RLE8 bitmaps end with this code. For
1857 * example, Paint Shop Pro produces some that don't.
1858 * That's (I think) what caused the previous
1859 * implementation to fail. [JAY]
1868 default: /* switch to absolute mode */
1869 length = escape_code;
1872 int color = colors[*pIn++];
1873 if (x >= (left + dstwidth))
1878 if( x >= left) XPutPixel(bmpImage, x, y, color);
1882 * If you think for a moment you'll realise that the
1883 * only time we could ever possibly read an odd
1884 * number of bytes is when there is a 0x00 (escape),
1885 * a value >0x02 (absolute mode) and then an odd-
1886 * length run. Therefore this is the only place we
1887 * need to worry about it. Everywhere else the
1888 * bytes are always read in pairs. [JAY]
1890 if (escape_code & 1) pIn++; /* Throw away the pad byte. */
1892 } /* switch (escape_code) : Escape sequence */
1898 /***********************************************************************
1899 * X11DRV_DIB_SetImageBits_16
1901 * SetDIBits for a 16-bit deep DIB.
1903 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1904 DWORD srcwidth, DWORD dstwidth, int left,
1905 X11DRV_PDEVICE *physDev, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1906 XImage *bmpImage, DWORD linebytes )
1909 int h, width = min(srcwidth, dstwidth);
1910 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
1915 srcbits = srcbits + ( linebytes * (lines-1));
1916 linebytes = -linebytes;
1919 switch (bmpImage->depth)
1926 srcbits=srcbits+left*2;
1927 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
1929 if (bmpImage->green_mask==0x03e0) {
1930 if (gSrc==bmpImage->green_mask) {
1931 if (rSrc==bmpImage->red_mask) {
1932 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
1933 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
1934 convs->Convert_5x5_asis
1937 dstbits,-bmpImage->bytes_per_line);
1938 } else if (rSrc==bmpImage->blue_mask) {
1939 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
1940 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
1941 convs->Convert_555_reverse
1944 dstbits,-bmpImage->bytes_per_line);
1947 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
1948 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
1949 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
1950 convs->Convert_565_to_555_asis
1953 dstbits,-bmpImage->bytes_per_line);
1955 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
1956 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
1957 convs->Convert_565_to_555_reverse
1960 dstbits,-bmpImage->bytes_per_line);
1963 } else if (bmpImage->green_mask==0x07e0) {
1964 if (gSrc==bmpImage->green_mask) {
1965 if (rSrc==bmpImage->red_mask) {
1966 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
1967 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
1968 convs->Convert_5x5_asis
1971 dstbits,-bmpImage->bytes_per_line);
1973 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
1974 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
1975 convs->Convert_565_reverse
1978 dstbits,-bmpImage->bytes_per_line);
1981 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
1982 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
1983 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
1984 convs->Convert_555_to_565_asis
1987 dstbits,-bmpImage->bytes_per_line);
1989 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
1990 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
1991 convs->Convert_555_to_565_reverse
1994 dstbits,-bmpImage->bytes_per_line);
2004 if (bmpImage->bits_per_pixel==24) {
2007 srcbits=srcbits+left*2;
2008 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
2010 if (bmpImage->green_mask!=0x00ff00 ||
2011 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2013 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
2014 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
2016 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
2017 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
2018 convs->Convert_555_to_888_asis
2021 dstbits,-bmpImage->bytes_per_line);
2023 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
2024 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
2025 convs->Convert_565_to_888_asis
2028 dstbits,-bmpImage->bytes_per_line);
2032 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
2033 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
2034 convs->Convert_555_to_888_reverse
2037 dstbits,-bmpImage->bytes_per_line);
2039 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
2040 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
2041 convs->Convert_565_to_888_reverse
2044 dstbits,-bmpImage->bytes_per_line);
2055 srcbits=srcbits+left*2;
2056 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2058 if (bmpImage->green_mask!=0x00ff00 ||
2059 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2061 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
2062 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
2064 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
2065 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
2066 convs->Convert_555_to_0888_asis
2069 dstbits,-bmpImage->bytes_per_line);
2071 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
2072 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
2073 convs->Convert_565_to_0888_asis
2076 dstbits,-bmpImage->bytes_per_line);
2080 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
2081 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
2082 convs->Convert_555_to_0888_reverse
2085 dstbits,-bmpImage->bytes_per_line);
2087 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
2088 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
2089 convs->Convert_565_to_0888_reverse
2092 dstbits,-bmpImage->bytes_per_line);
2100 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2101 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
2102 bmpImage->green_mask, bmpImage->blue_mask );
2108 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
2109 const WORD* srcpixel;
2110 int rShift1,gShift1,bShift1;
2111 int rShift2,gShift2,bShift2;
2114 /* Set color scaling values */
2115 rShift1=16+X11DRV_DIB_MaskToShift(rSrc)-3;
2116 gShift1=16+X11DRV_DIB_MaskToShift(gSrc)-3;
2117 bShift1=16+X11DRV_DIB_MaskToShift(bSrc)-3;
2122 /* Green has 5 bits, like the others */
2126 /* Green has 6 bits, not 5. Compensate. */
2135 /* We could split it into four separate cases to optimize
2136 * but it is probably not worth it.
2138 for (h=lines-1; h>=0; h--) {
2139 srcpixel=(const WORD*)srcbits;
2140 for (x=left; x<width+left; x++) {
2142 BYTE red,green,blue;
2143 srcval=*srcpixel++ << 16;
2144 red= ((srcval >> rShift1) & 0xf8) |
2145 ((srcval >> rShift2) & 0x07);
2146 green=((srcval >> gShift1) & gMask1) |
2147 ((srcval >> gShift2) & gMask2);
2148 blue= ((srcval >> bShift1) & 0xf8) |
2149 ((srcval >> bShift2) & 0x07);
2150 XPutPixel(bmpImage, x, h,
2151 X11DRV_PALETTE_ToPhysical
2152 (physDev, RGB(red,green,blue)));
2154 srcbits += linebytes;
2162 /***********************************************************************
2163 * X11DRV_DIB_GetImageBits_16
2165 * GetDIBits for an 16-bit deep DIB.
2167 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
2168 DWORD dstwidth, DWORD srcwidth,
2169 PALETTEENTRY *srccolors,
2170 DWORD rDst, DWORD gDst, DWORD bDst,
2171 XImage *bmpImage, DWORD dibpitch )
2174 int h, width = min(srcwidth, dstwidth);
2175 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
2177 DWORD linebytes = dibpitch;
2182 dstbits = dstbits + ( linebytes * (lines-1));
2183 linebytes = -linebytes;
2186 switch (bmpImage->depth)
2191 const char* srcbits;
2193 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2195 if (bmpImage->green_mask==0x03e0) {
2196 if (gDst==bmpImage->green_mask) {
2197 if (rDst==bmpImage->red_mask) {
2198 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
2199 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
2200 convs->Convert_5x5_asis
2202 srcbits,-bmpImage->bytes_per_line,
2205 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
2206 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
2207 convs->Convert_555_reverse
2209 srcbits,-bmpImage->bytes_per_line,
2213 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
2214 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
2215 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
2216 convs->Convert_555_to_565_asis
2218 srcbits,-bmpImage->bytes_per_line,
2221 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
2222 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
2223 convs->Convert_555_to_565_reverse
2225 srcbits,-bmpImage->bytes_per_line,
2229 } else if (bmpImage->green_mask==0x07e0) {
2230 if (gDst==bmpImage->green_mask) {
2231 if (rDst == bmpImage->red_mask) {
2232 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
2233 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
2234 convs->Convert_5x5_asis
2236 srcbits,-bmpImage->bytes_per_line,
2239 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
2240 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
2241 convs->Convert_565_reverse
2243 srcbits,-bmpImage->bytes_per_line,
2247 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
2248 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
2249 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
2250 convs->Convert_565_to_555_asis
2252 srcbits,-bmpImage->bytes_per_line,
2255 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
2256 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
2257 convs->Convert_565_to_555_reverse
2259 srcbits,-bmpImage->bytes_per_line,
2270 if (bmpImage->bits_per_pixel == 24) {
2271 const char* srcbits;
2273 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2275 if (bmpImage->green_mask!=0x00ff00 ||
2276 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2278 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
2279 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
2281 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
2282 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
2283 convs->Convert_888_to_555_asis
2285 srcbits,-bmpImage->bytes_per_line,
2288 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2289 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2290 convs->Convert_888_to_565_asis
2292 srcbits,-bmpImage->bytes_per_line,
2297 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
2298 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
2299 convs->Convert_888_to_555_reverse
2301 srcbits,-bmpImage->bytes_per_line,
2304 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
2305 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
2306 convs->Convert_888_to_565_reverse
2308 srcbits,-bmpImage->bytes_per_line,
2318 const char* srcbits;
2320 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2322 if (bmpImage->green_mask!=0x00ff00 ||
2323 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2325 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
2326 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
2328 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
2329 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
2330 convs->Convert_0888_to_555_asis
2332 srcbits,-bmpImage->bytes_per_line,
2335 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
2336 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
2337 convs->Convert_0888_to_565_asis
2339 srcbits,-bmpImage->bytes_per_line,
2344 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
2345 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
2346 convs->Convert_0888_to_555_reverse
2348 srcbits,-bmpImage->bytes_per_line,
2351 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
2352 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
2353 convs->Convert_0888_to_565_reverse
2355 srcbits,-bmpImage->bytes_per_line,
2364 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2365 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
2366 int rShift,gShift,bShift;
2369 /* Shift everything 16 bits left so that all shifts are >0,
2370 * even for BGR DIBs. Then a single >> 16 will bring everything
2373 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2374 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2375 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2377 /* 6 bits for the green */
2383 for (h = lines - 1; h >= 0; h--) {
2384 dstpixel=(LPWORD)dstbits;
2385 for (x = 0; x < width; x++) {
2386 PALETTEENTRY srcval;
2388 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2389 dstval=((srcval.peRed << rShift) & rDst) |
2390 ((srcval.peGreen << gShift) & gDst) |
2391 ((srcval.peBlue << bShift) & bDst);
2392 *dstpixel++=dstval >> 16;
2394 dstbits += linebytes;
2402 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2403 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
2404 int rShift,gShift,bShift;
2405 const BYTE* srcbits;
2406 const BYTE* srcpixel;
2409 /* Shift everything 16 bits left so that all shifts are >0,
2410 * even for BGR DIBs. Then a single >> 16 will bring everything
2413 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2414 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2415 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2417 /* 6 bits for the green */
2423 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2424 for (h=0; h<lines; h++) {
2426 dstpixel=(LPWORD)dstbits;
2427 for (x = 0; x < width; x++) {
2428 PALETTEENTRY srcval;
2430 srcval=srccolors[(int)*srcpixel++];
2431 dstval=((srcval.peRed << rShift) & rDst) |
2432 ((srcval.peGreen << gShift) & gDst) |
2433 ((srcval.peBlue << bShift) & bDst);
2434 *dstpixel++=dstval >> 16;
2436 srcbits -= bmpImage->bytes_per_line;
2437 dstbits += linebytes;
2447 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
2448 int rShift,gShift,bShift;
2451 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
2452 bmpImage->depth, bmpImage->red_mask,
2453 bmpImage->green_mask, bmpImage->blue_mask,
2456 /* Shift everything 16 bits left so that all shifts are >0,
2457 * even for BGR DIBs. Then a single >> 16 will bring everything
2460 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2461 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2462 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2464 /* 6 bits for the green */
2470 for (h = lines - 1; h >= 0; h--) {
2471 dstpixel=(LPWORD)dstbits;
2472 for (x = 0; x < width; x++) {
2475 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
2476 dstval=((GetRValue(srcval) << rShift) & rDst) |
2477 ((GetGValue(srcval) << gShift) & gDst) |
2478 ((GetBValue(srcval) << bShift) & bDst);
2479 *dstpixel++=dstval >> 16;
2481 dstbits += linebytes;
2489 /***********************************************************************
2490 * X11DRV_DIB_SetImageBits_24
2492 * SetDIBits for a 24-bit deep DIB.
2494 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
2495 DWORD srcwidth, DWORD dstwidth, int left,
2496 X11DRV_PDEVICE *physDev,
2497 DWORD rSrc, DWORD gSrc, DWORD bSrc,
2498 XImage *bmpImage, DWORD linebytes )
2501 int h, width = min(srcwidth, dstwidth);
2502 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
2507 srcbits = srcbits + linebytes * (lines - 1);
2508 linebytes = -linebytes;
2511 switch (bmpImage->depth)
2514 if (bmpImage->bits_per_pixel==24) {
2517 srcbits=srcbits+left*3;
2518 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
2520 if (bmpImage->green_mask!=0x00ff00 ||
2521 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2523 } else if (rSrc==bmpImage->red_mask) {
2524 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
2525 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
2526 convs->Convert_888_asis
2529 dstbits,-bmpImage->bytes_per_line);
2531 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
2532 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
2533 convs->Convert_888_reverse
2536 dstbits,-bmpImage->bytes_per_line);
2546 srcbits=srcbits+left*3;
2547 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2549 if (bmpImage->green_mask!=0x00ff00 ||
2550 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2552 } else if (rSrc==bmpImage->red_mask) {
2553 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
2554 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
2555 convs->Convert_888_to_0888_asis
2558 dstbits,-bmpImage->bytes_per_line);
2560 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
2561 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
2562 convs->Convert_888_to_0888_reverse
2565 dstbits,-bmpImage->bytes_per_line);
2575 srcbits=srcbits+left*3;
2576 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2578 if (bmpImage->green_mask==0x03e0) {
2579 if ((rSrc==0xff0000 && bmpImage->red_mask==0x7f00) ||
2580 (bSrc==0xff0000 && bmpImage->blue_mask==0x7f00)) {
2581 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
2582 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
2583 convs->Convert_888_to_555_asis
2586 dstbits,-bmpImage->bytes_per_line);
2587 } else if ((rSrc==0xff && bmpImage->red_mask==0x7f00) ||
2588 (bSrc==0xff && bmpImage->blue_mask==0x7f00)) {
2589 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
2590 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
2591 convs->Convert_888_to_555_reverse
2594 dstbits,-bmpImage->bytes_per_line);
2598 } else if (bmpImage->green_mask==0x07e0) {
2599 if ((rSrc==0xff0000 && bmpImage->red_mask==0xf800) ||
2600 (bSrc==0xff0000 && bmpImage->blue_mask==0xf800)) {
2601 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
2602 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
2603 convs->Convert_888_to_565_asis
2606 dstbits,-bmpImage->bytes_per_line);
2607 } else if ((rSrc==0xff && bmpImage->red_mask==0xf800) ||
2608 (bSrc==0xff && bmpImage->blue_mask==0xf800)) {
2609 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
2610 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
2611 convs->Convert_888_to_565_reverse
2614 dstbits,-bmpImage->bytes_per_line);
2626 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2627 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
2628 bmpImage->green_mask, bmpImage->blue_mask );
2634 /* ==== rgb 888 dib -> any bmp bormat ==== */
2635 const BYTE* srcbyte;
2637 /* Windows only supports one 24bpp DIB format: RGB888 */
2639 for (h = lines - 1; h >= 0; h--) {
2640 srcbyte=(const BYTE*)srcbits;
2641 for (x = left; x < width+left; x++) {
2642 XPutPixel(bmpImage, x, h,
2643 X11DRV_PALETTE_ToPhysical
2644 (physDev, RGB(srcbyte[2], srcbyte[1], srcbyte[0])));
2647 srcbits += linebytes;
2655 /***********************************************************************
2656 * X11DRV_DIB_GetImageBits_24
2658 * GetDIBits for an 24-bit deep DIB.
2660 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
2661 DWORD dstwidth, DWORD srcwidth,
2662 PALETTEENTRY *srccolors,
2663 DWORD rDst, DWORD gDst, DWORD bDst,
2664 XImage *bmpImage, DWORD linebytes )
2667 int h, width = min(srcwidth, dstwidth);
2668 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
2673 dstbits = dstbits + ( linebytes * (lines-1) );
2674 linebytes = -linebytes;
2677 switch (bmpImage->depth)
2680 if (bmpImage->bits_per_pixel==24) {
2681 const char* srcbits;
2683 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2685 if (bmpImage->green_mask!=0x00ff00 ||
2686 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2688 } else if (rDst==bmpImage->red_mask) {
2689 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
2690 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
2691 convs->Convert_888_asis
2693 srcbits,-bmpImage->bytes_per_line,
2696 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
2697 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
2698 convs->Convert_888_reverse
2700 srcbits,-bmpImage->bytes_per_line,
2709 const char* srcbits;
2711 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2713 if (bmpImage->green_mask!=0x00ff00 ||
2714 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2716 } else if (rDst==bmpImage->red_mask) {
2717 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2718 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2719 convs->Convert_0888_to_888_asis
2721 srcbits,-bmpImage->bytes_per_line,
2724 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
2725 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
2726 convs->Convert_0888_to_888_reverse
2728 srcbits,-bmpImage->bytes_per_line,
2737 const char* srcbits;
2739 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2741 if (bmpImage->green_mask==0x03e0) {
2742 if ((rDst==0xff0000 && bmpImage->red_mask==0x7f00) ||
2743 (bDst==0xff0000 && bmpImage->blue_mask==0x7f00)) {
2744 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
2745 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
2746 convs->Convert_555_to_888_asis
2748 srcbits,-bmpImage->bytes_per_line,
2750 } else if ((rDst==0xff && bmpImage->red_mask==0x7f00) ||
2751 (bDst==0xff && bmpImage->blue_mask==0x7f00)) {
2752 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
2753 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
2754 convs->Convert_555_to_888_reverse
2756 srcbits,-bmpImage->bytes_per_line,
2761 } else if (bmpImage->green_mask==0x07e0) {
2762 if ((rDst==0xff0000 && bmpImage->red_mask==0xf800) ||
2763 (bDst==0xff0000 && bmpImage->blue_mask==0xf800)) {
2764 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
2765 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
2766 convs->Convert_565_to_888_asis
2768 srcbits,-bmpImage->bytes_per_line,
2770 } else if ((rDst==0xff && bmpImage->red_mask==0xf800) ||
2771 (bDst==0xff && bmpImage->blue_mask==0xf800)) {
2772 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
2773 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
2774 convs->Convert_565_to_888_reverse
2776 srcbits,-bmpImage->bytes_per_line,
2789 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2790 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
2793 /* Windows only supports one 24bpp DIB format: rgb 888 */
2794 for (h = lines - 1; h >= 0; h--) {
2796 for (x = 0; x < width; x++) {
2797 PALETTEENTRY srcval;
2798 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2799 dstbyte[0]=srcval.peBlue;
2800 dstbyte[1]=srcval.peGreen;
2801 dstbyte[2]=srcval.peRed;
2804 dstbits += linebytes;
2812 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors) {
2813 /* ==== pal 8 bmp -> rgb 888 dib ==== */
2814 const void* srcbits;
2815 const BYTE* srcpixel;
2818 /* Windows only supports one 24bpp DIB format: rgb 888 */
2819 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2820 for (h = lines - 1; h >= 0; h--) {
2823 for (x = 0; x < width; x++ ) {
2824 PALETTEENTRY srcval;
2825 srcval=srccolors[(int)*srcpixel++];
2826 dstbyte[0]=srcval.peBlue;
2827 dstbyte[1]=srcval.peGreen;
2828 dstbyte[2]=srcval.peRed;
2831 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
2832 dstbits += linebytes;
2842 /* ==== any bmp format -> 888 dib ==== */
2845 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
2846 bmpImage->depth, bmpImage->red_mask,
2847 bmpImage->green_mask, bmpImage->blue_mask,
2850 /* Windows only supports one 24bpp DIB format: rgb 888 */
2851 for (h = lines - 1; h >= 0; h--) {
2853 for (x = 0; x < width; x++) {
2854 COLORREF srcval=X11DRV_PALETTE_ToLogical
2855 (XGetPixel( bmpImage, x, h ));
2856 dstbyte[0]=GetBValue(srcval);
2857 dstbyte[1]=GetGValue(srcval);
2858 dstbyte[2]=GetRValue(srcval);
2861 dstbits += linebytes;
2869 /***********************************************************************
2870 * X11DRV_DIB_SetImageBits_32
2872 * SetDIBits for a 32-bit deep DIB.
2874 static void X11DRV_DIB_SetImageBits_32(int lines, const BYTE *srcbits,
2875 DWORD srcwidth, DWORD dstwidth, int left,
2876 X11DRV_PDEVICE *physDev,
2877 DWORD rSrc, DWORD gSrc, DWORD bSrc,
2883 int h, width = min(srcwidth, dstwidth);
2884 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
2889 srcbits = srcbits + ( linebytes * (lines-1) );
2890 linebytes = -linebytes;
2893 ptr = (const DWORD *) srcbits + left;
2895 switch (bmpImage->depth)
2898 if (bmpImage->bits_per_pixel==24) {
2901 srcbits=srcbits+left*4;
2902 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
2904 if (rSrc==bmpImage->red_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->blue_mask) {
2905 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
2906 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
2907 convs->Convert_0888_to_888_asis
2910 dstbits,-bmpImage->bytes_per_line);
2911 } else if (bmpImage->green_mask!=0x00ff00 ||
2912 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2914 /* the tests below assume sane bmpImage masks */
2915 } else if (rSrc==bmpImage->blue_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->red_mask) {
2916 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
2917 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
2918 convs->Convert_0888_to_888_reverse
2921 dstbits,-bmpImage->bytes_per_line);
2922 } else if (bmpImage->blue_mask==0xff) {
2923 /* ==== any 0888 dib -> rgb 888 bmp ==== */
2924 convs->Convert_any0888_to_rgb888
2928 dstbits,-bmpImage->bytes_per_line);
2930 /* ==== any 0888 dib -> bgr 888 bmp ==== */
2931 convs->Convert_any0888_to_bgr888
2935 dstbits,-bmpImage->bytes_per_line);
2945 srcbits=srcbits+left*4;
2946 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2948 if (gSrc==bmpImage->green_mask) {
2949 if (rSrc==bmpImage->red_mask && bSrc==bmpImage->blue_mask) {
2950 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
2951 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
2952 convs->Convert_0888_asis
2955 dstbits,-bmpImage->bytes_per_line);
2956 } else if (bmpImage->green_mask!=0x00ff00 ||
2957 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2959 /* the tests below assume sane bmpImage masks */
2960 } else if (rSrc==bmpImage->blue_mask && bSrc==bmpImage->red_mask) {
2961 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
2962 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
2963 convs->Convert_0888_reverse
2966 dstbits,-bmpImage->bytes_per_line);
2968 /* ==== any 0888 dib -> any 0888 bmp ==== */
2969 convs->Convert_0888_any
2973 dstbits,-bmpImage->bytes_per_line,
2974 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2976 } else if (bmpImage->green_mask!=0x00ff00 ||
2977 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2979 /* the tests below assume sane bmpImage masks */
2981 /* ==== any 0888 dib -> any 0888 bmp ==== */
2982 convs->Convert_0888_any
2986 dstbits,-bmpImage->bytes_per_line,
2987 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2997 srcbits=srcbits+left*4;
2998 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
3000 if (rSrc==0xff0000 && gSrc==0x00ff00 && bSrc==0x0000ff) {
3001 if (bmpImage->green_mask==0x03e0) {
3002 if (bmpImage->red_mask==0x7f00) {
3003 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
3004 convs->Convert_0888_to_555_asis
3007 dstbits,-bmpImage->bytes_per_line);
3008 } else if (bmpImage->blue_mask==0x7f00) {
3009 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
3010 convs->Convert_0888_to_555_reverse
3013 dstbits,-bmpImage->bytes_per_line);
3017 } else if (bmpImage->green_mask==0x07e0) {
3018 if (bmpImage->red_mask==0xf800) {
3019 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
3020 convs->Convert_0888_to_565_asis
3023 dstbits,-bmpImage->bytes_per_line);
3024 } else if (bmpImage->blue_mask==0xf800) {
3025 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
3026 convs->Convert_0888_to_565_reverse
3029 dstbits,-bmpImage->bytes_per_line);
3036 } else if (rSrc==0x0000ff && gSrc==0x00ff00 && bSrc==0xff0000) {
3037 if (bmpImage->green_mask==0x03e0) {
3038 if (bmpImage->blue_mask==0x7f00) {
3039 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
3040 convs->Convert_0888_to_555_asis
3043 dstbits,-bmpImage->bytes_per_line);
3044 } else if (bmpImage->red_mask==0x7f00) {
3045 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
3046 convs->Convert_0888_to_555_reverse
3049 dstbits,-bmpImage->bytes_per_line);
3053 } else if (bmpImage->green_mask==0x07e0) {
3054 if (bmpImage->blue_mask==0xf800) {
3055 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
3056 convs->Convert_0888_to_565_asis
3059 dstbits,-bmpImage->bytes_per_line);
3060 } else if (bmpImage->red_mask==0xf800) {
3061 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
3062 convs->Convert_0888_to_565_reverse
3065 dstbits,-bmpImage->bytes_per_line);
3073 if (bmpImage->green_mask==0x03e0 &&
3074 (bmpImage->red_mask==0x7f00 ||
3075 bmpImage->blue_mask==0x7f00)) {
3076 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
3077 convs->Convert_any0888_to_5x5
3081 dstbits,-bmpImage->bytes_per_line,
3082 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3083 } else if (bmpImage->green_mask==0x07e0 &&
3084 (bmpImage->red_mask==0xf800 ||
3085 bmpImage->blue_mask==0xf800)) {
3086 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
3087 convs->Convert_any0888_to_5x5
3091 dstbits,-bmpImage->bytes_per_line,
3092 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3102 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3103 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3104 bmpImage->green_mask, bmpImage->blue_mask );
3110 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
3111 const DWORD* srcpixel;
3112 int rShift,gShift,bShift;
3114 rShift=X11DRV_DIB_MaskToShift(rSrc);
3115 gShift=X11DRV_DIB_MaskToShift(gSrc);
3116 bShift=X11DRV_DIB_MaskToShift(bSrc);
3118 for (h = lines - 1; h >= 0; h--) {
3119 srcpixel=(const DWORD*)srcbits;
3120 for (x = left; x < width+left; x++) {
3122 BYTE red,green,blue;
3123 srcvalue=*srcpixel++;
3124 red= (srcvalue >> rShift) & 0xff;
3125 green=(srcvalue >> gShift) & 0xff;
3126 blue= (srcvalue >> bShift) & 0xff;
3127 XPutPixel(bmpImage, x, h, X11DRV_PALETTE_ToPhysical
3128 (physDev, RGB(red,green,blue)));
3130 srcbits += linebytes;
3138 /***********************************************************************
3139 * X11DRV_DIB_GetImageBits_32
3141 * GetDIBits for an 32-bit deep DIB.
3143 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
3144 DWORD dstwidth, DWORD srcwidth,
3145 PALETTEENTRY *srccolors,
3146 DWORD rDst, DWORD gDst, DWORD bDst,
3147 XImage *bmpImage, DWORD linebytes )
3150 int h, width = min(srcwidth, dstwidth);
3152 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
3157 dstbits = dstbits + ( linebytes * (lines-1) );
3158 linebytes = -linebytes;
3163 switch (bmpImage->depth)
3166 if (bmpImage->bits_per_pixel==24) {
3167 const void* srcbits;
3169 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3171 if (rDst==bmpImage->red_mask && gDst==bmpImage->green_mask && bDst==bmpImage->blue_mask) {
3172 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3173 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3174 convs->Convert_888_to_0888_asis
3176 srcbits,-bmpImage->bytes_per_line,
3178 } else if (bmpImage->green_mask!=0x00ff00 ||
3179 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3181 /* the tests below assume sane bmpImage masks */
3182 } else if (rDst==bmpImage->blue_mask && gDst==bmpImage->green_mask && bDst==bmpImage->red_mask) {
3183 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3184 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3185 convs->Convert_888_to_0888_reverse
3187 srcbits,-bmpImage->bytes_per_line,
3189 } else if (bmpImage->blue_mask==0xff) {
3190 /* ==== rgb 888 bmp -> any 0888 dib ==== */
3191 convs->Convert_rgb888_to_any0888
3193 srcbits,-bmpImage->bytes_per_line,
3197 /* ==== bgr 888 bmp -> any 0888 dib ==== */
3198 convs->Convert_bgr888_to_any0888
3200 srcbits,-bmpImage->bytes_per_line,
3210 const char* srcbits;
3212 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3214 if (gDst==bmpImage->green_mask) {
3215 if (rDst==bmpImage->red_mask && bDst==bmpImage->blue_mask) {
3216 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
3217 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
3218 convs->Convert_0888_asis
3220 srcbits,-bmpImage->bytes_per_line,
3222 } else if (bmpImage->green_mask!=0x00ff00 ||
3223 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3225 /* the tests below assume sane bmpImage masks */
3226 } else if (rDst==bmpImage->blue_mask && bDst==bmpImage->red_mask) {
3227 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
3228 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
3229 convs->Convert_0888_reverse
3231 srcbits,-bmpImage->bytes_per_line,
3234 /* ==== any 0888 bmp -> any 0888 dib ==== */
3235 convs->Convert_0888_any
3237 srcbits,-bmpImage->bytes_per_line,
3238 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3242 } else if (bmpImage->green_mask!=0x00ff00 ||
3243 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3245 /* the tests below assume sane bmpImage masks */
3247 /* ==== any 0888 bmp -> any 0888 dib ==== */
3248 convs->Convert_0888_any
3250 srcbits,-bmpImage->bytes_per_line,
3251 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3261 const char* srcbits;
3263 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3265 if (rDst==0xff0000 && gDst==0x00ff00 && bDst==0x0000ff) {
3266 if (bmpImage->green_mask==0x03e0) {
3267 if (bmpImage->red_mask==0x7f00) {
3268 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
3269 convs->Convert_555_to_0888_asis
3271 srcbits,-bmpImage->bytes_per_line,
3273 } else if (bmpImage->blue_mask==0x7f00) {
3274 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
3275 convs->Convert_555_to_0888_reverse
3277 srcbits,-bmpImage->bytes_per_line,
3282 } else if (bmpImage->green_mask==0x07e0) {
3283 if (bmpImage->red_mask==0xf800) {
3284 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
3285 convs->Convert_565_to_0888_asis
3287 srcbits,-bmpImage->bytes_per_line,
3289 } else if (bmpImage->blue_mask==0xf800) {
3290 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
3291 convs->Convert_565_to_0888_reverse
3293 srcbits,-bmpImage->bytes_per_line,
3301 } else if (rDst==0x0000ff && gDst==0x00ff00 && bDst==0xff0000) {
3302 if (bmpImage->green_mask==0x03e0) {
3303 if (bmpImage->blue_mask==0x7f00) {
3304 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
3305 convs->Convert_555_to_0888_asis
3307 srcbits,-bmpImage->bytes_per_line,
3309 } else if (bmpImage->red_mask==0x7f00) {
3310 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
3311 convs->Convert_555_to_0888_reverse
3313 srcbits,-bmpImage->bytes_per_line,
3318 } else if (bmpImage->green_mask==0x07e0) {
3319 if (bmpImage->blue_mask==0xf800) {
3320 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
3321 convs->Convert_565_to_0888_asis
3323 srcbits,-bmpImage->bytes_per_line,
3325 } else if (bmpImage->red_mask==0xf800) {
3326 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
3327 convs->Convert_565_to_0888_reverse
3329 srcbits,-bmpImage->bytes_per_line,
3338 if (bmpImage->green_mask==0x03e0 &&
3339 (bmpImage->red_mask==0x7f00 ||
3340 bmpImage->blue_mask==0x7f00)) {
3341 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
3342 convs->Convert_5x5_to_any0888
3344 srcbits,-bmpImage->bytes_per_line,
3345 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3348 } else if (bmpImage->green_mask==0x07e0 &&
3349 (bmpImage->red_mask==0xf800 ||
3350 bmpImage->blue_mask==0xf800)) {
3351 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
3352 convs->Convert_5x5_to_any0888
3354 srcbits,-bmpImage->bytes_per_line,
3355 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3367 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3368 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
3369 int rShift,gShift,bShift;
3372 rShift=X11DRV_DIB_MaskToShift(rDst);
3373 gShift=X11DRV_DIB_MaskToShift(gDst);
3374 bShift=X11DRV_DIB_MaskToShift(bDst);
3375 for (h = lines - 1; h >= 0; h--) {
3376 dstpixel=(DWORD*)dstbits;
3377 for (x = 0; x < width; x++) {
3378 PALETTEENTRY srcval;
3379 srcval = srccolors[XGetPixel(bmpImage, x, h)];
3380 *dstpixel++=(srcval.peRed << rShift) |
3381 (srcval.peGreen << gShift) |
3382 (srcval.peBlue << bShift);
3384 dstbits += linebytes;
3392 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3393 /* ==== pal 8 bmp -> any 0888 dib ==== */
3394 int rShift,gShift,bShift;
3395 const void* srcbits;
3396 const BYTE* srcpixel;
3399 rShift=X11DRV_DIB_MaskToShift(rDst);
3400 gShift=X11DRV_DIB_MaskToShift(gDst);
3401 bShift=X11DRV_DIB_MaskToShift(bDst);
3402 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3403 for (h = lines - 1; h >= 0; h--) {
3405 dstpixel=(DWORD*)dstbits;
3406 for (x = 0; x < width; x++) {
3407 PALETTEENTRY srcval;
3408 srcval=srccolors[(int)*srcpixel++];
3409 *dstpixel++=(srcval.peRed << rShift) |
3410 (srcval.peGreen << gShift) |
3411 (srcval.peBlue << bShift);
3413 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
3414 dstbits += linebytes;
3424 /* ==== any bmp format -> any 0888 dib ==== */
3425 int rShift,gShift,bShift;
3428 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
3429 bmpImage->depth, bmpImage->red_mask,
3430 bmpImage->green_mask, bmpImage->blue_mask,
3433 rShift=X11DRV_DIB_MaskToShift(rDst);
3434 gShift=X11DRV_DIB_MaskToShift(gDst);
3435 bShift=X11DRV_DIB_MaskToShift(bDst);
3436 for (h = lines - 1; h >= 0; h--) {
3437 dstpixel=(DWORD*)dstbits;
3438 for (x = 0; x < width; x++) {
3440 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
3441 *dstpixel++=(GetRValue(srcval) << rShift) |
3442 (GetGValue(srcval) << gShift) |
3443 (GetBValue(srcval) << bShift);
3445 dstbits += linebytes;
3452 /***********************************************************************
3453 * X11DRV_DIB_SetImageBits
3455 * Transfer the bits to an X image.
3456 * Helper function for SetDIBits() and SetDIBitsToDevice().
3458 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
3460 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
3465 bmpImage = descr->image;
3467 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
3468 descr->infoWidth, lines, 32, 0 );
3469 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
3470 if(bmpImage->data == NULL) {
3471 ERR("Out of memory!\n");
3472 XDestroyImage( bmpImage );
3473 wine_tsx11_unlock();
3478 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
3479 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
3480 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
3481 bmpImage->depth,bmpImage->bits_per_pixel,
3482 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3484 /* Transfer the pixels */
3485 switch(descr->infoBpp)
3488 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
3489 descr->width, descr->xSrc, (int *)(descr->colorMap),
3490 bmpImage, descr->dibpitch );
3493 if (descr->compression) {
3494 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
3495 descr->width, descr->height, AllPlanes, ZPixmap,
3496 bmpImage, descr->xSrc, descr->ySrc );
3498 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
3499 descr->infoWidth, descr->width,
3500 descr->xSrc, (int *)(descr->colorMap),
3503 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
3504 descr->infoWidth, descr->width,
3505 descr->xSrc, (int*)(descr->colorMap),
3506 bmpImage, descr->dibpitch );
3509 if (descr->compression) {
3510 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
3511 descr->width, descr->height, AllPlanes, ZPixmap,
3512 bmpImage, descr->xSrc, descr->ySrc );
3513 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
3514 descr->infoWidth, descr->width,
3515 descr->xSrc, (int *)(descr->colorMap),
3518 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
3519 descr->infoWidth, descr->width,
3520 descr->xSrc, (int *)(descr->colorMap),
3521 bmpImage, descr->dibpitch );
3525 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
3526 descr->infoWidth, descr->width,
3527 descr->xSrc, descr->physDev,
3528 descr->rMask, descr->gMask, descr->bMask,
3529 bmpImage, descr->dibpitch);
3532 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
3533 descr->infoWidth, descr->width,
3534 descr->xSrc, descr->physDev,
3535 descr->rMask, descr->gMask, descr->bMask,
3536 bmpImage, descr->dibpitch);
3539 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
3540 descr->infoWidth, descr->width,
3541 descr->xSrc, descr->physDev,
3542 descr->rMask, descr->gMask, descr->bMask,
3543 bmpImage, descr->dibpitch);
3546 WARN("(%d): Invalid depth\n", descr->infoBpp );
3550 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
3551 descr->drawable, descr->gc, bmpImage,
3552 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3553 descr->width, descr->height);
3554 #ifdef HAVE_LIBXXSHM
3557 XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
3558 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3559 descr->width, descr->height, FALSE );
3560 XSync( gdi_display, 0 );
3564 XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
3565 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3566 descr->width, descr->height );
3568 if (!descr->image) XDestroyImage( bmpImage );
3569 wine_tsx11_unlock();
3573 /***********************************************************************
3574 * X11DRV_DIB_GetImageBits
3576 * Transfer the bits from an X image.
3578 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
3580 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
3585 bmpImage = descr->image;
3587 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
3588 descr->infoWidth, lines, 32, 0 );
3589 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
3590 if(bmpImage->data == NULL) {
3591 ERR("Out of memory!\n");
3592 XDestroyImage( bmpImage );
3593 wine_tsx11_unlock();
3598 #ifdef HAVE_LIBXXSHM
3601 int saveRed, saveGreen, saveBlue;
3603 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
3604 gdi_display, descr->drawable, bmpImage,
3605 descr->xSrc, descr->ySrc, AllPlanes);
3607 /* We must save and restore the bmpImage's masks in order
3608 * to preserve them across the call to XShmGetImage, which
3609 * decides to eleminate them since it doesn't happen to know
3610 * what the format of the image is supposed to be, even though
3612 saveRed = bmpImage->red_mask;
3613 saveBlue= bmpImage->blue_mask;
3614 saveGreen = bmpImage->green_mask;
3616 XShmGetImage( gdi_display, descr->drawable, bmpImage,
3617 descr->xSrc, descr->ySrc, AllPlanes);
3619 bmpImage->red_mask = saveRed;
3620 bmpImage->blue_mask = saveBlue;
3621 bmpImage->green_mask = saveGreen;
3624 #endif /* HAVE_LIBXXSHM */
3626 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
3627 gdi_display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
3628 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
3629 XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
3630 descr->width, lines, AllPlanes, ZPixmap,
3631 bmpImage, descr->xDest, descr->yDest );
3634 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
3635 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
3636 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
3637 bmpImage->depth,bmpImage->bits_per_pixel,
3638 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3639 /* Transfer the pixels */
3640 switch(descr->infoBpp)
3643 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
3644 descr->infoWidth, descr->width,
3645 descr->colorMap, descr->palentry,
3646 bmpImage, descr->dibpitch );
3650 if (descr->compression) {
3651 FIXME("Compression not yet supported!\n");
3652 if(descr->sizeImage < X11DRV_DIB_GetDIBWidthBytes( descr->infoWidth, 4 ) * abs(descr->lines))
3655 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
3656 descr->infoWidth, descr->width,
3657 descr->colorMap, descr->palentry,
3658 bmpImage, descr->dibpitch );
3661 if (descr->compression) {
3662 FIXME("Compression not yet supported!\n");
3663 if(descr->sizeImage < X11DRV_DIB_GetDIBWidthBytes( descr->infoWidth, 8 ) * abs(descr->lines))
3666 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
3667 descr->infoWidth, descr->width,
3668 descr->colorMap, descr->palentry,
3669 bmpImage, descr->dibpitch );
3673 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
3674 descr->infoWidth,descr->width,
3676 descr->rMask, descr->gMask, descr->bMask,
3677 bmpImage, descr->dibpitch );
3681 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
3682 descr->infoWidth,descr->width,
3684 descr->rMask, descr->gMask, descr->bMask,
3685 bmpImage, descr->dibpitch);
3689 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
3690 descr->infoWidth, descr->width,
3692 descr->rMask, descr->gMask, descr->bMask,
3693 bmpImage, descr->dibpitch);
3697 WARN("(%d): Invalid depth\n", descr->infoBpp );
3701 if (!descr->image) XDestroyImage( bmpImage );
3702 wine_tsx11_unlock();
3706 /*************************************************************************
3707 * X11DRV_SetDIBitsToDevice
3710 INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWORD cx,
3711 DWORD cy, INT xSrc, INT ySrc,
3712 UINT startscan, UINT lines, LPCVOID bits,
3713 const BITMAPINFO *info, UINT coloruse )
3715 X11DRV_DIB_IMAGEBITS_DESCR descr;
3722 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
3723 &descr.infoBpp, &descr.compression ) == -1)
3726 top_down = (height < 0);
3727 if (top_down) height = -height;
3731 LPtoDP(physDev->hdc, &pt, 1);
3733 if (!lines || (startscan >= height)) return 0;
3734 if (!top_down && startscan + lines > height) lines = height - startscan;
3736 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
3737 * and clamp all values to fit inside [startscan,startscan+lines]
3739 if (ySrc + cy <= startscan + lines)
3741 UINT y = startscan + lines - (ySrc + cy);
3742 if (ySrc < startscan) cy -= (startscan - ySrc);
3745 /* avoid getting unnecessary lines */
3747 if (y >= lines) return 0;
3752 if (y >= lines) return lines;
3753 ySrc = y; /* need to get all lines in top down mode */
3758 if (ySrc >= startscan + lines) return lines;
3759 pt.y += ySrc + cy - (startscan + lines);
3760 cy = startscan + lines - ySrc;
3762 if (cy > lines) cy = lines;
3764 if (xSrc >= width) return lines;
3765 if (xSrc + cx >= width) cx = width - xSrc;
3766 if (!cx || !cy) return lines;
3768 /* Update the pixmap from the DIB section */
3769 X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
3771 X11DRV_SetupGCForText( physDev ); /* To have the correct colors */
3773 XSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[GetROP2(physDev->hdc) - 1]);
3774 wine_tsx11_unlock();
3776 colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
3778 switch (descr.infoBpp)
3783 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3784 coloruse == DIB_PAL_COLORS ? physDev : NULL, coloruse,
3785 physDev->depth, info, &descr.nColorMap );
3786 if (!descr.colorMap) return 0;
3787 descr.rMask = descr.gMask = descr.bMask = 0;
3791 descr.rMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr ) : 0x7c00;
3792 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr + 1) : 0x03e0;
3793 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr + 2) : 0x001f;
3799 descr.rMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr ) : 0xff0000;
3800 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr + 1) : 0x00ff00;
3801 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr + 2) : 0x0000ff;
3806 descr.physDev = physDev;
3809 descr.palentry = NULL;
3810 descr.lines = top_down ? -lines : lines;
3811 descr.infoWidth = width;
3812 descr.depth = physDev->depth;
3813 descr.drawable = physDev->drawable;
3814 descr.gc = physDev->gc;
3817 descr.xDest = physDev->org.x + pt.x;
3818 descr.yDest = physDev->org.y + pt.y;
3821 descr.useShm = FALSE;
3822 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
3824 result = X11DRV_DIB_SetImageBits( &descr );
3826 if (descr.infoBpp <= 8)
3827 HeapFree(GetProcessHeap(), 0, descr.colorMap);
3829 /* Update the DIBSection of the pixmap */
3830 X11DRV_UnlockDIBSection(physDev, TRUE);
3835 /***********************************************************************
3836 * SetDIBits (X11DRV.@)
3838 INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
3839 UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse )
3841 X_PHYSBITMAP *physBitmap = X11DRV_get_phys_bitmap( hbitmap );
3842 X11DRV_DIB_IMAGEBITS_DESCR descr;
3844 LONG height, tmpheight;
3848 descr.physDev = physDev;
3850 if (!physBitmap) return 0;
3852 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
3853 &descr.infoBpp, &descr.compression ) == -1)
3857 if (height < 0) height = -height;
3858 if (!lines || (startscan >= height))
3861 if (!GetObjectW( hbitmap, sizeof(bitmap), &bitmap )) return 0;
3863 if (startscan + lines > height) lines = height - startscan;
3865 colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
3867 switch (descr.infoBpp)
3872 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3873 coloruse == DIB_PAL_COLORS ? descr.physDev : NULL, coloruse,
3874 physBitmap->pixmap_depth,
3875 info, &descr.nColorMap );
3876 if (!descr.colorMap) return 0;
3877 descr.rMask = descr.gMask = descr.bMask = 0;
3881 descr.rMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD*)colorPtr ) : 0x7c00;
3882 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD*)colorPtr + 1) : 0x03e0;
3883 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD*)colorPtr + 2) : 0x001f;
3889 descr.rMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD*)colorPtr ) : 0xff0000;
3890 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD*)colorPtr + 1) : 0x00ff00;
3891 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD*)colorPtr + 2) : 0x0000ff;
3900 descr.palentry = NULL;
3901 descr.lines = tmpheight >= 0 ? lines : -lines;
3902 descr.depth = physBitmap->pixmap_depth;
3903 descr.drawable = physBitmap->pixmap;
3904 descr.gc = BITMAP_GC(physBitmap);
3908 descr.yDest = height - startscan - lines;
3909 descr.width = bitmap.bmWidth;
3910 descr.height = lines;
3911 descr.useShm = FALSE;
3912 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
3913 X11DRV_DIB_Lock( physBitmap, DIB_Status_GdiMod, FALSE );
3914 result = X11DRV_DIB_SetImageBits( &descr );
3915 X11DRV_DIB_Unlock( physBitmap, TRUE );
3917 HeapFree(GetProcessHeap(), 0, descr.colorMap);
3922 /***********************************************************************
3923 * GetDIBits (X11DRV.@)
3925 INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, UINT lines,
3926 LPVOID bits, BITMAPINFO *info, UINT coloruse )
3928 X_PHYSBITMAP *physBitmap = X11DRV_get_phys_bitmap( hbitmap );
3930 X11DRV_DIB_IMAGEBITS_DESCR descr;
3931 PALETTEENTRY palette[256];
3939 GetPaletteEntries( GetCurrentObject( physDev->hdc, OBJ_PAL ), 0, 256, palette );
3941 if (!physBitmap) return 0;
3942 if (!(obj_size = GetObjectW( hbitmap, sizeof(dib), &dib ))) return 0;
3944 bitmap_type = DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &descr.infoWidth, &tempHeight, &descr.infoBpp, &descr.compression);
3945 descr.lines = tempHeight;
3946 if (bitmap_type == -1)
3948 ERR("Invalid bitmap\n");
3951 core_header = (bitmap_type == 0);
3952 colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
3954 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3955 lines, dib.dsBm.bmWidth, dib.dsBm.bmHeight, (int)descr.infoWidth, descr.lines, startscan);
3957 if( lines > dib.dsBm.bmHeight ) lines = dib.dsBm.bmHeight;
3959 height = descr.lines;
3960 if (height < 0) height = -height;
3961 if( lines > height ) lines = height;
3962 /* Top-down images have a negative biHeight, the scanlines of theses images
3963 * were inverted in X11DRV_DIB_GetImageBits_xx
3964 * To prevent this we simply change the sign of lines
3965 * (the number of scan lines to copy).
3966 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3968 if( descr.lines < 0 && lines > 0) lines = -lines;
3970 if( startscan >= dib.dsBm.bmHeight ) return 0;
3972 descr.colorMap = NULL;
3974 switch (descr.infoBpp)
3979 descr.rMask= descr.gMask = descr.bMask = 0;
3980 if(coloruse == DIB_RGB_COLORS)
3981 descr.colorMap = colorPtr;
3983 int num_colors = 1 << descr.infoBpp, i;
3986 WORD *index = (WORD*)colorPtr;
3987 descr.colorMap = rgb = HeapAlloc(GetProcessHeap(), 0, num_colors * sizeof(RGBQUAD));
3988 for(i = 0; i < num_colors; i++, rgb++, index++) {
3989 colref = X11DRV_PALETTE_ToLogical(X11DRV_PALETTE_ToPhysical(physDev, PALETTEINDEX(*index)));
3990 rgb->rgbRed = GetRValue(colref);
3991 rgb->rgbGreen = GetGValue(colref);
3992 rgb->rgbBlue = GetBValue(colref);
3993 rgb->rgbReserved = 0;
3999 descr.rMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr ) : 0x7c00;
4000 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
4001 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
4005 descr.rMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr ) : 0xff0000;
4006 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
4007 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
4011 descr.physDev = physDev;
4012 descr.palentry = palette;
4015 descr.lines = lines;
4016 descr.depth = physBitmap->pixmap_depth;
4017 descr.drawable = physBitmap->pixmap;
4018 descr.gc = BITMAP_GC(physBitmap);
4019 descr.width = dib.dsBm.bmWidth;
4020 descr.height = dib.dsBm.bmHeight;
4024 descr.sizeImage = core_header ? 0 : info->bmiHeader.biSizeImage;
4026 if (descr.lines > 0)
4028 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
4032 descr.ySrc = startscan;
4034 #ifdef HAVE_LIBXXSHM
4035 descr.useShm = (obj_size == sizeof(DIBSECTION)) && (physBitmap->shminfo.shmid != -1);
4037 descr.useShm = FALSE;
4039 descr.dibpitch = (obj_size == sizeof(DIBSECTION)) ? dib.dsBm.bmWidthBytes
4040 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
4042 X11DRV_DIB_Lock( physBitmap, DIB_Status_GdiMod, FALSE );
4043 X11DRV_DIB_GetImageBits( &descr );
4044 X11DRV_DIB_Unlock( physBitmap, TRUE );
4046 if(!core_header && info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
4047 info->bmiHeader.biSizeImage = X11DRV_DIB_GetDIBImageBytes( descr.infoWidth,
4051 if (descr.compression == BI_BITFIELDS)
4053 *(DWORD *) colorPtr = descr.rMask;
4054 *((DWORD *)colorPtr + 1) = descr.gMask;
4055 *((DWORD *)colorPtr + 2) = descr.bMask;
4057 else if (!core_header)
4059 /* if RLE or JPEG compression were supported,
4060 * this line would be invalid. */
4061 info->bmiHeader.biCompression = 0;
4064 if(descr.colorMap && descr.colorMap != colorPtr)
4065 HeapFree(GetProcessHeap(), 0, descr.colorMap);
4069 /***********************************************************************
4070 * DIB_DoProtectDIBSection
4072 static void X11DRV_DIB_DoProtectDIBSection( X_PHYSBITMAP *physBitmap, DWORD new_prot )
4077 GetObjectW( physBitmap->hbitmap, sizeof(dib), &dib );
4078 VirtualProtect(dib.dsBm.bmBits, dib.dsBmih.biSizeImage, new_prot, &old_prot);
4079 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
4082 /***********************************************************************
4083 * X11DRV_DIB_DoCopyDIBSection
4085 static void X11DRV_DIB_DoCopyDIBSection(X_PHYSBITMAP *physBitmap, BOOL toDIB,
4086 void *colorMap, int nColorMap,
4088 DWORD xSrc, DWORD ySrc,
4089 DWORD xDest, DWORD yDest,
4090 DWORD width, DWORD height)
4092 DIBSECTION dibSection;
4093 X11DRV_DIB_IMAGEBITS_DESCR descr;
4094 int identity[2] = {0,1};
4096 if (!GetObjectW( physBitmap->hbitmap, sizeof(dibSection), &dibSection )) return;
4098 descr.physDev = NULL;
4099 descr.palentry = NULL;
4100 descr.infoWidth = dibSection.dsBmih.biWidth;
4101 descr.infoBpp = dibSection.dsBmih.biBitCount;
4102 descr.lines = dibSection.dsBmih.biHeight;
4103 descr.image = physBitmap->image;
4104 descr.colorMap = colorMap;
4105 descr.nColorMap = nColorMap;
4106 descr.bits = dibSection.dsBm.bmBits;
4107 descr.depth = physBitmap->pixmap_depth;
4108 descr.compression = dibSection.dsBmih.biCompression;
4110 if(descr.infoBpp == 1)
4111 descr.colorMap = (void*)identity;
4113 switch (descr.infoBpp)
4118 descr.rMask = descr.gMask = descr.bMask = 0;
4122 descr.rMask = (descr.compression == BI_BITFIELDS) ? dibSection.dsBitfields[0] : 0x7c00;
4123 descr.gMask = (descr.compression == BI_BITFIELDS) ? dibSection.dsBitfields[1] : 0x03e0;
4124 descr.bMask = (descr.compression == BI_BITFIELDS) ? dibSection.dsBitfields[2] : 0x001f;
4129 descr.rMask = (descr.compression == BI_BITFIELDS) ? dibSection.dsBitfields[0] : 0xff0000;
4130 descr.gMask = (descr.compression == BI_BITFIELDS) ? dibSection.dsBitfields[1] : 0x00ff00;
4131 descr.bMask = (descr.compression == BI_BITFIELDS) ? dibSection.dsBitfields[2] : 0x0000ff;
4136 descr.drawable = dest;
4137 descr.gc = BITMAP_GC(physBitmap);
4140 descr.xDest = xDest;
4141 descr.yDest = yDest;
4142 descr.width = width;
4143 descr.height = height;
4144 descr.sizeImage = 0;
4146 #ifdef HAVE_LIBXXSHM
4147 descr.useShm = (physBitmap->shminfo.shmid != -1);
4149 descr.useShm = FALSE;
4151 descr.dibpitch = dibSection.dsBm.bmWidthBytes;
4155 TRACE("Copying from Pixmap to DIB bits\n");
4156 X11DRV_DIB_GetImageBits( &descr );
4160 TRACE("Copying from DIB bits to Pixmap\n");
4161 X11DRV_DIB_SetImageBits( &descr );
4165 /***********************************************************************
4166 * X11DRV_DIB_CopyDIBSection
4168 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
4169 DWORD xSrc, DWORD ySrc, DWORD xDest, DWORD yDest,
4170 DWORD width, DWORD height)
4173 X_PHYSBITMAP *physBitmap;
4174 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
4176 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", physDevSrc->hdc, physDevDst->hdc,
4177 xSrc, ySrc, xDest, yDest, width, height);
4178 /* this function is meant as an optimization for BitBlt,
4179 * not to be called otherwise */
4180 physBitmap = physDevSrc->bitmap;
4181 if (!physBitmap || GetObjectW( physBitmap->hbitmap, sizeof(dib), &dib ) != sizeof(dib))
4183 ERR("called for non-DIBSection!?\n");
4186 /* while BitBlt should already have made sure we only get
4187 * positive values, we should check for oversize values */
4188 if ((xSrc < dib.dsBm.bmWidth) &&
4189 (ySrc < dib.dsBm.bmHeight)) {
4190 if (xSrc + width > dib.dsBm.bmWidth)
4191 width = dib.dsBm.bmWidth - xSrc;
4192 if (ySrc + height > dib.dsBm.bmHeight)
4193 height = dib.dsBm.bmHeight - ySrc;
4194 /* if the source bitmap is 8bpp or less, we're supposed to use the
4195 * DC's palette for color conversion (not the DIB color table) */
4196 if (dib.dsBm.bmBitsPixel <= 8) {
4197 HPALETTE hPalette = GetCurrentObject( physDevSrc->hdc, OBJ_PAL );
4198 if (!hPalette || (hPalette == GetStockObject(DEFAULT_PALETTE))) {
4199 /* HACK: no palette has been set in the source DC,
4200 * use the DIB colormap instead - this is necessary in some
4201 * cases since we need to do depth conversion in some places
4202 * where real Windows can just copy data straight over */
4203 colorMap = physBitmap->colorMap;
4204 nColorMap = physBitmap->nColorMap;
4206 colorMap = X11DRV_DIB_BuildColorMap( physDevSrc, (WORD)-1,
4207 dib.dsBm.bmBitsPixel,
4208 (BITMAPINFO*)&dib.dsBmih,
4210 if (colorMap) aColorMap = TRUE;
4213 /* perform the copy */
4214 X11DRV_DIB_DoCopyDIBSection(physBitmap, FALSE, colorMap, nColorMap,
4215 physDevDst->drawable, xSrc, ySrc,
4216 physDevDst->org.x + xDest, physDevDst->org.y + yDest,
4218 /* free color mapping */
4220 HeapFree(GetProcessHeap(), 0, colorMap);
4224 /***********************************************************************
4225 * X11DRV_DIB_DoUpdateDIBSection
4227 static void X11DRV_DIB_DoUpdateDIBSection(X_PHYSBITMAP *physBitmap, BOOL toDIB)
4231 GetObjectW( physBitmap->hbitmap, sizeof(bitmap), &bitmap );
4232 X11DRV_DIB_DoCopyDIBSection(physBitmap, toDIB,
4233 physBitmap->colorMap, physBitmap->nColorMap,
4234 physBitmap->pixmap, 0, 0, 0, 0,
4235 bitmap.bmWidth, bitmap.bmHeight);
4238 /***********************************************************************
4239 * X11DRV_DIB_FaultHandler
4241 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
4243 X_PHYSBITMAP *physBitmap = res;
4244 INT state = X11DRV_DIB_Lock( physBitmap, DIB_Status_None, FALSE );
4246 if (state != DIB_Status_InSync) {
4247 /* no way to tell whether app needs read or write yet,
4249 X11DRV_DIB_Coerce( physBitmap, DIB_Status_InSync, FALSE );
4251 /* hm, apparently the app must have write access */
4252 X11DRV_DIB_Coerce( physBitmap, DIB_Status_AppMod, FALSE );
4254 X11DRV_DIB_Unlock( physBitmap, TRUE );
4259 /***********************************************************************
4262 static INT X11DRV_DIB_Coerce(X_PHYSBITMAP *physBitmap, INT req, BOOL lossy)
4264 INT ret = DIB_Status_None;
4266 if (!physBitmap->image) return ret; /* not a DIB section */
4267 EnterCriticalSection(&physBitmap->lock);
4268 ret = physBitmap->status;
4270 case DIB_Status_GdiMod:
4271 /* GDI access - request to draw on pixmap */
4272 switch (physBitmap->status)
4275 case DIB_Status_None:
4276 physBitmap->p_status = DIB_Status_GdiMod;
4277 X11DRV_DIB_DoUpdateDIBSection( physBitmap, FALSE );
4280 case DIB_Status_GdiMod:
4281 TRACE("GdiMod requested in status GdiMod\n" );
4282 physBitmap->p_status = DIB_Status_GdiMod;
4285 case DIB_Status_InSync:
4286 TRACE("GdiMod requested in status InSync\n" );
4287 X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_NOACCESS );
4288 physBitmap->status = DIB_Status_GdiMod;
4289 physBitmap->p_status = DIB_Status_InSync;
4292 case DIB_Status_AppMod:
4293 TRACE("GdiMod requested in status AppMod\n" );
4295 /* make it readonly to avoid app changing data while we copy */
4296 X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READONLY );
4297 X11DRV_DIB_DoUpdateDIBSection( physBitmap, FALSE );
4299 X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_NOACCESS );
4300 physBitmap->p_status = DIB_Status_AppMod;
4301 physBitmap->status = DIB_Status_GdiMod;
4306 case DIB_Status_InSync:
4307 /* App access - request access to read DIB surface */
4308 /* (typically called from signal handler) */
4309 switch (physBitmap->status)
4312 case DIB_Status_None:
4313 /* shouldn't happen from signal handler */
4316 case DIB_Status_GdiMod:
4317 TRACE("InSync requested in status GdiMod\n" );
4319 X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READWRITE );
4320 X11DRV_DIB_DoUpdateDIBSection( physBitmap, TRUE );
4322 X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READONLY );
4323 physBitmap->status = DIB_Status_InSync;
4326 case DIB_Status_InSync:
4327 TRACE("InSync requested in status InSync\n" );
4328 /* shouldn't happen from signal handler */
4331 case DIB_Status_AppMod:
4332 TRACE("InSync requested in status AppMod\n" );
4333 /* no reason to do anything here, and this
4334 * shouldn't happen from signal handler */
4339 case DIB_Status_AppMod:
4340 /* App access - request access to write DIB surface */
4341 /* (typically called from signal handler) */
4342 switch (physBitmap->status)
4345 case DIB_Status_None:
4346 /* shouldn't happen from signal handler */
4349 case DIB_Status_GdiMod:
4350 TRACE("AppMod requested in status GdiMod\n" );
4351 X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READWRITE );
4352 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( physBitmap, TRUE );
4353 physBitmap->status = DIB_Status_AppMod;
4356 case DIB_Status_InSync:
4357 TRACE("AppMod requested in status InSync\n" );
4358 X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READWRITE );
4359 physBitmap->status = DIB_Status_AppMod;
4362 case DIB_Status_AppMod:
4363 TRACE("AppMod requested in status AppMod\n" );
4364 /* shouldn't happen from signal handler */
4369 /* it is up to the caller to do the copy/conversion, probably
4370 * using the return value to decide where to copy from */
4372 LeaveCriticalSection(&physBitmap->lock);
4376 /***********************************************************************
4379 static INT X11DRV_DIB_Lock(X_PHYSBITMAP *physBitmap, INT req, BOOL lossy)
4381 INT ret = DIB_Status_None;
4383 if (!physBitmap->image) return ret; /* not a DIB section */
4384 TRACE("Locking %p from thread %04lx\n", physBitmap->hbitmap, GetCurrentThreadId());
4385 EnterCriticalSection(&physBitmap->lock);
4386 ret = physBitmap->status;
4387 if (req != DIB_Status_None)
4388 X11DRV_DIB_Coerce(physBitmap, req, lossy);
4392 /***********************************************************************
4395 static void X11DRV_DIB_Unlock(X_PHYSBITMAP *physBitmap, BOOL commit)
4397 if (!physBitmap->image) return; /* not a DIB section */
4398 switch (physBitmap->status)
4401 case DIB_Status_None:
4402 /* in case anyone is wondering, this is the "signal handler doesn't
4403 * work" case, where we always have to be ready for app access */
4405 switch (physBitmap->p_status)
4407 case DIB_Status_GdiMod:
4408 TRACE("Unlocking and syncing from GdiMod\n" );
4409 X11DRV_DIB_DoUpdateDIBSection( physBitmap, TRUE );
4413 TRACE("Unlocking without needing to sync\n" );
4417 else TRACE("Unlocking with no changes\n");
4418 physBitmap->p_status = DIB_Status_None;
4421 case DIB_Status_GdiMod:
4422 TRACE("Unlocking in status GdiMod\n" );
4423 /* DIB was protected in Coerce */
4425 /* no commit, revert to InSync if applicable */
4426 if ((physBitmap->p_status == DIB_Status_InSync) ||
4427 (physBitmap->p_status == DIB_Status_AppMod)) {
4428 X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READONLY );
4429 physBitmap->status = DIB_Status_InSync;
4434 case DIB_Status_InSync:
4435 TRACE("Unlocking in status InSync\n" );
4436 /* DIB was already protected in Coerce */
4439 case DIB_Status_AppMod:
4440 TRACE("Unlocking in status AppMod\n" );
4441 /* DIB was already protected in Coerce */
4442 /* this case is ordinary only called from the signal handler,
4443 * so we don't bother to check for !commit */
4446 LeaveCriticalSection(&physBitmap->lock);
4447 TRACE("Unlocked %p\n", physBitmap->hbitmap);
4450 /***********************************************************************
4451 * X11DRV_CoerceDIBSection
4453 INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
4455 if (!physDev || !physDev->bitmap) return DIB_Status_None;
4456 return X11DRV_DIB_Coerce(physDev->bitmap, req, lossy);
4459 /***********************************************************************
4460 * X11DRV_LockDIBSection
4462 INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
4464 if (!physDev || !physDev->bitmap) return DIB_Status_None;
4465 return X11DRV_DIB_Lock(physDev->bitmap, req, lossy);
4468 /***********************************************************************
4469 * X11DRV_UnlockDIBSection
4471 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev, BOOL commit)
4473 if (!physDev || !physDev->bitmap) return;
4474 X11DRV_DIB_Unlock(physDev->bitmap, commit);
4478 #ifdef HAVE_LIBXXSHM
4479 /***********************************************************************
4480 * X11DRV_XShmErrorHandler
4483 static int XShmErrorHandler( Display *dpy, XErrorEvent *event, void *arg )
4485 return 1; /* FIXME: should check event contents */
4488 /***********************************************************************
4489 * X11DRV_XShmCreateImage
4492 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
4493 XShmSegmentInfo* shminfo)
4497 image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
4500 shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
4502 if( shminfo->shmid != -1 )
4504 shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
4505 if( shminfo->shmaddr != (char*)-1 )
4509 shminfo->readOnly = FALSE;
4510 X11DRV_expect_error( gdi_display, XShmErrorHandler, NULL );
4511 ok = (XShmAttach( gdi_display, shminfo ) != 0);
4512 XSync( gdi_display, False );
4513 if (X11DRV_check_error()) ok = FALSE;
4516 shmctl(shminfo->shmid, IPC_RMID, 0);
4517 return image; /* Success! */
4519 /* An error occurred */
4520 shmdt(shminfo->shmaddr);
4522 shmctl(shminfo->shmid, IPC_RMID, 0);
4524 XFlush(gdi_display);
4525 XDestroyImage(image);
4530 #endif /* HAVE_LIBXXSHM */
4533 /***********************************************************************
4534 * X11DRV_CreateDIBSection (X11DRV.@)
4536 HBITMAP X11DRV_CreateDIBSection( X11DRV_PDEVICE *physDev, HBITMAP hbitmap,
4537 const BITMAPINFO *bmi, UINT usage )
4539 extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, BOOL (*proc)(LPVOID, LPCVOID), LPVOID arg);
4540 X_PHYSBITMAP *physBitmap;
4543 if (!(physBitmap = X11DRV_init_phys_bitmap( hbitmap ))) return 0;
4544 physBitmap->status = DIB_Status_None;
4546 GetObjectW( hbitmap, sizeof(dib), &dib );
4548 /* create color map */
4549 if (dib.dsBm.bmBitsPixel <= 8)
4551 physBitmap->colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS ? physDev : NULL,
4552 usage, dib.dsBm.bmBitsPixel, bmi,
4553 &physBitmap->nColorMap );
4554 physBitmap->colorTable = X11DRV_DIB_BuildColorTable( physDev, usage, dib.dsBm.bmBitsPixel, bmi );
4557 /* create pixmap and X image */
4559 physBitmap->pixmap_depth = (dib.dsBm.bmBitsPixel == 1) ? 1 : screen_depth;
4560 physBitmap->pixmap = XCreatePixmap( gdi_display, root_window, dib.dsBm.bmWidth,
4561 dib.dsBm.bmHeight, physBitmap->pixmap_depth );
4562 #ifdef HAVE_LIBXXSHM
4563 physBitmap->shminfo.shmid = -1;
4564 if (!XShmQueryExtension(gdi_display) ||
4565 !(physBitmap->image = X11DRV_XShmCreateImage( dib.dsBm.bmWidth, dib.dsBm.bmHeight,
4566 physBitmap->pixmap_depth, &physBitmap->shminfo )) )
4568 physBitmap->image = X11DRV_DIB_CreateXImage( dib.dsBm.bmWidth, dib.dsBm.bmHeight,
4569 physBitmap->pixmap_depth );
4570 wine_tsx11_unlock();
4571 if (!physBitmap->pixmap || !physBitmap->image) return 0;
4573 /* install fault handler */
4574 InitializeCriticalSection( &physBitmap->lock );
4575 if (VIRTUAL_SetFaultHandler(dib.dsBm.bmBits, X11DRV_DIB_FaultHandler, physBitmap))
4577 X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READWRITE );
4578 physBitmap->status = DIB_Status_AppMod;
4584 /***********************************************************************
4585 * X11DRV_DIB_DeleteDIBSection
4587 void X11DRV_DIB_DeleteDIBSection(X_PHYSBITMAP *physBitmap, DIBSECTION *dib)
4589 if (dib->dshSection)
4590 X11DRV_DIB_Coerce(physBitmap, DIB_Status_InSync, FALSE);
4592 if (physBitmap->image)
4595 #ifdef HAVE_LIBXXSHM
4596 if (physBitmap->shminfo.shmid != -1)
4598 XShmDetach( gdi_display, &(physBitmap->shminfo) );
4599 XDestroyImage( physBitmap->image );
4600 shmdt( physBitmap->shminfo.shmaddr );
4601 physBitmap->shminfo.shmid = -1;
4605 XDestroyImage( physBitmap->image );
4606 wine_tsx11_unlock();
4609 HeapFree(GetProcessHeap(), 0, physBitmap->colorMap);
4610 HeapFree(GetProcessHeap(), 0, physBitmap->colorTable);
4611 DeleteCriticalSection(&physBitmap->lock);
4614 /***********************************************************************
4615 * SetDIBColorTable (X11DRV.@)
4617 UINT X11DRV_SetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, const RGBQUAD *colors )
4621 X_PHYSBITMAP *physBitmap = physDev->bitmap;
4623 if (!physBitmap) return 0;
4624 GetObjectW( physBitmap->hbitmap, sizeof(dib), &dib );
4626 if (physBitmap->colorMap && start < physBitmap->nColorMap) {
4627 UINT end = count + start;
4628 if (end > physBitmap->nColorMap) end = physBitmap->nColorMap;
4630 * Changing color table might change the mapping between
4631 * DIB colors and X11 colors and thus alter the visible state
4632 * of the bitmap object.
4634 X11DRV_DIB_Lock( physBitmap, DIB_Status_AppMod, FALSE );
4635 memcpy(physBitmap->colorTable + start, colors, (end - start) * sizeof(RGBQUAD));
4636 X11DRV_DIB_GenColorMap( physDev, physBitmap->colorMap, DIB_RGB_COLORS,
4637 dib.dsBm.bmBitsPixel,
4638 TRUE, colors, start, end );
4639 X11DRV_DIB_Unlock( physBitmap, TRUE );
4645 /***********************************************************************
4646 * GetDIBColorTable (X11DRV.@)
4648 UINT X11DRV_GetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, RGBQUAD *colors )
4651 X_PHYSBITMAP *physBitmap = physDev->bitmap;
4653 if (physBitmap && physBitmap->colorTable && start < physBitmap->nColorMap) {
4654 if (start + count > physBitmap->nColorMap) count = physBitmap->nColorMap - start;
4655 memcpy(colors, physBitmap->colorTable + start, count * sizeof(RGBQUAD));
4663 /***********************************************************************
4664 * X11DRV_DIB_CreateDIBFromBitmap
4666 * Allocates a packed DIB and copies the bitmap data into it.
4668 HGLOBAL X11DRV_DIB_CreateDIBFromBitmap(HDC hdc, HBITMAP hBmp)
4673 LPBITMAPINFOHEADER pbmiHeader;
4674 unsigned int cDataSize, cPackedSize, OffsetBits;
4677 if (!GetObjectW( hBmp, sizeof(bmp), &bmp )) return 0;
4680 * A packed DIB contains a BITMAPINFO structure followed immediately by
4681 * an optional color palette and the pixel data.
4684 /* Calculate the size of the packed DIB */
4685 cDataSize = X11DRV_DIB_GetDIBWidthBytes( bmp.bmWidth, bmp.bmBitsPixel ) * abs( bmp.bmHeight );
4686 cPackedSize = sizeof(BITMAPINFOHEADER)
4687 + ( (bmp.bmBitsPixel <= 8) ? (sizeof(RGBQUAD) * (1 << bmp.bmBitsPixel)) : 0 )
4689 /* Get the offset to the bits */
4690 OffsetBits = cPackedSize - cDataSize;
4692 /* Allocate the packed DIB */
4693 TRACE("\tAllocating packed DIB of size %d\n", cPackedSize);
4694 hPackedDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE /*| GMEM_ZEROINIT*/,
4698 WARN("Could not allocate packed DIB!\n");
4702 /* A packed DIB starts with a BITMAPINFOHEADER */
4703 pPackedDIB = GlobalLock(hPackedDIB);
4704 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
4706 /* Init the BITMAPINFOHEADER */
4707 pbmiHeader->biSize = sizeof(BITMAPINFOHEADER);
4708 pbmiHeader->biWidth = bmp.bmWidth;
4709 pbmiHeader->biHeight = bmp.bmHeight;
4710 pbmiHeader->biPlanes = 1;
4711 pbmiHeader->biBitCount = bmp.bmBitsPixel;
4712 pbmiHeader->biCompression = BI_RGB;
4713 pbmiHeader->biSizeImage = 0;
4714 pbmiHeader->biXPelsPerMeter = pbmiHeader->biYPelsPerMeter = 0;
4715 pbmiHeader->biClrUsed = 0;
4716 pbmiHeader->biClrImportant = 0;
4718 /* Retrieve the DIB bits from the bitmap and fill in the
4719 * DIB color table if present */
4721 nLinesCopied = GetDIBits(hdc, /* Handle to device context */
4722 hBmp, /* Handle to bitmap */
4723 0, /* First scan line to set in dest bitmap */
4724 bmp.bmHeight, /* Number of scan lines to copy */
4725 pPackedDIB + OffsetBits, /* [out] Address of array for bitmap bits */
4726 (LPBITMAPINFO) pbmiHeader, /* [out] Address of BITMAPINFO structure */
4727 0); /* RGB or palette index */
4728 GlobalUnlock(hPackedDIB);
4730 /* Cleanup if GetDIBits failed */
4731 if (nLinesCopied != bmp.bmHeight)
4733 TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied, bmp.bmHeight);
4734 GlobalFree(hPackedDIB);
4741 /**************************************************************************
4742 * X11DRV_DIB_CreateDIBFromPixmap
4744 * Allocates a packed DIB and copies the Pixmap data into it.
4745 * The Pixmap passed in is deleted after the conversion.
4747 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc)
4750 X_PHYSBITMAP *physBitmap;
4751 HBITMAP hBmp = 0, old;
4752 HGLOBAL hPackedDIB = 0;
4754 int x,y; /* Unused */
4755 unsigned border_width; /* Unused */
4756 unsigned int depth, width, height;
4758 /* Get the Pixmap dimensions and bit depth */
4760 if (!XGetGeometry(gdi_display, pixmap, &root, &x, &y, &width, &height,
4761 &border_width, &depth)) depth = 0;
4762 wine_tsx11_unlock();
4763 if (!depth) return 0;
4765 TRACE("\tPixmap properties: width=%d, height=%d, depth=%d\n",
4766 width, height, depth);
4769 * Create an HBITMAP with the same dimensions and BPP as the pixmap,
4770 * and make it a container for the pixmap passed.
4772 hBmp = CreateBitmap( width, height, 1, depth, NULL );
4774 /* force bitmap to be owned by a screen DC */
4775 hdcMem = CreateCompatibleDC( hdc );
4776 old = SelectObject( hdcMem, hBmp );
4778 physBitmap = X11DRV_get_phys_bitmap( hBmp );
4781 if (physBitmap->pixmap) XFreePixmap( gdi_display, physBitmap->pixmap );
4782 physBitmap->pixmap = pixmap;
4783 wine_tsx11_unlock();
4785 SelectObject( hdcMem, old );
4789 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4790 * A packed DIB contains a BITMAPINFO structure followed immediately by
4791 * an optional color palette and the pixel data.
4793 hPackedDIB = X11DRV_DIB_CreateDIBFromBitmap(hdc, hBmp);
4795 /* We can now get rid of the HBITMAP wrapper we created earlier.
4796 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4800 TRACE("\tReturning packed DIB %p\n", hPackedDIB);
4805 /**************************************************************************
4806 * X11DRV_DIB_CreatePixmapFromDIB
4808 * Creates a Pixmap from a packed DIB
4810 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
4813 X_PHYSBITMAP *physBitmap;
4817 /* Create a DDB from the DIB */
4819 pbmi = GlobalLock(hPackedDIB);
4820 hBmp = CreateDIBitmap(hdc, &pbmi->bmiHeader, CBM_INIT,
4821 (LPBYTE)pbmi + X11DRV_DIB_BitmapInfoSize( pbmi, DIB_RGB_COLORS ),
4822 pbmi, DIB_RGB_COLORS);
4823 GlobalUnlock(hPackedDIB);
4825 /* clear the physBitmap so that we can steal its pixmap */
4826 physBitmap = X11DRV_get_phys_bitmap( hBmp );
4827 pixmap = physBitmap->pixmap;
4828 physBitmap->pixmap = 0;
4830 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4833 TRACE("Returning Pixmap %ld\n", pixmap);