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) */
25 #include "debugtools.h"
29 #include "selectors.h"
32 DEFAULT_DEBUG_CHANNEL(bitmap);
33 DECLARE_DEBUG_CHANNEL(x11drv);
35 static int bitmapDepthTable[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
36 static int ximageDepthTable[] = { 0, 0, 0, 0, 0, 0, 0 };
38 static int XShmErrorFlag = 0;
40 /***********************************************************************
43 BOOL X11DRV_DIB_Init(void)
48 for( i = 0; bitmapDepthTable[i]; i++ )
50 testimage = TSXCreateImage(display, X11DRV_GetVisual(),
51 bitmapDepthTable[i], ZPixmap, 0, NULL, 1, 1, 32, 20 );
52 if( testimage ) ximageDepthTable[i] = testimage->bits_per_pixel;
54 TSXDestroyImage(testimage);
60 /***********************************************************************
61 * X11DRV_DIB_GetXImageWidthBytes
63 * Return the width of an X image in bytes
65 int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
69 if (!ximageDepthTable[0]) {
72 for( i = 0; bitmapDepthTable[i] ; i++ )
73 if( bitmapDepthTable[i] == depth )
74 return (4 * ((width * ximageDepthTable[i] + 31)/32));
76 WARN("(%d): Unsupported depth\n", depth );
80 /***********************************************************************
81 * X11DRV_DIB_GenColorMap
83 * Fills the color map of a bitmap palette. Should not be called
84 * for a >8-bit deep bitmap.
86 int *X11DRV_DIB_GenColorMap( DC *dc, int *colorMapping,
87 WORD coloruse, WORD depth, BOOL quads,
88 const void *colorPtr, int start, int end )
92 if (coloruse == DIB_RGB_COLORS)
96 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
98 if (depth == 1) /* Monochrome */
99 for (i = start; i < end; i++, rgb++)
100 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
101 rgb->rgbBlue > 255*3/2);
103 for (i = start; i < end; i++, rgb++)
104 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbRed,
110 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
112 if (depth == 1) /* Monochrome */
113 for (i = start; i < end; i++, rgb++)
114 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
115 rgb->rgbtBlue > 255*3/2);
117 for (i = start; i < end; i++, rgb++)
118 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbtRed,
123 else /* DIB_PAL_COLORS */
125 WORD * index = (WORD *)colorPtr;
127 for (i = start; i < end; i++, index++)
128 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) );
134 /***********************************************************************
135 * X11DRV_DIB_BuildColorMap
137 * Build the color map from the bitmap palette. Should not be called
138 * for a >8-bit deep bitmap.
140 int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth,
141 const BITMAPINFO *info, int *nColors )
148 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
150 colors = info->bmiHeader.biClrUsed;
151 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
152 colorPtr = (WORD *)info->bmiColors;
154 else /* assume BITMAPCOREINFO */
156 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
157 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
162 ERR("called with >256 colors!\n");
166 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
167 colors * sizeof(int) )))
171 return X11DRV_DIB_GenColorMap( dc, colorMapping, coloruse, depth,
172 isInfo, colorPtr, 0, colors);
176 /***********************************************************************
177 * X11DRV_DIB_MapColor
179 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
183 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
186 for (color = 0; color < nPhysMap; color++)
187 if (physMap[color] == phys)
190 WARN("Strange color %08x\n", phys);
195 /*********************************************************************
196 * X11DRV_DIB_GetNearestIndex
198 * Helper for X11DRV_DIB_GetDIBits.
199 * Returns the nearest colour table index for a given RGB.
200 * Nearest is defined by minimizing the sum of the squares.
202 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
204 INT i, best = -1, diff, bestdiff = -1;
207 for(color = colormap, i = 0; i < numColors; color++, i++) {
208 diff = (r - color->rgbRed) * (r - color->rgbRed) +
209 (g - color->rgbGreen) * (g - color->rgbGreen) +
210 (b - color->rgbBlue) * (b - color->rgbBlue);
213 if(best == -1 || diff < bestdiff) {
221 /***********************************************************************
222 * X11DRV_DIB_SetImageBits_1_Line
224 * Handles a single line of 1 bit data.
226 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
227 XImage *bmpImage, int h, const BYTE *bits)
232 if((extra = (left & 7)) != 0) {
239 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
240 for (i = dstwidth/8, x = left; i > 0; i--)
243 XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
244 XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
245 XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
246 XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
247 XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
248 XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
249 XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
250 XPutPixel( bmpImage, x++, h, colors[pix & 1] );
255 case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
256 case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
257 case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
258 case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
259 case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
260 case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
261 case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
265 /***********************************************************************
266 * X11DRV_DIB_SetImageBits_1
268 * SetDIBits for a 1-bit deep DIB.
270 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
271 DWORD srcwidth, DWORD dstwidth, int left,
272 int *colors, XImage *bmpImage, DWORD linebytes)
277 for (h = lines-1; h >=0; h--) {
278 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
280 srcbits += linebytes;
284 for (h = 0; h < lines; h++) {
285 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
287 srcbits += linebytes;
292 /***********************************************************************
293 * X11DRV_DIB_GetImageBits_1
295 * GetDIBits for a 1-bit deep DIB.
297 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
298 DWORD dstwidth, DWORD srcwidth,
299 RGBQUAD *colors, PALETTEENTRY *srccolors,
300 XImage *bmpImage, DWORD linebytes )
308 dstbits = dstbits + linebytes * (lines - 1);
309 linebytes = -linebytes;
314 switch(bmpImage->depth) {
317 /* ==== monochrome bitmap to monochrome dib ==== */
319 /* ==== 4 colormap bitmap to monochrome dib ==== */
320 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
324 for (h = lines - 1; h >= 0; h--) {
325 for (x = 0; x < dstwidth; x++) {
326 val = srccolors[XGetPixel(bmpImage, x, h)];
327 if (!(x&7)) *bits = 0;
328 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2,
331 val.peBlue) << (7 - (x & 7)));
332 if ((x&7)==7) bits++;
334 bits = (dstbits += linebytes);
337 else goto notsupported;
342 /* ==== 8 colormap bitmap to monochrome dib ==== */
343 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
348 for( h = lines- 1; h >= 0; h-- ) {
349 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
350 for( x = 0; x < dstwidth; x++ ) {
351 if (!(x&7)) *bits = 0;
352 val = srccolors[(int)*srcpixel++];
353 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 2,
356 val.peBlue) << (7-(x&7)) );
357 if ((x&7)==7) bits++;
359 bits = (dstbits += linebytes);
362 else goto notsupported;
371 /* ==== 555 BGR bitmap to monochrome dib ==== */
372 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
374 for( h = lines - 1; h >= 0; h--) {
375 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
376 for( x = 0; x < dstwidth; x++) {
377 if (!(x&7)) *bits = 0;
379 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
380 ((val >> 7) & 0xf8) |
382 ((val >> 2) & 0xf8) |
384 ((val << 3) & 0xf8) |
385 ((val >> 2) & 0x7) ) << (7-(x&7)) );
386 if ((x&7)==7) bits++;
388 bits = (dstbits += linebytes);
391 /* ==== 555 RGB bitmap to monochrome dib ==== */
392 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
394 for( h = lines - 1; h >= 0; h--)
396 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
397 for( x = 0; x < dstwidth; x++) {
398 if (!(x&1)) *bits = 0;
400 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
401 ((val << 3) & 0xf8) |
403 ((val >> 2) & 0xf8) |
405 ((val >> 7) & 0xf8) |
406 ((val >> 12) & 0x7) ) << (7-(x&7)) );
407 if ((x&7)==7) bits++;
409 bits = (dstbits += linebytes);
412 else goto notsupported;
421 /* ==== 565 BGR bitmap to monochrome dib ==== */
422 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
424 for( h = lines - 1; h >= 0; h--)
426 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
427 for( x = 0; x < dstwidth; x++) {
428 if (!(x&7)) *bits = 0;
430 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
431 ((val >> 8) & 0xf8) |
433 ((val >> 3) & 0xfc) |
435 ((val << 3) & 0xf8) |
436 ((val >> 2) & 0x7) ) << (7-(x&7)) );
437 if ((x&7)==7) bits++;
439 bits = (dstbits += linebytes);
442 /* ==== 565 RGB bitmap to monochrome dib ==== */
443 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
445 for( h = lines - 1; h >= 0; h--)
447 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
448 for( x = 0; x < dstwidth; x++) {
449 if (!(x&7)) *bits = 0;
451 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
452 ((val << 3) & 0xf8) |
454 ((val >> 3) & 0xfc) |
456 ((val >> 8) & 0xf8) |
457 ((val >> 13) & 0x7) ) << (7-(x&7)) );
458 if ((x&7)==7) bits++;
460 bits = (dstbits += linebytes);
463 else goto notsupported;
472 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
473 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
475 for (h = lines - 1; h >= 0; h--)
477 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
478 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
479 if (!(x&7)) *bits = 0;
480 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[2] , srcpixel[1], srcpixel[0]) << (7-(x&7)) );
481 if ((x&7)==7) bits++;
483 bits = (dstbits += linebytes);
486 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
487 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
489 for (h = lines - 1; h >= 0; h--)
491 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
492 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
493 if (!(x & 7)) *bits = 0;
494 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[0] , srcpixel[1], srcpixel[2]) << (7-(x&7)) );
495 if ((x & 7) == 7) bits++;
497 bits = (dstbits += linebytes);
500 else goto notsupported;
504 default: /* ? bit bmp -> monochrome DIB */
507 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
509 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
510 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
511 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
513 for( h = lines - 1; h >= 0; h-- ) {
514 for( x = 0; x < dstwidth; x++ ) {
515 if (!(x&7)) *bits = 0;
516 *bits |= (XGetPixel( bmpImage, x, h) >= white)
518 if ((x&7)==7) bits++;
520 bits = (dstbits += linebytes);
527 /***********************************************************************
528 * X11DRV_DIB_SetImageBits_4
530 * SetDIBits for a 4-bit deep DIB.
532 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
533 DWORD srcwidth, DWORD dstwidth, int left,
534 int *colors, XImage *bmpImage, DWORD linebytes)
538 const BYTE *bits = srcbits + (left >> 1);
546 for (h = lines-1; h >= 0; h--) {
547 for (i = dstwidth/2, x = left; i > 0; i--) {
549 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
550 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
552 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
553 srcbits += linebytes;
554 bits = srcbits + (left >> 1);
558 for (h = 0; h < lines; h++) {
559 for (i = dstwidth/2, x = left; i > 0; i--) {
561 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
562 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
564 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
565 srcbits += linebytes;
566 bits = srcbits + (left >> 1);
573 /***********************************************************************
574 * X11DRV_DIB_GetImageBits_4
576 * GetDIBits for a 4-bit deep DIB.
578 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
579 DWORD srcwidth, DWORD dstwidth,
580 RGBQUAD *colors, PALETTEENTRY *srccolors,
581 XImage *bmpImage, DWORD linebytes )
591 dstbits = dstbits + ( linebytes * (lines-1) );
592 linebytes = -linebytes;
597 switch(bmpImage->depth) {
600 /* ==== monochrome bitmap to 4 colormap dib ==== */
602 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
603 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
607 for (h = lines-1; h >= 0; h--) {
608 for (x = 0; x < dstwidth; x++) {
609 if (!(x&1)) *bits = 0;
610 val = srccolors[XGetPixel(bmpImage, x, h)];
611 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 16,
614 val.peBlue) << (4-((x&1)<<2)));
615 if ((x&1)==1) bits++;
617 bits = (dstbits += linebytes);
620 else goto notsupported;
625 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
626 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
630 for( h = lines - 1; h >= 0; h-- ) {
631 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
632 for( x = 0; x < dstwidth; x++ ) {
633 if (!(x&1)) *bits = 0;
634 val = srccolors[(int)*srcpixel++];
635 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 16,
638 val.peBlue) << (4*(1-(x&1))) );
639 if ((x&1)==1) bits++;
641 bits = (dstbits += linebytes);
644 else goto notsupported;
653 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
654 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
656 for( h = lines - 1; h >= 0; h--) {
657 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
658 for( x = 0; x < dstwidth; x++) {
659 if (!(x&1)) *bits = 0;
661 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
662 ((val >> 7) & 0xf8) |
664 ((val >> 2) & 0xf8) |
666 ((val << 3) & 0xf8) |
667 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
668 if ((x&1)==1) bits++;
670 bits = (dstbits += linebytes);
673 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
674 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
676 for( h = lines - 1; h >= 0; h--)
678 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
679 for( x = 0; x < dstwidth; x++) {
680 if (!(x&1)) *bits = 0;
682 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
683 ((val << 3) & 0xf8) |
685 ((val >> 2) & 0xfc) |
687 ((val >> 7) & 0xf8) |
688 ((val >> 12) & 0x7) ) << ((1-(x&1))<<2) );
689 if ((x&1)==1) bits++;
691 bits = (dstbits += linebytes);
694 else goto notsupported;
703 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
704 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
706 for( h = lines - 1; h >= 0; h--)
708 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
709 for( x = 0; x < dstwidth; x++) {
710 if (!(x&1)) *bits = 0;
712 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
713 ((val >> 8) & 0xf8) |
715 ((val >> 3) & 0xfc) |
717 ((val << 3) & 0xf8) |
718 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
719 if ((x&1)==1) bits++;
721 bits = (dstbits += linebytes);
724 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
725 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
727 for( h = lines - 1; h >= 0; h--)
729 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
730 for( x = 0; x < dstwidth; x++) {
731 if (!(x&1)) *bits = 0;
733 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
734 ((val << 3) & 0xf8) |
736 ((val >> 3) & 0xfc) |
738 ((val >> 8) & 0xf8) |
739 ((val >> 13) & 0x7) ) << ((1-(x&1))<<2) );
740 if ((x&1)==1) bits++;
742 bits = (dstbits += linebytes);
745 else goto notsupported;
754 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
755 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
757 for (h = lines - 1; h >= 0; h--)
759 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
760 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
761 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[2] , srcpixel[1], srcpixel[0]) << 4) |
762 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[6] , srcpixel[5], srcpixel[4]);
763 bits = (dstbits += linebytes);
766 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
767 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
769 for (h = lines - 1; h >= 0; h--)
771 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
772 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
773 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[0] , srcpixel[1], srcpixel[2]) << 4) |
774 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[4] , srcpixel[5], srcpixel[6]);
775 bits = (dstbits += linebytes);
778 else goto notsupported;
782 default: /* ? bit bmp -> 4 bit DIB */
784 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
785 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
786 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
787 for (h = lines-1; h >= 0; h--) {
788 for (x = 0; x < dstwidth/2; x++) {
789 *bits++ = (X11DRV_DIB_MapColor((int *)colors, 16,
790 XGetPixel( bmpImage, x++, h ), 0) << 4)
791 | (X11DRV_DIB_MapColor((int *)colors, 16,
792 XGetPixel( bmpImage, x++, h ), 0) & 0x0f);
795 *bits = (X11DRV_DIB_MapColor((int *)colors, 16,
796 XGetPixel( bmpImage, x++, h ), 0) << 4);
797 bits = (dstbits += linebytes);
803 /***********************************************************************
804 * X11DRV_DIB_SetImageBits_RLE4
806 * SetDIBits for a 4-bit deep compressed DIB.
808 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
809 DWORD width, DWORD dstwidth,
810 int left, int *colors,
813 int x = 0, c, length;
814 const BYTE *begin = bits;
818 while ((int)lines >= 0) {
820 if (length) { /* encoded */
828 XPutPixel(bmpImage, x++, lines, colors[c >>4]);
836 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
847 case 1: /* eopicture */
853 FIXME_(x11drv)("x-delta is too large?\n");
859 default: /* absolute */
867 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
875 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
878 if ((bits - begin) & 1)
887 /***********************************************************************
888 * X11DRV_DIB_SetImageBits_8
890 * SetDIBits for an 8-bit deep DIB.
892 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
893 DWORD srcwidth, DWORD dstwidth, int left,
894 const int *colors, XImage *bmpImage,
906 srcbits = srcbits + ( linebytes * (lines-1) );
907 linebytes = -linebytes;
910 bits = srcbits + left;
912 switch (bmpImage->depth) {
915 #if defined(__i386__) && defined(__GNUC__)
916 /* Some X servers might have 32 bit/ 16bit deep pixel */
917 if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 16))
919 for (h = lines ; h--; ) {
920 int _cl1,_cl2; /* temp outputs for asm below */
921 /* Borrowed from DirectDraw */
922 __asm__ __volatile__(
927 " movw (%%edx,%%eax,4),%%ax\n"
931 :"=S" (bits), "=D" (_cl1), "=c" (_cl2)
933 "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*2),
936 :"eax", "cc", "memory"
938 bits = (srcbits += linebytes) + left;
945 break; /* use slow generic case below */
948 for (h = lines - 1; h >= 0; h--) {
949 for (x = left; x < dstwidth; x++, bits++) {
950 color = colors[*bits];
951 XPutPixel( bmpImage, x, h, colors[*bits] );
953 bits = (srcbits += linebytes) + left;
957 /***********************************************************************
958 * X11DRV_DIB_GetImageBits_8
960 * GetDIBits for an 8-bit deep DIB.
962 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
963 DWORD srcwidth, DWORD dstwidth,
964 RGBQUAD *colors, PALETTEENTRY *srccolors,
965 XImage *bmpImage, DWORD linebytes )
974 dstbits = dstbits + ( linebytes * (lines-1) );
975 linebytes = -linebytes;
982 This condition is true when GetImageBits has been called by UpdateDIBSection.
983 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
984 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
986 if (!srccolors) goto updatesection;
988 switch(bmpImage->depth) {
991 /* ==== monochrome bitmap to 8 colormap dib ==== */
993 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
994 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
998 for (h = lines - 1; h >= 0; h--) {
999 for (x = 0; x < dstwidth; x++) {
1000 val = srccolors[XGetPixel(bmpImage, x, h)];
1001 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1002 val.peGreen, val.peBlue);
1004 bits = (dstbits += linebytes);
1007 else goto notsupported;
1012 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
1013 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1018 for (h = lines - 1; h >= 0; h--) {
1019 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1020 for (x = 0; x < dstwidth; x++) {
1021 val = srccolors[(int)*srcpixel++];
1022 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1023 val.peGreen, val.peBlue);
1025 bits = (dstbits += linebytes);
1028 else goto notsupported;
1037 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1038 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
1040 for( h = lines - 1; h >= 0; h--)
1042 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1043 for( x = 0; x < dstwidth; x++ )
1046 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1047 ((val >> 7) & 0xf8) |
1048 ((val >> 12) & 0x7),
1049 ((val >> 2) & 0xf8) |
1051 ((val << 3) & 0xf8) |
1052 ((val >> 2) & 0x7) );
1054 bits = (dstbits += linebytes);
1057 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1058 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
1060 for( h = lines - 1; h >= 0; h--)
1062 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1063 for( x = 0; x < dstwidth; x++ )
1066 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1067 ((val << 3) & 0xf8) |
1069 ((val >> 2) & 0xf8) |
1071 ((val >> 7) & 0xf8) |
1072 ((val >> 12) & 0x7) );
1074 bits = (dstbits += linebytes);
1077 else goto notsupported;
1086 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1087 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
1089 for( h = lines - 1; h >= 0; h--)
1091 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1092 for( x = 0; x < dstwidth; x++ )
1095 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1096 ((val >> 8) & 0xf8) |
1097 ((val >> 13) & 0x7),
1098 ((val >> 3) & 0xfc) |
1100 ((val << 3) & 0xf8) |
1101 ((val >> 2) & 0x7) );
1103 bits = (dstbits += linebytes);
1106 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1107 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
1109 for( h = lines - 1; h >= 0; h--)
1111 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1112 for( x = 0; x < dstwidth; x++ )
1115 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1116 ((val << 3) & 0xf8) |
1118 ((val >> 3) & 0x00fc) |
1120 ((val >> 8) & 0x00f8) |
1121 ((val >> 13) & 0x7) );
1123 bits = (dstbits += linebytes);
1126 else goto notsupported;
1135 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1136 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1138 for (h = lines - 1; h >= 0; h--)
1140 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1141 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1142 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1143 srcpixel[2] , srcpixel[1], *srcpixel);
1144 bits = (dstbits += linebytes);
1147 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1148 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1150 for (h = lines - 1; h >= 0; h--)
1152 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1153 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1154 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1155 *srcpixel, srcpixel[1], srcpixel[2]);
1156 bits = (dstbits += linebytes);
1160 else goto notsupported;
1164 default: /* ? bit bmp -> 8 bit DIB */
1166 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1167 bmpImage->depth, (int)bmpImage->red_mask,
1168 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1170 for (h = lines - 1; h >= 0; h--) {
1171 for (x = 0; x < dstwidth; x++, bits++) {
1172 *bits = X11DRV_DIB_MapColor((int *)colors, 256,
1173 XGetPixel( bmpImage, x, h ), *bits);
1175 bits = (dstbits += linebytes);
1181 /***********************************************************************
1182 * X11DRV_DIB_SetImageBits_RLE8
1184 * SetDIBits for an 8-bit deep compressed DIB.
1186 * This function rewritten 941113 by James Youngman. WINE blew out when I
1187 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1189 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1190 * 'End of bitmap' escape code. This code is very much laxer in what it
1191 * allows to end the expansion. Possibly too lax. See the note by
1192 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1193 * bitmap should end with RleEnd, but on the other hand, software exists
1194 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1197 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1198 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1202 enum Rle8_EscapeCodes
1205 * Apologies for polluting your file's namespace...
1207 RleEol = 0, /* End of line */
1208 RleEnd = 1, /* End of bitmap */
1209 RleDelta = 2 /* Delta */
1212 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1213 DWORD width, DWORD dstwidth,
1214 int left, int *colors,
1217 int x; /* X-positon on each line. Increases. */
1218 int line; /* Line #. Starts at lines-1, decreases */
1219 const BYTE *pIn = bits; /* Pointer to current position in bits */
1220 BYTE length; /* The length pf a run */
1221 BYTE color_index; /* index into colors[] as read from bits */
1222 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
1223 int color; /* value of colour[color_index] */
1225 if (lines == 0) /* Let's hope this doesn't happen. */
1229 * Note that the bitmap data is stored by Windows starting at the
1230 * bottom line of the bitmap and going upwards. Within each line,
1231 * the data is stored left-to-right. That's the reason why line
1232 * goes from lines-1 to 0. [JAY]
1242 * If the length byte is not zero (which is the escape value),
1243 * We have a run of length pixels all the same colour. The colour
1244 * index is stored next.
1246 * If the length byte is zero, we need to read the next byte to
1247 * know what to do. [JAY]
1252 * [Run-Length] Encoded mode
1254 color_index = (*pIn++); /* Get the colour index. */
1255 color = colors[color_index];
1264 XPutPixel(bmpImage, x++, line, color);
1270 * Escape codes (may be an absolute sequence though)
1272 escape_code = (*pIn++);
1275 case RleEol: /* =0, end of line */
1282 case RleEnd: /* =1, end of bitmap */
1285 * Not all RLE8 bitmaps end with this
1286 * code. For example, Paint Shop Pro
1287 * produces some that don't. That's (I think)
1288 * what caused the previous implementation to
1291 line=-1; /* Cause exit from do loop. */
1295 case RleDelta: /* =2, a delta */
1298 * Note that deltaing to line 0
1299 * will cause an exit from the loop,
1300 * which may not be what is intended.
1301 * The fact that there is a delta in the bits
1302 * almost certainly implies that there is data
1303 * to follow. You may feel that we should
1304 * jump to the top of the loop to avoid exiting
1307 * TODO: Decide what to do here in that case. [JAY]
1313 TRACE("Delta to last line of bitmap "
1314 "(wrongly?) causes loop exit\n");
1319 default: /* >2, switch to absolute mode */
1324 length = escape_code;
1327 color_index = (*pIn++);
1333 XPutPixel(bmpImage, x++, line,
1334 colors[color_index]);
1338 * If you think for a moment you'll realise that the
1339 * only time we could ever possibly read an odd
1340 * number of bytes is when there is a 0x00 (escape),
1341 * a value >0x02 (absolute mode) and then an odd-
1342 * length run. Therefore this is the only place we
1343 * need to worry about it. Everywhere else the
1344 * bytes are always read in pairs. [JAY]
1346 if (escape_code & 1)
1347 pIn++; /* Throw away the pad byte. */
1350 } /* switch (escape_code) : Escape sequence */
1351 } /* process either an encoded sequence or an escape sequence */
1353 /* We expect to come here more than once per line. */
1354 } while (line >= 0); /* Do this until the bitmap is filled */
1357 * Everybody comes here at the end.
1358 * Check how we exited the loop and print a message if it's a bit odd.
1361 if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
1363 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1364 "bytes were: %02X %02X.\n", (int)*(pIn-2),(int)*(pIn-1));
1369 /***********************************************************************
1370 * X11DRV_DIB_SetImageBits_16
1372 * SetDIBits for a 16-bit deep DIB.
1374 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1375 DWORD srcwidth, DWORD dstwidth, int left,
1376 DC *dc, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1377 XImage *bmpImage, DWORD linebytes )
1385 srcbits = srcbits + ( linebytes * (lines-1));
1386 linebytes = -linebytes;
1389 switch ( bmpImage->depth )
1392 /* using same format as XImage */
1393 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1394 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1395 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1396 else /* We need to do a conversion from a 565 dib */
1398 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1400 int div = dstwidth % 2;
1402 for (h = lines - 1; h >= 0; h--) {
1403 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1404 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1406 *dstpixel++ = ((val >> 1) & 0x7fe07fe0) | (val & 0x001f001f); /* Red & Green & Blue */
1408 if (div != 0) /* Odd width? */
1409 *dstpixel = ((*(WORD *)ptr >> 1) & 0x7fe0) | (*(WORD *)ptr & 0x001f);
1410 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1416 /* using same format as XImage */
1417 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1418 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1419 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1420 else /* We need to do a conversion from a 555 dib */
1422 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1424 int div = dstwidth % 2;
1426 for (h = lines - 1; h >= 0; h--) {
1427 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1428 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1430 *dstpixel++ = ((val << 1) & 0xffc0ffc0) | ((val >> 4) & 0x00200020) | /* Red & Green */
1431 (val & 0x001f001f); /* Blue */
1433 if (div != 0) /* Odd width? */
1434 *dstpixel = ((*(WORD *)ptr << 1) & 0xffc0) | ((*(WORD *)ptr >> 4) & 0x0020)
1435 | (*(WORD *)ptr & 0x001f);
1436 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1445 LPWORD ptr = (LPWORD)srcbits + left;
1448 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1449 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1451 for (h = lines - 1; h >= 0; h--) {
1452 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1453 for (x = 0; x < dstwidth; x++) {
1456 *dstpixel++ = ((val << 9) & 0xf80000) | ((val << 4) & 0x070000) | /* Red */
1457 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1458 ((val << 3) & 0x0000f8) | ((val >> 2) & 0x000007); /* Blue */
1460 ptr = (LPWORD)(srcbits += linebytes) + left;
1463 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1464 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1466 for (h = lines - 1; h >= 0; h--) {
1467 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1468 for (x = 0; x < dstwidth; x++) {
1471 *dstpixel++ = ((val >> 7) & 0x0000f8) | ((val >> 12) & 0x000007) | /* Red */
1472 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1473 ((val << 19) & 0xf80000) | ((val >> 14) & 0x070000); /* Blue */
1475 ptr = (LPWORD)(srcbits += linebytes) + left;
1486 LPWORD ptr = (LPWORD)srcbits + left;
1490 /* Set color scaling values */
1491 if ( rSrc == 0x7c00 ) { sc1 = 7; sc2 = 2; } /* 555 dib */
1492 else { sc1 = 8; sc2 = 3; } /* 565 dib */
1494 for (h = lines - 1; h >= 0; h--) {
1495 for (x = left; x < dstwidth+left; x++) {
1497 XPutPixel( bmpImage, x, h,
1498 X11DRV_PALETTE_ToPhysical(dc, RGB(((val & rSrc) >> sc1), /* Red */
1499 ((val & gSrc) >> sc2), /* Green */
1500 ((val & bSrc) << 3)))); /* Blue */
1502 ptr = (LPWORD) (srcbits += linebytes) + left;
1508 FIXME("16 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
1515 /***********************************************************************
1516 * X11DRV_DIB_GetImageBits_16
1518 * GetDIBits for an 16-bit deep DIB.
1520 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
1521 DWORD dstwidth, DWORD srcwidth,
1522 PALETTEENTRY *srccolors,
1523 DWORD rDst, DWORD gDst, DWORD bDst,
1524 XImage *bmpImage, DWORD dibpitch )
1529 DWORD linebytes = dibpitch;
1534 dstbits = dstbits + ( linebytes * (lines-1));
1535 linebytes = -linebytes;
1538 /* Set color scaling values */
1539 if ( rDst == 0x7c00 ) { rsc = 7; gsc = 2; } /* 555 dib */
1540 else { rsc = 8; gsc = 3; } /* 565 dib */
1542 switch ( bmpImage->depth )
1545 /* using same format as XImage */
1546 if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1547 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1548 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1549 /* reversed format (BGR <=> RGB) */
1550 else if (rDst == bmpImage->blue_mask && bDst == bmpImage->red_mask)
1552 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1554 int div = srcwidth % 2;
1556 for (h = lines - 1; h >= 0; h--) {
1557 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1558 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1560 *ptr++ = ((val << 10) & 0xf800f800) | (val & 0x03e003e0) | /* Red & Green */
1561 ((val >> 10) & 0x001f001f); /* Blue */
1563 if (div != 0) /* Odd width? */
1564 *ptr = ((*(WORD *)srcpixel << 1) & 0xffc0) | ((*(WORD *)srcpixel >> 4) & 0x0020) |
1565 (*(WORD *)srcpixel & 0x001f);
1566 ptr = (LPDWORD)(dstbits += linebytes);
1569 else goto notsupported;
1575 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1577 int div = srcwidth % 2;
1579 /* using same format as XImage */
1580 if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1581 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1582 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1583 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1584 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f &&
1585 rDst == 0x7c00 && bDst == 0x001f)
1587 for (h = lines - 1; h >= 0; h--) {
1588 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1589 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1591 *ptr++ = ((val >> 1) & 0x7fe07fe0) | /* Red & Green */
1592 (val & 0x001f001f); /* Blue */
1594 if (div != 0) /* Odd width? */
1595 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1596 ptr = (LPDWORD) (dstbits += linebytes);
1599 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1600 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800 &&
1601 rDst == 0x7c00 && bDst == 0x001f)
1603 for (h = lines - 1; h >= 0; h--) {
1604 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1605 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1607 *ptr++ = ((val << 10) & 0x7c007c00) | ((val >> 1) & 0x03e003e0) | /* Red & Green */
1608 ((val >> 11) & 0x001f001f); /* Blue */
1610 if (div != 0) /* Odd width? */
1611 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1612 ptr = (LPDWORD) (dstbits += linebytes);
1615 else goto notsupported;
1623 LPWORD ptr = (LPWORD)dstbits;
1626 /* ==== 24/32 BGR bitmap ==== */
1627 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1629 int rsc2 = 16-rsc, gsc2 = 8-gsc;
1630 for (h = lines - 1; h >= 0; h--) {
1631 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1632 for (x = 0; x < srcwidth; x++, ptr++) {
1634 *ptr = ((val >> rsc2) & rDst) |
1635 ((val >> gsc2) & gDst) |
1636 ((val >> 3) & bDst);
1638 ptr = (LPWORD)(dstbits += linebytes);
1641 /* ==== 24/32 RGB bitmap ==== */
1642 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1645 for (h = lines - 1; h >= 0; h--) {
1646 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1647 for (x = 0; x < srcwidth; x++, ptr++) {
1649 *ptr = ((val << rsc) & rDst) |
1650 ((val >> gsc2) & gDst) |
1651 ((val >> 19) & bDst);
1653 ptr = (LPWORD) (dstbits += linebytes);
1656 else goto notsupported;
1661 /* ==== monochrome bitmap ==== */
1663 /* ==== 4 colormap bitmap ==== */
1664 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1666 LPWORD ptr = (LPWORD)dstbits;
1669 for (h = lines - 1; h >= 0; h--) {
1670 for (x = 0; x < dstwidth; x++) {
1671 val = srccolors[XGetPixel(bmpImage, x, h)];
1672 *ptr++ = ((val.peRed << rsc) & rDst) |
1673 ((val.peGreen << gsc) & gDst) |
1674 ((val.peBlue >> 3) & bDst);
1676 ptr = (LPWORD)(dstbits += linebytes);
1679 else goto notsupported;
1684 /* ==== 8 colormap bitmap ==== */
1685 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1687 LPWORD ptr = (LPWORD)dstbits;
1691 for (h = lines - 1; h >= 0; h--) {
1692 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1693 for (x = 0; x < dstwidth; x++) {
1694 val = srccolors[(int)*srcpixel++];
1695 *ptr++ = ((val.peRed << rsc) & rDst) |
1696 ((val.peGreen << gsc) & gDst) |
1697 ((val.peBlue >> 3) & bDst);
1699 ptr = (LPWORD)(dstbits += linebytes);
1702 else goto notsupported;
1710 LPWORD ptr = (LPWORD)dstbits;
1712 FIXME("from %d bit bitmap with mask R,G,B %lx,%lx,%lx to 16 bit DIB %lx,%lx,%lx\n",
1713 bmpImage->depth, bmpImage->red_mask,
1714 bmpImage->green_mask, bmpImage->blue_mask,
1717 for (h = lines - 1; h >= 0; h--)
1719 for (x = 0; x < dstwidth; x++, ptr++)
1721 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
1722 r = (BYTE) GetRValue(pixel);
1723 g = (BYTE) GetGValue(pixel);
1724 b = (BYTE) GetBValue(pixel);
1725 *ptr = ( ((r << rsc) & rDst) | ((g << gsc) & gDst) | ((b >> 3) & bDst) );
1727 ptr = (LPWORD) (dstbits += linebytes);
1735 /***********************************************************************
1736 * X11DRV_DIB_SetImageBits_24
1738 * SetDIBits for a 24-bit deep DIB.
1740 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
1741 DWORD srcwidth, DWORD dstwidth, int left,
1742 DC *dc, XImage *bmpImage, DWORD linebytes )
1750 srcbits = srcbits + linebytes * (lines - 1);
1751 linebytes = -linebytes;
1754 switch ( bmpImage->depth )
1758 if (bmpImage->bits_per_pixel == 24) {
1759 int dstlinebytes = linebytes;
1761 BYTE *ptr = (BYTE *)(srcbits+left*3);
1763 if (dstlinebytes < 0 ) dstlinebytes = -dstlinebytes;
1764 dstpixel = bmpImage->data + lines*dstlinebytes + left*3;
1765 for(h = lines ; h-- ; ) {
1766 dstpixel-=dstlinebytes;
1767 memcpy(dstpixel,ptr,dstwidth*3);
1775 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 ) /* packed BGR to unpacked BGR */
1777 DWORD *dstpixel, val, buf;
1778 DWORD *ptr = (DWORD *)(srcbits + left*3);
1780 int div = dstwidth % 4;
1783 for(h = lines - 1; h >= 0; h--)
1785 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1787 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1789 *dstpixel++ = buf&0x00ffffff; /* b1, g1, r1 */
1790 val = (buf >> 24); /* b2 */
1792 *dstpixel++ = (val | (buf<<8)) &0x00ffffff; /* g2, r2 */
1793 val = (buf >> 16); /* b3, g3 */
1795 *dstpixel++ = (val | (buf<<16)) &0x00ffffff; /* r3 */
1796 *dstpixel++ = (buf >> 8); /* b4, g4, r4 */
1798 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1800 *dstpixel++ = *(DWORD*)bits & 0x00ffffff; /* b, g, r */
1802 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1805 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff ) /* packed BGR to unpacked RGB */
1807 DWORD *dstpixel, val, buf;
1808 DWORD *ptr = (DWORD *)(srcbits + left*3);
1810 int div = dstwidth % 4;
1813 for(h = lines - 1; h >= 0; h--)
1815 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1817 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1819 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b1, g1, r1 */
1820 val = ((buf&0xff000000)>>8); /* b2 */
1822 *dstpixel++ = val | ((buf&0xff)<<8) | ((buf&0xff00)>>8); /* g2, r2 */
1823 val = (buf&0xff0000) | ((buf&0xff000000)>>16); /* b3, g3 */
1825 *dstpixel++ = val | (buf&0xff); /* r3 */
1826 *dstpixel++ = ((buf&0xff00)<<8) | ((buf&0xff0000)>>8) | (buf>>24); /* b4, g4, r4 */
1828 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1830 buf = *(DWORD*)bits;
1831 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b, g, r */
1833 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1843 if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f ) /* BGR888 to RGB555 */
1845 DWORD *ptr = (DWORD *)(srcbits + left*3), val;
1848 int div = dstwidth % 4;
1851 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1852 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1853 for (x = 0; x < dstwidth/4; x++) {
1854 *dstpixel++ = (WORD)((((val = *ptr++) << 7) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 19) & 0x1f));
1855 *dstpixel++ = (WORD)(((val >> 17) & 0x7c00) | (((val = *ptr++) << 2) & 0x03e0) | ((val >> 11) & 0x1f));
1856 *dstpixel++ = (WORD)(((val >> 9) & 0x07c00) | ((val >> 22) & 0x03e0) | (((val = *ptr++) >> 3) & 0x1f));
1857 *dstpixel++ = (WORD)(((val >> 1) & 0x07c00) | ((val >> 14) & 0x03e0) | ((val >> 27) & 0x1f));
1859 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1860 *dstpixel++ = (((WORD)bits[0] << 7) & 0x07c00) |
1861 (((WORD)bits[1] << 2) & 0x03e0) |
1862 (((WORD)bits[2] >> 3) & 0x001f);
1863 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1866 else if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 ) /* BGR888 to BGR555 */
1868 DWORD *ptr = (DWORD *)(srcbits + left*3), val;
1871 int div = dstwidth % 4;
1874 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1875 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1876 for (x = 0; x < dstwidth/4; x++) {
1877 *dstpixel++ = (WORD)((((val = *ptr++) >> 3) & 0x1f) | ((val >> 6) & 0x03e0) | ((val >> 9) & 0x7c00));
1878 *dstpixel++ = (WORD)(((val >> 27) & 0x1f) | (((val = *ptr++) << 2) & 0x03e0) | ((val >> 1) & 0x7c00));
1879 *dstpixel++ = (WORD)(((val >> 19) & 0x1f) | ((val >> 22) & 0x03e0) | (((val = *ptr++) << 7) & 0x7c00));
1880 *dstpixel++ = (WORD)(((val >> 11) & 0x1f) | ((val >> 14) & 0x03e0) | ((val >> 17) & 0x7c00));
1882 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1883 *dstpixel++ = (((WORD)bits[2] << 7) & 0x07c00) |
1884 (((WORD)bits[1] << 2) & 0x03e0) |
1885 (((WORD)bits[0] >> 3) & 0x001f);
1886 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1896 DWORD *ptr = (DWORD *)(srcbits + left*3), val;
1899 int div = dstwidth % 4;
1902 if( bmpImage->blue_mask == 0x001f && bmpImage->red_mask == 0xf800 ) /* BGR888 to BGR565 */
1904 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1905 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1906 for (x = 0; x < dstwidth/4; x++) {
1907 *dstpixel++ = (WORD)((((val = *ptr++) >> 3) & 0x1f) | ((val >> 5) & 0x07e0) | ((val >> 8) & 0xf800));
1908 *dstpixel++ = (WORD)(((val >> 27) & 0x1f) | (((val = *ptr++) << 3) & 0x07e0) | ((val) & 0xf800));
1909 *dstpixel++ = (WORD)(((val >> 19) & 0x1f) | ((val >> 21) & 0x07e0) | (((val = *ptr++) << 8) & 0xf800));
1910 *dstpixel++ = (WORD)(((val >> 11) & 0x1f) | ((val >> 13) & 0x07e0) | ((val >> 16) & 0xf800));
1912 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
1913 *dstpixel++ = (((WORD)bits[2] << 8) & 0xf800) |
1914 (((WORD)bits[1] << 3) & 0x07e0) |
1915 (((WORD)bits[0] >> 3) & 0x001f);
1916 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1919 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x001f ) /* BGR888 to RGB565 */
1921 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1922 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1923 for (x = 0; x < dstwidth/4; x++) {
1924 *dstpixel++ = (WORD)((((val = *ptr++) << 8) & 0xf800) | ((val >> 5) & 0x07e0) | ((val >> 19) & 0x1f));
1925 *dstpixel++ = (WORD)(((val >> 16) & 0xf800) | (((val = *ptr++) << 3) & 0x07e0) | ((val >> 11) & 0x1f));
1926 *dstpixel++ = (WORD)(((val >> 8) & 0xf800) | ((val >> 21) & 0x07e0) | (((val = *ptr++) >> 3) & 0x1f));
1927 *dstpixel++ = (WORD)((val & 0xf800) | ((val >> 13) & 0x07e0) | ((val >> 27) & 0x1f));
1929 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
1930 *dstpixel++ = (((WORD)bits[0] << 8) & 0xf800) |
1931 (((WORD)bits[1] << 3) & 0x07e0) |
1932 (((WORD)bits[2] >> 3) & 0x001f);
1933 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1945 LPBYTE bits = (LPBYTE)srcbits + left*3;
1947 for (h = lines - 1; h >= 0; h--) {
1948 for (x = left; x < dstwidth+left; x++, bits+=3)
1949 XPutPixel( bmpImage, x, h,
1950 X11DRV_PALETTE_ToPhysical(dc, RGB(bits[2], bits[1], bits[0])));
1951 bits = (LPBYTE)(srcbits += linebytes) + left * 3;
1958 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
1959 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
1960 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1966 /***********************************************************************
1967 * X11DRV_DIB_GetImageBits_24
1969 * GetDIBits for an 24-bit deep DIB.
1971 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
1972 DWORD dstwidth, DWORD srcwidth,
1973 PALETTEENTRY *srccolors,
1974 XImage *bmpImage, DWORD linebytes )
1982 dstbits = dstbits + ( linebytes * (lines-1) );
1983 linebytes = -linebytes;
1986 switch ( bmpImage->depth )
1990 if (bmpImage->bits_per_pixel == 24) {
1991 int tocopy = linebytes;
1993 BYTE *ptr = (LPBYTE)dstbits;
1995 if (tocopy < 0 ) tocopy = -tocopy;
1996 srcpixel = bmpImage->data + lines*tocopy;
1997 for(h = lines ; h-- ; ) {
1999 memcpy(ptr,srcpixel,tocopy);
2000 ptr = (LPBYTE)(dstbits+=linebytes);
2007 DWORD *srcpixel, buf;
2009 DWORD *ptr=(DWORD *)dstbits;
2010 int quotient = dstwidth / 4;
2011 int remainder = dstwidth % 4;
2014 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
2015 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 )
2017 for(h = lines - 1; h >= 0; h--)
2019 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2021 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
2022 buf = ((*srcpixel++)&0x00ffffff); /* b1, g1, r1*/
2023 *ptr++ = buf | ((*srcpixel)<<24); /* b2 */
2024 buf = ((*srcpixel++>>8)&0x0000ffff); /* g2, r2 */
2025 *ptr++ = buf | ((*srcpixel)<<16); /* b3, g3 */
2026 buf = ((*srcpixel++>>16)&0x000000ff); /* r3 */
2027 *ptr++ = buf | ((*srcpixel++)<<8); /* b4, g4, r4 */
2029 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2032 *(WORD*)bits = buf; /* b, g */
2033 *(bits+2) = buf>>16; /* r */
2035 ptr = (DWORD*)(dstbits+=linebytes);
2039 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
2040 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff )
2042 for(h = lines - 1; h >= 0; h--)
2044 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2046 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
2048 val = ((buf&0xff0000)>>16) | (buf&0xff00) | ((buf&0xff)<<16); /* b1, g1, r1 */
2050 *ptr++ = val | ((buf&0xff0000)<<8); /* b2 */
2051 val = ((buf&0xff00)>>8) | ((buf&0xff)<<8); /* g2, r2 */
2053 *ptr++ = val | (buf&0xff0000) | ((buf&0xff00)<<16); /* b3, g3 */
2054 val = (buf&0xff); /* r3 */
2056 *ptr++ = val | ((buf&0xff0000)>>8) | ((buf&0xff00)<<8) | (buf<<24); /* b4, g4, r4 */
2058 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2061 *(WORD*)bits = (buf&0xff00) | ((buf&0xff0000)>>16) ; /* b, g */
2062 *(bits+2) = buf; /* r */
2064 ptr = (DWORD*)(dstbits+=linebytes);
2067 else goto notsupported;
2074 LPBYTE bits = dstbits;
2077 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2078 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 )
2080 for (h = lines - 1; h >= 0; h--) {
2081 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2082 for (x = 0; x < srcwidth; x++, bits += 3) {
2084 bits[2] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2085 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2086 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2088 bits = (dstbits += linebytes);
2091 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2092 else if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f )
2094 for (h = lines - 1; h >= 0; h--) {
2095 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2096 for (x = 0; x < srcwidth; x++, bits += 3) {
2098 bits[0] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2099 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2100 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2102 bits = (dstbits += linebytes);
2105 else goto notsupported;
2112 LPBYTE bits = dstbits;
2115 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2116 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0xf800 )
2118 for (h = lines - 1; h >= 0; h--) {
2119 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2120 for (x = 0; x < srcwidth; x++, bits += 3) {
2122 bits[2] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2123 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2124 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2126 bits = (dstbits += linebytes);
2129 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2130 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x1f )
2132 for (h = lines - 1; h >= 0; h--) {
2133 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2134 for (x = 0; x < srcwidth; x++, bits += 3) {
2136 bits[0] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2137 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2138 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2140 bits = (dstbits += linebytes);
2143 else goto notsupported;
2148 /* ==== monochrome bitmap to 24 BGR dib ==== */
2150 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2151 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2153 LPBYTE bits = dstbits;
2156 for (h = lines - 1; h >= 0; h--) {
2157 for (x = 0; x < dstwidth; x++) {
2158 val = srccolors[XGetPixel(bmpImage, x, h)];
2159 *bits++ = val.peBlue;
2160 *bits++ = val.peGreen;
2161 *bits++ = val.peRed;
2163 bits = (dstbits += linebytes);
2166 else goto notsupported;
2171 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2172 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors)
2175 LPBYTE bits = dstbits;
2178 for (h = lines - 1; h >= 0; h--) {
2179 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2180 for (x = 0; x < dstwidth; x++ ) {
2181 val = srccolors[(int)*srcpixel++];
2182 *bits++ = val.peBlue; /*Blue*/
2183 *bits++ = val.peGreen; /*Green*/
2184 *bits++ = val.peRed; /*Red*/
2186 bits = (dstbits += linebytes);
2189 else goto notsupported;
2196 LPBYTE bits = dstbits;
2198 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2199 bmpImage->depth, (int)bmpImage->red_mask,
2200 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2201 for (h = lines - 1; h >= 0; h--)
2203 for (x = 0; x < dstwidth; x++, bits += 3)
2205 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2206 bits[0] = GetBValue(pixel);
2207 bits[1] = GetGValue(pixel);
2208 bits[2] = GetRValue(pixel);
2210 bits = (dstbits += linebytes);
2218 /***********************************************************************
2219 * X11DRV_DIB_SetImageBits_32
2221 * SetDIBits for a 32-bit deep DIB.
2223 static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
2224 DWORD srcwidth, DWORD dstwidth, int left,
2225 DC *dc, XImage *bmpImage,
2234 srcbits = srcbits + ( linebytes * (lines-1) );
2235 linebytes = -linebytes;
2238 ptr = (DWORD *) srcbits + left;
2240 switch ( bmpImage->depth )
2243 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2244 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) {
2245 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2246 memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2250 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2251 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
2255 for (h = lines - 1; h >= 0; h--) {
2256 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2257 for (x = 0; x < dstwidth; x++, ptr++) {
2258 *dstpixel++ = ((*ptr << 16) & 0xff0000) | (*ptr & 0xff00) | ((*ptr >> 16) & 0xff);
2260 ptr = (DWORD *) (srcbits += linebytes) + left;
2263 else goto notsupported;
2268 /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
2269 /* we need to check that source mask matches destination */
2270 if (bmpImage->bits_per_pixel == 32)
2272 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2273 memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2280 ptr = (DWORD *) srcbits + left;
2281 bptr = bmpImage->data;
2283 for (h = lines - 1; h >= 0; h--) {
2284 for (x = 0; x < dstwidth; x++) {
2285 /* *ptr is a 32bit value */
2286 /* bptr points to first of 3 bytes */
2287 *bptr++ = (*ptr >> 16) & 0xff;
2288 *bptr++ = (*ptr >> 8) & 0xff;
2289 *bptr++ = (*ptr ) & 0xff;
2292 ptr = (DWORD *) (srcbits += linebytes) + left;
2298 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2299 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f) {
2302 for (h = lines - 1; h >= 0; h--) {
2303 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2304 for (x = 0; x < dstwidth; x++, ptr++) {
2305 *dstpixel++ = (WORD) (((*ptr >> 9) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 3) & 0x001f));
2307 ptr = (DWORD *) (srcbits += linebytes) + left;
2310 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2311 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2315 for (h = lines - 1; h >= 0; h--) {
2316 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2317 for (x = 0; x < dstwidth; x++, ptr++) {
2318 *dstpixel++ = (WORD) (((*ptr << 7) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 19) & 0x001f));
2320 ptr = (DWORD *) (srcbits += linebytes) + left;
2323 else goto notsupported;
2328 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2329 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2333 for (h = lines - 1; h >= 0; h--) {
2334 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2335 for (x = 0; x < dstwidth; x++, ptr++) {
2336 *dstpixel++ = (WORD) (((*ptr >> 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 3) & 0x001f));
2338 ptr = (DWORD *) (srcbits += linebytes) + left;
2341 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2342 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
2346 for (h = lines - 1; h >= 0; h--) {
2347 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2348 for (x = 0; x < dstwidth; x++, ptr++) {
2349 *dstpixel++ = (WORD) (((*ptr << 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 19) & 0x001f));
2351 ptr = (DWORD *) (srcbits += linebytes) + left;
2354 else goto notsupported;
2362 LPBYTE bits = (LPBYTE)srcbits + left*4;
2364 for (h = lines - 1; h >= 0; h--) {
2365 for (x = left; x < dstwidth+left; x++, bits += 4)
2366 XPutPixel( bmpImage, x, h,
2367 X11DRV_PALETTE_ToPhysical(dc, RGB( bits[2], bits[1], *bits )));
2368 bits = (LPBYTE)(srcbits += linebytes) + left * 4;
2375 FIXME("32 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
2381 /***********************************************************************
2382 * X11DRV_DIB_GetImageBits_32
2384 * GetDIBits for an 32-bit deep DIB.
2386 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
2387 DWORD dstwidth, DWORD srcwidth,
2388 PALETTEENTRY *srccolors,
2389 XImage *bmpImage, DWORD linebytes )
2395 DWORD copybytes = srcwidth * 4;
2400 dstbits = dstbits + ( linebytes * (lines-1) );
2401 linebytes = -linebytes;
2406 switch ( bmpImage->depth )
2409 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2410 if ( bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff )
2411 for (h = lines - 1; h >= 0; h--, dstbits+=linebytes)
2412 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, copybytes );
2414 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2415 else if ( bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000 )
2419 for (h = lines - 1; h >= 0; h--) {
2420 srcbits = bmpImage->data + h * bmpImage->bytes_per_line;
2421 for (x = 0; x < dstwidth; x++, bits+=4, srcbits+=2) {
2422 *(bits + 2) = *srcbits++;
2423 *(bits + 1) = *srcbits++;
2426 bits = (dstbits += linebytes);
2429 else goto notsupported;
2433 /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */
2434 /* we need to check that source mask matches destination */
2440 srcpixel = (DWORD *) dstbits;
2441 bptr = bmpImage->data;
2443 for (h = lines - 1; h >= 0; h--) {
2444 for (x = 0; x < dstwidth; x++) {
2445 /* *srcpixel is a 32bit value */
2446 /* bptr points to first of 3 bytes */
2448 srcdata = srcdata << 8 | *bptr++;
2449 srcdata = srcdata << 8 | *bptr++;
2450 srcdata = srcdata << 8 | *bptr++;
2452 *srcpixel++ = srcdata;
2454 srcpixel = (DWORD *) (dstbits += linebytes);
2464 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2465 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
2467 for (h = lines - 1; h >= 0; h--) {
2468 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2469 for (x = 0; x < dstwidth; x++, bits+=2) {
2471 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2472 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2473 *bits = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2475 bits = (dstbits += linebytes);
2478 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2479 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2481 for (h = lines - 1; h >= 0; h--) {
2482 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2483 for (x = 0; x < dstwidth; x++, bits+=2) {
2485 *bits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));/*Blue*/
2486 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2487 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2489 bits = (dstbits += linebytes);
2492 else goto notsupported;
2501 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2502 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2504 for (h = lines - 1; h >= 0; h--) {
2505 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2506 for (x = 0; x < srcwidth; x++, bits+=2) {
2508 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2509 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2510 *bits = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2512 bits = (dstbits += linebytes);
2515 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2516 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2518 for (h = lines - 1; h >= 0; h--) {
2519 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2520 for (x = 0; x < srcwidth; x++, bits+=2) {
2522 *bits++ = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));/*Blue*/
2523 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2524 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2526 bits = (dstbits += linebytes);
2529 else goto notsupported;
2534 /* ==== monochrome bitmap to 32 BGR dib ==== */
2536 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2537 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2541 for (h = lines - 1; h >= 0; h--) {
2542 for (x = 0; x < dstwidth; x++) {
2543 val = srccolors[XGetPixel(bmpImage, x, h)];
2544 *bits++ = val.peBlue;
2545 *bits++ = val.peGreen;
2546 *bits++ = val.peRed;
2549 bits = (dstbits += linebytes);
2552 else goto notsupported;
2557 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2558 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2563 for (h = lines - 1; h >= 0; h--) {
2564 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2565 for (x = 0; x < dstwidth; x++) {
2566 val = srccolors[(int)*srcpixel++];
2567 *bits++ = val.peBlue; /*Blue*/
2568 *bits++ = val.peGreen; /*Green*/
2569 *bits++ = val.peRed; /*Red*/
2572 bits = (dstbits += linebytes);
2575 else goto notsupported;
2580 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2581 bmpImage->depth, (int)bmpImage->red_mask,
2582 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2583 for (h = lines - 1; h >= 0; h--)
2585 for (x = 0; x < dstwidth; x++, bits += 4)
2587 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2588 bits[0] = GetBValue(pixel);
2589 bits[1] = GetGValue(pixel);
2590 bits[2] = GetRValue(pixel);
2592 bits = (dstbits += linebytes);
2598 /***********************************************************************
2599 * X11DRV_DIB_SetImageBits
2601 * Transfer the bits to an X image.
2602 * Helper function for SetDIBits() and SetDIBitsToDevice().
2603 * The Xlib critical section must be entered before calling this function.
2605 int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2607 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2611 bmpImage = descr->image;
2613 bmpImage = XCreateImage( display, X11DRV_GetVisual(), descr->depth, ZPixmap, 0, NULL,
2614 descr->infoWidth, lines, 32, 0 );
2615 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2616 if(bmpImage->data == NULL) {
2617 ERR("Out of memory!\n");
2618 XDestroyImage( bmpImage );
2623 /* Transfer the pixels */
2624 switch(descr->infoBpp)
2627 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
2628 descr->width, descr->xSrc, (int *)(descr->colorMap),
2629 bmpImage, descr->dibpitch );
2632 if (descr->compression) {
2633 XGetSubImage( display, descr->drawable, descr->xDest, descr->yDest,
2634 descr->width, descr->height, AllPlanes, ZPixmap,
2635 bmpImage, descr->xSrc, descr->ySrc );
2637 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
2638 descr->infoWidth, descr->width,
2639 descr->xSrc, (int *)(descr->colorMap),
2642 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
2643 descr->infoWidth, descr->width,
2644 descr->xSrc, (int*)(descr->colorMap),
2645 bmpImage, descr->dibpitch );
2648 if (descr->compression) {
2649 XGetSubImage( display, descr->drawable, descr->xDest, descr->yDest,
2650 descr->width, descr->height, AllPlanes, ZPixmap,
2651 bmpImage, descr->xSrc, descr->ySrc );
2652 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
2653 descr->infoWidth, descr->width,
2654 descr->xSrc, (int *)(descr->colorMap),
2657 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
2658 descr->infoWidth, descr->width,
2659 descr->xSrc, (int *)(descr->colorMap),
2660 bmpImage, descr->dibpitch );
2664 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
2665 descr->infoWidth, descr->width,
2666 descr->xSrc, descr->dc,
2667 descr->rMask, descr->gMask, descr->bMask,
2668 bmpImage, descr->dibpitch);
2671 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
2672 descr->infoWidth, descr->width,
2673 descr->xSrc, descr->dc, bmpImage,
2677 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
2678 descr->infoWidth, descr->width,
2679 descr->xSrc, descr->dc,
2680 bmpImage, descr->dibpitch);
2683 WARN("(%d): Invalid depth\n", descr->infoBpp );
2689 XShmPutImage( display, descr->drawable, descr->gc, bmpImage,
2690 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2691 descr->width, descr->height, FALSE );
2692 XSync( display, 0 );
2695 XPutImage( display, descr->drawable, descr->gc, bmpImage,
2696 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2697 descr->width, descr->height );
2699 if (!descr->image) XDestroyImage( bmpImage );
2703 /***********************************************************************
2704 * X11DRV_DIB_GetImageBits
2706 * Transfer the bits from an X image.
2707 * The Xlib critical section must be entered before calling this function.
2709 int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2711 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2715 bmpImage = descr->image;
2717 bmpImage = XCreateImage( display, X11DRV_GetVisual(), descr->depth, ZPixmap, 0, NULL,
2718 descr->infoWidth, lines, 32, 0 );
2719 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2720 if(bmpImage->data == NULL) {
2721 ERR("Out of memory!\n");
2722 XDestroyImage( bmpImage );
2726 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
2727 display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
2728 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
2729 XGetSubImage( display, descr->drawable, descr->xSrc, descr->ySrc,
2730 descr->width, lines, AllPlanes, ZPixmap,
2731 bmpImage, descr->xDest, descr->yDest );
2733 /* Transfer the pixels */
2734 switch(descr->infoBpp)
2737 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
2738 descr->infoWidth, descr->width,
2739 descr->colorMap, descr->palentry,
2740 bmpImage, descr->dibpitch );
2744 if (descr->compression)
2745 FIXME("Compression not yet supported!\n");
2747 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
2748 descr->infoWidth, descr->width,
2749 descr->colorMap, descr->palentry,
2750 bmpImage, descr->dibpitch );
2754 if (descr->compression)
2755 FIXME("Compression not yet supported!\n");
2757 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
2758 descr->infoWidth, descr->width,
2759 descr->colorMap, descr->palentry,
2760 bmpImage, descr->dibpitch );
2764 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
2765 descr->infoWidth,descr->width,
2767 descr->rMask, descr->gMask, descr->bMask,
2768 bmpImage, descr->dibpitch );
2772 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
2773 descr->infoWidth,descr->width,
2774 descr->palentry, bmpImage, descr->dibpitch);
2778 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
2779 descr->infoWidth, descr->width,
2780 descr->palentry, bmpImage, descr->dibpitch);
2784 WARN("(%d): Invalid depth\n", descr->infoBpp );
2788 if (!descr->image) XDestroyImage( bmpImage );
2792 /*************************************************************************
2793 * X11DRV_SetDIBitsToDevice
2796 INT X11DRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx,
2797 DWORD cy, INT xSrc, INT ySrc,
2798 UINT startscan, UINT lines, LPCVOID bits,
2799 const BITMAPINFO *info, UINT coloruse )
2801 X11DRV_DIB_IMAGEBITS_DESCR descr;
2802 DWORD width, oldcy = cy;
2804 int height, tmpheight;
2805 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
2808 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
2809 &descr.infoBpp, &descr.compression ) == -1)
2812 if (height < 0) height = -height;
2813 if (!lines || (startscan >= height)) return 0;
2814 if (startscan + lines > height) lines = height - startscan;
2815 if (ySrc < startscan) ySrc = startscan;
2816 else if (ySrc >= startscan + lines) return 0;
2817 if (xSrc >= width) return 0;
2818 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
2819 if (xSrc + cx >= width) cx = width - xSrc;
2820 if (!cx || !cy) return 0;
2822 X11DRV_SetupGCForText( dc ); /* To have the correct colors */
2823 TSXSetFunction(display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);
2825 switch (descr.infoBpp)
2830 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
2831 coloruse == DIB_PAL_COLORS ? dc : NULL, coloruse,
2832 dc->bitsPerPixel, info, &descr.nColorMap );
2833 if (!descr.colorMap) return 0;
2834 descr.rMask = descr.gMask = descr.bMask = 0;
2838 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2839 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
2840 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
2845 descr.rMask = descr.gMask = descr.bMask = 0;
2850 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2851 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
2852 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
2860 descr.palentry = NULL;
2861 descr.lines = tmpheight >= 0 ? lines : -lines;
2862 descr.infoWidth = width;
2863 descr.depth = dc->bitsPerPixel;
2864 descr.drawable = physDev->drawable;
2865 descr.gc = physDev->gc;
2867 descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy)
2869 descr.xDest = dc->DCOrgX + XLPTODP( dc, xDest );
2870 descr.yDest = dc->DCOrgY + YLPTODP( dc, yDest ) +
2871 (tmpheight >= 0 ? oldcy-cy : 0);
2874 descr.useShm = FALSE;
2875 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
2877 EnterCriticalSection( &X11DRV_CritSection );
2878 result = CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
2879 LeaveCriticalSection( &X11DRV_CritSection );
2881 if (descr.infoBpp <= 8)
2882 HeapFree(GetProcessHeap(), 0, descr.colorMap);
2886 /***********************************************************************
2887 * X11DRV_DIB_SetDIBits
2889 INT X11DRV_DIB_SetDIBits(
2890 BITMAPOBJ *bmp, DC *dc, UINT startscan,
2891 UINT lines, LPCVOID bits, const BITMAPINFO *info,
2892 UINT coloruse, HBITMAP hbitmap)
2894 X11DRV_DIB_IMAGEBITS_DESCR descr;
2895 int height, tmpheight;
2900 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
2901 &descr.infoBpp, &descr.compression ) == -1)
2905 if (height < 0) height = -height;
2906 if (!lines || (startscan >= height))
2909 if (startscan + lines > height) lines = height - startscan;
2911 switch (descr.infoBpp)
2916 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
2917 coloruse == DIB_PAL_COLORS ? descr.dc : NULL, coloruse,
2918 bmp->bitmap.bmBitsPixel,
2919 info, &descr.nColorMap );
2920 if (!descr.colorMap) return 0;
2921 descr.rMask = descr.gMask = descr.bMask = 0;
2925 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2926 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
2927 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
2932 descr.rMask = descr.gMask = descr.bMask = 0;
2937 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2938 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
2939 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
2947 if(!bmp->physBitmap)
2948 X11DRV_CreateBitmap(hbitmap);
2952 descr.palentry = NULL;
2953 descr.lines = tmpheight >= 0 ? lines : -lines;
2954 descr.depth = bmp->bitmap.bmBitsPixel;
2955 descr.drawable = (Pixmap)bmp->physBitmap;
2956 descr.gc = BITMAP_GC(bmp);
2960 descr.yDest = height - startscan - lines;
2961 descr.width = bmp->bitmap.bmWidth;
2962 descr.height = lines;
2963 descr.useShm = FALSE;
2964 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
2966 EnterCriticalSection( &X11DRV_CritSection );
2967 result = CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
2968 LeaveCriticalSection( &X11DRV_CritSection );
2970 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
2975 /***********************************************************************
2976 * X11DRV_DIB_GetDIBits
2978 INT X11DRV_DIB_GetDIBits(
2979 BITMAPOBJ *bmp, DC *dc, UINT startscan,
2980 UINT lines, LPVOID bits, BITMAPINFO *info,
2981 UINT coloruse, HBITMAP hbitmap)
2983 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
2984 X11DRV_DIB_IMAGEBITS_DESCR descr;
2985 PALETTEOBJ * palette;
2988 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
2989 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
2990 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
2993 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
2996 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
2998 height = info->bmiHeader.biHeight;
2999 if (height < 0) height = -height;
3000 if( lines > height ) lines = height;
3001 /* Top-down images have a negative biHeight, the scanlines of theses images
3002 * were inverted in X11DRV_DIB_GetImageBits_xx
3003 * To prevent this we simply change the sign of lines
3004 * (the number of scan lines to copy).
3005 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3007 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
3009 if( startscan >= bmp->bitmap.bmHeight )
3015 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
3016 &descr.infoBpp, &descr.compression ) == -1)
3022 switch (descr.infoBpp)
3028 descr.rMask = descr.gMask = descr.bMask = 0;
3032 descr.rMask = 0x7c00;
3033 descr.gMask = 0x03e0;
3034 descr.bMask = 0x001f;
3038 descr.rMask = 0xff0000;
3039 descr.gMask = 0xff00;
3045 if(!bmp->physBitmap)
3046 X11DRV_CreateBitmap(hbitmap);
3050 descr.palentry = palette->logpalette.palPalEntry;
3053 descr.lines = lines;
3054 descr.depth = bmp->bitmap.bmBitsPixel;
3055 descr.drawable = (Pixmap)bmp->physBitmap;
3056 descr.gc = BITMAP_GC(bmp);
3057 descr.width = bmp->bitmap.bmWidth;
3058 descr.height = bmp->bitmap.bmHeight;
3059 descr.colorMap = info->bmiColors;
3064 if (descr.lines > 0)
3066 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
3070 descr.ySrc = startscan;
3072 #ifdef HAVE_LIBXXSHM
3073 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
3075 descr.useShm = FALSE;
3077 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
3078 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
3080 EnterCriticalSection( &X11DRV_CritSection );
3082 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits, &descr );
3084 LeaveCriticalSection( &X11DRV_CritSection );
3086 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
3087 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
3088 info->bmiHeader.biWidth,
3089 info->bmiHeader.biHeight,
3090 info->bmiHeader.biBitCount );
3092 info->bmiHeader.biCompression = 0;
3093 if (descr.compression == BI_BITFIELDS)
3095 *(DWORD *)info->bmiColors = descr.rMask;
3096 *((DWORD *)info->bmiColors+1) = descr.gMask;
3097 *((DWORD *)info->bmiColors+2) = descr.bMask;
3101 GDI_ReleaseObj( dc->hPalette );
3106 /***********************************************************************
3107 * DIB_DoProtectDIBSection
3109 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
3111 DIBSECTION *dib = bmp->dib;
3112 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
3113 : -dib->dsBm.bmHeight;
3114 /* use the biSizeImage data as the memory size only if we're dealing with a
3115 compressed image where the value is set. Otherwise, calculate based on
3117 INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
3118 ? dib->dsBmih.biSizeImage
3119 : dib->dsBm.bmWidthBytes * effHeight;
3122 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
3123 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
3126 /***********************************************************************
3127 * X11DRV_DIB_DoUpdateDIBSection
3129 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
3131 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3132 X11DRV_DIB_IMAGEBITS_DESCR descr;
3134 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
3135 &descr.infoBpp, &descr.compression ) == -1)
3139 descr.palentry = NULL;
3140 descr.image = dib->image;
3141 descr.colorMap = (RGBQUAD *)dib->colorMap;
3142 descr.nColorMap = dib->nColorMap;
3143 descr.bits = dib->dibSection.dsBm.bmBits;
3144 descr.depth = bmp->bitmap.bmBitsPixel;
3146 switch (descr.infoBpp)
3152 descr.rMask = descr.gMask = descr.bMask = 0;
3156 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
3157 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
3158 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
3162 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff;
3163 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0xff00;
3164 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0xff0000;
3169 descr.drawable = (Pixmap)bmp->physBitmap;
3170 descr.gc = BITMAP_GC(bmp);
3175 descr.width = bmp->bitmap.bmWidth;
3176 descr.height = bmp->bitmap.bmHeight;
3177 #ifdef HAVE_LIBXXSHM
3178 descr.useShm = (dib->shminfo.shmid != -1);
3180 descr.useShm = FALSE;
3182 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
3186 TRACE("Copying from Pixmap to DIB bits\n");
3187 EnterCriticalSection( &X11DRV_CritSection );
3188 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits, &descr );
3189 LeaveCriticalSection( &X11DRV_CritSection );
3193 TRACE("Copying from DIB bits to Pixmap\n");
3194 EnterCriticalSection( &X11DRV_CritSection );
3195 CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
3196 LeaveCriticalSection( &X11DRV_CritSection );
3200 /***********************************************************************
3201 * X11DRV_DIB_FaultHandler
3203 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
3208 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
3209 if (!bmp) return FALSE;
3211 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
3212 if (state != DIB_Status_InSync) {
3213 /* no way to tell whether app needs read or write yet,
3215 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
3217 /* hm, apparently the app must have write access */
3218 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
3220 X11DRV_DIB_Unlock(bmp, TRUE);
3222 GDI_ReleaseObj( (HBITMAP)res );
3226 /***********************************************************************
3229 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
3231 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3232 INT ret = DIB_Status_None;
3235 EnterCriticalSection(&(dib->lock));
3238 case DIB_Status_GdiMod:
3239 /* GDI access - request to draw on pixmap */
3240 switch (dib->status)
3243 case DIB_Status_None:
3244 dib->p_status = DIB_Status_GdiMod;
3245 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3248 case DIB_Status_GdiMod:
3249 TRACE("GdiMod requested in status GdiMod\n" );
3252 case DIB_Status_InSync:
3253 TRACE("GdiMod requested in status InSync\n" );
3254 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3255 dib->status = DIB_Status_GdiMod;
3256 dib->p_status = DIB_Status_InSync;
3259 case DIB_Status_AuxMod:
3260 TRACE("GdiMod requested in status AuxMod\n" );
3261 if (lossy) dib->status = DIB_Status_GdiMod;
3262 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
3263 dib->p_status = DIB_Status_AuxMod;
3264 if (dib->status != DIB_Status_AppMod) {
3265 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3268 /* fall through if copy_aux() had to change to AppMod state */
3270 case DIB_Status_AppMod:
3271 TRACE("GdiMod requested in status AppMod\n" );
3273 /* make it readonly to avoid app changing data while we copy */
3274 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3275 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3277 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3278 dib->p_status = DIB_Status_AppMod;
3279 dib->status = DIB_Status_GdiMod;
3284 case DIB_Status_InSync:
3285 /* App access - request access to read DIB surface */
3286 /* (typically called from signal handler) */
3287 switch (dib->status)
3290 case DIB_Status_None:
3291 /* shouldn't happen from signal handler */
3294 case DIB_Status_AuxMod:
3295 TRACE("InSync requested in status AuxMod\n" );
3296 if (lossy) dib->status = DIB_Status_InSync;
3298 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3299 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
3301 if (dib->status != DIB_Status_GdiMod) {
3302 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3305 /* fall through if copy_aux() had to change to GdiMod state */
3307 case DIB_Status_GdiMod:
3308 TRACE("InSync requested in status GdiMod\n" );
3310 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3311 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3313 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3314 dib->status = DIB_Status_InSync;
3317 case DIB_Status_InSync:
3318 TRACE("InSync requested in status InSync\n" );
3319 /* shouldn't happen from signal handler */
3322 case DIB_Status_AppMod:
3323 TRACE("InSync requested in status AppMod\n" );
3324 /* no reason to do anything here, and this
3325 * shouldn't happen from signal handler */
3330 case DIB_Status_AppMod:
3331 /* App access - request access to write DIB surface */
3332 /* (typically called from signal handler) */
3333 switch (dib->status)
3336 case DIB_Status_None:
3337 /* shouldn't happen from signal handler */
3340 case DIB_Status_AuxMod:
3341 TRACE("AppMod requested in status AuxMod\n" );
3342 if (lossy) dib->status = DIB_Status_AppMod;
3344 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3345 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
3347 if (dib->status != DIB_Status_GdiMod)
3349 /* fall through if copy_aux() had to change to GdiMod state */
3351 case DIB_Status_GdiMod:
3352 TRACE("AppMod requested in status GdiMod\n" );
3353 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3354 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3357 case DIB_Status_InSync:
3358 TRACE("AppMod requested in status InSync\n" );
3359 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3360 dib->status = DIB_Status_AppMod;
3363 case DIB_Status_AppMod:
3364 TRACE("AppMod requested in status AppMod\n" );
3365 /* shouldn't happen from signal handler */
3370 case DIB_Status_AuxMod:
3371 if (dib->status == DIB_Status_None) {
3372 dib->p_status = req;
3374 if (dib->status != DIB_Status_AuxMod)
3375 dib->p_status = dib->status;
3376 dib->status = DIB_Status_AuxMod;
3379 /* it is up to the caller to do the copy/conversion, probably
3380 * using the return value to decide where to copy from */
3382 LeaveCriticalSection(&(dib->lock));
3387 /***********************************************************************
3390 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
3392 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3393 INT ret = DIB_Status_None;
3396 EnterCriticalSection(&(dib->lock));
3398 if (req != DIB_Status_None)
3399 X11DRV_DIB_Coerce(bmp, req, lossy);
3404 /***********************************************************************
3407 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
3409 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3412 switch (dib->status)
3415 case DIB_Status_None:
3416 /* in case anyone is wondering, this is the "signal handler doesn't
3417 * work" case, where we always have to be ready for app access */
3419 switch (dib->p_status)
3421 case DIB_Status_AuxMod:
3422 TRACE("Unlocking and syncing from AuxMod\n" );
3423 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
3424 if (dib->status != DIB_Status_None) {
3425 dib->p_status = dib->status;
3426 dib->status = DIB_Status_None;
3428 if (dib->p_status != DIB_Status_GdiMod)
3430 /* fall through if copy_aux() had to change to GdiMod state */
3432 case DIB_Status_GdiMod:
3433 TRACE("Unlocking and syncing from GdiMod\n" );
3434 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3438 TRACE("Unlocking without needing to sync\n" );
3442 else TRACE("Unlocking with no changes\n");
3443 dib->p_status = DIB_Status_None;
3446 case DIB_Status_GdiMod:
3447 TRACE("Unlocking in status GdiMod\n" );
3448 /* DIB was protected in Coerce */
3450 /* no commit, revert to InSync if applicable */
3451 if ((dib->p_status == DIB_Status_InSync) ||
3452 (dib->p_status == DIB_Status_AppMod)) {
3453 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3454 dib->status = DIB_Status_InSync;
3459 case DIB_Status_InSync:
3460 TRACE("Unlocking in status InSync\n" );
3461 /* DIB was already protected in Coerce */
3464 case DIB_Status_AppMod:
3465 TRACE("Unlocking in status AppMod\n" );
3466 /* DIB was already protected in Coerce */
3467 /* this case is ordinary only called from the signal handler,
3468 * so we don't bother to check for !commit */
3471 case DIB_Status_AuxMod:
3472 TRACE("Unlocking in status AuxMod\n" );
3474 /* DIB may need protection now */
3475 if ((dib->p_status == DIB_Status_InSync) ||
3476 (dib->p_status == DIB_Status_AppMod))
3477 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3479 /* no commit, revert to previous state */
3480 if (dib->p_status != DIB_Status_None)
3481 dib->status = dib->p_status;
3482 /* no protections changed */
3484 dib->p_status = DIB_Status_None;
3487 LeaveCriticalSection(&(dib->lock));
3491 /***********************************************************************
3492 * X11DRV_CoerceDIBSection
3494 INT X11DRV_CoerceDIBSection(DC *dc, INT req, BOOL lossy)
3499 if (!dc) return DIB_Status_None;
3500 if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;
3502 bmp = (BITMAPOBJ *)GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
3503 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
3504 GDI_ReleaseObj( dc->hBitmap );
3508 /***********************************************************************
3509 * X11DRV_LockDIBSection2
3511 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
3516 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3517 ret = X11DRV_DIB_Lock(bmp, req, lossy);
3518 GDI_ReleaseObj( hBmp );
3522 /***********************************************************************
3523 * X11DRV_UnlockDIBSection2
3525 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
3529 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3530 X11DRV_DIB_Unlock(bmp, commit);
3531 GDI_ReleaseObj( hBmp );
3534 /***********************************************************************
3535 * X11DRV_LockDIBSection
3537 INT X11DRV_LockDIBSection(DC *dc, INT req, BOOL lossy)
3539 if (!dc) return DIB_Status_None;
3540 if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;
3542 return X11DRV_LockDIBSection2( dc->hBitmap, req, lossy );
3545 /***********************************************************************
3546 * X11DRV_UnlockDIBSection
3548 void X11DRV_UnlockDIBSection(DC *dc, BOOL commit)
3551 if (!(dc->flags & DC_MEMORY)) return;
3553 X11DRV_UnlockDIBSection2( dc->hBitmap, commit );
3556 /***********************************************************************
3557 * X11DRV_DIB_CreateDIBSection16
3559 HBITMAP16 X11DRV_DIB_CreateDIBSection16(
3560 DC *dc, BITMAPINFO *bmi, UINT16 usage,
3561 SEGPTR *bits, HANDLE section,
3562 DWORD offset, DWORD ovr_pitch)
3564 HBITMAP res = X11DRV_DIB_CreateDIBSection(dc, bmi, usage, NULL,
3565 section, offset, ovr_pitch);
3568 BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3569 if ( bmp && bmp->dib )
3571 DIBSECTION *dib = bmp->dib;
3572 INT height = dib->dsBm.bmHeight >= 0 ?
3573 dib->dsBm.bmHeight : -dib->dsBm.bmHeight;
3574 /* same as above - only use biSizeImage as the correct size if it a
3575 compressed image and it's currently non-zero. In other cases, use
3576 width * height as the value. */
3577 INT size = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
3578 ? dib->dsBmih.biSizeImage
3579 : dib->dsBm.bmWidthBytes * height;
3580 if ( dib->dsBm.bmBits )
3582 ((X11DRV_DIBSECTION *) bmp->dib)->selector =
3583 SELECTOR_AllocBlock( dib->dsBm.bmBits, size, WINE_LDT_FLAGS_DATA );
3585 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3586 dib->dsBm.bmBits, size, ((X11DRV_DIBSECTION *) bmp->dib)->selector,
3587 MAKESEGPTR(((X11DRV_DIBSECTION *) bmp->dib)->selector, 0));
3589 *bits = MAKESEGPTR( ((X11DRV_DIBSECTION *) bmp->dib)->selector, 0 );
3591 if (bmp) GDI_ReleaseObj( res );
3597 /***********************************************************************
3598 * X11DRV_XShmErrorHandler
3601 static int XShmErrorHandler(Display *dpy, XErrorEvent *event)
3607 /***********************************************************************
3608 * X11DRV_XShmCreateImage
3612 #ifdef HAVE_LIBXXSHM
3613 extern BOOL X11DRV_XShmCreateImage(XImage** image, int width, int height, int bpp,
3614 XShmSegmentInfo* shminfo)
3616 int (*WineXHandler)(Display *, XErrorEvent *);
3618 *image = TSXShmCreateImage(display, X11DRV_GetVisual(), bpp, ZPixmap, NULL, shminfo, width, height);
3619 if( *image != NULL )
3621 EnterCriticalSection( &X11DRV_CritSection );
3622 shminfo->shmid = shmget(IPC_PRIVATE, (*image)->bytes_per_line * height,
3624 if( shminfo->shmid != -1 )
3626 shminfo->shmaddr = (*image)->data = shmat(shminfo->shmid, 0, 0);
3627 if( shminfo->shmaddr != (char*)-1 )
3629 shminfo->readOnly = FALSE;
3630 if( TSXShmAttach( display, shminfo ) != 0)
3632 /* Reset the error flag */
3634 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3635 XSync( display, 0 );
3639 shmctl(shminfo->shmid, IPC_RMID, 0);
3641 XSetErrorHandler(WineXHandler);
3642 LeaveCriticalSection( &X11DRV_CritSection );
3644 return TRUE; /* Success! */
3646 /* An error occured */
3648 XSetErrorHandler(WineXHandler);
3650 shmdt(shminfo->shmaddr);
3652 shmctl(shminfo->shmid, IPC_RMID, 0);
3655 XDestroyImage(*image);
3656 LeaveCriticalSection( &X11DRV_CritSection );
3660 #endif /* HAVE_LIBXXSHM */
3664 /***********************************************************************
3665 * X11DRV_DIB_CreateDIBSection
3667 HBITMAP X11DRV_DIB_CreateDIBSection(
3668 DC *dc, BITMAPINFO *bmi, UINT usage,
3669 LPVOID *bits, HANDLE section,
3670 DWORD offset, DWORD ovr_pitch)
3673 BITMAPOBJ *bmp = NULL;
3674 X11DRV_DIBSECTION *dib = NULL;
3675 int *colorMap = NULL;
3678 /* Fill BITMAP32 structure with DIB data */
3679 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
3680 INT effHeight, totalSize;
3683 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3684 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
3685 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
3687 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
3689 bm.bmWidth = bi->biWidth;
3690 bm.bmHeight = effHeight;
3691 bm.bmWidthBytes = ovr_pitch ? ovr_pitch
3692 : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
3693 bm.bmPlanes = bi->biPlanes;
3694 bm.bmBitsPixel = bi->biBitCount;
3697 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
3698 we're dealing with a compressed bitmap. Otherwise, use width * height. */
3699 totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
3700 ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
3703 bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS,
3704 0L, offset, totalSize);
3705 else if (ovr_pitch && offset)
3706 bm.bmBits = (LPVOID) offset;
3709 bm.bmBits = VirtualAlloc(NULL, totalSize,
3710 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
3713 /* Create Color Map */
3714 if (bm.bmBits && bm.bmBitsPixel <= 8)
3715 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? dc : NULL,
3716 usage, bm.bmBitsPixel, bmi, &nColorMap );
3718 /* Allocate Memory for DIB and fill structure */
3720 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
3723 dib->dibSection.dsBm = bm;
3724 dib->dibSection.dsBmih = *bi;
3725 dib->dibSection.dsBmih.biSizeImage = totalSize;
3727 /* Set dsBitfields values */
3728 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
3730 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
3732 else switch( bi->biBitCount )
3735 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
3736 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
3737 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
3741 dib->dibSection.dsBitfields[0] = 0xff;
3742 dib->dibSection.dsBitfields[1] = 0xff00;
3743 dib->dibSection.dsBitfields[2] = 0xff0000;
3747 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
3748 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
3749 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
3752 dib->dibSection.dshSection = section;
3753 dib->dibSection.dsOffset = offset;
3755 dib->status = DIB_Status_None;
3758 dib->nColorMap = nColorMap;
3759 dib->colorMap = colorMap;
3762 /* Create Device Dependent Bitmap and add DIB pointer */
3765 res = CreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
3768 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3771 bmp->dib = (DIBSECTION *) dib;
3773 if(!bmp->physBitmap)
3774 X11DRV_CreateBitmap(res);
3782 #ifdef HAVE_LIBXXSHM
3783 if (TSXShmQueryExtension(display) &&
3784 X11DRV_XShmCreateImage( &dib->image, bm.bmWidth, effHeight,
3785 bmp->bitmap.bmBitsPixel, &dib->shminfo ) )
3787 ; /* Created Image */
3789 XCREATEIMAGE( dib->image, bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3790 dib->shminfo.shmid = -1;
3793 XCREATEIMAGE( dib->image, bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3797 /* Clean up in case of errors */
3798 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
3800 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3801 res, bmp, dib, bm.bmBits);
3805 UnmapViewOfFile(bm.bmBits), bm.bmBits = NULL;
3807 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
3810 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
3811 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
3812 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
3813 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
3814 if (res) { DeleteObject(res); res = 0; }
3818 /* Install fault handler, if possible */
3819 InitializeCriticalSection(&(dib->lock));
3820 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
3822 if (section || offset)
3824 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3825 if (dib) dib->status = DIB_Status_AppMod;
3829 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3830 if (dib) dib->status = DIB_Status_InSync;
3835 /* Return BITMAP handle and storage location */
3836 if (bmp) GDI_ReleaseObj(res);
3837 if (bm.bmBits && bits) *bits = bm.bmBits;
3841 /***********************************************************************
3842 * X11DRV_DIB_DeleteDIBSection
3844 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
3846 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3850 #ifdef HAVE_LIBXXSHM
3851 if (dib->shminfo.shmid != -1)
3853 TSXShmDetach (display, &(dib->shminfo));
3854 XDestroyImage (dib->image);
3855 shmdt (dib->shminfo.shmaddr);
3856 dib->shminfo.shmid = -1;
3860 XDestroyImage( dib->image );
3864 HeapFree(GetProcessHeap(), 0, dib->colorMap);
3866 if (dib->selector) SELECTOR_FreeBlock( dib->selector );
3867 DeleteCriticalSection(&(dib->lock));
3870 /***********************************************************************
3871 * X11DRV_DIB_SetDIBColorTable
3873 UINT X11DRV_DIB_SetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, const RGBQUAD *colors)
3875 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3877 if (dib && dib->colorMap) {
3878 X11DRV_DIB_GenColorMap( dc, dib->colorMap, DIB_RGB_COLORS, dib->dibSection.dsBm.bmBitsPixel,
3879 TRUE, colors, start, count + start );
3885 /***********************************************************************
3886 * X11DRV_DIB_GetDIBColorTable
3888 UINT X11DRV_DIB_GetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, RGBQUAD *colors)
3890 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3892 if (dib && dib->colorMap) {
3893 int i, end = count + start;
3894 if (end > dib->nColorMap) end = dib->nColorMap;
3895 for (i = start; i < end; i++,colors++) {
3896 COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
3897 colors->rgbBlue = GetBValue(col);
3898 colors->rgbGreen = GetGValue(col);
3899 colors->rgbRed = GetRValue(col);
3900 colors->rgbReserved = 0;
3908 /**************************************************************************
3909 * X11DRV_DIB_CreateDIBFromPixmap
3911 * Allocates a packed DIB and copies the Pixmap data into it.
3912 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
3914 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
3917 BITMAPOBJ *pBmp = NULL;
3918 HGLOBAL hPackedDIB = 0;
3920 /* Allocates an HBITMAP which references the Pixmap passed to us */
3921 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
3924 TRACE("\tCould not create bitmap header for Pixmap\n");
3929 * Create a packed DIB from the Pixmap wrapper bitmap created above.
3930 * A packed DIB contains a BITMAPINFO structure followed immediately by
3931 * an optional color palette and the pixel data.
3933 hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
3935 /* Get a pointer to the BITMAPOBJ structure */
3936 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3938 /* We can now get rid of the HBITMAP wrapper we created earlier.
3939 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
3943 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
3944 pBmp->physBitmap = NULL;
3947 GDI_ReleaseObj( hBmp );
3951 TRACE("\tReturning packed DIB %x\n", hPackedDIB);
3956 /**************************************************************************
3957 * X11DRV_DIB_CreatePixmapFromDIB
3959 * Creates a Pixmap from a packed DIB
3961 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
3963 Pixmap pixmap = None;
3965 BITMAPOBJ *pBmp = NULL;
3966 LPBYTE pPackedDIB = NULL;
3967 LPBITMAPINFO pbmi = NULL;
3968 LPBITMAPINFOHEADER pbmiHeader = NULL;
3969 LPBYTE pbits = NULL;
3971 /* Get a pointer to the packed DIB's data */
3972 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
3973 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
3974 pbmi = (LPBITMAPINFO)pPackedDIB;
3975 pbits = (LPBYTE)(pPackedDIB
3976 + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
3978 /* Create a DDB from the DIB */
3980 hBmp = CreateDIBitmap(hdc,
3987 GlobalUnlock(hPackedDIB);
3989 TRACE("CreateDIBitmap returned %x\n", hBmp);
3991 /* Retrieve the internal Pixmap from the DDB */
3993 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3995 pixmap = (Pixmap)pBmp->physBitmap;
3996 /* clear the physBitmap so that we can steal its pixmap */
3997 pBmp->physBitmap = NULL;
4000 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4001 GDI_ReleaseObj( hBmp );
4004 TRACE("\tReturning Pixmap %ld\n", pixmap);