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 bitmapDepthTable[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
36 static int ximageDepthTable[] = { 0, 0, 0, 0, 0, 0, 0 };
38 static int XShmErrorFlag = 0;
40 /* This structure holds the arguments for DIB_SetImageBits() */
46 PALETTEENTRY *palentry;
67 } X11DRV_DIB_IMAGEBITS_DESCR;
69 /***********************************************************************
72 BOOL X11DRV_DIB_Init(void)
77 for( i = 0; bitmapDepthTable[i]; i++ )
79 testimage = TSXCreateImage(display, X11DRV_GetVisual(),
80 bitmapDepthTable[i], ZPixmap, 0, NULL, 1, 1, 32, 20 );
81 if( testimage ) ximageDepthTable[i] = testimage->bits_per_pixel;
83 TSXDestroyImage(testimage);
89 /***********************************************************************
90 * X11DRV_DIB_GetXImageWidthBytes
92 * Return the width of an X image in bytes
94 int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
98 if (!ximageDepthTable[0]) {
101 for( i = 0; bitmapDepthTable[i] ; i++ )
102 if( bitmapDepthTable[i] == depth )
103 return (4 * ((width * ximageDepthTable[i] + 31)/32));
105 WARN("(%d): Unsupported depth\n", depth );
109 /***********************************************************************
110 * X11DRV_DIB_GenColorMap
112 * Fills the color map of a bitmap palette. Should not be called
113 * for a >8-bit deep bitmap.
115 int *X11DRV_DIB_GenColorMap( DC *dc, int *colorMapping,
116 WORD coloruse, WORD depth, BOOL quads,
117 const void *colorPtr, int start, int end )
121 if (coloruse == DIB_RGB_COLORS)
125 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
127 if (depth == 1) /* Monochrome */
128 for (i = start; i < end; i++, rgb++)
129 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
130 rgb->rgbBlue > 255*3/2);
132 for (i = start; i < end; i++, rgb++)
133 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbRed,
139 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
141 if (depth == 1) /* Monochrome */
142 for (i = start; i < end; i++, rgb++)
143 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
144 rgb->rgbtBlue > 255*3/2);
146 for (i = start; i < end; i++, rgb++)
147 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbtRed,
152 else /* DIB_PAL_COLORS */
155 WORD * index = (WORD *)colorPtr;
157 for (i = start; i < end; i++, index++)
158 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) );
160 for (i = start; i < end; i++)
161 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(i) );
168 /***********************************************************************
169 * X11DRV_DIB_BuildColorMap
171 * Build the color map from the bitmap palette. Should not be called
172 * for a >8-bit deep bitmap.
174 int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth,
175 const BITMAPINFO *info, int *nColors )
179 const void *colorPtr;
182 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
184 colors = info->bmiHeader.biClrUsed;
185 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
186 colorPtr = info->bmiColors;
188 else /* assume BITMAPCOREINFO */
190 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
191 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
196 ERR("called with >256 colors!\n");
200 /* just so CopyDIBSection doesn't have to create an identity palette */
201 if (coloruse == (WORD)-1) colorPtr = NULL;
203 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
204 colors * sizeof(int) )))
208 return X11DRV_DIB_GenColorMap( dc, colorMapping, coloruse, depth,
209 isInfo, colorPtr, 0, colors);
213 /***********************************************************************
214 * X11DRV_DIB_MapColor
216 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
220 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
223 for (color = 0; color < nPhysMap; color++)
224 if (physMap[color] == phys)
227 WARN("Strange color %08x\n", phys);
232 /*********************************************************************
233 * X11DRV_DIB_GetNearestIndex
235 * Helper for X11DRV_DIB_GetDIBits.
236 * Returns the nearest colour table index for a given RGB.
237 * Nearest is defined by minimizing the sum of the squares.
239 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
241 INT i, best = -1, diff, bestdiff = -1;
244 for(color = colormap, i = 0; i < numColors; color++, i++) {
245 diff = (r - color->rgbRed) * (r - color->rgbRed) +
246 (g - color->rgbGreen) * (g - color->rgbGreen) +
247 (b - color->rgbBlue) * (b - color->rgbBlue);
250 if(best == -1 || diff < bestdiff) {
258 /***********************************************************************
259 * X11DRV_DIB_SetImageBits_1_Line
261 * Handles a single line of 1 bit data.
263 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
264 XImage *bmpImage, int h, const BYTE *bits)
269 if((extra = (left & 7)) != 0) {
276 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
277 for (i = dstwidth/8, x = left; i > 0; i--)
280 XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
281 XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
282 XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
283 XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
284 XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
285 XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
286 XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
287 XPutPixel( bmpImage, x++, h, colors[pix & 1] );
292 case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
293 case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
294 case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
295 case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
296 case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
297 case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
298 case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
302 /***********************************************************************
303 * X11DRV_DIB_SetImageBits_1
305 * SetDIBits for a 1-bit deep DIB.
307 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
308 DWORD srcwidth, DWORD dstwidth, int left,
309 int *colors, XImage *bmpImage, DWORD linebytes)
314 for (h = lines-1; h >=0; h--) {
315 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
317 srcbits += linebytes;
321 for (h = 0; h < lines; h++) {
322 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
324 srcbits += linebytes;
329 /***********************************************************************
330 * X11DRV_DIB_GetImageBits_1
332 * GetDIBits for a 1-bit deep DIB.
334 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
335 DWORD dstwidth, DWORD srcwidth,
336 RGBQUAD *colors, PALETTEENTRY *srccolors,
337 XImage *bmpImage, DWORD linebytes )
345 dstbits = dstbits + linebytes * (lines - 1);
346 linebytes = -linebytes;
351 switch(bmpImage->depth) {
354 /* ==== monochrome bitmap to monochrome dib ==== */
356 /* ==== 4 colormap bitmap to monochrome dib ==== */
357 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
361 for (h = lines - 1; h >= 0; h--) {
362 for (x = 0; x < dstwidth; x++) {
363 val = srccolors[XGetPixel(bmpImage, x, h)];
364 if (!(x&7)) *bits = 0;
365 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2,
368 val.peBlue) << (7 - (x & 7)));
369 if ((x&7)==7) bits++;
371 bits = (dstbits += linebytes);
374 else goto notsupported;
379 /* ==== 8 colormap bitmap to monochrome dib ==== */
380 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
385 for( h = lines- 1; h >= 0; h-- ) {
386 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
387 for( x = 0; x < dstwidth; x++ ) {
388 if (!(x&7)) *bits = 0;
389 val = srccolors[(int)*srcpixel++];
390 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 2,
393 val.peBlue) << (7-(x&7)) );
394 if ((x&7)==7) bits++;
396 bits = (dstbits += linebytes);
399 else goto notsupported;
408 /* ==== 555 BGR bitmap to monochrome dib ==== */
409 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
411 for( h = lines - 1; h >= 0; h--) {
412 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
413 for( x = 0; x < dstwidth; x++) {
414 if (!(x&7)) *bits = 0;
416 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
417 ((val >> 7) & 0xf8) |
419 ((val >> 2) & 0xf8) |
421 ((val << 3) & 0xf8) |
422 ((val >> 2) & 0x7) ) << (7-(x&7)) );
423 if ((x&7)==7) bits++;
425 bits = (dstbits += linebytes);
428 /* ==== 555 RGB bitmap to monochrome dib ==== */
429 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
431 for( h = lines - 1; h >= 0; h--)
433 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
434 for( x = 0; x < dstwidth; x++) {
435 if (!(x&1)) *bits = 0;
437 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
438 ((val << 3) & 0xf8) |
440 ((val >> 2) & 0xf8) |
442 ((val >> 7) & 0xf8) |
443 ((val >> 12) & 0x7) ) << (7-(x&7)) );
444 if ((x&7)==7) bits++;
446 bits = (dstbits += linebytes);
449 else goto notsupported;
458 /* ==== 565 BGR bitmap to monochrome dib ==== */
459 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
461 for( h = lines - 1; h >= 0; h--)
463 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
464 for( x = 0; x < dstwidth; x++) {
465 if (!(x&7)) *bits = 0;
467 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
468 ((val >> 8) & 0xf8) |
470 ((val >> 3) & 0xfc) |
472 ((val << 3) & 0xf8) |
473 ((val >> 2) & 0x7) ) << (7-(x&7)) );
474 if ((x&7)==7) bits++;
476 bits = (dstbits += linebytes);
479 /* ==== 565 RGB bitmap to monochrome dib ==== */
480 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
482 for( h = lines - 1; h >= 0; h--)
484 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
485 for( x = 0; x < dstwidth; x++) {
486 if (!(x&7)) *bits = 0;
488 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
489 ((val << 3) & 0xf8) |
491 ((val >> 3) & 0xfc) |
493 ((val >> 8) & 0xf8) |
494 ((val >> 13) & 0x7) ) << (7-(x&7)) );
495 if ((x&7)==7) bits++;
497 bits = (dstbits += linebytes);
500 else goto notsupported;
509 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
510 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
512 for (h = lines - 1; h >= 0; h--)
514 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
515 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
516 if (!(x&7)) *bits = 0;
517 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[2] , srcpixel[1], srcpixel[0]) << (7-(x&7)) );
518 if ((x&7)==7) bits++;
520 bits = (dstbits += linebytes);
523 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
524 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
526 for (h = lines - 1; h >= 0; h--)
528 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
529 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
530 if (!(x & 7)) *bits = 0;
531 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[0] , srcpixel[1], srcpixel[2]) << (7-(x&7)) );
532 if ((x & 7) == 7) bits++;
534 bits = (dstbits += linebytes);
537 else goto notsupported;
541 default: /* ? bit bmp -> monochrome DIB */
544 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
546 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
547 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
548 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
550 for( h = lines - 1; h >= 0; h-- ) {
551 for( x = 0; x < dstwidth; x++ ) {
552 if (!(x&7)) *bits = 0;
553 *bits |= (XGetPixel( bmpImage, x, h) >= white)
555 if ((x&7)==7) bits++;
557 bits = (dstbits += linebytes);
564 /***********************************************************************
565 * X11DRV_DIB_SetImageBits_4
567 * SetDIBits for a 4-bit deep DIB.
569 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
570 DWORD srcwidth, DWORD dstwidth, int left,
571 int *colors, XImage *bmpImage, DWORD linebytes)
575 const BYTE *bits = srcbits + (left >> 1);
583 for (h = lines-1; h >= 0; h--) {
584 for (i = dstwidth/2, x = left; i > 0; i--) {
586 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
587 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
589 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
590 srcbits += linebytes;
591 bits = srcbits + (left >> 1);
595 for (h = 0; h < lines; h++) {
596 for (i = dstwidth/2, x = left; i > 0; i--) {
598 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
599 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
601 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
602 srcbits += linebytes;
603 bits = srcbits + (left >> 1);
610 /***********************************************************************
611 * X11DRV_DIB_GetImageBits_4
613 * GetDIBits for a 4-bit deep DIB.
615 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
616 DWORD srcwidth, DWORD dstwidth,
617 RGBQUAD *colors, PALETTEENTRY *srccolors,
618 XImage *bmpImage, DWORD linebytes )
628 dstbits = dstbits + ( linebytes * (lines-1) );
629 linebytes = -linebytes;
634 switch(bmpImage->depth) {
637 /* ==== monochrome bitmap to 4 colormap dib ==== */
639 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
640 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
644 for (h = lines-1; h >= 0; h--) {
645 for (x = 0; x < dstwidth; x++) {
646 if (!(x&1)) *bits = 0;
647 val = srccolors[XGetPixel(bmpImage, x, h)];
648 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 16,
651 val.peBlue) << (4-((x&1)<<2)));
652 if ((x&1)==1) bits++;
654 bits = (dstbits += linebytes);
657 else goto notsupported;
662 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
663 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
667 for( h = lines - 1; h >= 0; h-- ) {
668 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
669 for( x = 0; x < dstwidth; x++ ) {
670 if (!(x&1)) *bits = 0;
671 val = srccolors[(int)*srcpixel++];
672 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 16,
675 val.peBlue) << (4*(1-(x&1))) );
676 if ((x&1)==1) bits++;
678 bits = (dstbits += linebytes);
681 else goto notsupported;
690 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
691 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
693 for( h = lines - 1; h >= 0; h--) {
694 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
695 for( x = 0; x < dstwidth; x++) {
696 if (!(x&1)) *bits = 0;
698 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
699 ((val >> 7) & 0xf8) |
701 ((val >> 2) & 0xf8) |
703 ((val << 3) & 0xf8) |
704 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
705 if ((x&1)==1) bits++;
707 bits = (dstbits += linebytes);
710 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
711 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
713 for( h = lines - 1; h >= 0; h--)
715 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
716 for( x = 0; x < dstwidth; x++) {
717 if (!(x&1)) *bits = 0;
719 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
720 ((val << 3) & 0xf8) |
722 ((val >> 2) & 0xfc) |
724 ((val >> 7) & 0xf8) |
725 ((val >> 12) & 0x7) ) << ((1-(x&1))<<2) );
726 if ((x&1)==1) bits++;
728 bits = (dstbits += linebytes);
731 else goto notsupported;
740 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
741 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
743 for( h = lines - 1; h >= 0; h--)
745 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
746 for( x = 0; x < dstwidth; x++) {
747 if (!(x&1)) *bits = 0;
749 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
750 ((val >> 8) & 0xf8) |
752 ((val >> 3) & 0xfc) |
754 ((val << 3) & 0xf8) |
755 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
756 if ((x&1)==1) bits++;
758 bits = (dstbits += linebytes);
761 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
762 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
764 for( h = lines - 1; h >= 0; h--)
766 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
767 for( x = 0; x < dstwidth; x++) {
768 if (!(x&1)) *bits = 0;
770 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
771 ((val << 3) & 0xf8) |
773 ((val >> 3) & 0xfc) |
775 ((val >> 8) & 0xf8) |
776 ((val >> 13) & 0x7) ) << ((1-(x&1))<<2) );
777 if ((x&1)==1) bits++;
779 bits = (dstbits += linebytes);
782 else goto notsupported;
791 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
792 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
794 for (h = lines - 1; h >= 0; h--)
796 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
797 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
798 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[2] , srcpixel[1], srcpixel[0]) << 4) |
799 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[6] , srcpixel[5], srcpixel[4]);
800 bits = (dstbits += linebytes);
803 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
804 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
806 for (h = lines - 1; h >= 0; h--)
808 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
809 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
810 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[0] , srcpixel[1], srcpixel[2]) << 4) |
811 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[4] , srcpixel[5], srcpixel[6]);
812 bits = (dstbits += linebytes);
815 else goto notsupported;
819 default: /* ? bit bmp -> 4 bit DIB */
821 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
822 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
823 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
824 for (h = lines-1; h >= 0; h--) {
825 for (x = 0; x < dstwidth/2; x++) {
826 *bits++ = (X11DRV_DIB_MapColor((int *)colors, 16,
827 XGetPixel( bmpImage, x++, h ), 0) << 4)
828 | (X11DRV_DIB_MapColor((int *)colors, 16,
829 XGetPixel( bmpImage, x++, h ), 0) & 0x0f);
832 *bits = (X11DRV_DIB_MapColor((int *)colors, 16,
833 XGetPixel( bmpImage, x++, h ), 0) << 4);
834 bits = (dstbits += linebytes);
840 /***********************************************************************
841 * X11DRV_DIB_SetImageBits_RLE4
843 * SetDIBits for a 4-bit deep compressed DIB.
845 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
846 DWORD width, DWORD dstwidth,
847 int left, int *colors,
850 int x = 0, c, length;
851 const BYTE *begin = bits;
855 while ((int)lines >= 0) {
857 if (length) { /* encoded */
865 XPutPixel(bmpImage, x++, lines, colors[c >>4]);
873 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
884 case 1: /* eopicture */
890 FIXME_(x11drv)("x-delta is too large?\n");
896 default: /* absolute */
904 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
912 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
915 if ((bits - begin) & 1)
924 /***********************************************************************
925 * X11DRV_DIB_SetImageBits_8
927 * SetDIBits for an 8-bit deep DIB.
929 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
930 DWORD srcwidth, DWORD dstwidth, int left,
931 const int *colors, XImage *bmpImage,
943 srcbits = srcbits + ( linebytes * (lines-1) );
944 linebytes = -linebytes;
947 bits = srcbits + left;
949 switch (bmpImage->depth) {
952 #if defined(__i386__) && defined(__GNUC__)
953 /* Some X servers might have 32 bit/ 16bit deep pixel */
954 if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 16))
956 for (h = lines ; h--; ) {
957 int _cl1,_cl2; /* temp outputs for asm below */
958 /* Borrowed from DirectDraw */
959 __asm__ __volatile__(
964 " movw (%%edx,%%eax,4),%%ax\n"
968 :"=S" (bits), "=D" (_cl1), "=c" (_cl2)
970 "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*2),
973 :"eax", "cc", "memory"
975 bits = (srcbits += linebytes) + left;
982 #if defined(__i386__) && defined(__GNUC__)
983 if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 32))
985 for (h = lines ; h--; ) {
986 int _cl1,_cl2; /* temp outputs for asm below */
987 /* Borrowed from DirectDraw */
988 __asm__ __volatile__(
993 " movl (%%edx,%%eax,4),%%eax\n"
997 :"=S" (bits), "=D" (_cl1), "=c" (_cl2)
999 "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*4),
1000 "c" (dstwidth-left),
1002 :"eax", "cc", "memory"
1004 bits = (srcbits += linebytes) + left;
1011 break; /* use slow generic case below */
1014 for (h = lines - 1; h >= 0; h--) {
1015 for (x = left; x < dstwidth; x++, bits++) {
1016 color = colors[*bits];
1017 XPutPixel( bmpImage, x, h, colors[*bits] );
1019 bits = (srcbits += linebytes) + left;
1023 /***********************************************************************
1024 * X11DRV_DIB_GetImageBits_8
1026 * GetDIBits for an 8-bit deep DIB.
1028 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
1029 DWORD srcwidth, DWORD dstwidth,
1030 RGBQUAD *colors, PALETTEENTRY *srccolors,
1031 XImage *bmpImage, DWORD linebytes )
1040 dstbits = dstbits + ( linebytes * (lines-1) );
1041 linebytes = -linebytes;
1048 This condition is true when GetImageBits has been called by UpdateDIBSection.
1049 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
1050 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
1052 if (!srccolors) goto updatesection;
1054 switch(bmpImage->depth) {
1057 /* ==== monochrome bitmap to 8 colormap dib ==== */
1059 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
1060 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1064 for (h = lines - 1; h >= 0; h--) {
1065 for (x = 0; x < dstwidth; x++) {
1066 val = srccolors[XGetPixel(bmpImage, x, h)];
1067 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1068 val.peGreen, val.peBlue);
1070 bits = (dstbits += linebytes);
1073 else goto notsupported;
1078 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
1079 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1084 for (h = lines - 1; h >= 0; h--) {
1085 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1086 for (x = 0; x < dstwidth; x++) {
1087 val = srccolors[(int)*srcpixel++];
1088 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1089 val.peGreen, val.peBlue);
1091 bits = (dstbits += linebytes);
1094 else goto notsupported;
1103 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1104 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
1106 for( h = lines - 1; h >= 0; h--)
1108 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1109 for( x = 0; x < dstwidth; x++ )
1112 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1113 ((val >> 7) & 0xf8) |
1114 ((val >> 12) & 0x7),
1115 ((val >> 2) & 0xf8) |
1117 ((val << 3) & 0xf8) |
1118 ((val >> 2) & 0x7) );
1120 bits = (dstbits += linebytes);
1123 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1124 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
1126 for( h = lines - 1; h >= 0; h--)
1128 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1129 for( x = 0; x < dstwidth; x++ )
1132 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1133 ((val << 3) & 0xf8) |
1135 ((val >> 2) & 0xf8) |
1137 ((val >> 7) & 0xf8) |
1138 ((val >> 12) & 0x7) );
1140 bits = (dstbits += linebytes);
1143 else goto notsupported;
1152 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1153 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
1155 for( h = lines - 1; h >= 0; h--)
1157 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1158 for( x = 0; x < dstwidth; x++ )
1161 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1162 ((val >> 8) & 0xf8) |
1163 ((val >> 13) & 0x7),
1164 ((val >> 3) & 0xfc) |
1166 ((val << 3) & 0xf8) |
1167 ((val >> 2) & 0x7) );
1169 bits = (dstbits += linebytes);
1172 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1173 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
1175 for( h = lines - 1; h >= 0; h--)
1177 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1178 for( x = 0; x < dstwidth; x++ )
1181 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1182 ((val << 3) & 0xf8) |
1184 ((val >> 3) & 0x00fc) |
1186 ((val >> 8) & 0x00f8) |
1187 ((val >> 13) & 0x7) );
1189 bits = (dstbits += linebytes);
1192 else goto notsupported;
1201 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1202 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1204 for (h = lines - 1; h >= 0; h--)
1206 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1207 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1208 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1209 srcpixel[2] , srcpixel[1], *srcpixel);
1210 bits = (dstbits += linebytes);
1213 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1214 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1216 for (h = lines - 1; h >= 0; h--)
1218 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1219 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1220 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1221 *srcpixel, srcpixel[1], srcpixel[2]);
1222 bits = (dstbits += linebytes);
1226 else goto notsupported;
1230 default: /* ? bit bmp -> 8 bit DIB */
1232 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1233 bmpImage->depth, (int)bmpImage->red_mask,
1234 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1236 for (h = lines - 1; h >= 0; h--) {
1237 for (x = 0; x < dstwidth; x++, bits++) {
1238 *bits = X11DRV_DIB_MapColor((int *)colors, 256,
1239 XGetPixel( bmpImage, x, h ), *bits);
1241 bits = (dstbits += linebytes);
1247 /***********************************************************************
1248 * X11DRV_DIB_SetImageBits_RLE8
1250 * SetDIBits for an 8-bit deep compressed DIB.
1252 * This function rewritten 941113 by James Youngman. WINE blew out when I
1253 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1255 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1256 * 'End of bitmap' escape code. This code is very much laxer in what it
1257 * allows to end the expansion. Possibly too lax. See the note by
1258 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1259 * bitmap should end with RleEnd, but on the other hand, software exists
1260 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1263 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1264 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1268 enum Rle8_EscapeCodes
1271 * Apologies for polluting your file's namespace...
1273 RleEol = 0, /* End of line */
1274 RleEnd = 1, /* End of bitmap */
1275 RleDelta = 2 /* Delta */
1278 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1279 DWORD width, DWORD dstwidth,
1280 int left, int *colors,
1283 int x; /* X-positon on each line. Increases. */
1284 int line; /* Line #. Starts at lines-1, decreases */
1285 const BYTE *pIn = bits; /* Pointer to current position in bits */
1286 BYTE length; /* The length pf a run */
1287 BYTE color_index; /* index into colors[] as read from bits */
1288 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
1289 int color; /* value of colour[color_index] */
1291 if (lines == 0) /* Let's hope this doesn't happen. */
1295 * Note that the bitmap data is stored by Windows starting at the
1296 * bottom line of the bitmap and going upwards. Within each line,
1297 * the data is stored left-to-right. That's the reason why line
1298 * goes from lines-1 to 0. [JAY]
1308 * If the length byte is not zero (which is the escape value),
1309 * We have a run of length pixels all the same colour. The colour
1310 * index is stored next.
1312 * If the length byte is zero, we need to read the next byte to
1313 * know what to do. [JAY]
1318 * [Run-Length] Encoded mode
1320 color_index = (*pIn++); /* Get the colour index. */
1321 color = colors[color_index];
1330 XPutPixel(bmpImage, x++, line, color);
1336 * Escape codes (may be an absolute sequence though)
1338 escape_code = (*pIn++);
1341 case RleEol: /* =0, end of line */
1348 case RleEnd: /* =1, end of bitmap */
1351 * Not all RLE8 bitmaps end with this
1352 * code. For example, Paint Shop Pro
1353 * produces some that don't. That's (I think)
1354 * what caused the previous implementation to
1357 line=-1; /* Cause exit from do loop. */
1361 case RleDelta: /* =2, a delta */
1364 * Note that deltaing to line 0
1365 * will cause an exit from the loop,
1366 * which may not be what is intended.
1367 * The fact that there is a delta in the bits
1368 * almost certainly implies that there is data
1369 * to follow. You may feel that we should
1370 * jump to the top of the loop to avoid exiting
1373 * TODO: Decide what to do here in that case. [JAY]
1379 TRACE("Delta to last line of bitmap "
1380 "(wrongly?) causes loop exit\n");
1385 default: /* >2, switch to absolute mode */
1390 length = escape_code;
1393 color_index = (*pIn++);
1399 XPutPixel(bmpImage, x++, line,
1400 colors[color_index]);
1404 * If you think for a moment you'll realise that the
1405 * only time we could ever possibly read an odd
1406 * number of bytes is when there is a 0x00 (escape),
1407 * a value >0x02 (absolute mode) and then an odd-
1408 * length run. Therefore this is the only place we
1409 * need to worry about it. Everywhere else the
1410 * bytes are always read in pairs. [JAY]
1412 if (escape_code & 1)
1413 pIn++; /* Throw away the pad byte. */
1416 } /* switch (escape_code) : Escape sequence */
1417 } /* process either an encoded sequence or an escape sequence */
1419 /* We expect to come here more than once per line. */
1420 } while (line >= 0); /* Do this until the bitmap is filled */
1423 * Everybody comes here at the end.
1424 * Check how we exited the loop and print a message if it's a bit odd.
1427 if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
1429 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1430 "bytes were: %02X %02X.\n", (int)*(pIn-2),(int)*(pIn-1));
1435 /***********************************************************************
1436 * X11DRV_DIB_SetImageBits_16
1438 * SetDIBits for a 16-bit deep DIB.
1440 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1441 DWORD srcwidth, DWORD dstwidth, int left,
1442 DC *dc, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1443 XImage *bmpImage, DWORD linebytes )
1451 srcbits = srcbits + ( linebytes * (lines-1));
1452 linebytes = -linebytes;
1455 switch ( bmpImage->depth )
1458 /* using same format as XImage */
1459 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1460 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1461 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1462 else /* We need to do a conversion from a 565 dib */
1464 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1466 int div = dstwidth % 2;
1468 for (h = lines - 1; h >= 0; h--) {
1469 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1470 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1472 *dstpixel++ = ((val >> 1) & 0x7fe07fe0) | (val & 0x001f001f); /* Red & Green & Blue */
1474 if (div != 0) /* Odd width? */
1475 *dstpixel = ((*(WORD *)ptr >> 1) & 0x7fe0) | (*(WORD *)ptr & 0x001f);
1476 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1482 /* using same format as XImage */
1483 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1484 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1485 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1486 else /* We need to do a conversion from a 555 dib */
1488 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1490 int div = dstwidth % 2;
1492 for (h = lines - 1; h >= 0; h--) {
1493 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1494 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1496 *dstpixel++ = ((val << 1) & 0xffc0ffc0) | ((val >> 4) & 0x00200020) | /* Red & Green */
1497 (val & 0x001f001f); /* Blue */
1499 if (div != 0) /* Odd width? */
1500 *dstpixel = ((*(WORD *)ptr << 1) & 0xffc0) | ((*(WORD *)ptr >> 4) & 0x0020)
1501 | (*(WORD *)ptr & 0x001f);
1502 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1511 LPWORD ptr = (LPWORD)srcbits + left;
1514 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1516 if ((rSrc == 0xF800) && (gSrc == 0x07E0) && (bSrc == 0x001F)) {
1517 /* ==== 555 RGB dib to 24/32 RGB bitmap ==== */
1518 for (h = lines - 1; h >= 0; h--) {
1519 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1520 for (x = 0; x < dstwidth; x++) {
1522 *dstpixel++ = ((val << 8) & 0xF80000) | /* Red */
1523 ((val << 5) & 0x00FC00) | /* Green */
1524 ((val << 3) & 0x0000FF); /* Blue */
1526 ptr = (LPWORD)(srcbits += linebytes) + left;
1529 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1530 for (h = lines - 1; h >= 0; h--) {
1531 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1532 for (x = 0; x < dstwidth; x++) {
1535 *dstpixel++ = ((val << 9) & 0xf80000) | ((val << 4) & 0x070000) | /* Red */
1536 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1537 ((val << 3) & 0x0000f8) | ((val >> 2) & 0x000007); /* Blue */
1539 ptr = (LPWORD)(srcbits += linebytes) + left;
1543 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1544 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1546 for (h = lines - 1; h >= 0; h--) {
1547 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1548 for (x = 0; x < dstwidth; x++) {
1551 *dstpixel++ = ((val >> 7) & 0x0000f8) | ((val >> 12) & 0x000007) | /* Red */
1552 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1553 ((val << 19) & 0xf80000) | ((val >> 14) & 0x070000); /* Blue */
1555 ptr = (LPWORD)(srcbits += linebytes) + left;
1566 LPWORD ptr = (LPWORD)srcbits + left;
1570 /* Set color scaling values */
1571 if ( rSrc == 0x7c00 ) { sc1 = 7; sc2 = 2; } /* 555 dib */
1572 else { sc1 = 8; sc2 = 3; } /* 565 dib */
1574 for (h = lines - 1; h >= 0; h--) {
1575 for (x = left; x < dstwidth+left; x++) {
1577 XPutPixel( bmpImage, x, h,
1578 X11DRV_PALETTE_ToPhysical(dc, RGB(((val & rSrc) >> sc1), /* Red */
1579 ((val & gSrc) >> sc2), /* Green */
1580 ((val & bSrc) << 3)))); /* Blue */
1582 ptr = (LPWORD) (srcbits += linebytes) + left;
1588 FIXME("16 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
1595 /***********************************************************************
1596 * X11DRV_DIB_GetImageBits_16
1598 * GetDIBits for an 16-bit deep DIB.
1600 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
1601 DWORD dstwidth, DWORD srcwidth,
1602 PALETTEENTRY *srccolors,
1603 DWORD rDst, DWORD gDst, DWORD bDst,
1604 XImage *bmpImage, DWORD dibpitch )
1609 DWORD linebytes = dibpitch;
1614 dstbits = dstbits + ( linebytes * (lines-1));
1615 linebytes = -linebytes;
1618 /* Set color scaling values */
1619 if ( rDst == 0x7c00 ) { rsc = 7; gsc = 2; } /* 555 dib */
1620 else { rsc = 8; gsc = 3; } /* 565 dib */
1622 switch ( bmpImage->depth )
1625 /* using same format as XImage */
1626 if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1627 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1628 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1629 /* reversed format (BGR <=> RGB) */
1630 else if (rDst == bmpImage->blue_mask && bDst == bmpImage->red_mask)
1632 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1634 int div = srcwidth % 2;
1636 for (h = lines - 1; h >= 0; h--) {
1637 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1638 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1640 *ptr++ = ((val << 10) & 0xf800f800) | (val & 0x03e003e0) | /* Red & Green */
1641 ((val >> 10) & 0x001f001f); /* Blue */
1643 if (div != 0) /* Odd width? */
1644 *ptr = ((*(WORD *)srcpixel << 1) & 0xffc0) | ((*(WORD *)srcpixel >> 4) & 0x0020) |
1645 (*(WORD *)srcpixel & 0x001f);
1646 ptr = (LPDWORD)(dstbits += linebytes);
1649 else goto notsupported;
1655 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1657 int div = srcwidth % 2;
1659 /* using same format as XImage */
1660 if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1661 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1662 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1663 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1664 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f &&
1665 rDst == 0x7c00 && bDst == 0x001f)
1667 for (h = lines - 1; h >= 0; h--) {
1668 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1669 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1671 *ptr++ = ((val >> 1) & 0x7fe07fe0) | /* Red & Green */
1672 (val & 0x001f001f); /* Blue */
1674 if (div != 0) /* Odd width? */
1675 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1676 ptr = (LPDWORD) (dstbits += linebytes);
1679 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1680 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800 &&
1681 rDst == 0x7c00 && bDst == 0x001f)
1683 for (h = lines - 1; h >= 0; h--) {
1684 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1685 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1687 *ptr++ = ((val << 10) & 0x7c007c00) | ((val >> 1) & 0x03e003e0) | /* Red & Green */
1688 ((val >> 11) & 0x001f001f); /* Blue */
1690 if (div != 0) /* Odd width? */
1691 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1692 ptr = (LPDWORD) (dstbits += linebytes);
1695 else goto notsupported;
1703 LPWORD ptr = (LPWORD)dstbits;
1706 /* ==== 24/32 BGR bitmap ==== */
1707 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1709 int rsc2 = 16-rsc, gsc2 = 8-gsc;
1710 for (h = lines - 1; h >= 0; h--) {
1711 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1712 for (x = 0; x < srcwidth; x++, ptr++) {
1714 *ptr = ((val >> rsc2) & rDst) |
1715 ((val >> gsc2) & gDst) |
1716 ((val >> 3) & bDst);
1718 ptr = (LPWORD)(dstbits += linebytes);
1721 /* ==== 24/32 RGB bitmap ==== */
1722 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1725 for (h = lines - 1; h >= 0; h--) {
1726 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1727 for (x = 0; x < srcwidth; x++, ptr++) {
1729 *ptr = ((val << rsc) & rDst) |
1730 ((val >> gsc2) & gDst) |
1731 ((val >> 19) & bDst);
1733 ptr = (LPWORD) (dstbits += linebytes);
1736 else goto notsupported;
1741 /* ==== monochrome bitmap ==== */
1743 /* ==== 4 colormap bitmap ==== */
1744 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1746 LPWORD ptr = (LPWORD)dstbits;
1749 for (h = lines - 1; h >= 0; h--) {
1750 for (x = 0; x < dstwidth; x++) {
1751 val = srccolors[XGetPixel(bmpImage, x, h)];
1752 *ptr++ = ((val.peRed << rsc) & rDst) |
1753 ((val.peGreen << gsc) & gDst) |
1754 ((val.peBlue >> 3) & bDst);
1756 ptr = (LPWORD)(dstbits += linebytes);
1759 else goto notsupported;
1764 /* ==== 8 colormap bitmap ==== */
1765 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1767 LPWORD ptr = (LPWORD)dstbits;
1771 for (h = lines - 1; h >= 0; h--) {
1772 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1773 for (x = 0; x < dstwidth; x++) {
1774 val = srccolors[(int)*srcpixel++];
1775 *ptr++ = ((val.peRed << rsc) & rDst) |
1776 ((val.peGreen << gsc) & gDst) |
1777 ((val.peBlue >> 3) & bDst);
1779 ptr = (LPWORD)(dstbits += linebytes);
1782 else goto notsupported;
1790 LPWORD ptr = (LPWORD)dstbits;
1792 FIXME("from %d bit bitmap with mask R,G,B %lx,%lx,%lx to 16 bit DIB %lx,%lx,%lx\n",
1793 bmpImage->depth, bmpImage->red_mask,
1794 bmpImage->green_mask, bmpImage->blue_mask,
1797 for (h = lines - 1; h >= 0; h--)
1799 for (x = 0; x < dstwidth; x++, ptr++)
1801 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
1802 r = (BYTE) GetRValue(pixel);
1803 g = (BYTE) GetGValue(pixel);
1804 b = (BYTE) GetBValue(pixel);
1805 *ptr = ( ((r << rsc) & rDst) | ((g << gsc) & gDst) | ((b >> 3) & bDst) );
1807 ptr = (LPWORD) (dstbits += linebytes);
1815 /***********************************************************************
1816 * X11DRV_DIB_SetImageBits_24
1818 * SetDIBits for a 24-bit deep DIB.
1820 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
1821 DWORD srcwidth, DWORD dstwidth, int left,
1822 DC *dc, XImage *bmpImage, DWORD linebytes )
1830 srcbits = srcbits + linebytes * (lines - 1);
1831 linebytes = -linebytes;
1834 switch ( bmpImage->depth )
1838 if (bmpImage->bits_per_pixel == 24) {
1839 int dstlinebytes = linebytes;
1841 BYTE *ptr = (BYTE *)(srcbits+left*3);
1843 if (dstlinebytes < 0 ) dstlinebytes = -dstlinebytes;
1844 dstpixel = bmpImage->data + lines*dstlinebytes + left*3;
1845 for(h = lines ; h-- ; ) {
1846 dstpixel-=dstlinebytes;
1847 memcpy(dstpixel,ptr,dstwidth*3);
1855 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 ) /* packed BGR to unpacked BGR */
1857 DWORD *dstpixel, val, buf;
1858 DWORD *ptr = (DWORD *)(srcbits + left*3);
1860 int div = dstwidth % 4;
1863 for(h = lines - 1; h >= 0; h--)
1865 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1867 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1869 *dstpixel++ = buf&0x00ffffff; /* b1, g1, r1 */
1870 val = (buf >> 24); /* b2 */
1872 *dstpixel++ = (val | (buf<<8)) &0x00ffffff; /* g2, r2 */
1873 val = (buf >> 16); /* b3, g3 */
1875 *dstpixel++ = (val | (buf<<16)) &0x00ffffff; /* r3 */
1876 *dstpixel++ = (buf >> 8); /* b4, g4, r4 */
1878 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1880 *dstpixel++ = *(DWORD*)bits & 0x00ffffff; /* b, g, r */
1882 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1885 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff ) /* packed BGR to unpacked RGB */
1887 DWORD *dstpixel, val, buf;
1888 DWORD *ptr = (DWORD *)(srcbits + left*3);
1890 int div = dstwidth % 4;
1893 for(h = lines - 1; h >= 0; h--)
1895 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1897 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1899 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b1, g1, r1 */
1900 val = ((buf&0xff000000)>>8); /* b2 */
1902 *dstpixel++ = val | ((buf&0xff)<<8) | ((buf&0xff00)>>8); /* g2, r2 */
1903 val = (buf&0xff0000) | ((buf&0xff000000)>>16); /* b3, g3 */
1905 *dstpixel++ = val | (buf&0xff); /* r3 */
1906 *dstpixel++ = ((buf&0xff00)<<8) | ((buf&0xff0000)>>8) | (buf>>24); /* b4, g4, r4 */
1908 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1910 buf = *(DWORD*)bits;
1911 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b, g, r */
1913 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1923 if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f ) /* BGR888 to RGB555 */
1925 DWORD *ptr = (DWORD *)(srcbits + left*3), val;
1928 int div = dstwidth % 4;
1931 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1932 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1933 for (x = 0; x < dstwidth/4; x++) {
1934 *dstpixel++ = (WORD)((((val = *ptr++) << 7) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 19) & 0x1f));
1935 *dstpixel++ = (WORD)(((val >> 17) & 0x7c00) | (((val = *ptr++) << 2) & 0x03e0) | ((val >> 11) & 0x1f));
1936 *dstpixel++ = (WORD)(((val >> 9) & 0x07c00) | ((val >> 22) & 0x03e0) | (((val = *ptr++) >> 3) & 0x1f));
1937 *dstpixel++ = (WORD)(((val >> 1) & 0x07c00) | ((val >> 14) & 0x03e0) | ((val >> 27) & 0x1f));
1939 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1940 *dstpixel++ = (((WORD)bits[0] << 7) & 0x07c00) |
1941 (((WORD)bits[1] << 2) & 0x03e0) |
1942 (((WORD)bits[2] >> 3) & 0x001f);
1943 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1946 else if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 ) /* BGR888 to BGR555 */
1948 DWORD *ptr = (DWORD *)(srcbits + left*3), val;
1951 int div = dstwidth % 4;
1954 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1955 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1956 for (x = 0; x < dstwidth/4; x++) {
1957 *dstpixel++ = (WORD)((((val = *ptr++) >> 3) & 0x1f) | ((val >> 6) & 0x03e0) | ((val >> 9) & 0x7c00));
1958 *dstpixel++ = (WORD)(((val >> 27) & 0x1f) | (((val = *ptr++) << 2) & 0x03e0) | ((val >> 1) & 0x7c00));
1959 *dstpixel++ = (WORD)(((val >> 19) & 0x1f) | ((val >> 22) & 0x03e0) | (((val = *ptr++) << 7) & 0x7c00));
1960 *dstpixel++ = (WORD)(((val >> 11) & 0x1f) | ((val >> 14) & 0x03e0) | ((val >> 17) & 0x7c00));
1962 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1963 *dstpixel++ = (((WORD)bits[2] << 7) & 0x07c00) |
1964 (((WORD)bits[1] << 2) & 0x03e0) |
1965 (((WORD)bits[0] >> 3) & 0x001f);
1966 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1976 DWORD *ptr = (DWORD *)(srcbits + left*3), val;
1979 int div = dstwidth % 4;
1982 if( bmpImage->blue_mask == 0x001f && bmpImage->red_mask == 0xf800 ) /* BGR888 to BGR565 */
1984 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1985 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1986 for (x = 0; x < dstwidth/4; x++) {
1987 *dstpixel++ = (WORD)((((val = *ptr++) >> 3) & 0x1f) | ((val >> 5) & 0x07e0) | ((val >> 8) & 0xf800));
1988 *dstpixel++ = (WORD)(((val >> 27) & 0x1f) | (((val = *ptr++) << 3) & 0x07e0) | ((val) & 0xf800));
1989 *dstpixel++ = (WORD)(((val >> 19) & 0x1f) | ((val >> 21) & 0x07e0) | (((val = *ptr++) << 8) & 0xf800));
1990 *dstpixel++ = (WORD)(((val >> 11) & 0x1f) | ((val >> 13) & 0x07e0) | ((val >> 16) & 0xf800));
1992 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
1993 *dstpixel++ = (((WORD)bits[2] << 8) & 0xf800) |
1994 (((WORD)bits[1] << 3) & 0x07e0) |
1995 (((WORD)bits[0] >> 3) & 0x001f);
1996 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1999 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x001f ) /* BGR888 to RGB565 */
2001 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
2002 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
2003 for (x = 0; x < dstwidth/4; x++) {
2004 *dstpixel++ = (WORD)((((val = *ptr++) << 8) & 0xf800) | ((val >> 5) & 0x07e0) | ((val >> 19) & 0x1f));
2005 *dstpixel++ = (WORD)(((val >> 16) & 0xf800) | (((val = *ptr++) << 3) & 0x07e0) | ((val >> 11) & 0x1f));
2006 *dstpixel++ = (WORD)(((val >> 8) & 0xf800) | ((val >> 21) & 0x07e0) | (((val = *ptr++) >> 3) & 0x1f));
2007 *dstpixel++ = (WORD)((val & 0xf800) | ((val >> 13) & 0x07e0) | ((val >> 27) & 0x1f));
2009 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
2010 *dstpixel++ = (((WORD)bits[0] << 8) & 0xf800) |
2011 (((WORD)bits[1] << 3) & 0x07e0) |
2012 (((WORD)bits[2] >> 3) & 0x001f);
2013 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
2025 LPBYTE bits = (LPBYTE)srcbits + left*3;
2027 for (h = lines - 1; h >= 0; h--) {
2028 for (x = left; x < dstwidth+left; x++, bits+=3)
2029 XPutPixel( bmpImage, x, h,
2030 X11DRV_PALETTE_ToPhysical(dc, RGB(bits[2], bits[1], bits[0])));
2031 bits = (LPBYTE)(srcbits += linebytes) + left * 3;
2038 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
2039 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
2040 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2046 /***********************************************************************
2047 * X11DRV_DIB_GetImageBits_24
2049 * GetDIBits for an 24-bit deep DIB.
2051 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
2052 DWORD dstwidth, DWORD srcwidth,
2053 PALETTEENTRY *srccolors,
2054 XImage *bmpImage, DWORD linebytes )
2062 dstbits = dstbits + ( linebytes * (lines-1) );
2063 linebytes = -linebytes;
2066 switch ( bmpImage->depth )
2070 if (bmpImage->bits_per_pixel == 24) {
2071 int tocopy = linebytes;
2073 BYTE *ptr = (LPBYTE)dstbits;
2075 if (tocopy < 0 ) tocopy = -tocopy;
2076 srcpixel = bmpImage->data + lines*tocopy;
2077 for(h = lines ; h-- ; ) {
2079 memcpy(ptr,srcpixel,tocopy);
2080 ptr = (LPBYTE)(dstbits+=linebytes);
2087 DWORD *srcpixel, buf;
2089 DWORD *ptr=(DWORD *)dstbits;
2090 int quotient = dstwidth / 4;
2091 int remainder = dstwidth % 4;
2094 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
2095 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 )
2097 for(h = lines - 1; h >= 0; h--)
2099 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2101 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
2102 buf = ((*srcpixel++)&0x00ffffff); /* b1, g1, r1*/
2103 *ptr++ = buf | ((*srcpixel)<<24); /* b2 */
2104 buf = ((*srcpixel++>>8)&0x0000ffff); /* g2, r2 */
2105 *ptr++ = buf | ((*srcpixel)<<16); /* b3, g3 */
2106 buf = ((*srcpixel++>>16)&0x000000ff); /* r3 */
2107 *ptr++ = buf | ((*srcpixel++)<<8); /* b4, g4, r4 */
2109 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2112 *(WORD*)bits = buf; /* b, g */
2113 *(bits+2) = buf>>16; /* r */
2115 ptr = (DWORD*)(dstbits+=linebytes);
2119 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
2120 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff )
2122 for(h = lines - 1; h >= 0; h--)
2124 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2126 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
2128 val = ((buf&0xff0000)>>16) | (buf&0xff00) | ((buf&0xff)<<16); /* b1, g1, r1 */
2130 *ptr++ = val | ((buf&0xff0000)<<8); /* b2 */
2131 val = ((buf&0xff00)>>8) | ((buf&0xff)<<8); /* g2, r2 */
2133 *ptr++ = val | (buf&0xff0000) | ((buf&0xff00)<<16); /* b3, g3 */
2134 val = (buf&0xff); /* r3 */
2136 *ptr++ = val | ((buf&0xff0000)>>8) | ((buf&0xff00)<<8) | (buf<<24); /* b4, g4, r4 */
2138 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2141 *(WORD*)bits = (buf&0xff00) | ((buf&0xff0000)>>16) ; /* b, g */
2142 *(bits+2) = buf; /* r */
2144 ptr = (DWORD*)(dstbits+=linebytes);
2147 else goto notsupported;
2154 LPBYTE bits = dstbits;
2157 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2158 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 )
2160 for (h = lines - 1; h >= 0; h--) {
2161 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2162 for (x = 0; x < srcwidth; x++, bits += 3) {
2164 bits[2] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2165 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2166 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2168 bits = (dstbits += linebytes);
2171 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2172 else if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f )
2174 for (h = lines - 1; h >= 0; h--) {
2175 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2176 for (x = 0; x < srcwidth; x++, bits += 3) {
2178 bits[0] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2179 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2180 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2182 bits = (dstbits += linebytes);
2185 else goto notsupported;
2192 LPBYTE bits = dstbits;
2195 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2196 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0xf800 )
2198 for (h = lines - 1; h >= 0; h--) {
2199 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2200 for (x = 0; x < srcwidth; x++, bits += 3) {
2202 bits[2] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2203 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2204 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2206 bits = (dstbits += linebytes);
2209 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2210 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x1f )
2212 for (h = lines - 1; h >= 0; h--) {
2213 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2214 for (x = 0; x < srcwidth; x++, bits += 3) {
2216 bits[0] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2217 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2218 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2220 bits = (dstbits += linebytes);
2223 else goto notsupported;
2228 /* ==== monochrome bitmap to 24 BGR dib ==== */
2230 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2231 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2233 LPBYTE bits = dstbits;
2236 for (h = lines - 1; h >= 0; h--) {
2237 for (x = 0; x < dstwidth; x++) {
2238 val = srccolors[XGetPixel(bmpImage, x, h)];
2239 *bits++ = val.peBlue;
2240 *bits++ = val.peGreen;
2241 *bits++ = val.peRed;
2243 bits = (dstbits += linebytes);
2246 else goto notsupported;
2251 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2252 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors)
2255 LPBYTE bits = dstbits;
2258 for (h = lines - 1; h >= 0; h--) {
2259 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2260 for (x = 0; x < dstwidth; x++ ) {
2261 val = srccolors[(int)*srcpixel++];
2262 *bits++ = val.peBlue; /*Blue*/
2263 *bits++ = val.peGreen; /*Green*/
2264 *bits++ = val.peRed; /*Red*/
2266 bits = (dstbits += linebytes);
2269 else goto notsupported;
2276 LPBYTE bits = dstbits;
2278 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2279 bmpImage->depth, (int)bmpImage->red_mask,
2280 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2281 for (h = lines - 1; h >= 0; h--)
2283 for (x = 0; x < dstwidth; x++, bits += 3)
2285 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2286 bits[0] = GetBValue(pixel);
2287 bits[1] = GetGValue(pixel);
2288 bits[2] = GetRValue(pixel);
2290 bits = (dstbits += linebytes);
2298 /***********************************************************************
2299 * X11DRV_DIB_SetImageBits_32
2301 * SetDIBits for a 32-bit deep DIB.
2303 static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
2304 DWORD srcwidth, DWORD dstwidth, int left,
2305 DC *dc, XImage *bmpImage,
2314 srcbits = srcbits + ( linebytes * (lines-1) );
2315 linebytes = -linebytes;
2318 ptr = (DWORD *) srcbits + left;
2320 switch ( bmpImage->depth )
2323 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2324 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) {
2325 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2326 memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2330 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2331 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
2335 for (h = lines - 1; h >= 0; h--) {
2336 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2337 for (x = 0; x < dstwidth; x++, ptr++) {
2338 *dstpixel++ = ((*ptr << 16) & 0xff0000) | (*ptr & 0xff00) | ((*ptr >> 16) & 0xff);
2340 ptr = (DWORD *) (srcbits += linebytes) + left;
2343 else goto notsupported;
2348 /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
2349 /* we need to check that source mask matches destination */
2350 if (bmpImage->bits_per_pixel == 32)
2352 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2353 memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2360 ptr = (DWORD *) srcbits + left;
2361 bptr = bmpImage->data;
2363 for (h = lines - 1; h >= 0; h--) {
2364 for (x = 0; x < dstwidth; x++) {
2365 /* *ptr is a 32bit value */
2366 /* bptr points to first of 3 bytes */
2367 *bptr++ = (*ptr >> 16) & 0xff;
2368 *bptr++ = (*ptr >> 8) & 0xff;
2369 *bptr++ = (*ptr ) & 0xff;
2372 ptr = (DWORD *) (srcbits += linebytes) + left;
2378 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2379 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f) {
2382 for (h = lines - 1; h >= 0; h--) {
2383 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2384 for (x = 0; x < dstwidth; x++, ptr++) {
2385 *dstpixel++ = (WORD) (((*ptr >> 9) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 3) & 0x001f));
2387 ptr = (DWORD *) (srcbits += linebytes) + left;
2390 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2391 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2395 for (h = lines - 1; h >= 0; h--) {
2396 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2397 for (x = 0; x < dstwidth; x++, ptr++) {
2398 *dstpixel++ = (WORD) (((*ptr << 7) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 19) & 0x001f));
2400 ptr = (DWORD *) (srcbits += linebytes) + left;
2403 else goto notsupported;
2408 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2409 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2413 for (h = lines - 1; h >= 0; h--) {
2414 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2415 for (x = 0; x < dstwidth; x++, ptr++) {
2416 *dstpixel++ = (WORD) (((*ptr >> 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 3) & 0x001f));
2418 ptr = (DWORD *) (srcbits += linebytes) + left;
2421 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2422 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
2426 for (h = lines - 1; h >= 0; h--) {
2427 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2428 for (x = 0; x < dstwidth; x++, ptr++) {
2429 *dstpixel++ = (WORD) (((*ptr << 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 19) & 0x001f));
2431 ptr = (DWORD *) (srcbits += linebytes) + left;
2434 else goto notsupported;
2442 LPBYTE bits = (LPBYTE)srcbits + left*4;
2444 for (h = lines - 1; h >= 0; h--) {
2445 for (x = left; x < dstwidth+left; x++, bits += 4)
2446 XPutPixel( bmpImage, x, h,
2447 X11DRV_PALETTE_ToPhysical(dc, RGB( bits[2], bits[1], *bits )));
2448 bits = (LPBYTE)(srcbits += linebytes) + left * 4;
2455 FIXME("32 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
2461 /***********************************************************************
2462 * X11DRV_DIB_GetImageBits_32
2464 * GetDIBits for an 32-bit deep DIB.
2466 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
2467 DWORD dstwidth, DWORD srcwidth,
2468 PALETTEENTRY *srccolors,
2469 XImage *bmpImage, DWORD linebytes )
2475 DWORD copybytes = srcwidth * 4;
2480 dstbits = dstbits + ( linebytes * (lines-1) );
2481 linebytes = -linebytes;
2486 switch ( bmpImage->depth )
2489 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2490 if ( bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff )
2491 for (h = lines - 1; h >= 0; h--, dstbits+=linebytes)
2492 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, copybytes );
2494 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2495 else if ( bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000 )
2499 for (h = lines - 1; h >= 0; h--) {
2500 srcbits = bmpImage->data + h * bmpImage->bytes_per_line;
2501 for (x = 0; x < dstwidth; x++, bits+=4, srcbits+=2) {
2502 *(bits + 2) = *srcbits++;
2503 *(bits + 1) = *srcbits++;
2506 bits = (dstbits += linebytes);
2509 else goto notsupported;
2513 /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */
2514 /* we need to check that source mask matches destination */
2520 srcpixel = (DWORD *) dstbits;
2521 bptr = bmpImage->data;
2523 for (h = lines - 1; h >= 0; h--) {
2524 for (x = 0; x < dstwidth; x++) {
2525 /* *srcpixel is a 32bit value */
2526 /* bptr points to first of 3 bytes */
2528 srcdata = srcdata << 8 | *bptr++;
2529 srcdata = srcdata << 8 | *bptr++;
2530 srcdata = srcdata << 8 | *bptr++;
2532 *srcpixel++ = srcdata;
2534 srcpixel = (DWORD *) (dstbits += linebytes);
2544 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2545 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
2547 for (h = lines - 1; h >= 0; h--) {
2548 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2549 for (x = 0; x < dstwidth; x++, bits+=2) {
2551 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2552 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2553 *bits = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2555 bits = (dstbits += linebytes);
2558 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2559 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2561 for (h = lines - 1; h >= 0; h--) {
2562 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2563 for (x = 0; x < dstwidth; x++, bits+=2) {
2565 *bits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));/*Blue*/
2566 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2567 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2569 bits = (dstbits += linebytes);
2572 else goto notsupported;
2581 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2582 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2584 for (h = lines - 1; h >= 0; h--) {
2585 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2586 for (x = 0; x < srcwidth; x++, bits+=2) {
2588 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2589 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2590 *bits = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2592 bits = (dstbits += linebytes);
2595 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2596 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2598 for (h = lines - 1; h >= 0; h--) {
2599 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2600 for (x = 0; x < srcwidth; x++, bits+=2) {
2602 *bits++ = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));/*Blue*/
2603 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2604 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2606 bits = (dstbits += linebytes);
2609 else goto notsupported;
2614 /* ==== monochrome bitmap to 32 BGR dib ==== */
2616 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2617 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2621 for (h = lines - 1; h >= 0; h--) {
2622 for (x = 0; x < dstwidth; x++) {
2623 val = srccolors[XGetPixel(bmpImage, x, h)];
2624 *bits++ = val.peBlue;
2625 *bits++ = val.peGreen;
2626 *bits++ = val.peRed;
2629 bits = (dstbits += linebytes);
2632 else goto notsupported;
2637 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2638 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2643 for (h = lines - 1; h >= 0; h--) {
2644 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2645 for (x = 0; x < dstwidth; x++) {
2646 val = srccolors[(int)*srcpixel++];
2647 *bits++ = val.peBlue; /*Blue*/
2648 *bits++ = val.peGreen; /*Green*/
2649 *bits++ = val.peRed; /*Red*/
2652 bits = (dstbits += linebytes);
2655 else goto notsupported;
2660 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2661 bmpImage->depth, (int)bmpImage->red_mask,
2662 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2663 for (h = lines - 1; h >= 0; h--)
2665 for (x = 0; x < dstwidth; x++, bits += 4)
2667 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2668 bits[0] = GetBValue(pixel);
2669 bits[1] = GetGValue(pixel);
2670 bits[2] = GetRValue(pixel);
2672 bits = (dstbits += linebytes);
2678 /***********************************************************************
2679 * X11DRV_DIB_SetImageBits
2681 * Transfer the bits to an X image.
2682 * Helper function for SetDIBits() and SetDIBitsToDevice().
2684 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2686 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2691 bmpImage = descr->image;
2693 bmpImage = XCreateImage( display, X11DRV_GetVisual(), descr->depth, ZPixmap, 0, NULL,
2694 descr->infoWidth, lines, 32, 0 );
2695 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2696 if(bmpImage->data == NULL) {
2697 ERR("Out of memory!\n");
2698 XDestroyImage( bmpImage );
2699 wine_tsx11_unlock();
2704 /* Transfer the pixels */
2705 switch(descr->infoBpp)
2708 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
2709 descr->width, descr->xSrc, (int *)(descr->colorMap),
2710 bmpImage, descr->dibpitch );
2713 if (descr->compression) {
2714 XGetSubImage( display, descr->drawable, descr->xDest, descr->yDest,
2715 descr->width, descr->height, AllPlanes, ZPixmap,
2716 bmpImage, descr->xSrc, descr->ySrc );
2718 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
2719 descr->infoWidth, descr->width,
2720 descr->xSrc, (int *)(descr->colorMap),
2723 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
2724 descr->infoWidth, descr->width,
2725 descr->xSrc, (int*)(descr->colorMap),
2726 bmpImage, descr->dibpitch );
2729 if (descr->compression) {
2730 XGetSubImage( display, descr->drawable, descr->xDest, descr->yDest,
2731 descr->width, descr->height, AllPlanes, ZPixmap,
2732 bmpImage, descr->xSrc, descr->ySrc );
2733 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
2734 descr->infoWidth, descr->width,
2735 descr->xSrc, (int *)(descr->colorMap),
2738 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
2739 descr->infoWidth, descr->width,
2740 descr->xSrc, (int *)(descr->colorMap),
2741 bmpImage, descr->dibpitch );
2745 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
2746 descr->infoWidth, descr->width,
2747 descr->xSrc, descr->dc,
2748 descr->rMask, descr->gMask, descr->bMask,
2749 bmpImage, descr->dibpitch);
2752 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
2753 descr->infoWidth, descr->width,
2754 descr->xSrc, descr->dc, bmpImage,
2758 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
2759 descr->infoWidth, descr->width,
2760 descr->xSrc, descr->dc,
2761 bmpImage, descr->dibpitch);
2764 WARN("(%d): Invalid depth\n", descr->infoBpp );
2768 TRACE("XPutImage(%p,%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
2769 display, descr->drawable, descr->gc, bmpImage,
2770 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2771 descr->width, descr->height);
2774 XShmPutImage( display, descr->drawable, descr->gc, bmpImage,
2775 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2776 descr->width, descr->height, FALSE );
2777 XSync( display, 0 );
2780 XPutImage( display, descr->drawable, descr->gc, bmpImage,
2781 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2782 descr->width, descr->height );
2784 if (!descr->image) XDestroyImage( bmpImage );
2785 wine_tsx11_unlock();
2789 /***********************************************************************
2790 * X11DRV_DIB_GetImageBits
2792 * Transfer the bits from an X image.
2794 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2796 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2801 bmpImage = descr->image;
2803 bmpImage = XCreateImage( display, X11DRV_GetVisual(), descr->depth, ZPixmap, 0, NULL,
2804 descr->infoWidth, lines, 32, 0 );
2805 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2806 if(bmpImage->data == NULL) {
2807 ERR("Out of memory!\n");
2808 XDestroyImage( bmpImage );
2809 wine_tsx11_unlock();
2814 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
2815 display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
2816 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
2817 XGetSubImage( display, descr->drawable, descr->xSrc, descr->ySrc,
2818 descr->width, lines, AllPlanes, ZPixmap,
2819 bmpImage, descr->xDest, descr->yDest );
2821 /* Transfer the pixels */
2822 switch(descr->infoBpp)
2825 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
2826 descr->infoWidth, descr->width,
2827 descr->colorMap, descr->palentry,
2828 bmpImage, descr->dibpitch );
2832 if (descr->compression)
2833 FIXME("Compression not yet supported!\n");
2835 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
2836 descr->infoWidth, descr->width,
2837 descr->colorMap, descr->palentry,
2838 bmpImage, descr->dibpitch );
2842 if (descr->compression)
2843 FIXME("Compression not yet supported!\n");
2845 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
2846 descr->infoWidth, descr->width,
2847 descr->colorMap, descr->palentry,
2848 bmpImage, descr->dibpitch );
2852 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
2853 descr->infoWidth,descr->width,
2855 descr->rMask, descr->gMask, descr->bMask,
2856 bmpImage, descr->dibpitch );
2860 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
2861 descr->infoWidth,descr->width,
2862 descr->palentry, bmpImage, descr->dibpitch);
2866 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
2867 descr->infoWidth, descr->width,
2868 descr->palentry, bmpImage, descr->dibpitch);
2872 WARN("(%d): Invalid depth\n", descr->infoBpp );
2876 if (!descr->image) XDestroyImage( bmpImage );
2877 wine_tsx11_unlock();
2881 /*************************************************************************
2882 * X11DRV_SetDIBitsToDevice
2885 INT X11DRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx,
2886 DWORD cy, INT xSrc, INT ySrc,
2887 UINT startscan, UINT lines, LPCVOID bits,
2888 const BITMAPINFO *info, UINT coloruse )
2890 X11DRV_DIB_IMAGEBITS_DESCR descr;
2891 DWORD width, oldcy = cy;
2893 int height, tmpheight;
2894 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
2897 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
2898 &descr.infoBpp, &descr.compression ) == -1)
2901 if (height < 0) height = -height;
2902 if (!lines || (startscan >= height)) return 0;
2903 if (startscan + lines > height) lines = height - startscan;
2904 if (ySrc < startscan) ySrc = startscan;
2905 else if (ySrc >= startscan + lines) return 0;
2906 if (xSrc >= width) return 0;
2907 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
2908 if (xSrc + cx >= width) cx = width - xSrc;
2909 if (!cx || !cy) return 0;
2911 X11DRV_SetupGCForText( dc ); /* To have the correct colors */
2912 TSXSetFunction(display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);
2914 switch (descr.infoBpp)
2919 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
2920 coloruse == DIB_PAL_COLORS ? dc : NULL, coloruse,
2921 dc->bitsPerPixel, info, &descr.nColorMap );
2922 if (!descr.colorMap) return 0;
2923 descr.rMask = descr.gMask = descr.bMask = 0;
2927 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2928 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
2929 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
2934 descr.rMask = descr.gMask = descr.bMask = 0;
2939 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2940 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
2941 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
2949 descr.palentry = NULL;
2950 descr.lines = tmpheight >= 0 ? lines : -lines;
2951 descr.infoWidth = width;
2952 descr.depth = dc->bitsPerPixel;
2953 descr.drawable = physDev->drawable;
2954 descr.gc = physDev->gc;
2956 descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy)
2958 descr.xDest = dc->DCOrgX + XLPTODP( dc, xDest );
2959 descr.yDest = dc->DCOrgY + YLPTODP( dc, yDest ) +
2960 (tmpheight >= 0 ? oldcy-cy : 0);
2963 descr.useShm = FALSE;
2964 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
2966 result = X11DRV_DIB_SetImageBits( &descr );
2968 if (descr.infoBpp <= 8)
2969 HeapFree(GetProcessHeap(), 0, descr.colorMap);
2973 /***********************************************************************
2974 * X11DRV_DIB_SetDIBits
2976 INT X11DRV_DIB_SetDIBits(
2977 BITMAPOBJ *bmp, DC *dc, UINT startscan,
2978 UINT lines, LPCVOID bits, const BITMAPINFO *info,
2979 UINT coloruse, HBITMAP hbitmap)
2981 X11DRV_DIB_IMAGEBITS_DESCR descr;
2982 int height, tmpheight;
2987 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
2988 &descr.infoBpp, &descr.compression ) == -1)
2992 if (height < 0) height = -height;
2993 if (!lines || (startscan >= height))
2996 if (startscan + lines > height) lines = height - startscan;
2998 switch (descr.infoBpp)
3003 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3004 coloruse == DIB_PAL_COLORS ? descr.dc : NULL, coloruse,
3005 bmp->bitmap.bmBitsPixel,
3006 info, &descr.nColorMap );
3007 if (!descr.colorMap) return 0;
3008 descr.rMask = descr.gMask = descr.bMask = 0;
3012 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3013 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3014 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3019 descr.rMask = descr.gMask = descr.bMask = 0;
3024 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3025 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
3026 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
3034 if(!bmp->physBitmap)
3035 X11DRV_CreateBitmap(hbitmap);
3039 descr.palentry = NULL;
3040 descr.lines = tmpheight >= 0 ? lines : -lines;
3041 descr.depth = bmp->bitmap.bmBitsPixel;
3042 descr.drawable = (Pixmap)bmp->physBitmap;
3043 descr.gc = BITMAP_GC(bmp);
3047 descr.yDest = height - startscan - lines;
3048 descr.width = bmp->bitmap.bmWidth;
3049 descr.height = lines;
3050 descr.useShm = FALSE;
3051 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
3052 result = X11DRV_DIB_SetImageBits( &descr );
3054 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
3059 /***********************************************************************
3060 * X11DRV_DIB_GetDIBits
3062 INT X11DRV_DIB_GetDIBits(
3063 BITMAPOBJ *bmp, DC *dc, UINT startscan,
3064 UINT lines, LPVOID bits, BITMAPINFO *info,
3065 UINT coloruse, HBITMAP hbitmap)
3067 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3068 X11DRV_DIB_IMAGEBITS_DESCR descr;
3069 PALETTEOBJ * palette;
3072 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3073 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
3074 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
3077 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
3080 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
3082 height = info->bmiHeader.biHeight;
3083 if (height < 0) height = -height;
3084 if( lines > height ) lines = height;
3085 /* Top-down images have a negative biHeight, the scanlines of theses images
3086 * were inverted in X11DRV_DIB_GetImageBits_xx
3087 * To prevent this we simply change the sign of lines
3088 * (the number of scan lines to copy).
3089 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3091 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
3093 if( startscan >= bmp->bitmap.bmHeight )
3099 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
3100 &descr.infoBpp, &descr.compression ) == -1)
3106 switch (descr.infoBpp)
3112 descr.rMask = descr.gMask = descr.bMask = 0;
3116 descr.rMask = 0x7c00;
3117 descr.gMask = 0x03e0;
3118 descr.bMask = 0x001f;
3122 descr.rMask = 0xff0000;
3123 descr.gMask = 0xff00;
3129 if(!bmp->physBitmap)
3130 X11DRV_CreateBitmap(hbitmap);
3134 descr.palentry = palette->logpalette.palPalEntry;
3137 descr.lines = lines;
3138 descr.depth = bmp->bitmap.bmBitsPixel;
3139 descr.drawable = (Pixmap)bmp->physBitmap;
3140 descr.gc = BITMAP_GC(bmp);
3141 descr.width = bmp->bitmap.bmWidth;
3142 descr.height = bmp->bitmap.bmHeight;
3143 descr.colorMap = info->bmiColors;
3148 if (descr.lines > 0)
3150 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
3154 descr.ySrc = startscan;
3156 #ifdef HAVE_LIBXXSHM
3157 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
3159 descr.useShm = FALSE;
3161 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
3162 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
3164 X11DRV_DIB_GetImageBits( &descr );
3166 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
3167 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
3168 info->bmiHeader.biWidth,
3169 info->bmiHeader.biHeight,
3170 info->bmiHeader.biBitCount );
3172 info->bmiHeader.biCompression = 0;
3173 if (descr.compression == BI_BITFIELDS)
3175 *(DWORD *)info->bmiColors = descr.rMask;
3176 *((DWORD *)info->bmiColors+1) = descr.gMask;
3177 *((DWORD *)info->bmiColors+2) = descr.bMask;
3181 GDI_ReleaseObj( dc->hPalette );
3186 /***********************************************************************
3187 * DIB_DoProtectDIBSection
3189 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
3191 DIBSECTION *dib = bmp->dib;
3192 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
3193 : -dib->dsBm.bmHeight;
3194 /* use the biSizeImage data as the memory size only if we're dealing with a
3195 compressed image where the value is set. Otherwise, calculate based on
3197 INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
3198 ? dib->dsBmih.biSizeImage
3199 : dib->dsBm.bmWidthBytes * effHeight;
3202 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
3203 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
3206 /***********************************************************************
3207 * X11DRV_DIB_DoUpdateDIBSection
3209 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
3210 void *colorMap, int nColorMap,
3212 DWORD xSrc, DWORD ySrc,
3213 DWORD xDest, DWORD yDest,
3214 DWORD width, DWORD height)
3216 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3217 X11DRV_DIB_IMAGEBITS_DESCR descr;
3219 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
3220 &descr.infoBpp, &descr.compression ) == -1)
3224 descr.palentry = NULL;
3225 descr.image = dib->image;
3226 descr.colorMap = colorMap;
3227 descr.nColorMap = nColorMap;
3228 descr.bits = dib->dibSection.dsBm.bmBits;
3229 descr.depth = bmp->bitmap.bmBitsPixel;
3231 switch (descr.infoBpp)
3237 descr.rMask = descr.gMask = descr.bMask = 0;
3241 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
3242 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
3243 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
3247 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff;
3248 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0xff00;
3249 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0xff0000;
3254 descr.drawable = dest;
3255 descr.gc = BITMAP_GC(bmp);
3258 descr.xDest = xDest;
3259 descr.yDest = yDest;
3260 descr.width = width;
3261 descr.height = height;
3262 #ifdef HAVE_LIBXXSHM
3263 descr.useShm = (dib->shminfo.shmid != -1);
3265 descr.useShm = FALSE;
3267 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
3271 TRACE("Copying from Pixmap to DIB bits\n");
3272 X11DRV_DIB_GetImageBits( &descr );
3276 TRACE("Copying from DIB bits to Pixmap\n");
3277 X11DRV_DIB_SetImageBits( &descr );
3281 /***********************************************************************
3282 * X11DRV_DIB_CopyDIBSection
3284 void X11DRV_DIB_CopyDIBSection(DC *dcSrc, DC *dcDst,
3285 DWORD xSrc, DWORD ySrc,
3286 DWORD xDest, DWORD yDest,
3287 DWORD width, DWORD height)
3290 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcDst->physDev;
3291 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
3293 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst,
3294 xSrc, ySrc, xDest, yDest, width, height);
3295 /* this function is meant as an optimization for BitBlt,
3296 * not to be called otherwise */
3297 if (!(dcSrc->flags & DC_MEMORY)) {
3298 ERR("called for non-memory source DC!?\n");
3302 bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC );
3303 if (!(bmp && bmp->dib)) {
3304 ERR("called for non-DIBSection!?\n");
3305 GDI_ReleaseObj( dcSrc->hBitmap );
3308 /* while BitBlt should already have made sure we only get
3309 * positive values, we should check for oversize values */
3310 if ((xSrc < bmp->bitmap.bmWidth) &&
3311 (ySrc < bmp->bitmap.bmHeight)) {
3312 if (xSrc + width > bmp->bitmap.bmWidth)
3313 width = bmp->bitmap.bmWidth - xSrc;
3314 if (ySrc + height > bmp->bitmap.bmHeight)
3315 height = bmp->bitmap.bmHeight - ySrc;
3316 /* if the source bitmap is 8bpp or less, we're supposed to use the
3317 * DC's palette for color conversion (not the DIB color table) */
3318 if (bmp->dib->dsBm.bmBitsPixel <= 8) {
3319 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3320 if ((!dcSrc->hPalette) ||
3321 (dcSrc->hPalette == GetStockObject(DEFAULT_PALETTE))) {
3322 /* HACK: no palette has been set in the source DC,
3323 * use the DIB colormap instead - this is necessary in some
3324 * cases since we need to do depth conversion in some places
3325 * where real Windows can just copy data straight over */
3326 colorMap = dib->colorMap;
3327 nColorMap = dib->nColorMap;
3329 colorMap = X11DRV_DIB_BuildColorMap( dcSrc, (WORD)-1,
3330 bmp->dib->dsBm.bmBitsPixel,
3331 (BITMAPINFO*)&(bmp->dib->dsBmih),
3333 if (colorMap) aColorMap = TRUE;
3336 /* perform the copy */
3337 X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
3338 physDev->drawable, xSrc, ySrc, xDest, yDest,
3340 /* free color mapping */
3342 HeapFree(GetProcessHeap(), 0, colorMap);
3344 GDI_ReleaseObj( dcSrc->hBitmap );
3347 /***********************************************************************
3348 * X11DRV_DIB_DoUpdateDIBSection
3350 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
3352 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3353 X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
3354 (Drawable)bmp->physBitmap, 0, 0, 0, 0,
3355 bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
3358 /***********************************************************************
3359 * X11DRV_DIB_FaultHandler
3361 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
3366 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
3367 if (!bmp) return FALSE;
3369 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
3370 if (state != DIB_Status_InSync) {
3371 /* no way to tell whether app needs read or write yet,
3373 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
3375 /* hm, apparently the app must have write access */
3376 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
3378 X11DRV_DIB_Unlock(bmp, TRUE);
3380 GDI_ReleaseObj( (HBITMAP)res );
3384 /***********************************************************************
3387 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
3389 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3390 INT ret = DIB_Status_None;
3393 EnterCriticalSection(&(dib->lock));
3396 case DIB_Status_GdiMod:
3397 /* GDI access - request to draw on pixmap */
3398 switch (dib->status)
3401 case DIB_Status_None:
3402 dib->p_status = DIB_Status_GdiMod;
3403 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3406 case DIB_Status_GdiMod:
3407 TRACE("GdiMod requested in status GdiMod\n" );
3410 case DIB_Status_InSync:
3411 TRACE("GdiMod requested in status InSync\n" );
3412 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3413 dib->status = DIB_Status_GdiMod;
3414 dib->p_status = DIB_Status_InSync;
3417 case DIB_Status_AuxMod:
3418 TRACE("GdiMod requested in status AuxMod\n" );
3419 if (lossy) dib->status = DIB_Status_GdiMod;
3420 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
3421 dib->p_status = DIB_Status_AuxMod;
3422 if (dib->status != DIB_Status_AppMod) {
3423 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3426 /* fall through if copy_aux() had to change to AppMod state */
3428 case DIB_Status_AppMod:
3429 TRACE("GdiMod requested in status AppMod\n" );
3431 /* make it readonly to avoid app changing data while we copy */
3432 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3433 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3435 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3436 dib->p_status = DIB_Status_AppMod;
3437 dib->status = DIB_Status_GdiMod;
3442 case DIB_Status_InSync:
3443 /* App access - request access to read DIB surface */
3444 /* (typically called from signal handler) */
3445 switch (dib->status)
3448 case DIB_Status_None:
3449 /* shouldn't happen from signal handler */
3452 case DIB_Status_AuxMod:
3453 TRACE("InSync requested in status AuxMod\n" );
3454 if (lossy) dib->status = DIB_Status_InSync;
3456 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3457 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
3459 if (dib->status != DIB_Status_GdiMod) {
3460 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3463 /* fall through if copy_aux() had to change to GdiMod state */
3465 case DIB_Status_GdiMod:
3466 TRACE("InSync requested in status GdiMod\n" );
3468 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3469 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3471 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3472 dib->status = DIB_Status_InSync;
3475 case DIB_Status_InSync:
3476 TRACE("InSync requested in status InSync\n" );
3477 /* shouldn't happen from signal handler */
3480 case DIB_Status_AppMod:
3481 TRACE("InSync requested in status AppMod\n" );
3482 /* no reason to do anything here, and this
3483 * shouldn't happen from signal handler */
3488 case DIB_Status_AppMod:
3489 /* App access - request access to write DIB surface */
3490 /* (typically called from signal handler) */
3491 switch (dib->status)
3494 case DIB_Status_None:
3495 /* shouldn't happen from signal handler */
3498 case DIB_Status_AuxMod:
3499 TRACE("AppMod requested in status AuxMod\n" );
3500 if (lossy) dib->status = DIB_Status_AppMod;
3502 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3503 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
3505 if (dib->status != DIB_Status_GdiMod)
3507 /* fall through if copy_aux() had to change to GdiMod state */
3509 case DIB_Status_GdiMod:
3510 TRACE("AppMod requested in status GdiMod\n" );
3511 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3512 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3515 case DIB_Status_InSync:
3516 TRACE("AppMod requested in status InSync\n" );
3517 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3518 dib->status = DIB_Status_AppMod;
3521 case DIB_Status_AppMod:
3522 TRACE("AppMod requested in status AppMod\n" );
3523 /* shouldn't happen from signal handler */
3528 case DIB_Status_AuxMod:
3529 if (dib->status == DIB_Status_None) {
3530 dib->p_status = req;
3532 if (dib->status != DIB_Status_AuxMod)
3533 dib->p_status = dib->status;
3534 dib->status = DIB_Status_AuxMod;
3537 /* it is up to the caller to do the copy/conversion, probably
3538 * using the return value to decide where to copy from */
3540 LeaveCriticalSection(&(dib->lock));
3545 /***********************************************************************
3548 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
3550 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3551 INT ret = DIB_Status_None;
3554 EnterCriticalSection(&(dib->lock));
3556 if (req != DIB_Status_None)
3557 X11DRV_DIB_Coerce(bmp, req, lossy);
3562 /***********************************************************************
3565 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
3567 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3570 switch (dib->status)
3573 case DIB_Status_None:
3574 /* in case anyone is wondering, this is the "signal handler doesn't
3575 * work" case, where we always have to be ready for app access */
3577 switch (dib->p_status)
3579 case DIB_Status_AuxMod:
3580 TRACE("Unlocking and syncing from AuxMod\n" );
3581 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
3582 if (dib->status != DIB_Status_None) {
3583 dib->p_status = dib->status;
3584 dib->status = DIB_Status_None;
3586 if (dib->p_status != DIB_Status_GdiMod)
3588 /* fall through if copy_aux() had to change to GdiMod state */
3590 case DIB_Status_GdiMod:
3591 TRACE("Unlocking and syncing from GdiMod\n" );
3592 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3596 TRACE("Unlocking without needing to sync\n" );
3600 else TRACE("Unlocking with no changes\n");
3601 dib->p_status = DIB_Status_None;
3604 case DIB_Status_GdiMod:
3605 TRACE("Unlocking in status GdiMod\n" );
3606 /* DIB was protected in Coerce */
3608 /* no commit, revert to InSync if applicable */
3609 if ((dib->p_status == DIB_Status_InSync) ||
3610 (dib->p_status == DIB_Status_AppMod)) {
3611 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3612 dib->status = DIB_Status_InSync;
3617 case DIB_Status_InSync:
3618 TRACE("Unlocking in status InSync\n" );
3619 /* DIB was already protected in Coerce */
3622 case DIB_Status_AppMod:
3623 TRACE("Unlocking in status AppMod\n" );
3624 /* DIB was already protected in Coerce */
3625 /* this case is ordinary only called from the signal handler,
3626 * so we don't bother to check for !commit */
3629 case DIB_Status_AuxMod:
3630 TRACE("Unlocking in status AuxMod\n" );
3632 /* DIB may need protection now */
3633 if ((dib->p_status == DIB_Status_InSync) ||
3634 (dib->p_status == DIB_Status_AppMod))
3635 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3637 /* no commit, revert to previous state */
3638 if (dib->p_status != DIB_Status_None)
3639 dib->status = dib->p_status;
3640 /* no protections changed */
3642 dib->p_status = DIB_Status_None;
3645 LeaveCriticalSection(&(dib->lock));
3649 /***********************************************************************
3650 * X11DRV_CoerceDIBSection
3652 INT X11DRV_CoerceDIBSection(DC *dc, INT req, BOOL lossy)
3657 if (!dc) return DIB_Status_None;
3658 if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;
3660 bmp = (BITMAPOBJ *)GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
3661 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
3662 GDI_ReleaseObj( dc->hBitmap );
3666 /***********************************************************************
3667 * X11DRV_LockDIBSection2
3669 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
3674 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3675 ret = X11DRV_DIB_Lock(bmp, req, lossy);
3676 GDI_ReleaseObj( hBmp );
3680 /***********************************************************************
3681 * X11DRV_UnlockDIBSection2
3683 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
3687 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3688 X11DRV_DIB_Unlock(bmp, commit);
3689 GDI_ReleaseObj( hBmp );
3692 /***********************************************************************
3693 * X11DRV_LockDIBSection
3695 INT X11DRV_LockDIBSection(DC *dc, INT req, BOOL lossy)
3697 if (!dc) return DIB_Status_None;
3698 if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;
3700 return X11DRV_LockDIBSection2( dc->hBitmap, req, lossy );
3703 /***********************************************************************
3704 * X11DRV_UnlockDIBSection
3706 void X11DRV_UnlockDIBSection(DC *dc, BOOL commit)
3709 if (!(dc->flags & DC_MEMORY)) return;
3711 X11DRV_UnlockDIBSection2( dc->hBitmap, commit );
3714 /***********************************************************************
3715 * X11DRV_DIB_CreateDIBSection16
3717 HBITMAP16 X11DRV_DIB_CreateDIBSection16(
3718 DC *dc, BITMAPINFO *bmi, UINT16 usage,
3719 SEGPTR *bits, HANDLE section,
3720 DWORD offset, DWORD ovr_pitch)
3722 HBITMAP res = X11DRV_DIB_CreateDIBSection(dc, bmi, usage, NULL,
3723 section, offset, ovr_pitch);
3726 BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3727 if ( bmp && bmp->dib )
3729 DIBSECTION *dib = bmp->dib;
3730 INT height = dib->dsBm.bmHeight >= 0 ?
3731 dib->dsBm.bmHeight : -dib->dsBm.bmHeight;
3732 /* same as above - only use biSizeImage as the correct size if it a
3733 compressed image and it's currently non-zero. In other cases, use
3734 width * height as the value. */
3735 INT size = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
3736 ? dib->dsBmih.biSizeImage
3737 : dib->dsBm.bmWidthBytes * height;
3738 if ( dib->dsBm.bmBits )
3740 ((X11DRV_DIBSECTION *) bmp->dib)->selector =
3741 SELECTOR_AllocBlock( dib->dsBm.bmBits, size, WINE_LDT_FLAGS_DATA );
3743 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3744 dib->dsBm.bmBits, size, ((X11DRV_DIBSECTION *) bmp->dib)->selector,
3745 MAKESEGPTR(((X11DRV_DIBSECTION *) bmp->dib)->selector, 0));
3747 *bits = MAKESEGPTR( ((X11DRV_DIBSECTION *) bmp->dib)->selector, 0 );
3749 if (bmp) GDI_ReleaseObj( res );
3755 /***********************************************************************
3756 * X11DRV_XShmErrorHandler
3759 static int XShmErrorHandler(Display *dpy, XErrorEvent *event)
3765 /***********************************************************************
3766 * X11DRV_XShmCreateImage
3770 #ifdef HAVE_LIBXXSHM
3771 extern BOOL X11DRV_XShmCreateImage(XImage** image, int width, int height, int bpp,
3772 XShmSegmentInfo* shminfo)
3774 int (*WineXHandler)(Display *, XErrorEvent *);
3776 *image = TSXShmCreateImage(display, X11DRV_GetVisual(), bpp, ZPixmap, NULL, shminfo, width, height);
3777 if( *image != NULL )
3780 shminfo->shmid = shmget(IPC_PRIVATE, (*image)->bytes_per_line * height,
3782 if( shminfo->shmid != -1 )
3784 shminfo->shmaddr = (*image)->data = shmat(shminfo->shmid, 0, 0);
3785 if( shminfo->shmaddr != (char*)-1 )
3787 shminfo->readOnly = FALSE;
3788 if( TSXShmAttach( display, shminfo ) != 0)
3790 /* Reset the error flag */
3792 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3793 XSync( display, 0 );
3797 shmctl(shminfo->shmid, IPC_RMID, 0);
3799 XSetErrorHandler(WineXHandler);
3800 wine_tsx11_unlock();
3801 return TRUE; /* Success! */
3803 /* An error occured */
3805 XSetErrorHandler(WineXHandler);
3807 shmdt(shminfo->shmaddr);
3809 shmctl(shminfo->shmid, IPC_RMID, 0);
3812 XDestroyImage(*image);
3813 wine_tsx11_unlock();
3817 #endif /* HAVE_LIBXXSHM */
3821 /***********************************************************************
3822 * X11DRV_DIB_CreateDIBSection
3824 HBITMAP X11DRV_DIB_CreateDIBSection(
3825 DC *dc, BITMAPINFO *bmi, UINT usage,
3826 LPVOID *bits, HANDLE section,
3827 DWORD offset, DWORD ovr_pitch)
3830 BITMAPOBJ *bmp = NULL;
3831 X11DRV_DIBSECTION *dib = NULL;
3832 int *colorMap = NULL;
3835 /* Fill BITMAP32 structure with DIB data */
3836 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
3837 INT effHeight, totalSize;
3839 LPVOID mapBits = NULL;
3841 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3842 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
3843 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
3845 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
3847 bm.bmWidth = bi->biWidth;
3848 bm.bmHeight = effHeight;
3849 bm.bmWidthBytes = ovr_pitch ? ovr_pitch
3850 : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
3851 bm.bmPlanes = bi->biPlanes;
3852 bm.bmBitsPixel = bi->biBitCount;
3855 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
3856 we're dealing with a compressed bitmap. Otherwise, use width * height. */
3857 totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
3858 ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
3862 SYSTEM_INFO SystemInfo;
3866 GetSystemInfo( &SystemInfo );
3867 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
3868 mapSize = totalSize + (offset - mapOffset);
3869 mapBits = MapViewOfFile( section,
3870 FILE_MAP_ALL_ACCESS,
3874 bm.bmBits = (char *)mapBits + (offset - mapOffset);
3876 else if (ovr_pitch && offset)
3877 bm.bmBits = (LPVOID) offset;
3880 bm.bmBits = VirtualAlloc(NULL, totalSize,
3881 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
3884 /* Create Color Map */
3885 if (bm.bmBits && bm.bmBitsPixel <= 8)
3886 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? dc : NULL,
3887 usage, bm.bmBitsPixel, bmi, &nColorMap );
3889 /* Allocate Memory for DIB and fill structure */
3891 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
3894 dib->dibSection.dsBm = bm;
3895 dib->dibSection.dsBmih = *bi;
3896 dib->dibSection.dsBmih.biSizeImage = totalSize;
3898 /* Set dsBitfields values */
3899 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
3901 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
3903 else switch( bi->biBitCount )
3906 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
3907 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
3908 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
3912 dib->dibSection.dsBitfields[0] = 0xff;
3913 dib->dibSection.dsBitfields[1] = 0xff00;
3914 dib->dibSection.dsBitfields[2] = 0xff0000;
3918 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
3919 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
3920 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
3923 dib->dibSection.dshSection = section;
3924 dib->dibSection.dsOffset = offset;
3926 dib->status = DIB_Status_None;
3929 dib->nColorMap = nColorMap;
3930 dib->colorMap = colorMap;
3933 /* Create Device Dependent Bitmap and add DIB pointer */
3936 res = CreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
3939 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3942 bmp->dib = (DIBSECTION *) dib;
3944 if(!bmp->physBitmap)
3945 X11DRV_CreateBitmap(res);
3953 #ifdef HAVE_LIBXXSHM
3954 if (TSXShmQueryExtension(display) &&
3955 X11DRV_XShmCreateImage( &dib->image, bm.bmWidth, effHeight,
3956 bmp->bitmap.bmBitsPixel, &dib->shminfo ) )
3958 ; /* Created Image */
3960 XCREATEIMAGE( dib->image, bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3961 dib->shminfo.shmid = -1;
3964 XCREATEIMAGE( dib->image, bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3968 /* Clean up in case of errors */
3969 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
3971 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3972 res, bmp, dib, bm.bmBits);
3976 UnmapViewOfFile(mapBits), bm.bmBits = NULL;
3978 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
3981 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
3982 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
3983 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
3984 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
3985 if (res) { DeleteObject(res); res = 0; }
3989 /* Install fault handler, if possible */
3990 InitializeCriticalSection(&(dib->lock));
3991 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
3993 if (section || offset)
3995 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3996 if (dib) dib->status = DIB_Status_AppMod;
4000 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4001 if (dib) dib->status = DIB_Status_InSync;
4006 /* Return BITMAP handle and storage location */
4007 if (bmp) GDI_ReleaseObj(res);
4008 if (bm.bmBits && bits) *bits = bm.bmBits;
4012 /***********************************************************************
4013 * X11DRV_DIB_DeleteDIBSection
4015 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
4017 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4021 #ifdef HAVE_LIBXXSHM
4022 if (dib->shminfo.shmid != -1)
4024 TSXShmDetach (display, &(dib->shminfo));
4025 XDestroyImage (dib->image);
4026 shmdt (dib->shminfo.shmaddr);
4027 dib->shminfo.shmid = -1;
4031 XDestroyImage( dib->image );
4035 HeapFree(GetProcessHeap(), 0, dib->colorMap);
4037 if (dib->selector) SELECTOR_FreeBlock( dib->selector );
4038 DeleteCriticalSection(&(dib->lock));
4041 /***********************************************************************
4042 * X11DRV_DIB_SetDIBColorTable
4044 UINT X11DRV_DIB_SetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, const RGBQUAD *colors)
4046 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4048 if (dib && dib->colorMap) {
4049 X11DRV_DIB_GenColorMap( dc, dib->colorMap, DIB_RGB_COLORS, dib->dibSection.dsBm.bmBitsPixel,
4050 TRUE, colors, start, count + start );
4056 /***********************************************************************
4057 * X11DRV_DIB_GetDIBColorTable
4059 UINT X11DRV_DIB_GetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, RGBQUAD *colors)
4061 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4063 if (dib && dib->colorMap) {
4064 int i, end = count + start;
4065 if (end > dib->nColorMap) end = dib->nColorMap;
4066 for (i = start; i < end; i++,colors++) {
4067 COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
4068 colors->rgbBlue = GetBValue(col);
4069 colors->rgbGreen = GetGValue(col);
4070 colors->rgbRed = GetRValue(col);
4071 colors->rgbReserved = 0;
4079 /**************************************************************************
4080 * X11DRV_DIB_CreateDIBFromPixmap
4082 * Allocates a packed DIB and copies the Pixmap data into it.
4083 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
4085 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
4088 BITMAPOBJ *pBmp = NULL;
4089 HGLOBAL hPackedDIB = 0;
4091 /* Allocates an HBITMAP which references the Pixmap passed to us */
4092 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
4095 TRACE("\tCould not create bitmap header for Pixmap\n");
4100 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4101 * A packed DIB contains a BITMAPINFO structure followed immediately by
4102 * an optional color palette and the pixel data.
4104 hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
4106 /* Get a pointer to the BITMAPOBJ structure */
4107 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4109 /* We can now get rid of the HBITMAP wrapper we created earlier.
4110 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4114 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4115 pBmp->physBitmap = NULL;
4118 GDI_ReleaseObj( hBmp );
4122 TRACE("\tReturning packed DIB %x\n", hPackedDIB);
4127 /**************************************************************************
4128 * X11DRV_DIB_CreatePixmapFromDIB
4130 * Creates a Pixmap from a packed DIB
4132 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
4134 Pixmap pixmap = None;
4136 BITMAPOBJ *pBmp = NULL;
4137 LPBYTE pPackedDIB = NULL;
4138 LPBITMAPINFO pbmi = NULL;
4139 LPBITMAPINFOHEADER pbmiHeader = NULL;
4140 LPBYTE pbits = NULL;
4142 /* Get a pointer to the packed DIB's data */
4143 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
4144 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
4145 pbmi = (LPBITMAPINFO)pPackedDIB;
4146 pbits = (LPBYTE)(pPackedDIB
4147 + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
4149 /* Create a DDB from the DIB */
4151 hBmp = CreateDIBitmap(hdc,
4158 GlobalUnlock(hPackedDIB);
4160 TRACE("CreateDIBitmap returned %x\n", hBmp);
4162 /* Retrieve the internal Pixmap from the DDB */
4164 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4166 pixmap = (Pixmap)pBmp->physBitmap;
4167 /* clear the physBitmap so that we can steal its pixmap */
4168 pBmp->physBitmap = NULL;
4171 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4172 GDI_ReleaseObj( hBmp );
4175 TRACE("\tReturning Pixmap %ld\n", pixmap);