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 */
86 /***********************************************************************
87 * X11DRV_DIB_GetXImageWidthBytes
89 * Return the width of an X image in bytes
91 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
93 if (!depth || depth > 32) goto error;
95 if (!ximageDepthTable[depth-1])
97 XImage *testimage = XCreateImage( gdi_display, visual, depth,
98 ZPixmap, 0, NULL, 1, 1, 32, 20 );
101 ximageDepthTable[depth-1] = testimage->bits_per_pixel;
102 XDestroyImage( testimage );
104 else ximageDepthTable[depth-1] = -1;
106 if (ximageDepthTable[depth-1] != -1)
107 return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
110 WARN( "(%d): Unsupported depth\n", depth );
115 /***********************************************************************
116 * X11DRV_DIB_GetDIBWidthBytes
118 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
120 static int X11DRV_DIB_GetDIBWidthBytes( int width, int depth )
126 case 1: words = (width + 31) / 32; break;
127 case 4: words = (width + 7) / 8; break;
128 case 8: words = (width + 3) / 4; break;
130 case 16: words = (width + 1) / 2; break;
131 case 24: words = (width * 3 + 3) / 4; break;
133 WARN("(%d): Unsupported depth\n", depth );
142 /***********************************************************************
143 * X11DRV_DIB_BitmapInfoSize
145 * Return the size of the bitmap info structure including color table.
147 int X11DRV_DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
151 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
153 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
154 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
155 return sizeof(BITMAPCOREHEADER) + colors *
156 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
158 else /* assume BITMAPINFOHEADER */
160 colors = info->bmiHeader.biClrUsed;
161 if (!colors && (info->bmiHeader.biBitCount <= 8))
162 colors = 1 << info->bmiHeader.biBitCount;
163 return sizeof(BITMAPINFOHEADER) + colors *
164 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
169 /***********************************************************************
170 * X11DRV_DIB_CreateXImage
174 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
180 width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
181 image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
182 calloc( height, width_bytes ),
183 width, height, 32, width_bytes );
189 /***********************************************************************
192 * Get the info from a bitmap header.
193 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
195 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
196 int *height, WORD *bpp, WORD *compr )
198 if (header->biSize == sizeof(BITMAPCOREHEADER))
200 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
201 *width = core->bcWidth;
202 *height = core->bcHeight;
203 *bpp = core->bcBitCount;
207 if (header->biSize >= sizeof(BITMAPINFOHEADER))
209 *width = header->biWidth;
210 *height = header->biHeight;
211 *bpp = header->biBitCount;
212 *compr = header->biCompression;
215 ERR("(%ld): unknown/wrong size for header\n", header->biSize );
220 /***********************************************************************
221 * X11DRV_DIB_GenColorMap
223 * Fills the color map of a bitmap palette. Should not be called
224 * for a >8-bit deep bitmap.
226 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
227 WORD coloruse, WORD depth, BOOL quads,
228 const void *colorPtr, int start, int end )
232 if (coloruse == DIB_RGB_COLORS)
234 int max = 1 << depth;
236 if (end > max) end = max;
240 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
242 if (depth == 1) /* Monochrome */
243 for (i = start; i < end; i++, rgb++)
244 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
245 rgb->rgbBlue > 255*3/2);
247 for (i = start; i < end; i++, rgb++)
248 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbRed,
254 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
256 if (depth == 1) /* Monochrome */
257 for (i = start; i < end; i++, rgb++)
258 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
259 rgb->rgbtBlue > 255*3/2);
261 for (i = start; i < end; i++, rgb++)
262 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbtRed,
267 else /* DIB_PAL_COLORS */
270 WORD * index = (WORD *)colorPtr;
272 for (i = start; i < end; i++, index++)
273 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(*index) );
275 for (i = start; i < end; i++)
276 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(i) );
283 /***********************************************************************
284 * X11DRV_DIB_BuildColorMap
286 * Build the color map from the bitmap palette. Should not be called
287 * for a >8-bit deep bitmap.
289 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
290 const BITMAPINFO *info, int *nColors )
294 const void *colorPtr;
297 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
299 colors = info->bmiHeader.biClrUsed;
300 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
301 colorPtr = info->bmiColors;
303 else /* assume BITMAPCOREINFO */
305 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
306 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
311 ERR("called with >256 colors!\n");
315 /* just so CopyDIBSection doesn't have to create an identity palette */
316 if (coloruse == (WORD)-1) colorPtr = NULL;
318 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
319 colors * sizeof(int) )))
323 return X11DRV_DIB_GenColorMap( physDev, colorMapping, coloruse, depth,
324 isInfo, colorPtr, 0, colors);
328 /***********************************************************************
329 * X11DRV_DIB_MapColor
331 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
335 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
338 for (color = 0; color < nPhysMap; color++)
339 if (physMap[color] == phys)
342 WARN("Strange color %08x\n", phys);
347 /*********************************************************************
348 * X11DRV_DIB_GetNearestIndex
350 * Helper for X11DRV_DIB_GetDIBits.
351 * Returns the nearest colour table index for a given RGB.
352 * Nearest is defined by minimizing the sum of the squares.
354 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
356 INT i, best = -1, diff, bestdiff = -1;
359 for(color = colormap, i = 0; i < numColors; color++, i++) {
360 diff = (r - color->rgbRed) * (r - color->rgbRed) +
361 (g - color->rgbGreen) * (g - color->rgbGreen) +
362 (b - color->rgbBlue) * (b - color->rgbBlue);
365 if(best == -1 || diff < bestdiff) {
372 /*********************************************************************
373 * X11DRV_DIB_MaskToShift
375 * Helper for X11DRV_DIB_GetDIBits.
376 * Returns the by how many bits to shift a given color so that it is
377 * in the proper position.
379 INT X11DRV_DIB_MaskToShift(DWORD mask)
387 while ((mask&1)==0) {
394 /***********************************************************************
395 * X11DRV_DIB_SetImageBits_1
397 * SetDIBits for a 1-bit deep DIB.
399 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
400 DWORD srcwidth, DWORD dstwidth, int left,
401 int *colors, XImage *bmpImage, DWORD linebytes)
410 srcbits = srcbits + linebytes * (lines - 1);
411 linebytes = -linebytes;
414 if ((extra = (left & 7)) != 0) {
418 srcbits += left >> 3;
420 /* ==== pal 1 dib -> any bmp format ==== */
421 for (h = lines-1; h >=0; h--) {
423 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
424 for (i = dstwidth/8, x = left; i > 0; i--) {
426 XPutPixel( bmpImage, x++, h, colors[ srcval >> 7] );
427 XPutPixel( bmpImage, x++, h, colors[(srcval >> 6) & 1] );
428 XPutPixel( bmpImage, x++, h, colors[(srcval >> 5) & 1] );
429 XPutPixel( bmpImage, x++, h, colors[(srcval >> 4) & 1] );
430 XPutPixel( bmpImage, x++, h, colors[(srcval >> 3) & 1] );
431 XPutPixel( bmpImage, x++, h, colors[(srcval >> 2) & 1] );
432 XPutPixel( bmpImage, x++, h, colors[(srcval >> 1) & 1] );
433 XPutPixel( bmpImage, x++, h, colors[ srcval & 1] );
437 switch (dstwidth & 7)
439 case 7: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
440 case 6: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
441 case 5: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
442 case 4: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
443 case 3: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
444 case 2: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
445 case 1: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]);
448 srcbits += linebytes;
452 /***********************************************************************
453 * X11DRV_DIB_GetImageBits_1
455 * GetDIBits for a 1-bit deep DIB.
457 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
458 DWORD dstwidth, DWORD srcwidth,
459 RGBQUAD *colors, PALETTEENTRY *srccolors,
460 XImage *bmpImage, DWORD linebytes )
467 dstbits = dstbits + linebytes * (lines - 1);
468 linebytes = -linebytes;
471 switch (bmpImage->depth)
475 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
476 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
479 for (h=lines-1; h>=0; h--) {
483 for (x=0; x<dstwidth; x++) {
485 srcval=srccolors[XGetPixel(bmpImage, x, h)];
486 dstval|=(X11DRV_DIB_GetNearestIndex
490 srcval.peBlue) << (7 - (x & 7)));
496 if ((dstwidth&7)!=0) {
499 dstbits += linebytes;
507 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
508 /* ==== pal 8 bmp -> pal 1 dib ==== */
510 const BYTE* srcpixel;
513 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
515 for (h=0; h<lines; h++) {
520 for (x=0; x<dstwidth; x++) {
522 srcval=srccolors[(int)*srcpixel++];
523 dstval|=(X11DRV_DIB_GetNearestIndex
527 srcval.peBlue) << (7-(x&7)) );
533 if ((dstwidth&7)!=0) {
536 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
537 dstbits += linebytes;
548 const WORD* srcpixel;
551 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
553 if (bmpImage->green_mask==0x03e0) {
554 if (bmpImage->red_mask==0x7c00) {
555 /* ==== rgb 555 bmp -> pal 1 dib ==== */
556 for (h=0; h<lines; h++) {
561 for (x=0; x<dstwidth; x++) {
564 dstval|=(X11DRV_DIB_GetNearestIndex
566 ((srcval >> 7) & 0xf8) | /* r */
567 ((srcval >> 12) & 0x07),
568 ((srcval >> 2) & 0xf8) | /* g */
569 ((srcval >> 7) & 0x07),
570 ((srcval << 3) & 0xf8) | /* b */
571 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
577 if ((dstwidth&7)!=0) {
580 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
581 dstbits += linebytes;
583 } else if (bmpImage->blue_mask==0x7c00) {
584 /* ==== bgr 555 bmp -> pal 1 dib ==== */
585 for (h=0; h<lines; h++) {
590 for (x=0; x<dstwidth; x++) {
593 dstval|=(X11DRV_DIB_GetNearestIndex
595 ((srcval << 3) & 0xf8) | /* r */
596 ((srcval >> 2) & 0x07),
597 ((srcval >> 2) & 0xf8) | /* g */
598 ((srcval >> 7) & 0x07),
599 ((srcval >> 7) & 0xf8) | /* b */
600 ((srcval >> 12) & 0x07) ) << (7-(x&7)) );
606 if ((dstwidth&7)!=0) {
609 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
610 dstbits += linebytes;
615 } else if (bmpImage->green_mask==0x07e0) {
616 if (bmpImage->red_mask==0xf800) {
617 /* ==== rgb 565 bmp -> pal 1 dib ==== */
618 for (h=0; h<lines; h++) {
623 for (x=0; x<dstwidth; x++) {
626 dstval|=(X11DRV_DIB_GetNearestIndex
628 ((srcval >> 8) & 0xf8) | /* r */
629 ((srcval >> 13) & 0x07),
630 ((srcval >> 3) & 0xfc) | /* g */
631 ((srcval >> 9) & 0x03),
632 ((srcval << 3) & 0xf8) | /* b */
633 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
639 if ((dstwidth&7)!=0) {
642 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
643 dstbits += linebytes;
645 } else if (bmpImage->blue_mask==0xf800) {
646 /* ==== bgr 565 bmp -> pal 1 dib ==== */
647 for (h=0; h<lines; h++) {
652 for (x=0; x<dstwidth; x++) {
655 dstval|=(X11DRV_DIB_GetNearestIndex
657 ((srcval << 3) & 0xf8) | /* r */
658 ((srcval >> 2) & 0x07),
659 ((srcval >> 3) & 0xfc) | /* g */
660 ((srcval >> 9) & 0x03),
661 ((srcval >> 8) & 0xf8) | /* b */
662 ((srcval >> 13) & 0x07) ) << (7-(x&7)) );
668 if ((dstwidth&7)!=0) {
671 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
672 dstbits += linebytes;
691 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
692 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
694 if (bmpImage->green_mask!=0x00ff00 ||
695 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
697 } else if (bmpImage->blue_mask==0xff) {
698 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
699 for (h=0; h<lines; h++) {
704 for (x=0; x<dstwidth; x++) {
705 dstval|=(X11DRV_DIB_GetNearestIndex
709 srcbyte[0]) << (7-(x&7)) );
710 srcbyte+=bytes_per_pixel;
716 if ((dstwidth&7)!=0) {
719 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
720 dstbits += linebytes;
723 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
724 for (h=0; h<lines; h++) {
729 for (x=0; x<dstwidth; x++) {
730 dstval|=(X11DRV_DIB_GetNearestIndex
734 srcbyte[2]) << (7-(x&7)) );
735 srcbyte+=bytes_per_pixel;
741 if ((dstwidth&7)!=0) {
744 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
745 dstbits += linebytes;
755 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
757 /* ==== any bmp format -> pal 1 dib ==== */
758 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
759 bmpImage->bits_per_pixel, bmpImage->red_mask,
760 bmpImage->green_mask, bmpImage->blue_mask );
762 for (h=lines-1; h>=0; h--) {
766 for (x=0; x<dstwidth; x++) {
767 dstval|=(XGetPixel( bmpImage, x, h) >= white) << (7 - (x&7));
773 if ((dstwidth&7)!=0) {
776 dstbits += linebytes;
783 /***********************************************************************
784 * X11DRV_DIB_SetImageBits_4
786 * SetDIBits for a 4-bit deep DIB.
788 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
789 DWORD srcwidth, DWORD dstwidth, int left,
790 int *colors, XImage *bmpImage, DWORD linebytes)
798 srcbits = srcbits + linebytes * (lines - 1);
799 linebytes = -linebytes;
806 srcbits += left >> 1;
808 /* ==== pal 4 dib -> any bmp format ==== */
809 for (h = lines-1; h >= 0; h--) {
811 for (i = dstwidth/2, x = left; i > 0; i--) {
812 BYTE srcval=*srcbyte++;
813 XPutPixel( bmpImage, x++, h, colors[srcval >> 4] );
814 XPutPixel( bmpImage, x++, h, colors[srcval & 0x0f] );
817 XPutPixel( bmpImage, x, h, colors[*srcbyte >> 4] );
818 srcbits += linebytes;
824 /***********************************************************************
825 * X11DRV_DIB_GetImageBits_4
827 * GetDIBits for a 4-bit deep DIB.
829 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
830 DWORD srcwidth, DWORD dstwidth,
831 RGBQUAD *colors, PALETTEENTRY *srccolors,
832 XImage *bmpImage, DWORD linebytes )
841 dstbits = dstbits + ( linebytes * (lines-1) );
842 linebytes = -linebytes;
847 switch (bmpImage->depth) {
850 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
851 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
854 for (h = lines-1; h >= 0; h--) {
858 for (x = 0; x < dstwidth; x++) {
860 srcval=srccolors[XGetPixel(bmpImage, x, h)];
861 dstval|=(X11DRV_DIB_GetNearestIndex
865 srcval.peBlue) << (4-((x&1)<<2)));
871 if ((dstwidth&1)!=0) {
874 dstbits += linebytes;
882 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
883 /* ==== pal 8 bmp -> pal 4 dib ==== */
885 const BYTE *srcpixel;
888 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
889 for (h=0; h<lines; h++) {
894 for (x=0; x<dstwidth; x++) {
896 srcval = srccolors[(int)*srcpixel++];
897 dstval|=(X11DRV_DIB_GetNearestIndex
901 srcval.peBlue) << (4*(1-(x&1))) );
907 if ((dstwidth&1)!=0) {
910 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
911 dstbits += linebytes;
922 const WORD* srcpixel;
925 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
927 if (bmpImage->green_mask==0x03e0) {
928 if (bmpImage->red_mask==0x7c00) {
929 /* ==== rgb 555 bmp -> pal 4 dib ==== */
930 for (h=0; h<lines; h++) {
935 for (x=0; x<dstwidth; x++) {
938 dstval|=(X11DRV_DIB_GetNearestIndex
940 ((srcval >> 7) & 0xf8) | /* r */
941 ((srcval >> 12) & 0x07),
942 ((srcval >> 2) & 0xf8) | /* g */
943 ((srcval >> 7) & 0x07),
944 ((srcval << 3) & 0xf8) | /* b */
945 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
951 if ((dstwidth&1)!=0) {
954 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
955 dstbits += linebytes;
957 } else if (bmpImage->blue_mask==0x7c00) {
958 /* ==== bgr 555 bmp -> pal 4 dib ==== */
959 for (h=0; h<lines; h++) {
964 for (x=0; x<dstwidth; x++) {
967 dstval|=(X11DRV_DIB_GetNearestIndex
969 ((srcval << 3) & 0xf8) | /* r */
970 ((srcval >> 2) & 0x07),
971 ((srcval >> 2) & 0xf8) | /* g */
972 ((srcval >> 7) & 0x07),
973 ((srcval >> 7) & 0xf8) | /* b */
974 ((srcval >> 12) & 0x07) ) << ((1-(x&1))<<2) );
980 if ((dstwidth&1)!=0) {
983 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
984 dstbits += linebytes;
989 } else if (bmpImage->green_mask==0x07e0) {
990 if (bmpImage->red_mask==0xf800) {
991 /* ==== rgb 565 bmp -> pal 4 dib ==== */
992 for (h=0; h<lines; h++) {
997 for (x=0; x<dstwidth; x++) {
1000 dstval|=(X11DRV_DIB_GetNearestIndex
1002 ((srcval >> 8) & 0xf8) | /* r */
1003 ((srcval >> 13) & 0x07),
1004 ((srcval >> 3) & 0xfc) | /* g */
1005 ((srcval >> 9) & 0x03),
1006 ((srcval << 3) & 0xf8) | /* b */
1007 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
1013 if ((dstwidth&1)!=0) {
1016 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1017 dstbits += linebytes;
1019 } else if (bmpImage->blue_mask==0xf800) {
1020 /* ==== bgr 565 bmp -> pal 4 dib ==== */
1021 for (h=0; h<lines; h++) {
1026 for (x=0; x<dstwidth; x++) {
1029 dstval|=(X11DRV_DIB_GetNearestIndex
1031 ((srcval << 3) & 0xf8) | /* r */
1032 ((srcval >> 2) & 0x07),
1033 ((srcval >> 3) & 0xfc) | /* g */
1034 ((srcval >> 9) & 0x03),
1035 ((srcval >> 8) & 0xf8) | /* b */
1036 ((srcval >> 13) & 0x07) ) << ((1-(x&1))<<2) );
1042 if ((dstwidth&1)!=0) {
1045 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1046 dstbits += linebytes;
1058 if (bmpImage->bits_per_pixel==24) {
1059 const void* srcbits;
1060 const BYTE *srcbyte;
1063 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1065 if (bmpImage->green_mask!=0x00ff00 ||
1066 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1068 } else if (bmpImage->blue_mask==0xff) {
1069 /* ==== rgb 888 bmp -> pal 4 dib ==== */
1070 for (h=0; h<lines; h++) {
1073 for (x=0; x<dstwidth/2; x++) {
1074 /* Do 2 pixels at a time */
1075 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1080 X11DRV_DIB_GetNearestIndex
1088 /* And the the odd pixel */
1089 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1095 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1096 dstbits += linebytes;
1099 /* ==== bgr 888 bmp -> pal 4 dib ==== */
1100 for (h=0; h<lines; h++) {
1103 for (x=0; x<dstwidth/2; x++) {
1104 /* Do 2 pixels at a time */
1105 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1110 X11DRV_DIB_GetNearestIndex
1118 /* And the the odd pixel */
1119 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1125 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1126 dstbits += linebytes;
1135 const void* srcbits;
1136 const BYTE *srcbyte;
1139 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1141 if (bmpImage->green_mask!=0x00ff00 ||
1142 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1144 } else if (bmpImage->blue_mask==0xff) {
1145 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
1146 for (h=0; h<lines; h++) {
1149 for (x=0; x<dstwidth/2; x++) {
1150 /* Do 2 pixels at a time */
1151 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1156 X11DRV_DIB_GetNearestIndex
1164 /* And the the odd pixel */
1165 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1171 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1172 dstbits += linebytes;
1175 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
1176 for (h=0; h<lines; h++) {
1179 for (x=0; x<dstwidth/2; x++) {
1180 /* Do 2 pixels at a time */
1181 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1186 X11DRV_DIB_GetNearestIndex
1194 /* And the the odd pixel */
1195 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1201 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1202 dstbits += linebytes;
1213 /* ==== any bmp format -> pal 4 dib ==== */
1214 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
1215 bmpImage->bits_per_pixel, bmpImage->red_mask,
1216 bmpImage->green_mask, bmpImage->blue_mask );
1217 for (h=lines-1; h>=0; h--) {
1219 for (x=0; x<(dstwidth & ~1); x+=2) {
1220 *dstbyte++=(X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4) |
1221 X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x+1, h), 0);
1224 *dstbyte=(X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4);
1226 dstbits += linebytes;
1233 /***********************************************************************
1234 * X11DRV_DIB_SetImageBits_RLE4
1236 * SetDIBits for a 4-bit deep compressed DIB.
1238 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
1239 DWORD width, DWORD dstwidth,
1240 int left, int *colors,
1243 int x = 0, y = lines - 1, c, length;
1244 const BYTE *begin = bits;
1249 if (length) { /* encoded */
1252 if (x >= width) break;
1253 XPutPixel(bmpImage, x++, y, colors[c >> 4]);
1254 if (!length--) break;
1255 if (x >= width) break;
1256 XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
1275 default: /* absolute */
1278 if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
1279 if (!length--) break;
1280 if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
1282 if ((bits - begin) & 1)
1291 /***********************************************************************
1292 * X11DRV_DIB_SetImageBits_8
1294 * SetDIBits for an 8-bit deep DIB.
1296 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
1297 DWORD srcwidth, DWORD dstwidth, int left,
1298 const int *colors, XImage *bmpImage,
1303 const BYTE* srcbyte;
1309 srcbits = srcbits + linebytes * (lines-1);
1310 linebytes = -linebytes;
1315 switch (bmpImage->depth) {
1318 #if defined(__i386__) && defined(__GNUC__)
1319 /* Some X servers might have 32 bit/ 16bit deep pixel */
1320 if (lines && dstwidth && (bmpImage->bits_per_pixel == 16) &&
1321 (ImageByteOrder(gdi_display)==LSBFirst) )
1323 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
1324 /* FIXME: Does this really handle all these cases correctly? */
1325 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
1326 for (h = lines ; h--; ) {
1327 int _cl1,_cl2; /* temp outputs for asm below */
1328 /* Borrowed from DirectDraw */
1329 __asm__ __volatile__(
1334 " movw (%%edx,%%eax,4),%%ax\n"
1336 " xor %%eax,%%eax\n"
1338 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
1343 :"eax", "cc", "memory"
1345 srcbyte = (srcbits += linebytes);
1346 dstbits -= bmpImage->bytes_per_line;
1354 #if defined(__i386__) && defined(__GNUC__)
1355 if (lines && dstwidth && (bmpImage->bits_per_pixel == 32) &&
1356 (ImageByteOrder(gdi_display)==LSBFirst) )
1358 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
1359 /* FIXME: Does this really handle both cases correctly? */
1360 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
1361 for (h = lines ; h--; ) {
1362 int _cl1,_cl2; /* temp outputs for asm below */
1363 /* Borrowed from DirectDraw */
1364 __asm__ __volatile__(
1369 " movl (%%edx,%%eax,4),%%eax\n"
1371 " xor %%eax,%%eax\n"
1373 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
1378 :"eax", "cc", "memory"
1380 srcbyte = (srcbits += linebytes);
1381 dstbits -= bmpImage->bytes_per_line;
1388 break; /* use slow generic case below */
1391 /* ==== pal 8 dib -> any bmp format ==== */
1392 for (h=lines-1; h>=0; h--) {
1393 for (x=left; x<dstwidth+left; x++) {
1394 XPutPixel(bmpImage, x, h, colors[*srcbyte++]);
1396 srcbyte = (srcbits += linebytes);
1400 /***********************************************************************
1401 * X11DRV_DIB_GetImageBits_8
1403 * GetDIBits for an 8-bit deep DIB.
1405 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
1406 DWORD srcwidth, DWORD dstwidth,
1407 RGBQUAD *colors, PALETTEENTRY *srccolors,
1408 XImage *bmpImage, DWORD linebytes )
1417 dstbits = dstbits + ( linebytes * (lines-1) );
1418 linebytes = -linebytes;
1423 * This condition is true when GetImageBits has been called by
1424 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
1425 * 256 colormaps, so we'll just use for for GetDIBits calls.
1426 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
1428 if (!srccolors) goto updatesection;
1430 switch (bmpImage->depth) {
1433 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1435 /* ==== pal 1 bmp -> pal 8 dib ==== */
1436 /* ==== pal 4 bmp -> pal 8 dib ==== */
1437 for (h=lines-1; h>=0; h--) {
1439 for (x=0; x<dstwidth; x++) {
1440 PALETTEENTRY srcval;
1441 srcval=srccolors[XGetPixel(bmpImage, x, h)];
1442 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
1447 dstbits += linebytes;
1455 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1456 /* ==== pal 8 bmp -> pal 8 dib ==== */
1457 const void* srcbits;
1458 const BYTE* srcpixel;
1460 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1461 for (h=0; h<lines; h++) {
1464 for (x = 0; x < dstwidth; x++) {
1465 PALETTEENTRY srcval;
1466 srcval=srccolors[(int)*srcpixel++];
1467 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
1472 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1473 dstbits += linebytes;
1483 const void* srcbits;
1484 const WORD* srcpixel;
1487 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1489 if (bmpImage->green_mask==0x03e0) {
1490 if (bmpImage->red_mask==0x7c00) {
1491 /* ==== rgb 555 bmp -> pal 8 dib ==== */
1492 for (h=0; h<lines; h++) {
1495 for (x=0; x<dstwidth; x++) {
1498 *dstbyte++=X11DRV_DIB_GetNearestIndex
1500 ((srcval >> 7) & 0xf8) | /* r */
1501 ((srcval >> 12) & 0x07),
1502 ((srcval >> 2) & 0xf8) | /* g */
1503 ((srcval >> 7) & 0x07),
1504 ((srcval << 3) & 0xf8) | /* b */
1505 ((srcval >> 2) & 0x07) );
1507 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1508 dstbits += linebytes;
1510 } else if (bmpImage->blue_mask==0x7c00) {
1511 /* ==== bgr 555 bmp -> pal 8 dib ==== */
1512 for (h=0; h<lines; h++) {
1515 for (x=0; x<dstwidth; x++) {
1518 *dstbyte++=X11DRV_DIB_GetNearestIndex
1520 ((srcval << 3) & 0xf8) | /* r */
1521 ((srcval >> 2) & 0x07),
1522 ((srcval >> 2) & 0xf8) | /* g */
1523 ((srcval >> 7) & 0x07),
1524 ((srcval >> 7) & 0xf8) | /* b */
1525 ((srcval >> 12) & 0x07) );
1527 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1528 dstbits += linebytes;
1533 } else if (bmpImage->green_mask==0x07e0) {
1534 if (bmpImage->red_mask==0xf800) {
1535 /* ==== rgb 565 bmp -> pal 8 dib ==== */
1536 for (h=0; h<lines; h++) {
1539 for (x=0; x<dstwidth; x++) {
1542 *dstbyte++=X11DRV_DIB_GetNearestIndex
1544 ((srcval >> 8) & 0xf8) | /* r */
1545 ((srcval >> 13) & 0x07),
1546 ((srcval >> 3) & 0xfc) | /* g */
1547 ((srcval >> 9) & 0x03),
1548 ((srcval << 3) & 0xf8) | /* b */
1549 ((srcval >> 2) & 0x07) );
1551 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1552 dstbits += linebytes;
1554 } else if (bmpImage->blue_mask==0xf800) {
1555 /* ==== bgr 565 bmp -> pal 8 dib ==== */
1556 for (h=0; h<lines; h++) {
1559 for (x=0; x<dstwidth; x++) {
1562 *dstbyte++=X11DRV_DIB_GetNearestIndex
1564 ((srcval << 3) & 0xf8) | /* r */
1565 ((srcval >> 2) & 0x07),
1566 ((srcval >> 3) & 0xfc) | /* g */
1567 ((srcval >> 9) & 0x03),
1568 ((srcval >> 8) & 0xf8) | /* b */
1569 ((srcval >> 13) & 0x07) );
1571 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1572 dstbits += linebytes;
1586 const void* srcbits;
1587 const BYTE *srcbyte;
1589 int bytes_per_pixel;
1591 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1592 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
1594 if (bmpImage->green_mask!=0x00ff00 ||
1595 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1597 } else if (bmpImage->blue_mask==0xff) {
1598 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
1599 for (h=0; h<lines; h++) {
1602 for (x=0; x<dstwidth; x++) {
1603 *dstbyte++=X11DRV_DIB_GetNearestIndex
1608 srcbyte+=bytes_per_pixel;
1610 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1611 dstbits += linebytes;
1614 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
1615 for (h=0; h<lines; h++) {
1618 for (x=0; x<dstwidth; x++) {
1619 *dstbyte++=X11DRV_DIB_GetNearestIndex
1624 srcbyte+=bytes_per_pixel;
1626 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1627 dstbits += linebytes;
1635 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
1636 bmpImage->depth, bmpImage->red_mask,
1637 bmpImage->green_mask, bmpImage->blue_mask );
1639 /* ==== any bmp format -> pal 8 dib ==== */
1640 for (h=lines-1; h>=0; h--) {
1642 for (x=0; x<dstwidth; x++) {
1643 *dstbyte=X11DRV_DIB_MapColor
1645 XGetPixel(bmpImage, x, h), *dstbyte);
1648 dstbits += linebytes;
1654 /***********************************************************************
1655 * X11DRV_DIB_SetImageBits_RLE8
1657 * SetDIBits for an 8-bit deep compressed DIB.
1659 * This function rewritten 941113 by James Youngman. WINE blew out when I
1660 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1662 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1663 * 'End of bitmap' escape code. This code is very much laxer in what it
1664 * allows to end the expansion. Possibly too lax. See the note by
1665 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1666 * bitmap should end with RleEnd, but on the other hand, software exists
1667 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1670 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1671 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1674 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1675 DWORD width, DWORD dstwidth,
1676 int left, int *colors,
1679 int x; /* X-positon on each line. Increases. */
1680 int y; /* Line #. Starts at lines-1, decreases */
1681 const BYTE *pIn = bits; /* Pointer to current position in bits */
1682 BYTE length; /* The length pf a run */
1683 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
1686 * Note that the bitmap data is stored by Windows starting at the
1687 * bottom line of the bitmap and going upwards. Within each line,
1688 * the data is stored left-to-right. That's the reason why line
1689 * goes from lines-1 to 0. [JAY]
1699 * If the length byte is not zero (which is the escape value),
1700 * We have a run of length pixels all the same colour. The colour
1701 * index is stored next.
1703 * If the length byte is zero, we need to read the next byte to
1704 * know what to do. [JAY]
1709 * [Run-Length] Encoded mode
1711 int color = colors[*pIn++];
1712 while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
1717 * Escape codes (may be an absolute sequence though)
1719 escape_code = (*pIn++);
1728 /* Not all RLE8 bitmaps end with this code. For
1729 * example, Paint Shop Pro produces some that don't.
1730 * That's (I think) what caused the previous
1731 * implementation to fail. [JAY]
1740 default: /* switch to absolute mode */
1741 length = escape_code;
1744 int color = colors[*pIn++];
1750 XPutPixel(bmpImage, x++, y, color);
1753 * If you think for a moment you'll realise that the
1754 * only time we could ever possibly read an odd
1755 * number of bytes is when there is a 0x00 (escape),
1756 * a value >0x02 (absolute mode) and then an odd-
1757 * length run. Therefore this is the only place we
1758 * need to worry about it. Everywhere else the
1759 * bytes are always read in pairs. [JAY]
1761 if (escape_code & 1) pIn++; /* Throw away the pad byte. */
1763 } /* switch (escape_code) : Escape sequence */
1769 /***********************************************************************
1770 * X11DRV_DIB_SetImageBits_16
1772 * SetDIBits for a 16-bit deep DIB.
1774 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1775 DWORD srcwidth, DWORD dstwidth, int left,
1776 X11DRV_PDEVICE *physDev, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1777 XImage *bmpImage, DWORD linebytes )
1781 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
1786 srcbits = srcbits + ( linebytes * (lines-1));
1787 linebytes = -linebytes;
1790 switch (bmpImage->depth)
1797 srcbits=srcbits+left*2;
1798 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
1800 if (bmpImage->green_mask==0x03e0) {
1801 if (gSrc==bmpImage->green_mask) {
1802 if (rSrc==bmpImage->red_mask) {
1803 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
1804 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
1805 convs->Convert_5x5_asis
1808 dstbits,-bmpImage->bytes_per_line);
1809 } else if (rSrc==bmpImage->blue_mask) {
1810 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
1811 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
1812 convs->Convert_555_reverse
1815 dstbits,-bmpImage->bytes_per_line);
1818 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
1819 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
1820 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
1821 convs->Convert_565_to_555_asis
1824 dstbits,-bmpImage->bytes_per_line);
1826 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
1827 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
1828 convs->Convert_565_to_555_reverse
1831 dstbits,-bmpImage->bytes_per_line);
1834 } else if (bmpImage->green_mask==0x07e0) {
1835 if (gSrc==bmpImage->green_mask) {
1836 if (rSrc==bmpImage->red_mask) {
1837 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
1838 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
1839 convs->Convert_5x5_asis
1842 dstbits,-bmpImage->bytes_per_line);
1844 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
1845 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
1846 convs->Convert_565_reverse
1849 dstbits,-bmpImage->bytes_per_line);
1852 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
1853 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
1854 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
1855 convs->Convert_555_to_565_asis
1858 dstbits,-bmpImage->bytes_per_line);
1860 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
1861 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
1862 convs->Convert_555_to_565_reverse
1865 dstbits,-bmpImage->bytes_per_line);
1875 if (bmpImage->bits_per_pixel==24) {
1878 srcbits=srcbits+left*2;
1879 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
1881 if (bmpImage->green_mask!=0x00ff00 ||
1882 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1884 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
1885 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
1887 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
1888 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
1889 convs->Convert_555_to_888_asis
1892 dstbits,-bmpImage->bytes_per_line);
1894 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
1895 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
1896 convs->Convert_565_to_888_asis
1899 dstbits,-bmpImage->bytes_per_line);
1903 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
1904 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
1905 convs->Convert_555_to_888_reverse
1908 dstbits,-bmpImage->bytes_per_line);
1910 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
1911 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
1912 convs->Convert_565_to_888_reverse
1915 dstbits,-bmpImage->bytes_per_line);
1926 srcbits=srcbits+left*2;
1927 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
1929 if (bmpImage->green_mask!=0x00ff00 ||
1930 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1932 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
1933 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
1935 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
1936 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
1937 convs->Convert_555_to_0888_asis
1940 dstbits,-bmpImage->bytes_per_line);
1942 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
1943 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
1944 convs->Convert_565_to_0888_asis
1947 dstbits,-bmpImage->bytes_per_line);
1951 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
1952 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
1953 convs->Convert_555_to_0888_reverse
1956 dstbits,-bmpImage->bytes_per_line);
1958 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
1959 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
1960 convs->Convert_565_to_0888_reverse
1963 dstbits,-bmpImage->bytes_per_line);
1971 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
1972 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
1973 bmpImage->green_mask, bmpImage->blue_mask );
1979 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
1980 const WORD* srcpixel;
1981 int rShift1,gShift1,bShift1;
1982 int rShift2,gShift2,bShift2;
1985 /* Set color scaling values */
1986 rShift1=16+X11DRV_DIB_MaskToShift(rSrc)-3;
1987 gShift1=16+X11DRV_DIB_MaskToShift(gSrc)-3;
1988 bShift1=16+X11DRV_DIB_MaskToShift(bSrc)-3;
1993 /* Green has 5 bits, like the others */
1997 /* Green has 6 bits, not 5. Compensate. */
2006 /* We could split it into four separate cases to optimize
2007 * but it is probably not worth it.
2009 for (h=lines-1; h>=0; h--) {
2010 srcpixel=(const WORD*)srcbits;
2011 for (x=left; x<dstwidth+left; x++) {
2013 BYTE red,green,blue;
2014 srcval=*srcpixel++ << 16;
2015 red= ((srcval >> rShift1) & 0xf8) |
2016 ((srcval >> rShift2) & 0x07);
2017 green=((srcval >> gShift1) & gMask1) |
2018 ((srcval >> gShift2) & gMask2);
2019 blue= ((srcval >> bShift1) & 0xf8) |
2020 ((srcval >> bShift2) & 0x07);
2021 XPutPixel(bmpImage, x, h,
2022 X11DRV_PALETTE_ToPhysical
2023 (physDev, RGB(red,green,blue)));
2025 srcbits += linebytes;
2033 /***********************************************************************
2034 * X11DRV_DIB_GetImageBits_16
2036 * GetDIBits for an 16-bit deep DIB.
2038 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
2039 DWORD dstwidth, DWORD srcwidth,
2040 PALETTEENTRY *srccolors,
2041 DWORD rDst, DWORD gDst, DWORD bDst,
2042 XImage *bmpImage, DWORD dibpitch )
2046 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
2048 DWORD linebytes = dibpitch;
2053 dstbits = dstbits + ( linebytes * (lines-1));
2054 linebytes = -linebytes;
2057 switch (bmpImage->depth)
2062 const char* srcbits;
2064 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2066 if (bmpImage->green_mask==0x03e0) {
2067 if (gDst==bmpImage->green_mask) {
2068 if (rDst==bmpImage->red_mask) {
2069 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
2070 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
2071 convs->Convert_5x5_asis
2073 srcbits,-bmpImage->bytes_per_line,
2076 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
2077 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
2078 convs->Convert_555_reverse
2080 srcbits,-bmpImage->bytes_per_line,
2084 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
2085 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
2086 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
2087 convs->Convert_555_to_565_asis
2089 srcbits,-bmpImage->bytes_per_line,
2092 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
2093 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
2094 convs->Convert_555_to_565_reverse
2096 srcbits,-bmpImage->bytes_per_line,
2100 } else if (bmpImage->green_mask==0x07e0) {
2101 if (gDst==bmpImage->green_mask) {
2102 if (rDst == bmpImage->red_mask) {
2103 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
2104 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
2105 convs->Convert_5x5_asis
2107 srcbits,-bmpImage->bytes_per_line,
2110 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
2111 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
2112 convs->Convert_565_reverse
2114 srcbits,-bmpImage->bytes_per_line,
2118 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
2119 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
2120 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
2121 convs->Convert_565_to_555_asis
2123 srcbits,-bmpImage->bytes_per_line,
2126 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
2127 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
2128 convs->Convert_565_to_555_reverse
2130 srcbits,-bmpImage->bytes_per_line,
2141 if (bmpImage->bits_per_pixel == 24) {
2142 const char* srcbits;
2144 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2146 if (bmpImage->green_mask!=0x00ff00 ||
2147 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2149 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
2150 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
2152 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
2153 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
2154 convs->Convert_888_to_555_asis
2156 srcbits,-bmpImage->bytes_per_line,
2159 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2160 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2161 convs->Convert_888_to_565_asis
2163 srcbits,-bmpImage->bytes_per_line,
2168 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
2169 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
2170 convs->Convert_888_to_555_reverse
2172 srcbits,-bmpImage->bytes_per_line,
2175 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
2176 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
2177 convs->Convert_888_to_565_reverse
2179 srcbits,-bmpImage->bytes_per_line,
2189 const char* srcbits;
2191 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2193 if (bmpImage->green_mask!=0x00ff00 ||
2194 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2196 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
2197 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
2199 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
2200 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
2201 convs->Convert_0888_to_555_asis
2203 srcbits,-bmpImage->bytes_per_line,
2206 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
2207 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
2208 convs->Convert_0888_to_565_asis
2210 srcbits,-bmpImage->bytes_per_line,
2215 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
2216 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
2217 convs->Convert_0888_to_555_reverse
2219 srcbits,-bmpImage->bytes_per_line,
2222 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
2223 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
2224 convs->Convert_0888_to_565_reverse
2226 srcbits,-bmpImage->bytes_per_line,
2235 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2236 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
2237 int rShift,gShift,bShift;
2240 /* Shift everything 16 bits left so that all shifts are >0,
2241 * even for BGR DIBs. Then a single >> 16 will bring everything
2244 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2245 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2246 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2248 /* 6 bits for the green */
2254 for (h = lines - 1; h >= 0; h--) {
2255 dstpixel=(LPWORD)dstbits;
2256 for (x = 0; x < dstwidth; x++) {
2257 PALETTEENTRY srcval;
2259 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2260 dstval=((srcval.peRed << rShift) & rDst) |
2261 ((srcval.peGreen << gShift) & gDst) |
2262 ((srcval.peBlue << bShift) & bDst);
2263 *dstpixel++=dstval >> 16;
2265 dstbits += linebytes;
2273 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2274 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
2275 int rShift,gShift,bShift;
2276 const BYTE* srcbits;
2277 const BYTE* srcpixel;
2280 /* Shift everything 16 bits left so that all shifts are >0,
2281 * even for BGR DIBs. Then a single >> 16 will bring everything
2284 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2285 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2286 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2288 /* 6 bits for the green */
2294 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2295 for (h=0; h<lines; h++) {
2297 dstpixel=(LPWORD)dstbits;
2298 for (x = 0; x < dstwidth; x++) {
2299 PALETTEENTRY srcval;
2301 srcval=srccolors[(int)*srcpixel++];
2302 dstval=((srcval.peRed << rShift) & rDst) |
2303 ((srcval.peGreen << gShift) & gDst) |
2304 ((srcval.peBlue << bShift) & bDst);
2305 *dstpixel++=dstval >> 16;
2307 srcbits -= bmpImage->bytes_per_line;
2308 dstbits += linebytes;
2318 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
2319 int rShift,gShift,bShift;
2322 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
2323 bmpImage->depth, bmpImage->red_mask,
2324 bmpImage->green_mask, bmpImage->blue_mask,
2327 /* Shift everything 16 bits left so that all shifts are >0,
2328 * even for BGR DIBs. Then a single >> 16 will bring everything
2331 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2332 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2333 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2335 /* 6 bits for the green */
2341 for (h = lines - 1; h >= 0; h--) {
2342 dstpixel=(LPWORD)dstbits;
2343 for (x = 0; x < dstwidth; x++) {
2346 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
2347 dstval=((GetRValue(srcval) << rShift) & rDst) |
2348 ((GetGValue(srcval) << gShift) & gDst) |
2349 ((GetBValue(srcval) << bShift) & bDst);
2350 *dstpixel++=dstval >> 16;
2352 dstbits += linebytes;
2360 /***********************************************************************
2361 * X11DRV_DIB_SetImageBits_24
2363 * SetDIBits for a 24-bit deep DIB.
2365 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
2366 DWORD srcwidth, DWORD dstwidth, int left,
2367 X11DRV_PDEVICE *physDev,
2368 DWORD rSrc, DWORD gSrc, DWORD bSrc,
2369 XImage *bmpImage, DWORD linebytes )
2373 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
2378 srcbits = srcbits + linebytes * (lines - 1);
2379 linebytes = -linebytes;
2382 switch (bmpImage->depth)
2385 if (bmpImage->bits_per_pixel==24) {
2388 srcbits=srcbits+left*3;
2389 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
2391 if (bmpImage->green_mask!=0x00ff00 ||
2392 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2394 } else if (rSrc==bmpImage->red_mask) {
2395 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
2396 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
2397 convs->Convert_888_asis
2400 dstbits,-bmpImage->bytes_per_line);
2402 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
2403 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
2404 convs->Convert_888_reverse
2407 dstbits,-bmpImage->bytes_per_line);
2417 srcbits=srcbits+left*3;
2418 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2420 if (bmpImage->green_mask!=0x00ff00 ||
2421 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2423 } else if (rSrc==bmpImage->red_mask) {
2424 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
2425 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
2426 convs->Convert_888_to_0888_asis
2429 dstbits,-bmpImage->bytes_per_line);
2431 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
2432 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
2433 convs->Convert_888_to_0888_reverse
2436 dstbits,-bmpImage->bytes_per_line);
2446 srcbits=srcbits+left*3;
2447 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2449 if (bmpImage->green_mask==0x03e0) {
2450 if ((rSrc==0xff0000 && bmpImage->red_mask==0x7f00) ||
2451 (bSrc==0xff0000 && bmpImage->blue_mask==0x7f00)) {
2452 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
2453 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
2454 convs->Convert_888_to_555_asis
2457 dstbits,-bmpImage->bytes_per_line);
2458 } else if ((rSrc==0xff && bmpImage->red_mask==0x7f00) ||
2459 (bSrc==0xff && bmpImage->blue_mask==0x7f00)) {
2460 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
2461 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
2462 convs->Convert_888_to_555_reverse
2465 dstbits,-bmpImage->bytes_per_line);
2469 } else if (bmpImage->green_mask==0x07e0) {
2470 if ((rSrc==0xff0000 && bmpImage->red_mask==0xf800) ||
2471 (bSrc==0xff0000 && bmpImage->blue_mask==0xf800)) {
2472 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
2473 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
2474 convs->Convert_888_to_565_asis
2477 dstbits,-bmpImage->bytes_per_line);
2478 } else if ((rSrc==0xff && bmpImage->red_mask==0xf800) ||
2479 (bSrc==0xff && bmpImage->blue_mask==0xf800)) {
2480 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
2481 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
2482 convs->Convert_888_to_565_reverse
2485 dstbits,-bmpImage->bytes_per_line);
2497 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2498 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
2499 bmpImage->green_mask, bmpImage->blue_mask );
2505 /* ==== rgb 888 dib -> any bmp bormat ==== */
2506 const BYTE* srcbyte;
2508 /* Windows only supports one 24bpp DIB format: RGB888 */
2510 for (h = lines - 1; h >= 0; h--) {
2511 srcbyte=(const BYTE*)srcbits;
2512 for (x = left; x < dstwidth+left; x++) {
2513 XPutPixel(bmpImage, x, h,
2514 X11DRV_PALETTE_ToPhysical
2515 (physDev, RGB(srcbyte[2], srcbyte[1], srcbyte[0])));
2518 srcbits += linebytes;
2526 /***********************************************************************
2527 * X11DRV_DIB_GetImageBits_24
2529 * GetDIBits for an 24-bit deep DIB.
2531 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
2532 DWORD dstwidth, DWORD srcwidth,
2533 PALETTEENTRY *srccolors,
2534 DWORD rDst, DWORD gDst, DWORD bDst,
2535 XImage *bmpImage, DWORD linebytes )
2539 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
2544 dstbits = dstbits + ( linebytes * (lines-1) );
2545 linebytes = -linebytes;
2548 switch (bmpImage->depth)
2551 if (bmpImage->bits_per_pixel==24) {
2552 const char* srcbits;
2554 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2556 if (bmpImage->green_mask!=0x00ff00 ||
2557 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2559 } else if (rDst==bmpImage->red_mask) {
2560 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
2561 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
2562 convs->Convert_888_asis
2564 srcbits,-bmpImage->bytes_per_line,
2567 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
2568 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
2569 convs->Convert_888_reverse
2571 srcbits,-bmpImage->bytes_per_line,
2580 const char* srcbits;
2582 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2584 if (bmpImage->green_mask!=0x00ff00 ||
2585 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2587 } else if (rDst==bmpImage->red_mask) {
2588 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2589 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2590 convs->Convert_0888_to_888_asis
2592 srcbits,-bmpImage->bytes_per_line,
2595 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
2596 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
2597 convs->Convert_0888_to_888_reverse
2599 srcbits,-bmpImage->bytes_per_line,
2608 const char* srcbits;
2610 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2612 if (bmpImage->green_mask==0x03e0) {
2613 if ((rDst==0xff0000 && bmpImage->red_mask==0x7f00) ||
2614 (bDst==0xff0000 && bmpImage->blue_mask==0x7f00)) {
2615 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
2616 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
2617 convs->Convert_555_to_888_asis
2619 srcbits,-bmpImage->bytes_per_line,
2621 } else if ((rDst==0xff && bmpImage->red_mask==0x7f00) ||
2622 (bDst==0xff && bmpImage->blue_mask==0x7f00)) {
2623 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
2624 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
2625 convs->Convert_555_to_888_reverse
2627 srcbits,-bmpImage->bytes_per_line,
2632 } else if (bmpImage->green_mask==0x07e0) {
2633 if ((rDst==0xff0000 && bmpImage->red_mask==0xf800) ||
2634 (bDst==0xff0000 && bmpImage->blue_mask==0xf800)) {
2635 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
2636 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
2637 convs->Convert_565_to_888_asis
2639 srcbits,-bmpImage->bytes_per_line,
2641 } else if ((rDst==0xff && bmpImage->red_mask==0xf800) ||
2642 (bDst==0xff && bmpImage->blue_mask==0xf800)) {
2643 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
2644 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
2645 convs->Convert_565_to_888_reverse
2647 srcbits,-bmpImage->bytes_per_line,
2660 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2661 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
2664 /* Windows only supports one 24bpp DIB format: rgb 888 */
2665 for (h = lines - 1; h >= 0; h--) {
2667 for (x = 0; x < dstwidth; x++) {
2668 PALETTEENTRY srcval;
2669 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2670 dstbyte[0]=srcval.peBlue;
2671 dstbyte[1]=srcval.peGreen;
2672 dstbyte[2]=srcval.peRed;
2675 dstbits += linebytes;
2683 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors) {
2684 /* ==== pal 8 bmp -> rgb 888 dib ==== */
2685 const void* srcbits;
2686 const BYTE* srcpixel;
2689 /* Windows only supports one 24bpp DIB format: rgb 888 */
2690 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2691 for (h = lines - 1; h >= 0; h--) {
2694 for (x = 0; x < dstwidth; x++ ) {
2695 PALETTEENTRY srcval;
2696 srcval=srccolors[(int)*srcpixel++];
2697 dstbyte[0]=srcval.peBlue;
2698 dstbyte[1]=srcval.peGreen;
2699 dstbyte[2]=srcval.peRed;
2702 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2703 dstbits += linebytes;
2713 /* ==== any bmp format -> 888 dib ==== */
2716 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
2717 bmpImage->depth, bmpImage->red_mask,
2718 bmpImage->green_mask, bmpImage->blue_mask,
2721 /* Windows only supports one 24bpp DIB format: rgb 888 */
2722 for (h = lines - 1; h >= 0; h--) {
2724 for (x = 0; x < dstwidth; x++) {
2725 COLORREF srcval=X11DRV_PALETTE_ToLogical
2726 (XGetPixel( bmpImage, x, h ));
2727 dstbyte[0]=GetBValue(srcval);
2728 dstbyte[1]=GetGValue(srcval);
2729 dstbyte[2]=GetRValue(srcval);
2732 dstbits += linebytes;
2740 /***********************************************************************
2741 * X11DRV_DIB_SetImageBits_32
2743 * SetDIBits for a 32-bit deep DIB.
2745 static void X11DRV_DIB_SetImageBits_32(int lines, const BYTE *srcbits,
2746 DWORD srcwidth, DWORD dstwidth, int left,
2747 X11DRV_PDEVICE *physDev,
2748 DWORD rSrc, DWORD gSrc, DWORD bSrc,
2754 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
2759 srcbits = srcbits + ( linebytes * (lines-1) );
2760 linebytes = -linebytes;
2763 ptr = (DWORD *) srcbits + left;
2765 switch (bmpImage->depth)
2768 if (bmpImage->bits_per_pixel==24) {
2771 srcbits=srcbits+left*4;
2772 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
2774 if (rSrc==bmpImage->red_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->blue_mask) {
2775 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
2776 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
2777 convs->Convert_0888_to_888_asis
2780 dstbits,-bmpImage->bytes_per_line);
2781 } else if (bmpImage->green_mask!=0x00ff00 ||
2782 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2784 /* the tests below assume sane bmpImage masks */
2785 } else if (rSrc==bmpImage->blue_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->red_mask) {
2786 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
2787 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
2788 convs->Convert_0888_to_888_reverse
2791 dstbits,-bmpImage->bytes_per_line);
2792 } else if (bmpImage->blue_mask==0xff) {
2793 /* ==== any 0888 dib -> rgb 888 bmp ==== */
2794 convs->Convert_any0888_to_rgb888
2798 dstbits,-bmpImage->bytes_per_line);
2800 /* ==== any 0888 dib -> bgr 888 bmp ==== */
2801 convs->Convert_any0888_to_bgr888
2805 dstbits,-bmpImage->bytes_per_line);
2815 srcbits=srcbits+left*4;
2816 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2818 if (gSrc==bmpImage->green_mask) {
2819 if (rSrc==bmpImage->red_mask && bSrc==bmpImage->blue_mask) {
2820 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
2821 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
2822 convs->Convert_0888_asis
2825 dstbits,-bmpImage->bytes_per_line);
2826 } else if (bmpImage->green_mask!=0x00ff00 ||
2827 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2829 /* the tests below assume sane bmpImage masks */
2830 } else if (rSrc==bmpImage->blue_mask && bSrc==bmpImage->red_mask) {
2831 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
2832 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
2833 convs->Convert_0888_reverse
2836 dstbits,-bmpImage->bytes_per_line);
2838 /* ==== any 0888 dib -> any 0888 bmp ==== */
2839 convs->Convert_0888_any
2843 dstbits,-bmpImage->bytes_per_line,
2844 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2846 } else if (bmpImage->green_mask!=0x00ff00 ||
2847 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2849 /* the tests below assume sane bmpImage masks */
2851 /* ==== any 0888 dib -> any 0888 bmp ==== */
2852 convs->Convert_0888_any
2856 dstbits,-bmpImage->bytes_per_line,
2857 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2867 srcbits=srcbits+left*4;
2868 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2870 if (rSrc==0xff0000 && gSrc==0x00ff00 && bSrc==0x0000ff) {
2871 if (bmpImage->green_mask==0x03e0) {
2872 if (bmpImage->red_mask==0x7f00) {
2873 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
2874 convs->Convert_0888_to_555_asis
2877 dstbits,-bmpImage->bytes_per_line);
2878 } else if (bmpImage->blue_mask==0x7f00) {
2879 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
2880 convs->Convert_0888_to_555_reverse
2883 dstbits,-bmpImage->bytes_per_line);
2887 } else if (bmpImage->green_mask==0x07e0) {
2888 if (bmpImage->red_mask==0xf800) {
2889 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
2890 convs->Convert_0888_to_565_asis
2893 dstbits,-bmpImage->bytes_per_line);
2894 } else if (bmpImage->blue_mask==0xf800) {
2895 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
2896 convs->Convert_0888_to_565_reverse
2899 dstbits,-bmpImage->bytes_per_line);
2906 } else if (rSrc==0x0000ff && gSrc==0x00ff00 && bSrc==0xff0000) {
2907 if (bmpImage->green_mask==0x03e0) {
2908 if (bmpImage->blue_mask==0x7f00) {
2909 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
2910 convs->Convert_0888_to_555_asis
2913 dstbits,-bmpImage->bytes_per_line);
2914 } else if (bmpImage->red_mask==0x7f00) {
2915 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
2916 convs->Convert_0888_to_555_reverse
2919 dstbits,-bmpImage->bytes_per_line);
2923 } else if (bmpImage->green_mask==0x07e0) {
2924 if (bmpImage->blue_mask==0xf800) {
2925 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
2926 convs->Convert_0888_to_565_asis
2929 dstbits,-bmpImage->bytes_per_line);
2930 } else if (bmpImage->red_mask==0xf800) {
2931 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
2932 convs->Convert_0888_to_565_reverse
2935 dstbits,-bmpImage->bytes_per_line);
2943 if (bmpImage->green_mask==0x03e0 &&
2944 (bmpImage->red_mask==0x7f00 ||
2945 bmpImage->blue_mask==0x7f00)) {
2946 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
2947 convs->Convert_any0888_to_5x5
2951 dstbits,-bmpImage->bytes_per_line,
2952 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2953 } else if (bmpImage->green_mask==0x07e0 &&
2954 (bmpImage->red_mask==0xf800 ||
2955 bmpImage->blue_mask==0xf800)) {
2956 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
2957 convs->Convert_any0888_to_5x5
2961 dstbits,-bmpImage->bytes_per_line,
2962 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2972 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2973 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
2974 bmpImage->green_mask, bmpImage->blue_mask );
2980 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
2981 const DWORD* srcpixel;
2982 int rShift,gShift,bShift;
2984 rShift=X11DRV_DIB_MaskToShift(rSrc);
2985 gShift=X11DRV_DIB_MaskToShift(gSrc);
2986 bShift=X11DRV_DIB_MaskToShift(bSrc);
2988 for (h = lines - 1; h >= 0; h--) {
2989 srcpixel=(const DWORD*)srcbits;
2990 for (x = left; x < dstwidth+left; x++) {
2992 BYTE red,green,blue;
2993 srcvalue=*srcpixel++;
2994 red= (srcvalue >> rShift) & 0xff;
2995 green=(srcvalue >> gShift) & 0xff;
2996 blue= (srcvalue >> bShift) & 0xff;
2997 XPutPixel(bmpImage, x, h, X11DRV_PALETTE_ToPhysical
2998 (physDev, RGB(red,green,blue)));
3000 srcbits += linebytes;
3008 /***********************************************************************
3009 * X11DRV_DIB_GetImageBits_32
3011 * GetDIBits for an 32-bit deep DIB.
3013 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
3014 DWORD dstwidth, DWORD srcwidth,
3015 PALETTEENTRY *srccolors,
3016 DWORD rDst, DWORD gDst, DWORD bDst,
3017 XImage *bmpImage, DWORD linebytes )
3022 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
3027 dstbits = dstbits + ( linebytes * (lines-1) );
3028 linebytes = -linebytes;
3033 switch (bmpImage->depth)
3036 if (bmpImage->bits_per_pixel==24) {
3037 const void* srcbits;
3039 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3041 if (rDst==bmpImage->red_mask && gDst==bmpImage->green_mask && bDst==bmpImage->blue_mask) {
3042 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3043 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3044 convs->Convert_888_to_0888_asis
3046 srcbits,-bmpImage->bytes_per_line,
3048 } else if (bmpImage->green_mask!=0x00ff00 ||
3049 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3051 /* the tests below assume sane bmpImage masks */
3052 } else if (rDst==bmpImage->blue_mask && gDst==bmpImage->green_mask && bDst==bmpImage->red_mask) {
3053 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3054 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3055 convs->Convert_888_to_0888_reverse
3057 srcbits,-bmpImage->bytes_per_line,
3059 } else if (bmpImage->blue_mask==0xff) {
3060 /* ==== rgb 888 bmp -> any 0888 dib ==== */
3061 convs->Convert_rgb888_to_any0888
3063 srcbits,-bmpImage->bytes_per_line,
3067 /* ==== bgr 888 bmp -> any 0888 dib ==== */
3068 convs->Convert_bgr888_to_any0888
3070 srcbits,-bmpImage->bytes_per_line,
3080 const char* srcbits;
3082 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3084 if (gDst==bmpImage->green_mask) {
3085 if (rDst==bmpImage->red_mask && bDst==bmpImage->blue_mask) {
3086 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
3087 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
3088 convs->Convert_0888_asis
3090 srcbits,-bmpImage->bytes_per_line,
3092 } else if (bmpImage->green_mask!=0x00ff00 ||
3093 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3095 /* the tests below assume sane bmpImage masks */
3096 } else if (rDst==bmpImage->blue_mask && bDst==bmpImage->red_mask) {
3097 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
3098 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
3099 convs->Convert_0888_reverse
3101 srcbits,-bmpImage->bytes_per_line,
3104 /* ==== any 0888 bmp -> any 0888 dib ==== */
3105 convs->Convert_0888_any
3107 srcbits,-bmpImage->bytes_per_line,
3108 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3112 } else if (bmpImage->green_mask!=0x00ff00 ||
3113 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3115 /* the tests below assume sane bmpImage masks */
3117 /* ==== any 0888 bmp -> any 0888 dib ==== */
3118 convs->Convert_0888_any
3120 srcbits,-bmpImage->bytes_per_line,
3121 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3131 const char* srcbits;
3133 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3135 if (rDst==0xff0000 && gDst==0x00ff00 && bDst==0x0000ff) {
3136 if (bmpImage->green_mask==0x03e0) {
3137 if (bmpImage->red_mask==0x7f00) {
3138 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
3139 convs->Convert_555_to_0888_asis
3141 srcbits,-bmpImage->bytes_per_line,
3143 } else if (bmpImage->blue_mask==0x7f00) {
3144 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
3145 convs->Convert_555_to_0888_reverse
3147 srcbits,-bmpImage->bytes_per_line,
3152 } else if (bmpImage->green_mask==0x07e0) {
3153 if (bmpImage->red_mask==0xf800) {
3154 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
3155 convs->Convert_565_to_0888_asis
3157 srcbits,-bmpImage->bytes_per_line,
3159 } else if (bmpImage->blue_mask==0xf800) {
3160 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
3161 convs->Convert_565_to_0888_reverse
3163 srcbits,-bmpImage->bytes_per_line,
3171 } else if (rDst==0x0000ff && gDst==0x00ff00 && bDst==0xff0000) {
3172 if (bmpImage->green_mask==0x03e0) {
3173 if (bmpImage->blue_mask==0x7f00) {
3174 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
3175 convs->Convert_555_to_0888_asis
3177 srcbits,-bmpImage->bytes_per_line,
3179 } else if (bmpImage->red_mask==0x7f00) {
3180 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
3181 convs->Convert_555_to_0888_reverse
3183 srcbits,-bmpImage->bytes_per_line,
3188 } else if (bmpImage->green_mask==0x07e0) {
3189 if (bmpImage->blue_mask==0xf800) {
3190 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
3191 convs->Convert_565_to_0888_asis
3193 srcbits,-bmpImage->bytes_per_line,
3195 } else if (bmpImage->red_mask==0xf800) {
3196 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
3197 convs->Convert_565_to_0888_reverse
3199 srcbits,-bmpImage->bytes_per_line,
3208 if (bmpImage->green_mask==0x03e0 &&
3209 (bmpImage->red_mask==0x7f00 ||
3210 bmpImage->blue_mask==0x7f00)) {
3211 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
3212 convs->Convert_5x5_to_any0888
3214 srcbits,-bmpImage->bytes_per_line,
3215 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3218 } else if (bmpImage->green_mask==0x07e0 &&
3219 (bmpImage->red_mask==0xf800 ||
3220 bmpImage->blue_mask==0xf800)) {
3221 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
3222 convs->Convert_5x5_to_any0888
3224 srcbits,-bmpImage->bytes_per_line,
3225 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3237 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3238 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
3239 int rShift,gShift,bShift;
3242 rShift=X11DRV_DIB_MaskToShift(rDst);
3243 gShift=X11DRV_DIB_MaskToShift(gDst);
3244 bShift=X11DRV_DIB_MaskToShift(bDst);
3245 for (h = lines - 1; h >= 0; h--) {
3246 dstpixel=(DWORD*)dstbits;
3247 for (x = 0; x < dstwidth; x++) {
3248 PALETTEENTRY srcval;
3249 srcval = srccolors[XGetPixel(bmpImage, x, h)];
3250 *dstpixel++=(srcval.peRed << rShift) |
3251 (srcval.peGreen << gShift) |
3252 (srcval.peBlue << bShift);
3254 dstbits += linebytes;
3262 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3263 /* ==== pal 8 bmp -> any 0888 dib ==== */
3264 int rShift,gShift,bShift;
3265 const void* srcbits;
3266 const BYTE* srcpixel;
3269 rShift=X11DRV_DIB_MaskToShift(rDst);
3270 gShift=X11DRV_DIB_MaskToShift(gDst);
3271 bShift=X11DRV_DIB_MaskToShift(bDst);
3272 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3273 for (h = lines - 1; h >= 0; h--) {
3275 dstpixel=(DWORD*)dstbits;
3276 for (x = 0; x < dstwidth; x++) {
3277 PALETTEENTRY srcval;
3278 srcval=srccolors[(int)*srcpixel++];
3279 *dstpixel++=(srcval.peRed << rShift) |
3280 (srcval.peGreen << gShift) |
3281 (srcval.peBlue << bShift);
3283 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
3284 dstbits += linebytes;
3294 /* ==== any bmp format -> any 0888 dib ==== */
3295 int rShift,gShift,bShift;
3298 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
3299 bmpImage->depth, bmpImage->red_mask,
3300 bmpImage->green_mask, bmpImage->blue_mask,
3303 rShift=X11DRV_DIB_MaskToShift(rDst);
3304 gShift=X11DRV_DIB_MaskToShift(gDst);
3305 bShift=X11DRV_DIB_MaskToShift(bDst);
3306 for (h = lines - 1; h >= 0; h--) {
3307 dstpixel=(DWORD*)dstbits;
3308 for (x = 0; x < dstwidth; x++) {
3310 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
3311 *dstpixel++=(GetRValue(srcval) << rShift) |
3312 (GetGValue(srcval) << gShift) |
3313 (GetBValue(srcval) << bShift);
3315 dstbits += linebytes;
3322 /***********************************************************************
3323 * X11DRV_DIB_SetImageBits
3325 * Transfer the bits to an X image.
3326 * Helper function for SetDIBits() and SetDIBitsToDevice().
3328 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
3330 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
3335 bmpImage = descr->image;
3337 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
3338 descr->infoWidth, lines, 32, 0 );
3339 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
3340 if(bmpImage->data == NULL) {
3341 ERR("Out of memory!\n");
3342 XDestroyImage( bmpImage );
3343 wine_tsx11_unlock();
3348 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
3349 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
3350 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
3351 bmpImage->depth,bmpImage->bits_per_pixel,
3352 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3354 /* Transfer the pixels */
3355 switch(descr->infoBpp)
3358 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
3359 descr->width, descr->xSrc, (int *)(descr->colorMap),
3360 bmpImage, descr->dibpitch );
3363 if (descr->compression) {
3364 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
3365 descr->width, descr->height, AllPlanes, ZPixmap,
3366 bmpImage, descr->xSrc, descr->ySrc );
3368 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
3369 descr->infoWidth, descr->width,
3370 descr->xSrc, (int *)(descr->colorMap),
3373 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
3374 descr->infoWidth, descr->width,
3375 descr->xSrc, (int*)(descr->colorMap),
3376 bmpImage, descr->dibpitch );
3379 if (descr->compression) {
3380 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
3381 descr->width, descr->height, AllPlanes, ZPixmap,
3382 bmpImage, descr->xSrc, descr->ySrc );
3383 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
3384 descr->infoWidth, descr->width,
3385 descr->xSrc, (int *)(descr->colorMap),
3388 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
3389 descr->infoWidth, descr->width,
3390 descr->xSrc, (int *)(descr->colorMap),
3391 bmpImage, descr->dibpitch );
3395 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
3396 descr->infoWidth, descr->width,
3397 descr->xSrc, descr->physDev,
3398 descr->rMask, descr->gMask, descr->bMask,
3399 bmpImage, descr->dibpitch);
3402 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
3403 descr->infoWidth, descr->width,
3404 descr->xSrc, descr->physDev,
3405 descr->rMask, descr->gMask, descr->bMask,
3406 bmpImage, descr->dibpitch);
3409 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
3410 descr->infoWidth, descr->width,
3411 descr->xSrc, descr->physDev,
3412 descr->rMask, descr->gMask, descr->bMask,
3413 bmpImage, descr->dibpitch);
3416 WARN("(%d): Invalid depth\n", descr->infoBpp );
3420 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
3421 descr->drawable, descr->gc, bmpImage,
3422 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3423 descr->width, descr->height);
3424 #ifdef HAVE_LIBXXSHM
3427 XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
3428 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3429 descr->width, descr->height, FALSE );
3430 XSync( gdi_display, 0 );
3434 XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
3435 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3436 descr->width, descr->height );
3438 if (!descr->image) XDestroyImage( bmpImage );
3439 wine_tsx11_unlock();
3443 /***********************************************************************
3444 * X11DRV_DIB_GetImageBits
3446 * Transfer the bits from an X image.
3448 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
3450 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
3455 bmpImage = descr->image;
3457 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
3458 descr->infoWidth, lines, 32, 0 );
3459 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
3460 if(bmpImage->data == NULL) {
3461 ERR("Out of memory!\n");
3462 XDestroyImage( bmpImage );
3463 wine_tsx11_unlock();
3468 #ifdef HAVE_LIBXXSHM
3471 int saveRed, saveGreen, saveBlue;
3473 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
3474 gdi_display, descr->drawable, bmpImage,
3475 descr->xSrc, descr->ySrc, AllPlanes);
3477 /* We must save and restore the bmpImage's masks in order
3478 * to preserve them across the call to XShmGetImage, which
3479 * decides to eleminate them since it doesn't happen to know
3480 * what the format of the image is supposed to be, even though
3482 saveRed = bmpImage->red_mask;
3483 saveBlue= bmpImage->blue_mask;
3484 saveGreen = bmpImage->green_mask;
3486 XShmGetImage( gdi_display, descr->drawable, bmpImage,
3487 descr->xSrc, descr->ySrc, AllPlanes);
3489 bmpImage->red_mask = saveRed;
3490 bmpImage->blue_mask = saveBlue;
3491 bmpImage->green_mask = saveGreen;
3494 #endif /* HAVE_LIBXXSHM */
3496 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
3497 gdi_display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
3498 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
3499 XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
3500 descr->width, lines, AllPlanes, ZPixmap,
3501 bmpImage, descr->xDest, descr->yDest );
3504 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
3505 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
3506 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
3507 bmpImage->depth,bmpImage->bits_per_pixel,
3508 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3509 /* Transfer the pixels */
3510 switch(descr->infoBpp)
3513 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
3514 descr->infoWidth, descr->width,
3515 descr->colorMap, descr->palentry,
3516 bmpImage, descr->dibpitch );
3520 if (descr->compression) {
3521 FIXME("Compression not yet supported!\n");
3522 if(descr->sizeImage < X11DRV_DIB_GetDIBWidthBytes( descr->infoWidth, 4 ) * abs(descr->lines))
3525 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
3526 descr->infoWidth, descr->width,
3527 descr->colorMap, descr->palentry,
3528 bmpImage, descr->dibpitch );
3531 if (descr->compression) {
3532 FIXME("Compression not yet supported!\n");
3533 if(descr->sizeImage < X11DRV_DIB_GetDIBWidthBytes( descr->infoWidth, 8 ) * abs(descr->lines))
3536 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
3537 descr->infoWidth, descr->width,
3538 descr->colorMap, descr->palentry,
3539 bmpImage, descr->dibpitch );
3543 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
3544 descr->infoWidth,descr->width,
3546 descr->rMask, descr->gMask, descr->bMask,
3547 bmpImage, descr->dibpitch );
3551 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
3552 descr->infoWidth,descr->width,
3554 descr->rMask, descr->gMask, descr->bMask,
3555 bmpImage, descr->dibpitch);
3559 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
3560 descr->infoWidth, descr->width,
3562 descr->rMask, descr->gMask, descr->bMask,
3563 bmpImage, descr->dibpitch);
3567 WARN("(%d): Invalid depth\n", descr->infoBpp );
3571 if (!descr->image) XDestroyImage( bmpImage );
3572 wine_tsx11_unlock();
3576 /*************************************************************************
3577 * X11DRV_SetDIBitsToDevice
3580 INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWORD cx,
3581 DWORD cy, INT xSrc, INT ySrc,
3582 UINT startscan, UINT lines, LPCVOID bits,
3583 const BITMAPINFO *info, UINT coloruse )
3585 X11DRV_DIB_IMAGEBITS_DESCR descr;
3592 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
3593 &descr.infoBpp, &descr.compression ) == -1)
3595 top_down = (height < 0);
3596 if (top_down) height = -height;
3600 LPtoDP(physDev->hdc, &pt, 1);
3602 if (!lines || (startscan >= height)) return 0;
3603 if (!top_down && startscan + lines > height) lines = height - startscan;
3605 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
3606 * and clamp all values to fit inside [startscan,startscan+lines]
3608 if (ySrc + cy <= startscan + lines)
3610 INT y = startscan + lines - (ySrc + cy);
3611 if (ySrc < startscan) cy -= (startscan - ySrc);
3614 /* avoid getting unnecessary lines */
3616 if (y >= lines) return 0;
3621 if (y >= lines) return lines;
3622 ySrc = y; /* need to get all lines in top down mode */
3627 if (ySrc >= startscan + lines) return lines;
3628 pt.y += ySrc + cy - (startscan + lines);
3629 cy = startscan + lines - ySrc;
3631 if (cy > lines) cy = lines;
3633 if (xSrc >= width) return lines;
3634 if (xSrc + cx >= width) cx = width - xSrc;
3635 if (!cx || !cy) return lines;
3637 X11DRV_SetupGCForText( physDev ); /* To have the correct colors */
3639 XSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[GetROP2(physDev->hdc) - 1]);
3640 wine_tsx11_unlock();
3642 switch (descr.infoBpp)
3647 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3648 coloruse == DIB_PAL_COLORS ? physDev : NULL, coloruse,
3649 physDev->depth, info, &descr.nColorMap );
3650 if (!descr.colorMap) return 0;
3651 descr.rMask = descr.gMask = descr.bMask = 0;
3655 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3656 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3657 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3663 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3664 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
3665 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
3670 descr.physDev = physDev;
3673 descr.palentry = NULL;
3674 descr.lines = top_down ? -lines : lines;
3675 descr.infoWidth = width;
3676 descr.depth = physDev->depth;
3677 descr.drawable = physDev->drawable;
3678 descr.gc = physDev->gc;
3681 descr.xDest = physDev->org.x + pt.x;
3682 descr.yDest = physDev->org.y + pt.y;
3685 descr.useShm = FALSE;
3686 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
3688 result = X11DRV_DIB_SetImageBits( &descr );
3690 if (descr.infoBpp <= 8)
3691 HeapFree(GetProcessHeap(), 0, descr.colorMap);
3695 /***********************************************************************
3696 * SetDIBits (X11DRV.@)
3698 INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
3699 UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse )
3701 X11DRV_DIB_IMAGEBITS_DESCR descr;
3703 int height, tmpheight;
3706 descr.physDev = physDev;
3708 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
3709 &descr.infoBpp, &descr.compression ) == -1)
3713 if (height < 0) height = -height;
3714 if (!lines || (startscan >= height))
3717 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
3719 if (startscan + lines > height) lines = height - startscan;
3721 switch (descr.infoBpp)
3726 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3727 coloruse == DIB_PAL_COLORS ? descr.physDev : NULL, coloruse,
3728 bmp->bitmap.bmBitsPixel,
3729 info, &descr.nColorMap );
3730 if (!descr.colorMap)
3732 GDI_ReleaseObj( hbitmap );
3735 descr.rMask = descr.gMask = descr.bMask = 0;
3739 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3740 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3741 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3747 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3748 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
3749 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
3758 descr.palentry = NULL;
3759 descr.lines = tmpheight >= 0 ? lines : -lines;
3760 descr.depth = bmp->bitmap.bmBitsPixel;
3761 descr.drawable = (Pixmap)bmp->physBitmap;
3762 descr.gc = BITMAP_GC(bmp);
3766 descr.yDest = height - startscan - lines;
3767 descr.width = bmp->bitmap.bmWidth;
3768 descr.height = lines;
3769 descr.useShm = FALSE;
3770 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
3771 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
3772 result = X11DRV_DIB_SetImageBits( &descr );
3773 X11DRV_DIB_Unlock(bmp, TRUE);
3775 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
3777 GDI_ReleaseObj( hbitmap );
3781 /***********************************************************************
3782 * GetDIBits (X11DRV.@)
3784 INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, UINT lines,
3785 LPVOID bits, BITMAPINFO *info, UINT coloruse )
3787 X11DRV_DIBSECTION *dib;
3788 X11DRV_DIB_IMAGEBITS_DESCR descr;
3789 PALETTEENTRY palette[256];
3793 GetPaletteEntries( GetCurrentObject( physDev->hdc, OBJ_PAL ), 0, 256, palette );
3795 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
3797 dib = (X11DRV_DIBSECTION *) bmp->dib;
3799 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3800 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
3801 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
3804 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
3806 height = info->bmiHeader.biHeight;
3807 if (height < 0) height = -height;
3808 if( lines > height ) lines = height;
3809 /* Top-down images have a negative biHeight, the scanlines of theses images
3810 * were inverted in X11DRV_DIB_GetImageBits_xx
3811 * To prevent this we simply change the sign of lines
3812 * (the number of scan lines to copy).
3813 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3815 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
3817 if( startscan >= bmp->bitmap.bmHeight )
3823 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
3824 &descr.infoBpp, &descr.compression ) == -1)
3830 descr.colorMap = NULL;
3832 switch (descr.infoBpp)
3837 descr.rMask= descr.gMask = descr.bMask = 0;
3838 if(coloruse == DIB_RGB_COLORS)
3839 descr.colorMap = info->bmiColors;
3841 int num_colors = 1 << descr.infoBpp, i;
3844 WORD *index = (WORD*)info->bmiColors;
3845 descr.colorMap = rgb = HeapAlloc(GetProcessHeap(), 0, num_colors * sizeof(RGBQUAD));
3846 for(i = 0; i < num_colors; i++, rgb++, index++) {
3847 colref = X11DRV_PALETTE_ToLogical(X11DRV_PALETTE_ToPhysical(physDev, PALETTEINDEX(*index)));
3848 rgb->rgbRed = GetRValue(colref);
3849 rgb->rgbGreen = GetGValue(colref);
3850 rgb->rgbBlue = GetBValue(colref);
3851 rgb->rgbReserved = 0;
3857 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3858 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3859 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3863 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3864 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
3865 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
3869 descr.physDev = physDev;
3870 descr.palentry = palette;
3873 descr.lines = lines;
3874 descr.depth = bmp->bitmap.bmBitsPixel;
3875 descr.drawable = (Pixmap)bmp->physBitmap;
3876 descr.gc = BITMAP_GC(bmp);
3877 descr.width = bmp->bitmap.bmWidth;
3878 descr.height = bmp->bitmap.bmHeight;
3882 descr.sizeImage = info->bmiHeader.biSizeImage;
3884 if (descr.lines > 0)
3886 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
3890 descr.ySrc = startscan;
3892 #ifdef HAVE_LIBXXSHM
3893 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
3895 descr.useShm = FALSE;
3897 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
3898 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
3900 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
3901 X11DRV_DIB_GetImageBits( &descr );
3902 X11DRV_DIB_Unlock(bmp, TRUE);
3904 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
3905 info->bmiHeader.biSizeImage = X11DRV_DIB_GetDIBWidthBytes( info->bmiHeader.biWidth,
3906 info->bmiHeader.biBitCount )
3907 * abs( info->bmiHeader.biHeight );
3909 if (descr.compression == BI_BITFIELDS)
3911 *(DWORD *)info->bmiColors = descr.rMask;
3912 *((DWORD *)info->bmiColors+1) = descr.gMask;
3913 *((DWORD *)info->bmiColors+2) = descr.bMask;
3917 /* if RLE or JPEG compression were supported,
3918 * this line would be invalid. */
3919 info->bmiHeader.biCompression = 0;
3922 if(descr.colorMap && descr.colorMap != info->bmiColors)
3923 HeapFree(GetProcessHeap(), 0, descr.colorMap);
3925 GDI_ReleaseObj( hbitmap );
3929 /***********************************************************************
3930 * DIB_DoProtectDIBSection
3932 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
3936 DIBSECTION *dib = bmp->dib;
3937 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
3938 : -dib->dsBm.bmHeight;
3940 /* use the biSizeImage data as the memory size only if we're dealing with a
3941 compressed image where the value is set. Otherwise, calculate based on
3943 if (dib->dsBmih.biSizeImage &&
3944 (dib->dsBmih.biCompression == BI_RLE4 || dib->dsBmih.biCompression == BI_RLE8))
3945 totalSize = dib->dsBmih.biSizeImage;
3947 totalSize = dib->dsBm.bmWidthBytes * effHeight;
3949 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
3950 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
3953 /***********************************************************************
3954 * X11DRV_DIB_DoUpdateDIBSection
3956 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
3957 void *colorMap, int nColorMap,
3959 DWORD xSrc, DWORD ySrc,
3960 DWORD xDest, DWORD yDest,
3961 DWORD width, DWORD height)
3963 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3964 X11DRV_DIB_IMAGEBITS_DESCR descr;
3966 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
3967 &descr.infoBpp, &descr.compression ) == -1)
3970 descr.physDev = NULL;
3971 descr.palentry = NULL;
3972 descr.image = dib->image;
3973 descr.colorMap = colorMap;
3974 descr.nColorMap = nColorMap;
3975 descr.bits = dib->dibSection.dsBm.bmBits;
3976 descr.depth = bmp->bitmap.bmBitsPixel;
3978 switch (descr.infoBpp)
3983 descr.rMask = descr.gMask = descr.bMask = 0;
3987 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
3988 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
3989 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
3994 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff0000;
3995 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x00ff00;
3996 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x0000ff;
4001 descr.drawable = dest;
4002 descr.gc = BITMAP_GC(bmp);
4005 descr.xDest = xDest;
4006 descr.yDest = yDest;
4007 descr.width = width;
4008 descr.height = height;
4009 descr.sizeImage = 0;
4011 #ifdef HAVE_LIBXXSHM
4012 descr.useShm = (dib->shminfo.shmid != -1);
4014 descr.useShm = FALSE;
4016 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
4020 TRACE("Copying from Pixmap to DIB bits\n");
4021 X11DRV_DIB_GetImageBits( &descr );
4025 TRACE("Copying from DIB bits to Pixmap\n");
4026 X11DRV_DIB_SetImageBits( &descr );
4030 /***********************************************************************
4031 * X11DRV_DIB_CopyDIBSection
4033 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
4034 DWORD xSrc, DWORD ySrc, DWORD xDest, DWORD yDest,
4035 DWORD width, DWORD height)
4039 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
4041 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", physDevSrc->hdc, physDevDst->hdc,
4042 xSrc, ySrc, xDest, yDest, width, height);
4043 /* this function is meant as an optimization for BitBlt,
4044 * not to be called otherwise */
4045 if (GetObjectType( physDevSrc->hdc ) != OBJ_MEMDC) {
4046 ERR("called for non-memory source DC!?\n");
4050 hBitmap = GetCurrentObject( physDevSrc->hdc, OBJ_BITMAP );
4051 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC );
4052 if (!(bmp && bmp->dib)) {
4053 ERR("called for non-DIBSection!?\n");
4054 GDI_ReleaseObj( hBitmap );
4057 /* while BitBlt should already have made sure we only get
4058 * positive values, we should check for oversize values */
4059 if ((xSrc < bmp->bitmap.bmWidth) &&
4060 (ySrc < bmp->bitmap.bmHeight)) {
4061 if (xSrc + width > bmp->bitmap.bmWidth)
4062 width = bmp->bitmap.bmWidth - xSrc;
4063 if (ySrc + height > bmp->bitmap.bmHeight)
4064 height = bmp->bitmap.bmHeight - ySrc;
4065 /* if the source bitmap is 8bpp or less, we're supposed to use the
4066 * DC's palette for color conversion (not the DIB color table) */
4067 if (bmp->dib->dsBm.bmBitsPixel <= 8) {
4068 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4069 HPALETTE hPalette = GetCurrentObject( physDevSrc->hdc, OBJ_PAL );
4070 if (!hPalette || (hPalette == GetStockObject(DEFAULT_PALETTE))) {
4071 /* HACK: no palette has been set in the source DC,
4072 * use the DIB colormap instead - this is necessary in some
4073 * cases since we need to do depth conversion in some places
4074 * where real Windows can just copy data straight over */
4075 colorMap = dib->colorMap;
4076 nColorMap = dib->nColorMap;
4078 colorMap = X11DRV_DIB_BuildColorMap( physDevSrc, (WORD)-1,
4079 bmp->dib->dsBm.bmBitsPixel,
4080 (BITMAPINFO*)&(bmp->dib->dsBmih),
4082 if (colorMap) aColorMap = TRUE;
4085 /* perform the copy */
4086 X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
4087 physDevDst->drawable, xSrc, ySrc,
4088 physDevDst->org.x + xDest, physDevDst->org.y + yDest,
4090 /* free color mapping */
4092 HeapFree(GetProcessHeap(), 0, colorMap);
4094 GDI_ReleaseObj( hBitmap );
4097 /***********************************************************************
4098 * X11DRV_DIB_DoUpdateDIBSection
4100 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
4102 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4103 X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
4104 (Drawable)bmp->physBitmap, 0, 0, 0, 0,
4105 bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
4108 /***********************************************************************
4109 * X11DRV_DIB_FaultHandler
4111 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
4116 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
4117 if (!bmp) return FALSE;
4119 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
4120 if (state != DIB_Status_InSync) {
4121 /* no way to tell whether app needs read or write yet,
4123 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
4125 /* hm, apparently the app must have write access */
4126 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
4128 X11DRV_DIB_Unlock(bmp, TRUE);
4130 GDI_ReleaseObj( (HBITMAP)res );
4134 /***********************************************************************
4137 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
4139 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4140 INT ret = DIB_Status_None;
4143 EnterCriticalSection(&(dib->lock));
4146 case DIB_Status_GdiMod:
4147 /* GDI access - request to draw on pixmap */
4148 switch (dib->status)
4151 case DIB_Status_None:
4152 dib->p_status = DIB_Status_GdiMod;
4153 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
4156 case DIB_Status_GdiMod:
4157 TRACE("GdiMod requested in status GdiMod\n" );
4160 case DIB_Status_InSync:
4161 TRACE("GdiMod requested in status InSync\n" );
4162 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4163 dib->status = DIB_Status_GdiMod;
4164 dib->p_status = DIB_Status_InSync;
4167 case DIB_Status_AuxMod:
4168 TRACE("GdiMod requested in status AuxMod\n" );
4169 if (lossy) dib->status = DIB_Status_GdiMod;
4170 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
4171 dib->p_status = DIB_Status_AuxMod;
4172 if (dib->status != DIB_Status_AppMod) {
4173 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4176 /* fall through if copy_aux() had to change to AppMod state */
4178 case DIB_Status_AppMod:
4179 TRACE("GdiMod requested in status AppMod\n" );
4181 /* make it readonly to avoid app changing data while we copy */
4182 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4183 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
4185 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4186 dib->p_status = DIB_Status_AppMod;
4187 dib->status = DIB_Status_GdiMod;
4192 case DIB_Status_InSync:
4193 /* App access - request access to read DIB surface */
4194 /* (typically called from signal handler) */
4195 switch (dib->status)
4198 case DIB_Status_None:
4199 /* shouldn't happen from signal handler */
4202 case DIB_Status_AuxMod:
4203 TRACE("InSync requested in status AuxMod\n" );
4204 if (lossy) dib->status = DIB_Status_InSync;
4206 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4207 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
4209 if (dib->status != DIB_Status_GdiMod) {
4210 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4213 /* fall through if copy_aux() had to change to GdiMod state */
4215 case DIB_Status_GdiMod:
4216 TRACE("InSync requested in status GdiMod\n" );
4218 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4219 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
4221 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4222 dib->status = DIB_Status_InSync;
4225 case DIB_Status_InSync:
4226 TRACE("InSync requested in status InSync\n" );
4227 /* shouldn't happen from signal handler */
4230 case DIB_Status_AppMod:
4231 TRACE("InSync requested in status AppMod\n" );
4232 /* no reason to do anything here, and this
4233 * shouldn't happen from signal handler */
4238 case DIB_Status_AppMod:
4239 /* App access - request access to write DIB surface */
4240 /* (typically called from signal handler) */
4241 switch (dib->status)
4244 case DIB_Status_None:
4245 /* shouldn't happen from signal handler */
4248 case DIB_Status_AuxMod:
4249 TRACE("AppMod requested in status AuxMod\n" );
4250 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4251 if (lossy) dib->status = DIB_Status_AppMod;
4252 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
4253 if (dib->status != DIB_Status_GdiMod)
4255 /* fall through if copy_aux() had to change to GdiMod state */
4257 case DIB_Status_GdiMod:
4258 TRACE("AppMod requested in status GdiMod\n" );
4259 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4260 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
4261 dib->status = DIB_Status_AppMod;
4264 case DIB_Status_InSync:
4265 TRACE("AppMod requested in status InSync\n" );
4266 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4267 dib->status = DIB_Status_AppMod;
4270 case DIB_Status_AppMod:
4271 TRACE("AppMod requested in status AppMod\n" );
4272 /* shouldn't happen from signal handler */
4277 case DIB_Status_AuxMod:
4278 if (dib->status == DIB_Status_None) {
4279 dib->p_status = req;
4281 if (dib->status != DIB_Status_AuxMod)
4282 dib->p_status = dib->status;
4283 dib->status = DIB_Status_AuxMod;
4286 /* it is up to the caller to do the copy/conversion, probably
4287 * using the return value to decide where to copy from */
4289 LeaveCriticalSection(&(dib->lock));
4294 /***********************************************************************
4297 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
4299 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4300 INT ret = DIB_Status_None;
4303 TRACE("Locking %p from thread %04lx\n", bmp, GetCurrentThreadId());
4304 EnterCriticalSection(&(dib->lock));
4306 if (req != DIB_Status_None)
4307 X11DRV_DIB_Coerce(bmp, req, lossy);
4312 /***********************************************************************
4315 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
4317 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4320 switch (dib->status)
4323 case DIB_Status_None:
4324 /* in case anyone is wondering, this is the "signal handler doesn't
4325 * work" case, where we always have to be ready for app access */
4327 switch (dib->p_status)
4329 case DIB_Status_AuxMod:
4330 TRACE("Unlocking and syncing from AuxMod\n" );
4331 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
4332 if (dib->status != DIB_Status_None) {
4333 dib->p_status = dib->status;
4334 dib->status = DIB_Status_None;
4336 if (dib->p_status != DIB_Status_GdiMod)
4338 /* fall through if copy_aux() had to change to GdiMod state */
4340 case DIB_Status_GdiMod:
4341 TRACE("Unlocking and syncing from GdiMod\n" );
4342 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
4346 TRACE("Unlocking without needing to sync\n" );
4350 else TRACE("Unlocking with no changes\n");
4351 dib->p_status = DIB_Status_None;
4354 case DIB_Status_GdiMod:
4355 TRACE("Unlocking in status GdiMod\n" );
4356 /* DIB was protected in Coerce */
4358 /* no commit, revert to InSync if applicable */
4359 if ((dib->p_status == DIB_Status_InSync) ||
4360 (dib->p_status == DIB_Status_AppMod)) {
4361 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4362 dib->status = DIB_Status_InSync;
4367 case DIB_Status_InSync:
4368 TRACE("Unlocking in status InSync\n" );
4369 /* DIB was already protected in Coerce */
4372 case DIB_Status_AppMod:
4373 TRACE("Unlocking in status AppMod\n" );
4374 /* DIB was already protected in Coerce */
4375 /* this case is ordinary only called from the signal handler,
4376 * so we don't bother to check for !commit */
4379 case DIB_Status_AuxMod:
4380 TRACE("Unlocking in status AuxMod\n" );
4382 /* DIB may need protection now */
4383 if ((dib->p_status == DIB_Status_InSync) ||
4384 (dib->p_status == DIB_Status_AppMod))
4385 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4387 /* no commit, revert to previous state */
4388 if (dib->p_status != DIB_Status_None)
4389 dib->status = dib->p_status;
4390 /* no protections changed */
4392 dib->p_status = DIB_Status_None;
4395 LeaveCriticalSection(&(dib->lock));
4396 TRACE("Unlocked %p\n", bmp);
4400 /***********************************************************************
4401 * X11DRV_CoerceDIBSection2
4403 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
4408 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4409 if (!bmp) return DIB_Status_None;
4410 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
4411 GDI_ReleaseObj( hBmp );
4415 /***********************************************************************
4416 * X11DRV_LockDIBSection2
4418 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
4423 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4424 if (!bmp) return DIB_Status_None;
4425 ret = X11DRV_DIB_Lock(bmp, req, lossy);
4426 GDI_ReleaseObj( hBmp );
4430 /***********************************************************************
4431 * X11DRV_UnlockDIBSection2
4433 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
4437 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4439 X11DRV_DIB_Unlock(bmp, commit);
4440 GDI_ReleaseObj( hBmp );
4443 /***********************************************************************
4444 * X11DRV_CoerceDIBSection
4446 INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
4448 if (!physDev) return DIB_Status_None;
4449 return X11DRV_CoerceDIBSection2( GetCurrentObject( physDev->hdc, OBJ_BITMAP ), req, lossy );
4452 /***********************************************************************
4453 * X11DRV_LockDIBSection
4455 INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
4457 if (!physDev) return DIB_Status_None;
4458 if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return DIB_Status_None;
4460 return X11DRV_LockDIBSection2( GetCurrentObject( physDev->hdc, OBJ_BITMAP ), req, lossy );
4463 /***********************************************************************
4464 * X11DRV_UnlockDIBSection
4466 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev, BOOL commit)
4468 if (!physDev) return;
4469 if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return;
4471 X11DRV_UnlockDIBSection2( GetCurrentObject( physDev->hdc, OBJ_BITMAP ), commit );
4475 #ifdef HAVE_LIBXXSHM
4476 /***********************************************************************
4477 * X11DRV_XShmErrorHandler
4480 static int XShmErrorHandler( Display *dpy, XErrorEvent *event, void *arg )
4482 return 1; /* FIXME: should check event contents */
4485 /***********************************************************************
4486 * X11DRV_XShmCreateImage
4489 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
4490 XShmSegmentInfo* shminfo)
4494 image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
4497 shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
4499 if( shminfo->shmid != -1 )
4501 shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
4502 if( shminfo->shmaddr != (char*)-1 )
4506 shminfo->readOnly = FALSE;
4507 X11DRV_expect_error( gdi_display, XShmErrorHandler, NULL );
4508 ok = (XShmAttach( gdi_display, shminfo ) != 0);
4509 XSync( gdi_display, False );
4510 if (X11DRV_check_error()) ok = FALSE;
4513 shmctl(shminfo->shmid, IPC_RMID, 0);
4514 return image; /* Success! */
4516 /* An error occurred */
4517 shmdt(shminfo->shmaddr);
4519 shmctl(shminfo->shmid, IPC_RMID, 0);
4521 XFlush(gdi_display);
4522 XDestroyImage(image);
4527 #endif /* HAVE_LIBXXSHM */
4530 /***********************************************************************
4531 * X11DRV_DIB_CreateDIBSection
4533 HBITMAP X11DRV_DIB_CreateDIBSection(
4534 X11DRV_PDEVICE *physDev, const BITMAPINFO *bmi, UINT usage,
4535 VOID **bits, HANDLE section,
4536 DWORD offset, DWORD ovr_pitch)
4539 BITMAPOBJ *bmp = NULL;
4540 X11DRV_DIBSECTION *dib = NULL;
4541 int *colorMap = NULL;
4544 /* Fill BITMAP32 structure with DIB data */
4545 const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
4546 INT effHeight, totalSize;
4548 LPVOID mapBits = NULL;
4550 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
4551 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
4552 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
4554 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
4556 bm.bmWidth = bi->biWidth;
4557 bm.bmHeight = effHeight;
4558 bm.bmWidthBytes = ovr_pitch ? ovr_pitch : X11DRV_DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
4559 bm.bmPlanes = bi->biPlanes;
4560 bm.bmBitsPixel = bi->biBitCount;
4563 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
4564 we're dealing with a compressed bitmap. Otherwise, use width * height. */
4565 if (bi->biSizeImage && (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8))
4566 totalSize = bi->biSizeImage;
4568 totalSize = bm.bmWidthBytes * effHeight;
4572 SYSTEM_INFO SystemInfo;
4576 GetSystemInfo( &SystemInfo );
4577 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
4578 mapSize = totalSize + (offset - mapOffset);
4579 mapBits = MapViewOfFile( section,
4580 FILE_MAP_ALL_ACCESS,
4584 bm.bmBits = (char *)mapBits + (offset - mapOffset);
4586 else if (ovr_pitch && offset)
4587 bm.bmBits = (LPVOID) offset;
4590 bm.bmBits = VirtualAlloc(NULL, totalSize,
4591 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
4594 /* Create Color Map */
4595 if (bm.bmBits && bm.bmBitsPixel <= 8)
4596 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? physDev : NULL,
4597 usage, bm.bmBitsPixel, bmi, &nColorMap );
4599 /* Allocate Memory for DIB and fill structure */
4601 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
4604 dib->dibSection.dsBm = bm;
4605 dib->dibSection.dsBmih = *bi;
4606 dib->dibSection.dsBmih.biSizeImage = totalSize;
4608 /* Set dsBitfields values */
4609 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
4611 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
4613 else switch( bi->biBitCount )
4617 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
4618 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
4619 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
4624 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff0000;
4625 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x00ff00;
4626 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x0000ff;
4629 dib->dibSection.dshSection = section;
4630 dib->dibSection.dsOffset = offset;
4632 dib->status = DIB_Status_None;
4633 dib->nColorMap = nColorMap;
4634 dib->colorMap = colorMap;
4637 /* Create Device Dependent Bitmap and add DIB pointer */
4640 res = CreateDIBitmap(physDev->hdc, bi, 0, NULL, bmi, usage);
4643 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
4644 if (bmp) bmp->dib = (DIBSECTION *) dib;
4652 #ifdef HAVE_LIBXXSHM
4653 if (XShmQueryExtension(gdi_display) &&
4654 (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
4655 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
4657 ; /* Created Image */
4659 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
4660 dib->shminfo.shmid = -1;
4663 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
4665 wine_tsx11_unlock();
4668 /* Clean up in case of errors */
4669 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
4671 TRACE("got an error res=%p, bmp=%p, dib=%p, bm.bmBits=%p\n",
4672 res, bmp, dib, bm.bmBits);
4676 UnmapViewOfFile(mapBits), bm.bmBits = NULL;
4678 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
4681 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
4682 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
4683 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
4684 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
4685 if (res) { DeleteObject(res); res = 0; }
4689 extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, BOOL (*proc)(LPVOID, LPCVOID), LPVOID arg);
4690 /* Install fault handler, if possible */
4691 InitializeCriticalSection(&(dib->lock));
4692 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
4694 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4695 if (dib) dib->status = DIB_Status_AppMod;
4699 /* Return BITMAP handle and storage location */
4700 if (bmp) GDI_ReleaseObj(res);
4701 if (bm.bmBits && bits) *bits = bm.bmBits;
4705 /***********************************************************************
4706 * X11DRV_DIB_DeleteDIBSection
4708 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
4710 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4715 #ifdef HAVE_LIBXXSHM
4716 if (dib->shminfo.shmid != -1)
4718 XShmDetach (gdi_display, &(dib->shminfo));
4719 XDestroyImage (dib->image);
4720 shmdt (dib->shminfo.shmaddr);
4721 dib->shminfo.shmid = -1;
4725 XDestroyImage( dib->image );
4726 wine_tsx11_unlock();
4730 HeapFree(GetProcessHeap(), 0, dib->colorMap);
4732 DeleteCriticalSection(&(dib->lock));
4735 /***********************************************************************
4736 * SetDIBColorTable (X11DRV.@)
4738 UINT X11DRV_SetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, const RGBQUAD *colors )
4741 X11DRV_DIBSECTION *dib;
4743 HBITMAP hBitmap = GetCurrentObject( physDev->hdc, OBJ_BITMAP );
4745 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC ))) return 0;
4746 dib = (X11DRV_DIBSECTION *) bmp->dib;
4748 if (dib && dib->colorMap) {
4749 UINT end = count + start;
4750 if (end > dib->nColorMap) end = dib->nColorMap;
4752 * Changing color table might change the mapping between
4753 * DIB colors and X11 colors and thus alter the visible state
4754 * of the bitmap object.
4756 X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
4757 X11DRV_DIB_GenColorMap( physDev, dib->colorMap, DIB_RGB_COLORS,
4758 dib->dibSection.dsBm.bmBitsPixel,
4759 TRUE, colors, start, end );
4760 X11DRV_DIB_Unlock(bmp, TRUE);
4763 GDI_ReleaseObj( hBitmap );
4767 /***********************************************************************
4768 * GetDIBColorTable (X11DRV.@)
4770 UINT X11DRV_GetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, RGBQUAD *colors )
4773 X11DRV_DIBSECTION *dib;
4775 HBITMAP hBitmap = GetCurrentObject( physDev->hdc, OBJ_BITMAP );
4777 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC ))) return 0;
4778 dib = (X11DRV_DIBSECTION *) bmp->dib;
4780 if (dib && dib->colorMap) {
4781 UINT i, end = count + start;
4782 if (end > dib->nColorMap) end = dib->nColorMap;
4783 for (i = start; i < end; i++,colors++) {
4784 COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
4785 colors->rgbBlue = GetBValue(col);
4786 colors->rgbGreen = GetGValue(col);
4787 colors->rgbRed = GetRValue(col);
4788 colors->rgbReserved = 0;
4792 GDI_ReleaseObj( hBitmap );
4798 /***********************************************************************
4799 * X11DRV_DIB_CreateDIBFromBitmap
4801 * Allocates a packed DIB and copies the bitmap data into it.
4803 HGLOBAL X11DRV_DIB_CreateDIBFromBitmap(HDC hdc, HBITMAP hBmp)
4808 LPBITMAPINFOHEADER pbmiHeader;
4809 unsigned int cDataSize, cPackedSize, OffsetBits, nLinesCopied;
4811 if (!GetObjectW( hBmp, sizeof(bmp), &bmp )) return 0;
4814 * A packed DIB contains a BITMAPINFO structure followed immediately by
4815 * an optional color palette and the pixel data.
4818 /* Calculate the size of the packed DIB */
4819 cDataSize = X11DRV_DIB_GetDIBWidthBytes( bmp.bmWidth, bmp.bmBitsPixel ) * abs( bmp.bmHeight );
4820 cPackedSize = sizeof(BITMAPINFOHEADER)
4821 + ( (bmp.bmBitsPixel <= 8) ? (sizeof(RGBQUAD) * (1 << bmp.bmBitsPixel)) : 0 )
4823 /* Get the offset to the bits */
4824 OffsetBits = cPackedSize - cDataSize;
4826 /* Allocate the packed DIB */
4827 TRACE("\tAllocating packed DIB of size %d\n", cPackedSize);
4828 hPackedDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE /*| GMEM_ZEROINIT*/,
4832 WARN("Could not allocate packed DIB!\n");
4836 /* A packed DIB starts with a BITMAPINFOHEADER */
4837 pPackedDIB = GlobalLock(hPackedDIB);
4838 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
4840 /* Init the BITMAPINFOHEADER */
4841 pbmiHeader->biSize = sizeof(BITMAPINFOHEADER);
4842 pbmiHeader->biWidth = bmp.bmWidth;
4843 pbmiHeader->biHeight = bmp.bmHeight;
4844 pbmiHeader->biPlanes = 1;
4845 pbmiHeader->biBitCount = bmp.bmBitsPixel;
4846 pbmiHeader->biCompression = BI_RGB;
4847 pbmiHeader->biSizeImage = 0;
4848 pbmiHeader->biXPelsPerMeter = pbmiHeader->biYPelsPerMeter = 0;
4849 pbmiHeader->biClrUsed = 0;
4850 pbmiHeader->biClrImportant = 0;
4852 /* Retrieve the DIB bits from the bitmap and fill in the
4853 * DIB color table if present */
4855 nLinesCopied = GetDIBits(hdc, /* Handle to device context */
4856 hBmp, /* Handle to bitmap */
4857 0, /* First scan line to set in dest bitmap */
4858 bmp.bmHeight, /* Number of scan lines to copy */
4859 pPackedDIB + OffsetBits, /* [out] Address of array for bitmap bits */
4860 (LPBITMAPINFO) pbmiHeader, /* [out] Address of BITMAPINFO structure */
4861 0); /* RGB or palette index */
4862 GlobalUnlock(hPackedDIB);
4864 /* Cleanup if GetDIBits failed */
4865 if (nLinesCopied != bmp.bmHeight)
4867 TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied, bmp.bmHeight);
4868 GlobalFree(hPackedDIB);
4875 /**************************************************************************
4876 * X11DRV_DIB_CreateDIBFromPixmap
4878 * Allocates a packed DIB and copies the Pixmap data into it.
4879 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
4881 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
4884 BITMAPOBJ *pBmp = NULL;
4885 HGLOBAL hPackedDIB = 0;
4887 /* Allocates an HBITMAP which references the Pixmap passed to us */
4888 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(hdc, pixmap);
4891 TRACE("\tCould not create bitmap header for Pixmap\n");
4896 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4897 * A packed DIB contains a BITMAPINFO structure followed immediately by
4898 * an optional color palette and the pixel data.
4900 hPackedDIB = X11DRV_DIB_CreateDIBFromBitmap(hdc, hBmp);
4902 /* Get a pointer to the BITMAPOBJ structure */
4903 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4905 /* We can now get rid of the HBITMAP wrapper we created earlier.
4906 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4910 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4911 pBmp->physBitmap = NULL;
4914 GDI_ReleaseObj( hBmp );
4918 TRACE("\tReturning packed DIB %p\n", hPackedDIB);
4923 /**************************************************************************
4924 * X11DRV_DIB_CreatePixmapFromDIB
4926 * Creates a Pixmap from a packed DIB
4928 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
4930 Pixmap pixmap = None;
4932 BITMAPOBJ *pBmp = NULL;
4933 LPBYTE pPackedDIB = NULL;
4934 LPBITMAPINFO pbmi = NULL;
4935 LPBITMAPINFOHEADER pbmiHeader = NULL;
4936 LPBYTE pbits = NULL;
4938 /* Get a pointer to the packed DIB's data */
4939 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
4940 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
4941 pbmi = (LPBITMAPINFO)pPackedDIB;
4942 pbits = (LPBYTE)(pPackedDIB
4943 + X11DRV_DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
4945 /* Create a DDB from the DIB */
4947 hBmp = CreateDIBitmap(hdc,
4954 GlobalUnlock(hPackedDIB);
4956 TRACE("CreateDIBitmap returned %p\n", hBmp);
4958 /* Retrieve the internal Pixmap from the DDB */
4960 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4962 pixmap = (Pixmap)pBmp->physBitmap;
4963 /* clear the physBitmap so that we can steal its pixmap */
4964 pBmp->physBitmap = NULL;
4967 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4968 GDI_ReleaseObj( hBmp );
4971 TRACE("\tReturning Pixmap %ld\n", pixmap);