2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
13 # ifdef HAVE_SYS_SHM_H
16 # ifdef HAVE_SYS_IPC_H
19 #endif /* defined(HAVE_LIBXXSHM) */
26 #include "debugtools.h"
29 #include "selectors.h"
32 DEFAULT_DEBUG_CHANNEL(bitmap);
33 DECLARE_DEBUG_CHANNEL(x11drv);
35 static int ximageDepthTable[32];
37 static int XShmErrorFlag = 0;
39 /* This structure holds the arguments for DIB_SetImageBits() */
45 PALETTEENTRY *palentry;
66 } X11DRV_DIB_IMAGEBITS_DESCR;
69 /***********************************************************************
70 * X11DRV_DIB_GetXImageWidthBytes
72 * Return the width of an X image in bytes
74 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
76 if (!depth || depth > 32) goto error;
78 if (!ximageDepthTable[depth-1])
80 XImage *testimage = XCreateImage( gdi_display, visual, depth,
81 ZPixmap, 0, NULL, 1, 1, 32, 20 );
84 ximageDepthTable[depth-1] = testimage->bits_per_pixel;
85 XDestroyImage( testimage );
87 else ximageDepthTable[depth-1] = -1;
89 if (ximageDepthTable[depth-1] != -1)
90 return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
93 WARN( "(%d): Unsupported depth\n", depth );
98 /***********************************************************************
99 * X11DRV_DIB_CreateXImage
103 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
109 width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
110 image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
111 calloc( height, width_bytes ),
112 width, height, 32, width_bytes );
118 /***********************************************************************
119 * X11DRV_DIB_GenColorMap
121 * Fills the color map of a bitmap palette. Should not be called
122 * for a >8-bit deep bitmap.
124 int *X11DRV_DIB_GenColorMap( DC *dc, int *colorMapping,
125 WORD coloruse, WORD depth, BOOL quads,
126 const void *colorPtr, int start, int end )
130 if (coloruse == DIB_RGB_COLORS)
134 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
136 if (depth == 1) /* Monochrome */
137 for (i = start; i < end; i++, rgb++)
138 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
139 rgb->rgbBlue > 255*3/2);
141 for (i = start; i < end; i++, rgb++)
142 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbRed,
148 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
150 if (depth == 1) /* Monochrome */
151 for (i = start; i < end; i++, rgb++)
152 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
153 rgb->rgbtBlue > 255*3/2);
155 for (i = start; i < end; i++, rgb++)
156 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbtRed,
161 else /* DIB_PAL_COLORS */
164 WORD * index = (WORD *)colorPtr;
166 for (i = start; i < end; i++, index++)
167 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) );
169 for (i = start; i < end; i++)
170 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(i) );
177 /***********************************************************************
178 * X11DRV_DIB_BuildColorMap
180 * Build the color map from the bitmap palette. Should not be called
181 * for a >8-bit deep bitmap.
183 int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth,
184 const BITMAPINFO *info, int *nColors )
188 const void *colorPtr;
191 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
193 colors = info->bmiHeader.biClrUsed;
194 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
195 colorPtr = info->bmiColors;
197 else /* assume BITMAPCOREINFO */
199 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
200 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
205 ERR("called with >256 colors!\n");
209 /* just so CopyDIBSection doesn't have to create an identity palette */
210 if (coloruse == (WORD)-1) colorPtr = NULL;
212 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
213 colors * sizeof(int) )))
217 return X11DRV_DIB_GenColorMap( dc, colorMapping, coloruse, depth,
218 isInfo, colorPtr, 0, colors);
222 /***********************************************************************
223 * X11DRV_DIB_MapColor
225 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
229 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
232 for (color = 0; color < nPhysMap; color++)
233 if (physMap[color] == phys)
236 WARN("Strange color %08x\n", phys);
241 /*********************************************************************
242 * X11DRV_DIB_GetNearestIndex
244 * Helper for X11DRV_DIB_GetDIBits.
245 * Returns the nearest colour table index for a given RGB.
246 * Nearest is defined by minimizing the sum of the squares.
248 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
250 INT i, best = -1, diff, bestdiff = -1;
253 for(color = colormap, i = 0; i < numColors; color++, i++) {
254 diff = (r - color->rgbRed) * (r - color->rgbRed) +
255 (g - color->rgbGreen) * (g - color->rgbGreen) +
256 (b - color->rgbBlue) * (b - color->rgbBlue);
259 if(best == -1 || diff < bestdiff) {
267 /***********************************************************************
268 * X11DRV_DIB_SetImageBits_1_Line
270 * Handles a single line of 1 bit data.
272 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
273 XImage *bmpImage, int h, const BYTE *bits)
278 if((extra = (left & 7)) != 0) {
285 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
286 for (i = dstwidth/8, x = left; i > 0; i--)
289 XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
290 XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
291 XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
292 XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
293 XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
294 XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
295 XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
296 XPutPixel( bmpImage, x++, h, colors[pix & 1] );
301 case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
302 case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
303 case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
304 case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
305 case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
306 case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
307 case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
311 /***********************************************************************
312 * X11DRV_DIB_SetImageBits_1
314 * SetDIBits for a 1-bit deep DIB.
316 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
317 DWORD srcwidth, DWORD dstwidth, int left,
318 int *colors, XImage *bmpImage, DWORD linebytes)
323 for (h = lines-1; h >=0; h--) {
324 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
326 srcbits += linebytes;
330 for (h = 0; h < lines; h++) {
331 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
333 srcbits += linebytes;
338 /***********************************************************************
339 * X11DRV_DIB_GetImageBits_1
341 * GetDIBits for a 1-bit deep DIB.
343 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
344 DWORD dstwidth, DWORD srcwidth,
345 RGBQUAD *colors, PALETTEENTRY *srccolors,
346 XImage *bmpImage, DWORD linebytes )
354 dstbits = dstbits + linebytes * (lines - 1);
355 linebytes = -linebytes;
360 switch(bmpImage->depth) {
363 /* ==== monochrome bitmap to monochrome dib ==== */
365 /* ==== 4 colormap bitmap to monochrome dib ==== */
366 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
370 for (h = lines - 1; h >= 0; h--) {
371 for (x = 0; x < dstwidth; x++) {
372 val = srccolors[XGetPixel(bmpImage, x, h)];
373 if (!(x&7)) *bits = 0;
374 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2,
377 val.peBlue) << (7 - (x & 7)));
378 if ((x&7)==7) bits++;
380 bits = (dstbits += linebytes);
383 else goto notsupported;
388 /* ==== 8 colormap bitmap to monochrome dib ==== */
389 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
394 for( h = lines- 1; h >= 0; h-- ) {
395 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
396 for( x = 0; x < dstwidth; x++ ) {
397 if (!(x&7)) *bits = 0;
398 val = srccolors[(int)*srcpixel++];
399 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 2,
402 val.peBlue) << (7-(x&7)) );
403 if ((x&7)==7) bits++;
405 bits = (dstbits += linebytes);
408 else goto notsupported;
417 /* ==== 555 BGR bitmap to monochrome dib ==== */
418 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
420 for( h = lines - 1; h >= 0; h--) {
421 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
422 for( x = 0; x < dstwidth; x++) {
423 if (!(x&7)) *bits = 0;
425 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
426 ((val >> 7) & 0xf8) |
428 ((val >> 2) & 0xf8) |
430 ((val << 3) & 0xf8) |
431 ((val >> 2) & 0x7) ) << (7-(x&7)) );
432 if ((x&7)==7) bits++;
434 bits = (dstbits += linebytes);
437 /* ==== 555 RGB bitmap to monochrome dib ==== */
438 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
440 for( h = lines - 1; h >= 0; h--)
442 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
443 for( x = 0; x < dstwidth; x++) {
444 if (!(x&1)) *bits = 0;
446 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
447 ((val << 3) & 0xf8) |
449 ((val >> 2) & 0xf8) |
451 ((val >> 7) & 0xf8) |
452 ((val >> 12) & 0x7) ) << (7-(x&7)) );
453 if ((x&7)==7) bits++;
455 bits = (dstbits += linebytes);
458 else goto notsupported;
467 /* ==== 565 BGR bitmap to monochrome dib ==== */
468 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
470 for( h = lines - 1; h >= 0; h--)
472 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
473 for( x = 0; x < dstwidth; x++) {
474 if (!(x&7)) *bits = 0;
476 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
477 ((val >> 8) & 0xf8) |
479 ((val >> 3) & 0xfc) |
481 ((val << 3) & 0xf8) |
482 ((val >> 2) & 0x7) ) << (7-(x&7)) );
483 if ((x&7)==7) bits++;
485 bits = (dstbits += linebytes);
488 /* ==== 565 RGB bitmap to monochrome dib ==== */
489 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
491 for( h = lines - 1; h >= 0; h--)
493 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
494 for( x = 0; x < dstwidth; x++) {
495 if (!(x&7)) *bits = 0;
497 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
498 ((val << 3) & 0xf8) |
500 ((val >> 3) & 0xfc) |
502 ((val >> 8) & 0xf8) |
503 ((val >> 13) & 0x7) ) << (7-(x&7)) );
504 if ((x&7)==7) bits++;
506 bits = (dstbits += linebytes);
509 else goto notsupported;
518 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
519 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
521 for (h = lines - 1; h >= 0; h--)
523 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
524 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
525 if (!(x&7)) *bits = 0;
526 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[2] , srcpixel[1], srcpixel[0]) << (7-(x&7)) );
527 if ((x&7)==7) bits++;
529 bits = (dstbits += linebytes);
532 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
533 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
535 for (h = lines - 1; h >= 0; h--)
537 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
538 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
539 if (!(x & 7)) *bits = 0;
540 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[0] , srcpixel[1], srcpixel[2]) << (7-(x&7)) );
541 if ((x & 7) == 7) bits++;
543 bits = (dstbits += linebytes);
546 else goto notsupported;
550 default: /* ? bit bmp -> monochrome DIB */
553 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
555 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
556 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
557 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
559 for( h = lines - 1; h >= 0; h-- ) {
560 for( x = 0; x < dstwidth; x++ ) {
561 if (!(x&7)) *bits = 0;
562 *bits |= (XGetPixel( bmpImage, x, h) >= white)
564 if ((x&7)==7) bits++;
566 bits = (dstbits += linebytes);
573 /***********************************************************************
574 * X11DRV_DIB_SetImageBits_4
576 * SetDIBits for a 4-bit deep DIB.
578 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
579 DWORD srcwidth, DWORD dstwidth, int left,
580 int *colors, XImage *bmpImage, DWORD linebytes)
584 const BYTE *bits = srcbits + (left >> 1);
592 for (h = lines-1; h >= 0; h--) {
593 for (i = dstwidth/2, x = left; i > 0; i--) {
595 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
596 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
598 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
599 srcbits += linebytes;
600 bits = srcbits + (left >> 1);
604 for (h = 0; h < lines; h++) {
605 for (i = dstwidth/2, x = left; i > 0; i--) {
607 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
608 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
610 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
611 srcbits += linebytes;
612 bits = srcbits + (left >> 1);
619 /***********************************************************************
620 * X11DRV_DIB_GetImageBits_4
622 * GetDIBits for a 4-bit deep DIB.
624 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
625 DWORD srcwidth, DWORD dstwidth,
626 RGBQUAD *colors, PALETTEENTRY *srccolors,
627 XImage *bmpImage, DWORD linebytes )
637 dstbits = dstbits + ( linebytes * (lines-1) );
638 linebytes = -linebytes;
643 switch(bmpImage->depth) {
646 /* ==== monochrome bitmap to 4 colormap dib ==== */
648 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
649 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
653 for (h = lines-1; h >= 0; h--) {
654 for (x = 0; x < dstwidth; x++) {
655 if (!(x&1)) *bits = 0;
656 val = srccolors[XGetPixel(bmpImage, x, h)];
657 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 16,
660 val.peBlue) << (4-((x&1)<<2)));
661 if ((x&1)==1) bits++;
663 bits = (dstbits += linebytes);
666 else goto notsupported;
671 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
672 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
676 for( h = lines - 1; h >= 0; h-- ) {
677 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
678 for( x = 0; x < dstwidth; x++ ) {
679 if (!(x&1)) *bits = 0;
680 val = srccolors[(int)*srcpixel++];
681 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 16,
684 val.peBlue) << (4*(1-(x&1))) );
685 if ((x&1)==1) bits++;
687 bits = (dstbits += linebytes);
690 else goto notsupported;
699 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
700 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
702 for( h = lines - 1; h >= 0; h--) {
703 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
704 for( x = 0; x < dstwidth; x++) {
705 if (!(x&1)) *bits = 0;
707 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
708 ((val >> 7) & 0xf8) |
710 ((val >> 2) & 0xf8) |
712 ((val << 3) & 0xf8) |
713 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
714 if ((x&1)==1) bits++;
716 bits = (dstbits += linebytes);
719 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
720 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
722 for( h = lines - 1; h >= 0; h--)
724 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
725 for( x = 0; x < dstwidth; x++) {
726 if (!(x&1)) *bits = 0;
728 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
729 ((val << 3) & 0xf8) |
731 ((val >> 2) & 0xfc) |
733 ((val >> 7) & 0xf8) |
734 ((val >> 12) & 0x7) ) << ((1-(x&1))<<2) );
735 if ((x&1)==1) bits++;
737 bits = (dstbits += linebytes);
740 else goto notsupported;
749 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
750 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
752 for( h = lines - 1; h >= 0; h--)
754 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
755 for( x = 0; x < dstwidth; x++) {
756 if (!(x&1)) *bits = 0;
758 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
759 ((val >> 8) & 0xf8) |
761 ((val >> 3) & 0xfc) |
763 ((val << 3) & 0xf8) |
764 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
765 if ((x&1)==1) bits++;
767 bits = (dstbits += linebytes);
770 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
771 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
773 for( h = lines - 1; h >= 0; h--)
775 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
776 for( x = 0; x < dstwidth; x++) {
777 if (!(x&1)) *bits = 0;
779 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
780 ((val << 3) & 0xf8) |
782 ((val >> 3) & 0xfc) |
784 ((val >> 8) & 0xf8) |
785 ((val >> 13) & 0x7) ) << ((1-(x&1))<<2) );
786 if ((x&1)==1) bits++;
788 bits = (dstbits += linebytes);
791 else goto notsupported;
800 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
801 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
803 for (h = lines - 1; h >= 0; h--)
805 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
806 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
807 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[2] , srcpixel[1], srcpixel[0]) << 4) |
808 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[6] , srcpixel[5], srcpixel[4]);
809 bits = (dstbits += linebytes);
812 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
813 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
815 for (h = lines - 1; h >= 0; h--)
817 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
818 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
819 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[0] , srcpixel[1], srcpixel[2]) << 4) |
820 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[4] , srcpixel[5], srcpixel[6]);
821 bits = (dstbits += linebytes);
824 else goto notsupported;
828 default: /* ? bit bmp -> 4 bit DIB */
830 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
831 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
832 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
833 for (h = lines-1; h >= 0; h--) {
834 for (x = 0; x < dstwidth-1; x += 2)
836 *bits++ = (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x, h ), 0) << 4)
837 | (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x+1, h ), 0) & 0x0f);
840 *bits = (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x, h ), 0) << 4);
841 bits = (dstbits += linebytes);
847 /***********************************************************************
848 * X11DRV_DIB_SetImageBits_RLE4
850 * SetDIBits for a 4-bit deep compressed DIB.
852 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
853 DWORD width, DWORD dstwidth,
854 int left, int *colors,
857 int x = 0, c, length;
858 const BYTE *begin = bits;
862 while ((int)lines >= 0) {
864 if (length) { /* encoded */
872 XPutPixel(bmpImage, x++, lines, colors[c >>4]);
880 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
891 case 1: /* eopicture */
897 FIXME_(x11drv)("x-delta is too large?\n");
903 default: /* absolute */
911 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
919 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
922 if ((bits - begin) & 1)
931 /***********************************************************************
932 * X11DRV_DIB_SetImageBits_8
934 * SetDIBits for an 8-bit deep DIB.
936 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
937 DWORD srcwidth, DWORD dstwidth, int left,
938 const int *colors, XImage *bmpImage,
950 srcbits = srcbits + ( linebytes * (lines-1) );
951 linebytes = -linebytes;
954 bits = srcbits + left;
956 switch (bmpImage->depth) {
959 #if defined(__i386__) && defined(__GNUC__)
960 /* Some X servers might have 32 bit/ 16bit deep pixel */
961 if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 16))
963 for (h = lines ; h--; ) {
964 int _cl1,_cl2; /* temp outputs for asm below */
965 /* Borrowed from DirectDraw */
966 __asm__ __volatile__(
971 " movw (%%edx,%%eax,4),%%ax\n"
975 :"=S" (bits), "=D" (_cl1), "=c" (_cl2)
977 "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*2),
980 :"eax", "cc", "memory"
982 bits = (srcbits += linebytes) + left;
989 #if defined(__i386__) && defined(__GNUC__)
990 if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 32))
992 for (h = lines ; h--; ) {
993 int _cl1,_cl2; /* temp outputs for asm below */
994 /* Borrowed from DirectDraw */
995 __asm__ __volatile__(
1000 " movl (%%edx,%%eax,4),%%eax\n"
1002 " xor %%eax,%%eax\n"
1004 :"=S" (bits), "=D" (_cl1), "=c" (_cl2)
1006 "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*4),
1007 "c" (dstwidth-left),
1009 :"eax", "cc", "memory"
1011 bits = (srcbits += linebytes) + left;
1018 break; /* use slow generic case below */
1021 for (h = lines - 1; h >= 0; h--) {
1022 for (x = left; x < dstwidth; x++, bits++) {
1023 color = colors[*bits];
1024 XPutPixel( bmpImage, x, h, colors[*bits] );
1026 bits = (srcbits += linebytes) + left;
1030 /***********************************************************************
1031 * X11DRV_DIB_GetImageBits_8
1033 * GetDIBits for an 8-bit deep DIB.
1035 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
1036 DWORD srcwidth, DWORD dstwidth,
1037 RGBQUAD *colors, PALETTEENTRY *srccolors,
1038 XImage *bmpImage, DWORD linebytes )
1047 dstbits = dstbits + ( linebytes * (lines-1) );
1048 linebytes = -linebytes;
1055 This condition is true when GetImageBits has been called by UpdateDIBSection.
1056 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
1057 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
1059 if (!srccolors) goto updatesection;
1061 switch(bmpImage->depth) {
1064 /* ==== monochrome bitmap to 8 colormap dib ==== */
1066 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
1067 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1071 for (h = lines - 1; h >= 0; h--) {
1072 for (x = 0; x < dstwidth; x++) {
1073 val = srccolors[XGetPixel(bmpImage, x, h)];
1074 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1075 val.peGreen, val.peBlue);
1077 bits = (dstbits += linebytes);
1080 else goto notsupported;
1085 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
1086 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1091 for (h = lines - 1; h >= 0; h--) {
1092 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1093 for (x = 0; x < dstwidth; x++) {
1094 val = srccolors[(int)*srcpixel++];
1095 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1096 val.peGreen, val.peBlue);
1098 bits = (dstbits += linebytes);
1101 else goto notsupported;
1110 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1111 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
1113 for( h = lines - 1; h >= 0; h--)
1115 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1116 for( x = 0; x < dstwidth; x++ )
1119 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1120 ((val >> 7) & 0xf8) |
1121 ((val >> 12) & 0x7),
1122 ((val >> 2) & 0xf8) |
1124 ((val << 3) & 0xf8) |
1125 ((val >> 2) & 0x7) );
1127 bits = (dstbits += linebytes);
1130 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1131 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
1133 for( h = lines - 1; h >= 0; h--)
1135 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1136 for( x = 0; x < dstwidth; x++ )
1139 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1140 ((val << 3) & 0xf8) |
1142 ((val >> 2) & 0xf8) |
1144 ((val >> 7) & 0xf8) |
1145 ((val >> 12) & 0x7) );
1147 bits = (dstbits += linebytes);
1150 else goto notsupported;
1159 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1160 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
1162 for( h = lines - 1; h >= 0; h--)
1164 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1165 for( x = 0; x < dstwidth; x++ )
1168 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1169 ((val >> 8) & 0xf8) |
1170 ((val >> 13) & 0x7),
1171 ((val >> 3) & 0xfc) |
1173 ((val << 3) & 0xf8) |
1174 ((val >> 2) & 0x7) );
1176 bits = (dstbits += linebytes);
1179 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1180 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
1182 for( h = lines - 1; h >= 0; h--)
1184 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1185 for( x = 0; x < dstwidth; x++ )
1188 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1189 ((val << 3) & 0xf8) |
1191 ((val >> 3) & 0x00fc) |
1193 ((val >> 8) & 0x00f8) |
1194 ((val >> 13) & 0x7) );
1196 bits = (dstbits += linebytes);
1199 else goto notsupported;
1208 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1209 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1211 for (h = lines - 1; h >= 0; h--)
1213 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1214 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1215 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1216 srcpixel[2] , srcpixel[1], *srcpixel);
1217 bits = (dstbits += linebytes);
1220 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1221 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1223 for (h = lines - 1; h >= 0; h--)
1225 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1226 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1227 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1228 *srcpixel, srcpixel[1], srcpixel[2]);
1229 bits = (dstbits += linebytes);
1233 else goto notsupported;
1237 default: /* ? bit bmp -> 8 bit DIB */
1239 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1240 bmpImage->depth, (int)bmpImage->red_mask,
1241 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1243 for (h = lines - 1; h >= 0; h--) {
1244 for (x = 0; x < dstwidth; x++, bits++) {
1245 *bits = X11DRV_DIB_MapColor((int *)colors, 256,
1246 XGetPixel( bmpImage, x, h ), *bits);
1248 bits = (dstbits += linebytes);
1254 /***********************************************************************
1255 * X11DRV_DIB_SetImageBits_RLE8
1257 * SetDIBits for an 8-bit deep compressed DIB.
1259 * This function rewritten 941113 by James Youngman. WINE blew out when I
1260 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1262 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1263 * 'End of bitmap' escape code. This code is very much laxer in what it
1264 * allows to end the expansion. Possibly too lax. See the note by
1265 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1266 * bitmap should end with RleEnd, but on the other hand, software exists
1267 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1270 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1271 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1275 enum Rle8_EscapeCodes
1278 * Apologies for polluting your file's namespace...
1280 RleEol = 0, /* End of line */
1281 RleEnd = 1, /* End of bitmap */
1282 RleDelta = 2 /* Delta */
1285 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1286 DWORD width, DWORD dstwidth,
1287 int left, int *colors,
1290 int x; /* X-positon on each line. Increases. */
1291 int line; /* Line #. Starts at lines-1, decreases */
1292 const BYTE *pIn = bits; /* Pointer to current position in bits */
1293 BYTE length; /* The length pf a run */
1294 BYTE color_index; /* index into colors[] as read from bits */
1295 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
1296 int color; /* value of colour[color_index] */
1298 if (lines == 0) /* Let's hope this doesn't happen. */
1302 * Note that the bitmap data is stored by Windows starting at the
1303 * bottom line of the bitmap and going upwards. Within each line,
1304 * the data is stored left-to-right. That's the reason why line
1305 * goes from lines-1 to 0. [JAY]
1315 * If the length byte is not zero (which is the escape value),
1316 * We have a run of length pixels all the same colour. The colour
1317 * index is stored next.
1319 * If the length byte is zero, we need to read the next byte to
1320 * know what to do. [JAY]
1325 * [Run-Length] Encoded mode
1327 color_index = (*pIn++); /* Get the colour index. */
1328 color = colors[color_index];
1337 XPutPixel(bmpImage, x++, line, color);
1343 * Escape codes (may be an absolute sequence though)
1345 escape_code = (*pIn++);
1348 case RleEol: /* =0, end of line */
1355 case RleEnd: /* =1, end of bitmap */
1358 * Not all RLE8 bitmaps end with this
1359 * code. For example, Paint Shop Pro
1360 * produces some that don't. That's (I think)
1361 * what caused the previous implementation to
1364 line=-1; /* Cause exit from do loop. */
1368 case RleDelta: /* =2, a delta */
1371 * Note that deltaing to line 0
1372 * will cause an exit from the loop,
1373 * which may not be what is intended.
1374 * The fact that there is a delta in the bits
1375 * almost certainly implies that there is data
1376 * to follow. You may feel that we should
1377 * jump to the top of the loop to avoid exiting
1380 * TODO: Decide what to do here in that case. [JAY]
1386 TRACE("Delta to last line of bitmap "
1387 "(wrongly?) causes loop exit\n");
1392 default: /* >2, switch to absolute mode */
1397 length = escape_code;
1400 color_index = (*pIn++);
1406 XPutPixel(bmpImage, x++, line,
1407 colors[color_index]);
1411 * If you think for a moment you'll realise that the
1412 * only time we could ever possibly read an odd
1413 * number of bytes is when there is a 0x00 (escape),
1414 * a value >0x02 (absolute mode) and then an odd-
1415 * length run. Therefore this is the only place we
1416 * need to worry about it. Everywhere else the
1417 * bytes are always read in pairs. [JAY]
1419 if (escape_code & 1)
1420 pIn++; /* Throw away the pad byte. */
1423 } /* switch (escape_code) : Escape sequence */
1424 } /* process either an encoded sequence or an escape sequence */
1426 /* We expect to come here more than once per line. */
1427 } while (line >= 0); /* Do this until the bitmap is filled */
1430 * Everybody comes here at the end.
1431 * Check how we exited the loop and print a message if it's a bit odd.
1434 if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
1436 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1437 "bytes were: %02X %02X.\n", (int)*(pIn-2),(int)*(pIn-1));
1442 /***********************************************************************
1443 * X11DRV_DIB_SetImageBits_16
1445 * SetDIBits for a 16-bit deep DIB.
1447 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1448 DWORD srcwidth, DWORD dstwidth, int left,
1449 DC *dc, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1450 XImage *bmpImage, DWORD linebytes )
1458 srcbits = srcbits + ( linebytes * (lines-1));
1459 linebytes = -linebytes;
1462 switch ( bmpImage->depth )
1465 /* using same format as XImage */
1466 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1467 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1468 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1469 else /* We need to do a conversion from a 565 dib */
1471 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1473 int div = dstwidth % 2;
1475 for (h = lines - 1; h >= 0; h--) {
1476 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1477 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1479 *dstpixel++ = ((val >> 1) & 0x7fe07fe0) | (val & 0x001f001f); /* Red & Green & Blue */
1481 if (div != 0) /* Odd width? */
1482 *dstpixel = ((*(WORD *)ptr >> 1) & 0x7fe0) | (*(WORD *)ptr & 0x001f);
1483 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1489 /* using same format as XImage */
1490 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1491 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1492 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1493 else /* We need to do a conversion from a 555 dib */
1495 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1497 int div = dstwidth % 2;
1499 for (h = lines - 1; h >= 0; h--) {
1500 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1501 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1503 *dstpixel++ = ((val << 1) & 0xffc0ffc0) | ((val >> 4) & 0x00200020) | /* Red & Green */
1504 (val & 0x001f001f); /* Blue */
1506 if (div != 0) /* Odd width? */
1507 *dstpixel = ((*(WORD *)ptr << 1) & 0xffc0) | ((*(WORD *)ptr >> 4) & 0x0020)
1508 | (*(WORD *)ptr & 0x001f);
1509 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1518 LPWORD ptr = (LPWORD)srcbits + left;
1521 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1523 if ((rSrc == 0xF800) && (gSrc == 0x07E0) && (bSrc == 0x001F)) {
1524 /* ==== 555 RGB dib to 24/32 RGB bitmap ==== */
1525 for (h = lines - 1; h >= 0; h--) {
1526 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1527 for (x = 0; x < dstwidth; x++) {
1529 *dstpixel++ = ((val << 8) & 0xF80000) | /* Red */
1530 ((val << 5) & 0x00FC00) | /* Green */
1531 ((val << 3) & 0x0000FF); /* Blue */
1533 ptr = (LPWORD)(srcbits += linebytes) + left;
1536 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1537 for (h = lines - 1; h >= 0; h--) {
1538 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1539 for (x = 0; x < dstwidth; x++) {
1542 *dstpixel++ = ((val << 9) & 0xf80000) | ((val << 4) & 0x070000) | /* Red */
1543 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1544 ((val << 3) & 0x0000f8) | ((val >> 2) & 0x000007); /* Blue */
1546 ptr = (LPWORD)(srcbits += linebytes) + left;
1550 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1551 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1553 for (h = lines - 1; h >= 0; h--) {
1554 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1555 for (x = 0; x < dstwidth; x++) {
1558 *dstpixel++ = ((val >> 7) & 0x0000f8) | ((val >> 12) & 0x000007) | /* Red */
1559 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1560 ((val << 19) & 0xf80000) | ((val >> 14) & 0x070000); /* Blue */
1562 ptr = (LPWORD)(srcbits += linebytes) + left;
1573 LPWORD ptr = (LPWORD)srcbits + left;
1577 /* Set color scaling values */
1578 if ( rSrc == 0x7c00 ) { sc1 = 7; sc2 = 2; } /* 555 dib */
1579 else { sc1 = 8; sc2 = 3; } /* 565 dib */
1581 for (h = lines - 1; h >= 0; h--) {
1582 for (x = left; x < dstwidth+left; x++) {
1584 XPutPixel( bmpImage, x, h,
1585 X11DRV_PALETTE_ToPhysical(dc, RGB(((val & rSrc) >> sc1), /* Red */
1586 ((val & gSrc) >> sc2), /* Green */
1587 ((val & bSrc) << 3)))); /* Blue */
1589 ptr = (LPWORD) (srcbits += linebytes) + left;
1595 FIXME("16 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
1602 /***********************************************************************
1603 * X11DRV_DIB_GetImageBits_16
1605 * GetDIBits for an 16-bit deep DIB.
1607 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
1608 DWORD dstwidth, DWORD srcwidth,
1609 PALETTEENTRY *srccolors,
1610 DWORD rDst, DWORD gDst, DWORD bDst,
1611 XImage *bmpImage, DWORD dibpitch )
1616 DWORD linebytes = dibpitch;
1621 dstbits = dstbits + ( linebytes * (lines-1));
1622 linebytes = -linebytes;
1625 /* Set color scaling values */
1626 if ( rDst == 0x7c00 ) { rsc = 7; gsc = 2; } /* 555 dib */
1627 else { rsc = 8; gsc = 3; } /* 565 dib */
1629 switch ( bmpImage->depth )
1632 /* using same format as XImage */
1633 if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1634 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1635 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1636 /* reversed format (BGR <=> RGB) */
1637 else if (rDst == bmpImage->blue_mask && bDst == bmpImage->red_mask)
1639 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1641 int div = srcwidth % 2;
1643 for (h = lines - 1; h >= 0; h--) {
1644 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1645 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1647 *ptr++ = ((val << 10) & 0xf800f800) | (val & 0x03e003e0) | /* Red & Green */
1648 ((val >> 10) & 0x001f001f); /* Blue */
1650 if (div != 0) /* Odd width? */
1651 *ptr = ((*(WORD *)srcpixel << 1) & 0xffc0) | ((*(WORD *)srcpixel >> 4) & 0x0020) |
1652 (*(WORD *)srcpixel & 0x001f);
1653 ptr = (LPDWORD)(dstbits += linebytes);
1656 else goto notsupported;
1662 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1664 int div = srcwidth % 2;
1666 /* using same format as XImage */
1667 if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1668 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1669 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1670 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1671 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f &&
1672 rDst == 0x7c00 && bDst == 0x001f)
1674 for (h = lines - 1; h >= 0; h--) {
1675 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1676 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1678 *ptr++ = ((val >> 1) & 0x7fe07fe0) | /* Red & Green */
1679 (val & 0x001f001f); /* Blue */
1681 if (div != 0) /* Odd width? */
1682 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1683 ptr = (LPDWORD) (dstbits += linebytes);
1686 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1687 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800 &&
1688 rDst == 0x7c00 && bDst == 0x001f)
1690 for (h = lines - 1; h >= 0; h--) {
1691 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1692 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1694 *ptr++ = ((val << 10) & 0x7c007c00) | ((val >> 1) & 0x03e003e0) | /* Red & Green */
1695 ((val >> 11) & 0x001f001f); /* Blue */
1697 if (div != 0) /* Odd width? */
1698 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1699 ptr = (LPDWORD) (dstbits += linebytes);
1702 else goto notsupported;
1710 LPWORD ptr = (LPWORD)dstbits;
1713 /* ==== 24/32 BGR bitmap ==== */
1714 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1716 int rsc2 = 16-rsc, gsc2 = 8-gsc;
1717 for (h = lines - 1; h >= 0; h--) {
1718 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1719 for (x = 0; x < srcwidth; x++, ptr++) {
1721 *ptr = ((val >> rsc2) & rDst) |
1722 ((val >> gsc2) & gDst) |
1723 ((val >> 3) & bDst);
1725 ptr = (LPWORD)(dstbits += linebytes);
1728 /* ==== 24/32 RGB bitmap ==== */
1729 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1732 for (h = lines - 1; h >= 0; h--) {
1733 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1734 for (x = 0; x < srcwidth; x++, ptr++) {
1736 *ptr = ((val << rsc) & rDst) |
1737 ((val >> gsc2) & gDst) |
1738 ((val >> 19) & bDst);
1740 ptr = (LPWORD) (dstbits += linebytes);
1743 else goto notsupported;
1748 /* ==== monochrome bitmap ==== */
1750 /* ==== 4 colormap bitmap ==== */
1751 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1753 LPWORD ptr = (LPWORD)dstbits;
1756 for (h = lines - 1; h >= 0; h--) {
1757 for (x = 0; x < dstwidth; x++) {
1758 val = srccolors[XGetPixel(bmpImage, x, h)];
1759 *ptr++ = ((val.peRed << rsc) & rDst) |
1760 ((val.peGreen << gsc) & gDst) |
1761 ((val.peBlue >> 3) & bDst);
1763 ptr = (LPWORD)(dstbits += linebytes);
1766 else goto notsupported;
1771 /* ==== 8 colormap bitmap ==== */
1772 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1774 LPWORD ptr = (LPWORD)dstbits;
1778 for (h = lines - 1; h >= 0; h--) {
1779 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1780 for (x = 0; x < dstwidth; x++) {
1781 val = srccolors[(int)*srcpixel++];
1782 *ptr++ = ((val.peRed << rsc) & rDst) |
1783 ((val.peGreen << gsc) & gDst) |
1784 ((val.peBlue >> 3) & bDst);
1786 ptr = (LPWORD)(dstbits += linebytes);
1789 else goto notsupported;
1797 LPWORD ptr = (LPWORD)dstbits;
1799 FIXME("from %d bit bitmap with mask R,G,B %lx,%lx,%lx to 16 bit DIB %lx,%lx,%lx\n",
1800 bmpImage->depth, bmpImage->red_mask,
1801 bmpImage->green_mask, bmpImage->blue_mask,
1804 for (h = lines - 1; h >= 0; h--)
1806 for (x = 0; x < dstwidth; x++, ptr++)
1808 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
1809 r = (BYTE) GetRValue(pixel);
1810 g = (BYTE) GetGValue(pixel);
1811 b = (BYTE) GetBValue(pixel);
1812 *ptr = ( ((r << rsc) & rDst) | ((g << gsc) & gDst) | ((b >> 3) & bDst) );
1814 ptr = (LPWORD) (dstbits += linebytes);
1822 /***********************************************************************
1823 * X11DRV_DIB_SetImageBits_24
1825 * SetDIBits for a 24-bit deep DIB.
1827 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
1828 DWORD srcwidth, DWORD dstwidth, int left,
1829 DC *dc, XImage *bmpImage, DWORD linebytes )
1837 srcbits = srcbits + linebytes * (lines - 1);
1838 linebytes = -linebytes;
1841 switch ( bmpImage->depth )
1845 if (bmpImage->bits_per_pixel == 24) {
1846 int dstlinebytes = linebytes;
1848 BYTE *ptr = (BYTE *)(srcbits+left*3);
1850 if (dstlinebytes < 0 ) dstlinebytes = -dstlinebytes;
1851 dstpixel = bmpImage->data + lines*dstlinebytes + left*3;
1852 for(h = lines ; h-- ; ) {
1853 dstpixel-=dstlinebytes;
1854 memcpy(dstpixel,ptr,dstwidth*3);
1862 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 ) /* packed BGR to unpacked BGR */
1864 DWORD *dstpixel, val, buf;
1865 DWORD *ptr = (DWORD *)(srcbits + left*3);
1867 int div = dstwidth % 4;
1870 for(h = lines - 1; h >= 0; h--)
1872 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1874 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1876 *dstpixel++ = buf&0x00ffffff; /* b1, g1, r1 */
1877 val = (buf >> 24); /* b2 */
1879 *dstpixel++ = (val | (buf<<8)) &0x00ffffff; /* g2, r2 */
1880 val = (buf >> 16); /* b3, g3 */
1882 *dstpixel++ = (val | (buf<<16)) &0x00ffffff; /* r3 */
1883 *dstpixel++ = (buf >> 8); /* b4, g4, r4 */
1885 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1887 *dstpixel++ = *(DWORD*)bits & 0x00ffffff; /* b, g, r */
1889 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1892 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff ) /* packed BGR to unpacked RGB */
1894 DWORD *dstpixel, val, buf;
1895 DWORD *ptr = (DWORD *)(srcbits + left*3);
1897 int div = dstwidth % 4;
1900 for(h = lines - 1; h >= 0; h--)
1902 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1904 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1906 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b1, g1, r1 */
1907 val = ((buf&0xff000000)>>8); /* b2 */
1909 *dstpixel++ = val | ((buf&0xff)<<8) | ((buf&0xff00)>>8); /* g2, r2 */
1910 val = (buf&0xff0000) | ((buf&0xff000000)>>16); /* b3, g3 */
1912 *dstpixel++ = val | (buf&0xff); /* r3 */
1913 *dstpixel++ = ((buf&0xff00)<<8) | ((buf&0xff0000)>>8) | (buf>>24); /* b4, g4, r4 */
1915 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1917 buf = *(DWORD*)bits;
1918 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b, g, r */
1920 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1930 if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f ) /* BGR888 to RGB555 */
1932 DWORD *ptr = (DWORD *)(srcbits + left*3);
1935 int div = dstwidth % 4;
1938 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1939 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1940 for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1941 *dstpixel++ = ((ptr[0] << 7) & 0x7c00) | ((ptr[0] >> 6) & 0x03e0) | ((ptr[0] >> 19) & 0x1f);
1942 *dstpixel++ = ((ptr[0] >> 17) & 0x7c00) | ((ptr[1] << 2) & 0x03e0) | ((ptr[1] >> 11) & 0x1f);
1943 *dstpixel++ = ((ptr[1] >> 9) & 0x07c00) | ((ptr[1] >> 22) & 0x03e0) | ((ptr[2] >> 3) & 0x1f);
1944 *dstpixel++ = ((ptr[2] >> 1) & 0x07c00) | ((ptr[2] >> 14) & 0x03e0) | ((ptr[2] >> 27) & 0x1f);
1946 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1947 *dstpixel++ = (((WORD)bits[0] << 7) & 0x07c00) |
1948 (((WORD)bits[1] << 2) & 0x03e0) |
1949 (((WORD)bits[2] >> 3) & 0x001f);
1950 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1953 else if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 ) /* BGR888 to BGR555 */
1955 DWORD *ptr = (DWORD *)(srcbits + left*3);
1958 int div = dstwidth % 4;
1961 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1962 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1963 for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1964 *dstpixel++ = ((ptr[0] >> 3) & 0x1f) | ((ptr[0] >> 6) & 0x03e0) | ((ptr[0] >> 9) & 0x7c00);
1965 *dstpixel++ = ((ptr[0] >> 27) & 0x1f) | ((ptr[1] << 2) & 0x03e0) | ((ptr[1] >> 1) & 0x7c00);
1966 *dstpixel++ = ((ptr[1] >> 19) & 0x1f) | ((ptr[1] >> 22) & 0x03e0) | ((ptr[2] << 7) & 0x7c00);
1967 *dstpixel++ = ((ptr[2] >> 11) & 0x1f) | ((ptr[2] >> 14) & 0x03e0) | ((ptr[2] >> 17) & 0x7c00);
1969 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1970 *dstpixel++ = (((WORD)bits[2] << 7) & 0x07c00) |
1971 (((WORD)bits[1] << 2) & 0x03e0) |
1972 (((WORD)bits[0] >> 3) & 0x001f);
1973 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1983 DWORD *ptr = (DWORD *)(srcbits + left*3);
1986 int div = dstwidth % 4;
1989 if( bmpImage->blue_mask == 0x001f && bmpImage->red_mask == 0xf800 ) /* BGR888 to BGR565 */
1991 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1992 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1993 for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1994 *dstpixel++ = ((ptr[0] >> 3) & 0x1f) | ((ptr[0] >> 5) & 0x07e0) | ((ptr[0] >> 8) & 0xf800);
1995 *dstpixel++ = ((ptr[0] >> 27) & 0x1f) | ((ptr[1] << 3) & 0x07e0) | (ptr[1] & 0xf800);
1996 *dstpixel++ = ((ptr[1] >> 19) & 0x1f) | ((ptr[1] >> 21) & 0x07e0) | ((ptr[2] << 8) & 0xf800);
1997 *dstpixel++ = ((ptr[2] >> 11) & 0x1f) | ((ptr[2] >> 13) & 0x07e0) | ((ptr[2] >> 16) & 0xf800);
1999 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
2000 *dstpixel++ = (((WORD)bits[2] << 8) & 0xf800) |
2001 (((WORD)bits[1] << 3) & 0x07e0) |
2002 (((WORD)bits[0] >> 3) & 0x001f);
2003 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
2006 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x001f ) /* BGR888 to RGB565 */
2008 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
2009 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
2010 for (x = 0; x < dstwidth/4; x++, ptr += 3) {
2011 *dstpixel++ = ((ptr[0] << 8) & 0xf800) | ((ptr[0] >> 5) & 0x07e0) | ((ptr[0] >> 19) & 0x1f);
2012 *dstpixel++ = ((ptr[0] >> 16) & 0xf800) | ((ptr[1] << 3) & 0x07e0) | ((ptr[1] >> 11) & 0x1f);
2013 *dstpixel++ = ((ptr[1] >> 8) & 0xf800) | ((ptr[1] >> 21) & 0x07e0) | ((ptr[2] >> 3) & 0x1f);
2014 *dstpixel++ = (ptr[2] & 0xf800) | ((ptr[2] >> 13) & 0x07e0) | ((ptr[2] >> 27) & 0x1f);
2016 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
2017 *dstpixel++ = (((WORD)bits[0] << 8) & 0xf800) |
2018 (((WORD)bits[1] << 3) & 0x07e0) |
2019 (((WORD)bits[2] >> 3) & 0x001f);
2020 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
2032 LPBYTE bits = (LPBYTE)srcbits + left*3;
2034 for (h = lines - 1; h >= 0; h--) {
2035 for (x = left; x < dstwidth+left; x++, bits+=3)
2036 XPutPixel( bmpImage, x, h,
2037 X11DRV_PALETTE_ToPhysical(dc, RGB(bits[2], bits[1], bits[0])));
2038 bits = (LPBYTE)(srcbits += linebytes) + left * 3;
2045 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
2046 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
2047 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2053 /***********************************************************************
2054 * X11DRV_DIB_GetImageBits_24
2056 * GetDIBits for an 24-bit deep DIB.
2058 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
2059 DWORD dstwidth, DWORD srcwidth,
2060 PALETTEENTRY *srccolors,
2061 XImage *bmpImage, DWORD linebytes )
2069 dstbits = dstbits + ( linebytes * (lines-1) );
2070 linebytes = -linebytes;
2073 switch ( bmpImage->depth )
2077 if (bmpImage->bits_per_pixel == 24) {
2078 int tocopy = linebytes;
2080 BYTE *ptr = (LPBYTE)dstbits;
2082 if (tocopy < 0 ) tocopy = -tocopy;
2083 srcpixel = bmpImage->data + lines*tocopy;
2084 for(h = lines ; h-- ; ) {
2086 memcpy(ptr,srcpixel,tocopy);
2087 ptr = (LPBYTE)(dstbits+=linebytes);
2094 DWORD *srcpixel, buf;
2096 DWORD *ptr=(DWORD *)dstbits;
2097 int quotient = dstwidth / 4;
2098 int remainder = dstwidth % 4;
2101 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
2102 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 )
2104 for(h = lines - 1; h >= 0; h--)
2106 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2108 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
2109 buf = ((*srcpixel++)&0x00ffffff); /* b1, g1, r1*/
2110 *ptr++ = buf | ((*srcpixel)<<24); /* b2 */
2111 buf = ((*srcpixel++>>8)&0x0000ffff); /* g2, r2 */
2112 *ptr++ = buf | ((*srcpixel)<<16); /* b3, g3 */
2113 buf = ((*srcpixel++>>16)&0x000000ff); /* r3 */
2114 *ptr++ = buf | ((*srcpixel++)<<8); /* b4, g4, r4 */
2116 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2119 *(WORD*)bits = buf; /* b, g */
2120 *(bits+2) = buf>>16; /* r */
2122 ptr = (DWORD*)(dstbits+=linebytes);
2126 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
2127 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff )
2129 for(h = lines - 1; h >= 0; h--)
2131 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2133 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
2135 val = ((buf&0xff0000)>>16) | (buf&0xff00) | ((buf&0xff)<<16); /* b1, g1, r1 */
2137 *ptr++ = val | ((buf&0xff0000)<<8); /* b2 */
2138 val = ((buf&0xff00)>>8) | ((buf&0xff)<<8); /* g2, r2 */
2140 *ptr++ = val | (buf&0xff0000) | ((buf&0xff00)<<16); /* b3, g3 */
2141 val = (buf&0xff); /* r3 */
2143 *ptr++ = val | ((buf&0xff0000)>>8) | ((buf&0xff00)<<8) | (buf<<24); /* b4, g4, r4 */
2145 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2148 *(WORD*)bits = (buf&0xff00) | ((buf&0xff0000)>>16) ; /* b, g */
2149 *(bits+2) = buf; /* r */
2151 ptr = (DWORD*)(dstbits+=linebytes);
2154 else goto notsupported;
2161 LPBYTE bits = dstbits;
2164 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2165 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 )
2167 for (h = lines - 1; h >= 0; h--) {
2168 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2169 for (x = 0; x < srcwidth; x++, bits += 3) {
2171 bits[2] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2172 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2173 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2175 bits = (dstbits += linebytes);
2178 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2179 else if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f )
2181 for (h = lines - 1; h >= 0; h--) {
2182 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2183 for (x = 0; x < srcwidth; x++, bits += 3) {
2185 bits[0] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2186 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2187 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2189 bits = (dstbits += linebytes);
2192 else goto notsupported;
2199 LPBYTE bits = dstbits;
2202 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2203 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0xf800 )
2205 for (h = lines - 1; h >= 0; h--) {
2206 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2207 for (x = 0; x < srcwidth; x++, bits += 3) {
2209 bits[2] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2210 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2211 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2213 bits = (dstbits += linebytes);
2216 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2217 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x1f )
2219 for (h = lines - 1; h >= 0; h--) {
2220 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2221 for (x = 0; x < srcwidth; x++, bits += 3) {
2223 bits[0] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2224 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2225 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2227 bits = (dstbits += linebytes);
2230 else goto notsupported;
2235 /* ==== monochrome bitmap to 24 BGR dib ==== */
2237 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2238 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2240 LPBYTE bits = dstbits;
2243 for (h = lines - 1; h >= 0; h--) {
2244 for (x = 0; x < dstwidth; x++) {
2245 val = srccolors[XGetPixel(bmpImage, x, h)];
2246 *bits++ = val.peBlue;
2247 *bits++ = val.peGreen;
2248 *bits++ = val.peRed;
2250 bits = (dstbits += linebytes);
2253 else goto notsupported;
2258 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2259 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors)
2262 LPBYTE bits = dstbits;
2265 for (h = lines - 1; h >= 0; h--) {
2266 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2267 for (x = 0; x < dstwidth; x++ ) {
2268 val = srccolors[(int)*srcpixel++];
2269 *bits++ = val.peBlue; /*Blue*/
2270 *bits++ = val.peGreen; /*Green*/
2271 *bits++ = val.peRed; /*Red*/
2273 bits = (dstbits += linebytes);
2276 else goto notsupported;
2283 LPBYTE bits = dstbits;
2285 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2286 bmpImage->depth, (int)bmpImage->red_mask,
2287 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2288 for (h = lines - 1; h >= 0; h--)
2290 for (x = 0; x < dstwidth; x++, bits += 3)
2292 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2293 bits[0] = GetBValue(pixel);
2294 bits[1] = GetGValue(pixel);
2295 bits[2] = GetRValue(pixel);
2297 bits = (dstbits += linebytes);
2305 /***********************************************************************
2306 * X11DRV_DIB_SetImageBits_32
2308 * SetDIBits for a 32-bit deep DIB.
2310 static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
2311 DWORD srcwidth, DWORD dstwidth, int left,
2312 DC *dc, XImage *bmpImage,
2321 srcbits = srcbits + ( linebytes * (lines-1) );
2322 linebytes = -linebytes;
2325 ptr = (DWORD *) srcbits + left;
2327 switch ( bmpImage->depth )
2330 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2331 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) {
2332 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2333 memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2337 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2338 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
2342 for (h = lines - 1; h >= 0; h--) {
2343 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2344 for (x = 0; x < dstwidth; x++, ptr++) {
2345 *dstpixel++ = ((*ptr << 16) & 0xff0000) | (*ptr & 0xff00) | ((*ptr >> 16) & 0xff);
2347 ptr = (DWORD *) (srcbits += linebytes) + left;
2350 else goto notsupported;
2355 /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
2356 /* we need to check that source mask matches destination */
2357 if (bmpImage->bits_per_pixel == 32)
2359 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2360 memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2367 ptr = (DWORD *) srcbits + left;
2368 bptr = bmpImage->data;
2370 for (h = lines - 1; h >= 0; h--) {
2371 for (x = 0; x < dstwidth; x++) {
2372 /* *ptr is a 32bit value */
2373 /* bptr points to first of 3 bytes */
2374 *bptr++ = (*ptr >> 16) & 0xff;
2375 *bptr++ = (*ptr >> 8) & 0xff;
2376 *bptr++ = (*ptr ) & 0xff;
2379 ptr = (DWORD *) (srcbits += linebytes) + left;
2385 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2386 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f) {
2389 for (h = lines - 1; h >= 0; h--) {
2390 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2391 for (x = 0; x < dstwidth; x++, ptr++) {
2392 *dstpixel++ = (WORD) (((*ptr >> 9) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 3) & 0x001f));
2394 ptr = (DWORD *) (srcbits += linebytes) + left;
2397 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2398 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2402 for (h = lines - 1; h >= 0; h--) {
2403 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2404 for (x = 0; x < dstwidth; x++, ptr++) {
2405 *dstpixel++ = (WORD) (((*ptr << 7) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 19) & 0x001f));
2407 ptr = (DWORD *) (srcbits += linebytes) + left;
2410 else goto notsupported;
2415 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2416 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2420 for (h = lines - 1; h >= 0; h--) {
2421 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2422 for (x = 0; x < dstwidth; x++, ptr++) {
2423 *dstpixel++ = (WORD) (((*ptr >> 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 3) & 0x001f));
2425 ptr = (DWORD *) (srcbits += linebytes) + left;
2428 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2429 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
2433 for (h = lines - 1; h >= 0; h--) {
2434 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2435 for (x = 0; x < dstwidth; x++, ptr++) {
2436 *dstpixel++ = (WORD) (((*ptr << 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 19) & 0x001f));
2438 ptr = (DWORD *) (srcbits += linebytes) + left;
2441 else goto notsupported;
2449 LPBYTE bits = (LPBYTE)srcbits + left*4;
2451 for (h = lines - 1; h >= 0; h--) {
2452 for (x = left; x < dstwidth+left; x++, bits += 4)
2453 XPutPixel( bmpImage, x, h,
2454 X11DRV_PALETTE_ToPhysical(dc, RGB( bits[2], bits[1], *bits )));
2455 bits = (LPBYTE)(srcbits += linebytes) + left * 4;
2462 FIXME("32 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
2468 /***********************************************************************
2469 * X11DRV_DIB_GetImageBits_32
2471 * GetDIBits for an 32-bit deep DIB.
2473 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
2474 DWORD dstwidth, DWORD srcwidth,
2475 PALETTEENTRY *srccolors,
2476 XImage *bmpImage, DWORD linebytes )
2482 DWORD copybytes = srcwidth * 4;
2487 dstbits = dstbits + ( linebytes * (lines-1) );
2488 linebytes = -linebytes;
2493 switch ( bmpImage->depth )
2496 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2497 if ( bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff )
2498 for (h = lines - 1; h >= 0; h--, dstbits+=linebytes)
2499 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, copybytes );
2501 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2502 else if ( bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000 )
2506 for (h = lines - 1; h >= 0; h--) {
2507 srcbits = bmpImage->data + h * bmpImage->bytes_per_line;
2508 for (x = 0; x < dstwidth; x++, bits+=4, srcbits+=2) {
2509 *(bits + 2) = *srcbits++;
2510 *(bits + 1) = *srcbits++;
2513 bits = (dstbits += linebytes);
2516 else goto notsupported;
2520 /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */
2521 /* we need to check that source mask matches destination */
2527 srcpixel = (DWORD *) dstbits;
2528 bptr = bmpImage->data;
2530 for (h = lines - 1; h >= 0; h--) {
2531 for (x = 0; x < dstwidth; x++) {
2532 /* *srcpixel is a 32bit value */
2533 /* bptr points to first of 3 bytes */
2535 srcdata = srcdata << 8 | *bptr++;
2536 srcdata = srcdata << 8 | *bptr++;
2537 srcdata = srcdata << 8 | *bptr++;
2539 *srcpixel++ = srcdata;
2541 srcpixel = (DWORD *) (dstbits += linebytes);
2551 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2552 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
2554 for (h = lines - 1; h >= 0; h--) {
2555 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2556 for (x = 0; x < dstwidth; x++, bits+=2) {
2558 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2559 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2560 *bits = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2562 bits = (dstbits += linebytes);
2565 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2566 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2568 for (h = lines - 1; h >= 0; h--) {
2569 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2570 for (x = 0; x < dstwidth; x++, bits+=2) {
2572 *bits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));/*Blue*/
2573 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2574 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2576 bits = (dstbits += linebytes);
2579 else goto notsupported;
2588 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2589 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2591 for (h = lines - 1; h >= 0; h--) {
2592 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2593 for (x = 0; x < srcwidth; x++, bits+=2) {
2595 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2596 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2597 *bits = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2599 bits = (dstbits += linebytes);
2602 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2603 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2605 for (h = lines - 1; h >= 0; h--) {
2606 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2607 for (x = 0; x < srcwidth; x++, bits+=2) {
2609 *bits++ = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));/*Blue*/
2610 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2611 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2613 bits = (dstbits += linebytes);
2616 else goto notsupported;
2621 /* ==== monochrome bitmap to 32 BGR dib ==== */
2623 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2624 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2628 for (h = lines - 1; h >= 0; h--) {
2629 for (x = 0; x < dstwidth; x++) {
2630 val = srccolors[XGetPixel(bmpImage, x, h)];
2631 *bits++ = val.peBlue;
2632 *bits++ = val.peGreen;
2633 *bits++ = val.peRed;
2636 bits = (dstbits += linebytes);
2639 else goto notsupported;
2644 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2645 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2650 for (h = lines - 1; h >= 0; h--) {
2651 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2652 for (x = 0; x < dstwidth; x++) {
2653 val = srccolors[(int)*srcpixel++];
2654 *bits++ = val.peBlue; /*Blue*/
2655 *bits++ = val.peGreen; /*Green*/
2656 *bits++ = val.peRed; /*Red*/
2659 bits = (dstbits += linebytes);
2662 else goto notsupported;
2667 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2668 bmpImage->depth, (int)bmpImage->red_mask,
2669 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2670 for (h = lines - 1; h >= 0; h--)
2672 for (x = 0; x < dstwidth; x++, bits += 4)
2674 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2675 bits[0] = GetBValue(pixel);
2676 bits[1] = GetGValue(pixel);
2677 bits[2] = GetRValue(pixel);
2679 bits = (dstbits += linebytes);
2685 /***********************************************************************
2686 * X11DRV_DIB_SetImageBits
2688 * Transfer the bits to an X image.
2689 * Helper function for SetDIBits() and SetDIBitsToDevice().
2691 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2693 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2698 bmpImage = descr->image;
2700 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
2701 descr->infoWidth, lines, 32, 0 );
2702 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2703 if(bmpImage->data == NULL) {
2704 ERR("Out of memory!\n");
2705 XDestroyImage( bmpImage );
2706 wine_tsx11_unlock();
2711 /* Transfer the pixels */
2712 switch(descr->infoBpp)
2715 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
2716 descr->width, descr->xSrc, (int *)(descr->colorMap),
2717 bmpImage, descr->dibpitch );
2720 if (descr->compression) {
2721 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
2722 descr->width, descr->height, AllPlanes, ZPixmap,
2723 bmpImage, descr->xSrc, descr->ySrc );
2725 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
2726 descr->infoWidth, descr->width,
2727 descr->xSrc, (int *)(descr->colorMap),
2730 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
2731 descr->infoWidth, descr->width,
2732 descr->xSrc, (int*)(descr->colorMap),
2733 bmpImage, descr->dibpitch );
2736 if (descr->compression) {
2737 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
2738 descr->width, descr->height, AllPlanes, ZPixmap,
2739 bmpImage, descr->xSrc, descr->ySrc );
2740 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
2741 descr->infoWidth, descr->width,
2742 descr->xSrc, (int *)(descr->colorMap),
2745 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
2746 descr->infoWidth, descr->width,
2747 descr->xSrc, (int *)(descr->colorMap),
2748 bmpImage, descr->dibpitch );
2752 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
2753 descr->infoWidth, descr->width,
2754 descr->xSrc, descr->dc,
2755 descr->rMask, descr->gMask, descr->bMask,
2756 bmpImage, descr->dibpitch);
2759 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
2760 descr->infoWidth, descr->width,
2761 descr->xSrc, descr->dc, bmpImage,
2765 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
2766 descr->infoWidth, descr->width,
2767 descr->xSrc, descr->dc,
2768 bmpImage, descr->dibpitch);
2771 WARN("(%d): Invalid depth\n", descr->infoBpp );
2775 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
2776 descr->drawable, descr->gc, bmpImage,
2777 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2778 descr->width, descr->height);
2781 XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
2782 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2783 descr->width, descr->height, FALSE );
2784 XSync( gdi_display, 0 );
2787 XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
2788 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2789 descr->width, descr->height );
2791 if (!descr->image) XDestroyImage( bmpImage );
2792 wine_tsx11_unlock();
2796 /***********************************************************************
2797 * X11DRV_DIB_GetImageBits
2799 * Transfer the bits from an X image.
2801 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2803 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2808 bmpImage = descr->image;
2810 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
2811 descr->infoWidth, lines, 32, 0 );
2812 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2813 if(bmpImage->data == NULL) {
2814 ERR("Out of memory!\n");
2815 XDestroyImage( bmpImage );
2816 wine_tsx11_unlock();
2821 TRACE("XGetSubImage(%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
2822 descr->drawable, descr->xSrc, descr->ySrc, descr->width,
2823 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
2824 XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
2825 descr->width, lines, AllPlanes, ZPixmap,
2826 bmpImage, descr->xDest, descr->yDest );
2828 /* Transfer the pixels */
2829 switch(descr->infoBpp)
2832 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
2833 descr->infoWidth, descr->width,
2834 descr->colorMap, descr->palentry,
2835 bmpImage, descr->dibpitch );
2839 if (descr->compression)
2840 FIXME("Compression not yet supported!\n");
2842 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
2843 descr->infoWidth, descr->width,
2844 descr->colorMap, descr->palentry,
2845 bmpImage, descr->dibpitch );
2849 if (descr->compression)
2850 FIXME("Compression not yet supported!\n");
2852 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
2853 descr->infoWidth, descr->width,
2854 descr->colorMap, descr->palentry,
2855 bmpImage, descr->dibpitch );
2859 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
2860 descr->infoWidth,descr->width,
2862 descr->rMask, descr->gMask, descr->bMask,
2863 bmpImage, descr->dibpitch );
2867 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
2868 descr->infoWidth,descr->width,
2869 descr->palentry, bmpImage, descr->dibpitch);
2873 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
2874 descr->infoWidth, descr->width,
2875 descr->palentry, bmpImage, descr->dibpitch);
2879 WARN("(%d): Invalid depth\n", descr->infoBpp );
2883 if (!descr->image) XDestroyImage( bmpImage );
2884 wine_tsx11_unlock();
2888 /*************************************************************************
2889 * X11DRV_SetDIBitsToDevice
2892 INT X11DRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx,
2893 DWORD cy, INT xSrc, INT ySrc,
2894 UINT startscan, UINT lines, LPCVOID bits,
2895 const BITMAPINFO *info, UINT coloruse )
2897 X11DRV_DIB_IMAGEBITS_DESCR descr;
2898 DWORD width, oldcy = cy;
2900 int height, tmpheight;
2901 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
2904 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
2905 &descr.infoBpp, &descr.compression ) == -1)
2908 if (height < 0) height = -height;
2909 if (!lines || (startscan >= height)) return 0;
2910 if (startscan + lines > height) lines = height - startscan;
2911 if (ySrc < startscan) ySrc = startscan;
2912 else if (ySrc >= startscan + lines) return 0;
2913 if (xSrc >= width) return 0;
2914 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
2915 if (xSrc + cx >= width) cx = width - xSrc;
2916 if (!cx || !cy) return 0;
2918 X11DRV_SetupGCForText( dc ); /* To have the correct colors */
2919 TSXSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);
2921 switch (descr.infoBpp)
2926 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
2927 coloruse == DIB_PAL_COLORS ? dc : NULL, coloruse,
2928 dc->bitsPerPixel, info, &descr.nColorMap );
2929 if (!descr.colorMap) return 0;
2930 descr.rMask = descr.gMask = descr.bMask = 0;
2934 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2935 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
2936 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
2941 descr.rMask = descr.gMask = descr.bMask = 0;
2946 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2947 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
2948 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
2956 descr.palentry = NULL;
2957 descr.lines = tmpheight >= 0 ? lines : -lines;
2958 descr.infoWidth = width;
2959 descr.depth = dc->bitsPerPixel;
2960 descr.drawable = physDev->drawable;
2961 descr.gc = physDev->gc;
2963 descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy)
2965 descr.xDest = dc->DCOrgX + XLPTODP( dc, xDest );
2966 descr.yDest = dc->DCOrgY + YLPTODP( dc, yDest ) +
2967 (tmpheight >= 0 ? oldcy-cy : 0);
2970 descr.useShm = FALSE;
2971 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
2973 result = X11DRV_DIB_SetImageBits( &descr );
2975 if (descr.infoBpp <= 8)
2976 HeapFree(GetProcessHeap(), 0, descr.colorMap);
2980 /***********************************************************************
2981 * X11DRV_DIB_SetDIBits
2983 INT X11DRV_DIB_SetDIBits(
2984 BITMAPOBJ *bmp, DC *dc, UINT startscan,
2985 UINT lines, LPCVOID bits, const BITMAPINFO *info,
2986 UINT coloruse, HBITMAP hbitmap)
2988 X11DRV_DIB_IMAGEBITS_DESCR descr;
2989 int height, tmpheight;
2994 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
2995 &descr.infoBpp, &descr.compression ) == -1)
2999 if (height < 0) height = -height;
3000 if (!lines || (startscan >= height))
3003 if (startscan + lines > height) lines = height - startscan;
3005 switch (descr.infoBpp)
3010 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3011 coloruse == DIB_PAL_COLORS ? descr.dc : NULL, coloruse,
3012 bmp->bitmap.bmBitsPixel,
3013 info, &descr.nColorMap );
3014 if (!descr.colorMap) return 0;
3015 descr.rMask = descr.gMask = descr.bMask = 0;
3019 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3020 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3021 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3026 descr.rMask = descr.gMask = descr.bMask = 0;
3031 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3032 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
3033 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
3041 if(!bmp->physBitmap)
3042 X11DRV_CreateBitmap(hbitmap);
3046 descr.palentry = NULL;
3047 descr.lines = tmpheight >= 0 ? lines : -lines;
3048 descr.depth = bmp->bitmap.bmBitsPixel;
3049 descr.drawable = (Pixmap)bmp->physBitmap;
3050 descr.gc = BITMAP_GC(bmp);
3054 descr.yDest = height - startscan - lines;
3055 descr.width = bmp->bitmap.bmWidth;
3056 descr.height = lines;
3057 descr.useShm = FALSE;
3058 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
3059 result = X11DRV_DIB_SetImageBits( &descr );
3061 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
3066 /***********************************************************************
3067 * X11DRV_DIB_GetDIBits
3069 INT X11DRV_DIB_GetDIBits(
3070 BITMAPOBJ *bmp, DC *dc, UINT startscan,
3071 UINT lines, LPVOID bits, BITMAPINFO *info,
3072 UINT coloruse, HBITMAP hbitmap)
3074 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3075 X11DRV_DIB_IMAGEBITS_DESCR descr;
3076 PALETTEOBJ * palette;
3079 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3080 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
3081 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
3084 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
3087 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
3089 height = info->bmiHeader.biHeight;
3090 if (height < 0) height = -height;
3091 if( lines > height ) lines = height;
3092 /* Top-down images have a negative biHeight, the scanlines of theses images
3093 * were inverted in X11DRV_DIB_GetImageBits_xx
3094 * To prevent this we simply change the sign of lines
3095 * (the number of scan lines to copy).
3096 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3098 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
3100 if( startscan >= bmp->bitmap.bmHeight )
3106 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
3107 &descr.infoBpp, &descr.compression ) == -1)
3113 switch (descr.infoBpp)
3119 descr.rMask = descr.gMask = descr.bMask = 0;
3123 descr.rMask = 0x7c00;
3124 descr.gMask = 0x03e0;
3125 descr.bMask = 0x001f;
3129 descr.rMask = 0xff0000;
3130 descr.gMask = 0xff00;
3136 if(!bmp->physBitmap)
3137 X11DRV_CreateBitmap(hbitmap);
3141 descr.palentry = palette->logpalette.palPalEntry;
3144 descr.lines = lines;
3145 descr.depth = bmp->bitmap.bmBitsPixel;
3146 descr.drawable = (Pixmap)bmp->physBitmap;
3147 descr.gc = BITMAP_GC(bmp);
3148 descr.width = bmp->bitmap.bmWidth;
3149 descr.height = bmp->bitmap.bmHeight;
3150 descr.colorMap = info->bmiColors;
3155 if (descr.lines > 0)
3157 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
3161 descr.ySrc = startscan;
3163 #ifdef HAVE_LIBXXSHM
3164 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
3166 descr.useShm = FALSE;
3168 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
3169 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
3171 X11DRV_DIB_GetImageBits( &descr );
3173 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
3174 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
3175 info->bmiHeader.biWidth,
3176 info->bmiHeader.biHeight,
3177 info->bmiHeader.biBitCount );
3179 info->bmiHeader.biCompression = 0;
3180 if (descr.compression == BI_BITFIELDS)
3182 *(DWORD *)info->bmiColors = descr.rMask;
3183 *((DWORD *)info->bmiColors+1) = descr.gMask;
3184 *((DWORD *)info->bmiColors+2) = descr.bMask;
3188 GDI_ReleaseObj( dc->hPalette );
3193 /***********************************************************************
3194 * DIB_DoProtectDIBSection
3196 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
3198 DIBSECTION *dib = bmp->dib;
3199 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
3200 : -dib->dsBm.bmHeight;
3201 /* use the biSizeImage data as the memory size only if we're dealing with a
3202 compressed image where the value is set. Otherwise, calculate based on
3204 INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
3205 ? dib->dsBmih.biSizeImage
3206 : dib->dsBm.bmWidthBytes * effHeight;
3209 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
3210 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
3213 /***********************************************************************
3214 * X11DRV_DIB_DoUpdateDIBSection
3216 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
3217 void *colorMap, int nColorMap,
3219 DWORD xSrc, DWORD ySrc,
3220 DWORD xDest, DWORD yDest,
3221 DWORD width, DWORD height)
3223 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3224 X11DRV_DIB_IMAGEBITS_DESCR descr;
3226 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
3227 &descr.infoBpp, &descr.compression ) == -1)
3231 descr.palentry = NULL;
3232 descr.image = dib->image;
3233 descr.colorMap = colorMap;
3234 descr.nColorMap = nColorMap;
3235 descr.bits = dib->dibSection.dsBm.bmBits;
3236 descr.depth = bmp->bitmap.bmBitsPixel;
3238 switch (descr.infoBpp)
3244 descr.rMask = descr.gMask = descr.bMask = 0;
3248 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
3249 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
3250 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
3254 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff;
3255 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0xff00;
3256 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0xff0000;
3261 descr.drawable = dest;
3262 descr.gc = BITMAP_GC(bmp);
3265 descr.xDest = xDest;
3266 descr.yDest = yDest;
3267 descr.width = width;
3268 descr.height = height;
3269 #ifdef HAVE_LIBXXSHM
3270 descr.useShm = (dib->shminfo.shmid != -1);
3272 descr.useShm = FALSE;
3274 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
3278 TRACE("Copying from Pixmap to DIB bits\n");
3279 X11DRV_DIB_GetImageBits( &descr );
3283 TRACE("Copying from DIB bits to Pixmap\n");
3284 X11DRV_DIB_SetImageBits( &descr );
3288 /***********************************************************************
3289 * X11DRV_DIB_CopyDIBSection
3291 void X11DRV_DIB_CopyDIBSection(DC *dcSrc, DC *dcDst,
3292 DWORD xSrc, DWORD ySrc,
3293 DWORD xDest, DWORD yDest,
3294 DWORD width, DWORD height)
3297 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcDst->physDev;
3298 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
3300 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst,
3301 xSrc, ySrc, xDest, yDest, width, height);
3302 /* this function is meant as an optimization for BitBlt,
3303 * not to be called otherwise */
3304 if (!(dcSrc->flags & DC_MEMORY)) {
3305 ERR("called for non-memory source DC!?\n");
3309 bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC );
3310 if (!(bmp && bmp->dib)) {
3311 ERR("called for non-DIBSection!?\n");
3312 GDI_ReleaseObj( dcSrc->hBitmap );
3315 /* while BitBlt should already have made sure we only get
3316 * positive values, we should check for oversize values */
3317 if ((xSrc < bmp->bitmap.bmWidth) &&
3318 (ySrc < bmp->bitmap.bmHeight)) {
3319 if (xSrc + width > bmp->bitmap.bmWidth)
3320 width = bmp->bitmap.bmWidth - xSrc;
3321 if (ySrc + height > bmp->bitmap.bmHeight)
3322 height = bmp->bitmap.bmHeight - ySrc;
3323 /* if the source bitmap is 8bpp or less, we're supposed to use the
3324 * DC's palette for color conversion (not the DIB color table) */
3325 if (bmp->dib->dsBm.bmBitsPixel <= 8) {
3326 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3327 if ((!dcSrc->hPalette) ||
3328 (dcSrc->hPalette == GetStockObject(DEFAULT_PALETTE))) {
3329 /* HACK: no palette has been set in the source DC,
3330 * use the DIB colormap instead - this is necessary in some
3331 * cases since we need to do depth conversion in some places
3332 * where real Windows can just copy data straight over */
3333 colorMap = dib->colorMap;
3334 nColorMap = dib->nColorMap;
3336 colorMap = X11DRV_DIB_BuildColorMap( dcSrc, (WORD)-1,
3337 bmp->dib->dsBm.bmBitsPixel,
3338 (BITMAPINFO*)&(bmp->dib->dsBmih),
3340 if (colorMap) aColorMap = TRUE;
3343 /* perform the copy */
3344 X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
3345 physDev->drawable, xSrc, ySrc, xDest, yDest,
3347 /* free color mapping */
3349 HeapFree(GetProcessHeap(), 0, colorMap);
3351 GDI_ReleaseObj( dcSrc->hBitmap );
3354 /***********************************************************************
3355 * X11DRV_DIB_DoUpdateDIBSection
3357 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
3359 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3360 X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
3361 (Drawable)bmp->physBitmap, 0, 0, 0, 0,
3362 bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
3365 /***********************************************************************
3366 * X11DRV_DIB_FaultHandler
3368 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
3373 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
3374 if (!bmp) return FALSE;
3376 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
3377 if (state != DIB_Status_InSync) {
3378 /* no way to tell whether app needs read or write yet,
3380 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
3382 /* hm, apparently the app must have write access */
3383 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
3385 X11DRV_DIB_Unlock(bmp, TRUE);
3387 GDI_ReleaseObj( (HBITMAP)res );
3391 /***********************************************************************
3394 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
3396 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3397 INT ret = DIB_Status_None;
3400 EnterCriticalSection(&(dib->lock));
3403 case DIB_Status_GdiMod:
3404 /* GDI access - request to draw on pixmap */
3405 switch (dib->status)
3408 case DIB_Status_None:
3409 dib->p_status = DIB_Status_GdiMod;
3410 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3413 case DIB_Status_GdiMod:
3414 TRACE("GdiMod requested in status GdiMod\n" );
3417 case DIB_Status_InSync:
3418 TRACE("GdiMod requested in status InSync\n" );
3419 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3420 dib->status = DIB_Status_GdiMod;
3421 dib->p_status = DIB_Status_InSync;
3424 case DIB_Status_AuxMod:
3425 TRACE("GdiMod requested in status AuxMod\n" );
3426 if (lossy) dib->status = DIB_Status_GdiMod;
3427 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
3428 dib->p_status = DIB_Status_AuxMod;
3429 if (dib->status != DIB_Status_AppMod) {
3430 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3433 /* fall through if copy_aux() had to change to AppMod state */
3435 case DIB_Status_AppMod:
3436 TRACE("GdiMod requested in status AppMod\n" );
3438 /* make it readonly to avoid app changing data while we copy */
3439 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3440 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3442 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3443 dib->p_status = DIB_Status_AppMod;
3444 dib->status = DIB_Status_GdiMod;
3449 case DIB_Status_InSync:
3450 /* App access - request access to read DIB surface */
3451 /* (typically called from signal handler) */
3452 switch (dib->status)
3455 case DIB_Status_None:
3456 /* shouldn't happen from signal handler */
3459 case DIB_Status_AuxMod:
3460 TRACE("InSync requested in status AuxMod\n" );
3461 if (lossy) dib->status = DIB_Status_InSync;
3463 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3464 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
3466 if (dib->status != DIB_Status_GdiMod) {
3467 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3470 /* fall through if copy_aux() had to change to GdiMod state */
3472 case DIB_Status_GdiMod:
3473 TRACE("InSync requested in status GdiMod\n" );
3475 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3476 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3478 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3479 dib->status = DIB_Status_InSync;
3482 case DIB_Status_InSync:
3483 TRACE("InSync requested in status InSync\n" );
3484 /* shouldn't happen from signal handler */
3487 case DIB_Status_AppMod:
3488 TRACE("InSync requested in status AppMod\n" );
3489 /* no reason to do anything here, and this
3490 * shouldn't happen from signal handler */
3495 case DIB_Status_AppMod:
3496 /* App access - request access to write DIB surface */
3497 /* (typically called from signal handler) */
3498 switch (dib->status)
3501 case DIB_Status_None:
3502 /* shouldn't happen from signal handler */
3505 case DIB_Status_AuxMod:
3506 TRACE("AppMod requested in status AuxMod\n" );
3507 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3508 if (lossy) dib->status = DIB_Status_AppMod;
3509 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
3510 if (dib->status != DIB_Status_GdiMod)
3512 /* fall through if copy_aux() had to change to GdiMod state */
3514 case DIB_Status_GdiMod:
3515 TRACE("AppMod requested in status GdiMod\n" );
3516 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3517 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3518 dib->status = DIB_Status_AppMod;
3521 case DIB_Status_InSync:
3522 TRACE("AppMod requested in status InSync\n" );
3523 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3524 dib->status = DIB_Status_AppMod;
3527 case DIB_Status_AppMod:
3528 TRACE("AppMod requested in status AppMod\n" );
3529 /* shouldn't happen from signal handler */
3534 case DIB_Status_AuxMod:
3535 if (dib->status == DIB_Status_None) {
3536 dib->p_status = req;
3538 if (dib->status != DIB_Status_AuxMod)
3539 dib->p_status = dib->status;
3540 dib->status = DIB_Status_AuxMod;
3543 /* it is up to the caller to do the copy/conversion, probably
3544 * using the return value to decide where to copy from */
3546 LeaveCriticalSection(&(dib->lock));
3551 /***********************************************************************
3554 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
3556 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3557 INT ret = DIB_Status_None;
3560 TRACE("Locking %p from thread %08lx\n", bmp, GetCurrentThreadId());
3561 EnterCriticalSection(&(dib->lock));
3563 if (req != DIB_Status_None)
3564 X11DRV_DIB_Coerce(bmp, req, lossy);
3569 /***********************************************************************
3572 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
3574 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3577 switch (dib->status)
3580 case DIB_Status_None:
3581 /* in case anyone is wondering, this is the "signal handler doesn't
3582 * work" case, where we always have to be ready for app access */
3584 switch (dib->p_status)
3586 case DIB_Status_AuxMod:
3587 TRACE("Unlocking and syncing from AuxMod\n" );
3588 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
3589 if (dib->status != DIB_Status_None) {
3590 dib->p_status = dib->status;
3591 dib->status = DIB_Status_None;
3593 if (dib->p_status != DIB_Status_GdiMod)
3595 /* fall through if copy_aux() had to change to GdiMod state */
3597 case DIB_Status_GdiMod:
3598 TRACE("Unlocking and syncing from GdiMod\n" );
3599 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3603 TRACE("Unlocking without needing to sync\n" );
3607 else TRACE("Unlocking with no changes\n");
3608 dib->p_status = DIB_Status_None;
3611 case DIB_Status_GdiMod:
3612 TRACE("Unlocking in status GdiMod\n" );
3613 /* DIB was protected in Coerce */
3615 /* no commit, revert to InSync if applicable */
3616 if ((dib->p_status == DIB_Status_InSync) ||
3617 (dib->p_status == DIB_Status_AppMod)) {
3618 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3619 dib->status = DIB_Status_InSync;
3624 case DIB_Status_InSync:
3625 TRACE("Unlocking in status InSync\n" );
3626 /* DIB was already protected in Coerce */
3629 case DIB_Status_AppMod:
3630 TRACE("Unlocking in status AppMod\n" );
3631 /* DIB was already protected in Coerce */
3632 /* this case is ordinary only called from the signal handler,
3633 * so we don't bother to check for !commit */
3636 case DIB_Status_AuxMod:
3637 TRACE("Unlocking in status AuxMod\n" );
3639 /* DIB may need protection now */
3640 if ((dib->p_status == DIB_Status_InSync) ||
3641 (dib->p_status == DIB_Status_AppMod))
3642 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3644 /* no commit, revert to previous state */
3645 if (dib->p_status != DIB_Status_None)
3646 dib->status = dib->p_status;
3647 /* no protections changed */
3649 dib->p_status = DIB_Status_None;
3652 LeaveCriticalSection(&(dib->lock));
3653 TRACE("Unlocked %p\n", bmp);
3657 /***********************************************************************
3658 * X11DRV_CoerceDIBSection2
3660 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
3665 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3666 if (!bmp) return DIB_Status_None;
3667 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
3668 GDI_ReleaseObj( hBmp );
3672 /***********************************************************************
3673 * X11DRV_LockDIBSection2
3675 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
3680 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3681 if (!bmp) return DIB_Status_None;
3682 ret = X11DRV_DIB_Lock(bmp, req, lossy);
3683 GDI_ReleaseObj( hBmp );
3687 /***********************************************************************
3688 * X11DRV_UnlockDIBSection2
3690 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
3694 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3696 X11DRV_DIB_Unlock(bmp, commit);
3697 GDI_ReleaseObj( hBmp );
3700 /***********************************************************************
3701 * X11DRV_CoerceDIBSection
3703 INT X11DRV_CoerceDIBSection(DC *dc, INT req, BOOL lossy)
3705 if (!dc) return DIB_Status_None;
3706 return X11DRV_CoerceDIBSection2( dc->hBitmap, req, lossy );
3709 /***********************************************************************
3710 * X11DRV_LockDIBSection
3712 INT X11DRV_LockDIBSection(DC *dc, INT req, BOOL lossy)
3714 if (!dc) return DIB_Status_None;
3715 if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;
3717 return X11DRV_LockDIBSection2( dc->hBitmap, req, lossy );
3720 /***********************************************************************
3721 * X11DRV_UnlockDIBSection
3723 void X11DRV_UnlockDIBSection(DC *dc, BOOL commit)
3726 if (!(dc->flags & DC_MEMORY)) return;
3728 X11DRV_UnlockDIBSection2( dc->hBitmap, commit );
3731 /***********************************************************************
3732 * X11DRV_DIB_CreateDIBSection16
3734 HBITMAP16 X11DRV_DIB_CreateDIBSection16(
3735 DC *dc, BITMAPINFO *bmi, UINT16 usage,
3736 SEGPTR *bits, HANDLE section,
3737 DWORD offset, DWORD ovr_pitch)
3739 HBITMAP res = X11DRV_DIB_CreateDIBSection(dc, bmi, usage, NULL,
3740 section, offset, ovr_pitch);
3743 BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3744 if ( bmp && bmp->dib )
3746 DIBSECTION *dib = bmp->dib;
3747 INT height = dib->dsBm.bmHeight >= 0 ?
3748 dib->dsBm.bmHeight : -dib->dsBm.bmHeight;
3749 /* same as above - only use biSizeImage as the correct size if it a
3750 compressed image and it's currently non-zero. In other cases, use
3751 width * height as the value. */
3752 INT size = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
3753 ? dib->dsBmih.biSizeImage
3754 : dib->dsBm.bmWidthBytes * height;
3755 if ( dib->dsBm.bmBits )
3757 ((X11DRV_DIBSECTION *) bmp->dib)->selector =
3758 SELECTOR_AllocBlock( dib->dsBm.bmBits, size, WINE_LDT_FLAGS_DATA );
3760 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3761 dib->dsBm.bmBits, size, ((X11DRV_DIBSECTION *) bmp->dib)->selector,
3762 MAKESEGPTR(((X11DRV_DIBSECTION *) bmp->dib)->selector, 0));
3764 *bits = MAKESEGPTR( ((X11DRV_DIBSECTION *) bmp->dib)->selector, 0 );
3766 if (bmp) GDI_ReleaseObj( res );
3772 /***********************************************************************
3773 * X11DRV_XShmErrorHandler
3776 static int XShmErrorHandler(Display *dpy, XErrorEvent *event)
3782 /***********************************************************************
3783 * X11DRV_XShmCreateImage
3787 #ifdef HAVE_LIBXXSHM
3788 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
3789 XShmSegmentInfo* shminfo)
3791 int (*WineXHandler)(Display *, XErrorEvent *);
3795 image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
3798 shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
3800 if( shminfo->shmid != -1 )
3802 shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
3803 if( shminfo->shmaddr != (char*)-1 )
3805 shminfo->readOnly = FALSE;
3806 if( XShmAttach( gdi_display, shminfo ) != 0)
3808 /* Reset the error flag */
3810 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3811 XSync( gdi_display, 0 );
3815 shmctl(shminfo->shmid, IPC_RMID, 0);
3817 XSetErrorHandler(WineXHandler);
3818 wine_tsx11_unlock();
3819 return image; /* Success! */
3821 /* An error occured */
3823 XSetErrorHandler(WineXHandler);
3825 shmdt(shminfo->shmaddr);
3827 shmctl(shminfo->shmid, IPC_RMID, 0);
3829 XFlush(gdi_display);
3830 XDestroyImage(image);
3833 wine_tsx11_unlock();
3836 #endif /* HAVE_LIBXXSHM */
3839 /***********************************************************************
3840 * X11DRV_DIB_CreateDIBSection
3842 HBITMAP X11DRV_DIB_CreateDIBSection(
3843 DC *dc, BITMAPINFO *bmi, UINT usage,
3844 LPVOID *bits, HANDLE section,
3845 DWORD offset, DWORD ovr_pitch)
3848 BITMAPOBJ *bmp = NULL;
3849 X11DRV_DIBSECTION *dib = NULL;
3850 int *colorMap = NULL;
3853 /* Fill BITMAP32 structure with DIB data */
3854 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
3855 INT effHeight, totalSize;
3857 LPVOID mapBits = NULL;
3859 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3860 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
3861 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
3863 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
3865 bm.bmWidth = bi->biWidth;
3866 bm.bmHeight = effHeight;
3867 bm.bmWidthBytes = ovr_pitch ? ovr_pitch
3868 : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
3869 bm.bmPlanes = bi->biPlanes;
3870 bm.bmBitsPixel = bi->biBitCount;
3873 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
3874 we're dealing with a compressed bitmap. Otherwise, use width * height. */
3875 totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
3876 ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
3880 SYSTEM_INFO SystemInfo;
3884 GetSystemInfo( &SystemInfo );
3885 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
3886 mapSize = totalSize + (offset - mapOffset);
3887 mapBits = MapViewOfFile( section,
3888 FILE_MAP_ALL_ACCESS,
3892 bm.bmBits = (char *)mapBits + (offset - mapOffset);
3894 else if (ovr_pitch && offset)
3895 bm.bmBits = (LPVOID) offset;
3898 bm.bmBits = VirtualAlloc(NULL, totalSize,
3899 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
3902 /* Create Color Map */
3903 if (bm.bmBits && bm.bmBitsPixel <= 8)
3904 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? dc : NULL,
3905 usage, bm.bmBitsPixel, bmi, &nColorMap );
3907 /* Allocate Memory for DIB and fill structure */
3909 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
3912 dib->dibSection.dsBm = bm;
3913 dib->dibSection.dsBmih = *bi;
3914 dib->dibSection.dsBmih.biSizeImage = totalSize;
3916 /* Set dsBitfields values */
3917 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
3919 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
3921 else switch( bi->biBitCount )
3924 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
3925 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
3926 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
3930 dib->dibSection.dsBitfields[0] = 0xff;
3931 dib->dibSection.dsBitfields[1] = 0xff00;
3932 dib->dibSection.dsBitfields[2] = 0xff0000;
3936 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
3937 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
3938 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
3941 dib->dibSection.dshSection = section;
3942 dib->dibSection.dsOffset = offset;
3944 dib->status = DIB_Status_None;
3947 dib->nColorMap = nColorMap;
3948 dib->colorMap = colorMap;
3951 /* Create Device Dependent Bitmap and add DIB pointer */
3954 res = CreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
3957 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3960 bmp->dib = (DIBSECTION *) dib;
3962 if(!bmp->physBitmap)
3963 X11DRV_CreateBitmap(res);
3971 #ifdef HAVE_LIBXXSHM
3972 if (TSXShmQueryExtension(gdi_display) &&
3973 (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
3974 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
3976 ; /* Created Image */
3978 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3979 dib->shminfo.shmid = -1;
3982 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3986 /* Clean up in case of errors */
3987 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
3989 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3990 res, bmp, dib, bm.bmBits);
3994 UnmapViewOfFile(mapBits), bm.bmBits = NULL;
3996 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
3999 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
4000 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
4001 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
4002 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
4003 if (res) { DeleteObject(res); res = 0; }
4007 /* Install fault handler, if possible */
4008 InitializeCriticalSection(&(dib->lock));
4009 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
4011 if (section || offset)
4013 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4014 if (dib) dib->status = DIB_Status_AppMod;
4018 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4019 if (dib) dib->status = DIB_Status_InSync;
4024 /* Return BITMAP handle and storage location */
4025 if (bmp) GDI_ReleaseObj(res);
4026 if (bm.bmBits && bits) *bits = bm.bmBits;
4030 /***********************************************************************
4031 * X11DRV_DIB_DeleteDIBSection
4033 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
4035 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4039 #ifdef HAVE_LIBXXSHM
4040 if (dib->shminfo.shmid != -1)
4042 TSXShmDetach (gdi_display, &(dib->shminfo));
4043 XDestroyImage (dib->image);
4044 shmdt (dib->shminfo.shmaddr);
4045 dib->shminfo.shmid = -1;
4049 XDestroyImage( dib->image );
4053 HeapFree(GetProcessHeap(), 0, dib->colorMap);
4055 if (dib->selector) SELECTOR_FreeBlock( dib->selector );
4056 DeleteCriticalSection(&(dib->lock));
4059 /***********************************************************************
4060 * X11DRV_DIB_SetDIBColorTable
4062 UINT X11DRV_DIB_SetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, const RGBQUAD *colors)
4064 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4066 if (dib && dib->colorMap) {
4067 X11DRV_DIB_GenColorMap( dc, dib->colorMap, DIB_RGB_COLORS, dib->dibSection.dsBm.bmBitsPixel,
4068 TRUE, colors, start, count + start );
4074 /***********************************************************************
4075 * X11DRV_DIB_GetDIBColorTable
4077 UINT X11DRV_DIB_GetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, RGBQUAD *colors)
4079 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4081 if (dib && dib->colorMap) {
4082 int i, end = count + start;
4083 if (end > dib->nColorMap) end = dib->nColorMap;
4084 for (i = start; i < end; i++,colors++) {
4085 COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
4086 colors->rgbBlue = GetBValue(col);
4087 colors->rgbGreen = GetGValue(col);
4088 colors->rgbRed = GetRValue(col);
4089 colors->rgbReserved = 0;
4097 /**************************************************************************
4098 * X11DRV_DIB_CreateDIBFromPixmap
4100 * Allocates a packed DIB and copies the Pixmap data into it.
4101 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
4103 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
4106 BITMAPOBJ *pBmp = NULL;
4107 HGLOBAL hPackedDIB = 0;
4109 /* Allocates an HBITMAP which references the Pixmap passed to us */
4110 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
4113 TRACE("\tCould not create bitmap header for Pixmap\n");
4118 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4119 * A packed DIB contains a BITMAPINFO structure followed immediately by
4120 * an optional color palette and the pixel data.
4122 hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
4124 /* Get a pointer to the BITMAPOBJ structure */
4125 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4127 /* We can now get rid of the HBITMAP wrapper we created earlier.
4128 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4132 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4133 pBmp->physBitmap = NULL;
4136 GDI_ReleaseObj( hBmp );
4140 TRACE("\tReturning packed DIB %x\n", hPackedDIB);
4145 /**************************************************************************
4146 * X11DRV_DIB_CreatePixmapFromDIB
4148 * Creates a Pixmap from a packed DIB
4150 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
4152 Pixmap pixmap = None;
4154 BITMAPOBJ *pBmp = NULL;
4155 LPBYTE pPackedDIB = NULL;
4156 LPBITMAPINFO pbmi = NULL;
4157 LPBITMAPINFOHEADER pbmiHeader = NULL;
4158 LPBYTE pbits = NULL;
4160 /* Get a pointer to the packed DIB's data */
4161 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
4162 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
4163 pbmi = (LPBITMAPINFO)pPackedDIB;
4164 pbits = (LPBYTE)(pPackedDIB
4165 + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
4167 /* Create a DDB from the DIB */
4169 hBmp = CreateDIBitmap(hdc,
4176 GlobalUnlock(hPackedDIB);
4178 TRACE("CreateDIBitmap returned %x\n", hBmp);
4180 /* Retrieve the internal Pixmap from the DDB */
4182 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4184 pixmap = (Pixmap)pBmp->physBitmap;
4185 /* clear the physBitmap so that we can steal its pixmap */
4186 pBmp->physBitmap = NULL;
4189 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4190 GDI_ReleaseObj( hBmp );
4193 TRACE("\tReturning Pixmap %ld\n", pixmap);