2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
13 # ifdef HAVE_SYS_SHM_H
16 # ifdef HAVE_SYS_IPC_H
19 #endif /* defined(HAVE_LIBXXSHM) */
26 #include "debugtools.h"
29 #include "selectors.h"
32 DEFAULT_DEBUG_CHANNEL(bitmap);
33 DECLARE_DEBUG_CHANNEL(x11drv);
35 static int ximageDepthTable[32];
38 static int XShmErrorFlag = 0;
41 /* This structure holds the arguments for DIB_SetImageBits() */
47 PALETTEENTRY *palentry;
68 } X11DRV_DIB_IMAGEBITS_DESCR;
71 /***********************************************************************
72 * X11DRV_DIB_GetXImageWidthBytes
74 * Return the width of an X image in bytes
76 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
78 if (!depth || depth > 32) goto error;
80 if (!ximageDepthTable[depth-1])
82 XImage *testimage = XCreateImage( gdi_display, visual, depth,
83 ZPixmap, 0, NULL, 1, 1, 32, 20 );
86 ximageDepthTable[depth-1] = testimage->bits_per_pixel;
87 XDestroyImage( testimage );
89 else ximageDepthTable[depth-1] = -1;
91 if (ximageDepthTable[depth-1] != -1)
92 return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
95 WARN( "(%d): Unsupported depth\n", depth );
100 /***********************************************************************
101 * X11DRV_DIB_CreateXImage
105 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
111 width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
112 image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
113 calloc( height, width_bytes ),
114 width, height, 32, width_bytes );
120 /***********************************************************************
121 * X11DRV_DIB_GenColorMap
123 * Fills the color map of a bitmap palette. Should not be called
124 * for a >8-bit deep bitmap.
126 int *X11DRV_DIB_GenColorMap( DC *dc, int *colorMapping,
127 WORD coloruse, WORD depth, BOOL quads,
128 const void *colorPtr, int start, int end )
132 if (coloruse == DIB_RGB_COLORS)
136 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
138 if (depth == 1) /* Monochrome */
139 for (i = start; i < end; i++, rgb++)
140 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
141 rgb->rgbBlue > 255*3/2);
143 for (i = start; i < end; i++, rgb++)
144 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbRed,
150 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
152 if (depth == 1) /* Monochrome */
153 for (i = start; i < end; i++, rgb++)
154 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
155 rgb->rgbtBlue > 255*3/2);
157 for (i = start; i < end; i++, rgb++)
158 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbtRed,
163 else /* DIB_PAL_COLORS */
166 WORD * index = (WORD *)colorPtr;
168 for (i = start; i < end; i++, index++)
169 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) );
171 for (i = start; i < end; i++)
172 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(i) );
179 /***********************************************************************
180 * X11DRV_DIB_BuildColorMap
182 * Build the color map from the bitmap palette. Should not be called
183 * for a >8-bit deep bitmap.
185 int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth,
186 const BITMAPINFO *info, int *nColors )
190 const void *colorPtr;
193 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
195 colors = info->bmiHeader.biClrUsed;
196 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
197 colorPtr = info->bmiColors;
199 else /* assume BITMAPCOREINFO */
201 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
202 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
207 ERR("called with >256 colors!\n");
211 /* just so CopyDIBSection doesn't have to create an identity palette */
212 if (coloruse == (WORD)-1) colorPtr = NULL;
214 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
215 colors * sizeof(int) )))
219 return X11DRV_DIB_GenColorMap( dc, colorMapping, coloruse, depth,
220 isInfo, colorPtr, 0, colors);
224 /***********************************************************************
225 * X11DRV_DIB_MapColor
227 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
231 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
234 for (color = 0; color < nPhysMap; color++)
235 if (physMap[color] == phys)
238 WARN("Strange color %08x\n", phys);
243 /*********************************************************************
244 * X11DRV_DIB_GetNearestIndex
246 * Helper for X11DRV_DIB_GetDIBits.
247 * Returns the nearest colour table index for a given RGB.
248 * Nearest is defined by minimizing the sum of the squares.
250 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
252 INT i, best = -1, diff, bestdiff = -1;
255 for(color = colormap, i = 0; i < numColors; color++, i++) {
256 diff = (r - color->rgbRed) * (r - color->rgbRed) +
257 (g - color->rgbGreen) * (g - color->rgbGreen) +
258 (b - color->rgbBlue) * (b - color->rgbBlue);
261 if(best == -1 || diff < bestdiff) {
269 /***********************************************************************
270 * X11DRV_DIB_SetImageBits_1_Line
272 * Handles a single line of 1 bit data.
274 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
275 XImage *bmpImage, int h, const BYTE *bits)
280 if((extra = (left & 7)) != 0) {
287 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
288 for (i = dstwidth/8, x = left; i > 0; i--)
291 XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
292 XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
293 XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
294 XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
295 XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
296 XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
297 XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
298 XPutPixel( bmpImage, x++, h, colors[pix & 1] );
303 case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
304 case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
305 case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
306 case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
307 case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
308 case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
309 case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
313 /***********************************************************************
314 * X11DRV_DIB_SetImageBits_1
316 * SetDIBits for a 1-bit deep DIB.
318 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
319 DWORD srcwidth, DWORD dstwidth, int left,
320 int *colors, XImage *bmpImage, DWORD linebytes)
325 for (h = lines-1; h >=0; h--) {
326 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
328 srcbits += linebytes;
332 for (h = 0; h < lines; h++) {
333 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
335 srcbits += linebytes;
340 /***********************************************************************
341 * X11DRV_DIB_GetImageBits_1
343 * GetDIBits for a 1-bit deep DIB.
345 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
346 DWORD dstwidth, DWORD srcwidth,
347 RGBQUAD *colors, PALETTEENTRY *srccolors,
348 XImage *bmpImage, DWORD linebytes )
356 dstbits = dstbits + linebytes * (lines - 1);
357 linebytes = -linebytes;
362 switch(bmpImage->depth) {
365 /* ==== monochrome bitmap to monochrome dib ==== */
367 /* ==== 4 colormap bitmap to monochrome dib ==== */
368 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
372 for (h = lines - 1; h >= 0; h--) {
373 for (x = 0; x < dstwidth; x++) {
374 val = srccolors[XGetPixel(bmpImage, x, h)];
375 if (!(x&7)) *bits = 0;
376 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2,
379 val.peBlue) << (7 - (x & 7)));
380 if ((x&7)==7) bits++;
382 bits = (dstbits += linebytes);
385 else goto notsupported;
390 /* ==== 8 colormap bitmap to monochrome dib ==== */
391 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
396 for( h = lines- 1; h >= 0; h-- ) {
397 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
398 for( x = 0; x < dstwidth; x++ ) {
399 if (!(x&7)) *bits = 0;
400 val = srccolors[(int)*srcpixel++];
401 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 2,
404 val.peBlue) << (7-(x&7)) );
405 if ((x&7)==7) bits++;
407 bits = (dstbits += linebytes);
410 else goto notsupported;
419 /* ==== 555 BGR bitmap to monochrome dib ==== */
420 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
422 for( h = lines - 1; h >= 0; h--) {
423 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
424 for( x = 0; x < dstwidth; x++) {
425 if (!(x&7)) *bits = 0;
427 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
428 ((val >> 7) & 0xf8) |
430 ((val >> 2) & 0xf8) |
432 ((val << 3) & 0xf8) |
433 ((val >> 2) & 0x7) ) << (7-(x&7)) );
434 if ((x&7)==7) bits++;
436 bits = (dstbits += linebytes);
439 /* ==== 555 RGB bitmap to monochrome dib ==== */
440 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
442 for( h = lines - 1; h >= 0; h--)
444 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
445 for( x = 0; x < dstwidth; x++) {
446 if (!(x&1)) *bits = 0;
448 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
449 ((val << 3) & 0xf8) |
451 ((val >> 2) & 0xf8) |
453 ((val >> 7) & 0xf8) |
454 ((val >> 12) & 0x7) ) << (7-(x&7)) );
455 if ((x&7)==7) bits++;
457 bits = (dstbits += linebytes);
460 else goto notsupported;
469 /* ==== 565 BGR bitmap to monochrome dib ==== */
470 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
472 for( h = lines - 1; h >= 0; h--)
474 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
475 for( x = 0; x < dstwidth; x++) {
476 if (!(x&7)) *bits = 0;
478 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
479 ((val >> 8) & 0xf8) |
481 ((val >> 3) & 0xfc) |
483 ((val << 3) & 0xf8) |
484 ((val >> 2) & 0x7) ) << (7-(x&7)) );
485 if ((x&7)==7) bits++;
487 bits = (dstbits += linebytes);
490 /* ==== 565 RGB bitmap to monochrome dib ==== */
491 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
493 for( h = lines - 1; h >= 0; h--)
495 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
496 for( x = 0; x < dstwidth; x++) {
497 if (!(x&7)) *bits = 0;
499 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
500 ((val << 3) & 0xf8) |
502 ((val >> 3) & 0xfc) |
504 ((val >> 8) & 0xf8) |
505 ((val >> 13) & 0x7) ) << (7-(x&7)) );
506 if ((x&7)==7) bits++;
508 bits = (dstbits += linebytes);
511 else goto notsupported;
520 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
521 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
523 for (h = lines - 1; h >= 0; h--)
525 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
526 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
527 if (!(x&7)) *bits = 0;
528 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[2] , srcpixel[1], srcpixel[0]) << (7-(x&7)) );
529 if ((x&7)==7) bits++;
531 bits = (dstbits += linebytes);
534 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
535 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
537 for (h = lines - 1; h >= 0; h--)
539 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
540 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
541 if (!(x & 7)) *bits = 0;
542 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[0] , srcpixel[1], srcpixel[2]) << (7-(x&7)) );
543 if ((x & 7) == 7) bits++;
545 bits = (dstbits += linebytes);
548 else goto notsupported;
552 default: /* ? bit bmp -> monochrome DIB */
555 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
557 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
558 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
559 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
561 for( h = lines - 1; h >= 0; h-- ) {
562 for( x = 0; x < dstwidth; x++ ) {
563 if (!(x&7)) *bits = 0;
564 *bits |= (XGetPixel( bmpImage, x, h) >= white)
566 if ((x&7)==7) bits++;
568 bits = (dstbits += linebytes);
575 /***********************************************************************
576 * X11DRV_DIB_SetImageBits_4
578 * SetDIBits for a 4-bit deep DIB.
580 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
581 DWORD srcwidth, DWORD dstwidth, int left,
582 int *colors, XImage *bmpImage, DWORD linebytes)
586 const BYTE *bits = srcbits + (left >> 1);
594 for (h = lines-1; h >= 0; h--) {
595 for (i = dstwidth/2, x = left; i > 0; i--) {
597 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
598 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
600 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
601 srcbits += linebytes;
602 bits = srcbits + (left >> 1);
606 for (h = 0; h < lines; h++) {
607 for (i = dstwidth/2, x = left; i > 0; i--) {
609 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
610 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
612 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
613 srcbits += linebytes;
614 bits = srcbits + (left >> 1);
621 /***********************************************************************
622 * X11DRV_DIB_GetImageBits_4
624 * GetDIBits for a 4-bit deep DIB.
626 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
627 DWORD srcwidth, DWORD dstwidth,
628 RGBQUAD *colors, PALETTEENTRY *srccolors,
629 XImage *bmpImage, DWORD linebytes )
639 dstbits = dstbits + ( linebytes * (lines-1) );
640 linebytes = -linebytes;
645 switch(bmpImage->depth) {
648 /* ==== monochrome bitmap to 4 colormap dib ==== */
650 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
651 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
655 for (h = lines-1; h >= 0; h--) {
656 for (x = 0; x < dstwidth; x++) {
657 if (!(x&1)) *bits = 0;
658 val = srccolors[XGetPixel(bmpImage, x, h)];
659 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 16,
662 val.peBlue) << (4-((x&1)<<2)));
663 if ((x&1)==1) bits++;
665 bits = (dstbits += linebytes);
668 else goto notsupported;
673 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
674 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
678 for( h = lines - 1; h >= 0; h-- ) {
679 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
680 for( x = 0; x < dstwidth; x++ ) {
681 if (!(x&1)) *bits = 0;
682 val = srccolors[(int)*srcpixel++];
683 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 16,
686 val.peBlue) << (4*(1-(x&1))) );
687 if ((x&1)==1) bits++;
689 bits = (dstbits += linebytes);
692 else goto notsupported;
701 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
702 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
704 for( h = lines - 1; h >= 0; h--) {
705 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
706 for( x = 0; x < dstwidth; x++) {
707 if (!(x&1)) *bits = 0;
709 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
710 ((val >> 7) & 0xf8) |
712 ((val >> 2) & 0xf8) |
714 ((val << 3) & 0xf8) |
715 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
716 if ((x&1)==1) bits++;
718 bits = (dstbits += linebytes);
721 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
722 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
724 for( h = lines - 1; h >= 0; h--)
726 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
727 for( x = 0; x < dstwidth; x++) {
728 if (!(x&1)) *bits = 0;
730 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
731 ((val << 3) & 0xf8) |
733 ((val >> 2) & 0xfc) |
735 ((val >> 7) & 0xf8) |
736 ((val >> 12) & 0x7) ) << ((1-(x&1))<<2) );
737 if ((x&1)==1) bits++;
739 bits = (dstbits += linebytes);
742 else goto notsupported;
751 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
752 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
754 for( h = lines - 1; h >= 0; h--)
756 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
757 for( x = 0; x < dstwidth; x++) {
758 if (!(x&1)) *bits = 0;
760 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
761 ((val >> 8) & 0xf8) |
763 ((val >> 3) & 0xfc) |
765 ((val << 3) & 0xf8) |
766 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
767 if ((x&1)==1) bits++;
769 bits = (dstbits += linebytes);
772 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
773 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
775 for( h = lines - 1; h >= 0; h--)
777 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
778 for( x = 0; x < dstwidth; x++) {
779 if (!(x&1)) *bits = 0;
781 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
782 ((val << 3) & 0xf8) |
784 ((val >> 3) & 0xfc) |
786 ((val >> 8) & 0xf8) |
787 ((val >> 13) & 0x7) ) << ((1-(x&1))<<2) );
788 if ((x&1)==1) bits++;
790 bits = (dstbits += linebytes);
793 else goto notsupported;
802 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
803 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
805 for (h = lines - 1; h >= 0; h--)
807 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
808 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
809 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[2] , srcpixel[1], srcpixel[0]) << 4) |
810 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[6] , srcpixel[5], srcpixel[4]);
811 bits = (dstbits += linebytes);
814 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
815 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
817 for (h = lines - 1; h >= 0; h--)
819 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
820 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
821 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[0] , srcpixel[1], srcpixel[2]) << 4) |
822 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[4] , srcpixel[5], srcpixel[6]);
823 bits = (dstbits += linebytes);
826 else goto notsupported;
830 default: /* ? bit bmp -> 4 bit DIB */
832 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
833 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
834 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
835 for (h = lines-1; h >= 0; h--) {
836 for (x = 0; x < dstwidth-1; x += 2)
838 *bits++ = (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x, h ), 0) << 4)
839 | (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x+1, h ), 0) & 0x0f);
842 *bits = (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x, h ), 0) << 4);
843 bits = (dstbits += linebytes);
849 /***********************************************************************
850 * X11DRV_DIB_SetImageBits_RLE4
852 * SetDIBits for a 4-bit deep compressed DIB.
854 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
855 DWORD width, DWORD dstwidth,
856 int left, int *colors,
859 int x = 0, c, length;
860 const BYTE *begin = bits;
864 while ((int)lines >= 0) {
866 if (length) { /* encoded */
874 XPutPixel(bmpImage, x++, lines, colors[c >>4]);
882 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
893 case 1: /* eopicture */
899 FIXME_(x11drv)("x-delta is too large?\n");
905 default: /* absolute */
913 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
921 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
924 if ((bits - begin) & 1)
933 /***********************************************************************
934 * X11DRV_DIB_SetImageBits_8
936 * SetDIBits for an 8-bit deep DIB.
938 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
939 DWORD srcwidth, DWORD dstwidth, int left,
940 const int *colors, XImage *bmpImage,
952 srcbits = srcbits + ( linebytes * (lines-1) );
953 linebytes = -linebytes;
956 bits = srcbits + left;
958 switch (bmpImage->depth) {
961 #if defined(__i386__) && defined(__GNUC__)
962 /* Some X servers might have 32 bit/ 16bit deep pixel */
963 if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 16))
965 for (h = lines ; h--; ) {
966 int _cl1,_cl2; /* temp outputs for asm below */
967 /* Borrowed from DirectDraw */
968 __asm__ __volatile__(
973 " movw (%%edx,%%eax,4),%%ax\n"
977 :"=S" (bits), "=D" (_cl1), "=c" (_cl2)
979 "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*2),
982 :"eax", "cc", "memory"
984 bits = (srcbits += linebytes) + left;
991 #if defined(__i386__) && defined(__GNUC__)
992 if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 32))
994 for (h = lines ; h--; ) {
995 int _cl1,_cl2; /* temp outputs for asm below */
996 /* Borrowed from DirectDraw */
997 __asm__ __volatile__(
1002 " movl (%%edx,%%eax,4),%%eax\n"
1004 " xor %%eax,%%eax\n"
1006 :"=S" (bits), "=D" (_cl1), "=c" (_cl2)
1008 "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*4),
1009 "c" (dstwidth-left),
1011 :"eax", "cc", "memory"
1013 bits = (srcbits += linebytes) + left;
1020 break; /* use slow generic case below */
1023 for (h = lines - 1; h >= 0; h--) {
1024 for (x = left; x < dstwidth; x++, bits++) {
1025 color = colors[*bits];
1026 XPutPixel( bmpImage, x, h, colors[*bits] );
1028 bits = (srcbits += linebytes) + left;
1032 /***********************************************************************
1033 * X11DRV_DIB_GetImageBits_8
1035 * GetDIBits for an 8-bit deep DIB.
1037 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
1038 DWORD srcwidth, DWORD dstwidth,
1039 RGBQUAD *colors, PALETTEENTRY *srccolors,
1040 XImage *bmpImage, DWORD linebytes )
1049 dstbits = dstbits + ( linebytes * (lines-1) );
1050 linebytes = -linebytes;
1057 This condition is true when GetImageBits has been called by UpdateDIBSection.
1058 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
1059 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
1061 if (!srccolors) goto updatesection;
1063 switch(bmpImage->depth) {
1066 /* ==== monochrome bitmap to 8 colormap dib ==== */
1068 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
1069 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1073 for (h = lines - 1; h >= 0; h--) {
1074 for (x = 0; x < dstwidth; x++) {
1075 val = srccolors[XGetPixel(bmpImage, x, h)];
1076 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1077 val.peGreen, val.peBlue);
1079 bits = (dstbits += linebytes);
1082 else goto notsupported;
1087 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
1088 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1093 for (h = lines - 1; h >= 0; h--) {
1094 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1095 for (x = 0; x < dstwidth; x++) {
1096 val = srccolors[(int)*srcpixel++];
1097 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1098 val.peGreen, val.peBlue);
1100 bits = (dstbits += linebytes);
1103 else goto notsupported;
1112 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1113 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
1115 for( h = lines - 1; h >= 0; h--)
1117 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1118 for( x = 0; x < dstwidth; x++ )
1121 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1122 ((val >> 7) & 0xf8) |
1123 ((val >> 12) & 0x7),
1124 ((val >> 2) & 0xf8) |
1126 ((val << 3) & 0xf8) |
1127 ((val >> 2) & 0x7) );
1129 bits = (dstbits += linebytes);
1132 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1133 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
1135 for( h = lines - 1; h >= 0; h--)
1137 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1138 for( x = 0; x < dstwidth; x++ )
1141 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1142 ((val << 3) & 0xf8) |
1144 ((val >> 2) & 0xf8) |
1146 ((val >> 7) & 0xf8) |
1147 ((val >> 12) & 0x7) );
1149 bits = (dstbits += linebytes);
1152 else goto notsupported;
1161 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1162 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
1164 for( h = lines - 1; h >= 0; h--)
1166 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1167 for( x = 0; x < dstwidth; x++ )
1170 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1171 ((val >> 8) & 0xf8) |
1172 ((val >> 13) & 0x7),
1173 ((val >> 3) & 0xfc) |
1175 ((val << 3) & 0xf8) |
1176 ((val >> 2) & 0x7) );
1178 bits = (dstbits += linebytes);
1181 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1182 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
1184 for( h = lines - 1; h >= 0; h--)
1186 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1187 for( x = 0; x < dstwidth; x++ )
1190 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1191 ((val << 3) & 0xf8) |
1193 ((val >> 3) & 0x00fc) |
1195 ((val >> 8) & 0x00f8) |
1196 ((val >> 13) & 0x7) );
1198 bits = (dstbits += linebytes);
1201 else goto notsupported;
1210 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1211 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1213 for (h = lines - 1; h >= 0; h--)
1215 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1216 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1217 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1218 srcpixel[2] , srcpixel[1], *srcpixel);
1219 bits = (dstbits += linebytes);
1222 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1223 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1225 for (h = lines - 1; h >= 0; h--)
1227 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1228 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1229 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1230 *srcpixel, srcpixel[1], srcpixel[2]);
1231 bits = (dstbits += linebytes);
1235 else goto notsupported;
1239 default: /* ? bit bmp -> 8 bit DIB */
1241 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1242 bmpImage->depth, (int)bmpImage->red_mask,
1243 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1245 for (h = lines - 1; h >= 0; h--) {
1246 for (x = 0; x < dstwidth; x++, bits++) {
1247 *bits = X11DRV_DIB_MapColor((int *)colors, 256,
1248 XGetPixel( bmpImage, x, h ), *bits);
1250 bits = (dstbits += linebytes);
1256 /***********************************************************************
1257 * X11DRV_DIB_SetImageBits_RLE8
1259 * SetDIBits for an 8-bit deep compressed DIB.
1261 * This function rewritten 941113 by James Youngman. WINE blew out when I
1262 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1264 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1265 * 'End of bitmap' escape code. This code is very much laxer in what it
1266 * allows to end the expansion. Possibly too lax. See the note by
1267 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1268 * bitmap should end with RleEnd, but on the other hand, software exists
1269 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1272 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1273 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1277 enum Rle8_EscapeCodes
1280 * Apologies for polluting your file's namespace...
1282 RleEol = 0, /* End of line */
1283 RleEnd = 1, /* End of bitmap */
1284 RleDelta = 2 /* Delta */
1287 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1288 DWORD width, DWORD dstwidth,
1289 int left, int *colors,
1292 int x; /* X-positon on each line. Increases. */
1293 int line; /* Line #. Starts at lines-1, decreases */
1294 const BYTE *pIn = bits; /* Pointer to current position in bits */
1295 BYTE length; /* The length pf a run */
1296 BYTE color_index; /* index into colors[] as read from bits */
1297 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
1298 int color; /* value of colour[color_index] */
1300 if (lines == 0) /* Let's hope this doesn't happen. */
1304 * Note that the bitmap data is stored by Windows starting at the
1305 * bottom line of the bitmap and going upwards. Within each line,
1306 * the data is stored left-to-right. That's the reason why line
1307 * goes from lines-1 to 0. [JAY]
1317 * If the length byte is not zero (which is the escape value),
1318 * We have a run of length pixels all the same colour. The colour
1319 * index is stored next.
1321 * If the length byte is zero, we need to read the next byte to
1322 * know what to do. [JAY]
1327 * [Run-Length] Encoded mode
1329 color_index = (*pIn++); /* Get the colour index. */
1330 color = colors[color_index];
1339 XPutPixel(bmpImage, x++, line, color);
1345 * Escape codes (may be an absolute sequence though)
1347 escape_code = (*pIn++);
1350 case RleEol: /* =0, end of line */
1357 case RleEnd: /* =1, end of bitmap */
1360 * Not all RLE8 bitmaps end with this
1361 * code. For example, Paint Shop Pro
1362 * produces some that don't. That's (I think)
1363 * what caused the previous implementation to
1366 line=-1; /* Cause exit from do loop. */
1370 case RleDelta: /* =2, a delta */
1373 * Note that deltaing to line 0
1374 * will cause an exit from the loop,
1375 * which may not be what is intended.
1376 * The fact that there is a delta in the bits
1377 * almost certainly implies that there is data
1378 * to follow. You may feel that we should
1379 * jump to the top of the loop to avoid exiting
1382 * TODO: Decide what to do here in that case. [JAY]
1388 TRACE("Delta to last line of bitmap "
1389 "(wrongly?) causes loop exit\n");
1394 default: /* >2, switch to absolute mode */
1399 length = escape_code;
1402 color_index = (*pIn++);
1408 XPutPixel(bmpImage, x++, line,
1409 colors[color_index]);
1413 * If you think for a moment you'll realise that the
1414 * only time we could ever possibly read an odd
1415 * number of bytes is when there is a 0x00 (escape),
1416 * a value >0x02 (absolute mode) and then an odd-
1417 * length run. Therefore this is the only place we
1418 * need to worry about it. Everywhere else the
1419 * bytes are always read in pairs. [JAY]
1421 if (escape_code & 1)
1422 pIn++; /* Throw away the pad byte. */
1425 } /* switch (escape_code) : Escape sequence */
1426 } /* process either an encoded sequence or an escape sequence */
1428 /* We expect to come here more than once per line. */
1429 } while (line >= 0); /* Do this until the bitmap is filled */
1432 * Everybody comes here at the end.
1433 * Check how we exited the loop and print a message if it's a bit odd.
1436 if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
1438 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1439 "bytes were: %02X %02X.\n", (int)*(pIn-2),(int)*(pIn-1));
1444 /***********************************************************************
1445 * X11DRV_DIB_SetImageBits_16
1447 * SetDIBits for a 16-bit deep DIB.
1449 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1450 DWORD srcwidth, DWORD dstwidth, int left,
1451 DC *dc, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1452 XImage *bmpImage, DWORD linebytes )
1460 srcbits = srcbits + ( linebytes * (lines-1));
1461 linebytes = -linebytes;
1464 switch ( bmpImage->depth )
1467 /* using same format as XImage */
1468 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1469 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1470 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1471 else /* We need to do a conversion from a 565 dib */
1473 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1475 int div = dstwidth % 2;
1477 for (h = lines - 1; h >= 0; h--) {
1478 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1479 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1481 *dstpixel++ = ((val >> 1) & 0x7fe07fe0) | (val & 0x001f001f); /* Red & Green & Blue */
1483 if (div != 0) /* Odd width? */
1484 *dstpixel = ((*(WORD *)ptr >> 1) & 0x7fe0) | (*(WORD *)ptr & 0x001f);
1485 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1491 /* using same format as XImage */
1492 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1493 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1494 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1495 else /* We need to do a conversion from a 555 dib */
1497 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1499 int div = dstwidth % 2;
1501 for (h = lines - 1; h >= 0; h--) {
1502 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1503 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1505 *dstpixel++ = ((val << 1) & 0xffc0ffc0) | ((val >> 4) & 0x00200020) | /* Red & Green */
1506 (val & 0x001f001f); /* Blue */
1508 if (div != 0) /* Odd width? */
1509 *dstpixel = ((*(WORD *)ptr << 1) & 0xffc0) | ((*(WORD *)ptr >> 4) & 0x0020)
1510 | (*(WORD *)ptr & 0x001f);
1511 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1520 LPWORD ptr = (LPWORD)srcbits + left;
1523 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1525 if ((rSrc == 0xF800) && (gSrc == 0x07E0) && (bSrc == 0x001F)) {
1526 /* ==== 555 RGB dib to 24/32 RGB bitmap ==== */
1527 for (h = lines - 1; h >= 0; h--) {
1528 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1529 for (x = 0; x < dstwidth; x++) {
1531 *dstpixel++ = ((val << 8) & 0xF80000) | /* Red */
1532 ((val << 5) & 0x00FC00) | /* Green */
1533 ((val << 3) & 0x0000FF); /* Blue */
1535 ptr = (LPWORD)(srcbits += linebytes) + left;
1538 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1539 for (h = lines - 1; h >= 0; h--) {
1540 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1541 for (x = 0; x < dstwidth; x++) {
1544 *dstpixel++ = ((val << 9) & 0xf80000) | ((val << 4) & 0x070000) | /* Red */
1545 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1546 ((val << 3) & 0x0000f8) | ((val >> 2) & 0x000007); /* Blue */
1548 ptr = (LPWORD)(srcbits += linebytes) + left;
1552 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1553 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1555 for (h = lines - 1; h >= 0; h--) {
1556 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1557 for (x = 0; x < dstwidth; x++) {
1560 *dstpixel++ = ((val >> 7) & 0x0000f8) | ((val >> 12) & 0x000007) | /* Red */
1561 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1562 ((val << 19) & 0xf80000) | ((val >> 14) & 0x070000); /* Blue */
1564 ptr = (LPWORD)(srcbits += linebytes) + left;
1575 LPWORD ptr = (LPWORD)srcbits + left;
1579 /* Set color scaling values */
1580 if ( rSrc == 0x7c00 ) { sc1 = 7; sc2 = 2; } /* 555 dib */
1581 else { sc1 = 8; sc2 = 3; } /* 565 dib */
1583 for (h = lines - 1; h >= 0; h--) {
1584 for (x = left; x < dstwidth+left; x++) {
1586 XPutPixel( bmpImage, x, h,
1587 X11DRV_PALETTE_ToPhysical(dc, RGB(((val & rSrc) >> sc1), /* Red */
1588 ((val & gSrc) >> sc2), /* Green */
1589 ((val & bSrc) << 3)))); /* Blue */
1591 ptr = (LPWORD) (srcbits += linebytes) + left;
1597 FIXME("16 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
1604 /***********************************************************************
1605 * X11DRV_DIB_GetImageBits_16
1607 * GetDIBits for an 16-bit deep DIB.
1609 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
1610 DWORD dstwidth, DWORD srcwidth,
1611 PALETTEENTRY *srccolors,
1612 DWORD rDst, DWORD gDst, DWORD bDst,
1613 XImage *bmpImage, DWORD dibpitch )
1618 DWORD linebytes = dibpitch;
1623 dstbits = dstbits + ( linebytes * (lines-1));
1624 linebytes = -linebytes;
1627 /* Set color scaling values */
1628 if ( rDst == 0x7c00 ) { rsc = 7; gsc = 2; } /* 555 dib */
1629 else { rsc = 8; gsc = 3; } /* 565 dib */
1631 switch ( bmpImage->depth )
1634 /* using same format as XImage */
1635 if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1636 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1637 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1638 /* reversed format (BGR <=> RGB) */
1639 else if (rDst == bmpImage->blue_mask && bDst == bmpImage->red_mask)
1641 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1643 int div = srcwidth % 2;
1645 for (h = lines - 1; h >= 0; h--) {
1646 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1647 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1649 *ptr++ = ((val << 10) & 0xf800f800) | (val & 0x03e003e0) | /* Red & Green */
1650 ((val >> 10) & 0x001f001f); /* Blue */
1652 if (div != 0) /* Odd width? */
1653 *ptr = ((*(WORD *)srcpixel << 1) & 0xffc0) | ((*(WORD *)srcpixel >> 4) & 0x0020) |
1654 (*(WORD *)srcpixel & 0x001f);
1655 ptr = (LPDWORD)(dstbits += linebytes);
1658 else goto notsupported;
1664 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1666 int div = srcwidth % 2;
1668 /* using same format as XImage */
1669 if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1670 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1671 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1672 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1673 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f &&
1674 rDst == 0x7c00 && bDst == 0x001f)
1676 for (h = lines - 1; h >= 0; h--) {
1677 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1678 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1680 *ptr++ = ((val >> 1) & 0x7fe07fe0) | /* Red & Green */
1681 (val & 0x001f001f); /* Blue */
1683 if (div != 0) /* Odd width? */
1684 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1685 ptr = (LPDWORD) (dstbits += linebytes);
1688 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1689 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800 &&
1690 rDst == 0x7c00 && bDst == 0x001f)
1692 for (h = lines - 1; h >= 0; h--) {
1693 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1694 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1696 *ptr++ = ((val << 10) & 0x7c007c00) | ((val >> 1) & 0x03e003e0) | /* Red & Green */
1697 ((val >> 11) & 0x001f001f); /* Blue */
1699 if (div != 0) /* Odd width? */
1700 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1701 ptr = (LPDWORD) (dstbits += linebytes);
1704 else goto notsupported;
1712 LPWORD ptr = (LPWORD)dstbits;
1715 /* ==== 24/32 BGR bitmap ==== */
1716 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1718 int rsc2 = 16-rsc, gsc2 = 8-gsc;
1719 for (h = lines - 1; h >= 0; h--) {
1720 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1721 for (x = 0; x < srcwidth; x++, ptr++) {
1723 *ptr = ((val >> rsc2) & rDst) |
1724 ((val >> gsc2) & gDst) |
1725 ((val >> 3) & bDst);
1727 ptr = (LPWORD)(dstbits += linebytes);
1730 /* ==== 24/32 RGB bitmap ==== */
1731 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1734 for (h = lines - 1; h >= 0; h--) {
1735 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1736 for (x = 0; x < srcwidth; x++, ptr++) {
1738 *ptr = ((val << rsc) & rDst) |
1739 ((val >> gsc2) & gDst) |
1740 ((val >> 19) & bDst);
1742 ptr = (LPWORD) (dstbits += linebytes);
1745 else goto notsupported;
1750 /* ==== monochrome bitmap ==== */
1752 /* ==== 4 colormap bitmap ==== */
1753 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1755 LPWORD ptr = (LPWORD)dstbits;
1758 for (h = lines - 1; h >= 0; h--) {
1759 for (x = 0; x < dstwidth; x++) {
1760 val = srccolors[XGetPixel(bmpImage, x, h)];
1761 *ptr++ = ((val.peRed << rsc) & rDst) |
1762 ((val.peGreen << gsc) & gDst) |
1763 ((val.peBlue >> 3) & bDst);
1765 ptr = (LPWORD)(dstbits += linebytes);
1768 else goto notsupported;
1773 /* ==== 8 colormap bitmap ==== */
1774 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1776 LPWORD ptr = (LPWORD)dstbits;
1780 for (h = lines - 1; h >= 0; h--) {
1781 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1782 for (x = 0; x < dstwidth; x++) {
1783 val = srccolors[(int)*srcpixel++];
1784 *ptr++ = ((val.peRed << rsc) & rDst) |
1785 ((val.peGreen << gsc) & gDst) |
1786 ((val.peBlue >> 3) & bDst);
1788 ptr = (LPWORD)(dstbits += linebytes);
1791 else goto notsupported;
1799 LPWORD ptr = (LPWORD)dstbits;
1801 FIXME("from %d bit bitmap with mask R,G,B %lx,%lx,%lx to 16 bit DIB %lx,%lx,%lx\n",
1802 bmpImage->depth, bmpImage->red_mask,
1803 bmpImage->green_mask, bmpImage->blue_mask,
1806 for (h = lines - 1; h >= 0; h--)
1808 for (x = 0; x < dstwidth; x++, ptr++)
1810 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
1811 r = (BYTE) GetRValue(pixel);
1812 g = (BYTE) GetGValue(pixel);
1813 b = (BYTE) GetBValue(pixel);
1814 *ptr = ( ((r << rsc) & rDst) | ((g << gsc) & gDst) | ((b >> 3) & bDst) );
1816 ptr = (LPWORD) (dstbits += linebytes);
1824 /***********************************************************************
1825 * X11DRV_DIB_SetImageBits_24
1827 * SetDIBits for a 24-bit deep DIB.
1829 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
1830 DWORD srcwidth, DWORD dstwidth, int left,
1831 DC *dc, XImage *bmpImage, DWORD linebytes )
1839 srcbits = srcbits + linebytes * (lines - 1);
1840 linebytes = -linebytes;
1843 switch ( bmpImage->depth )
1847 if (bmpImage->bits_per_pixel == 24) {
1848 int dstlinebytes = linebytes;
1850 BYTE *ptr = (BYTE *)(srcbits+left*3);
1852 if (dstlinebytes < 0 ) dstlinebytes = -dstlinebytes;
1853 dstpixel = bmpImage->data + lines*dstlinebytes + left*3;
1854 for(h = lines ; h-- ; ) {
1855 dstpixel-=dstlinebytes;
1856 memcpy(dstpixel,ptr,dstwidth*3);
1864 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 ) /* packed BGR to unpacked BGR */
1866 DWORD *dstpixel, val, buf;
1867 DWORD *ptr = (DWORD *)(srcbits + left*3);
1869 int div = dstwidth % 4;
1872 for(h = lines - 1; h >= 0; h--)
1874 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1876 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1878 *dstpixel++ = buf&0x00ffffff; /* b1, g1, r1 */
1879 val = (buf >> 24); /* b2 */
1881 *dstpixel++ = (val | (buf<<8)) &0x00ffffff; /* g2, r2 */
1882 val = (buf >> 16); /* b3, g3 */
1884 *dstpixel++ = (val | (buf<<16)) &0x00ffffff; /* r3 */
1885 *dstpixel++ = (buf >> 8); /* b4, g4, r4 */
1887 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1889 *dstpixel++ = *(DWORD*)bits & 0x00ffffff; /* b, g, r */
1891 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1894 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff ) /* packed BGR to unpacked RGB */
1896 DWORD *dstpixel, val, buf;
1897 DWORD *ptr = (DWORD *)(srcbits + left*3);
1899 int div = dstwidth % 4;
1902 for(h = lines - 1; h >= 0; h--)
1904 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1906 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1908 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b1, g1, r1 */
1909 val = ((buf&0xff000000)>>8); /* b2 */
1911 *dstpixel++ = val | ((buf&0xff)<<8) | ((buf&0xff00)>>8); /* g2, r2 */
1912 val = (buf&0xff0000) | ((buf&0xff000000)>>16); /* b3, g3 */
1914 *dstpixel++ = val | (buf&0xff); /* r3 */
1915 *dstpixel++ = ((buf&0xff00)<<8) | ((buf&0xff0000)>>8) | (buf>>24); /* b4, g4, r4 */
1917 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1919 buf = *(DWORD*)bits;
1920 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b, g, r */
1922 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1932 if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f ) /* BGR888 to RGB555 */
1934 DWORD *ptr = (DWORD *)(srcbits + left*3);
1937 int div = dstwidth % 4;
1940 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1941 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1942 for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1943 *dstpixel++ = ((ptr[0] << 7) & 0x7c00) | ((ptr[0] >> 6) & 0x03e0) | ((ptr[0] >> 19) & 0x1f);
1944 *dstpixel++ = ((ptr[0] >> 17) & 0x7c00) | ((ptr[1] << 2) & 0x03e0) | ((ptr[1] >> 11) & 0x1f);
1945 *dstpixel++ = ((ptr[1] >> 9) & 0x07c00) | ((ptr[1] >> 22) & 0x03e0) | ((ptr[2] >> 3) & 0x1f);
1946 *dstpixel++ = ((ptr[2] >> 1) & 0x07c00) | ((ptr[2] >> 14) & 0x03e0) | ((ptr[2] >> 27) & 0x1f);
1948 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1949 *dstpixel++ = (((WORD)bits[0] << 7) & 0x07c00) |
1950 (((WORD)bits[1] << 2) & 0x03e0) |
1951 (((WORD)bits[2] >> 3) & 0x001f);
1952 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1955 else if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 ) /* BGR888 to BGR555 */
1957 DWORD *ptr = (DWORD *)(srcbits + left*3);
1960 int div = dstwidth % 4;
1963 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1964 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1965 for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1966 *dstpixel++ = ((ptr[0] >> 3) & 0x1f) | ((ptr[0] >> 6) & 0x03e0) | ((ptr[0] >> 9) & 0x7c00);
1967 *dstpixel++ = ((ptr[0] >> 27) & 0x1f) | ((ptr[1] << 2) & 0x03e0) | ((ptr[1] >> 1) & 0x7c00);
1968 *dstpixel++ = ((ptr[1] >> 19) & 0x1f) | ((ptr[1] >> 22) & 0x03e0) | ((ptr[2] << 7) & 0x7c00);
1969 *dstpixel++ = ((ptr[2] >> 11) & 0x1f) | ((ptr[2] >> 14) & 0x03e0) | ((ptr[2] >> 17) & 0x7c00);
1971 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1972 *dstpixel++ = (((WORD)bits[2] << 7) & 0x07c00) |
1973 (((WORD)bits[1] << 2) & 0x03e0) |
1974 (((WORD)bits[0] >> 3) & 0x001f);
1975 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1985 DWORD *ptr = (DWORD *)(srcbits + left*3);
1988 int div = dstwidth % 4;
1991 if( bmpImage->blue_mask == 0x001f && bmpImage->red_mask == 0xf800 ) /* BGR888 to BGR565 */
1993 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1994 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1995 for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1996 *dstpixel++ = ((ptr[0] >> 3) & 0x1f) | ((ptr[0] >> 5) & 0x07e0) | ((ptr[0] >> 8) & 0xf800);
1997 *dstpixel++ = ((ptr[0] >> 27) & 0x1f) | ((ptr[1] << 3) & 0x07e0) | (ptr[1] & 0xf800);
1998 *dstpixel++ = ((ptr[1] >> 19) & 0x1f) | ((ptr[1] >> 21) & 0x07e0) | ((ptr[2] << 8) & 0xf800);
1999 *dstpixel++ = ((ptr[2] >> 11) & 0x1f) | ((ptr[2] >> 13) & 0x07e0) | ((ptr[2] >> 16) & 0xf800);
2001 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
2002 *dstpixel++ = (((WORD)bits[2] << 8) & 0xf800) |
2003 (((WORD)bits[1] << 3) & 0x07e0) |
2004 (((WORD)bits[0] >> 3) & 0x001f);
2005 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
2008 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x001f ) /* BGR888 to RGB565 */
2010 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
2011 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
2012 for (x = 0; x < dstwidth/4; x++, ptr += 3) {
2013 *dstpixel++ = ((ptr[0] << 8) & 0xf800) | ((ptr[0] >> 5) & 0x07e0) | ((ptr[0] >> 19) & 0x1f);
2014 *dstpixel++ = ((ptr[0] >> 16) & 0xf800) | ((ptr[1] << 3) & 0x07e0) | ((ptr[1] >> 11) & 0x1f);
2015 *dstpixel++ = ((ptr[1] >> 8) & 0xf800) | ((ptr[1] >> 21) & 0x07e0) | ((ptr[2] >> 3) & 0x1f);
2016 *dstpixel++ = (ptr[2] & 0xf800) | ((ptr[2] >> 13) & 0x07e0) | ((ptr[2] >> 27) & 0x1f);
2018 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
2019 *dstpixel++ = (((WORD)bits[0] << 8) & 0xf800) |
2020 (((WORD)bits[1] << 3) & 0x07e0) |
2021 (((WORD)bits[2] >> 3) & 0x001f);
2022 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
2034 LPBYTE bits = (LPBYTE)srcbits + left*3;
2036 for (h = lines - 1; h >= 0; h--) {
2037 for (x = left; x < dstwidth+left; x++, bits+=3)
2038 XPutPixel( bmpImage, x, h,
2039 X11DRV_PALETTE_ToPhysical(dc, RGB(bits[2], bits[1], bits[0])));
2040 bits = (LPBYTE)(srcbits += linebytes) + left * 3;
2047 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
2048 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
2049 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2055 /***********************************************************************
2056 * X11DRV_DIB_GetImageBits_24
2058 * GetDIBits for an 24-bit deep DIB.
2060 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
2061 DWORD dstwidth, DWORD srcwidth,
2062 PALETTEENTRY *srccolors,
2063 XImage *bmpImage, DWORD linebytes )
2071 dstbits = dstbits + ( linebytes * (lines-1) );
2072 linebytes = -linebytes;
2075 switch ( bmpImage->depth )
2079 if (bmpImage->bits_per_pixel == 24) {
2080 int tocopy = linebytes;
2082 BYTE *ptr = (LPBYTE)dstbits;
2084 if (tocopy < 0 ) tocopy = -tocopy;
2085 srcpixel = bmpImage->data + lines*tocopy;
2086 for(h = lines ; h-- ; ) {
2088 memcpy(ptr,srcpixel,tocopy);
2089 ptr = (LPBYTE)(dstbits+=linebytes);
2096 DWORD *srcpixel, buf;
2098 DWORD *ptr=(DWORD *)dstbits;
2099 int quotient = dstwidth / 4;
2100 int remainder = dstwidth % 4;
2103 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
2104 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 )
2106 for(h = lines - 1; h >= 0; h--)
2108 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2110 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
2111 buf = ((*srcpixel++)&0x00ffffff); /* b1, g1, r1*/
2112 *ptr++ = buf | ((*srcpixel)<<24); /* b2 */
2113 buf = ((*srcpixel++>>8)&0x0000ffff); /* g2, r2 */
2114 *ptr++ = buf | ((*srcpixel)<<16); /* b3, g3 */
2115 buf = ((*srcpixel++>>16)&0x000000ff); /* r3 */
2116 *ptr++ = buf | ((*srcpixel++)<<8); /* b4, g4, r4 */
2118 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2121 *(WORD*)bits = buf; /* b, g */
2122 *(bits+2) = buf>>16; /* r */
2124 ptr = (DWORD*)(dstbits+=linebytes);
2128 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
2129 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff )
2131 for(h = lines - 1; h >= 0; h--)
2133 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2135 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
2137 val = ((buf&0xff0000)>>16) | (buf&0xff00) | ((buf&0xff)<<16); /* b1, g1, r1 */
2139 *ptr++ = val | ((buf&0xff0000)<<8); /* b2 */
2140 val = ((buf&0xff00)>>8) | ((buf&0xff)<<8); /* g2, r2 */
2142 *ptr++ = val | (buf&0xff0000) | ((buf&0xff00)<<16); /* b3, g3 */
2143 val = (buf&0xff); /* r3 */
2145 *ptr++ = val | ((buf&0xff0000)>>8) | ((buf&0xff00)<<8) | (buf<<24); /* b4, g4, r4 */
2147 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2150 *(WORD*)bits = (buf&0xff00) | ((buf&0xff0000)>>16) ; /* b, g */
2151 *(bits+2) = buf; /* r */
2153 ptr = (DWORD*)(dstbits+=linebytes);
2156 else goto notsupported;
2163 LPBYTE bits = dstbits;
2166 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2167 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 )
2169 for (h = lines - 1; h >= 0; h--) {
2170 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2171 for (x = 0; x < srcwidth; x++, bits += 3) {
2173 bits[2] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2174 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2175 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2177 bits = (dstbits += linebytes);
2180 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2181 else if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f )
2183 for (h = lines - 1; h >= 0; h--) {
2184 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2185 for (x = 0; x < srcwidth; x++, bits += 3) {
2187 bits[0] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2188 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2189 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2191 bits = (dstbits += linebytes);
2194 else goto notsupported;
2201 LPBYTE bits = dstbits;
2204 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2205 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0xf800 )
2207 for (h = lines - 1; h >= 0; h--) {
2208 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2209 for (x = 0; x < srcwidth; x++, bits += 3) {
2211 bits[2] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2212 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2213 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2215 bits = (dstbits += linebytes);
2218 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2219 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x1f )
2221 for (h = lines - 1; h >= 0; h--) {
2222 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2223 for (x = 0; x < srcwidth; x++, bits += 3) {
2225 bits[0] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2226 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2227 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2229 bits = (dstbits += linebytes);
2232 else goto notsupported;
2237 /* ==== monochrome bitmap to 24 BGR dib ==== */
2239 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2240 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2242 LPBYTE bits = dstbits;
2245 for (h = lines - 1; h >= 0; h--) {
2246 for (x = 0; x < dstwidth; x++) {
2247 val = srccolors[XGetPixel(bmpImage, x, h)];
2248 *bits++ = val.peBlue;
2249 *bits++ = val.peGreen;
2250 *bits++ = val.peRed;
2252 bits = (dstbits += linebytes);
2255 else goto notsupported;
2260 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2261 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors)
2264 LPBYTE bits = dstbits;
2267 for (h = lines - 1; h >= 0; h--) {
2268 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2269 for (x = 0; x < dstwidth; x++ ) {
2270 val = srccolors[(int)*srcpixel++];
2271 *bits++ = val.peBlue; /*Blue*/
2272 *bits++ = val.peGreen; /*Green*/
2273 *bits++ = val.peRed; /*Red*/
2275 bits = (dstbits += linebytes);
2278 else goto notsupported;
2285 LPBYTE bits = dstbits;
2287 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2288 bmpImage->depth, (int)bmpImage->red_mask,
2289 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2290 for (h = lines - 1; h >= 0; h--)
2292 for (x = 0; x < dstwidth; x++, bits += 3)
2294 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2295 bits[0] = GetBValue(pixel);
2296 bits[1] = GetGValue(pixel);
2297 bits[2] = GetRValue(pixel);
2299 bits = (dstbits += linebytes);
2307 /***********************************************************************
2308 * X11DRV_DIB_SetImageBits_32
2310 * SetDIBits for a 32-bit deep DIB.
2312 static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
2313 DWORD srcwidth, DWORD dstwidth, int left,
2314 DC *dc, XImage *bmpImage,
2323 srcbits = srcbits + ( linebytes * (lines-1) );
2324 linebytes = -linebytes;
2327 ptr = (DWORD *) srcbits + left;
2329 switch ( bmpImage->depth )
2332 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2333 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) {
2334 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2335 memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2339 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2340 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
2344 for (h = lines - 1; h >= 0; h--) {
2345 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2346 for (x = 0; x < dstwidth; x++, ptr++) {
2347 *dstpixel++ = ((*ptr << 16) & 0xff0000) | (*ptr & 0xff00) | ((*ptr >> 16) & 0xff);
2349 ptr = (DWORD *) (srcbits += linebytes) + left;
2352 else goto notsupported;
2357 /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
2358 /* we need to check that source mask matches destination */
2359 if (bmpImage->bits_per_pixel == 32)
2361 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2362 memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2369 ptr = (DWORD *) srcbits + left;
2370 bptr = bmpImage->data;
2372 for (h = lines - 1; h >= 0; h--) {
2373 for (x = 0; x < dstwidth; x++) {
2374 /* *ptr is a 32bit value */
2375 /* bptr points to first of 3 bytes */
2376 *bptr++ = (*ptr >> 16) & 0xff;
2377 *bptr++ = (*ptr >> 8) & 0xff;
2378 *bptr++ = (*ptr ) & 0xff;
2381 ptr = (DWORD *) (srcbits += linebytes) + left;
2387 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2388 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f) {
2391 for (h = lines - 1; h >= 0; h--) {
2392 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2393 for (x = 0; x < dstwidth; x++, ptr++) {
2394 *dstpixel++ = (WORD) (((*ptr >> 9) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 3) & 0x001f));
2396 ptr = (DWORD *) (srcbits += linebytes) + left;
2399 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2400 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2404 for (h = lines - 1; h >= 0; h--) {
2405 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2406 for (x = 0; x < dstwidth; x++, ptr++) {
2407 *dstpixel++ = (WORD) (((*ptr << 7) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 19) & 0x001f));
2409 ptr = (DWORD *) (srcbits += linebytes) + left;
2412 else goto notsupported;
2417 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2418 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2422 for (h = lines - 1; h >= 0; h--) {
2423 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2424 for (x = 0; x < dstwidth; x++, ptr++) {
2425 *dstpixel++ = (WORD) (((*ptr >> 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 3) & 0x001f));
2427 ptr = (DWORD *) (srcbits += linebytes) + left;
2430 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2431 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
2435 for (h = lines - 1; h >= 0; h--) {
2436 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2437 for (x = 0; x < dstwidth; x++, ptr++) {
2438 *dstpixel++ = (WORD) (((*ptr << 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 19) & 0x001f));
2440 ptr = (DWORD *) (srcbits += linebytes) + left;
2443 else goto notsupported;
2451 LPBYTE bits = (LPBYTE)srcbits + left*4;
2453 for (h = lines - 1; h >= 0; h--) {
2454 for (x = left; x < dstwidth+left; x++, bits += 4)
2455 XPutPixel( bmpImage, x, h,
2456 X11DRV_PALETTE_ToPhysical(dc, RGB( bits[2], bits[1], *bits )));
2457 bits = (LPBYTE)(srcbits += linebytes) + left * 4;
2464 FIXME("32 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
2470 /***********************************************************************
2471 * X11DRV_DIB_GetImageBits_32
2473 * GetDIBits for an 32-bit deep DIB.
2475 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
2476 DWORD dstwidth, DWORD srcwidth,
2477 PALETTEENTRY *srccolors,
2478 XImage *bmpImage, DWORD linebytes )
2484 DWORD copybytes = srcwidth * 4;
2489 dstbits = dstbits + ( linebytes * (lines-1) );
2490 linebytes = -linebytes;
2495 switch ( bmpImage->depth )
2498 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2499 if ( bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff )
2500 for (h = lines - 1; h >= 0; h--, dstbits+=linebytes)
2501 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, copybytes );
2503 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2504 else if ( bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000 )
2508 for (h = lines - 1; h >= 0; h--) {
2509 srcbits = bmpImage->data + h * bmpImage->bytes_per_line;
2510 for (x = 0; x < dstwidth; x++, bits+=4, srcbits+=2) {
2511 *(bits + 2) = *srcbits++;
2512 *(bits + 1) = *srcbits++;
2515 bits = (dstbits += linebytes);
2518 else goto notsupported;
2522 /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */
2523 /* we need to check that source mask matches destination */
2529 srcpixel = (DWORD *) dstbits;
2530 bptr = bmpImage->data;
2532 for (h = lines - 1; h >= 0; h--) {
2533 for (x = 0; x < dstwidth; x++) {
2534 /* *srcpixel is a 32bit value */
2535 /* bptr points to first of 3 bytes */
2537 srcdata = srcdata << 8 | *bptr++;
2538 srcdata = srcdata << 8 | *bptr++;
2539 srcdata = srcdata << 8 | *bptr++;
2541 *srcpixel++ = srcdata;
2543 srcpixel = (DWORD *) (dstbits += linebytes);
2553 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2554 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
2556 for (h = lines - 1; h >= 0; h--) {
2557 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2558 for (x = 0; x < dstwidth; x++, bits+=2) {
2560 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2561 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2562 *bits = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2564 bits = (dstbits += linebytes);
2567 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2568 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2570 for (h = lines - 1; h >= 0; h--) {
2571 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2572 for (x = 0; x < dstwidth; x++, bits+=2) {
2574 *bits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));/*Blue*/
2575 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2576 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2578 bits = (dstbits += linebytes);
2581 else goto notsupported;
2590 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2591 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2593 for (h = lines - 1; h >= 0; h--) {
2594 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2595 for (x = 0; x < srcwidth; x++, bits+=2) {
2597 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2598 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2599 *bits = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2601 bits = (dstbits += linebytes);
2604 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2605 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2607 for (h = lines - 1; h >= 0; h--) {
2608 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2609 for (x = 0; x < srcwidth; x++, bits+=2) {
2611 *bits++ = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));/*Blue*/
2612 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2613 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2615 bits = (dstbits += linebytes);
2618 else goto notsupported;
2623 /* ==== monochrome bitmap to 32 BGR dib ==== */
2625 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2626 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2630 for (h = lines - 1; h >= 0; h--) {
2631 for (x = 0; x < dstwidth; x++) {
2632 val = srccolors[XGetPixel(bmpImage, x, h)];
2633 *bits++ = val.peBlue;
2634 *bits++ = val.peGreen;
2635 *bits++ = val.peRed;
2638 bits = (dstbits += linebytes);
2641 else goto notsupported;
2646 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2647 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2652 for (h = lines - 1; h >= 0; h--) {
2653 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2654 for (x = 0; x < dstwidth; x++) {
2655 val = srccolors[(int)*srcpixel++];
2656 *bits++ = val.peBlue; /*Blue*/
2657 *bits++ = val.peGreen; /*Green*/
2658 *bits++ = val.peRed; /*Red*/
2661 bits = (dstbits += linebytes);
2664 else goto notsupported;
2669 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2670 bmpImage->depth, (int)bmpImage->red_mask,
2671 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2672 for (h = lines - 1; h >= 0; h--)
2674 for (x = 0; x < dstwidth; x++, bits += 4)
2676 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2677 bits[0] = GetBValue(pixel);
2678 bits[1] = GetGValue(pixel);
2679 bits[2] = GetRValue(pixel);
2681 bits = (dstbits += linebytes);
2687 /***********************************************************************
2688 * X11DRV_DIB_SetImageBits
2690 * Transfer the bits to an X image.
2691 * Helper function for SetDIBits() and SetDIBitsToDevice().
2693 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2695 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2700 bmpImage = descr->image;
2702 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
2703 descr->infoWidth, lines, 32, 0 );
2704 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2705 if(bmpImage->data == NULL) {
2706 ERR("Out of memory!\n");
2707 XDestroyImage( bmpImage );
2708 wine_tsx11_unlock();
2713 /* Transfer the pixels */
2714 switch(descr->infoBpp)
2717 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
2718 descr->width, descr->xSrc, (int *)(descr->colorMap),
2719 bmpImage, descr->dibpitch );
2722 if (descr->compression) {
2723 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
2724 descr->width, descr->height, AllPlanes, ZPixmap,
2725 bmpImage, descr->xSrc, descr->ySrc );
2727 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
2728 descr->infoWidth, descr->width,
2729 descr->xSrc, (int *)(descr->colorMap),
2732 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
2733 descr->infoWidth, descr->width,
2734 descr->xSrc, (int*)(descr->colorMap),
2735 bmpImage, descr->dibpitch );
2738 if (descr->compression) {
2739 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
2740 descr->width, descr->height, AllPlanes, ZPixmap,
2741 bmpImage, descr->xSrc, descr->ySrc );
2742 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
2743 descr->infoWidth, descr->width,
2744 descr->xSrc, (int *)(descr->colorMap),
2747 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
2748 descr->infoWidth, descr->width,
2749 descr->xSrc, (int *)(descr->colorMap),
2750 bmpImage, descr->dibpitch );
2754 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
2755 descr->infoWidth, descr->width,
2756 descr->xSrc, descr->dc,
2757 descr->rMask, descr->gMask, descr->bMask,
2758 bmpImage, descr->dibpitch);
2761 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
2762 descr->infoWidth, descr->width,
2763 descr->xSrc, descr->dc, bmpImage,
2767 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
2768 descr->infoWidth, descr->width,
2769 descr->xSrc, descr->dc,
2770 bmpImage, descr->dibpitch);
2773 WARN("(%d): Invalid depth\n", descr->infoBpp );
2777 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
2778 descr->drawable, descr->gc, bmpImage,
2779 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2780 descr->width, descr->height);
2781 #ifdef HAVE_LIBXXSHM
2784 XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
2785 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2786 descr->width, descr->height, FALSE );
2787 XSync( gdi_display, 0 );
2791 XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
2792 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2793 descr->width, descr->height );
2795 if (!descr->image) XDestroyImage( bmpImage );
2796 wine_tsx11_unlock();
2800 /***********************************************************************
2801 * X11DRV_DIB_GetImageBits
2803 * Transfer the bits from an X image.
2805 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2807 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2812 bmpImage = descr->image;
2814 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
2815 descr->infoWidth, lines, 32, 0 );
2816 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2817 if(bmpImage->data == NULL) {
2818 ERR("Out of memory!\n");
2819 XDestroyImage( bmpImage );
2820 wine_tsx11_unlock();
2825 TRACE("XGetSubImage(%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
2826 descr->drawable, descr->xSrc, descr->ySrc, descr->width,
2827 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
2828 XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
2829 descr->width, lines, AllPlanes, ZPixmap,
2830 bmpImage, descr->xDest, descr->yDest );
2832 /* Transfer the pixels */
2833 switch(descr->infoBpp)
2836 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
2837 descr->infoWidth, descr->width,
2838 descr->colorMap, descr->palentry,
2839 bmpImage, descr->dibpitch );
2843 if (descr->compression)
2844 FIXME("Compression not yet supported!\n");
2846 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
2847 descr->infoWidth, descr->width,
2848 descr->colorMap, descr->palentry,
2849 bmpImage, descr->dibpitch );
2853 if (descr->compression)
2854 FIXME("Compression not yet supported!\n");
2856 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
2857 descr->infoWidth, descr->width,
2858 descr->colorMap, descr->palentry,
2859 bmpImage, descr->dibpitch );
2863 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
2864 descr->infoWidth,descr->width,
2866 descr->rMask, descr->gMask, descr->bMask,
2867 bmpImage, descr->dibpitch );
2871 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
2872 descr->infoWidth,descr->width,
2873 descr->palentry, bmpImage, descr->dibpitch);
2877 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
2878 descr->infoWidth, descr->width,
2879 descr->palentry, bmpImage, descr->dibpitch);
2883 WARN("(%d): Invalid depth\n", descr->infoBpp );
2887 if (!descr->image) XDestroyImage( bmpImage );
2888 wine_tsx11_unlock();
2892 /*************************************************************************
2893 * X11DRV_SetDIBitsToDevice
2896 INT X11DRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx,
2897 DWORD cy, INT xSrc, INT ySrc,
2898 UINT startscan, UINT lines, LPCVOID bits,
2899 const BITMAPINFO *info, UINT coloruse )
2901 X11DRV_DIB_IMAGEBITS_DESCR descr;
2902 DWORD width, oldcy = cy;
2904 int height, tmpheight;
2905 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
2908 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
2909 &descr.infoBpp, &descr.compression ) == -1)
2912 if (height < 0) height = -height;
2913 if (!lines || (startscan >= height)) return 0;
2914 if (startscan + lines > height) lines = height - startscan;
2915 if (ySrc < startscan) ySrc = startscan;
2916 else if (ySrc >= startscan + lines) return 0;
2917 if (xSrc >= width) return 0;
2918 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
2919 if (xSrc + cx >= width) cx = width - xSrc;
2920 if (!cx || !cy) return 0;
2922 X11DRV_SetupGCForText( dc ); /* To have the correct colors */
2923 TSXSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);
2925 switch (descr.infoBpp)
2930 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
2931 coloruse == DIB_PAL_COLORS ? dc : NULL, coloruse,
2932 dc->bitsPerPixel, info, &descr.nColorMap );
2933 if (!descr.colorMap) return 0;
2934 descr.rMask = descr.gMask = descr.bMask = 0;
2938 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2939 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
2940 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
2945 descr.rMask = descr.gMask = descr.bMask = 0;
2950 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2951 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
2952 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
2960 descr.palentry = NULL;
2961 descr.lines = tmpheight >= 0 ? lines : -lines;
2962 descr.infoWidth = width;
2963 descr.depth = dc->bitsPerPixel;
2964 descr.drawable = physDev->drawable;
2965 descr.gc = physDev->gc;
2967 descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy)
2969 descr.xDest = dc->DCOrgX + XLPTODP( dc, xDest );
2970 descr.yDest = dc->DCOrgY + YLPTODP( dc, yDest ) +
2971 (tmpheight >= 0 ? oldcy-cy : 0);
2974 descr.useShm = FALSE;
2975 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
2977 result = X11DRV_DIB_SetImageBits( &descr );
2979 if (descr.infoBpp <= 8)
2980 HeapFree(GetProcessHeap(), 0, descr.colorMap);
2984 /***********************************************************************
2985 * X11DRV_DIB_SetDIBits
2987 INT X11DRV_DIB_SetDIBits(
2988 BITMAPOBJ *bmp, DC *dc, UINT startscan,
2989 UINT lines, LPCVOID bits, const BITMAPINFO *info,
2990 UINT coloruse, HBITMAP hbitmap)
2992 X11DRV_DIB_IMAGEBITS_DESCR descr;
2993 int height, tmpheight;
2998 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
2999 &descr.infoBpp, &descr.compression ) == -1)
3003 if (height < 0) height = -height;
3004 if (!lines || (startscan >= height))
3007 if (startscan + lines > height) lines = height - startscan;
3009 switch (descr.infoBpp)
3014 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3015 coloruse == DIB_PAL_COLORS ? descr.dc : NULL, coloruse,
3016 bmp->bitmap.bmBitsPixel,
3017 info, &descr.nColorMap );
3018 if (!descr.colorMap) return 0;
3019 descr.rMask = descr.gMask = descr.bMask = 0;
3023 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3024 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3025 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3030 descr.rMask = descr.gMask = descr.bMask = 0;
3035 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3036 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
3037 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
3045 if(!bmp->physBitmap)
3046 X11DRV_CreateBitmap(hbitmap);
3050 descr.palentry = NULL;
3051 descr.lines = tmpheight >= 0 ? lines : -lines;
3052 descr.depth = bmp->bitmap.bmBitsPixel;
3053 descr.drawable = (Pixmap)bmp->physBitmap;
3054 descr.gc = BITMAP_GC(bmp);
3058 descr.yDest = height - startscan - lines;
3059 descr.width = bmp->bitmap.bmWidth;
3060 descr.height = lines;
3061 descr.useShm = FALSE;
3062 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
3063 result = X11DRV_DIB_SetImageBits( &descr );
3065 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
3070 /***********************************************************************
3071 * X11DRV_DIB_GetDIBits
3073 INT X11DRV_DIB_GetDIBits(
3074 BITMAPOBJ *bmp, DC *dc, UINT startscan,
3075 UINT lines, LPVOID bits, BITMAPINFO *info,
3076 UINT coloruse, HBITMAP hbitmap)
3078 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3079 X11DRV_DIB_IMAGEBITS_DESCR descr;
3080 PALETTEOBJ * palette;
3083 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3084 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
3085 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
3088 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
3091 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
3093 height = info->bmiHeader.biHeight;
3094 if (height < 0) height = -height;
3095 if( lines > height ) lines = height;
3096 /* Top-down images have a negative biHeight, the scanlines of theses images
3097 * were inverted in X11DRV_DIB_GetImageBits_xx
3098 * To prevent this we simply change the sign of lines
3099 * (the number of scan lines to copy).
3100 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3102 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
3104 if( startscan >= bmp->bitmap.bmHeight )
3110 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
3111 &descr.infoBpp, &descr.compression ) == -1)
3117 switch (descr.infoBpp)
3123 descr.rMask = descr.gMask = descr.bMask = 0;
3127 descr.rMask = 0x7c00;
3128 descr.gMask = 0x03e0;
3129 descr.bMask = 0x001f;
3133 descr.rMask = 0xff0000;
3134 descr.gMask = 0xff00;
3140 if(!bmp->physBitmap)
3141 X11DRV_CreateBitmap(hbitmap);
3145 descr.palentry = palette->logpalette.palPalEntry;
3148 descr.lines = lines;
3149 descr.depth = bmp->bitmap.bmBitsPixel;
3150 descr.drawable = (Pixmap)bmp->physBitmap;
3151 descr.gc = BITMAP_GC(bmp);
3152 descr.width = bmp->bitmap.bmWidth;
3153 descr.height = bmp->bitmap.bmHeight;
3154 descr.colorMap = info->bmiColors;
3159 if (descr.lines > 0)
3161 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
3165 descr.ySrc = startscan;
3167 #ifdef HAVE_LIBXXSHM
3168 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
3170 descr.useShm = FALSE;
3172 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
3173 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
3175 X11DRV_DIB_GetImageBits( &descr );
3177 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
3178 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
3179 info->bmiHeader.biWidth,
3180 info->bmiHeader.biHeight,
3181 info->bmiHeader.biBitCount );
3183 info->bmiHeader.biCompression = 0;
3184 if (descr.compression == BI_BITFIELDS)
3186 *(DWORD *)info->bmiColors = descr.rMask;
3187 *((DWORD *)info->bmiColors+1) = descr.gMask;
3188 *((DWORD *)info->bmiColors+2) = descr.bMask;
3192 GDI_ReleaseObj( dc->hPalette );
3197 /***********************************************************************
3198 * DIB_DoProtectDIBSection
3200 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
3202 DIBSECTION *dib = bmp->dib;
3203 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
3204 : -dib->dsBm.bmHeight;
3205 /* use the biSizeImage data as the memory size only if we're dealing with a
3206 compressed image where the value is set. Otherwise, calculate based on
3208 INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
3209 ? dib->dsBmih.biSizeImage
3210 : dib->dsBm.bmWidthBytes * effHeight;
3213 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
3214 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
3217 /***********************************************************************
3218 * X11DRV_DIB_DoUpdateDIBSection
3220 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
3221 void *colorMap, int nColorMap,
3223 DWORD xSrc, DWORD ySrc,
3224 DWORD xDest, DWORD yDest,
3225 DWORD width, DWORD height)
3227 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3228 X11DRV_DIB_IMAGEBITS_DESCR descr;
3230 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
3231 &descr.infoBpp, &descr.compression ) == -1)
3235 descr.palentry = NULL;
3236 descr.image = dib->image;
3237 descr.colorMap = colorMap;
3238 descr.nColorMap = nColorMap;
3239 descr.bits = dib->dibSection.dsBm.bmBits;
3240 descr.depth = bmp->bitmap.bmBitsPixel;
3242 switch (descr.infoBpp)
3248 descr.rMask = descr.gMask = descr.bMask = 0;
3252 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
3253 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
3254 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
3258 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff;
3259 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0xff00;
3260 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0xff0000;
3265 descr.drawable = dest;
3266 descr.gc = BITMAP_GC(bmp);
3269 descr.xDest = xDest;
3270 descr.yDest = yDest;
3271 descr.width = width;
3272 descr.height = height;
3273 #ifdef HAVE_LIBXXSHM
3274 descr.useShm = (dib->shminfo.shmid != -1);
3276 descr.useShm = FALSE;
3278 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
3282 TRACE("Copying from Pixmap to DIB bits\n");
3283 X11DRV_DIB_GetImageBits( &descr );
3287 TRACE("Copying from DIB bits to Pixmap\n");
3288 X11DRV_DIB_SetImageBits( &descr );
3292 /***********************************************************************
3293 * X11DRV_DIB_CopyDIBSection
3295 void X11DRV_DIB_CopyDIBSection(DC *dcSrc, DC *dcDst,
3296 DWORD xSrc, DWORD ySrc,
3297 DWORD xDest, DWORD yDest,
3298 DWORD width, DWORD height)
3301 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcDst->physDev;
3302 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
3304 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst,
3305 xSrc, ySrc, xDest, yDest, width, height);
3306 /* this function is meant as an optimization for BitBlt,
3307 * not to be called otherwise */
3308 if (!(dcSrc->flags & DC_MEMORY)) {
3309 ERR("called for non-memory source DC!?\n");
3313 bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC );
3314 if (!(bmp && bmp->dib)) {
3315 ERR("called for non-DIBSection!?\n");
3316 GDI_ReleaseObj( dcSrc->hBitmap );
3319 /* while BitBlt should already have made sure we only get
3320 * positive values, we should check for oversize values */
3321 if ((xSrc < bmp->bitmap.bmWidth) &&
3322 (ySrc < bmp->bitmap.bmHeight)) {
3323 if (xSrc + width > bmp->bitmap.bmWidth)
3324 width = bmp->bitmap.bmWidth - xSrc;
3325 if (ySrc + height > bmp->bitmap.bmHeight)
3326 height = bmp->bitmap.bmHeight - ySrc;
3327 /* if the source bitmap is 8bpp or less, we're supposed to use the
3328 * DC's palette for color conversion (not the DIB color table) */
3329 if (bmp->dib->dsBm.bmBitsPixel <= 8) {
3330 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3331 if ((!dcSrc->hPalette) ||
3332 (dcSrc->hPalette == GetStockObject(DEFAULT_PALETTE))) {
3333 /* HACK: no palette has been set in the source DC,
3334 * use the DIB colormap instead - this is necessary in some
3335 * cases since we need to do depth conversion in some places
3336 * where real Windows can just copy data straight over */
3337 colorMap = dib->colorMap;
3338 nColorMap = dib->nColorMap;
3340 colorMap = X11DRV_DIB_BuildColorMap( dcSrc, (WORD)-1,
3341 bmp->dib->dsBm.bmBitsPixel,
3342 (BITMAPINFO*)&(bmp->dib->dsBmih),
3344 if (colorMap) aColorMap = TRUE;
3347 /* perform the copy */
3348 X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
3349 physDev->drawable, xSrc, ySrc, xDest, yDest,
3351 /* free color mapping */
3353 HeapFree(GetProcessHeap(), 0, colorMap);
3355 GDI_ReleaseObj( dcSrc->hBitmap );
3358 /***********************************************************************
3359 * X11DRV_DIB_DoUpdateDIBSection
3361 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
3363 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3364 X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
3365 (Drawable)bmp->physBitmap, 0, 0, 0, 0,
3366 bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
3369 /***********************************************************************
3370 * X11DRV_DIB_FaultHandler
3372 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
3377 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
3378 if (!bmp) return FALSE;
3380 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
3381 if (state != DIB_Status_InSync) {
3382 /* no way to tell whether app needs read or write yet,
3384 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
3386 /* hm, apparently the app must have write access */
3387 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
3389 X11DRV_DIB_Unlock(bmp, TRUE);
3391 GDI_ReleaseObj( (HBITMAP)res );
3395 /***********************************************************************
3398 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
3400 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3401 INT ret = DIB_Status_None;
3404 EnterCriticalSection(&(dib->lock));
3407 case DIB_Status_GdiMod:
3408 /* GDI access - request to draw on pixmap */
3409 switch (dib->status)
3412 case DIB_Status_None:
3413 dib->p_status = DIB_Status_GdiMod;
3414 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3417 case DIB_Status_GdiMod:
3418 TRACE("GdiMod requested in status GdiMod\n" );
3421 case DIB_Status_InSync:
3422 TRACE("GdiMod requested in status InSync\n" );
3423 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3424 dib->status = DIB_Status_GdiMod;
3425 dib->p_status = DIB_Status_InSync;
3428 case DIB_Status_AuxMod:
3429 TRACE("GdiMod requested in status AuxMod\n" );
3430 if (lossy) dib->status = DIB_Status_GdiMod;
3431 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
3432 dib->p_status = DIB_Status_AuxMod;
3433 if (dib->status != DIB_Status_AppMod) {
3434 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3437 /* fall through if copy_aux() had to change to AppMod state */
3439 case DIB_Status_AppMod:
3440 TRACE("GdiMod requested in status AppMod\n" );
3442 /* make it readonly to avoid app changing data while we copy */
3443 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3444 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3446 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3447 dib->p_status = DIB_Status_AppMod;
3448 dib->status = DIB_Status_GdiMod;
3453 case DIB_Status_InSync:
3454 /* App access - request access to read DIB surface */
3455 /* (typically called from signal handler) */
3456 switch (dib->status)
3459 case DIB_Status_None:
3460 /* shouldn't happen from signal handler */
3463 case DIB_Status_AuxMod:
3464 TRACE("InSync requested in status AuxMod\n" );
3465 if (lossy) dib->status = DIB_Status_InSync;
3467 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3468 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
3470 if (dib->status != DIB_Status_GdiMod) {
3471 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3474 /* fall through if copy_aux() had to change to GdiMod state */
3476 case DIB_Status_GdiMod:
3477 TRACE("InSync requested in status GdiMod\n" );
3479 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3480 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3482 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3483 dib->status = DIB_Status_InSync;
3486 case DIB_Status_InSync:
3487 TRACE("InSync requested in status InSync\n" );
3488 /* shouldn't happen from signal handler */
3491 case DIB_Status_AppMod:
3492 TRACE("InSync requested in status AppMod\n" );
3493 /* no reason to do anything here, and this
3494 * shouldn't happen from signal handler */
3499 case DIB_Status_AppMod:
3500 /* App access - request access to write DIB surface */
3501 /* (typically called from signal handler) */
3502 switch (dib->status)
3505 case DIB_Status_None:
3506 /* shouldn't happen from signal handler */
3509 case DIB_Status_AuxMod:
3510 TRACE("AppMod requested in status AuxMod\n" );
3511 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3512 if (lossy) dib->status = DIB_Status_AppMod;
3513 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
3514 if (dib->status != DIB_Status_GdiMod)
3516 /* fall through if copy_aux() had to change to GdiMod state */
3518 case DIB_Status_GdiMod:
3519 TRACE("AppMod requested in status GdiMod\n" );
3520 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3521 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3522 dib->status = DIB_Status_AppMod;
3525 case DIB_Status_InSync:
3526 TRACE("AppMod requested in status InSync\n" );
3527 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3528 dib->status = DIB_Status_AppMod;
3531 case DIB_Status_AppMod:
3532 TRACE("AppMod requested in status AppMod\n" );
3533 /* shouldn't happen from signal handler */
3538 case DIB_Status_AuxMod:
3539 if (dib->status == DIB_Status_None) {
3540 dib->p_status = req;
3542 if (dib->status != DIB_Status_AuxMod)
3543 dib->p_status = dib->status;
3544 dib->status = DIB_Status_AuxMod;
3547 /* it is up to the caller to do the copy/conversion, probably
3548 * using the return value to decide where to copy from */
3550 LeaveCriticalSection(&(dib->lock));
3555 /***********************************************************************
3558 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
3560 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3561 INT ret = DIB_Status_None;
3564 TRACE("Locking %p from thread %08lx\n", bmp, GetCurrentThreadId());
3565 EnterCriticalSection(&(dib->lock));
3567 if (req != DIB_Status_None)
3568 X11DRV_DIB_Coerce(bmp, req, lossy);
3573 /***********************************************************************
3576 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
3578 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3581 switch (dib->status)
3584 case DIB_Status_None:
3585 /* in case anyone is wondering, this is the "signal handler doesn't
3586 * work" case, where we always have to be ready for app access */
3588 switch (dib->p_status)
3590 case DIB_Status_AuxMod:
3591 TRACE("Unlocking and syncing from AuxMod\n" );
3592 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
3593 if (dib->status != DIB_Status_None) {
3594 dib->p_status = dib->status;
3595 dib->status = DIB_Status_None;
3597 if (dib->p_status != DIB_Status_GdiMod)
3599 /* fall through if copy_aux() had to change to GdiMod state */
3601 case DIB_Status_GdiMod:
3602 TRACE("Unlocking and syncing from GdiMod\n" );
3603 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3607 TRACE("Unlocking without needing to sync\n" );
3611 else TRACE("Unlocking with no changes\n");
3612 dib->p_status = DIB_Status_None;
3615 case DIB_Status_GdiMod:
3616 TRACE("Unlocking in status GdiMod\n" );
3617 /* DIB was protected in Coerce */
3619 /* no commit, revert to InSync if applicable */
3620 if ((dib->p_status == DIB_Status_InSync) ||
3621 (dib->p_status == DIB_Status_AppMod)) {
3622 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3623 dib->status = DIB_Status_InSync;
3628 case DIB_Status_InSync:
3629 TRACE("Unlocking in status InSync\n" );
3630 /* DIB was already protected in Coerce */
3633 case DIB_Status_AppMod:
3634 TRACE("Unlocking in status AppMod\n" );
3635 /* DIB was already protected in Coerce */
3636 /* this case is ordinary only called from the signal handler,
3637 * so we don't bother to check for !commit */
3640 case DIB_Status_AuxMod:
3641 TRACE("Unlocking in status AuxMod\n" );
3643 /* DIB may need protection now */
3644 if ((dib->p_status == DIB_Status_InSync) ||
3645 (dib->p_status == DIB_Status_AppMod))
3646 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3648 /* no commit, revert to previous state */
3649 if (dib->p_status != DIB_Status_None)
3650 dib->status = dib->p_status;
3651 /* no protections changed */
3653 dib->p_status = DIB_Status_None;
3656 LeaveCriticalSection(&(dib->lock));
3657 TRACE("Unlocked %p\n", bmp);
3661 /***********************************************************************
3662 * X11DRV_CoerceDIBSection2
3664 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
3669 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3670 if (!bmp) return DIB_Status_None;
3671 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
3672 GDI_ReleaseObj( hBmp );
3676 /***********************************************************************
3677 * X11DRV_LockDIBSection2
3679 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
3684 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3685 if (!bmp) return DIB_Status_None;
3686 ret = X11DRV_DIB_Lock(bmp, req, lossy);
3687 GDI_ReleaseObj( hBmp );
3691 /***********************************************************************
3692 * X11DRV_UnlockDIBSection2
3694 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
3698 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3700 X11DRV_DIB_Unlock(bmp, commit);
3701 GDI_ReleaseObj( hBmp );
3704 /***********************************************************************
3705 * X11DRV_CoerceDIBSection
3707 INT X11DRV_CoerceDIBSection(DC *dc, INT req, BOOL lossy)
3709 if (!dc) return DIB_Status_None;
3710 return X11DRV_CoerceDIBSection2( dc->hBitmap, req, lossy );
3713 /***********************************************************************
3714 * X11DRV_LockDIBSection
3716 INT X11DRV_LockDIBSection(DC *dc, INT req, BOOL lossy)
3718 if (!dc) return DIB_Status_None;
3719 if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;
3721 return X11DRV_LockDIBSection2( dc->hBitmap, req, lossy );
3724 /***********************************************************************
3725 * X11DRV_UnlockDIBSection
3727 void X11DRV_UnlockDIBSection(DC *dc, BOOL commit)
3730 if (!(dc->flags & DC_MEMORY)) return;
3732 X11DRV_UnlockDIBSection2( dc->hBitmap, commit );
3735 /***********************************************************************
3736 * X11DRV_DIB_CreateDIBSection16
3738 HBITMAP16 X11DRV_DIB_CreateDIBSection16(
3739 DC *dc, BITMAPINFO *bmi, UINT16 usage,
3740 SEGPTR *bits, HANDLE section,
3741 DWORD offset, DWORD ovr_pitch)
3743 HBITMAP res = X11DRV_DIB_CreateDIBSection(dc, bmi, usage, NULL,
3744 section, offset, ovr_pitch);
3747 BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3748 if ( bmp && bmp->dib )
3750 DIBSECTION *dib = bmp->dib;
3751 INT height = dib->dsBm.bmHeight >= 0 ?
3752 dib->dsBm.bmHeight : -dib->dsBm.bmHeight;
3753 /* same as above - only use biSizeImage as the correct size if it a
3754 compressed image and it's currently non-zero. In other cases, use
3755 width * height as the value. */
3756 INT size = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
3757 ? dib->dsBmih.biSizeImage
3758 : dib->dsBm.bmWidthBytes * height;
3759 if ( dib->dsBm.bmBits )
3761 ((X11DRV_DIBSECTION *) bmp->dib)->selector =
3762 SELECTOR_AllocBlock( dib->dsBm.bmBits, size, WINE_LDT_FLAGS_DATA );
3764 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3765 dib->dsBm.bmBits, size, ((X11DRV_DIBSECTION *) bmp->dib)->selector,
3766 MAKESEGPTR(((X11DRV_DIBSECTION *) bmp->dib)->selector, 0));
3768 *bits = MAKESEGPTR( ((X11DRV_DIBSECTION *) bmp->dib)->selector, 0 );
3770 if (bmp) GDI_ReleaseObj( res );
3776 #ifdef HAVE_LIBXXSHM
3777 /***********************************************************************
3778 * X11DRV_XShmErrorHandler
3781 static int XShmErrorHandler(Display *dpy, XErrorEvent *event)
3787 /***********************************************************************
3788 * X11DRV_XShmCreateImage
3791 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
3792 XShmSegmentInfo* shminfo)
3794 int (*WineXHandler)(Display *, XErrorEvent *);
3798 image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
3801 shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
3803 if( shminfo->shmid != -1 )
3805 shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
3806 if( shminfo->shmaddr != (char*)-1 )
3808 shminfo->readOnly = FALSE;
3809 if( XShmAttach( gdi_display, shminfo ) != 0)
3811 /* Reset the error flag */
3813 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3814 XSync( gdi_display, 0 );
3818 shmctl(shminfo->shmid, IPC_RMID, 0);
3820 XSetErrorHandler(WineXHandler);
3821 wine_tsx11_unlock();
3822 return image; /* Success! */
3824 /* An error occured */
3826 XSetErrorHandler(WineXHandler);
3828 shmdt(shminfo->shmaddr);
3830 shmctl(shminfo->shmid, IPC_RMID, 0);
3832 XFlush(gdi_display);
3833 XDestroyImage(image);
3836 wine_tsx11_unlock();
3839 #endif /* HAVE_LIBXXSHM */
3842 /***********************************************************************
3843 * X11DRV_DIB_CreateDIBSection
3845 HBITMAP X11DRV_DIB_CreateDIBSection(
3846 DC *dc, BITMAPINFO *bmi, UINT usage,
3847 LPVOID *bits, HANDLE section,
3848 DWORD offset, DWORD ovr_pitch)
3851 BITMAPOBJ *bmp = NULL;
3852 X11DRV_DIBSECTION *dib = NULL;
3853 int *colorMap = NULL;
3856 /* Fill BITMAP32 structure with DIB data */
3857 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
3858 INT effHeight, totalSize;
3860 LPVOID mapBits = NULL;
3862 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3863 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
3864 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
3866 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
3868 bm.bmWidth = bi->biWidth;
3869 bm.bmHeight = effHeight;
3870 bm.bmWidthBytes = ovr_pitch ? ovr_pitch
3871 : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
3872 bm.bmPlanes = bi->biPlanes;
3873 bm.bmBitsPixel = bi->biBitCount;
3876 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
3877 we're dealing with a compressed bitmap. Otherwise, use width * height. */
3878 totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
3879 ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
3883 SYSTEM_INFO SystemInfo;
3887 GetSystemInfo( &SystemInfo );
3888 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
3889 mapSize = totalSize + (offset - mapOffset);
3890 mapBits = MapViewOfFile( section,
3891 FILE_MAP_ALL_ACCESS,
3895 bm.bmBits = (char *)mapBits + (offset - mapOffset);
3897 else if (ovr_pitch && offset)
3898 bm.bmBits = (LPVOID) offset;
3901 bm.bmBits = VirtualAlloc(NULL, totalSize,
3902 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
3905 /* Create Color Map */
3906 if (bm.bmBits && bm.bmBitsPixel <= 8)
3907 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? dc : NULL,
3908 usage, bm.bmBitsPixel, bmi, &nColorMap );
3910 /* Allocate Memory for DIB and fill structure */
3912 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
3915 dib->dibSection.dsBm = bm;
3916 dib->dibSection.dsBmih = *bi;
3917 dib->dibSection.dsBmih.biSizeImage = totalSize;
3919 /* Set dsBitfields values */
3920 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
3922 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
3924 else switch( bi->biBitCount )
3927 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
3928 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
3929 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
3933 dib->dibSection.dsBitfields[0] = 0xff;
3934 dib->dibSection.dsBitfields[1] = 0xff00;
3935 dib->dibSection.dsBitfields[2] = 0xff0000;
3939 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
3940 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
3941 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
3944 dib->dibSection.dshSection = section;
3945 dib->dibSection.dsOffset = offset;
3947 dib->status = DIB_Status_None;
3950 dib->nColorMap = nColorMap;
3951 dib->colorMap = colorMap;
3954 /* Create Device Dependent Bitmap and add DIB pointer */
3957 res = CreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
3960 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3963 bmp->dib = (DIBSECTION *) dib;
3965 if(!bmp->physBitmap)
3966 X11DRV_CreateBitmap(res);
3974 #ifdef HAVE_LIBXXSHM
3975 if (TSXShmQueryExtension(gdi_display) &&
3976 (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
3977 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
3979 ; /* Created Image */
3981 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3982 dib->shminfo.shmid = -1;
3985 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3989 /* Clean up in case of errors */
3990 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
3992 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3993 res, bmp, dib, bm.bmBits);
3997 UnmapViewOfFile(mapBits), bm.bmBits = NULL;
3999 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
4002 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
4003 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
4004 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
4005 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
4006 if (res) { DeleteObject(res); res = 0; }
4010 /* Install fault handler, if possible */
4011 InitializeCriticalSection(&(dib->lock));
4012 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
4014 if (section || offset)
4016 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4017 if (dib) dib->status = DIB_Status_AppMod;
4021 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4022 if (dib) dib->status = DIB_Status_InSync;
4027 /* Return BITMAP handle and storage location */
4028 if (bmp) GDI_ReleaseObj(res);
4029 if (bm.bmBits && bits) *bits = bm.bmBits;
4033 /***********************************************************************
4034 * X11DRV_DIB_DeleteDIBSection
4036 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
4038 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4042 #ifdef HAVE_LIBXXSHM
4043 if (dib->shminfo.shmid != -1)
4045 TSXShmDetach (gdi_display, &(dib->shminfo));
4046 XDestroyImage (dib->image);
4047 shmdt (dib->shminfo.shmaddr);
4048 dib->shminfo.shmid = -1;
4052 XDestroyImage( dib->image );
4056 HeapFree(GetProcessHeap(), 0, dib->colorMap);
4058 if (dib->selector) SELECTOR_FreeBlock( dib->selector );
4059 DeleteCriticalSection(&(dib->lock));
4062 /***********************************************************************
4063 * X11DRV_DIB_SetDIBColorTable
4065 UINT X11DRV_DIB_SetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, const RGBQUAD *colors)
4067 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4069 if (dib && dib->colorMap) {
4070 X11DRV_DIB_GenColorMap( dc, dib->colorMap, DIB_RGB_COLORS, dib->dibSection.dsBm.bmBitsPixel,
4071 TRUE, colors, start, count + start );
4077 /***********************************************************************
4078 * X11DRV_DIB_GetDIBColorTable
4080 UINT X11DRV_DIB_GetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, RGBQUAD *colors)
4082 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4084 if (dib && dib->colorMap) {
4085 int i, end = count + start;
4086 if (end > dib->nColorMap) end = dib->nColorMap;
4087 for (i = start; i < end; i++,colors++) {
4088 COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
4089 colors->rgbBlue = GetBValue(col);
4090 colors->rgbGreen = GetGValue(col);
4091 colors->rgbRed = GetRValue(col);
4092 colors->rgbReserved = 0;
4100 /**************************************************************************
4101 * X11DRV_DIB_CreateDIBFromPixmap
4103 * Allocates a packed DIB and copies the Pixmap data into it.
4104 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
4106 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
4109 BITMAPOBJ *pBmp = NULL;
4110 HGLOBAL hPackedDIB = 0;
4112 /* Allocates an HBITMAP which references the Pixmap passed to us */
4113 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
4116 TRACE("\tCould not create bitmap header for Pixmap\n");
4121 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4122 * A packed DIB contains a BITMAPINFO structure followed immediately by
4123 * an optional color palette and the pixel data.
4125 hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
4127 /* Get a pointer to the BITMAPOBJ structure */
4128 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4130 /* We can now get rid of the HBITMAP wrapper we created earlier.
4131 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4135 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4136 pBmp->physBitmap = NULL;
4139 GDI_ReleaseObj( hBmp );
4143 TRACE("\tReturning packed DIB %x\n", hPackedDIB);
4148 /**************************************************************************
4149 * X11DRV_DIB_CreatePixmapFromDIB
4151 * Creates a Pixmap from a packed DIB
4153 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
4155 Pixmap pixmap = None;
4157 BITMAPOBJ *pBmp = NULL;
4158 LPBYTE pPackedDIB = NULL;
4159 LPBITMAPINFO pbmi = NULL;
4160 LPBITMAPINFOHEADER pbmiHeader = NULL;
4161 LPBYTE pbits = NULL;
4163 /* Get a pointer to the packed DIB's data */
4164 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
4165 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
4166 pbmi = (LPBITMAPINFO)pPackedDIB;
4167 pbits = (LPBYTE)(pPackedDIB
4168 + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
4170 /* Create a DDB from the DIB */
4172 hBmp = CreateDIBitmap(hdc,
4179 GlobalUnlock(hPackedDIB);
4181 TRACE("CreateDIBitmap returned %x\n", hBmp);
4183 /* Retrieve the internal Pixmap from the DDB */
4185 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4187 pixmap = (Pixmap)pBmp->physBitmap;
4188 /* clear the physBitmap so that we can steal its pixmap */
4189 pBmp->physBitmap = NULL;
4192 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4193 GDI_ReleaseObj( hBmp );
4196 TRACE("\tReturning Pixmap %ld\n", pixmap);