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;
440 case 6: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
441 case 5: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
442 case 4: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
443 case 3: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
444 case 2: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
445 case 1: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]);
448 srcbits
+= linebytes
;
452 /***********************************************************************
453 * X11DRV_DIB_GetImageBits_1
455 * GetDIBits for a 1-bit deep DIB.
457 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
458 DWORD dstwidth
, DWORD srcwidth
,
459 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
460 XImage
*bmpImage
, int linebytes
)
463 int h
, width
= min(dstwidth
, srcwidth
);
467 dstbits
= dstbits
+ linebytes
* (lines
- 1);
468 linebytes
= -linebytes
;
471 switch (bmpImage
->depth
)
475 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
477 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
480 for (h
=lines
-1; h
>=0; h
--) {
484 for (x
=0; x
<width
; x
++) {
486 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
487 dstval
|=(X11DRV_DIB_GetNearestIndex
491 srcval
.peBlue
) << (7 - (x
& 7)));
500 /* pad with 0 to DWORD alignment */
501 for (x
= (x
+7)&~7; x
< ((width
+ 31) & ~31); x
+=8)
503 dstbits
+= linebytes
;
511 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
, bmpImage
->green_mask
, bmpImage
->blue_mask
)
513 /* ==== pal 8 bmp -> pal 1 dib ==== */
515 const BYTE
* srcpixel
;
518 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
520 for (h
=0; h
<lines
; h
++) {
525 for (x
=0; x
<width
; x
++) {
527 srcval
=srccolors
[*srcpixel
++];
528 dstval
|=(X11DRV_DIB_GetNearestIndex
532 srcval
.peBlue
) << (7-(x
&7)) );
541 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
542 dstbits
+= linebytes
;
553 const WORD
* srcpixel
;
556 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
558 if (bmpImage
->green_mask
==0x03e0) {
559 if (bmpImage
->red_mask
==0x7c00) {
560 /* ==== rgb 555 bmp -> pal 1 dib ==== */
561 for (h
=0; h
<lines
; h
++) {
566 for (x
=0; x
<width
; x
++) {
569 dstval
|=(X11DRV_DIB_GetNearestIndex
571 ((srcval
>> 7) & 0xf8) | /* r */
572 ((srcval
>> 12) & 0x07),
573 ((srcval
>> 2) & 0xf8) | /* g */
574 ((srcval
>> 7) & 0x07),
575 ((srcval
<< 3) & 0xf8) | /* b */
576 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
585 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
586 dstbits
+= linebytes
;
588 } else if (bmpImage
->blue_mask
==0x7c00) {
589 /* ==== bgr 555 bmp -> pal 1 dib ==== */
590 for (h
=0; h
<lines
; h
++) {
595 for (x
=0; x
<width
; x
++) {
598 dstval
|=(X11DRV_DIB_GetNearestIndex
600 ((srcval
<< 3) & 0xf8) | /* r */
601 ((srcval
>> 2) & 0x07),
602 ((srcval
>> 2) & 0xf8) | /* g */
603 ((srcval
>> 7) & 0x07),
604 ((srcval
>> 7) & 0xf8) | /* b */
605 ((srcval
>> 12) & 0x07) ) << (7-(x
&7)) );
614 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
615 dstbits
+= linebytes
;
620 } else if (bmpImage
->green_mask
==0x07e0) {
621 if (bmpImage
->red_mask
==0xf800) {
622 /* ==== rgb 565 bmp -> pal 1 dib ==== */
623 for (h
=0; h
<lines
; h
++) {
628 for (x
=0; x
<width
; x
++) {
631 dstval
|=(X11DRV_DIB_GetNearestIndex
633 ((srcval
>> 8) & 0xf8) | /* r */
634 ((srcval
>> 13) & 0x07),
635 ((srcval
>> 3) & 0xfc) | /* g */
636 ((srcval
>> 9) & 0x03),
637 ((srcval
<< 3) & 0xf8) | /* b */
638 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
647 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
648 dstbits
+= linebytes
;
650 } else if (bmpImage
->blue_mask
==0xf800) {
651 /* ==== bgr 565 bmp -> pal 1 dib ==== */
652 for (h
=0; h
<lines
; h
++) {
657 for (x
=0; x
<width
; x
++) {
660 dstval
|=(X11DRV_DIB_GetNearestIndex
662 ((srcval
<< 3) & 0xf8) | /* r */
663 ((srcval
>> 2) & 0x07),
664 ((srcval
>> 3) & 0xfc) | /* g */
665 ((srcval
>> 9) & 0x03),
666 ((srcval
>> 8) & 0xf8) | /* b */
667 ((srcval
>> 13) & 0x07) ) << (7-(x
&7)) );
676 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
677 dstbits
+= linebytes
;
696 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
697 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
699 if (bmpImage
->green_mask
!=0x00ff00 ||
700 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
702 } else if (bmpImage
->blue_mask
==0xff) {
703 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
704 for (h
=0; h
<lines
; h
++) {
709 for (x
=0; x
<width
; x
++) {
710 dstval
|=(X11DRV_DIB_GetNearestIndex
714 srcbyte
[0]) << (7-(x
&7)) );
715 srcbyte
+=bytes_per_pixel
;
724 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
725 dstbits
+= linebytes
;
728 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
729 for (h
=0; h
<lines
; h
++) {
734 for (x
=0; x
<width
; x
++) {
735 dstval
|=(X11DRV_DIB_GetNearestIndex
739 srcbyte
[2]) << (7-(x
&7)) );
740 srcbyte
+=bytes_per_pixel
;
749 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
750 dstbits
+= linebytes
;
761 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
763 /* ==== any bmp format -> pal 1 dib ==== */
764 if ((unsigned)colors
[0].rgbRed
+colors
[0].rgbGreen
+colors
[0].rgbBlue
>=
765 (unsigned)colors
[1].rgbRed
+colors
[1].rgbGreen
+colors
[1].rgbBlue
)
768 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB, "
769 "%s color mapping\n",
770 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
771 bmpImage
->green_mask
, bmpImage
->blue_mask
,
772 neg
?"negative":"direct" );
774 for (h
=lines
-1; h
>=0; h
--) {
778 for (x
=0; x
<width
; x
++) {
779 dstval
|=((XGetPixel( bmpImage
, x
, h
) >= white
) ^ neg
) << (7 - (x
&7));
788 dstbits
+= linebytes
;
795 /***********************************************************************
796 * X11DRV_DIB_SetImageBits_4
798 * SetDIBits for a 4-bit deep DIB.
800 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
801 DWORD srcwidth
, DWORD dstwidth
, int left
,
802 int *colors
, XImage
*bmpImage
, int linebytes
)
810 srcbits
= srcbits
+ linebytes
* (lines
- 1);
811 linebytes
= -linebytes
;
818 srcbits
+= left
>> 1;
819 width
= min(srcwidth
, dstwidth
);
821 /* ==== pal 4 dib -> any bmp format ==== */
822 for (h
= lines
-1; h
>= 0; h
--) {
824 for (i
= width
/2, x
= left
; i
> 0; i
--) {
825 BYTE srcval
=*srcbyte
++;
826 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
>> 4] );
827 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
& 0x0f] );
830 XPutPixel( bmpImage
, x
, h
, colors
[*srcbyte
>> 4] );
831 srcbits
+= linebytes
;
837 /***********************************************************************
838 * X11DRV_DIB_GetImageBits_4
840 * GetDIBits for a 4-bit deep DIB.
842 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
843 DWORD srcwidth
, DWORD dstwidth
,
844 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
845 XImage
*bmpImage
, int linebytes
)
848 int h
, width
= min(srcwidth
, dstwidth
);
853 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
854 linebytes
= -linebytes
;
857 switch (bmpImage
->depth
) {
860 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
862 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
865 for (h
= lines
-1; h
>= 0; h
--) {
869 for (x
= 0; x
< width
; x
++) {
871 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
872 dstval
|=(X11DRV_DIB_GetNearestIndex
876 srcval
.peBlue
) << (4-((x
&1)<<2)));
885 dstbits
+= linebytes
;
893 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
895 /* ==== pal 8 bmp -> pal 4 dib ==== */
897 const BYTE
*srcpixel
;
900 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
901 for (h
=0; h
<lines
; h
++) {
906 for (x
=0; x
<width
; x
++) {
908 srcval
= srccolors
[*srcpixel
++];
909 dstval
|=(X11DRV_DIB_GetNearestIndex
913 srcval
.peBlue
) << (4*(1-(x
&1))) );
922 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
923 dstbits
+= linebytes
;
934 const WORD
* srcpixel
;
937 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
939 if (bmpImage
->green_mask
==0x03e0) {
940 if (bmpImage
->red_mask
==0x7c00) {
941 /* ==== rgb 555 bmp -> pal 4 dib ==== */
942 for (h
=0; h
<lines
; h
++) {
947 for (x
=0; x
<width
; x
++) {
950 dstval
|=(X11DRV_DIB_GetNearestIndex
952 ((srcval
>> 7) & 0xf8) | /* r */
953 ((srcval
>> 12) & 0x07),
954 ((srcval
>> 2) & 0xf8) | /* g */
955 ((srcval
>> 7) & 0x07),
956 ((srcval
<< 3) & 0xf8) | /* b */
957 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
966 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
967 dstbits
+= linebytes
;
969 } else if (bmpImage
->blue_mask
==0x7c00) {
970 /* ==== bgr 555 bmp -> pal 4 dib ==== */
971 for (h
=0; h
<lines
; h
++) {
976 for (x
=0; x
<width
; x
++) {
979 dstval
|=(X11DRV_DIB_GetNearestIndex
981 ((srcval
<< 3) & 0xf8) | /* r */
982 ((srcval
>> 2) & 0x07),
983 ((srcval
>> 2) & 0xf8) | /* g */
984 ((srcval
>> 7) & 0x07),
985 ((srcval
>> 7) & 0xf8) | /* b */
986 ((srcval
>> 12) & 0x07) ) << ((1-(x
&1))<<2) );
995 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
996 dstbits
+= linebytes
;
1001 } else if (bmpImage
->green_mask
==0x07e0) {
1002 if (bmpImage
->red_mask
==0xf800) {
1003 /* ==== rgb 565 bmp -> pal 4 dib ==== */
1004 for (h
=0; h
<lines
; h
++) {
1009 for (x
=0; x
<width
; x
++) {
1012 dstval
|=(X11DRV_DIB_GetNearestIndex
1014 ((srcval
>> 8) & 0xf8) | /* r */
1015 ((srcval
>> 13) & 0x07),
1016 ((srcval
>> 3) & 0xfc) | /* g */
1017 ((srcval
>> 9) & 0x03),
1018 ((srcval
<< 3) & 0xf8) | /* b */
1019 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
1028 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1029 dstbits
+= linebytes
;
1031 } else if (bmpImage
->blue_mask
==0xf800) {
1032 /* ==== bgr 565 bmp -> pal 4 dib ==== */
1033 for (h
=0; h
<lines
; h
++) {
1038 for (x
=0; x
<width
; x
++) {
1041 dstval
|=(X11DRV_DIB_GetNearestIndex
1043 ((srcval
<< 3) & 0xf8) | /* r */
1044 ((srcval
>> 2) & 0x07),
1045 ((srcval
>> 3) & 0xfc) | /* g */
1046 ((srcval
>> 9) & 0x03),
1047 ((srcval
>> 8) & 0xf8) | /* b */
1048 ((srcval
>> 13) & 0x07) ) << ((1-(x
&1))<<2) );
1057 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1058 dstbits
+= linebytes
;
1070 if (bmpImage
->bits_per_pixel
==24) {
1071 const void* srcbits
;
1072 const BYTE
*srcbyte
;
1075 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1077 if (bmpImage
->green_mask
!=0x00ff00 ||
1078 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1080 } else if (bmpImage
->blue_mask
==0xff) {
1081 /* ==== rgb 888 bmp -> pal 4 dib ==== */
1082 for (h
=0; h
<lines
; h
++) {
1085 for (x
=0; x
<width
/2; x
++) {
1086 /* Do 2 pixels at a time */
1087 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1092 X11DRV_DIB_GetNearestIndex
1100 /* And then the odd pixel */
1101 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1107 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1108 dstbits
+= linebytes
;
1111 /* ==== bgr 888 bmp -> pal 4 dib ==== */
1112 for (h
=0; h
<lines
; h
++) {
1115 for (x
=0; x
<width
/2; x
++) {
1116 /* Do 2 pixels at a time */
1117 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1122 X11DRV_DIB_GetNearestIndex
1130 /* And then the odd pixel */
1131 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1137 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1138 dstbits
+= linebytes
;
1147 const void* srcbits
;
1148 const BYTE
*srcbyte
;
1151 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1153 if (bmpImage
->green_mask
!=0x00ff00 ||
1154 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1156 } else if (bmpImage
->blue_mask
==0xff) {
1157 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
1158 for (h
=0; h
<lines
; h
++) {
1161 for (x
=0; x
<width
/2; x
++) {
1162 /* Do 2 pixels at a time */
1163 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1168 X11DRV_DIB_GetNearestIndex
1176 /* And then the odd pixel */
1177 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1183 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1184 dstbits
+= linebytes
;
1187 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
1188 for (h
=0; h
<lines
; h
++) {
1191 for (x
=0; x
<width
/2; x
++) {
1192 /* Do 2 pixels at a time */
1193 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1198 X11DRV_DIB_GetNearestIndex
1206 /* And then the odd pixel */
1207 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1213 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1214 dstbits
+= linebytes
;
1225 /* ==== any bmp format -> pal 4 dib ==== */
1226 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
1227 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1228 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1229 for (h
=lines
-1; h
>=0; h
--) {
1231 for (x
=0; x
<(width
& ~1); x
+=2) {
1232 *dstbyte
++=(X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4) |
1233 X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
+1, h
), 0);
1236 *dstbyte
=(X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4);
1238 dstbits
+= linebytes
;
1245 /***********************************************************************
1246 * X11DRV_DIB_SetImageBits_RLE4
1248 * SetDIBits for a 4-bit deep compressed DIB.
1250 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
1251 DWORD srcwidth
, DWORD dstwidth
,
1252 int left
, int *colors
,
1255 unsigned int x
= 0, width
= min(srcwidth
, dstwidth
);
1256 int y
= lines
- 1, c
, length
;
1257 const BYTE
*begin
= bits
;
1262 if (length
) { /* encoded */
1265 if (x
>= (left
+ width
)) break;
1266 if( x
>= left
) XPutPixel(bmpImage
, x
, y
, colors
[c
>> 4]);
1268 if (!length
--) break;
1269 if (x
>= (left
+ width
)) break;
1270 if( x
>= left
) XPutPixel(bmpImage
, x
, y
, colors
[c
& 0xf]);
1290 default: /* absolute */
1293 if (x
>= left
&& x
< (left
+ width
))
1294 XPutPixel(bmpImage
, x
, y
, colors
[c
>> 4]);
1296 if (!length
--) break;
1297 if (x
>= left
&& x
< (left
+ width
))
1298 XPutPixel(bmpImage
, x
, y
, colors
[c
& 0xf]);
1301 if ((bits
- begin
) & 1)
1310 /***********************************************************************
1311 * X11DRV_DIB_SetImageBits_8
1313 * SetDIBits for an 8-bit deep DIB.
1315 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
1316 DWORD srcwidth
, DWORD dstwidth
, int left
,
1317 const int *colors
, XImage
*bmpImage
,
1321 int h
, width
= min(srcwidth
, dstwidth
);
1322 const BYTE
* srcbyte
;
1328 srcbits
= srcbits
+ linebytes
* (lines
-1);
1329 linebytes
= -linebytes
;
1334 switch (bmpImage
->depth
) {
1337 /* Some X servers might have 32 bit/ 16bit deep pixel */
1338 if (lines
&& width
&& (bmpImage
->bits_per_pixel
== 16) &&
1339 (ImageByteOrder(gdi_display
)==LSBFirst
) )
1341 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
1342 dstbits
=(BYTE
*)bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
1343 for (h
= lines
; h
--; ) {
1344 #if defined(__i386__) && defined(__GNUC__)
1345 int _cl1
,_cl2
; /* temp outputs for asm below */
1346 /* Borrowed from DirectDraw */
1347 __asm__
__volatile__(
1352 " movw (%%edx,%%eax,4),%%ax\n"
1354 " xor %%eax,%%eax\n"
1356 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
1361 :"eax", "cc", "memory"
1364 DWORD
* dstpixel
=(DWORD
*)dstbits
;
1365 for (x
=0; x
<width
/2; x
++) {
1366 /* Do 2 pixels at a time */
1367 *dstpixel
++=(colors
[srcbyte
[1]] << 16) | colors
[srcbyte
[0]];
1371 /* And then the odd pixel */
1372 *((WORD
*)dstpixel
)=colors
[srcbyte
[0]];
1375 srcbyte
= (srcbits
+= linebytes
);
1376 dstbits
-= bmpImage
->bytes_per_line
;
1383 if (lines
&& width
&& (bmpImage
->bits_per_pixel
== 32) &&
1384 (ImageByteOrder(gdi_display
)==LSBFirst
) )
1386 dstbits
=(BYTE
*)bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
1387 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
1388 for (h
= lines
; h
--; ) {
1389 #if defined(__i386__) && defined(__GNUC__)
1390 int _cl1
,_cl2
; /* temp outputs for asm below */
1391 /* Borrowed from DirectDraw */
1392 __asm__
__volatile__(
1397 " movl (%%edx,%%eax,4),%%eax\n"
1399 " xor %%eax,%%eax\n"
1401 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
1406 :"eax", "cc", "memory"
1409 DWORD
* dstpixel
=(DWORD
*)dstbits
;
1410 for (x
=0; x
<width
; x
++) {
1411 *dstpixel
++=colors
[*srcbyte
++];
1414 srcbyte
= (srcbits
+= linebytes
);
1415 dstbits
-= bmpImage
->bytes_per_line
;
1421 break; /* use slow generic case below */
1424 /* ==== pal 8 dib -> any bmp format ==== */
1425 for (h
=lines
-1; h
>=0; h
--) {
1426 for (x
=left
; x
<width
+left
; x
++) {
1427 XPutPixel(bmpImage
, x
, h
, colors
[*srcbyte
++]);
1429 srcbyte
= (srcbits
+= linebytes
);
1433 /***********************************************************************
1434 * X11DRV_DIB_GetImageBits_8
1436 * GetDIBits for an 8-bit deep DIB.
1438 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
1439 DWORD srcwidth
, DWORD dstwidth
,
1440 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1441 XImage
*bmpImage
, int linebytes
)
1444 int h
, width
= min(srcwidth
, dstwidth
);
1450 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1451 linebytes
= -linebytes
;
1456 * This condition is true when GetImageBits has been called by
1457 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
1458 * 256 colormaps, so we'll just use it for GetDIBits calls.
1459 * (In some cases, in an updateDIBSection, the returned colors are bad too)
1461 if (!srccolors
) goto updatesection
;
1463 switch (bmpImage
->depth
) {
1466 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
1469 /* ==== pal 1 bmp -> pal 8 dib ==== */
1470 /* ==== pal 4 bmp -> pal 8 dib ==== */
1471 for (h
=lines
-1; h
>=0; h
--) {
1473 for (x
=0; x
<width
; x
++) {
1474 PALETTEENTRY srcval
;
1475 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
1476 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
1481 dstbits
+= linebytes
;
1489 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
1491 /* ==== pal 8 bmp -> pal 8 dib ==== */
1492 const void* srcbits
;
1493 const BYTE
* srcpixel
;
1495 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1496 for (h
=0; h
<lines
; h
++) {
1499 for (x
= 0; x
< width
; x
++) {
1500 PALETTEENTRY srcval
;
1501 srcval
=srccolors
[*srcpixel
++];
1502 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
1507 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1508 dstbits
+= linebytes
;
1518 const void* srcbits
;
1519 const WORD
* srcpixel
;
1522 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1524 if (bmpImage
->green_mask
==0x03e0) {
1525 if (bmpImage
->red_mask
==0x7c00) {
1526 /* ==== rgb 555 bmp -> pal 8 dib ==== */
1527 for (h
=0; h
<lines
; h
++) {
1530 for (x
=0; x
<width
; x
++) {
1533 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1535 ((srcval
>> 7) & 0xf8) | /* r */
1536 ((srcval
>> 12) & 0x07),
1537 ((srcval
>> 2) & 0xf8) | /* g */
1538 ((srcval
>> 7) & 0x07),
1539 ((srcval
<< 3) & 0xf8) | /* b */
1540 ((srcval
>> 2) & 0x07) );
1542 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1543 dstbits
+= linebytes
;
1545 } else if (bmpImage
->blue_mask
==0x7c00) {
1546 /* ==== bgr 555 bmp -> pal 8 dib ==== */
1547 for (h
=0; h
<lines
; h
++) {
1550 for (x
=0; x
<width
; x
++) {
1553 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1555 ((srcval
<< 3) & 0xf8) | /* r */
1556 ((srcval
>> 2) & 0x07),
1557 ((srcval
>> 2) & 0xf8) | /* g */
1558 ((srcval
>> 7) & 0x07),
1559 ((srcval
>> 7) & 0xf8) | /* b */
1560 ((srcval
>> 12) & 0x07) );
1562 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1563 dstbits
+= linebytes
;
1568 } else if (bmpImage
->green_mask
==0x07e0) {
1569 if (bmpImage
->red_mask
==0xf800) {
1570 /* ==== rgb 565 bmp -> pal 8 dib ==== */
1571 for (h
=0; h
<lines
; h
++) {
1574 for (x
=0; x
<width
; x
++) {
1577 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1579 ((srcval
>> 8) & 0xf8) | /* r */
1580 ((srcval
>> 13) & 0x07),
1581 ((srcval
>> 3) & 0xfc) | /* g */
1582 ((srcval
>> 9) & 0x03),
1583 ((srcval
<< 3) & 0xf8) | /* b */
1584 ((srcval
>> 2) & 0x07) );
1586 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1587 dstbits
+= linebytes
;
1589 } else if (bmpImage
->blue_mask
==0xf800) {
1590 /* ==== bgr 565 bmp -> pal 8 dib ==== */
1591 for (h
=0; h
<lines
; h
++) {
1594 for (x
=0; x
<width
; x
++) {
1597 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1599 ((srcval
<< 3) & 0xf8) | /* r */
1600 ((srcval
>> 2) & 0x07),
1601 ((srcval
>> 3) & 0xfc) | /* g */
1602 ((srcval
>> 9) & 0x03),
1603 ((srcval
>> 8) & 0xf8) | /* b */
1604 ((srcval
>> 13) & 0x07) );
1606 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1607 dstbits
+= linebytes
;
1621 const void* srcbits
;
1622 const BYTE
*srcbyte
;
1624 int bytes_per_pixel
;
1626 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1627 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
1629 if (bmpImage
->green_mask
!=0x00ff00 ||
1630 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1632 } else if (bmpImage
->blue_mask
==0xff) {
1633 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
1634 for (h
=0; h
<lines
; h
++) {
1637 for (x
=0; x
<width
; x
++) {
1638 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1643 srcbyte
+=bytes_per_pixel
;
1645 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1646 dstbits
+= linebytes
;
1649 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
1650 for (h
=0; h
<lines
; h
++) {
1653 for (x
=0; x
<width
; x
++) {
1654 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1659 srcbyte
+=bytes_per_pixel
;
1661 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1662 dstbits
+= linebytes
;
1670 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
1671 bmpImage
->depth
, bmpImage
->red_mask
,
1672 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1674 /* ==== any bmp format -> pal 8 dib ==== */
1675 for (h
=lines
-1; h
>=0; h
--) {
1677 for (x
=0; x
<width
; x
++) {
1678 *dstbyte
=X11DRV_DIB_MapColor
1680 XGetPixel(bmpImage
, x
, h
), *dstbyte
);
1683 dstbits
+= linebytes
;
1689 /***********************************************************************
1690 * X11DRV_DIB_SetImageBits_RLE8
1692 * SetDIBits for an 8-bit deep compressed DIB.
1694 * This function rewritten 941113 by James Youngman. WINE blew out when I
1695 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1697 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1698 * 'End of bitmap' escape code. This code is very much laxer in what it
1699 * allows to end the expansion. Possibly too lax. See the note by
1700 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1701 * bitmap should end with RleEnd, but on the other hand, software exists
1702 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1705 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1706 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1709 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1710 DWORD srcwidth
, DWORD dstwidth
,
1711 int left
, int *colors
,
1714 unsigned int x
; /* X-position on each line. Increases. */
1715 int y
; /* Line #. Starts at lines-1, decreases */
1716 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1717 BYTE length
; /* The length pf a run */
1718 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1721 * Note that the bitmap data is stored by Windows starting at the
1722 * bottom line of the bitmap and going upwards. Within each line,
1723 * the data is stored left-to-right. That's the reason why line
1724 * goes from lines-1 to 0. [JAY]
1734 * If the length byte is not zero (which is the escape value),
1735 * We have a run of length pixels all the same colour. The colour
1736 * index is stored next.
1738 * If the length byte is zero, we need to read the next byte to
1739 * know what to do. [JAY]
1744 * [Run-Length] Encoded mode
1746 int color
= colors
[*pIn
++];
1747 while (length
-- && x
< (left
+ dstwidth
)) {
1748 if( x
>= left
) XPutPixel(bmpImage
, x
, y
, color
);
1755 * Escape codes (may be an absolute sequence though)
1757 escape_code
= (*pIn
++);
1766 /* Not all RLE8 bitmaps end with this code. For
1767 * example, Paint Shop Pro produces some that don't.
1768 * That's (I think) what caused the previous
1769 * implementation to fail. [JAY]
1778 default: /* switch to absolute mode */
1779 length
= escape_code
;
1782 int color
= colors
[*pIn
++];
1783 if (x
>= (left
+ dstwidth
))
1788 if( x
>= left
) XPutPixel(bmpImage
, x
, y
, color
);
1792 * If you think for a moment you'll realise that the
1793 * only time we could ever possibly read an odd
1794 * number of bytes is when there is a 0x00 (escape),
1795 * a value >0x02 (absolute mode) and then an odd-
1796 * length run. Therefore this is the only place we
1797 * need to worry about it. Everywhere else the
1798 * bytes are always read in pairs. [JAY]
1800 if (escape_code
& 1) pIn
++; /* Throw away the pad byte. */
1802 } /* switch (escape_code) : Escape sequence */
1808 /***********************************************************************
1809 * X11DRV_DIB_SetImageBits_16
1811 * SetDIBits for a 16-bit deep DIB.
1813 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1814 DWORD srcwidth
, DWORD dstwidth
, int left
,
1815 X11DRV_PDEVICE
*physDev
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1816 XImage
*bmpImage
, int linebytes
)
1819 int h
, width
= min(srcwidth
, dstwidth
);
1820 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
1825 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1826 linebytes
= -linebytes
;
1829 switch (bmpImage
->depth
)
1836 srcbits
=srcbits
+left
*2;
1837 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
1839 if (bmpImage
->green_mask
==0x03e0) {
1840 if (gSrc
==bmpImage
->green_mask
) {
1841 if (rSrc
==bmpImage
->red_mask
) {
1842 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
1843 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
1844 convs
->Convert_5x5_asis
1847 dstbits
,-bmpImage
->bytes_per_line
);
1848 } else if (rSrc
==bmpImage
->blue_mask
) {
1849 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
1850 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
1851 convs
->Convert_555_reverse
1854 dstbits
,-bmpImage
->bytes_per_line
);
1857 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
1858 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
1859 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
1860 convs
->Convert_565_to_555_asis
1863 dstbits
,-bmpImage
->bytes_per_line
);
1865 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
1866 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
1867 convs
->Convert_565_to_555_reverse
1870 dstbits
,-bmpImage
->bytes_per_line
);
1873 } else if (bmpImage
->green_mask
==0x07e0) {
1874 if (gSrc
==bmpImage
->green_mask
) {
1875 if (rSrc
==bmpImage
->red_mask
) {
1876 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
1877 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
1878 convs
->Convert_5x5_asis
1881 dstbits
,-bmpImage
->bytes_per_line
);
1883 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
1884 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
1885 convs
->Convert_565_reverse
1888 dstbits
,-bmpImage
->bytes_per_line
);
1891 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
1892 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
1893 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
1894 convs
->Convert_555_to_565_asis
1897 dstbits
,-bmpImage
->bytes_per_line
);
1899 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
1900 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
1901 convs
->Convert_555_to_565_reverse
1904 dstbits
,-bmpImage
->bytes_per_line
);
1914 if (bmpImage
->bits_per_pixel
==24) {
1917 srcbits
=srcbits
+left
*2;
1918 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
1920 if (bmpImage
->green_mask
!=0x00ff00 ||
1921 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1923 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
1924 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
1926 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
1927 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
1928 convs
->Convert_555_to_888_asis
1931 dstbits
,-bmpImage
->bytes_per_line
);
1933 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
1934 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
1935 convs
->Convert_565_to_888_asis
1938 dstbits
,-bmpImage
->bytes_per_line
);
1942 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
1943 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
1944 convs
->Convert_555_to_888_reverse
1947 dstbits
,-bmpImage
->bytes_per_line
);
1949 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
1950 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
1951 convs
->Convert_565_to_888_reverse
1954 dstbits
,-bmpImage
->bytes_per_line
);
1965 srcbits
=srcbits
+left
*2;
1966 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
1968 if (bmpImage
->green_mask
!=0x00ff00 ||
1969 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1971 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
1972 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
1974 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
1975 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
1976 convs
->Convert_555_to_0888_asis
1979 dstbits
,-bmpImage
->bytes_per_line
);
1981 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
1982 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
1983 convs
->Convert_565_to_0888_asis
1986 dstbits
,-bmpImage
->bytes_per_line
);
1990 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
1991 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
1992 convs
->Convert_555_to_0888_reverse
1995 dstbits
,-bmpImage
->bytes_per_line
);
1997 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
1998 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
1999 convs
->Convert_565_to_0888_reverse
2002 dstbits
,-bmpImage
->bytes_per_line
);
2010 WARN("from 16 bit DIB (%x,%x,%x) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2011 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2012 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2018 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
2019 const WORD
* srcpixel
;
2020 int rShift1
,gShift1
,bShift1
;
2021 int rShift2
,gShift2
,bShift2
;
2024 /* Set color scaling values */
2025 rShift1
=16+X11DRV_DIB_MaskToShift(rSrc
)-3;
2026 gShift1
=16+X11DRV_DIB_MaskToShift(gSrc
)-3;
2027 bShift1
=16+X11DRV_DIB_MaskToShift(bSrc
)-3;
2032 /* Green has 5 bits, like the others */
2036 /* Green has 6 bits, not 5. Compensate. */
2045 /* We could split it into four separate cases to optimize
2046 * but it is probably not worth it.
2048 for (h
=lines
-1; h
>=0; h
--) {
2049 srcpixel
=(const WORD
*)srcbits
;
2050 for (x
=left
; x
<width
+left
; x
++) {
2052 BYTE red
,green
,blue
;
2053 srcval
=*srcpixel
++ << 16;
2054 red
= ((srcval
>> rShift1
) & 0xf8) |
2055 ((srcval
>> rShift2
) & 0x07);
2056 green
=((srcval
>> gShift1
) & gMask1
) |
2057 ((srcval
>> gShift2
) & gMask2
);
2058 blue
= ((srcval
>> bShift1
) & 0xf8) |
2059 ((srcval
>> bShift2
) & 0x07);
2060 XPutPixel(bmpImage
, x
, h
,
2061 X11DRV_PALETTE_ToPhysical
2062 (physDev
, RGB(red
,green
,blue
)));
2064 srcbits
+= linebytes
;
2072 /***********************************************************************
2073 * X11DRV_DIB_GetImageBits_16
2075 * GetDIBits for an 16-bit deep DIB.
2077 static void X11DRV_DIB_GetImageBits_16( X11DRV_PDEVICE
*physDev
, int lines
, BYTE
*dstbits
,
2078 DWORD dstwidth
, DWORD srcwidth
,
2079 PALETTEENTRY
*srccolors
,
2080 DWORD rDst
, DWORD gDst
, DWORD bDst
,
2081 XImage
*bmpImage
, int linebytes
)
2084 int h
, width
= min(srcwidth
, dstwidth
);
2085 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
2090 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
2091 linebytes
= -linebytes
;
2094 switch (bmpImage
->depth
)
2099 const char* srcbits
;
2101 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2103 if (bmpImage
->green_mask
==0x03e0) {
2104 if (gDst
==bmpImage
->green_mask
) {
2105 if (rDst
==bmpImage
->red_mask
) {
2106 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
2107 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
2108 convs
->Convert_5x5_asis
2110 srcbits
,-bmpImage
->bytes_per_line
,
2113 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
2114 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
2115 convs
->Convert_555_reverse
2117 srcbits
,-bmpImage
->bytes_per_line
,
2121 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
2122 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
2123 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
2124 convs
->Convert_555_to_565_asis
2126 srcbits
,-bmpImage
->bytes_per_line
,
2129 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
2130 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
2131 convs
->Convert_555_to_565_reverse
2133 srcbits
,-bmpImage
->bytes_per_line
,
2137 } else if (bmpImage
->green_mask
==0x07e0) {
2138 if (gDst
==bmpImage
->green_mask
) {
2139 if (rDst
== bmpImage
->red_mask
) {
2140 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
2141 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
2142 convs
->Convert_5x5_asis
2144 srcbits
,-bmpImage
->bytes_per_line
,
2147 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
2148 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
2149 convs
->Convert_565_reverse
2151 srcbits
,-bmpImage
->bytes_per_line
,
2155 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
2156 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
2157 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
2158 convs
->Convert_565_to_555_asis
2160 srcbits
,-bmpImage
->bytes_per_line
,
2163 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
2164 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
2165 convs
->Convert_565_to_555_reverse
2167 srcbits
,-bmpImage
->bytes_per_line
,
2178 if (bmpImage
->bits_per_pixel
== 24) {
2179 const char* srcbits
;
2181 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2183 if (bmpImage
->green_mask
!=0x00ff00 ||
2184 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2186 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
2187 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
2189 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
2190 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
2191 convs
->Convert_888_to_555_asis
2193 srcbits
,-bmpImage
->bytes_per_line
,
2196 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2197 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2198 convs
->Convert_888_to_565_asis
2200 srcbits
,-bmpImage
->bytes_per_line
,
2205 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
2206 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
2207 convs
->Convert_888_to_555_reverse
2209 srcbits
,-bmpImage
->bytes_per_line
,
2212 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
2213 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
2214 convs
->Convert_888_to_565_reverse
2216 srcbits
,-bmpImage
->bytes_per_line
,
2226 const char* srcbits
;
2228 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2230 if (bmpImage
->green_mask
!=0x00ff00 ||
2231 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2233 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
2234 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
2236 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
2237 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
2238 convs
->Convert_0888_to_555_asis
2240 srcbits
,-bmpImage
->bytes_per_line
,
2243 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
2244 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
2245 convs
->Convert_0888_to_565_asis
2247 srcbits
,-bmpImage
->bytes_per_line
,
2252 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
2253 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
2254 convs
->Convert_0888_to_555_reverse
2256 srcbits
,-bmpImage
->bytes_per_line
,
2259 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
2260 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
2261 convs
->Convert_0888_to_565_reverse
2263 srcbits
,-bmpImage
->bytes_per_line
,
2272 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
2274 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
2275 int rShift
,gShift
,bShift
;
2278 /* Shift everything 16 bits left so that all shifts are >0,
2279 * even for BGR DIBs. Then a single >> 16 will bring everything
2282 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2283 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2284 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2286 /* 6 bits for the green */
2292 for (h
= lines
- 1; h
>= 0; h
--) {
2293 dstpixel
=(LPWORD
)dstbits
;
2294 for (x
= 0; x
< width
; x
++) {
2295 PALETTEENTRY srcval
;
2297 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2298 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
2299 ((srcval
.peGreen
<< gShift
) & gDst
) |
2300 ((srcval
.peBlue
<< bShift
) & bDst
);
2301 *dstpixel
++=dstval
>> 16;
2303 dstbits
+= linebytes
;
2311 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
2313 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
2314 int rShift
,gShift
,bShift
;
2315 const BYTE
* srcbits
;
2316 const BYTE
* srcpixel
;
2319 /* Shift everything 16 bits left so that all shifts are >0,
2320 * even for BGR DIBs. Then a single >> 16 will bring everything
2323 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2324 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2325 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2327 /* 6 bits for the green */
2333 srcbits
=(BYTE
*)bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2334 for (h
=0; h
<lines
; h
++) {
2336 dstpixel
=(LPWORD
)dstbits
;
2337 for (x
= 0; x
< width
; x
++) {
2338 PALETTEENTRY srcval
;
2340 srcval
=srccolors
[*srcpixel
++];
2341 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
2342 ((srcval
.peGreen
<< gShift
) & gDst
) |
2343 ((srcval
.peBlue
<< bShift
) & bDst
);
2344 *dstpixel
++=dstval
>> 16;
2346 srcbits
-= bmpImage
->bytes_per_line
;
2347 dstbits
+= linebytes
;
2357 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
2358 int rShift
,gShift
,bShift
;
2361 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%x,%x,%x)\n",
2362 bmpImage
->depth
, bmpImage
->red_mask
,
2363 bmpImage
->green_mask
, bmpImage
->blue_mask
,
2366 /* Shift everything 16 bits left so that all shifts are >0,
2367 * even for BGR DIBs. Then a single >> 16 will bring everything
2370 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2371 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2372 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2374 /* 6 bits for the green */
2380 for (h
= lines
- 1; h
>= 0; h
--) {
2381 dstpixel
=(LPWORD
)dstbits
;
2382 for (x
= 0; x
< width
; x
++) {
2385 srcval
=X11DRV_PALETTE_ToLogical(physDev
, XGetPixel(bmpImage
, x
, h
));
2386 dstval
=((GetRValue(srcval
) << rShift
) & rDst
) |
2387 ((GetGValue(srcval
) << gShift
) & gDst
) |
2388 ((GetBValue(srcval
) << bShift
) & bDst
);
2389 *dstpixel
++=dstval
>> 16;
2391 dstbits
+= linebytes
;
2399 /***********************************************************************
2400 * X11DRV_DIB_SetImageBits_24
2402 * SetDIBits for a 24-bit deep DIB.
2404 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
2405 DWORD srcwidth
, DWORD dstwidth
, int left
,
2406 X11DRV_PDEVICE
*physDev
,
2407 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2408 XImage
*bmpImage
, DWORD linebytes
)
2411 int h
, width
= min(srcwidth
, dstwidth
);
2412 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
2417 srcbits
= srcbits
+ linebytes
* (lines
- 1);
2418 linebytes
= -linebytes
;
2421 switch (bmpImage
->depth
)
2424 if (bmpImage
->bits_per_pixel
==24) {
2427 srcbits
=srcbits
+left
*3;
2428 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
2430 if (bmpImage
->green_mask
!=0x00ff00 ||
2431 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2433 } else if (rSrc
==bmpImage
->red_mask
) {
2434 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
2435 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
2436 convs
->Convert_888_asis
2439 dstbits
,-bmpImage
->bytes_per_line
);
2441 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
2442 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
2443 convs
->Convert_888_reverse
2446 dstbits
,-bmpImage
->bytes_per_line
);
2456 srcbits
=srcbits
+left
*3;
2457 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2459 if (bmpImage
->green_mask
!=0x00ff00 ||
2460 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2462 } else if (rSrc
==bmpImage
->red_mask
) {
2463 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
2464 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
2465 convs
->Convert_888_to_0888_asis
2468 dstbits
,-bmpImage
->bytes_per_line
);
2470 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
2471 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
2472 convs
->Convert_888_to_0888_reverse
2475 dstbits
,-bmpImage
->bytes_per_line
);
2485 srcbits
=srcbits
+left
*3;
2486 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2488 if (bmpImage
->green_mask
==0x03e0) {
2489 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
2490 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
2491 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
2492 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
2493 convs
->Convert_888_to_555_asis
2496 dstbits
,-bmpImage
->bytes_per_line
);
2497 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0x7f00) ||
2498 (bSrc
==0xff && bmpImage
->blue_mask
==0x7f00)) {
2499 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
2500 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
2501 convs
->Convert_888_to_555_reverse
2504 dstbits
,-bmpImage
->bytes_per_line
);
2508 } else if (bmpImage
->green_mask
==0x07e0) {
2509 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
2510 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
2511 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
2512 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
2513 convs
->Convert_888_to_565_asis
2516 dstbits
,-bmpImage
->bytes_per_line
);
2517 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0xf800) ||
2518 (bSrc
==0xff && bmpImage
->blue_mask
==0xf800)) {
2519 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
2520 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
2521 convs
->Convert_888_to_565_reverse
2524 dstbits
,-bmpImage
->bytes_per_line
);
2536 WARN("from 24 bit DIB (%x,%x,%x) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2537 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2538 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2544 /* ==== rgb 888 dib -> any bmp format ==== */
2545 const BYTE
* srcbyte
;
2547 /* Windows only supports one 24bpp DIB format: RGB888 */
2549 for (h
= lines
- 1; h
>= 0; h
--) {
2551 for (x
= left
; x
< width
+left
; x
++) {
2552 XPutPixel(bmpImage
, x
, h
,
2553 X11DRV_PALETTE_ToPhysical
2554 (physDev
, RGB(srcbyte
[2], srcbyte
[1], srcbyte
[0])));
2557 srcbits
+= linebytes
;
2565 /***********************************************************************
2566 * X11DRV_DIB_GetImageBits_24
2568 * GetDIBits for an 24-bit deep DIB.
2570 static void X11DRV_DIB_GetImageBits_24( X11DRV_PDEVICE
*physDev
, int lines
, BYTE
*dstbits
,
2571 DWORD dstwidth
, DWORD srcwidth
,
2572 PALETTEENTRY
*srccolors
,
2573 DWORD rDst
, DWORD gDst
, DWORD bDst
,
2574 XImage
*bmpImage
, DWORD linebytes
)
2577 int h
, width
= min(srcwidth
, dstwidth
);
2578 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
2583 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2584 linebytes
= -linebytes
;
2587 switch (bmpImage
->depth
)
2590 if (bmpImage
->bits_per_pixel
==24) {
2591 const char* srcbits
;
2593 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2595 if (bmpImage
->green_mask
!=0x00ff00 ||
2596 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2598 } else if (rDst
==bmpImage
->red_mask
) {
2599 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
2600 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
2601 convs
->Convert_888_asis
2603 srcbits
,-bmpImage
->bytes_per_line
,
2606 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
2607 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
2608 convs
->Convert_888_reverse
2610 srcbits
,-bmpImage
->bytes_per_line
,
2619 const char* srcbits
;
2621 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2623 if (bmpImage
->green_mask
!=0x00ff00 ||
2624 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2626 } else if (rDst
==bmpImage
->red_mask
) {
2627 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2628 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2629 convs
->Convert_0888_to_888_asis
2631 srcbits
,-bmpImage
->bytes_per_line
,
2634 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
2635 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
2636 convs
->Convert_0888_to_888_reverse
2638 srcbits
,-bmpImage
->bytes_per_line
,
2647 const char* srcbits
;
2649 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2651 if (bmpImage
->green_mask
==0x03e0) {
2652 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
2653 (bDst
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
2654 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
2655 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
2656 convs
->Convert_555_to_888_asis
2658 srcbits
,-bmpImage
->bytes_per_line
,
2660 } else if ((rDst
==0xff && bmpImage
->red_mask
==0x7f00) ||
2661 (bDst
==0xff && bmpImage
->blue_mask
==0x7f00)) {
2662 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
2663 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
2664 convs
->Convert_555_to_888_reverse
2666 srcbits
,-bmpImage
->bytes_per_line
,
2671 } else if (bmpImage
->green_mask
==0x07e0) {
2672 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
2673 (bDst
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
2674 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
2675 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
2676 convs
->Convert_565_to_888_asis
2678 srcbits
,-bmpImage
->bytes_per_line
,
2680 } else if ((rDst
==0xff && bmpImage
->red_mask
==0xf800) ||
2681 (bDst
==0xff && bmpImage
->blue_mask
==0xf800)) {
2682 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
2683 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
2684 convs
->Convert_565_to_888_reverse
2686 srcbits
,-bmpImage
->bytes_per_line
,
2699 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
2701 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
2704 /* Windows only supports one 24bpp DIB format: rgb 888 */
2705 for (h
= lines
- 1; h
>= 0; h
--) {
2707 for (x
= 0; x
< width
; x
++) {
2708 PALETTEENTRY srcval
;
2709 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2710 dstbyte
[0]=srcval
.peBlue
;
2711 dstbyte
[1]=srcval
.peGreen
;
2712 dstbyte
[2]=srcval
.peRed
;
2715 dstbits
+= linebytes
;
2723 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
2725 /* ==== pal 8 bmp -> rgb 888 dib ==== */
2726 const void* srcbits
;
2727 const BYTE
* srcpixel
;
2730 /* Windows only supports one 24bpp DIB format: rgb 888 */
2731 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2732 for (h
= lines
- 1; h
>= 0; h
--) {
2735 for (x
= 0; x
< width
; x
++ ) {
2736 PALETTEENTRY srcval
;
2737 srcval
=srccolors
[*srcpixel
++];
2738 dstbyte
[0]=srcval
.peBlue
;
2739 dstbyte
[1]=srcval
.peGreen
;
2740 dstbyte
[2]=srcval
.peRed
;
2743 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
2744 dstbits
+= linebytes
;
2754 /* ==== any bmp format -> 888 dib ==== */
2757 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%x,%x,%x)\n",
2758 bmpImage
->depth
, bmpImage
->red_mask
,
2759 bmpImage
->green_mask
, bmpImage
->blue_mask
,
2762 /* Windows only supports one 24bpp DIB format: rgb 888 */
2763 for (h
= lines
- 1; h
>= 0; h
--) {
2765 for (x
= 0; x
< width
; x
++) {
2766 COLORREF srcval
=X11DRV_PALETTE_ToLogical
2767 (physDev
, XGetPixel( bmpImage
, x
, h
));
2768 dstbyte
[0]=GetBValue(srcval
);
2769 dstbyte
[1]=GetGValue(srcval
);
2770 dstbyte
[2]=GetRValue(srcval
);
2773 dstbits
+= linebytes
;
2781 /***********************************************************************
2782 * X11DRV_DIB_SetImageBits_32
2784 * SetDIBits for a 32-bit deep DIB.
2786 static void X11DRV_DIB_SetImageBits_32(int lines
, const BYTE
*srcbits
,
2787 DWORD srcwidth
, DWORD dstwidth
, int left
,
2788 X11DRV_PDEVICE
*physDev
,
2789 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2794 int h
, width
= min(srcwidth
, dstwidth
);
2795 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
2800 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2801 linebytes
= -linebytes
;
2804 switch (bmpImage
->depth
)
2807 if (bmpImage
->bits_per_pixel
==24) {
2810 srcbits
=srcbits
+left
*4;
2811 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
2813 if (rSrc
==bmpImage
->red_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->blue_mask
) {
2814 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
2815 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
2816 convs
->Convert_0888_to_888_asis
2819 dstbits
,-bmpImage
->bytes_per_line
);
2820 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2821 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2823 /* the tests below assume sane bmpImage masks */
2824 } else if (rSrc
==bmpImage
->blue_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->red_mask
) {
2825 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
2826 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
2827 convs
->Convert_0888_to_888_reverse
2830 dstbits
,-bmpImage
->bytes_per_line
);
2831 } else if (bmpImage
->blue_mask
==0xff) {
2832 /* ==== any 0888 dib -> rgb 888 bmp ==== */
2833 convs
->Convert_any0888_to_rgb888
2837 dstbits
,-bmpImage
->bytes_per_line
);
2839 /* ==== any 0888 dib -> bgr 888 bmp ==== */
2840 convs
->Convert_any0888_to_bgr888
2844 dstbits
,-bmpImage
->bytes_per_line
);
2854 srcbits
=srcbits
+left
*4;
2855 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2857 if (gSrc
==bmpImage
->green_mask
) {
2858 if (rSrc
==bmpImage
->red_mask
&& bSrc
==bmpImage
->blue_mask
) {
2859 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
2860 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
2861 convs
->Convert_0888_asis
2864 dstbits
,-bmpImage
->bytes_per_line
);
2865 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2866 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2868 /* the tests below assume sane bmpImage masks */
2869 } else if (rSrc
==bmpImage
->blue_mask
&& bSrc
==bmpImage
->red_mask
) {
2870 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
2871 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
2872 convs
->Convert_0888_reverse
2875 dstbits
,-bmpImage
->bytes_per_line
);
2877 /* ==== any 0888 dib -> any 0888 bmp ==== */
2878 convs
->Convert_0888_any
2882 dstbits
,-bmpImage
->bytes_per_line
,
2883 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2885 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2886 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2888 /* the tests below assume sane bmpImage masks */
2890 /* ==== any 0888 dib -> any 0888 bmp ==== */
2891 convs
->Convert_0888_any
2895 dstbits
,-bmpImage
->bytes_per_line
,
2896 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2906 srcbits
=srcbits
+left
*4;
2907 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2909 if (rSrc
==0xff0000 && gSrc
==0x00ff00 && bSrc
==0x0000ff) {
2910 if (bmpImage
->green_mask
==0x03e0) {
2911 if (bmpImage
->red_mask
==0x7f00) {
2912 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
2913 convs
->Convert_0888_to_555_asis
2916 dstbits
,-bmpImage
->bytes_per_line
);
2917 } else if (bmpImage
->blue_mask
==0x7f00) {
2918 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
2919 convs
->Convert_0888_to_555_reverse
2922 dstbits
,-bmpImage
->bytes_per_line
);
2926 } else if (bmpImage
->green_mask
==0x07e0) {
2927 if (bmpImage
->red_mask
==0xf800) {
2928 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
2929 convs
->Convert_0888_to_565_asis
2932 dstbits
,-bmpImage
->bytes_per_line
);
2933 } else if (bmpImage
->blue_mask
==0xf800) {
2934 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
2935 convs
->Convert_0888_to_565_reverse
2938 dstbits
,-bmpImage
->bytes_per_line
);
2945 } else if (rSrc
==0x0000ff && gSrc
==0x00ff00 && bSrc
==0xff0000) {
2946 if (bmpImage
->green_mask
==0x03e0) {
2947 if (bmpImage
->blue_mask
==0x7f00) {
2948 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
2949 convs
->Convert_0888_to_555_asis
2952 dstbits
,-bmpImage
->bytes_per_line
);
2953 } else if (bmpImage
->red_mask
==0x7f00) {
2954 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
2955 convs
->Convert_0888_to_555_reverse
2958 dstbits
,-bmpImage
->bytes_per_line
);
2962 } else if (bmpImage
->green_mask
==0x07e0) {
2963 if (bmpImage
->blue_mask
==0xf800) {
2964 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
2965 convs
->Convert_0888_to_565_asis
2968 dstbits
,-bmpImage
->bytes_per_line
);
2969 } else if (bmpImage
->red_mask
==0xf800) {
2970 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
2971 convs
->Convert_0888_to_565_reverse
2974 dstbits
,-bmpImage
->bytes_per_line
);
2982 if (bmpImage
->green_mask
==0x03e0 &&
2983 (bmpImage
->red_mask
==0x7f00 ||
2984 bmpImage
->blue_mask
==0x7f00)) {
2985 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
2986 convs
->Convert_any0888_to_5x5
2990 dstbits
,-bmpImage
->bytes_per_line
,
2991 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2992 } else if (bmpImage
->green_mask
==0x07e0 &&
2993 (bmpImage
->red_mask
==0xf800 ||
2994 bmpImage
->blue_mask
==0xf800)) {
2995 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
2996 convs
->Convert_any0888_to_5x5
3000 dstbits
,-bmpImage
->bytes_per_line
,
3001 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3011 WARN("from 32 bit DIB (%x,%x,%x) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3012 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
3013 bmpImage
->green_mask
, bmpImage
->blue_mask
);
3019 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
3020 const DWORD
* srcpixel
;
3021 int rShift
,gShift
,bShift
;
3023 rShift
=X11DRV_DIB_MaskToShift(rSrc
);
3024 gShift
=X11DRV_DIB_MaskToShift(gSrc
);
3025 bShift
=X11DRV_DIB_MaskToShift(bSrc
);
3027 for (h
= lines
- 1; h
>= 0; h
--) {
3028 srcpixel
=(const DWORD
*)srcbits
;
3029 for (x
= left
; x
< width
+left
; x
++) {
3031 BYTE red
,green
,blue
;
3032 srcvalue
=*srcpixel
++;
3033 red
= (srcvalue
>> rShift
) & 0xff;
3034 green
=(srcvalue
>> gShift
) & 0xff;
3035 blue
= (srcvalue
>> bShift
) & 0xff;
3036 XPutPixel(bmpImage
, x
, h
, X11DRV_PALETTE_ToPhysical
3037 (physDev
, RGB(red
,green
,blue
)));
3039 srcbits
+= linebytes
;
3047 /***********************************************************************
3048 * X11DRV_DIB_GetImageBits_32
3050 * GetDIBits for an 32-bit deep DIB.
3052 static void X11DRV_DIB_GetImageBits_32( X11DRV_PDEVICE
*physDev
, int lines
, BYTE
*dstbits
,
3053 DWORD dstwidth
, DWORD srcwidth
,
3054 PALETTEENTRY
*srccolors
,
3055 DWORD rDst
, DWORD gDst
, DWORD bDst
,
3056 XImage
*bmpImage
, int linebytes
)
3059 int h
, width
= min(srcwidth
, dstwidth
);
3060 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
3065 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
3066 linebytes
= -linebytes
;
3069 switch (bmpImage
->depth
)
3072 if (bmpImage
->bits_per_pixel
==24) {
3073 const void* srcbits
;
3075 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3077 if (rDst
==bmpImage
->red_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->blue_mask
) {
3078 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3079 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3080 convs
->Convert_888_to_0888_asis
3082 srcbits
,-bmpImage
->bytes_per_line
,
3084 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3085 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3087 /* the tests below assume sane bmpImage masks */
3088 } else if (rDst
==bmpImage
->blue_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->red_mask
) {
3089 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3090 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3091 convs
->Convert_888_to_0888_reverse
3093 srcbits
,-bmpImage
->bytes_per_line
,
3095 } else if (bmpImage
->blue_mask
==0xff) {
3096 /* ==== rgb 888 bmp -> any 0888 dib ==== */
3097 convs
->Convert_rgb888_to_any0888
3099 srcbits
,-bmpImage
->bytes_per_line
,
3103 /* ==== bgr 888 bmp -> any 0888 dib ==== */
3104 convs
->Convert_bgr888_to_any0888
3106 srcbits
,-bmpImage
->bytes_per_line
,
3116 const char* srcbits
;
3118 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3120 if (gDst
==bmpImage
->green_mask
) {
3121 if (rDst
==bmpImage
->red_mask
&& bDst
==bmpImage
->blue_mask
) {
3122 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
3123 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
3124 convs
->Convert_0888_asis
3126 srcbits
,-bmpImage
->bytes_per_line
,
3128 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3129 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3131 /* the tests below assume sane bmpImage masks */
3132 } else if (rDst
==bmpImage
->blue_mask
&& bDst
==bmpImage
->red_mask
) {
3133 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
3134 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
3135 convs
->Convert_0888_reverse
3137 srcbits
,-bmpImage
->bytes_per_line
,
3140 /* ==== any 0888 bmp -> any 0888 dib ==== */
3141 convs
->Convert_0888_any
3143 srcbits
,-bmpImage
->bytes_per_line
,
3144 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3148 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3149 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3151 /* the tests below assume sane bmpImage masks */
3153 /* ==== any 0888 bmp -> any 0888 dib ==== */
3154 convs
->Convert_0888_any
3156 srcbits
,-bmpImage
->bytes_per_line
,
3157 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3167 const char* srcbits
;
3169 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3171 if (rDst
==0xff0000 && gDst
==0x00ff00 && bDst
==0x0000ff) {
3172 if (bmpImage
->green_mask
==0x03e0) {
3173 if (bmpImage
->red_mask
==0x7f00) {
3174 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
3175 convs
->Convert_555_to_0888_asis
3177 srcbits
,-bmpImage
->bytes_per_line
,
3179 } else if (bmpImage
->blue_mask
==0x7f00) {
3180 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
3181 convs
->Convert_555_to_0888_reverse
3183 srcbits
,-bmpImage
->bytes_per_line
,
3188 } else if (bmpImage
->green_mask
==0x07e0) {
3189 if (bmpImage
->red_mask
==0xf800) {
3190 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
3191 convs
->Convert_565_to_0888_asis
3193 srcbits
,-bmpImage
->bytes_per_line
,
3195 } else if (bmpImage
->blue_mask
==0xf800) {
3196 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
3197 convs
->Convert_565_to_0888_reverse
3199 srcbits
,-bmpImage
->bytes_per_line
,
3207 } else if (rDst
==0x0000ff && gDst
==0x00ff00 && bDst
==0xff0000) {
3208 if (bmpImage
->green_mask
==0x03e0) {
3209 if (bmpImage
->blue_mask
==0x7f00) {
3210 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
3211 convs
->Convert_555_to_0888_asis
3213 srcbits
,-bmpImage
->bytes_per_line
,
3215 } else if (bmpImage
->red_mask
==0x7f00) {
3216 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
3217 convs
->Convert_555_to_0888_reverse
3219 srcbits
,-bmpImage
->bytes_per_line
,
3224 } else if (bmpImage
->green_mask
==0x07e0) {
3225 if (bmpImage
->blue_mask
==0xf800) {
3226 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
3227 convs
->Convert_565_to_0888_asis
3229 srcbits
,-bmpImage
->bytes_per_line
,
3231 } else if (bmpImage
->red_mask
==0xf800) {
3232 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
3233 convs
->Convert_565_to_0888_reverse
3235 srcbits
,-bmpImage
->bytes_per_line
,
3244 if (bmpImage
->green_mask
==0x03e0 &&
3245 (bmpImage
->red_mask
==0x7f00 ||
3246 bmpImage
->blue_mask
==0x7f00)) {
3247 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
3248 convs
->Convert_5x5_to_any0888
3250 srcbits
,-bmpImage
->bytes_per_line
,
3251 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3254 } else if (bmpImage
->green_mask
==0x07e0 &&
3255 (bmpImage
->red_mask
==0xf800 ||
3256 bmpImage
->blue_mask
==0xf800)) {
3257 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
3258 convs
->Convert_5x5_to_any0888
3260 srcbits
,-bmpImage
->bytes_per_line
,
3261 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3273 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
3275 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
3276 int rShift
,gShift
,bShift
;
3279 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3280 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3281 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3282 for (h
= lines
- 1; h
>= 0; h
--) {
3283 dstpixel
=(DWORD
*)dstbits
;
3284 for (x
= 0; x
< width
; x
++) {
3285 PALETTEENTRY srcval
;
3286 srcval
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
3287 *dstpixel
++=(srcval
.peRed
<< rShift
) |
3288 (srcval
.peGreen
<< gShift
) |
3289 (srcval
.peBlue
<< bShift
);
3291 dstbits
+= linebytes
;
3299 if (X11DRV_DIB_CheckMask(bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
)
3301 /* ==== pal 8 bmp -> any 0888 dib ==== */
3302 int rShift
,gShift
,bShift
;
3303 const void* srcbits
;
3304 const BYTE
* srcpixel
;
3307 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3308 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3309 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3310 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3311 for (h
= lines
- 1; h
>= 0; h
--) {
3313 dstpixel
=(DWORD
*)dstbits
;
3314 for (x
= 0; x
< width
; x
++) {
3315 PALETTEENTRY srcval
;
3316 srcval
=srccolors
[*srcpixel
++];
3317 *dstpixel
++=(srcval
.peRed
<< rShift
) |
3318 (srcval
.peGreen
<< gShift
) |
3319 (srcval
.peBlue
<< bShift
);
3321 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
3322 dstbits
+= linebytes
;
3332 /* ==== any bmp format -> any 0888 dib ==== */
3333 int rShift
,gShift
,bShift
;
3336 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%x,%x,%x)\n",
3337 bmpImage
->depth
, bmpImage
->red_mask
,
3338 bmpImage
->green_mask
, bmpImage
->blue_mask
,
3341 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3342 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3343 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3344 for (h
= lines
- 1; h
>= 0; h
--) {
3345 dstpixel
=(DWORD
*)dstbits
;
3346 for (x
= 0; x
< width
; x
++) {
3348 srcval
=X11DRV_PALETTE_ToLogical(physDev
, XGetPixel(bmpImage
, x
, h
));
3349 *dstpixel
++=(GetRValue(srcval
) << rShift
) |
3350 (GetGValue(srcval
) << gShift
) |
3351 (GetBValue(srcval
) << bShift
);
3353 dstbits
+= linebytes
;
3360 static int XGetSubImageErrorHandler(Display
*dpy
, XErrorEvent
*event
, void *arg
)
3362 return (event
->request_code
== X_GetImage
&& event
->error_code
== BadMatch
);
3365 /***********************************************************************
3366 * X11DRV_DIB_SetImageBits_GetSubImage
3368 * Helper for X11DRV_DIB_SetImageBits
3370 static void X11DRV_DIB_SetImageBits_GetSubImage(
3371 const X11DRV_DIB_IMAGEBITS_DESCR
*descr
, XImage
*bmpImage
)
3373 /* compressed bitmaps may contain gaps in them. So make a copy
3374 * of the existing pixels first */
3377 SetRect( &bmprc
, descr
->xDest
, descr
->yDest
,
3378 descr
->xDest
+ descr
->width
, descr
->yDest
+ descr
->height
);
3379 GetRgnBox( descr
->physDev
->region
, &rc
);
3380 /* convert from dc to drawable origin */
3381 OffsetRect( &rc
, descr
->physDev
->dc_rect
.left
, descr
->physDev
->dc_rect
.top
);
3382 /* clip visible rect with bitmap */
3383 if( IntersectRect( &rc
, &rc
, &bmprc
))
3385 X11DRV_expect_error( gdi_display
, XGetSubImageErrorHandler
, NULL
);
3386 XGetSubImage( gdi_display
, descr
->drawable
, rc
.left
, rc
.top
,
3387 rc
.right
- rc
.left
, rc
.bottom
- rc
.top
, AllPlanes
,
3389 descr
->xSrc
+ rc
.left
- bmprc
.left
,
3390 descr
->ySrc
+ rc
.top
- bmprc
.top
);
3391 X11DRV_check_error();
3395 /***********************************************************************
3396 * X11DRV_DIB_SetImageBits
3398 * Transfer the bits to an X image.
3399 * Helper function for SetDIBits() and SetDIBitsToDevice().
3401 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
3403 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
3404 void *old_data
= NULL
;
3409 bmpImage
= descr
->image
;
3411 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
3412 descr
->infoWidth
, lines
, 32, 0 );
3413 bmpImage
->data
= HeapAlloc( GetProcessHeap(), 0, lines
* bmpImage
->bytes_per_line
);
3414 if(bmpImage
->data
== NULL
) {
3415 ERR("Out of memory!\n");
3416 XDestroyImage( bmpImage
);
3417 wine_tsx11_unlock();
3422 bmpImage
->red_mask
= descr
->shifts
->physicalRed
.max
<< descr
->shifts
->physicalRed
.shift
;
3423 bmpImage
->green_mask
= descr
->shifts
->physicalGreen
.max
<< descr
->shifts
->physicalGreen
.shift
;
3424 bmpImage
->blue_mask
= descr
->shifts
->physicalBlue
.max
<< descr
->shifts
->physicalBlue
.shift
;
3427 wine_tsx11_unlock();
3429 TRACE("Dib: depth=%d r=%x g=%x b=%x\n",
3430 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
3431 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
3432 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
3433 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3435 #ifdef HAVE_LIBXXSHM
3436 if (descr
->shm_mode
== X11DRV_SHM_PIXMAP
3437 && descr
->xSrc
== 0 && descr
->ySrc
== 0
3438 && descr
->xDest
== 0 && descr
->yDest
== 0)
3440 TRACE("Using the shared pixmap data.\n");
3443 XSync( gdi_display
, False
);
3444 wine_tsx11_unlock();
3446 old_data
= descr
->image
->data
;
3447 descr
->image
->data
= descr
->physBitmap
->shminfo
.shmaddr
;
3451 /* Transfer the pixels */
3454 switch(descr
->infoBpp
)
3457 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
3458 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
3459 bmpImage
, descr
->dibpitch
);
3462 if (descr
->compression
) {
3463 X11DRV_DIB_SetImageBits_GetSubImage( descr
, bmpImage
);
3464 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
3465 descr
->infoWidth
, descr
->width
,
3466 descr
->xSrc
, (int *)(descr
->colorMap
),
3469 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
3470 descr
->infoWidth
, descr
->width
,
3471 descr
->xSrc
, (int*)(descr
->colorMap
),
3472 bmpImage
, descr
->dibpitch
);
3475 if (descr
->compression
) {
3476 X11DRV_DIB_SetImageBits_GetSubImage( descr
, bmpImage
);
3477 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
3478 descr
->infoWidth
, descr
->width
,
3479 descr
->xSrc
, (int *)(descr
->colorMap
),
3482 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
3483 descr
->infoWidth
, descr
->width
,
3484 descr
->xSrc
, (int *)(descr
->colorMap
),
3485 bmpImage
, descr
->dibpitch
);
3489 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
3490 descr
->infoWidth
, descr
->width
,
3491 descr
->xSrc
, descr
->physDev
,
3492 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3493 bmpImage
, descr
->dibpitch
);
3496 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
3497 descr
->infoWidth
, descr
->width
,
3498 descr
->xSrc
, descr
->physDev
,
3499 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3500 bmpImage
, descr
->dibpitch
);
3503 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
3504 descr
->infoWidth
, descr
->width
,
3505 descr
->xSrc
, descr
->physDev
,
3506 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3507 bmpImage
, descr
->dibpitch
);
3510 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
3516 WARN( "invalid bits pointer %p\n", descr
->bits
);
3521 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
3522 descr
->drawable
, descr
->gc
, bmpImage
,
3523 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3524 descr
->width
, descr
->height
);
3529 #ifdef HAVE_LIBXXSHM
3530 if (descr
->shm_mode
== X11DRV_SHM_PIXMAP
3531 && descr
->xSrc
== 0 && descr
->ySrc
== 0
3532 && descr
->xDest
== 0 && descr
->yDest
== 0)
3534 XSync( gdi_display
, False
);
3536 else if (descr
->shm_mode
== X11DRV_SHM_IMAGE
&& descr
->image
)
3538 XShmPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
3539 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3540 descr
->width
, descr
->height
, FALSE
);
3541 XSync( gdi_display
, 0 );
3546 XPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
3547 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3548 descr
->width
, descr
->height
);
3552 if (old_data
) descr
->image
->data
= old_data
;
3554 if (!descr
->image
) X11DRV_DIB_DestroyXImage( bmpImage
);
3555 wine_tsx11_unlock();
3559 /***********************************************************************
3560 * X11DRV_DIB_GetImageBits
3562 * Transfer the bits from an X image.
3564 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
3566 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
3567 void *old_data
= NULL
;
3572 bmpImage
= descr
->image
;
3574 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
3575 descr
->infoWidth
, lines
, 32, 0 );
3576 bmpImage
->data
= HeapAlloc( GetProcessHeap(), 0, lines
* bmpImage
->bytes_per_line
);
3577 if(bmpImage
->data
== NULL
) {
3578 ERR("Out of memory!\n");
3579 XDestroyImage( bmpImage
);
3580 wine_tsx11_unlock();
3585 bmpImage
->red_mask
= descr
->shifts
->physicalRed
.max
<< descr
->shifts
->physicalRed
.shift
;
3586 bmpImage
->green_mask
= descr
->shifts
->physicalGreen
.max
<< descr
->shifts
->physicalGreen
.shift
;
3587 bmpImage
->blue_mask
= descr
->shifts
->physicalBlue
.max
<< descr
->shifts
->physicalBlue
.shift
;
3591 #ifdef HAVE_LIBXXSHM
3593 /* We must not call XShmGetImage() with a bitmap which is bigger than the available area.
3594 If we do, XShmGetImage() will fail (X exception), as it checks for this internally. */
3595 if (descr
->shm_mode
== X11DRV_SHM_PIXMAP
&& descr
->image
3596 && descr
->xSrc
== 0 && descr
->ySrc
== 0
3597 && descr
->xDest
== 0 && descr
->yDest
== 0
3598 && bmpImage
->width
<= (descr
->width
- descr
->xSrc
)
3599 && bmpImage
->height
<= (descr
->height
- descr
->ySrc
))
3601 XSync( gdi_display
, False
);
3602 old_data
= bmpImage
->data
;
3603 bmpImage
->data
= descr
->physBitmap
->shminfo
.shmaddr
;
3604 TRACE("Using shared pixmap data.\n");
3606 else if (descr
->shm_mode
== X11DRV_SHM_IMAGE
&& descr
->image
3607 && bmpImage
->width
<= (descr
->width
- descr
->xSrc
)
3608 && bmpImage
->height
<= (descr
->height
- descr
->ySrc
))
3610 int saveRed
, saveGreen
, saveBlue
;
3612 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
3613 gdi_display
, descr
->drawable
, bmpImage
,
3614 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
3616 /* We must save and restore the bmpImage's masks in order
3617 * to preserve them across the call to XShmGetImage, which
3618 * decides to eliminate them since it doesn't happen to know
3619 * what the format of the image is supposed to be, even though
3621 saveRed
= bmpImage
->red_mask
;
3622 saveBlue
= bmpImage
->blue_mask
;
3623 saveGreen
= bmpImage
->green_mask
;
3625 XShmGetImage( gdi_display
, descr
->drawable
, bmpImage
,
3626 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
3628 bmpImage
->red_mask
= saveRed
;
3629 bmpImage
->blue_mask
= saveBlue
;
3630 bmpImage
->green_mask
= saveGreen
;
3633 #endif /* HAVE_LIBXXSHM */
3635 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
3636 gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
, descr
->width
,
3637 lines
, AllPlanes
, ZPixmap
, bmpImage
, descr
->xDest
, descr
->yDest
);
3638 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
3639 descr
->width
, lines
, AllPlanes
, ZPixmap
,
3640 bmpImage
, descr
->xDest
, descr
->yDest
);
3642 wine_tsx11_unlock();
3644 TRACE("Dib: depth=%2d r=%x g=%x b=%x\n",
3645 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
3646 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
3647 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
3648 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3649 /* Transfer the pixels */
3650 switch(descr
->infoBpp
)
3653 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
3654 descr
->infoWidth
, descr
->width
,
3655 descr
->colorMap
, descr
->palentry
,
3656 bmpImage
, descr
->dibpitch
);
3660 if (descr
->compression
) {
3661 FIXME("Compression not yet supported!\n");
3662 if(descr
->sizeImage
< X11DRV_DIB_GetDIBWidthBytes( descr
->infoWidth
, 4 ) * abs(descr
->lines
))
3665 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
3666 descr
->infoWidth
, descr
->width
,
3667 descr
->colorMap
, descr
->palentry
,
3668 bmpImage
, descr
->dibpitch
);
3671 if (descr
->compression
) {
3672 FIXME("Compression not yet supported!\n");
3673 if(descr
->sizeImage
< X11DRV_DIB_GetDIBWidthBytes( descr
->infoWidth
, 8 ) * abs(descr
->lines
))
3676 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
3677 descr
->infoWidth
, descr
->width
,
3678 descr
->colorMap
, descr
->palentry
,
3679 bmpImage
, descr
->dibpitch
);
3683 X11DRV_DIB_GetImageBits_16( descr
->physDev
, descr
->lines
, (LPVOID
)descr
->bits
,
3684 descr
->infoWidth
,descr
->width
,
3686 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3687 bmpImage
, descr
->dibpitch
);
3691 X11DRV_DIB_GetImageBits_24( descr
->physDev
, descr
->lines
, (LPVOID
)descr
->bits
,
3692 descr
->infoWidth
,descr
->width
,
3694 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3695 bmpImage
, descr
->dibpitch
);
3699 X11DRV_DIB_GetImageBits_32( descr
->physDev
, descr
->lines
, (LPVOID
)descr
->bits
,
3700 descr
->infoWidth
, descr
->width
,
3702 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3703 bmpImage
, descr
->dibpitch
);
3707 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
3711 if (old_data
) bmpImage
->data
= old_data
;
3712 if (!descr
->image
) X11DRV_DIB_DestroyXImage( bmpImage
);
3716 /*************************************************************************
3717 * X11DRV_SetDIBitsToDevice
3720 INT
X11DRV_SetDIBitsToDevice( PHYSDEV dev
, INT xDest
, INT yDest
, DWORD cx
, DWORD cy
,
3721 INT xSrc
, INT ySrc
, UINT startscan
, UINT lines
, LPCVOID bits
,
3722 BITMAPINFO
*info
, UINT coloruse
)
3724 X11DRV_PDEVICE
*physDev
= get_x11drv_dev( dev
);
3725 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3730 int rop
= X11DRV_XROPfunction
[GetROP2(dev
->hdc
) - 1];
3732 top_down
= (info
->bmiHeader
.biHeight
< 0);
3733 height
= abs( info
->bmiHeader
.biHeight
);
3734 descr
.infoBpp
= info
->bmiHeader
.biBitCount
;
3735 descr
.compression
= info
->bmiHeader
.biCompression
;
3739 LPtoDP(dev
->hdc
, &pt
, 1);
3740 if (GetLayout( dev
->hdc
) & LAYOUT_RTL
) pt
.x
-= cx
- 1;
3742 if (!lines
|| (startscan
>= height
)) return 0;
3743 if (!top_down
&& startscan
+ lines
> height
) lines
= height
- startscan
;
3745 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
3746 * and clamp all values to fit inside [startscan,startscan+lines]
3748 if (ySrc
+ cy
<= startscan
+ lines
)
3750 UINT y
= startscan
+ lines
- (ySrc
+ cy
);
3751 if (ySrc
< startscan
) cy
-= (startscan
- ySrc
);
3754 /* avoid getting unnecessary lines */
3756 if (y
>= lines
) return 0;
3761 if (y
>= lines
) return lines
;
3762 ySrc
= y
; /* need to get all lines in top down mode */
3767 if (ySrc
>= startscan
+ lines
) return 0;
3768 pt
.y
+= ySrc
+ cy
- (startscan
+ lines
);
3769 cy
= startscan
+ lines
- ySrc
;
3771 if (cy
> lines
) cy
= lines
;
3773 if (xSrc
>= info
->bmiHeader
.biWidth
) return lines
;
3774 if (xSrc
+ cx
<= 0) return lines
;
3775 if (xSrc
+ cx
>= info
->bmiHeader
.biWidth
) cx
= info
->bmiHeader
.biWidth
- xSrc
;
3782 if (!cx
|| !cy
) return lines
;
3784 /* Update the pixmap from the DIB section */
3785 X11DRV_LockDIBSection(physDev
, DIB_Status_GdiMod
);
3787 X11DRV_SetupGCForText( physDev
); /* To have the correct colors */
3789 XSetFunction(gdi_display
, physDev
->gc
, rop
);
3790 wine_tsx11_unlock();
3792 switch (descr
.infoBpp
)
3797 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
3799 physDev
->depth
, info
, &descr
.nColorMap
);
3800 if (!descr
.colorMap
) return 0;
3801 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3805 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(const DWORD
*)info
->bmiColors
: 0x7c00;
3806 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3807 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3813 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(const DWORD
*)info
->bmiColors
: 0xff0000;
3814 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
3815 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
3820 descr
.physDev
= physDev
;
3823 descr
.palentry
= NULL
;
3824 descr
.lines
= top_down
? -lines
: lines
;
3825 descr
.infoWidth
= info
->bmiHeader
.biWidth
;
3826 descr
.depth
= physDev
->depth
;
3827 descr
.shifts
= physDev
->color_shifts
;
3828 descr
.drawable
= physDev
->drawable
;
3829 descr
.gc
= physDev
->gc
;
3832 descr
.xDest
= physDev
->dc_rect
.left
+ pt
.x
;
3833 descr
.yDest
= physDev
->dc_rect
.top
+ pt
.y
;
3836 descr
.shm_mode
= X11DRV_SHM_NONE
;
3837 descr
.dibpitch
= X11DRV_DIB_GetDIBWidthBytes( info
->bmiHeader
.biWidth
, info
->bmiHeader
.biBitCount
);
3838 descr
.physBitmap
= NULL
;
3840 result
= X11DRV_DIB_SetImageBits( &descr
);
3842 if (descr
.infoBpp
<= 8)
3843 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
3845 /* Update the DIBSection of the pixmap */
3846 X11DRV_UnlockDIBSection(physDev
, TRUE
);
3851 /***********************************************************************
3852 * X11DRV_DIB_DoCopyDIBSection
3854 static void X11DRV_DIB_DoCopyDIBSection(X_PHYSBITMAP
*physBitmap
, BOOL toDIB
,
3855 void *colorMap
, int nColorMap
,
3856 Drawable dest
, GC gc
,
3857 DWORD xSrc
, DWORD ySrc
,
3858 DWORD xDest
, DWORD yDest
,
3859 DWORD width
, DWORD height
)
3861 DIBSECTION dibSection
;
3862 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3863 int identity
[2] = {0,1};
3865 if (!GetObjectW( physBitmap
->hbitmap
, sizeof(dibSection
), &dibSection
)) return;
3867 descr
.physDev
= NULL
;
3868 descr
.palentry
= NULL
;
3869 descr
.infoWidth
= dibSection
.dsBmih
.biWidth
;
3870 descr
.infoBpp
= dibSection
.dsBmih
.biBitCount
;
3871 descr
.lines
= physBitmap
->topdown
? -dibSection
.dsBmih
.biHeight
: dibSection
.dsBmih
.biHeight
;
3872 descr
.image
= physBitmap
->image
;
3873 descr
.colorMap
= colorMap
;
3874 descr
.nColorMap
= nColorMap
;
3875 descr
.bits
= dibSection
.dsBm
.bmBits
;
3876 descr
.depth
= physBitmap
->pixmap_depth
;
3877 descr
.shifts
= physBitmap
->trueColor
? &physBitmap
->pixmap_color_shifts
: NULL
;
3878 descr
.compression
= dibSection
.dsBmih
.biCompression
;
3879 descr
.physBitmap
= physBitmap
;
3881 if(descr
.infoBpp
== 1)
3882 descr
.colorMap
= (void*)identity
;
3884 switch (descr
.infoBpp
)
3889 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3893 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dibSection
.dsBitfields
[0] : 0x7c00;
3894 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dibSection
.dsBitfields
[1] : 0x03e0;
3895 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dibSection
.dsBitfields
[2] : 0x001f;
3900 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dibSection
.dsBitfields
[0] : 0xff0000;
3901 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dibSection
.dsBitfields
[1] : 0x00ff00;
3902 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dibSection
.dsBitfields
[2] : 0x0000ff;
3907 descr
.drawable
= dest
;
3911 descr
.xDest
= xDest
;
3912 descr
.yDest
= yDest
;
3913 descr
.width
= width
;
3914 descr
.height
= height
;
3915 descr
.sizeImage
= 0;
3917 descr
.shm_mode
= physBitmap
->shm_mode
;
3918 #ifdef HAVE_LIBXXSHM
3919 if (physBitmap
->shm_mode
== X11DRV_SHM_PIXMAP
&& physBitmap
->pixmap
!= dest
)
3921 descr
.shm_mode
= X11DRV_SHM_NONE
;
3924 descr
.dibpitch
= dibSection
.dsBm
.bmWidthBytes
;
3928 TRACE("Copying from Pixmap to DIB bits\n");
3929 X11DRV_DIB_GetImageBits( &descr
);
3933 TRACE("Copying from DIB bits to Pixmap\n");
3934 X11DRV_DIB_SetImageBits( &descr
);
3938 /***********************************************************************
3939 * X11DRV_DIB_CopyDIBSection
3941 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE
*physDevSrc
, X11DRV_PDEVICE
*physDevDst
,
3942 DWORD xSrc
, DWORD ySrc
, DWORD xDest
, DWORD yDest
,
3943 DWORD width
, DWORD height
)
3946 X_PHYSBITMAP
*physBitmap
;
3947 unsigned int nColorMap
;
3951 TRACE("(%p,%p,%d,%d,%d,%d,%d,%d)\n", physDevSrc
->dev
.hdc
, physDevDst
->dev
.hdc
,
3952 xSrc
, ySrc
, xDest
, yDest
, width
, height
);
3953 /* this function is meant as an optimization for BitBlt,
3954 * not to be called otherwise */
3955 physBitmap
= physDevSrc
->bitmap
;
3956 if (!physBitmap
|| GetObjectW( physBitmap
->hbitmap
, sizeof(dib
), &dib
) != sizeof(dib
))
3958 ERR("called for non-DIBSection!?\n");
3961 /* while BitBlt should already have made sure we only get
3962 * positive values, we should check for oversize values */
3963 if ((xSrc
< dib
.dsBm
.bmWidth
) &&
3964 (ySrc
< dib
.dsBm
.bmHeight
)) {
3965 if (xSrc
+ width
> dib
.dsBm
.bmWidth
)
3966 width
= dib
.dsBm
.bmWidth
- xSrc
;
3967 if (ySrc
+ height
> dib
.dsBm
.bmHeight
)
3968 height
= dib
.dsBm
.bmHeight
- ySrc
;
3969 /* if the source bitmap is 8bpp or less, we're supposed to use the
3970 * DC's palette for color conversion (not the DIB color table) */
3971 if (dib
.dsBm
.bmBitsPixel
<= 8) {
3972 HPALETTE hPalette
= GetCurrentObject( physDevSrc
->dev
.hdc
, OBJ_PAL
);
3973 if (!hPalette
|| (hPalette
== GetStockObject(DEFAULT_PALETTE
))) {
3974 /* HACK: no palette has been set in the source DC,
3975 * use the DIB colormap instead - this is necessary in some
3976 * cases since we need to do depth conversion in some places
3977 * where real Windows can just copy data straight over */
3978 x11ColorMap
= physBitmap
->colorMap
;
3979 nColorMap
= physBitmap
->nColorMap
;
3980 freeColorMap
= FALSE
;
3982 const BITMAPINFO
* info
= (BITMAPINFO
*)&dib
.dsBmih
;
3985 nColorMap
= X11DRV_DIB_GetColorCount(info
);
3986 x11ColorMap
= HeapAlloc(GetProcessHeap(), 0, nColorMap
* sizeof(int));
3987 for (i
= 0; i
< nColorMap
; i
++)
3988 x11ColorMap
[i
] = X11DRV_PALETTE_ToPhysical(physDevSrc
, PALETTEINDEX(i
));
3989 freeColorMap
= TRUE
;
3996 freeColorMap
= FALSE
;
3998 /* perform the copy */
3999 X11DRV_DIB_DoCopyDIBSection(physBitmap
, FALSE
, x11ColorMap
, nColorMap
,
4000 physDevDst
->drawable
, physDevDst
->gc
, xSrc
, ySrc
,
4001 physDevDst
->dc_rect
.left
+ xDest
, physDevDst
->dc_rect
.top
+ yDest
,
4003 /* free color mapping */
4005 HeapFree(GetProcessHeap(), 0, x11ColorMap
);
4009 /***********************************************************************
4010 * X11DRV_DIB_DoUpdateDIBSection
4012 static void X11DRV_DIB_DoUpdateDIBSection(X_PHYSBITMAP
*physBitmap
, BOOL toDIB
)
4016 GetObjectW( physBitmap
->hbitmap
, sizeof(bitmap
), &bitmap
);
4017 X11DRV_DIB_DoCopyDIBSection(physBitmap
, toDIB
,
4018 physBitmap
->colorMap
, physBitmap
->nColorMap
,
4019 physBitmap
->pixmap
, get_bitmap_gc(physBitmap
->pixmap_depth
),
4020 0, 0, 0, 0, bitmap
.bmWidth
, bitmap
.bmHeight
);
4023 /***********************************************************************
4024 * X11DRV_DIB_FaultHandler
4026 static LONG CALLBACK
X11DRV_DIB_FaultHandler( PEXCEPTION_POINTERS ep
)
4028 X_PHYSBITMAP
*physBitmap
= NULL
;
4032 const size_t pagemask
= getpagesize() - 1;
4034 if (ep
->ExceptionRecord
->ExceptionCode
!= EXCEPTION_ACCESS_VIOLATION
)
4035 return EXCEPTION_CONTINUE_SEARCH
;
4037 addr
= (BYTE
*)ep
->ExceptionRecord
->ExceptionInformation
[1];
4039 EnterCriticalSection(&dibs_cs
);
4040 LIST_FOR_EACH( ptr
, &dibs_list
)
4042 physBitmap
= LIST_ENTRY( ptr
, X_PHYSBITMAP
, entry
);
4043 if ((physBitmap
->base
<= addr
) &&
4044 (addr
< physBitmap
->base
+ ((physBitmap
->size
+ pagemask
) & ~pagemask
)))
4050 LeaveCriticalSection(&dibs_cs
);
4052 if (!found
) return EXCEPTION_CONTINUE_SEARCH
;
4054 if (addr
>= physBitmap
->base
+ physBitmap
->size
)
4055 WARN( "%p: access to %p beyond the end of the DIB\n", physBitmap
->hbitmap
, addr
);
4057 X11DRV_DIB_Lock( physBitmap
, DIB_Status_None
);
4058 if (ep
->ExceptionRecord
->ExceptionInformation
[0] == EXCEPTION_WRITE_FAULT
) {
4059 /* the app tried to write the DIB bits */
4060 X11DRV_DIB_Coerce( physBitmap
, DIB_Status_AppMod
);
4062 /* the app tried to read the DIB bits */
4063 X11DRV_DIB_Coerce( physBitmap
, DIB_Status_InSync
);
4065 X11DRV_DIB_Unlock( physBitmap
, TRUE
);
4067 return EXCEPTION_CONTINUE_EXECUTION
;
4070 /***********************************************************************
4073 static INT
X11DRV_DIB_Coerce(X_PHYSBITMAP
*physBitmap
, INT req
)
4075 INT ret
= DIB_Status_None
;
4077 if (!physBitmap
->image
) return ret
; /* not a DIB section */
4078 EnterCriticalSection(&physBitmap
->lock
);
4079 ret
= physBitmap
->status
;
4081 case DIB_Status_GdiMod
:
4082 /* GDI access - request to draw on pixmap */
4083 switch (physBitmap
->status
)
4086 case DIB_Status_None
:
4087 physBitmap
->p_status
= DIB_Status_GdiMod
;
4088 X11DRV_DIB_DoUpdateDIBSection( physBitmap
, FALSE
);
4091 case DIB_Status_GdiMod
:
4092 TRACE("GdiMod requested in status GdiMod\n" );
4093 physBitmap
->p_status
= DIB_Status_GdiMod
;
4096 case DIB_Status_InSync
:
4097 TRACE("GdiMod requested in status InSync\n" );
4098 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_NOACCESS
);
4099 physBitmap
->status
= DIB_Status_GdiMod
;
4100 physBitmap
->p_status
= DIB_Status_InSync
;
4103 case DIB_Status_AppMod
:
4104 TRACE("GdiMod requested in status AppMod\n" );
4105 /* make it readonly to avoid app changing data while we copy */
4106 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READONLY
);
4107 X11DRV_DIB_DoUpdateDIBSection( physBitmap
, FALSE
);
4108 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_NOACCESS
);
4109 physBitmap
->p_status
= DIB_Status_AppMod
;
4110 physBitmap
->status
= DIB_Status_GdiMod
;
4115 case DIB_Status_InSync
:
4116 /* App access - request access to read DIB surface */
4117 /* (typically called from signal handler) */
4118 switch (physBitmap
->status
)
4121 case DIB_Status_None
:
4122 /* shouldn't happen from signal handler */
4125 case DIB_Status_GdiMod
:
4126 TRACE("InSync requested in status GdiMod\n" );
4127 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READWRITE
);
4128 X11DRV_DIB_DoUpdateDIBSection( physBitmap
, TRUE
);
4129 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READONLY
);
4130 physBitmap
->status
= DIB_Status_InSync
;
4133 case DIB_Status_InSync
:
4134 TRACE("InSync requested in status InSync\n" );
4135 /* shouldn't happen from signal handler */
4138 case DIB_Status_AppMod
:
4139 TRACE("InSync requested in status AppMod\n" );
4140 /* no reason to do anything here, and this
4141 * shouldn't happen from signal handler */
4146 case DIB_Status_AppMod
:
4147 /* App access - request access to write DIB surface */
4148 /* (typically called from signal handler) */
4149 switch (physBitmap
->status
)
4152 case DIB_Status_None
:
4153 /* shouldn't happen from signal handler */
4156 case DIB_Status_GdiMod
:
4157 TRACE("AppMod requested in status GdiMod\n" );
4158 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READWRITE
);
4159 X11DRV_DIB_DoUpdateDIBSection( physBitmap
, TRUE
);
4160 physBitmap
->status
= DIB_Status_AppMod
;
4163 case DIB_Status_InSync
:
4164 TRACE("AppMod requested in status InSync\n" );
4165 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READWRITE
);
4166 physBitmap
->status
= DIB_Status_AppMod
;
4169 case DIB_Status_AppMod
:
4170 TRACE("AppMod requested in status AppMod\n" );
4171 /* shouldn't happen from signal handler */
4176 /* it is up to the caller to do the copy/conversion, probably
4177 * using the return value to decide where to copy from */
4179 LeaveCriticalSection(&physBitmap
->lock
);
4183 /***********************************************************************
4186 INT
X11DRV_DIB_Lock(X_PHYSBITMAP
*physBitmap
, INT req
)
4188 INT ret
= DIB_Status_None
;
4190 if (!physBitmap
->image
) return ret
; /* not a DIB section */
4191 TRACE("Locking %p from thread %04x\n", physBitmap
->hbitmap
, GetCurrentThreadId());
4192 EnterCriticalSection(&physBitmap
->lock
);
4193 ret
= physBitmap
->status
;
4194 if (req
!= DIB_Status_None
)
4195 X11DRV_DIB_Coerce(physBitmap
, req
);
4199 /***********************************************************************
4202 void X11DRV_DIB_Unlock(X_PHYSBITMAP
*physBitmap
, BOOL commit
)
4204 if (!physBitmap
->image
) return; /* not a DIB section */
4205 switch (physBitmap
->status
)
4208 case DIB_Status_None
:
4209 /* in case anyone is wondering, this is the "signal handler doesn't
4210 * work" case, where we always have to be ready for app access */
4212 switch (physBitmap
->p_status
)
4214 case DIB_Status_GdiMod
:
4215 TRACE("Unlocking and syncing from GdiMod\n" );
4216 X11DRV_DIB_DoUpdateDIBSection( physBitmap
, TRUE
);
4220 TRACE("Unlocking without needing to sync\n" );
4224 else TRACE("Unlocking with no changes\n");
4225 physBitmap
->p_status
= DIB_Status_None
;
4228 case DIB_Status_GdiMod
:
4229 TRACE("Unlocking in status GdiMod\n" );
4230 /* DIB was protected in Coerce */
4232 /* no commit, revert to InSync if applicable */
4233 if ((physBitmap
->p_status
== DIB_Status_InSync
) ||
4234 (physBitmap
->p_status
== DIB_Status_AppMod
)) {
4235 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READONLY
);
4236 physBitmap
->status
= DIB_Status_InSync
;
4241 case DIB_Status_InSync
:
4242 TRACE("Unlocking in status InSync\n" );
4243 /* DIB was already protected in Coerce */
4246 case DIB_Status_AppMod
:
4247 TRACE("Unlocking in status AppMod\n" );
4248 /* DIB was already protected in Coerce */
4249 /* this case is ordinary only called from the signal handler,
4250 * so we don't bother to check for !commit */
4253 LeaveCriticalSection(&physBitmap
->lock
);
4254 TRACE("Unlocked %p\n", physBitmap
->hbitmap
);
4257 /***********************************************************************
4258 * X11DRV_CoerceDIBSection
4260 INT
X11DRV_CoerceDIBSection(X11DRV_PDEVICE
*physDev
, INT req
)
4262 if (!physDev
|| !physDev
->bitmap
) return DIB_Status_None
;
4263 return X11DRV_DIB_Coerce(physDev
->bitmap
, req
);
4266 /***********************************************************************
4267 * X11DRV_LockDIBSection
4269 INT
X11DRV_LockDIBSection(X11DRV_PDEVICE
*physDev
, INT req
)
4271 if (!physDev
|| !physDev
->bitmap
) return DIB_Status_None
;
4272 return X11DRV_DIB_Lock(physDev
->bitmap
, req
);
4275 /***********************************************************************
4276 * X11DRV_UnlockDIBSection
4278 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE
*physDev
, BOOL commit
)
4280 if (!physDev
|| !physDev
->bitmap
) return;
4281 X11DRV_DIB_Unlock(physDev
->bitmap
, commit
);
4285 #ifdef HAVE_LIBXXSHM
4286 /***********************************************************************
4287 * X11DRV_XShmErrorHandler
4290 static int XShmErrorHandler( Display
*dpy
, XErrorEvent
*event
, void *arg
)
4292 return 1; /* FIXME: should check event contents */
4295 /***********************************************************************
4296 * X11DRV_XShmCreateImage
4299 static XImage
*X11DRV_XShmCreateImage( int width
, int height
, int bpp
,
4300 XShmSegmentInfo
* shminfo
)
4304 image
= XShmCreateImage(gdi_display
, visual
, bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
4307 shminfo
->shmid
= shmget(IPC_PRIVATE
, image
->bytes_per_line
* height
,
4309 if( shminfo
->shmid
!= -1 )
4311 shminfo
->shmaddr
= shmat( shminfo
->shmid
, 0, 0 );
4312 if( shminfo
->shmaddr
!= (char*)-1 )
4316 shminfo
->readOnly
= FALSE
;
4317 X11DRV_expect_error( gdi_display
, XShmErrorHandler
, NULL
);
4318 ok
= (XShmAttach( gdi_display
, shminfo
) != 0);
4319 XSync( gdi_display
, False
);
4320 if (X11DRV_check_error()) ok
= FALSE
;
4323 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
4324 return image
; /* Success! */
4326 /* An error occurred */
4327 shmdt(shminfo
->shmaddr
);
4329 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
4330 shminfo
->shmid
= -1;
4332 XFlush(gdi_display
);
4333 XDestroyImage(image
);
4338 #endif /* HAVE_LIBXXSHM */
4340 static Bool
X11DRV_DIB_QueryXShm( Bool
*pixmaps
)
4342 static Bool have_xshm
, have_xshm_pixmaps
;
4343 static BOOL initialized
;
4347 #ifdef HAVE_LIBXXSHM
4350 have_xshm
= XShmQueryVersion( gdi_display
, &major
, &minor
, &have_xshm_pixmaps
);
4355 *pixmaps
= have_xshm_pixmaps
;
4359 /***********************************************************************
4360 * X11DRV_CreateDIBSection (X11DRV.@)
4362 HBITMAP
X11DRV_CreateDIBSection( PHYSDEV dev
, HBITMAP hbitmap
, BITMAPINFO
*bmi
, UINT usage
)
4364 X11DRV_PDEVICE
*physDev
= get_x11drv_dev( dev
);
4365 X_PHYSBITMAP
*physBitmap
;
4367 #ifdef HAVE_LIBXXSHM
4371 if (!(physBitmap
= X11DRV_init_phys_bitmap( hbitmap
))) return 0;
4372 physBitmap
->topdown
= bmi
->bmiHeader
.biHeight
< 0;
4373 physBitmap
->status
= DIB_Status_None
;
4375 GetObjectW( hbitmap
, sizeof(dib
), &dib
);
4377 /* create color map */
4378 if (dib
.dsBm
.bmBitsPixel
<= 8)
4380 physBitmap
->colorMap
= X11DRV_DIB_BuildColorMap( physDev
,
4381 usage
, dib
.dsBm
.bmBitsPixel
, bmi
,
4382 &physBitmap
->nColorMap
);
4385 if (!X11DRV_XRender_SetPhysBitmapDepth( physBitmap
, dib
.dsBm
.bmBitsPixel
, &dib
))
4387 if (dib
.dsBm
.bmBitsPixel
== 1)
4389 physBitmap
->pixmap_depth
= 1;
4390 physBitmap
->trueColor
= FALSE
;
4394 physBitmap
->pixmap_depth
= screen_depth
;
4395 physBitmap
->pixmap_color_shifts
= X11DRV_PALETTE_default_shifts
;
4396 physBitmap
->trueColor
= (visual
->class == TrueColor
|| visual
->class == DirectColor
);
4400 /* create pixmap and X image */
4402 #ifdef HAVE_LIBXXSHM
4403 physBitmap
->shminfo
.shmid
= -1;
4405 if (X11DRV_DIB_QueryXShm( &pixmaps
)
4406 && (physBitmap
->image
= X11DRV_XShmCreateImage( dib
.dsBm
.bmWidth
, dib
.dsBm
.bmHeight
,
4407 physBitmap
->pixmap_depth
, &physBitmap
->shminfo
)))
4411 physBitmap
->shm_mode
= X11DRV_SHM_PIXMAP
;
4412 physBitmap
->image
->data
= HeapAlloc( GetProcessHeap(), 0,
4413 dib
.dsBm
.bmHeight
* physBitmap
->image
->bytes_per_line
);
4417 physBitmap
->shm_mode
= X11DRV_SHM_IMAGE
;
4418 physBitmap
->image
->data
= physBitmap
->shminfo
.shmaddr
;
4424 physBitmap
->shm_mode
= X11DRV_SHM_NONE
;
4425 physBitmap
->image
= X11DRV_DIB_CreateXImage( dib
.dsBm
.bmWidth
, dib
.dsBm
.bmHeight
,
4426 physBitmap
->pixmap_depth
);
4429 #ifdef HAVE_LIBXXSHM
4430 if (physBitmap
->shm_mode
== X11DRV_SHM_PIXMAP
)
4432 TRACE("Creating shared pixmap for bmp %p.\n", physBitmap
->hbitmap
);
4433 physBitmap
->pixmap
= XShmCreatePixmap( gdi_display
, root_window
,
4434 physBitmap
->shminfo
.shmaddr
, &physBitmap
->shminfo
,
4435 dib
.dsBm
.bmWidth
, dib
.dsBm
.bmHeight
,
4436 physBitmap
->pixmap_depth
);
4441 physBitmap
->pixmap
= XCreatePixmap( gdi_display
, root_window
, dib
.dsBm
.bmWidth
,
4442 dib
.dsBm
.bmHeight
, physBitmap
->pixmap_depth
);
4445 wine_tsx11_unlock();
4446 if (!physBitmap
->pixmap
|| !physBitmap
->image
) return 0;
4448 if (physBitmap
->trueColor
)
4450 ColorShifts
*shifts
= &physBitmap
->pixmap_color_shifts
;
4452 /* When XRender is around and used, we also support dibsections in other formats like 16-bit. In these
4453 * cases we need to override the mask of XImages. The reason is that during XImage creation the masks are
4454 * derived from a 24-bit visual (no 16-bit ones are around when X runs at 24-bit). SetImageBits and other
4455 * functions rely on the color masks for proper color conversion, so we need to override the masks here. */
4456 physBitmap
->image
->red_mask
= shifts
->physicalRed
.max
<< shifts
->physicalRed
.shift
;
4457 physBitmap
->image
->green_mask
= shifts
->physicalGreen
.max
<< shifts
->physicalGreen
.shift
;
4458 physBitmap
->image
->blue_mask
= shifts
->physicalBlue
.max
<< shifts
->physicalBlue
.shift
;
4461 /* install fault handler */
4462 InitializeCriticalSection( &physBitmap
->lock
);
4463 physBitmap
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": X_PHYSBITMAP.lock");
4465 physBitmap
->base
= dib
.dsBm
.bmBits
;
4466 physBitmap
->size
= dib
.dsBmih
.biSizeImage
;
4467 physBitmap
->status
= DIB_Status_AppMod
;
4470 dibs_handler
= AddVectoredExceptionHandler( TRUE
, X11DRV_DIB_FaultHandler
);
4471 EnterCriticalSection( &dibs_cs
);
4472 list_add_head( &dibs_list
, &physBitmap
->entry
);
4473 LeaveCriticalSection( &dibs_cs
);
4475 X11DRV_DIB_DoProtectDIBSection( physBitmap
, PAGE_READWRITE
);
4480 /***********************************************************************
4481 * X11DRV_DIB_DeleteDIBSection
4483 void X11DRV_DIB_DeleteDIBSection(X_PHYSBITMAP
*physBitmap
, DIBSECTION
*dib
)
4487 EnterCriticalSection( &dibs_cs
);
4488 list_remove( &physBitmap
->entry
);
4489 last
= list_empty( &dibs_list
);
4490 LeaveCriticalSection( &dibs_cs
);
4494 RemoveVectoredExceptionHandler( dibs_handler
);
4495 dibs_handler
= NULL
;
4498 if (dib
->dshSection
)
4499 X11DRV_DIB_Coerce(physBitmap
, DIB_Status_InSync
);
4501 if (physBitmap
->image
)
4504 #ifdef HAVE_LIBXXSHM
4505 if (physBitmap
->shminfo
.shmid
!= -1)
4507 XShmDetach( gdi_display
, &(physBitmap
->shminfo
) );
4508 if (physBitmap
->shm_mode
== X11DRV_SHM_PIXMAP
) X11DRV_DIB_DestroyXImage( physBitmap
->image
);
4509 else XDestroyImage( physBitmap
->image
);
4510 shmdt( physBitmap
->shminfo
.shmaddr
);
4511 physBitmap
->shminfo
.shmid
= -1;
4512 physBitmap
->shm_mode
= X11DRV_SHM_NONE
;
4516 X11DRV_DIB_DestroyXImage( physBitmap
->image
);
4517 wine_tsx11_unlock();
4520 HeapFree(GetProcessHeap(), 0, physBitmap
->colorMap
);
4521 physBitmap
->lock
.DebugInfo
->Spare
[0] = 0;
4522 DeleteCriticalSection(&physBitmap
->lock
);
4525 /***********************************************************************
4526 * SetDIBColorTable (X11DRV.@)
4528 UINT
X11DRV_SetDIBColorTable( PHYSDEV dev
, UINT start
, UINT count
, const RGBQUAD
*colors
)
4530 X11DRV_PDEVICE
*physDev
= get_x11drv_dev( dev
);
4533 X_PHYSBITMAP
*physBitmap
= physDev
->bitmap
;
4535 if (!physBitmap
) return 0;
4536 GetObjectW( physBitmap
->hbitmap
, sizeof(dib
), &dib
);
4538 if (physBitmap
->colorMap
&& start
< physBitmap
->nColorMap
) {
4539 UINT end
= count
+ start
;
4540 if (end
> physBitmap
->nColorMap
) end
= physBitmap
->nColorMap
;
4542 * Changing color table might change the mapping between
4543 * DIB colors and X11 colors and thus alter the visible state
4544 * of the bitmap object.
4547 * FIXME we need to recalculate the pen, brush, text and bkgnd pixels here,
4548 * at least for a 1 bpp dibsection
4550 X11DRV_DIB_Lock( physBitmap
, DIB_Status_AppMod
);
4551 X11DRV_DIB_GenColorMap( physDev
, physBitmap
->colorMap
, DIB_RGB_COLORS
,
4552 dib
.dsBm
.bmBitsPixel
, colors
, start
, end
);
4553 X11DRV_DIB_Unlock( physBitmap
, TRUE
);
4560 /***********************************************************************
4561 * X11DRV_DIB_CreateDIBFromBitmap
4563 * Allocates a packed DIB and copies the bitmap data into it.
4565 HGLOBAL
X11DRV_DIB_CreateDIBFromBitmap(HDC hdc
, HBITMAP hBmp
)
4570 LPBITMAPINFOHEADER pbmiHeader
;
4571 unsigned int cDataSize
, cPackedSize
, OffsetBits
;
4574 if (!GetObjectW( hBmp
, sizeof(bmp
), &bmp
)) return 0;
4577 * A packed DIB contains a BITMAPINFO structure followed immediately by
4578 * an optional color palette and the pixel data.
4581 /* Calculate the size of the packed DIB */
4582 cDataSize
= X11DRV_DIB_GetDIBWidthBytes( bmp
.bmWidth
, bmp
.bmBitsPixel
) * abs( bmp
.bmHeight
);
4583 cPackedSize
= sizeof(BITMAPINFOHEADER
)
4584 + ( (bmp
.bmBitsPixel
<= 8) ? (sizeof(RGBQUAD
) * (1 << bmp
.bmBitsPixel
)) : 0 )
4586 /* Get the offset to the bits */
4587 OffsetBits
= cPackedSize
- cDataSize
;
4589 /* Allocate the packed DIB */
4590 TRACE("\tAllocating packed DIB of size %d\n", cPackedSize
);
4591 hPackedDIB
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_DDESHARE
/*| GMEM_ZEROINIT*/,
4595 WARN("Could not allocate packed DIB!\n");
4599 /* A packed DIB starts with a BITMAPINFOHEADER */
4600 pPackedDIB
= GlobalLock(hPackedDIB
);
4601 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
4603 /* Init the BITMAPINFOHEADER */
4604 pbmiHeader
->biSize
= sizeof(BITMAPINFOHEADER
);
4605 pbmiHeader
->biWidth
= bmp
.bmWidth
;
4606 pbmiHeader
->biHeight
= bmp
.bmHeight
;
4607 pbmiHeader
->biPlanes
= 1;
4608 pbmiHeader
->biBitCount
= bmp
.bmBitsPixel
;
4609 pbmiHeader
->biCompression
= BI_RGB
;
4610 pbmiHeader
->biSizeImage
= 0;
4611 pbmiHeader
->biXPelsPerMeter
= pbmiHeader
->biYPelsPerMeter
= 0;
4612 pbmiHeader
->biClrUsed
= 0;
4613 pbmiHeader
->biClrImportant
= 0;
4615 /* Retrieve the DIB bits from the bitmap and fill in the
4616 * DIB color table if present */
4618 nLinesCopied
= GetDIBits(hdc
, /* Handle to device context */
4619 hBmp
, /* Handle to bitmap */
4620 0, /* First scan line to set in dest bitmap */
4621 bmp
.bmHeight
, /* Number of scan lines to copy */
4622 pPackedDIB
+ OffsetBits
, /* [out] Address of array for bitmap bits */
4623 (LPBITMAPINFO
) pbmiHeader
, /* [out] Address of BITMAPINFO structure */
4624 0); /* RGB or palette index */
4625 GlobalUnlock(hPackedDIB
);
4627 /* Cleanup if GetDIBits failed */
4628 if (nLinesCopied
!= bmp
.bmHeight
)
4630 TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied
, bmp
.bmHeight
);
4631 GlobalFree(hPackedDIB
);
4638 /**************************************************************************
4639 * X11DRV_DIB_CreateDIBFromPixmap
4641 * Allocates a packed DIB and copies the Pixmap data into it.
4642 * The Pixmap passed in is deleted after the conversion.
4644 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
)
4647 X_PHYSBITMAP
*physBitmap
;
4650 HGLOBAL hPackedDIB
= 0;
4652 int x
,y
; /* Unused */
4653 unsigned border_width
; /* Unused */
4654 unsigned int depth
, width
, height
;
4656 /* Get the Pixmap dimensions and bit depth */
4658 if (!XGetGeometry(gdi_display
, pixmap
, &root
, &x
, &y
, &width
, &height
,
4659 &border_width
, &depth
)) depth
= 0;
4660 wine_tsx11_unlock();
4661 if (!pixmap_formats
[depth
]) return 0;
4663 TRACE("\tPixmap properties: width=%d, height=%d, depth=%d\n",
4664 width
, height
, depth
);
4667 * Create an HBITMAP with the same dimensions and BPP as the pixmap,
4668 * and make it a container for the pixmap passed.
4670 if (!(hBmp
= CreateBitmap( width
, height
, 1, pixmap_formats
[depth
]->bits_per_pixel
, NULL
))) return 0;
4672 /* force bitmap to be owned by a screen DC */
4673 hdcMem
= CreateCompatibleDC( hdc
);
4674 SelectObject( hdcMem
, SelectObject( hdcMem
, hBmp
));
4677 physBitmap
= X11DRV_get_phys_bitmap( hBmp
);
4679 /* swap the new pixmap in */
4680 orig_pixmap
= physBitmap
->pixmap
;
4681 physBitmap
->pixmap
= pixmap
;
4684 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4685 * A packed DIB contains a BITMAPINFO structure followed immediately by
4686 * an optional color palette and the pixel data.
4688 hPackedDIB
= X11DRV_DIB_CreateDIBFromBitmap(hdc
, hBmp
);
4690 /* we can now get rid of the HBITMAP and its original pixmap */
4691 physBitmap
->pixmap
= orig_pixmap
;
4694 TRACE("\tReturning packed DIB %p\n", hPackedDIB
);
4699 /**************************************************************************
4700 * X11DRV_DIB_CreatePixmapFromDIB
4702 * Creates a Pixmap from a packed DIB
4704 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
4707 X_PHYSBITMAP
*physBitmap
;
4711 /* Create a DDB from the DIB */
4713 pbmi
= GlobalLock(hPackedDIB
);
4714 hBmp
= CreateDIBitmap(hdc
, &pbmi
->bmiHeader
, CBM_INIT
,
4715 (LPBYTE
)pbmi
+ bitmap_info_size( pbmi
, DIB_RGB_COLORS
),
4716 pbmi
, DIB_RGB_COLORS
);
4717 GlobalUnlock(hPackedDIB
);
4719 /* clear the physBitmap so that we can steal its pixmap */
4720 physBitmap
= X11DRV_get_phys_bitmap( hBmp
);
4721 pixmap
= physBitmap
->pixmap
;
4722 physBitmap
->pixmap
= 0;
4724 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4727 TRACE("Returning Pixmap %lx\n", pixmap
);