2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
26 #include <X11/extensions/XShm.h>
27 # ifdef HAVE_SYS_SHM_H
30 # ifdef HAVE_SYS_IPC_H
33 #endif /* defined(HAVE_LIBXXSHM) */
42 #include "wine/exception.h"
43 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(bitmap
);
47 static struct list dibs_list
= LIST_INIT(dibs_list
);
49 static CRITICAL_SECTION dibs_cs
;
50 static CRITICAL_SECTION_DEBUG dibs_cs_debug
=
53 { &dibs_cs_debug
.ProcessLocksList
, &dibs_cs_debug
.ProcessLocksList
},
54 0, 0, { (DWORD_PTR
)(__FILE__
": dibs_cs") }
56 static CRITICAL_SECTION dibs_cs
= { &dibs_cs_debug
, -1, 0, 0, 0, 0 };
58 static PVOID dibs_handler
;
60 static int ximageDepthTable
[32];
62 /* This structure holds the arguments for DIB_SetImageBits() */
65 X11DRV_PDEVICE
*physDev
;
68 PALETTEENTRY
*palentry
;
88 enum x11drv_shm_mode shm_mode
;
91 X_PHYSBITMAP
*physBitmap
;
92 } X11DRV_DIB_IMAGEBITS_DESCR
;
97 RLE_EOL
= 0, /* End of line */
98 RLE_END
= 1, /* End of bitmap */
99 RLE_DELTA
= 2 /* Delta */
103 static INT
X11DRV_DIB_Coerce(X_PHYSBITMAP
*,INT
);
106 Some of the following helper functions are duplicated in
110 /***********************************************************************
111 * DIB_DoProtectDIBSection
113 static void X11DRV_DIB_DoProtectDIBSection( X_PHYSBITMAP
*physBitmap
, DWORD new_prot
)
117 VirtualProtect(physBitmap
->base
, physBitmap
->size
, new_prot
, &old_prot
);
118 TRACE("Changed protection from %d to %d\n", old_prot
, new_prot
);
121 /***********************************************************************
122 * X11DRV_DIB_GetXImageWidthBytes
124 * Return the width of an X image in bytes
126 static inline int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
128 if (!depth
|| depth
> 32) goto error
;
130 if (!ximageDepthTable
[depth
-1])
132 XImage
*testimage
= XCreateImage( gdi_display
, visual
, depth
,
133 ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
136 ximageDepthTable
[depth
-1] = testimage
->bits_per_pixel
;
137 XDestroyImage( testimage
);
139 else ximageDepthTable
[depth
-1] = -1;
141 if (ximageDepthTable
[depth
-1] != -1)
142 return (4 * ((width
* ximageDepthTable
[depth
-1] + 31) / 32));
145 WARN( "(%d): Unsupported depth\n", depth
);
150 /***********************************************************************
151 * X11DRV_DIB_GetDIBWidthBytes
153 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
155 static int X11DRV_DIB_GetDIBWidthBytes( int width
, int depth
)
157 return ((width
* depth
+ 31) / 8) & ~3;
161 /***********************************************************************
164 * Return the size of the bitmap info structure including color table.
166 int bitmap_info_size( const BITMAPINFO
* info
, WORD coloruse
)
168 unsigned int colors
, size
, masks
= 0;
170 if (info
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
172 const BITMAPCOREHEADER
*core
= (const BITMAPCOREHEADER
*)info
;
173 colors
= (core
->bcBitCount
<= 8) ? 1 << core
->bcBitCount
: 0;
174 return sizeof(BITMAPCOREHEADER
) + colors
*
175 ((coloruse
== DIB_RGB_COLORS
) ? sizeof(RGBTRIPLE
) : sizeof(WORD
));
177 else /* assume BITMAPINFOHEADER */
179 colors
= info
->bmiHeader
.biClrUsed
;
180 if (!colors
&& (info
->bmiHeader
.biBitCount
<= 8))
181 colors
= 1 << info
->bmiHeader
.biBitCount
;
182 if (info
->bmiHeader
.biCompression
== BI_BITFIELDS
) masks
= 3;
183 size
= max( info
->bmiHeader
.biSize
, sizeof(BITMAPINFOHEADER
) + masks
* sizeof(DWORD
) );
184 return size
+ colors
* ((coloruse
== DIB_RGB_COLORS
) ? sizeof(RGBQUAD
) : sizeof(WORD
));
189 /***********************************************************************
190 * X11DRV_DIB_CreateXImage
194 XImage
*X11DRV_DIB_CreateXImage( int width
, int height
, int depth
)
197 XImage
*image
= NULL
;
201 width_bytes
= X11DRV_DIB_GetXImageWidthBytes( width
, depth
);
202 data
= HeapAlloc( GetProcessHeap(), 0, height
* width_bytes
);
203 if (data
) image
= XCreateImage( gdi_display
, visual
, depth
, ZPixmap
, 0,
204 data
, width
, height
, 32, width_bytes
);
205 if (!image
) HeapFree( GetProcessHeap(), 0, data
);
211 /***********************************************************************
212 * X11DRV_DIB_DestroyXImage
214 * Destroy an X image created with X11DRV_DIB_CreateXImage.
216 void X11DRV_DIB_DestroyXImage( XImage
*image
)
218 HeapFree( GetProcessHeap(), 0, image
->data
);
221 XDestroyImage( image
);
226 /***********************************************************************
227 * X11DRV_DIB_GetColorCount
229 * Computes the number of colors for the bitmap palette.
230 * Should not be called for a >8-bit deep bitmap.
232 static unsigned int X11DRV_DIB_GetColorCount(const BITMAPINFO
*info
)
234 unsigned int colors
= min( info
->bmiHeader
.biClrUsed
, 256 );
235 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
240 static inline BOOL
colour_is_brighter(RGBQUAD c1
, RGBQUAD c2
)
242 return (c1
.rgbRed
* c1
.rgbRed
+ c1
.rgbGreen
* c1
.rgbGreen
+ c1
.rgbBlue
* c1
.rgbBlue
) >
243 (c2
.rgbRed
* c2
.rgbRed
+ c2
.rgbGreen
* c2
.rgbGreen
+ c2
.rgbBlue
* c2
.rgbBlue
);
246 /***********************************************************************
247 * X11DRV_DIB_GenColorMap
249 * Fills the color map of a bitmap palette. Should not be called
250 * for a >8-bit deep bitmap.
252 static int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE
*physDev
, int *colorMapping
,
253 WORD coloruse
, WORD depth
, const void *colorPtr
, int start
, int end
)
257 if (coloruse
== DIB_RGB_COLORS
)
259 const RGBQUAD
* rgb
= colorPtr
;
261 if (depth
== 1) /* Monochrome */
266 if (GetDIBColorTable( physDev
->dev
.hdc
, 0, 2, table
) == 2)
267 invert
= !colour_is_brighter(table
[1], table
[0]);
269 for (i
= start
; i
< end
; i
++, rgb
++)
270 colorMapping
[i
] = ((rgb
->rgbRed
+ rgb
->rgbGreen
+
271 rgb
->rgbBlue
> 255*3/2 && !invert
) ||
272 (rgb
->rgbRed
+ rgb
->rgbGreen
+
273 rgb
->rgbBlue
<= 255*3/2 && invert
));
276 for (i
= start
; i
< end
; i
++, rgb
++)
277 colorMapping
[i
] = X11DRV_PALETTE_LookupPixel(physDev
->color_shifts
, RGB(rgb
->rgbRed
,
281 else /* DIB_PAL_COLORS */
283 const WORD
* index
= colorPtr
;
285 for (i
= start
; i
< end
; i
++, index
++)
286 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(*index
) );
292 /***********************************************************************
293 * X11DRV_DIB_BuildColorMap
295 * Build the color map from the bitmap palette. Should not be called
296 * for a >8-bit deep bitmap.
298 static int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE
*physDev
, WORD coloruse
, WORD depth
,
299 const BITMAPINFO
*info
, int *nColors
)
301 const void *colorPtr
;
305 *nColors
= X11DRV_DIB_GetColorCount(info
);
306 if (!*nColors
) return NULL
;
308 colorPtr
= (const BYTE
*)info
+ (WORD
)info
->bmiHeader
.biSize
;
309 if (!(colorMapping
= HeapAlloc(GetProcessHeap(), 0, *nColors
* sizeof(int) )))
312 return X11DRV_DIB_GenColorMap( physDev
, colorMapping
, coloruse
, depth
,
313 colorPtr
, 0, *nColors
);
316 /***********************************************************************
317 * X11DRV_DIB_MapColor
319 static int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
, int oldcol
)
323 if ((oldcol
< nPhysMap
) && (physMap
[oldcol
] == phys
))
326 for (color
= 0; color
< nPhysMap
; color
++)
327 if (physMap
[color
] == phys
)
330 WARN("Strange color %08x\n", phys
);
335 /*********************************************************************
336 * X11DRV_DIB_GetNearestIndex
338 * Helper for X11DRV_DIB_GetDIBits.
339 * Returns the nearest colour table index for a given RGB.
340 * Nearest is defined by minimizing the sum of the squares.
342 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
344 INT i
, best
= -1, diff
, bestdiff
= -1;
347 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
348 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
349 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
350 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
353 if(best
== -1 || diff
< bestdiff
) {
360 /*********************************************************************
361 * X11DRV_DIB_MaskToShift
363 * Helper for X11DRV_DIB_GetDIBits.
364 * Returns the by how many bits to shift a given color so that it is
365 * in the proper position.
367 INT
X11DRV_DIB_MaskToShift(DWORD mask
)
375 while ((mask
&1)==0) {
382 /***********************************************************************
383 * X11DRV_DIB_CheckMask
385 * Check RGB mask if it is either 0 or matches visual's mask.
387 static inline int X11DRV_DIB_CheckMask(int red_mask
, int green_mask
, int blue_mask
)
389 return ( red_mask
== 0 && green_mask
== 0 && blue_mask
== 0 ) ||
390 ( red_mask
== visual
->red_mask
&& green_mask
== visual
->green_mask
&&
391 blue_mask
== visual
->blue_mask
);
394 /***********************************************************************
395 * X11DRV_DIB_SetImageBits_1
397 * SetDIBits for a 1-bit deep DIB.
399 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
400 DWORD srcwidth
, DWORD dstwidth
, int left
,
401 int *colors
, XImage
*bmpImage
, int linebytes
)
410 srcbits
= srcbits
+ linebytes
* (lines
- 1);
411 linebytes
= -linebytes
;
414 if ((extra
= (left
& 7)) != 0) {
418 srcbits
+= left
>> 3;
419 width
= min(srcwidth
, dstwidth
);
421 /* ==== pal 1 dib -> any bmp format ==== */
422 for (h
= lines
-1; h
>=0; h
--) {
424 for (i
= width
/8, x
= left
; i
> 0; i
--) {
426 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
>> 7] );
427 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 6) & 1] );
428 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 5) & 1] );
429 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 4) & 1] );
430 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 3) & 1] );
431 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 2) & 1] );
432 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 1) & 1] );
433 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
& 1] );
439 case 7: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
441 case 6: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
443 case 5: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
445 case 4: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
447 case 3: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
449 case 2: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
451 case 1: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]);
454 srcbits
+= linebytes
;
458 /***********************************************************************
459 * X11DRV_DIB_GetImageBits_1
461 * GetDIBits for a 1-bit deep DIB.
463 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
464 DWORD dstwidth
, DWORD srcwidth
,
465 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
466 XImage
*bmpImage
, int linebytes
)
469 int h
, width
= min(dstwidth
, srcwidth
);
473 dstbits
= dstbits
+ linebytes
* (lines
- 1);
474 linebytes
= -linebytes
;
477 switch (bmpImage
->depth
)
481 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
483 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
486 for (h
=lines
-1; h
>=0; h
--) {
490 for (x
=0; x
<width
; x
++) {
492 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
493 dstval
|=(X11DRV_DIB_GetNearestIndex
497 srcval
.peBlue
) << (7 - (x
& 7)));
506 /* pad with 0 to DWORD alignment */
507 for (x
= (x
+7)&~7; x
< ((width
+ 31) & ~31); x
+=8)
509 dstbits
+= linebytes
;
517 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
, bmpImage
->green_mask
, bmpImage
->blue_mask
)
519 /* ==== pal 8 bmp -> pal 1 dib ==== */
521 const BYTE
* srcpixel
;
524 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
526 for (h
=0; h
<lines
; h
++) {
531 for (x
=0; x
<width
; x
++) {
533 srcval
=srccolors
[*srcpixel
++];
534 dstval
|=(X11DRV_DIB_GetNearestIndex
538 srcval
.peBlue
) << (7-(x
&7)) );
547 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
548 dstbits
+= linebytes
;
559 const WORD
* srcpixel
;
562 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
564 if (bmpImage
->green_mask
==0x03e0) {
565 if (bmpImage
->red_mask
==0x7c00) {
566 /* ==== rgb 555 bmp -> pal 1 dib ==== */
567 for (h
=0; h
<lines
; h
++) {
572 for (x
=0; x
<width
; x
++) {
575 dstval
|=(X11DRV_DIB_GetNearestIndex
577 ((srcval
>> 7) & 0xf8) | /* r */
578 ((srcval
>> 12) & 0x07),
579 ((srcval
>> 2) & 0xf8) | /* g */
580 ((srcval
>> 7) & 0x07),
581 ((srcval
<< 3) & 0xf8) | /* b */
582 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
591 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
592 dstbits
+= linebytes
;
594 } else if (bmpImage
->blue_mask
==0x7c00) {
595 /* ==== bgr 555 bmp -> pal 1 dib ==== */
596 for (h
=0; h
<lines
; h
++) {
601 for (x
=0; x
<width
; x
++) {
604 dstval
|=(X11DRV_DIB_GetNearestIndex
606 ((srcval
<< 3) & 0xf8) | /* r */
607 ((srcval
>> 2) & 0x07),
608 ((srcval
>> 2) & 0xf8) | /* g */
609 ((srcval
>> 7) & 0x07),
610 ((srcval
>> 7) & 0xf8) | /* b */
611 ((srcval
>> 12) & 0x07) ) << (7-(x
&7)) );
620 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
621 dstbits
+= linebytes
;
626 } else if (bmpImage
->green_mask
==0x07e0) {
627 if (bmpImage
->red_mask
==0xf800) {
628 /* ==== rgb 565 bmp -> pal 1 dib ==== */
629 for (h
=0; h
<lines
; h
++) {
634 for (x
=0; x
<width
; x
++) {
637 dstval
|=(X11DRV_DIB_GetNearestIndex
639 ((srcval
>> 8) & 0xf8) | /* r */
640 ((srcval
>> 13) & 0x07),
641 ((srcval
>> 3) & 0xfc) | /* g */
642 ((srcval
>> 9) & 0x03),
643 ((srcval
<< 3) & 0xf8) | /* b */
644 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
653 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
654 dstbits
+= linebytes
;
656 } else if (bmpImage
->blue_mask
==0xf800) {
657 /* ==== bgr 565 bmp -> pal 1 dib ==== */
658 for (h
=0; h
<lines
; h
++) {
663 for (x
=0; x
<width
; x
++) {
666 dstval
|=(X11DRV_DIB_GetNearestIndex
668 ((srcval
<< 3) & 0xf8) | /* r */
669 ((srcval
>> 2) & 0x07),
670 ((srcval
>> 3) & 0xfc) | /* g */
671 ((srcval
>> 9) & 0x03),
672 ((srcval
>> 8) & 0xf8) | /* b */
673 ((srcval
>> 13) & 0x07) ) << (7-(x
&7)) );
682 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
683 dstbits
+= linebytes
;
702 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
703 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
705 if (bmpImage
->green_mask
!=0x00ff00 ||
706 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
708 } else if (bmpImage
->blue_mask
==0xff) {
709 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
710 for (h
=0; h
<lines
; h
++) {
715 for (x
=0; x
<width
; x
++) {
716 dstval
|=(X11DRV_DIB_GetNearestIndex
720 srcbyte
[0]) << (7-(x
&7)) );
721 srcbyte
+=bytes_per_pixel
;
730 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
731 dstbits
+= linebytes
;
734 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
735 for (h
=0; h
<lines
; h
++) {
740 for (x
=0; x
<width
; x
++) {
741 dstval
|=(X11DRV_DIB_GetNearestIndex
745 srcbyte
[2]) << (7-(x
&7)) );
746 srcbyte
+=bytes_per_pixel
;
755 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
756 dstbits
+= linebytes
;
767 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
769 /* ==== any bmp format -> pal 1 dib ==== */
770 if ((unsigned)colors
[0].rgbRed
+colors
[0].rgbGreen
+colors
[0].rgbBlue
>=
771 (unsigned)colors
[1].rgbRed
+colors
[1].rgbGreen
+colors
[1].rgbBlue
)
774 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB, "
775 "%s color mapping\n",
776 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
777 bmpImage
->green_mask
, bmpImage
->blue_mask
,
778 neg
?"negative":"direct" );
780 for (h
=lines
-1; h
>=0; h
--) {
784 for (x
=0; x
<width
; x
++) {
785 dstval
|=((XGetPixel( bmpImage
, x
, h
) >= white
) ^ neg
) << (7 - (x
&7));
794 dstbits
+= linebytes
;
801 /***********************************************************************
802 * X11DRV_DIB_SetImageBits_4
804 * SetDIBits for a 4-bit deep DIB.
806 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
807 DWORD srcwidth
, DWORD dstwidth
, int left
,
808 int *colors
, XImage
*bmpImage
, int linebytes
)
816 srcbits
= srcbits
+ linebytes
* (lines
- 1);
817 linebytes
= -linebytes
;
824 srcbits
+= left
>> 1;
825 width
= min(srcwidth
, dstwidth
);
827 /* ==== pal 4 dib -> any bmp format ==== */
828 for (h
= lines
-1; h
>= 0; h
--) {
830 for (i
= width
/2, x
= left
; i
> 0; i
--) {
831 BYTE srcval
=*srcbyte
++;
832 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
>> 4] );
833 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
& 0x0f] );
836 XPutPixel( bmpImage
, x
, h
, colors
[*srcbyte
>> 4] );
837 srcbits
+= linebytes
;
843 /***********************************************************************
844 * X11DRV_DIB_GetImageBits_4
846 * GetDIBits for a 4-bit deep DIB.
848 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
849 DWORD srcwidth
, DWORD dstwidth
,
850 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
851 XImage
*bmpImage
, int linebytes
)
854 int h
, width
= min(srcwidth
, dstwidth
);
859 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
860 linebytes
= -linebytes
;
863 switch (bmpImage
->depth
) {
866 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
868 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
871 for (h
= lines
-1; h
>= 0; h
--) {
875 for (x
= 0; x
< width
; x
++) {
877 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
878 dstval
|=(X11DRV_DIB_GetNearestIndex
882 srcval
.peBlue
) << (4-((x
&1)<<2)));
891 dstbits
+= linebytes
;
899 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
901 /* ==== pal 8 bmp -> pal 4 dib ==== */
903 const BYTE
*srcpixel
;
906 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
907 for (h
=0; h
<lines
; h
++) {
912 for (x
=0; x
<width
; x
++) {
914 srcval
= srccolors
[*srcpixel
++];
915 dstval
|=(X11DRV_DIB_GetNearestIndex
919 srcval
.peBlue
) << (4*(1-(x
&1))) );
928 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
929 dstbits
+= linebytes
;
940 const WORD
* srcpixel
;
943 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
945 if (bmpImage
->green_mask
==0x03e0) {
946 if (bmpImage
->red_mask
==0x7c00) {
947 /* ==== rgb 555 bmp -> pal 4 dib ==== */
948 for (h
=0; h
<lines
; h
++) {
953 for (x
=0; x
<width
; x
++) {
956 dstval
|=(X11DRV_DIB_GetNearestIndex
958 ((srcval
>> 7) & 0xf8) | /* r */
959 ((srcval
>> 12) & 0x07),
960 ((srcval
>> 2) & 0xf8) | /* g */
961 ((srcval
>> 7) & 0x07),
962 ((srcval
<< 3) & 0xf8) | /* b */
963 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
972 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
973 dstbits
+= linebytes
;
975 } else if (bmpImage
->blue_mask
==0x7c00) {
976 /* ==== bgr 555 bmp -> pal 4 dib ==== */
977 for (h
=0; h
<lines
; h
++) {
982 for (x
=0; x
<width
; x
++) {
985 dstval
|=(X11DRV_DIB_GetNearestIndex
987 ((srcval
<< 3) & 0xf8) | /* r */
988 ((srcval
>> 2) & 0x07),
989 ((srcval
>> 2) & 0xf8) | /* g */
990 ((srcval
>> 7) & 0x07),
991 ((srcval
>> 7) & 0xf8) | /* b */
992 ((srcval
>> 12) & 0x07) ) << ((1-(x
&1))<<2) );
1001 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1002 dstbits
+= linebytes
;
1007 } else if (bmpImage
->green_mask
==0x07e0) {
1008 if (bmpImage
->red_mask
==0xf800) {
1009 /* ==== rgb 565 bmp -> pal 4 dib ==== */
1010 for (h
=0; h
<lines
; h
++) {
1015 for (x
=0; x
<width
; x
++) {
1018 dstval
|=(X11DRV_DIB_GetNearestIndex
1020 ((srcval
>> 8) & 0xf8) | /* r */
1021 ((srcval
>> 13) & 0x07),
1022 ((srcval
>> 3) & 0xfc) | /* g */
1023 ((srcval
>> 9) & 0x03),
1024 ((srcval
<< 3) & 0xf8) | /* b */
1025 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
1034 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1035 dstbits
+= linebytes
;
1037 } else if (bmpImage
->blue_mask
==0xf800) {
1038 /* ==== bgr 565 bmp -> pal 4 dib ==== */
1039 for (h
=0; h
<lines
; h
++) {
1044 for (x
=0; x
<width
; x
++) {
1047 dstval
|=(X11DRV_DIB_GetNearestIndex
1049 ((srcval
<< 3) & 0xf8) | /* r */
1050 ((srcval
>> 2) & 0x07),
1051 ((srcval
>> 3) & 0xfc) | /* g */
1052 ((srcval
>> 9) & 0x03),
1053 ((srcval
>> 8) & 0xf8) | /* b */
1054 ((srcval
>> 13) & 0x07) ) << ((1-(x
&1))<<2) );
1063 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1064 dstbits
+= linebytes
;
1076 if (bmpImage
->bits_per_pixel
==24) {
1077 const void* srcbits
;
1078 const BYTE
*srcbyte
;
1081 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1083 if (bmpImage
->green_mask
!=0x00ff00 ||
1084 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1086 } else if (bmpImage
->blue_mask
==0xff) {
1087 /* ==== rgb 888 bmp -> pal 4 dib ==== */
1088 for (h
=0; h
<lines
; h
++) {
1091 for (x
=0; x
<width
/2; x
++) {
1092 /* Do 2 pixels at a time */
1093 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1098 X11DRV_DIB_GetNearestIndex
1106 /* And then the odd pixel */
1107 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1113 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1114 dstbits
+= linebytes
;
1117 /* ==== bgr 888 bmp -> pal 4 dib ==== */
1118 for (h
=0; h
<lines
; h
++) {
1121 for (x
=0; x
<width
/2; x
++) {
1122 /* Do 2 pixels at a time */
1123 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1128 X11DRV_DIB_GetNearestIndex
1136 /* And then the odd pixel */
1137 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1143 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1144 dstbits
+= linebytes
;
1153 const void* srcbits
;
1154 const BYTE
*srcbyte
;
1157 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1159 if (bmpImage
->green_mask
!=0x00ff00 ||
1160 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1162 } else if (bmpImage
->blue_mask
==0xff) {
1163 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
1164 for (h
=0; h
<lines
; h
++) {
1167 for (x
=0; x
<width
/2; x
++) {
1168 /* Do 2 pixels at a time */
1169 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1174 X11DRV_DIB_GetNearestIndex
1182 /* And then the odd pixel */
1183 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1189 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1190 dstbits
+= linebytes
;
1193 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
1194 for (h
=0; h
<lines
; h
++) {
1197 for (x
=0; x
<width
/2; x
++) {
1198 /* Do 2 pixels at a time */
1199 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1204 X11DRV_DIB_GetNearestIndex
1212 /* And then the odd pixel */
1213 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1219 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1220 dstbits
+= linebytes
;
1231 /* ==== any bmp format -> pal 4 dib ==== */
1232 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
1233 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1234 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1235 for (h
=lines
-1; h
>=0; h
--) {
1237 for (x
=0; x
<(width
& ~1); x
+=2) {
1238 *dstbyte
++=(X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4) |
1239 X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
+1, h
), 0);
1242 *dstbyte
=(X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4);
1244 dstbits
+= linebytes
;
1251 /***********************************************************************
1252 * X11DRV_DIB_SetImageBits_8
1254 * SetDIBits for an 8-bit deep DIB.
1256 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
1257 DWORD srcwidth
, DWORD dstwidth
, int left
,
1258 const int *colors
, XImage
*bmpImage
,
1262 int h
, width
= min(srcwidth
, dstwidth
);
1263 const BYTE
* srcbyte
;
1269 srcbits
= srcbits
+ linebytes
* (lines
-1);
1270 linebytes
= -linebytes
;
1275 switch (bmpImage
->depth
) {
1278 /* Some X servers might have 32 bit/ 16bit deep pixel */
1279 if (lines
&& width
&& (bmpImage
->bits_per_pixel
== 16) &&
1280 (ImageByteOrder(gdi_display
)==LSBFirst
) )
1282 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
1283 dstbits
=(BYTE
*)bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
1284 for (h
= lines
; h
--; ) {
1285 DWORD
* dstpixel
=(DWORD
*)dstbits
;
1286 for (x
=0; x
<width
/2; x
++) {
1287 /* Do 2 pixels at a time */
1288 *dstpixel
++=(colors
[srcbyte
[1]] << 16) | colors
[srcbyte
[0]];
1292 /* And then the odd pixel */
1293 *((WORD
*)dstpixel
)=colors
[srcbyte
[0]];
1295 srcbyte
= (srcbits
+= linebytes
);
1296 dstbits
-= bmpImage
->bytes_per_line
;
1303 if (lines
&& width
&& (bmpImage
->bits_per_pixel
== 32) &&
1304 (ImageByteOrder(gdi_display
)==LSBFirst
) )
1306 dstbits
=(BYTE
*)bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
1307 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
1308 for (h
= lines
; h
--; ) {
1309 DWORD
* dstpixel
=(DWORD
*)dstbits
;
1310 for (x
=0; x
<width
; x
++) {
1311 *dstpixel
++=colors
[*srcbyte
++];
1313 srcbyte
= (srcbits
+= linebytes
);
1314 dstbits
-= bmpImage
->bytes_per_line
;
1320 break; /* use slow generic case below */
1323 /* ==== pal 8 dib -> any bmp format ==== */
1324 for (h
=lines
-1; h
>=0; h
--) {
1325 for (x
=left
; x
<width
+left
; x
++) {
1326 XPutPixel(bmpImage
, x
, h
, colors
[*srcbyte
++]);
1328 srcbyte
= (srcbits
+= linebytes
);
1332 /***********************************************************************
1333 * X11DRV_DIB_GetImageBits_8
1335 * GetDIBits for an 8-bit deep DIB.
1337 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
1338 DWORD srcwidth
, DWORD dstwidth
,
1339 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1340 XImage
*bmpImage
, int linebytes
)
1343 int h
, width
= min(srcwidth
, dstwidth
);
1349 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1350 linebytes
= -linebytes
;
1355 * This condition is true when GetImageBits has been called by
1356 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
1357 * 256 colormaps, so we'll just use it for GetDIBits calls.
1358 * (In some cases, in an updateDIBSection, the returned colors are bad too)
1360 if (!srccolors
) goto updatesection
;
1362 switch (bmpImage
->depth
) {
1365 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
1368 /* ==== pal 1 bmp -> pal 8 dib ==== */
1369 /* ==== pal 4 bmp -> pal 8 dib ==== */
1370 for (h
=lines
-1; h
>=0; h
--) {
1372 for (x
=0; x
<width
; x
++) {
1373 PALETTEENTRY srcval
;
1374 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
1375 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
1380 dstbits
+= linebytes
;
1388 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
1390 /* ==== pal 8 bmp -> pal 8 dib ==== */
1391 const void* srcbits
;
1392 const BYTE
* srcpixel
;
1394 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1395 for (h
=0; h
<lines
; h
++) {
1398 for (x
= 0; x
< width
; x
++) {
1399 PALETTEENTRY srcval
;
1400 srcval
=srccolors
[*srcpixel
++];
1401 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
1406 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1407 dstbits
+= linebytes
;
1417 const void* srcbits
;
1418 const WORD
* srcpixel
;
1421 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1423 if (bmpImage
->green_mask
==0x03e0) {
1424 if (bmpImage
->red_mask
==0x7c00) {
1425 /* ==== rgb 555 bmp -> pal 8 dib ==== */
1426 for (h
=0; h
<lines
; h
++) {
1429 for (x
=0; x
<width
; x
++) {
1432 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1434 ((srcval
>> 7) & 0xf8) | /* r */
1435 ((srcval
>> 12) & 0x07),
1436 ((srcval
>> 2) & 0xf8) | /* g */
1437 ((srcval
>> 7) & 0x07),
1438 ((srcval
<< 3) & 0xf8) | /* b */
1439 ((srcval
>> 2) & 0x07) );
1441 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1442 dstbits
+= linebytes
;
1444 } else if (bmpImage
->blue_mask
==0x7c00) {
1445 /* ==== bgr 555 bmp -> pal 8 dib ==== */
1446 for (h
=0; h
<lines
; h
++) {
1449 for (x
=0; x
<width
; x
++) {
1452 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1454 ((srcval
<< 3) & 0xf8) | /* r */
1455 ((srcval
>> 2) & 0x07),
1456 ((srcval
>> 2) & 0xf8) | /* g */
1457 ((srcval
>> 7) & 0x07),
1458 ((srcval
>> 7) & 0xf8) | /* b */
1459 ((srcval
>> 12) & 0x07) );
1461 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1462 dstbits
+= linebytes
;
1467 } else if (bmpImage
->green_mask
==0x07e0) {
1468 if (bmpImage
->red_mask
==0xf800) {
1469 /* ==== rgb 565 bmp -> pal 8 dib ==== */
1470 for (h
=0; h
<lines
; h
++) {
1473 for (x
=0; x
<width
; x
++) {
1476 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1478 ((srcval
>> 8) & 0xf8) | /* r */
1479 ((srcval
>> 13) & 0x07),
1480 ((srcval
>> 3) & 0xfc) | /* g */
1481 ((srcval
>> 9) & 0x03),
1482 ((srcval
<< 3) & 0xf8) | /* b */
1483 ((srcval
>> 2) & 0x07) );
1485 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1486 dstbits
+= linebytes
;
1488 } else if (bmpImage
->blue_mask
==0xf800) {
1489 /* ==== bgr 565 bmp -> pal 8 dib ==== */
1490 for (h
=0; h
<lines
; h
++) {
1493 for (x
=0; x
<width
; x
++) {
1496 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1498 ((srcval
<< 3) & 0xf8) | /* r */
1499 ((srcval
>> 2) & 0x07),
1500 ((srcval
>> 3) & 0xfc) | /* g */
1501 ((srcval
>> 9) & 0x03),
1502 ((srcval
>> 8) & 0xf8) | /* b */
1503 ((srcval
>> 13) & 0x07) );
1505 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1506 dstbits
+= linebytes
;
1520 const void* srcbits
;
1521 const BYTE
*srcbyte
;
1523 int bytes_per_pixel
;
1525 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1526 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
1528 if (bmpImage
->green_mask
!=0x00ff00 ||
1529 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1531 } else if (bmpImage
->blue_mask
==0xff) {
1532 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
1533 for (h
=0; h
<lines
; h
++) {
1536 for (x
=0; x
<width
; x
++) {
1537 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1542 srcbyte
+=bytes_per_pixel
;
1544 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1545 dstbits
+= linebytes
;
1548 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
1549 for (h
=0; h
<lines
; h
++) {
1552 for (x
=0; x
<width
; x
++) {
1553 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1558 srcbyte
+=bytes_per_pixel
;
1560 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1561 dstbits
+= linebytes
;
1569 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
1570 bmpImage
->depth
, bmpImage
->red_mask
,
1571 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1573 /* ==== any bmp format -> pal 8 dib ==== */
1574 for (h
=lines
-1; h
>=0; h
--) {
1576 for (x
=0; x
<width
; x
++) {
1577 *dstbyte
=X11DRV_DIB_MapColor
1579 XGetPixel(bmpImage
, x
, h
), *dstbyte
);
1582 dstbits
+= linebytes
;
1588 /***********************************************************************
1589 * X11DRV_DIB_SetImageBits_16
1591 * SetDIBits for a 16-bit deep DIB.
1593 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1594 DWORD srcwidth
, DWORD dstwidth
, int left
,
1595 X11DRV_PDEVICE
*physDev
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1596 XImage
*bmpImage
, int linebytes
)
1599 int h
, width
= min(srcwidth
, dstwidth
);
1600 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
1605 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1606 linebytes
= -linebytes
;
1609 switch (bmpImage
->depth
)
1616 srcbits
=srcbits
+left
*2;
1617 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
1619 if (bmpImage
->green_mask
==0x03e0) {
1620 if (gSrc
==bmpImage
->green_mask
) {
1621 if (rSrc
==bmpImage
->red_mask
) {
1622 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
1623 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
1624 convs
->Convert_5x5_asis
1627 dstbits
,-bmpImage
->bytes_per_line
);
1628 } else if (rSrc
==bmpImage
->blue_mask
) {
1629 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
1630 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
1631 convs
->Convert_555_reverse
1634 dstbits
,-bmpImage
->bytes_per_line
);
1637 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
1638 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
1639 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
1640 convs
->Convert_565_to_555_asis
1643 dstbits
,-bmpImage
->bytes_per_line
);
1645 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
1646 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
1647 convs
->Convert_565_to_555_reverse
1650 dstbits
,-bmpImage
->bytes_per_line
);
1653 } else if (bmpImage
->green_mask
==0x07e0) {
1654 if (gSrc
==bmpImage
->green_mask
) {
1655 if (rSrc
==bmpImage
->red_mask
) {
1656 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
1657 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
1658 convs
->Convert_5x5_asis
1661 dstbits
,-bmpImage
->bytes_per_line
);
1663 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
1664 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
1665 convs
->Convert_565_reverse
1668 dstbits
,-bmpImage
->bytes_per_line
);
1671 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
1672 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
1673 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
1674 convs
->Convert_555_to_565_asis
1677 dstbits
,-bmpImage
->bytes_per_line
);
1679 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
1680 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
1681 convs
->Convert_555_to_565_reverse
1684 dstbits
,-bmpImage
->bytes_per_line
);
1694 if (bmpImage
->bits_per_pixel
==24) {
1697 srcbits
=srcbits
+left
*2;
1698 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
1700 if (bmpImage
->green_mask
!=0x00ff00 ||
1701 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1703 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
1704 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
1706 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
1707 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
1708 convs
->Convert_555_to_888_asis
1711 dstbits
,-bmpImage
->bytes_per_line
);
1713 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
1714 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
1715 convs
->Convert_565_to_888_asis
1718 dstbits
,-bmpImage
->bytes_per_line
);
1722 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
1723 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
1724 convs
->Convert_555_to_888_reverse
1727 dstbits
,-bmpImage
->bytes_per_line
);
1729 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
1730 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
1731 convs
->Convert_565_to_888_reverse
1734 dstbits
,-bmpImage
->bytes_per_line
);
1745 srcbits
=srcbits
+left
*2;
1746 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
1748 if (bmpImage
->green_mask
!=0x00ff00 ||
1749 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1751 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
1752 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
1754 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
1755 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
1756 convs
->Convert_555_to_0888_asis
1759 dstbits
,-bmpImage
->bytes_per_line
);
1761 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
1762 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
1763 convs
->Convert_565_to_0888_asis
1766 dstbits
,-bmpImage
->bytes_per_line
);
1770 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
1771 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
1772 convs
->Convert_555_to_0888_reverse
1775 dstbits
,-bmpImage
->bytes_per_line
);
1777 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
1778 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
1779 convs
->Convert_565_to_0888_reverse
1782 dstbits
,-bmpImage
->bytes_per_line
);
1790 WARN("from 16 bit DIB (%x,%x,%x) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
1791 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1792 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1798 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
1799 const WORD
* srcpixel
;
1800 int rShift1
,gShift1
,bShift1
;
1801 int rShift2
,gShift2
,bShift2
;
1804 /* Set color scaling values */
1805 rShift1
=16+X11DRV_DIB_MaskToShift(rSrc
)-3;
1806 gShift1
=16+X11DRV_DIB_MaskToShift(gSrc
)-3;
1807 bShift1
=16+X11DRV_DIB_MaskToShift(bSrc
)-3;
1812 /* Green has 5 bits, like the others */
1816 /* Green has 6 bits, not 5. Compensate. */
1825 /* We could split it into four separate cases to optimize
1826 * but it is probably not worth it.
1828 for (h
=lines
-1; h
>=0; h
--) {
1829 srcpixel
=(const WORD
*)srcbits
;
1830 for (x
=left
; x
<width
+left
; x
++) {
1832 BYTE red
,green
,blue
;
1833 srcval
=*srcpixel
++ << 16;
1834 red
= ((srcval
>> rShift1
) & 0xf8) |
1835 ((srcval
>> rShift2
) & 0x07);
1836 green
=((srcval
>> gShift1
) & gMask1
) |
1837 ((srcval
>> gShift2
) & gMask2
);
1838 blue
= ((srcval
>> bShift1
) & 0xf8) |
1839 ((srcval
>> bShift2
) & 0x07);
1840 XPutPixel(bmpImage
, x
, h
,
1841 X11DRV_PALETTE_ToPhysical
1842 (physDev
, RGB(red
,green
,blue
)));
1844 srcbits
+= linebytes
;
1852 /***********************************************************************
1853 * X11DRV_DIB_GetImageBits_16
1855 * GetDIBits for an 16-bit deep DIB.
1857 static void X11DRV_DIB_GetImageBits_16( X11DRV_PDEVICE
*physDev
, int lines
, BYTE
*dstbits
,
1858 DWORD dstwidth
, DWORD srcwidth
,
1859 PALETTEENTRY
*srccolors
,
1860 DWORD rDst
, DWORD gDst
, DWORD bDst
,
1861 XImage
*bmpImage
, int linebytes
)
1864 int h
, width
= min(srcwidth
, dstwidth
);
1865 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
1870 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
1871 linebytes
= -linebytes
;
1874 switch (bmpImage
->depth
)
1879 const char* srcbits
;
1881 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1883 if (bmpImage
->green_mask
==0x03e0) {
1884 if (gDst
==bmpImage
->green_mask
) {
1885 if (rDst
==bmpImage
->red_mask
) {
1886 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
1887 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
1888 convs
->Convert_5x5_asis
1890 srcbits
,-bmpImage
->bytes_per_line
,
1893 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
1894 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
1895 convs
->Convert_555_reverse
1897 srcbits
,-bmpImage
->bytes_per_line
,
1901 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
1902 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
1903 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
1904 convs
->Convert_555_to_565_asis
1906 srcbits
,-bmpImage
->bytes_per_line
,
1909 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
1910 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
1911 convs
->Convert_555_to_565_reverse
1913 srcbits
,-bmpImage
->bytes_per_line
,
1917 } else if (bmpImage
->green_mask
==0x07e0) {
1918 if (gDst
==bmpImage
->green_mask
) {
1919 if (rDst
== bmpImage
->red_mask
) {
1920 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
1921 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
1922 convs
->Convert_5x5_asis
1924 srcbits
,-bmpImage
->bytes_per_line
,
1927 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
1928 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
1929 convs
->Convert_565_reverse
1931 srcbits
,-bmpImage
->bytes_per_line
,
1935 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
1936 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
1937 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
1938 convs
->Convert_565_to_555_asis
1940 srcbits
,-bmpImage
->bytes_per_line
,
1943 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
1944 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
1945 convs
->Convert_565_to_555_reverse
1947 srcbits
,-bmpImage
->bytes_per_line
,
1958 if (bmpImage
->bits_per_pixel
== 24) {
1959 const char* srcbits
;
1961 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1963 if (bmpImage
->green_mask
!=0x00ff00 ||
1964 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1966 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
1967 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
1969 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
1970 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
1971 convs
->Convert_888_to_555_asis
1973 srcbits
,-bmpImage
->bytes_per_line
,
1976 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
1977 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
1978 convs
->Convert_888_to_565_asis
1980 srcbits
,-bmpImage
->bytes_per_line
,
1985 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
1986 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
1987 convs
->Convert_888_to_555_reverse
1989 srcbits
,-bmpImage
->bytes_per_line
,
1992 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
1993 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
1994 convs
->Convert_888_to_565_reverse
1996 srcbits
,-bmpImage
->bytes_per_line
,
2006 const char* srcbits
;
2008 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2010 if (bmpImage
->green_mask
!=0x00ff00 ||
2011 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2013 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
2014 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
2016 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
2017 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
2018 convs
->Convert_0888_to_555_asis
2020 srcbits
,-bmpImage
->bytes_per_line
,
2023 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
2024 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
2025 convs
->Convert_0888_to_565_asis
2027 srcbits
,-bmpImage
->bytes_per_line
,
2032 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
2033 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
2034 convs
->Convert_0888_to_555_reverse
2036 srcbits
,-bmpImage
->bytes_per_line
,
2039 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
2040 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
2041 convs
->Convert_0888_to_565_reverse
2043 srcbits
,-bmpImage
->bytes_per_line
,
2052 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
2054 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
2055 int rShift
,gShift
,bShift
;
2058 /* Shift everything 16 bits left so that all shifts are >0,
2059 * even for BGR DIBs. Then a single >> 16 will bring everything
2062 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2063 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2064 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2066 /* 6 bits for the green */
2072 for (h
= lines
- 1; h
>= 0; h
--) {
2073 dstpixel
=(LPWORD
)dstbits
;
2074 for (x
= 0; x
< width
; x
++) {
2075 PALETTEENTRY srcval
;
2077 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2078 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
2079 ((srcval
.peGreen
<< gShift
) & gDst
) |
2080 ((srcval
.peBlue
<< bShift
) & bDst
);
2081 *dstpixel
++=dstval
>> 16;
2083 dstbits
+= linebytes
;
2091 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
2093 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
2094 int rShift
,gShift
,bShift
;
2095 const BYTE
* srcbits
;
2096 const BYTE
* srcpixel
;
2099 /* Shift everything 16 bits left so that all shifts are >0,
2100 * even for BGR DIBs. Then a single >> 16 will bring everything
2103 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2104 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2105 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2107 /* 6 bits for the green */
2113 srcbits
=(BYTE
*)bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2114 for (h
=0; h
<lines
; h
++) {
2116 dstpixel
=(LPWORD
)dstbits
;
2117 for (x
= 0; x
< width
; x
++) {
2118 PALETTEENTRY srcval
;
2120 srcval
=srccolors
[*srcpixel
++];
2121 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
2122 ((srcval
.peGreen
<< gShift
) & gDst
) |
2123 ((srcval
.peBlue
<< bShift
) & bDst
);
2124 *dstpixel
++=dstval
>> 16;
2126 srcbits
-= bmpImage
->bytes_per_line
;
2127 dstbits
+= linebytes
;
2137 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
2138 int rShift
,gShift
,bShift
;
2141 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%x,%x,%x)\n",
2142 bmpImage
->depth
, bmpImage
->red_mask
,
2143 bmpImage
->green_mask
, bmpImage
->blue_mask
,
2146 /* Shift everything 16 bits left so that all shifts are >0,
2147 * even for BGR DIBs. Then a single >> 16 will bring everything
2150 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2151 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2152 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2154 /* 6 bits for the green */
2160 for (h
= lines
- 1; h
>= 0; h
--) {
2161 dstpixel
=(LPWORD
)dstbits
;
2162 for (x
= 0; x
< width
; x
++) {
2165 srcval
=X11DRV_PALETTE_ToLogical(physDev
, XGetPixel(bmpImage
, x
, h
));
2166 dstval
=((GetRValue(srcval
) << rShift
) & rDst
) |
2167 ((GetGValue(srcval
) << gShift
) & gDst
) |
2168 ((GetBValue(srcval
) << bShift
) & bDst
);
2169 *dstpixel
++=dstval
>> 16;
2171 dstbits
+= linebytes
;
2179 /***********************************************************************
2180 * X11DRV_DIB_SetImageBits_24
2182 * SetDIBits for a 24-bit deep DIB.
2184 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
2185 DWORD srcwidth
, DWORD dstwidth
, int left
,
2186 X11DRV_PDEVICE
*physDev
,
2187 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2188 XImage
*bmpImage
, DWORD linebytes
)
2191 int h
, width
= min(srcwidth
, dstwidth
);
2192 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
2197 srcbits
= srcbits
+ linebytes
* (lines
- 1);
2198 linebytes
= -linebytes
;
2201 switch (bmpImage
->depth
)
2204 if (bmpImage
->bits_per_pixel
==24) {
2207 srcbits
=srcbits
+left
*3;
2208 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
2210 if (bmpImage
->green_mask
!=0x00ff00 ||
2211 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2213 } else if (rSrc
==bmpImage
->red_mask
) {
2214 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
2215 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
2216 convs
->Convert_888_asis
2219 dstbits
,-bmpImage
->bytes_per_line
);
2221 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
2222 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
2223 convs
->Convert_888_reverse
2226 dstbits
,-bmpImage
->bytes_per_line
);
2236 srcbits
=srcbits
+left
*3;
2237 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2239 if (bmpImage
->green_mask
!=0x00ff00 ||
2240 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2242 } else if (rSrc
==bmpImage
->red_mask
) {
2243 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
2244 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
2245 convs
->Convert_888_to_0888_asis
2248 dstbits
,-bmpImage
->bytes_per_line
);
2250 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
2251 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
2252 convs
->Convert_888_to_0888_reverse
2255 dstbits
,-bmpImage
->bytes_per_line
);
2265 srcbits
=srcbits
+left
*3;
2266 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2268 if (bmpImage
->green_mask
==0x03e0) {
2269 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
2270 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
2271 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
2272 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
2273 convs
->Convert_888_to_555_asis
2276 dstbits
,-bmpImage
->bytes_per_line
);
2277 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0x7f00) ||
2278 (bSrc
==0xff && bmpImage
->blue_mask
==0x7f00)) {
2279 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
2280 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
2281 convs
->Convert_888_to_555_reverse
2284 dstbits
,-bmpImage
->bytes_per_line
);
2288 } else if (bmpImage
->green_mask
==0x07e0) {
2289 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
2290 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
2291 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
2292 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
2293 convs
->Convert_888_to_565_asis
2296 dstbits
,-bmpImage
->bytes_per_line
);
2297 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0xf800) ||
2298 (bSrc
==0xff && bmpImage
->blue_mask
==0xf800)) {
2299 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
2300 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
2301 convs
->Convert_888_to_565_reverse
2304 dstbits
,-bmpImage
->bytes_per_line
);
2316 WARN("from 24 bit DIB (%x,%x,%x) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2317 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2318 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2324 /* ==== rgb 888 dib -> any bmp format ==== */
2325 const BYTE
* srcbyte
;
2327 /* Windows only supports one 24bpp DIB format: RGB888 */
2329 for (h
= lines
- 1; h
>= 0; h
--) {
2331 for (x
= left
; x
< width
+left
; x
++) {
2332 XPutPixel(bmpImage
, x
, h
,
2333 X11DRV_PALETTE_ToPhysical
2334 (physDev
, RGB(srcbyte
[2], srcbyte
[1], srcbyte
[0])));
2337 srcbits
+= linebytes
;
2345 /***********************************************************************
2346 * X11DRV_DIB_GetImageBits_24
2348 * GetDIBits for an 24-bit deep DIB.
2350 static void X11DRV_DIB_GetImageBits_24( X11DRV_PDEVICE
*physDev
, int lines
, BYTE
*dstbits
,
2351 DWORD dstwidth
, DWORD srcwidth
,
2352 PALETTEENTRY
*srccolors
,
2353 DWORD rDst
, DWORD gDst
, DWORD bDst
,
2354 XImage
*bmpImage
, DWORD linebytes
)
2357 int h
, width
= min(srcwidth
, dstwidth
);
2358 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
2363 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2364 linebytes
= -linebytes
;
2367 switch (bmpImage
->depth
)
2370 if (bmpImage
->bits_per_pixel
==24) {
2371 const char* srcbits
;
2373 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2375 if (bmpImage
->green_mask
!=0x00ff00 ||
2376 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2378 } else if (rDst
==bmpImage
->red_mask
) {
2379 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
2380 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
2381 convs
->Convert_888_asis
2383 srcbits
,-bmpImage
->bytes_per_line
,
2386 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
2387 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
2388 convs
->Convert_888_reverse
2390 srcbits
,-bmpImage
->bytes_per_line
,
2399 const char* srcbits
;
2401 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2403 if (bmpImage
->green_mask
!=0x00ff00 ||
2404 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2406 } else if (rDst
==bmpImage
->red_mask
) {
2407 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2408 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2409 convs
->Convert_0888_to_888_asis
2411 srcbits
,-bmpImage
->bytes_per_line
,
2414 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
2415 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
2416 convs
->Convert_0888_to_888_reverse
2418 srcbits
,-bmpImage
->bytes_per_line
,
2427 const char* srcbits
;
2429 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2431 if (bmpImage
->green_mask
==0x03e0) {
2432 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
2433 (bDst
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
2434 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
2435 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
2436 convs
->Convert_555_to_888_asis
2438 srcbits
,-bmpImage
->bytes_per_line
,
2440 } else if ((rDst
==0xff && bmpImage
->red_mask
==0x7f00) ||
2441 (bDst
==0xff && bmpImage
->blue_mask
==0x7f00)) {
2442 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
2443 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
2444 convs
->Convert_555_to_888_reverse
2446 srcbits
,-bmpImage
->bytes_per_line
,
2451 } else if (bmpImage
->green_mask
==0x07e0) {
2452 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
2453 (bDst
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
2454 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
2455 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
2456 convs
->Convert_565_to_888_asis
2458 srcbits
,-bmpImage
->bytes_per_line
,
2460 } else if ((rDst
==0xff && bmpImage
->red_mask
==0xf800) ||
2461 (bDst
==0xff && bmpImage
->blue_mask
==0xf800)) {
2462 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
2463 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
2464 convs
->Convert_565_to_888_reverse
2466 srcbits
,-bmpImage
->bytes_per_line
,
2479 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
2481 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
2484 /* Windows only supports one 24bpp DIB format: rgb 888 */
2485 for (h
= lines
- 1; h
>= 0; h
--) {
2487 for (x
= 0; x
< width
; x
++) {
2488 PALETTEENTRY srcval
;
2489 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2490 dstbyte
[0]=srcval
.peBlue
;
2491 dstbyte
[1]=srcval
.peGreen
;
2492 dstbyte
[2]=srcval
.peRed
;
2495 dstbits
+= linebytes
;
2503 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
2505 /* ==== pal 8 bmp -> rgb 888 dib ==== */
2506 const void* srcbits
;
2507 const BYTE
* srcpixel
;
2510 /* Windows only supports one 24bpp DIB format: rgb 888 */
2511 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2512 for (h
= lines
- 1; h
>= 0; h
--) {
2515 for (x
= 0; x
< width
; x
++ ) {
2516 PALETTEENTRY srcval
;
2517 srcval
=srccolors
[*srcpixel
++];
2518 dstbyte
[0]=srcval
.peBlue
;
2519 dstbyte
[1]=srcval
.peGreen
;
2520 dstbyte
[2]=srcval
.peRed
;
2523 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
2524 dstbits
+= linebytes
;
2534 /* ==== any bmp format -> 888 dib ==== */
2537 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%x,%x,%x)\n",
2538 bmpImage
->depth
, bmpImage
->red_mask
,
2539 bmpImage
->green_mask
, bmpImage
->blue_mask
,
2542 /* Windows only supports one 24bpp DIB format: rgb 888 */
2543 for (h
= lines
- 1; h
>= 0; h
--) {
2545 for (x
= 0; x
< width
; x
++) {
2546 COLORREF srcval
=X11DRV_PALETTE_ToLogical
2547 (physDev
, XGetPixel( bmpImage
, x
, h
));
2548 dstbyte
[0]=GetBValue(srcval
);
2549 dstbyte
[1]=GetGValue(srcval
);
2550 dstbyte
[2]=GetRValue(srcval
);
2553 dstbits
+= linebytes
;
2561 /***********************************************************************
2562 * X11DRV_DIB_SetImageBits_32
2564 * SetDIBits for a 32-bit deep DIB.
2566 static void X11DRV_DIB_SetImageBits_32(int lines
, const BYTE
*srcbits
,
2567 DWORD srcwidth
, DWORD dstwidth
, int left
,
2568 X11DRV_PDEVICE
*physDev
,
2569 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2574 int h
, width
= min(srcwidth
, dstwidth
);
2575 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
2580 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2581 linebytes
= -linebytes
;
2584 switch (bmpImage
->depth
)
2587 if (bmpImage
->bits_per_pixel
==24) {
2590 srcbits
=srcbits
+left
*4;
2591 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
2593 if (rSrc
==bmpImage
->red_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->blue_mask
) {
2594 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
2595 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
2596 convs
->Convert_0888_to_888_asis
2599 dstbits
,-bmpImage
->bytes_per_line
);
2600 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2601 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2603 /* the tests below assume sane bmpImage masks */
2604 } else if (rSrc
==bmpImage
->blue_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->red_mask
) {
2605 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
2606 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
2607 convs
->Convert_0888_to_888_reverse
2610 dstbits
,-bmpImage
->bytes_per_line
);
2611 } else if (bmpImage
->blue_mask
==0xff) {
2612 /* ==== any 0888 dib -> rgb 888 bmp ==== */
2613 convs
->Convert_any0888_to_rgb888
2617 dstbits
,-bmpImage
->bytes_per_line
);
2619 /* ==== any 0888 dib -> bgr 888 bmp ==== */
2620 convs
->Convert_any0888_to_bgr888
2624 dstbits
,-bmpImage
->bytes_per_line
);
2634 srcbits
=srcbits
+left
*4;
2635 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2637 if (gSrc
==bmpImage
->green_mask
) {
2638 if (rSrc
==bmpImage
->red_mask
&& bSrc
==bmpImage
->blue_mask
) {
2639 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
2640 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
2641 convs
->Convert_0888_asis
2644 dstbits
,-bmpImage
->bytes_per_line
);
2645 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2646 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2648 /* the tests below assume sane bmpImage masks */
2649 } else if (rSrc
==bmpImage
->blue_mask
&& bSrc
==bmpImage
->red_mask
) {
2650 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
2651 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
2652 convs
->Convert_0888_reverse
2655 dstbits
,-bmpImage
->bytes_per_line
);
2657 /* ==== any 0888 dib -> any 0888 bmp ==== */
2658 convs
->Convert_0888_any
2662 dstbits
,-bmpImage
->bytes_per_line
,
2663 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2665 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2666 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2668 /* the tests below assume sane bmpImage masks */
2670 /* ==== any 0888 dib -> any 0888 bmp ==== */
2671 convs
->Convert_0888_any
2675 dstbits
,-bmpImage
->bytes_per_line
,
2676 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2686 srcbits
=srcbits
+left
*4;
2687 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2689 if (rSrc
==0xff0000 && gSrc
==0x00ff00 && bSrc
==0x0000ff) {
2690 if (bmpImage
->green_mask
==0x03e0) {
2691 if (bmpImage
->red_mask
==0x7f00) {
2692 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
2693 convs
->Convert_0888_to_555_asis
2696 dstbits
,-bmpImage
->bytes_per_line
);
2697 } else if (bmpImage
->blue_mask
==0x7f00) {
2698 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
2699 convs
->Convert_0888_to_555_reverse
2702 dstbits
,-bmpImage
->bytes_per_line
);
2706 } else if (bmpImage
->green_mask
==0x07e0) {
2707 if (bmpImage
->red_mask
==0xf800) {
2708 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
2709 convs
->Convert_0888_to_565_asis
2712 dstbits
,-bmpImage
->bytes_per_line
);
2713 } else if (bmpImage
->blue_mask
==0xf800) {
2714 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
2715 convs
->Convert_0888_to_565_reverse
2718 dstbits
,-bmpImage
->bytes_per_line
);
2725 } else if (rSrc
==0x0000ff && gSrc
==0x00ff00 && bSrc
==0xff0000) {
2726 if (bmpImage
->green_mask
==0x03e0) {
2727 if (bmpImage
->blue_mask
==0x7f00) {
2728 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
2729 convs
->Convert_0888_to_555_asis
2732 dstbits
,-bmpImage
->bytes_per_line
);
2733 } else if (bmpImage
->red_mask
==0x7f00) {
2734 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
2735 convs
->Convert_0888_to_555_reverse
2738 dstbits
,-bmpImage
->bytes_per_line
);
2742 } else if (bmpImage
->green_mask
==0x07e0) {
2743 if (bmpImage
->blue_mask
==0xf800) {
2744 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
2745 convs
->Convert_0888_to_565_asis
2748 dstbits
,-bmpImage
->bytes_per_line
);
2749 } else if (bmpImage
->red_mask
==0xf800) {
2750 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
2751 convs
->Convert_0888_to_565_reverse
2754 dstbits
,-bmpImage
->bytes_per_line
);
2762 if (bmpImage
->green_mask
==0x03e0 &&
2763 (bmpImage
->red_mask
==0x7f00 ||
2764 bmpImage
->blue_mask
==0x7f00)) {
2765 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
2766 convs
->Convert_any0888_to_5x5
2770 dstbits
,-bmpImage
->bytes_per_line
,
2771 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2772 } else if (bmpImage
->green_mask
==0x07e0 &&
2773 (bmpImage
->red_mask
==0xf800 ||
2774 bmpImage
->blue_mask
==0xf800)) {
2775 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
2776 convs
->Convert_any0888_to_5x5
2780 dstbits
,-bmpImage
->bytes_per_line
,
2781 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2791 WARN("from 32 bit DIB (%x,%x,%x) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2792 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2793 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2799 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
2800 const DWORD
* srcpixel
;
2801 int rShift
,gShift
,bShift
;
2803 rShift
=X11DRV_DIB_MaskToShift(rSrc
);
2804 gShift
=X11DRV_DIB_MaskToShift(gSrc
);
2805 bShift
=X11DRV_DIB_MaskToShift(bSrc
);
2807 for (h
= lines
- 1; h
>= 0; h
--) {
2808 srcpixel
=(const DWORD
*)srcbits
;
2809 for (x
= left
; x
< width
+left
; x
++) {
2811 BYTE red
,green
,blue
;
2812 srcvalue
=*srcpixel
++;
2813 red
= (srcvalue
>> rShift
) & 0xff;
2814 green
=(srcvalue
>> gShift
) & 0xff;
2815 blue
= (srcvalue
>> bShift
) & 0xff;
2816 XPutPixel(bmpImage
, x
, h
, X11DRV_PALETTE_ToPhysical
2817 (physDev
, RGB(red
,green
,blue
)));
2819 srcbits
+= linebytes
;
2827 /***********************************************************************
2828 * X11DRV_DIB_GetImageBits_32
2830 * GetDIBits for an 32-bit deep DIB.
2832 static void X11DRV_DIB_GetImageBits_32( X11DRV_PDEVICE
*physDev
, int lines
, BYTE
*dstbits
,
2833 DWORD dstwidth
, DWORD srcwidth
,
2834 PALETTEENTRY
*srccolors
,
2835 DWORD rDst
, DWORD gDst
, DWORD bDst
,
2836 XImage
*bmpImage
, int linebytes
)
2839 int h
, width
= min(srcwidth
, dstwidth
);
2840 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
2845 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2846 linebytes
= -linebytes
;
2849 switch (bmpImage
->depth
)
2852 if (bmpImage
->bits_per_pixel
==24) {
2853 const void* srcbits
;
2855 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2857 if (rDst
==bmpImage
->red_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->blue_mask
) {
2858 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2859 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2860 convs
->Convert_888_to_0888_asis
2862 srcbits
,-bmpImage
->bytes_per_line
,
2864 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2865 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2867 /* the tests below assume sane bmpImage masks */
2868 } else if (rDst
==bmpImage
->blue_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->red_mask
) {
2869 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
2870 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
2871 convs
->Convert_888_to_0888_reverse
2873 srcbits
,-bmpImage
->bytes_per_line
,
2875 } else if (bmpImage
->blue_mask
==0xff) {
2876 /* ==== rgb 888 bmp -> any 0888 dib ==== */
2877 convs
->Convert_rgb888_to_any0888
2879 srcbits
,-bmpImage
->bytes_per_line
,
2883 /* ==== bgr 888 bmp -> any 0888 dib ==== */
2884 convs
->Convert_bgr888_to_any0888
2886 srcbits
,-bmpImage
->bytes_per_line
,
2896 const char* srcbits
;
2898 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2900 if (gDst
==bmpImage
->green_mask
) {
2901 if (rDst
==bmpImage
->red_mask
&& bDst
==bmpImage
->blue_mask
) {
2902 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
2903 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
2904 convs
->Convert_0888_asis
2906 srcbits
,-bmpImage
->bytes_per_line
,
2908 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2909 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2911 /* the tests below assume sane bmpImage masks */
2912 } else if (rDst
==bmpImage
->blue_mask
&& bDst
==bmpImage
->red_mask
) {
2913 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
2914 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
2915 convs
->Convert_0888_reverse
2917 srcbits
,-bmpImage
->bytes_per_line
,
2920 /* ==== any 0888 bmp -> any 0888 dib ==== */
2921 convs
->Convert_0888_any
2923 srcbits
,-bmpImage
->bytes_per_line
,
2924 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
2928 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2929 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2931 /* the tests below assume sane bmpImage masks */
2933 /* ==== any 0888 bmp -> any 0888 dib ==== */
2934 convs
->Convert_0888_any
2936 srcbits
,-bmpImage
->bytes_per_line
,
2937 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
2947 const char* srcbits
;
2949 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2951 if (rDst
==0xff0000 && gDst
==0x00ff00 && bDst
==0x0000ff) {
2952 if (bmpImage
->green_mask
==0x03e0) {
2953 if (bmpImage
->red_mask
==0x7f00) {
2954 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
2955 convs
->Convert_555_to_0888_asis
2957 srcbits
,-bmpImage
->bytes_per_line
,
2959 } else if (bmpImage
->blue_mask
==0x7f00) {
2960 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
2961 convs
->Convert_555_to_0888_reverse
2963 srcbits
,-bmpImage
->bytes_per_line
,
2968 } else if (bmpImage
->green_mask
==0x07e0) {
2969 if (bmpImage
->red_mask
==0xf800) {
2970 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
2971 convs
->Convert_565_to_0888_asis
2973 srcbits
,-bmpImage
->bytes_per_line
,
2975 } else if (bmpImage
->blue_mask
==0xf800) {
2976 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
2977 convs
->Convert_565_to_0888_reverse
2979 srcbits
,-bmpImage
->bytes_per_line
,
2987 } else if (rDst
==0x0000ff && gDst
==0x00ff00 && bDst
==0xff0000) {
2988 if (bmpImage
->green_mask
==0x03e0) {
2989 if (bmpImage
->blue_mask
==0x7f00) {
2990 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
2991 convs
->Convert_555_to_0888_asis
2993 srcbits
,-bmpImage
->bytes_per_line
,
2995 } else if (bmpImage
->red_mask
==0x7f00) {
2996 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
2997 convs
->Convert_555_to_0888_reverse
2999 srcbits
,-bmpImage
->bytes_per_line
,
3004 } else if (bmpImage
->green_mask
==0x07e0) {
3005 if (bmpImage
->blue_mask
==0xf800) {
3006 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
3007 convs
->Convert_565_to_0888_asis
3009 srcbits
,-bmpImage
->bytes_per_line
,
3011 } else if (bmpImage
->red_mask
==0xf800) {
3012 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
3013 convs
->Convert_565_to_0888_reverse
3015 srcbits
,-bmpImage
->bytes_per_line
,
3024 if (bmpImage
->green_mask
==0x03e0 &&
3025 (bmpImage
->red_mask
==0x7f00 ||
3026 bmpImage
->blue_mask
==0x7f00)) {
3027 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
3028 convs
->Convert_5x5_to_any0888
3030 srcbits
,-bmpImage
->bytes_per_line
,
3031 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3034 } else if (bmpImage
->green_mask
==0x07e0 &&
3035 (bmpImage
->red_mask
==0xf800 ||
3036 bmpImage
->blue_mask
==0xf800)) {
3037 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
3038 convs
->Convert_5x5_to_any0888
3040 srcbits
,-bmpImage
->bytes_per_line
,
3041 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3053 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
3055 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
3056 int rShift
,gShift
,bShift
;
3059 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3060 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3061 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3062 for (h
= lines
- 1; h
>= 0; h
--) {
3063 dstpixel
=(DWORD
*)dstbits
;
3064 for (x
= 0; x
< width
; x
++) {
3065 PALETTEENTRY srcval
;
3066 srcval
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
3067 *dstpixel
++=(srcval
.peRed
<< rShift
) |
3068 (srcval
.peGreen
<< gShift
) |
3069 (srcval
.peBlue
<< bShift
);
3071 dstbits
+= linebytes
;
3079 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
3081 /* ==== pal 8 bmp -> any 0888 dib ==== */
3082 int rShift
,gShift
,bShift
;
3083 const void* srcbits
;
3084 const BYTE
* srcpixel
;
3087 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3088 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3089 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3090 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3091 for (h
= lines
- 1; h
>= 0; h
--) {
3093 dstpixel
=(DWORD
*)dstbits
;
3094 for (x
= 0; x
< width
; x
++) {
3095 PALETTEENTRY srcval
;
3096 srcval
=srccolors
[*srcpixel
++];
3097 *dstpixel
++=(srcval
.peRed
<< rShift
) |
3098 (srcval
.peGreen
<< gShift
) |
3099 (srcval
.peBlue
<< bShift
);
3101 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
3102 dstbits
+= linebytes
;
3112 /* ==== any bmp format -> any 0888 dib ==== */
3113 int rShift
,gShift
,bShift
;
3116 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%x,%x,%x)\n",
3117 bmpImage
->depth
, bmpImage
->red_mask
,
3118 bmpImage
->green_mask
, bmpImage
->blue_mask
,
3121 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3122 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3123 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3124 for (h
= lines
- 1; h
>= 0; h
--) {
3125 dstpixel
=(DWORD
*)dstbits
;
3126 for (x
= 0; x
< width
; x
++) {
3128 srcval
=X11DRV_PALETTE_ToLogical(physDev
, XGetPixel(bmpImage
, x
, h
));
3129 *dstpixel
++=(GetRValue(srcval
) << rShift
) |
3130 (GetGValue(srcval
) << gShift
) |
3131 (GetBValue(srcval
) << bShift
);
3133 dstbits
+= linebytes
;
3140 /***********************************************************************
3141 * X11DRV_DIB_SetImageBits
3143 * Transfer the bits to an X image.
3144 * Helper function for SetDIBits() and SetDIBitsToDevice().
3146 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
3148 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
3149 void *old_data
= NULL
;
3154 bmpImage
= descr
->image
;
3156 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
3157 descr
->infoWidth
, lines
, 32, 0 );
3158 bmpImage
->data
= HeapAlloc( GetProcessHeap(), 0, lines
* bmpImage
->bytes_per_line
);
3159 if(bmpImage
->data
== NULL
) {
3160 ERR("Out of memory!\n");
3161 XDestroyImage( bmpImage
);
3162 wine_tsx11_unlock();
3167 bmpImage
->red_mask
= descr
->shifts
->physicalRed
.max
<< descr
->shifts
->physicalRed
.shift
;
3168 bmpImage
->green_mask
= descr
->shifts
->physicalGreen
.max
<< descr
->shifts
->physicalGreen
.shift
;
3169 bmpImage
->blue_mask
= descr
->shifts
->physicalBlue
.max
<< descr
->shifts
->physicalBlue
.shift
;
3172 wine_tsx11_unlock();
3174 TRACE("Dib: depth=%d r=%x g=%x b=%x\n",
3175 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
3176 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
3177 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
3178 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3180 #ifdef HAVE_LIBXXSHM
3181 if (descr
->shm_mode
== X11DRV_SHM_PIXMAP
3182 && descr
->xSrc
== 0 && descr
->ySrc
== 0
3183 && descr
->xDest
== 0 && descr
->yDest
== 0)
3185 TRACE("Using the shared pixmap data.\n");
3188 XSync( gdi_display
, False
);
3189 wine_tsx11_unlock();
3191 old_data
= descr
->image
->data
;
3192 descr
->image
->data
= descr
->physBitmap
->shminfo
.shmaddr
;
3196 /* Transfer the pixels */
3199 switch(descr
->infoBpp
)
3202 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
3203 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
3204 bmpImage
, descr
->dibpitch
);
3207 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
3208 descr
->infoWidth
, descr
->width
,
3209 descr
->xSrc
, (int*)(descr
->colorMap
),
3210 bmpImage
, descr
->dibpitch
);
3213 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
3214 descr
->infoWidth
, descr
->width
,
3215 descr
->xSrc
, (int *)(descr
->colorMap
),
3216 bmpImage
, descr
->dibpitch
);
3219 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
3220 descr
->infoWidth
, descr
->width
,
3221 descr
->xSrc
, descr
->physDev
,
3222 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3223 bmpImage
, descr
->dibpitch
);
3226 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
3227 descr
->infoWidth
, descr
->width
,
3228 descr
->xSrc
, descr
->physDev
,
3229 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3230 bmpImage
, descr
->dibpitch
);
3233 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
3234 descr
->infoWidth
, descr
->width
,
3235 descr
->xSrc
, descr
->physDev
,
3236 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3237 bmpImage
, descr
->dibpitch
);
3240 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
3246 WARN( "invalid bits pointer %p\n", descr
->bits
);
3251 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
3252 descr
->drawable
, descr
->gc
, bmpImage
,
3253 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3254 descr
->width
, descr
->height
);
3259 #ifdef HAVE_LIBXXSHM
3260 if (descr
->shm_mode
== X11DRV_SHM_PIXMAP
3261 && descr
->xSrc
== 0 && descr
->ySrc
== 0
3262 && descr
->xDest
== 0 && descr
->yDest
== 0)
3264 XSync( gdi_display
, False
);
3266 else if (descr
->shm_mode
== X11DRV_SHM_IMAGE
&& descr
->image
)
3268 XShmPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
3269 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3270 descr
->width
, descr
->height
, FALSE
);
3271 XSync( gdi_display
, 0 );
3276 XPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
3277 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3278 descr
->width
, descr
->height
);
3282 if (old_data
) descr
->image
->data
= old_data
;
3284 if (!descr
->image
) X11DRV_DIB_DestroyXImage( bmpImage
);
3285 wine_tsx11_unlock();
3289 /***********************************************************************
3290 * X11DRV_DIB_GetImageBits
3292 * Transfer the bits from an X image.
3294 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
3296 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
3297 void *old_data
= NULL
;
3302 bmpImage
= descr
->image
;
3304 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
3305 descr
->infoWidth
, lines
, 32, 0 );
3306 bmpImage
->data
= HeapAlloc( GetProcessHeap(), 0, lines
* bmpImage
->bytes_per_line
);
3307 if(bmpImage
->data
== NULL
) {
3308 ERR("Out of memory!\n");
3309 XDestroyImage( bmpImage
);
3310 wine_tsx11_unlock();
3315 bmpImage
->red_mask
= descr
->shifts
->physicalRed
.max
<< descr
->shifts
->physicalRed
.shift
;
3316 bmpImage
->green_mask
= descr
->shifts
->physicalGreen
.max
<< descr
->shifts
->physicalGreen
.shift
;
3317 bmpImage
->blue_mask
= descr
->shifts
->physicalBlue
.max
<< descr
->shifts
->physicalBlue
.shift
;
3321 #ifdef HAVE_LIBXXSHM
3323 /* We must not call XShmGetImage() with a bitmap which is bigger than the available area.
3324 If we do, XShmGetImage() will fail (X exception), as it checks for this internally. */
3325 if (descr
->shm_mode
== X11DRV_SHM_PIXMAP
&& descr
->image
3326 && descr
->xSrc
== 0 && descr
->ySrc
== 0
3327 && descr
->xDest
== 0 && descr
->yDest
== 0
3328 && bmpImage
->width
<= (descr
->width
- descr
->xSrc
)
3329 && bmpImage
->height
<= (descr
->height
- descr
->ySrc
))
3331 XSync( gdi_display
, False
);
3332 old_data
= bmpImage
->data
;
3333 bmpImage
->data
= descr
->physBitmap
->shminfo
.shmaddr
;
3334 TRACE("Using shared pixmap data.\n");
3336 else if (descr
->shm_mode
== X11DRV_SHM_IMAGE
&& descr
->image
3337 && bmpImage
->width
<= (descr
->width
- descr
->xSrc
)
3338 && bmpImage
->height
<= (descr
->height
- descr
->ySrc
))
3340 int saveRed
, saveGreen
, saveBlue
;
3342 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
3343 gdi_display
, descr
->drawable
, bmpImage
,
3344 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
3346 /* We must save and restore the bmpImage's masks in order
3347 * to preserve them across the call to XShmGetImage, which
3348 * decides to eliminate them since it doesn't happen to know
3349 * what the format of the image is supposed to be, even though
3351 saveRed
= bmpImage
->red_mask
;
3352 saveBlue
= bmpImage
->blue_mask
;
3353 saveGreen
= bmpImage
->green_mask
;
3355 XShmGetImage( gdi_display
, descr
->drawable
, bmpImage
,
3356 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
3358 bmpImage
->red_mask
= saveRed
;
3359 bmpImage
->blue_mask
= saveBlue
;
3360 bmpImage
->green_mask
= saveGreen
;
3363 #endif /* HAVE_LIBXXSHM */
3365 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
3366 gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
, descr
->width
,
3367 lines
, AllPlanes
, ZPixmap
, bmpImage
, descr
->xDest
, descr
->yDest
);
3368 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
3369 descr
->width
, lines
, AllPlanes
, ZPixmap
,
3370 bmpImage
, descr
->xDest
, descr
->yDest
);
3372 wine_tsx11_unlock();
3374 TRACE("Dib: depth=%2d r=%x g=%x b=%x\n",
3375 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
3376 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
3377 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
3378 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3379 /* Transfer the pixels */
3380 switch(descr
->infoBpp
)
3383 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
3384 descr
->infoWidth
, descr
->width
,
3385 descr
->colorMap
, descr
->palentry
,
3386 bmpImage
, descr
->dibpitch
);
3390 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
3391 descr
->infoWidth
, descr
->width
,
3392 descr
->colorMap
, descr
->palentry
,
3393 bmpImage
, descr
->dibpitch
);
3396 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
3397 descr
->infoWidth
, descr
->width
,
3398 descr
->colorMap
, descr
->palentry
,
3399 bmpImage
, descr
->dibpitch
);
3402 X11DRV_DIB_GetImageBits_16( descr
->physDev
, descr
->lines
, (LPVOID
)descr
->bits
,
3403 descr
->infoWidth
,descr
->width
,
3405 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3406 bmpImage
, descr
->dibpitch
);
3410 X11DRV_DIB_GetImageBits_24( descr
->physDev
, descr
->lines
, (LPVOID
)descr
->bits
,
3411 descr
->infoWidth
,descr
->width
,
3413 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3414 bmpImage
, descr
->dibpitch
);
3418 X11DRV_DIB_GetImageBits_32( descr
->physDev
, descr
->lines
, (LPVOID
)descr
->bits
,
3419 descr
->infoWidth
, descr
->width
,
3421 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3422 bmpImage
, descr
->dibpitch
);
3426 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
3430 if (old_data
) bmpImage
->data
= old_data
;
3431 if (!descr
->image
) X11DRV_DIB_DestroyXImage( bmpImage
);
3435 /***********************************************************************
3436 * X11DRV_DIB_DoCopyDIBSection
3438 static void X11DRV_DIB_DoCopyDIBSection(X_PHYSBITMAP
*physBitmap
, BOOL toDIB
,
3439 void *colorMap
, int nColorMap
,
3440 Drawable dest
, GC gc
,
3441 DWORD xSrc
, DWORD ySrc
,
3442 DWORD xDest
, DWORD yDest
,
3443 DWORD width
, DWORD height
)
3445 DIBSECTION dibSection
;
3446 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3447 int identity
[2] = {0,1};
3449 if (!GetObjectW( physBitmap
->hbitmap
, sizeof(dibSection
), &dibSection
)) return;
3451 descr
.physDev
= NULL
;
3452 descr
.palentry
= NULL
;
3453 descr
.infoWidth
= dibSection
.dsBmih
.biWidth
;
3454 descr
.infoBpp
= dibSection
.dsBmih
.biBitCount
;
3455 descr
.lines
= physBitmap
->topdown
? -dibSection
.dsBmih
.biHeight
: dibSection
.dsBmih
.biHeight
;
3456 descr
.image
= physBitmap
->image
;
3457 descr
.colorMap
= colorMap
;
3458 descr
.nColorMap
= nColorMap
;
3459 descr
.bits
= dibSection
.dsBm
.bmBits
;
3460 descr
.depth
= physBitmap
->depth
;
3461 descr
.shifts
= physBitmap
->trueColor
? &physBitmap
->color_shifts
: NULL
;
3462 descr
.compression
= dibSection
.dsBmih
.biCompression
;
3463 descr
.physBitmap
= physBitmap
;
3465 if(descr
.infoBpp
== 1)
3466 descr
.colorMap
= (void*)identity
;
3468 switch (descr
.infoBpp
)
3473 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3477 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dibSection
.dsBitfields
[0] : 0x7c00;
3478 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dibSection
.dsBitfields
[1] : 0x03e0;
3479 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dibSection
.dsBitfields
[2] : 0x001f;
3484 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dibSection
.dsBitfields
[0] : 0xff0000;
3485 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dibSection
.dsBitfields
[1] : 0x00ff00;
3486 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dibSection
.dsBitfields
[2] : 0x0000ff;
3491 descr
.drawable
= dest
;
3495 descr
.xDest
= xDest
;
3496 descr
.yDest
= yDest
;
3497 descr
.width
= width
;
3498 descr
.height
= height
;
3499 descr
.sizeImage
= 0;
3501 descr
.shm_mode
= physBitmap
->shm_mode
;
3502 #ifdef HAVE_LIBXXSHM
3503 if (physBitmap
->shm_mode
== X11DRV_SHM_PIXMAP
&& physBitmap
->pixmap
!= dest
)
3505 descr
.shm_mode
= X11DRV_SHM_NONE
;
3508 descr
.dibpitch
= dibSection
.dsBm
.bmWidthBytes
;
3512 TRACE("Copying from Pixmap to DIB bits\n");
3513 X11DRV_DIB_GetImageBits( &descr
);
3517 TRACE("Copying from DIB bits to Pixmap\n");
3518 X11DRV_DIB_SetImageBits( &descr
);
3522 /***********************************************************************
3523 * X11DRV_DIB_DoUpdateDIBSection
3525 static void X11DRV_DIB_DoUpdateDIBSection(X_PHYSBITMAP
*physBitmap
, BOOL toDIB
)
3529 GetObjectW( physBitmap
->hbitmap
, sizeof(bitmap
), &bitmap
);
3530 X11DRV_DIB_DoCopyDIBSection(physBitmap
, toDIB
,
3531 physBitmap
->colorMap
, physBitmap
->nColorMap
,
3532 physBitmap
->pixmap
, get_bitmap_gc(physBitmap
->depth
),
3533 0, 0, 0, 0, bitmap
.bmWidth
, bitmap
.bmHeight
);
3536 /***********************************************************************
3537 * X11DRV_DIB_FaultHandler
3539 static LONG CALLBACK
X11DRV_DIB_FaultHandler( PEXCEPTION_POINTERS ep
)
3541 X_PHYSBITMAP
*physBitmap
= NULL
;
3545 const size_t pagemask
= getpagesize() - 1;
3547 if (ep
->ExceptionRecord
->ExceptionCode
!= EXCEPTION_ACCESS_VIOLATION
)
3548 return EXCEPTION_CONTINUE_SEARCH
;
3550 addr
= (BYTE
*)ep
->ExceptionRecord
->ExceptionInformation
[1];
3552 EnterCriticalSection(&dibs_cs
);
3553 LIST_FOR_EACH( ptr
, &dibs_list
)
3555 physBitmap
= LIST_ENTRY( ptr
, X_PHYSBITMAP
, entry
);
3556 if ((physBitmap
->base
<= addr
) &&
3557 (addr
< physBitmap
->base
+ ((physBitmap
->size
+ pagemask
) & ~pagemask
)))
3563 LeaveCriticalSection(&dibs_cs
);
3565 if (!found
) return EXCEPTION_CONTINUE_SEARCH
;
3567 if (addr
>= physBitmap
->base
+ physBitmap
->size
)
3568 WARN( "%p: access to %p beyond the end of the DIB\n", physBitmap
->hbitmap
, addr
);
3570 X11DRV_DIB_Lock( physBitmap
, DIB_Status_None
);
3571 if (ep
->ExceptionRecord
->ExceptionInformation
[0] == EXCEPTION_WRITE_FAULT
) {
3572 /* the app tried to write the DIB bits */
3573 X11DRV_DIB_Coerce( physBitmap
, DIB_Status_AppMod
);
3575 /* the app tried to read the DIB bits */
3576 X11DRV_DIB_Coerce( physBitmap
, DIB_Status_InSync
);
3578 X11DRV_DIB_Unlock( physBitmap
, TRUE
);
3580 return EXCEPTION_CONTINUE_EXECUTION
;
3583 /***********************************************************************
3586 static INT
X11DRV_DIB_Coerce(X_PHYSBITMAP
*physBitmap
, INT req
)
3588 INT ret
= DIB_Status_None
;
3590 if (!physBitmap
->image
) return ret
; /* not a DIB section */
3591 EnterCriticalSection(&physBitmap
->lock
);
3592 ret
= physBitmap
->status
;
3594 case DIB_Status_GdiMod
:
3595 /* GDI access - request to draw on pixmap */
3596 switch (physBitmap
->status
)
3599 case DIB_Status_None
:
3600 physBitmap
->p_status
= DIB_Status_GdiMod
;
3601 X11DRV_DIB_DoUpdateDIBSection( physBitmap
, FALSE
);
3604 case DIB_Status_GdiMod
:
3605 TRACE("GdiMod requested in status GdiMod\n" );
3606 physBitmap
->p_status
= DIB_Status_GdiMod
;
3609 case DIB_Status_InSync
:
3610 TRACE("GdiMod requested in status InSync\n" );
3611 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_NOACCESS
);
3612 physBitmap
->status
= DIB_Status_GdiMod
;
3613 physBitmap
->p_status
= DIB_Status_InSync
;
3616 case DIB_Status_AppMod
:
3617 TRACE("GdiMod requested in status AppMod\n" );
3618 /* make it readonly to avoid app changing data while we copy */
3619 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READONLY
);
3620 X11DRV_DIB_DoUpdateDIBSection( physBitmap
, FALSE
);
3621 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_NOACCESS
);
3622 physBitmap
->p_status
= DIB_Status_AppMod
;
3623 physBitmap
->status
= DIB_Status_GdiMod
;
3628 case DIB_Status_InSync
:
3629 /* App access - request access to read DIB surface */
3630 /* (typically called from signal handler) */
3631 switch (physBitmap
->status
)
3634 case DIB_Status_None
:
3635 /* shouldn't happen from signal handler */
3638 case DIB_Status_GdiMod
:
3639 TRACE("InSync requested in status GdiMod\n" );
3640 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READWRITE
);
3641 X11DRV_DIB_DoUpdateDIBSection( physBitmap
, TRUE
);
3642 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READONLY
);
3643 physBitmap
->status
= DIB_Status_InSync
;
3646 case DIB_Status_InSync
:
3647 TRACE("InSync requested in status InSync\n" );
3648 /* shouldn't happen from signal handler */
3651 case DIB_Status_AppMod
:
3652 TRACE("InSync requested in status AppMod\n" );
3653 /* no reason to do anything here, and this
3654 * shouldn't happen from signal handler */
3659 case DIB_Status_AppMod
:
3660 /* App access - request access to write DIB surface */
3661 /* (typically called from signal handler) */
3662 switch (physBitmap
->status
)
3665 case DIB_Status_None
:
3666 /* shouldn't happen from signal handler */
3669 case DIB_Status_GdiMod
:
3670 TRACE("AppMod requested in status GdiMod\n" );
3671 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READWRITE
);
3672 X11DRV_DIB_DoUpdateDIBSection( physBitmap
, TRUE
);
3673 physBitmap
->status
= DIB_Status_AppMod
;
3676 case DIB_Status_InSync
:
3677 TRACE("AppMod requested in status InSync\n" );
3678 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READWRITE
);
3679 physBitmap
->status
= DIB_Status_AppMod
;
3682 case DIB_Status_AppMod
:
3683 TRACE("AppMod requested in status AppMod\n" );
3684 /* shouldn't happen from signal handler */
3689 /* it is up to the caller to do the copy/conversion, probably
3690 * using the return value to decide where to copy from */
3692 LeaveCriticalSection(&physBitmap
->lock
);
3696 /***********************************************************************
3699 INT
X11DRV_DIB_Lock(X_PHYSBITMAP
*physBitmap
, INT req
)
3701 INT ret
= DIB_Status_None
;
3703 if (!physBitmap
->image
) return ret
; /* not a DIB section */
3704 TRACE("Locking %p from thread %04x\n", physBitmap
->hbitmap
, GetCurrentThreadId());
3705 EnterCriticalSection(&physBitmap
->lock
);
3706 ret
= physBitmap
->status
;
3707 if (req
!= DIB_Status_None
)
3708 X11DRV_DIB_Coerce(physBitmap
, req
);
3712 /***********************************************************************
3715 void X11DRV_DIB_Unlock(X_PHYSBITMAP
*physBitmap
, BOOL commit
)
3717 if (!physBitmap
->image
) return; /* not a DIB section */
3718 switch (physBitmap
->status
)
3721 case DIB_Status_None
:
3722 /* in case anyone is wondering, this is the "signal handler doesn't
3723 * work" case, where we always have to be ready for app access */
3725 switch (physBitmap
->p_status
)
3727 case DIB_Status_GdiMod
:
3728 TRACE("Unlocking and syncing from GdiMod\n" );
3729 X11DRV_DIB_DoUpdateDIBSection( physBitmap
, TRUE
);
3733 TRACE("Unlocking without needing to sync\n" );
3737 else TRACE("Unlocking with no changes\n");
3738 physBitmap
->p_status
= DIB_Status_None
;
3741 case DIB_Status_GdiMod
:
3742 TRACE("Unlocking in status GdiMod\n" );
3743 /* DIB was protected in Coerce */
3745 /* no commit, revert to InSync if applicable */
3746 if ((physBitmap
->p_status
== DIB_Status_InSync
) ||
3747 (physBitmap
->p_status
== DIB_Status_AppMod
)) {
3748 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READONLY
);
3749 physBitmap
->status
= DIB_Status_InSync
;
3754 case DIB_Status_InSync
:
3755 TRACE("Unlocking in status InSync\n" );
3756 /* DIB was already protected in Coerce */
3759 case DIB_Status_AppMod
:
3760 TRACE("Unlocking in status AppMod\n" );
3761 /* DIB was already protected in Coerce */
3762 /* this case is ordinary only called from the signal handler,
3763 * so we don't bother to check for !commit */
3766 LeaveCriticalSection(&physBitmap
->lock
);
3767 TRACE("Unlocked %p\n", physBitmap
->hbitmap
);
3770 /***********************************************************************
3771 * X11DRV_CoerceDIBSection
3773 INT
X11DRV_CoerceDIBSection(X11DRV_PDEVICE
*physDev
, INT req
)
3775 if (!physDev
|| !physDev
->bitmap
) return DIB_Status_None
;
3776 return X11DRV_DIB_Coerce(physDev
->bitmap
, req
);
3779 /***********************************************************************
3780 * X11DRV_LockDIBSection
3782 INT
X11DRV_LockDIBSection(X11DRV_PDEVICE
*physDev
, INT req
)
3784 if (!physDev
|| !physDev
->bitmap
) return DIB_Status_None
;
3785 return X11DRV_DIB_Lock(physDev
->bitmap
, req
);
3788 /***********************************************************************
3789 * X11DRV_UnlockDIBSection
3791 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE
*physDev
, BOOL commit
)
3793 if (!physDev
|| !physDev
->bitmap
) return;
3794 X11DRV_DIB_Unlock(physDev
->bitmap
, commit
);
3798 #ifdef HAVE_LIBXXSHM
3799 /***********************************************************************
3800 * X11DRV_XShmErrorHandler
3803 static int XShmErrorHandler( Display
*dpy
, XErrorEvent
*event
, void *arg
)
3805 return 1; /* FIXME: should check event contents */
3808 /***********************************************************************
3809 * X11DRV_XShmCreateImage
3812 static XImage
*X11DRV_XShmCreateImage( int width
, int height
, int bpp
,
3813 XShmSegmentInfo
* shminfo
)
3817 image
= XShmCreateImage(gdi_display
, visual
, bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
3820 shminfo
->shmid
= shmget(IPC_PRIVATE
, image
->bytes_per_line
* height
,
3822 if( shminfo
->shmid
!= -1 )
3824 shminfo
->shmaddr
= shmat( shminfo
->shmid
, 0, 0 );
3825 if( shminfo
->shmaddr
!= (char*)-1 )
3829 shminfo
->readOnly
= FALSE
;
3830 X11DRV_expect_error( gdi_display
, XShmErrorHandler
, NULL
);
3831 ok
= (XShmAttach( gdi_display
, shminfo
) != 0);
3832 XSync( gdi_display
, False
);
3833 if (X11DRV_check_error()) ok
= FALSE
;
3836 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3837 return image
; /* Success! */
3839 /* An error occurred */
3840 shmdt(shminfo
->shmaddr
);
3842 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3843 shminfo
->shmid
= -1;
3845 XFlush(gdi_display
);
3846 XDestroyImage(image
);
3851 #endif /* HAVE_LIBXXSHM */
3853 static Bool
X11DRV_DIB_QueryXShm( Bool
*pixmaps
)
3855 static Bool have_xshm
, have_xshm_pixmaps
;
3856 static BOOL initialized
;
3860 #ifdef HAVE_LIBXXSHM
3863 have_xshm
= XShmQueryVersion( gdi_display
, &major
, &minor
, &have_xshm_pixmaps
);
3868 *pixmaps
= have_xshm_pixmaps
;
3872 /***********************************************************************
3873 * X11DRV_CreateDIBSection (X11DRV.@)
3875 HBITMAP
X11DRV_CreateDIBSection( PHYSDEV dev
, HBITMAP hbitmap
, BITMAPINFO
*bmi
, UINT usage
)
3877 X11DRV_PDEVICE
*physDev
= get_x11drv_dev( dev
);
3878 X_PHYSBITMAP
*physBitmap
;
3880 #ifdef HAVE_LIBXXSHM
3884 if (!(physBitmap
= X11DRV_init_phys_bitmap( hbitmap
))) return 0;
3885 physBitmap
->topdown
= bmi
->bmiHeader
.biHeight
< 0;
3886 physBitmap
->status
= DIB_Status_None
;
3888 GetObjectW( hbitmap
, sizeof(dib
), &dib
);
3890 /* create color map */
3891 if (dib
.dsBm
.bmBitsPixel
<= 8)
3893 physBitmap
->colorMap
= X11DRV_DIB_BuildColorMap( physDev
,
3894 usage
, dib
.dsBm
.bmBitsPixel
, bmi
,
3895 &physBitmap
->nColorMap
);
3898 if (!X11DRV_XRender_SetPhysBitmapDepth( physBitmap
, dib
.dsBm
.bmBitsPixel
, &dib
))
3900 if (dib
.dsBm
.bmBitsPixel
== 1)
3902 physBitmap
->depth
= 1;
3903 physBitmap
->trueColor
= FALSE
;
3907 physBitmap
->depth
= screen_depth
;
3908 physBitmap
->color_shifts
= X11DRV_PALETTE_default_shifts
;
3909 physBitmap
->trueColor
= (visual
->class == TrueColor
|| visual
->class == DirectColor
);
3913 /* create pixmap and X image */
3915 #ifdef HAVE_LIBXXSHM
3916 physBitmap
->shminfo
.shmid
= -1;
3918 if (X11DRV_DIB_QueryXShm( &pixmaps
)
3919 && (physBitmap
->image
= X11DRV_XShmCreateImage( dib
.dsBm
.bmWidth
, dib
.dsBm
.bmHeight
,
3920 physBitmap
->depth
, &physBitmap
->shminfo
)))
3924 physBitmap
->shm_mode
= X11DRV_SHM_PIXMAP
;
3925 physBitmap
->image
->data
= HeapAlloc( GetProcessHeap(), 0,
3926 dib
.dsBm
.bmHeight
* physBitmap
->image
->bytes_per_line
);
3930 physBitmap
->shm_mode
= X11DRV_SHM_IMAGE
;
3931 physBitmap
->image
->data
= physBitmap
->shminfo
.shmaddr
;
3937 physBitmap
->shm_mode
= X11DRV_SHM_NONE
;
3938 physBitmap
->image
= X11DRV_DIB_CreateXImage( dib
.dsBm
.bmWidth
, dib
.dsBm
.bmHeight
,
3939 physBitmap
->depth
);
3942 #ifdef HAVE_LIBXXSHM
3943 if (physBitmap
->shm_mode
== X11DRV_SHM_PIXMAP
)
3945 TRACE("Creating shared pixmap for bmp %p.\n", physBitmap
->hbitmap
);
3946 physBitmap
->pixmap
= XShmCreatePixmap( gdi_display
, root_window
,
3947 physBitmap
->shminfo
.shmaddr
, &physBitmap
->shminfo
,
3948 dib
.dsBm
.bmWidth
, dib
.dsBm
.bmHeight
,
3949 physBitmap
->depth
);
3954 physBitmap
->pixmap
= XCreatePixmap( gdi_display
, root_window
, dib
.dsBm
.bmWidth
,
3955 dib
.dsBm
.bmHeight
, physBitmap
->depth
);
3958 wine_tsx11_unlock();
3959 if (!physBitmap
->pixmap
|| !physBitmap
->image
) return 0;
3961 if (physBitmap
->trueColor
)
3963 ColorShifts
*shifts
= &physBitmap
->color_shifts
;
3965 /* When XRender is around and used, we also support dibsections in other formats like 16-bit. In these
3966 * cases we need to override the mask of XImages. The reason is that during XImage creation the masks are
3967 * derived from a 24-bit visual (no 16-bit ones are around when X runs at 24-bit). SetImageBits and other
3968 * functions rely on the color masks for proper color conversion, so we need to override the masks here. */
3969 physBitmap
->image
->red_mask
= shifts
->physicalRed
.max
<< shifts
->physicalRed
.shift
;
3970 physBitmap
->image
->green_mask
= shifts
->physicalGreen
.max
<< shifts
->physicalGreen
.shift
;
3971 physBitmap
->image
->blue_mask
= shifts
->physicalBlue
.max
<< shifts
->physicalBlue
.shift
;
3974 /* install fault handler */
3975 InitializeCriticalSection( &physBitmap
->lock
);
3976 physBitmap
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": X_PHYSBITMAP.lock");
3978 physBitmap
->base
= dib
.dsBm
.bmBits
;
3979 physBitmap
->size
= dib
.dsBmih
.biSizeImage
;
3980 physBitmap
->status
= DIB_Status_AppMod
;
3983 dibs_handler
= AddVectoredExceptionHandler( TRUE
, X11DRV_DIB_FaultHandler
);
3984 EnterCriticalSection( &dibs_cs
);
3985 list_add_head( &dibs_list
, &physBitmap
->entry
);
3986 LeaveCriticalSection( &dibs_cs
);
3988 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READWRITE
);
3993 /***********************************************************************
3994 * X11DRV_DIB_DeleteDIBSection
3996 void X11DRV_DIB_DeleteDIBSection(X_PHYSBITMAP
*physBitmap
, DIBSECTION
*dib
)
4000 EnterCriticalSection( &dibs_cs
);
4001 list_remove( &physBitmap
->entry
);
4002 last
= list_empty( &dibs_list
);
4003 LeaveCriticalSection( &dibs_cs
);
4007 RemoveVectoredExceptionHandler( dibs_handler
);
4008 dibs_handler
= NULL
;
4011 if (dib
->dshSection
)
4012 X11DRV_DIB_Coerce(physBitmap
, DIB_Status_InSync
);
4014 if (physBitmap
->image
)
4017 #ifdef HAVE_LIBXXSHM
4018 if (physBitmap
->shminfo
.shmid
!= -1)
4020 XShmDetach( gdi_display
, &(physBitmap
->shminfo
) );
4021 if (physBitmap
->shm_mode
== X11DRV_SHM_PIXMAP
) X11DRV_DIB_DestroyXImage( physBitmap
->image
);
4022 else XDestroyImage( physBitmap
->image
);
4023 shmdt( physBitmap
->shminfo
.shmaddr
);
4024 physBitmap
->shminfo
.shmid
= -1;
4025 physBitmap
->shm_mode
= X11DRV_SHM_NONE
;
4029 X11DRV_DIB_DestroyXImage( physBitmap
->image
);
4030 wine_tsx11_unlock();
4033 HeapFree(GetProcessHeap(), 0, physBitmap
->colorMap
);
4034 physBitmap
->lock
.DebugInfo
->Spare
[0] = 0;
4035 DeleteCriticalSection(&physBitmap
->lock
);
4038 /***********************************************************************
4039 * SetDIBColorTable (X11DRV.@)
4041 UINT
X11DRV_SetDIBColorTable( PHYSDEV dev
, UINT start
, UINT count
, const RGBQUAD
*colors
)
4043 X11DRV_PDEVICE
*physDev
= get_x11drv_dev( dev
);
4046 X_PHYSBITMAP
*physBitmap
= physDev
->bitmap
;
4048 if (!physBitmap
) return 0;
4049 GetObjectW( physBitmap
->hbitmap
, sizeof(dib
), &dib
);
4051 if (physBitmap
->colorMap
&& start
< physBitmap
->nColorMap
) {
4052 UINT end
= count
+ start
;
4053 if (end
> physBitmap
->nColorMap
) end
= physBitmap
->nColorMap
;
4055 * Changing color table might change the mapping between
4056 * DIB colors and X11 colors and thus alter the visible state
4057 * of the bitmap object.
4060 * FIXME we need to recalculate the pen, brush, text and bkgnd pixels here,
4061 * at least for a 1 bpp dibsection
4063 X11DRV_DIB_Lock( physBitmap
, DIB_Status_AppMod
);
4064 X11DRV_DIB_GenColorMap( physDev
, physBitmap
->colorMap
, DIB_RGB_COLORS
,
4065 dib
.dsBm
.bmBitsPixel
, colors
, start
, end
);
4066 X11DRV_DIB_Unlock( physBitmap
, TRUE
);
4073 /***********************************************************************
4074 * X11DRV_DIB_CreateDIBFromBitmap
4076 * Allocates a packed DIB and copies the bitmap data into it.
4078 HGLOBAL
X11DRV_DIB_CreateDIBFromBitmap(HDC hdc
, HBITMAP hBmp
)
4083 LPBITMAPINFOHEADER pbmiHeader
;
4084 unsigned int cDataSize
, cPackedSize
, OffsetBits
;
4087 if (!GetObjectW( hBmp
, sizeof(bmp
), &bmp
)) return 0;
4090 * A packed DIB contains a BITMAPINFO structure followed immediately by
4091 * an optional color palette and the pixel data.
4094 /* Calculate the size of the packed DIB */
4095 cDataSize
= X11DRV_DIB_GetDIBWidthBytes( bmp
.bmWidth
, bmp
.bmBitsPixel
) * abs( bmp
.bmHeight
);
4096 cPackedSize
= sizeof(BITMAPINFOHEADER
)
4097 + ( (bmp
.bmBitsPixel
<= 8) ? (sizeof(RGBQUAD
) * (1 << bmp
.bmBitsPixel
)) : 0 )
4099 /* Get the offset to the bits */
4100 OffsetBits
= cPackedSize
- cDataSize
;
4102 /* Allocate the packed DIB */
4103 TRACE("\tAllocating packed DIB of size %d\n", cPackedSize
);
4104 hPackedDIB
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_DDESHARE
/*| GMEM_ZEROINIT*/,
4108 WARN("Could not allocate packed DIB!\n");
4112 /* A packed DIB starts with a BITMAPINFOHEADER */
4113 pPackedDIB
= GlobalLock(hPackedDIB
);
4114 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
4116 /* Init the BITMAPINFOHEADER */
4117 pbmiHeader
->biSize
= sizeof(BITMAPINFOHEADER
);
4118 pbmiHeader
->biWidth
= bmp
.bmWidth
;
4119 pbmiHeader
->biHeight
= bmp
.bmHeight
;
4120 pbmiHeader
->biPlanes
= 1;
4121 pbmiHeader
->biBitCount
= bmp
.bmBitsPixel
;
4122 pbmiHeader
->biCompression
= BI_RGB
;
4123 pbmiHeader
->biSizeImage
= 0;
4124 pbmiHeader
->biXPelsPerMeter
= pbmiHeader
->biYPelsPerMeter
= 0;
4125 pbmiHeader
->biClrUsed
= 0;
4126 pbmiHeader
->biClrImportant
= 0;
4128 /* Retrieve the DIB bits from the bitmap and fill in the
4129 * DIB color table if present */
4131 nLinesCopied
= GetDIBits(hdc
, /* Handle to device context */
4132 hBmp
, /* Handle to bitmap */
4133 0, /* First scan line to set in dest bitmap */
4134 bmp
.bmHeight
, /* Number of scan lines to copy */
4135 pPackedDIB
+ OffsetBits
, /* [out] Address of array for bitmap bits */
4136 (LPBITMAPINFO
) pbmiHeader
, /* [out] Address of BITMAPINFO structure */
4137 0); /* RGB or palette index */
4138 GlobalUnlock(hPackedDIB
);
4140 /* Cleanup if GetDIBits failed */
4141 if (nLinesCopied
!= bmp
.bmHeight
)
4143 TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied
, bmp
.bmHeight
);
4144 GlobalFree(hPackedDIB
);
4151 /**************************************************************************
4152 * X11DRV_DIB_CreateDIBFromPixmap
4154 * Allocates a packed DIB and copies the Pixmap data into it.
4155 * The Pixmap passed in is deleted after the conversion.
4157 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
)
4160 X_PHYSBITMAP
*physBitmap
;
4163 HGLOBAL hPackedDIB
= 0;
4165 int x
,y
; /* Unused */
4166 unsigned border_width
; /* Unused */
4167 unsigned int depth
, width
, height
;
4169 /* Get the Pixmap dimensions and bit depth */
4171 if (!XGetGeometry(gdi_display
, pixmap
, &root
, &x
, &y
, &width
, &height
,
4172 &border_width
, &depth
)) depth
= 0;
4173 wine_tsx11_unlock();
4174 if (!pixmap_formats
[depth
]) return 0;
4176 TRACE("\tPixmap properties: width=%d, height=%d, depth=%d\n",
4177 width
, height
, depth
);
4180 * Create an HBITMAP with the same dimensions and BPP as the pixmap,
4181 * and make it a container for the pixmap passed.
4183 if (!(hBmp
= CreateBitmap( width
, height
, 1, pixmap_formats
[depth
]->bits_per_pixel
, NULL
))) return 0;
4185 /* force bitmap to be owned by a screen DC */
4186 hdcMem
= CreateCompatibleDC( hdc
);
4187 SelectObject( hdcMem
, SelectObject( hdcMem
, hBmp
));
4190 physBitmap
= X11DRV_get_phys_bitmap( hBmp
);
4192 /* swap the new pixmap in */
4193 orig_pixmap
= physBitmap
->pixmap
;
4194 physBitmap
->pixmap
= pixmap
;
4197 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4198 * A packed DIB contains a BITMAPINFO structure followed immediately by
4199 * an optional color palette and the pixel data.
4201 hPackedDIB
= X11DRV_DIB_CreateDIBFromBitmap(hdc
, hBmp
);
4203 /* we can now get rid of the HBITMAP and its original pixmap */
4204 physBitmap
->pixmap
= orig_pixmap
;
4207 TRACE("\tReturning packed DIB %p\n", hPackedDIB
);
4212 /**************************************************************************
4213 * X11DRV_DIB_CreatePixmapFromDIB
4215 * Creates a Pixmap from a packed DIB
4217 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
4220 X_PHYSBITMAP
*physBitmap
;
4225 /* Create a DDB from the DIB */
4227 pbmi
= GlobalLock(hPackedDIB
);
4228 hBmp
= CreateDIBitmap(hdc
, &pbmi
->bmiHeader
, CBM_INIT
,
4229 (LPBYTE
)pbmi
+ bitmap_info_size( pbmi
, DIB_RGB_COLORS
),
4230 pbmi
, DIB_RGB_COLORS
);
4231 GlobalUnlock(hPackedDIB
);
4233 /* make sure it's owned by x11drv */
4234 memdc
= CreateCompatibleDC( hdc
);
4235 SelectObject( memdc
, hBmp
);
4238 /* clear the physBitmap so that we can steal its pixmap */
4239 if ((physBitmap
= X11DRV_get_phys_bitmap( hBmp
)))
4241 pixmap
= physBitmap
->pixmap
;
4242 physBitmap
->pixmap
= 0;
4245 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4248 TRACE("Returning Pixmap %lx\n", pixmap
);