2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
9 #ifndef X_DISPLAY_MISSING
16 # ifdef HAVE_SYS_SHM_H
19 # ifdef HAVE_SYS_IPC_H
22 #endif /* defined(HAVE_LIBXXSHM) */
28 #include "debugtools.h"
32 #include "selectors.h"
35 DEFAULT_DEBUG_CHANNEL(bitmap
)
36 DECLARE_DEBUG_CHANNEL(x11drv
)
38 static int bitmapDepthTable
[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
39 static int ximageDepthTable
[] = { 0, 0, 0, 0, 0, 0, 0 };
41 static int XShmErrorFlag
= 0;
43 /***********************************************************************
46 BOOL
X11DRV_DIB_Init(void)
51 for( i
= 0; bitmapDepthTable
[i
]; i
++ )
53 testimage
= TSXCreateImage(display
, X11DRV_GetVisual(),
54 bitmapDepthTable
[i
], ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
55 if( testimage
) ximageDepthTable
[i
] = testimage
->bits_per_pixel
;
57 TSXDestroyImage(testimage
);
63 /***********************************************************************
64 * X11DRV_DIB_GetXImageWidthBytes
66 * Return the width of an X image in bytes
68 int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
72 if (!ximageDepthTable
[0]) {
75 for( i
= 0; bitmapDepthTable
[i
] ; i
++ )
76 if( bitmapDepthTable
[i
] == depth
)
77 return (4 * ((width
* ximageDepthTable
[i
] + 31)/32));
79 WARN("(%d): Unsupported depth\n", depth
);
83 /***********************************************************************
84 * X11DRV_DIB_BuildColorMap
86 * Build the color map from the bitmap palette. Should not be called
87 * for a >8-bit deep bitmap.
89 int *X11DRV_DIB_BuildColorMap( DC
*dc
, WORD coloruse
, WORD depth
,
90 const BITMAPINFO
*info
, int *nColors
)
97 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
99 colors
= info
->bmiHeader
.biClrUsed
;
100 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
101 colorPtr
= (WORD
*)info
->bmiColors
;
103 else /* assume BITMAPCOREINFO */
105 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
106 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
111 ERR("called with >256 colors!\n");
115 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
116 colors
* sizeof(int) )))
119 if (coloruse
== DIB_RGB_COLORS
)
123 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
125 if (depth
== 1) /* Monochrome */
126 for (i
= 0; i
< colors
; i
++, rgb
++)
127 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
128 rgb
->rgbBlue
> 255*3/2);
130 for (i
= 0; i
< colors
; i
++, rgb
++)
131 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbRed
,
137 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
139 if (depth
== 1) /* Monochrome */
140 for (i
= 0; i
< colors
; i
++, rgb
++)
141 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
142 rgb
->rgbtBlue
> 255*3/2);
144 for (i
= 0; i
< colors
; i
++, rgb
++)
145 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbtRed
,
150 else /* DIB_PAL_COLORS */
152 for (i
= 0; i
< colors
; i
++, colorPtr
++)
153 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(*colorPtr
) );
161 /***********************************************************************
162 * X11DRV_DIB_MapColor
164 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
)
168 for (color
= 0; color
< nPhysMap
; color
++)
169 if (physMap
[color
] == phys
)
172 WARN("Strange color %08x\n", phys
);
177 /*********************************************************************
178 * X11DRV_DIB_GetNearestIndex
180 * Helper for X11DRV_DIB_GetDIBits.
181 * Returns the nearest colour table index for a given RGB.
182 * Nearest is defined by minimizing the sum of the squares.
184 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
186 INT i
, best
= -1, diff
, bestdiff
= -1;
189 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
190 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
191 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
192 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
195 if(best
== -1 || diff
< bestdiff
) {
203 /***********************************************************************
204 * X11DRV_DIB_SetImageBits_1_Line
206 * Handles a single line of 1 bit data.
208 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth
, int left
, int *colors
,
209 XImage
*bmpImage
, int h
, const BYTE
*bits
)
214 if((extra
= (left
& 7)) != 0) {
221 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
222 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--)
225 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
226 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 6) & 1] );
227 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 5) & 1] );
228 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 4) & 1] );
229 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 3) & 1] );
230 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 2) & 1] );
231 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 1) & 1] );
232 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 1] );
237 case 7: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
238 case 6: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
239 case 5: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
240 case 4: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
241 case 3: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
242 case 2: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
243 case 1: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
247 /***********************************************************************
248 * X11DRV_DIB_SetImageBits_1
250 * SetDIBits for a 1-bit deep DIB.
252 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
253 DWORD srcwidth
, DWORD dstwidth
, int left
,
254 int *colors
, XImage
*bmpImage
)
259 DWORD linebytes
= ((srcwidth
+ 31) & ~31) / 8;
262 for (h
= lines
-1; h
>=0; h
--) {
263 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
265 srcbits
+= linebytes
;
269 for (h
= 0; h
< lines
; h
++) {
270 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
272 srcbits
+= linebytes
;
277 /***********************************************************************
278 * X11DRV_DIB_GetImageBits_1
280 * GetDIBits for a 1-bit deep DIB.
282 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
283 DWORD dstwidth
, DWORD srcwidth
,
284 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
292 DWORD linebytes
= ((dstwidth
+ 31) & ~31) / 8;
296 dstbits
= dstbits
+ linebytes
* (lines
- 1);
297 linebytes
= -linebytes
;
302 switch(bmpImage
->depth
) {
305 /* ==== monochrome bitmap to monochrome dib ==== */
307 /* ==== 4 colormap bitmap to monochrome dib ==== */
308 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
312 for (h
= lines
- 1; h
>= 0; h
--) {
313 for (x
= 0; x
< dstwidth
; x
++) {
314 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
315 if (!(x
&7)) *bits
= 0;
316 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2,
319 val
.peBlue
) << (7 - (x
& 7)));
320 if ((x
&7)==7) bits
++;
322 bits
= (dstbits
+= linebytes
);
325 else goto notsupported
;
330 /* ==== 8 colormap bitmap to monochrome dib ==== */
331 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
336 for( h
= lines
- 1; h
>= 0; h
-- ) {
337 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
338 for( x
= 0; x
< dstwidth
; x
++ ) {
339 if (!(x
&7)) *bits
= 0;
340 val
= srccolors
[(int)*srcpixel
++];
341 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 2,
344 val
.peBlue
) << (7-(x
&7)) );
345 if ((x
&7)==7) bits
++;
347 bits
= (dstbits
+= linebytes
);
350 else goto notsupported
;
359 /* ==== 555 BGR bitmap to monochrome dib ==== */
360 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
362 for( h
= lines
- 1; h
>= 0; h
--) {
363 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
364 for( x
= 0; x
< dstwidth
; x
++) {
365 if (!(x
&7)) *bits
= 0;
367 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
368 ((val
>> 7) & 0xf8) |
370 ((val
>> 2) & 0xf8) |
372 ((val
<< 3) & 0xf8) |
373 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
374 if ((x
&7)==7) bits
++;
376 bits
= (dstbits
+= linebytes
);
379 /* ==== 555 RGB bitmap to monochrome dib ==== */
380 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
382 for( h
= lines
- 1; h
>= 0; h
--)
384 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
385 for( x
= 0; x
< dstwidth
; x
++) {
386 if (!(x
&1)) *bits
= 0;
388 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
389 ((val
<< 3) & 0xf8) |
391 ((val
>> 2) & 0xf8) |
393 ((val
>> 7) & 0xf8) |
394 ((val
>> 12) & 0x7) ) << (7-(x
&7)) );
395 if ((x
&7)==7) bits
++;
397 bits
= (dstbits
+= linebytes
);
400 else goto notsupported
;
409 /* ==== 565 BGR bitmap to monochrome dib ==== */
410 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
412 for( h
= lines
- 1; h
>= 0; h
--)
414 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
415 for( x
= 0; x
< dstwidth
; x
++) {
416 if (!(x
&7)) *bits
= 0;
418 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
419 ((val
>> 8) & 0xf8) |
421 ((val
>> 3) & 0xfc) |
423 ((val
<< 3) & 0xf8) |
424 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
425 if ((x
&7)==7) bits
++;
427 bits
= (dstbits
+= linebytes
);
430 /* ==== 565 RGB bitmap to monochrome dib ==== */
431 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
433 for( h
= lines
- 1; h
>= 0; h
--)
435 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
436 for( x
= 0; x
< dstwidth
; x
++) {
437 if (!(x
&7)) *bits
= 0;
439 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
440 ((val
<< 3) & 0xf8) |
442 ((val
>> 3) & 0xfc) |
444 ((val
>> 8) & 0xf8) |
445 ((val
>> 13) & 0x7) ) << (7-(x
&7)) );
446 if ((x
&7)==7) bits
++;
448 bits
= (dstbits
+= linebytes
);
451 else goto notsupported
;
460 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
461 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
463 for (h
= lines
- 1; h
>= 0; h
--)
465 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
466 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
467 if (!(x
&7)) *bits
= 0;
468 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << (7-(x
&7)) );
469 if ((x
&7)==7) bits
++;
471 bits
= (dstbits
+= linebytes
);
474 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
475 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
477 for (h
= lines
- 1; h
>= 0; h
--)
479 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
480 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
481 if (!(x
& 7)) *bits
= 0;
482 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << (7-(x
&7)) );
483 if ((x
& 7) == 7) bits
++;
485 bits
= (dstbits
+= linebytes
);
488 else goto notsupported
;
492 default: /* ? bit bmp -> monochrome DIB */
495 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
497 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
498 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
499 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
501 for( h
= lines
- 1; h
>= 0; h
-- ) {
502 for( x
= 0; x
< dstwidth
; x
++ ) {
503 if (!(x
&7)) *bits
= 0;
504 *bits
|= (XGetPixel( bmpImage
, x
, h
) >= white
)
506 if ((x
&7)==7) bits
++;
508 bits
= (dstbits
+= linebytes
);
515 /***********************************************************************
516 * X11DRV_DIB_SetImageBits_4
518 * SetDIBits for a 4-bit deep DIB.
520 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
521 DWORD srcwidth
, DWORD dstwidth
, int left
,
522 int *colors
, XImage
*bmpImage
)
526 const BYTE
*bits
= srcbits
+ (left
>> 1);
529 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
537 for (h
= lines
-1; h
>= 0; h
--) {
538 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
540 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
541 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
543 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
544 srcbits
+= linebytes
;
545 bits
= srcbits
+ (left
>> 1);
549 for (h
= 0; h
< lines
; h
++) {
550 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
552 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
553 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
555 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
556 srcbits
+= linebytes
;
557 bits
= srcbits
+ (left
>> 1);
564 /***********************************************************************
565 * X11DRV_DIB_GetImageBits_4
567 * GetDIBits for a 4-bit deep DIB.
569 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
570 DWORD srcwidth
, DWORD dstwidth
,
571 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
580 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
585 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
586 linebytes
= -linebytes
;
591 switch(bmpImage
->depth
) {
594 /* ==== monochrome bitmap to 4 colormap dib ==== */
596 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
597 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
601 for (h
= lines
-1; h
>= 0; h
--) {
602 for (x
= 0; x
< dstwidth
; x
++) {
603 if (!(x
&1)) *bits
= 0;
604 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
605 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 16,
608 val
.peBlue
) << (4-((x
&1)<<2)));
609 if ((x
&1)==1) bits
++;
611 bits
= (dstbits
+= linebytes
);
614 else goto notsupported
;
619 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
620 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
624 for( h
= lines
- 1; h
>= 0; h
-- ) {
625 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
626 for( x
= 0; x
< dstwidth
; x
++ ) {
627 if (!(x
&1)) *bits
= 0;
628 val
= srccolors
[(int)*srcpixel
++];
629 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 16,
632 val
.peBlue
) << (4*(1-(x
&1))) );
633 if ((x
&1)==1) bits
++;
635 bits
= (dstbits
+= linebytes
);
638 else goto notsupported
;
647 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
648 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
650 for( h
= lines
- 1; h
>= 0; h
--) {
651 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
652 for( x
= 0; x
< dstwidth
; x
++) {
653 if (!(x
&1)) *bits
= 0;
655 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
656 ((val
>> 7) & 0xf8) |
658 ((val
>> 2) & 0xf8) |
660 ((val
<< 3) & 0xf8) |
661 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
662 if ((x
&1)==1) bits
++;
664 bits
= (dstbits
+= linebytes
);
667 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
668 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
670 for( h
= lines
- 1; h
>= 0; h
--)
672 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
673 for( x
= 0; x
< dstwidth
; x
++) {
674 if (!(x
&1)) *bits
= 0;
676 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
677 ((val
<< 3) & 0xf8) |
679 ((val
>> 2) & 0xfc) |
681 ((val
>> 7) & 0xf8) |
682 ((val
>> 12) & 0x7) ) << ((1-(x
&1))<<2) );
683 if ((x
&1)==1) bits
++;
685 bits
= (dstbits
+= linebytes
);
688 else goto notsupported
;
697 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
698 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
700 for( h
= lines
- 1; h
>= 0; h
--)
702 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
703 for( x
= 0; x
< dstwidth
; x
++) {
704 if (!(x
&1)) *bits
= 0;
706 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
707 ((val
>> 8) & 0xf8) |
709 ((val
>> 3) & 0xfc) |
711 ((val
<< 3) & 0xf8) |
712 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
713 if ((x
&1)==1) bits
++;
715 bits
= (dstbits
+= linebytes
);
718 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
719 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
721 for( h
= lines
- 1; h
>= 0; h
--)
723 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
724 for( x
= 0; x
< dstwidth
; x
++) {
725 if (!(x
&1)) *bits
= 0;
727 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
728 ((val
<< 3) & 0xf8) |
730 ((val
>> 3) & 0xfc) |
732 ((val
>> 8) & 0xf8) |
733 ((val
>> 13) & 0x7) ) << ((1-(x
&1))<<2) );
734 if ((x
&1)==1) bits
++;
736 bits
= (dstbits
+= linebytes
);
739 else goto notsupported
;
748 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
749 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
751 for (h
= lines
- 1; h
>= 0; h
--)
753 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
754 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
755 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << 4) |
756 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[6] , srcpixel
[5], srcpixel
[4]);
757 bits
= (dstbits
+= linebytes
);
760 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
761 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
763 for (h
= lines
- 1; h
>= 0; h
--)
765 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
766 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
767 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << 4) |
768 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[4] , srcpixel
[5], srcpixel
[6]);
769 bits
= (dstbits
+= linebytes
);
772 else goto notsupported
;
776 default: /* ? bit bmp -> 4 bit DIB */
778 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
779 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
780 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
781 for (h
= lines
-1; h
>= 0; h
--) {
782 for (x
= 0; x
< dstwidth
/2; x
++) {
783 *bits
++ = (X11DRV_DIB_MapColor((int *)colors
, 16,
784 XGetPixel( bmpImage
, x
++, h
)) << 4)
785 | (X11DRV_DIB_MapColor((int *)colors
, 16,
786 XGetPixel( bmpImage
, x
++, h
)) & 0x0f);
789 *bits
= (X11DRV_DIB_MapColor((int *)colors
, 16,
790 XGetPixel( bmpImage
, x
++, h
)) << 4);
791 bits
= (dstbits
+= linebytes
);
797 /***********************************************************************
798 * X11DRV_DIB_SetImageBits_RLE4
800 * SetDIBits for a 4-bit deep compressed DIB.
802 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
803 DWORD width
, DWORD dstwidth
,
804 int left
, int *colors
,
807 int x
= 0, c
, length
;
808 const BYTE
*begin
= bits
;
812 while ((int)lines
>= 0) {
814 if (length
) { /* encoded */
822 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>>4]);
830 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
841 case 1: /* eopicture */
847 FIXME_(x11drv
)("x-delta is too large?\n");
853 default: /* absolute */
861 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>> 4]);
869 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
872 if ((bits
- begin
) & 1)
881 /***********************************************************************
882 * X11DRV_DIB_SetImageBits_8
884 * SetDIBits for an 8-bit deep DIB.
886 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
887 DWORD srcwidth
, DWORD dstwidth
, int left
,
888 int *colors
, XImage
*bmpImage
)
894 /* align to 32 bit */
895 DWORD linebytes
= (srcwidth
+ 3) & ~3;
902 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
903 linebytes
= -linebytes
;
906 bits
= srcbits
+ left
;
908 for (h
= lines
- 1; h
>= 0; h
--) {
909 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
910 color
= colors
[*bits
];
911 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
913 bits
= (srcbits
+= linebytes
) + left
;
917 /***********************************************************************
918 * X11DRV_DIB_GetImageBits_8
920 * GetDIBits for an 8-bit deep DIB.
922 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
923 DWORD srcwidth
, DWORD dstwidth
,
924 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
931 /* align to 32 bit */
932 DWORD linebytes
= (srcwidth
+ 3) & ~3;
937 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
938 linebytes
= -linebytes
;
945 This condition is true when GetImageBits has been called by UpdateDIBSection.
946 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
947 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
949 if (!srccolors
) goto updatesection
;
951 switch(bmpImage
->depth
) {
954 /* ==== monochrome bitmap to 8 colormap dib ==== */
956 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
957 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
961 for (h
= lines
- 1; h
>= 0; h
--) {
962 for (x
= 0; x
< dstwidth
; x
++) {
963 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
964 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
965 val
.peGreen
, val
.peBlue
);
967 bits
= (dstbits
+= linebytes
);
970 else goto notsupported
;
975 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
976 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
981 for (h
= lines
- 1; h
>= 0; h
--) {
982 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
983 for (x
= 0; x
< dstwidth
; x
++) {
984 val
= srccolors
[(int)*srcpixel
++];
985 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
986 val
.peGreen
, val
.peBlue
);
988 bits
= (dstbits
+= linebytes
);
991 else goto notsupported
;
1000 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1001 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1003 for( h
= lines
- 1; h
>= 0; h
--)
1005 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1006 for( x
= 0; x
< dstwidth
; x
++ )
1009 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1010 ((val
>> 7) & 0xf8) |
1011 ((val
>> 12) & 0x7),
1012 ((val
>> 2) & 0xf8) |
1014 ((val
<< 3) & 0xf8) |
1015 ((val
>> 2) & 0x7) );
1017 bits
= (dstbits
+= linebytes
);
1020 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1021 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1023 for( h
= lines
- 1; h
>= 0; h
--)
1025 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1026 for( x
= 0; x
< dstwidth
; x
++ )
1029 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1030 ((val
<< 3) & 0xf8) |
1032 ((val
>> 2) & 0xf8) |
1034 ((val
>> 7) & 0xf8) |
1035 ((val
>> 12) & 0x7) );
1037 bits
= (dstbits
+= linebytes
);
1040 else goto notsupported
;
1049 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1050 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
1052 for( h
= lines
- 1; h
>= 0; h
--)
1054 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1055 for( x
= 0; x
< dstwidth
; x
++ )
1058 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1059 ((val
>> 8) & 0xf8) |
1060 ((val
>> 13) & 0x7),
1061 ((val
>> 3) & 0xfc) |
1063 ((val
<< 3) & 0xf8) |
1064 ((val
>> 2) & 0x7) );
1066 bits
= (dstbits
+= linebytes
);
1069 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1070 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1072 for( h
= lines
- 1; h
>= 0; h
--)
1074 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1075 for( x
= 0; x
< dstwidth
; x
++ )
1078 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1079 ((val
<< 3) & 0xf8) |
1081 ((val
>> 3) & 0x00fc) |
1083 ((val
>> 8) & 0x00f8) |
1084 ((val
>> 13) & 0x7) );
1086 bits
= (dstbits
+= linebytes
);
1089 else goto notsupported
;
1098 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1099 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1101 for (h
= lines
- 1; h
>= 0; h
--)
1103 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1104 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1105 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1106 srcpixel
[2] , srcpixel
[1], *srcpixel
);
1107 bits
= (dstbits
+= linebytes
);
1110 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1111 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1113 for (h
= lines
- 1; h
>= 0; h
--)
1115 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1116 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1117 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1118 *srcpixel
, srcpixel
[1], srcpixel
[2]);
1119 bits
= (dstbits
+= linebytes
);
1123 else goto notsupported
;
1127 default: /* ? bit bmp -> 8 bit DIB */
1129 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1130 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1131 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1133 for (h
= lines
- 1; h
>= 0; h
--) {
1134 for (x
= 0; x
< dstwidth
; x
++, bits
++) {
1135 *bits
= X11DRV_DIB_MapColor((int *)colors
, 256,
1136 XGetPixel( bmpImage
, x
, h
) );
1138 bits
= (dstbits
+= linebytes
);
1144 /***********************************************************************
1145 * X11DRV_DIB_SetImageBits_RLE8
1147 * SetDIBits for an 8-bit deep compressed DIB.
1149 * This function rewritten 941113 by James Youngman. WINE blew out when I
1150 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1152 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1153 * 'End of bitmap' escape code. This code is very much laxer in what it
1154 * allows to end the expansion. Possibly too lax. See the note by
1155 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1156 * bitmap should end with RleEnd, but on the other hand, software exists
1157 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1160 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1161 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1165 enum Rle8_EscapeCodes
1168 * Apologies for polluting your file's namespace...
1170 RleEol
= 0, /* End of line */
1171 RleEnd
= 1, /* End of bitmap */
1172 RleDelta
= 2 /* Delta */
1175 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1176 DWORD width
, DWORD dstwidth
,
1177 int left
, int *colors
,
1180 int x
; /* X-positon on each line. Increases. */
1181 int line
; /* Line #. Starts at lines-1, decreases */
1182 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1183 BYTE length
; /* The length pf a run */
1184 BYTE color_index
; /* index into colors[] as read from bits */
1185 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1186 int color
; /* value of colour[color_index] */
1188 if (lines
== 0) /* Let's hope this doesn't happen. */
1192 * Note that the bitmap data is stored by Windows starting at the
1193 * bottom line of the bitmap and going upwards. Within each line,
1194 * the data is stored left-to-right. That's the reason why line
1195 * goes from lines-1 to 0. [JAY]
1205 * If the length byte is not zero (which is the escape value),
1206 * We have a run of length pixels all the same colour. The colour
1207 * index is stored next.
1209 * If the length byte is zero, we need to read the next byte to
1210 * know what to do. [JAY]
1215 * [Run-Length] Encoded mode
1217 color_index
= (*pIn
++); /* Get the colour index. */
1218 color
= colors
[color_index
];
1221 XPutPixel(bmpImage
, x
++, line
, color
);
1226 * Escape codes (may be an absolute sequence though)
1228 escape_code
= (*pIn
++);
1231 case RleEol
: /* =0, end of line */
1238 case RleEnd
: /* =1, end of bitmap */
1241 * Not all RLE8 bitmaps end with this
1242 * code. For example, Paint Shop Pro
1243 * produces some that don't. That's (I think)
1244 * what caused the previous implementation to
1247 line
=-1; /* Cause exit from do loop. */
1251 case RleDelta
: /* =2, a delta */
1254 * Note that deltaing to line 0
1255 * will cause an exit from the loop,
1256 * which may not be what is intended.
1257 * The fact that there is a delta in the bits
1258 * almost certainly implies that there is data
1259 * to follow. You may feel that we should
1260 * jump to the top of the loop to avoid exiting
1263 * TODO: Decide what to do here in that case. [JAY]
1269 TRACE("Delta to last line of bitmap "
1270 "(wrongly?) causes loop exit\n");
1275 default: /* >2, switch to absolute mode */
1280 length
= escape_code
;
1283 color_index
= (*pIn
++);
1284 XPutPixel(bmpImage
, x
++, line
,
1285 colors
[color_index
]);
1289 * If you think for a moment you'll realise that the
1290 * only time we could ever possibly read an odd
1291 * number of bytes is when there is a 0x00 (escape),
1292 * a value >0x02 (absolute mode) and then an odd-
1293 * length run. Therefore this is the only place we
1294 * need to worry about it. Everywhere else the
1295 * bytes are always read in pairs. [JAY]
1297 if (escape_code
& 1)
1298 pIn
++; /* Throw away the pad byte. */
1301 } /* switch (escape_code) : Escape sequence */
1302 } /* process either an encoded sequence or an escape sequence */
1304 /* We expect to come here more than once per line. */
1305 } while (line
>= 0); /* Do this until the bitmap is filled */
1308 * Everybody comes here at the end.
1309 * Check how we exited the loop and print a message if it's a bit odd.
1312 if ( (*(pIn
-2) != 0/*escape*/) || (*(pIn
-1)!= RleEnd
) )
1314 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1315 "bytes were: %02X %02X.\n", (int)*(pIn
-2),(int)*(pIn
-1));
1320 /***********************************************************************
1321 * X11DRV_DIB_SetImageBits_16
1323 * SetDIBits for a 16-bit deep DIB.
1325 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1326 DWORD srcwidth
, DWORD dstwidth
, int left
,
1327 DC
*dc
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1333 /* align to 32 bit */
1334 DWORD linebytes
= (srcwidth
* 2 + 3) & ~3;
1339 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1340 linebytes
= -linebytes
;
1343 switch ( bmpImage
->depth
)
1346 /* using same format as XImage */
1347 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1348 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1349 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1350 else /* We need to do a conversion from a 565 dib */
1352 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1354 int div
= dstwidth
% 2;
1356 for (h
= lines
- 1; h
>= 0; h
--) {
1357 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1358 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1360 *dstpixel
++ = ((val
>> 1) & 0x7fe07fe0) | (val
& 0x001f001f); /* Red & Green & Blue */
1362 if (div
!= 0) /* Odd width? */
1363 *dstpixel
= ((*(WORD
*)ptr
>> 1) & 0x7fe0) | (*(WORD
*)ptr
& 0x001f);
1364 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1370 /* using same format as XImage */
1371 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1372 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1373 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1374 else /* We need to do a conversion from a 555 dib */
1376 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1378 int div
= dstwidth
% 2;
1380 for (h
= lines
- 1; h
>= 0; h
--) {
1381 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1382 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1384 *dstpixel
++ = ((val
<< 1) & 0xffc0ffc0) | ((val
>> 4) & 0x00200020) | /* Red & Green */
1385 (val
& 0x001f001f); /* Blue */
1387 if (div
!= 0) /* Odd width? */
1388 *dstpixel
= ((*(WORD
*)ptr
<< 1) & 0xffc0) | ((*(WORD
*)ptr
>> 4) & 0x0020)
1389 | (*(WORD
*)ptr
& 0x001f);
1390 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1399 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1402 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1403 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1405 for (h
= lines
- 1; h
>= 0; h
--) {
1406 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1407 for (x
= 0; x
< dstwidth
; x
++) {
1410 *dstpixel
++ = ((val
<< 9) & 0xf80000) | ((val
<< 4) & 0x070000) | /* Red */
1411 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1412 ((val
<< 3) & 0x0000f8) | ((val
>> 2) & 0x000007); /* Blue */
1414 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1417 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1418 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1420 for (h
= lines
- 1; h
>= 0; h
--) {
1421 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1422 for (x
= 0; x
< dstwidth
; x
++) {
1425 *dstpixel
++ = ((val
>> 7) & 0x0000f8) | ((val
>> 12) & 0x000007) | /* Red */
1426 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1427 ((val
<< 19) & 0xf80000) | ((val
>> 14) & 0x070000); /* Blue */
1429 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1440 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1444 /* Set color scaling values */
1445 if ( rSrc
== 0x7c00 ) { sc1
= 7; sc2
= 2; } /* 555 dib */
1446 else { sc1
= 8; sc2
= 3; } /* 565 dib */
1448 for (h
= lines
- 1; h
>= 0; h
--) {
1449 for (x
= left
; x
< dstwidth
+left
; x
++) {
1451 XPutPixel( bmpImage
, x
, h
,
1452 X11DRV_PALETTE_ToPhysical(dc
, RGB(((val
& rSrc
) >> sc1
), /* Red */
1453 ((val
& gSrc
) >> sc2
), /* Green */
1454 ((val
& bSrc
) << 3)))); /* Blue */
1456 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
1462 FIXME("16 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
1469 /***********************************************************************
1470 * X11DRV_DIB_GetImageBits_16
1472 * GetDIBits for an 16-bit deep DIB.
1474 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
1475 DWORD dstwidth
, DWORD srcwidth
,
1476 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
1481 /* align to 32 bit */
1482 DWORD linebytes
= (dstwidth
* 2 + 3) & ~3;
1487 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
1488 linebytes
= -linebytes
;
1491 switch ( bmpImage
->depth
)
1494 /* ==== 555 BGR bitmap to 555 BGR dib ==== */
1495 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1496 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+= linebytes
)
1497 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, srcwidth
*2 );
1499 /* ==== 555 RGB bitmap to 555 BGR dib ==== */
1500 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1502 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1504 int div
= srcwidth
% 2;
1506 for (h
= lines
- 1; h
>= 0; h
--) {
1507 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1508 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1510 *ptr
++ = ((val
<< 10) & 0xf800f800) | (val
& 0x03e003e0) | /* Red & Green */
1511 ((val
>> 10) & 0x001f001f); /* Blue */
1513 if (div
!= 0) /* Odd width? */
1514 *ptr
= ((*(WORD
*)srcpixel
<< 1) & 0xffc0) | ((*(WORD
*)srcpixel
>> 4) & 0x0020) |
1515 (*(WORD
*)srcpixel
& 0x001f);
1516 ptr
= (LPDWORD
)(dstbits
+= linebytes
);
1519 else goto notsupported
;
1525 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1527 int div
= srcwidth
% 2;
1529 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1530 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f )
1532 for (h
= lines
- 1; h
>= 0; h
--) {
1533 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1534 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1536 *ptr
++ = ((val
>> 1) & 0x7fe07fe0) | /* Red & Green */
1537 (val
& 0x001f001f); /* Blue */
1539 if (div
!= 0) /* Odd width? */
1540 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1541 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1544 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1545 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1547 for (h
= lines
- 1; h
>= 0; h
--) {
1548 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1549 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1551 *ptr
++ = ((val
<< 10) & 0x7c007c00) | ((val
>> 1) & 0x03e003e0) | /* Red & Green */
1552 ((val
>> 11) & 0x001f001f); /* Blue */
1554 if (div
!= 0) /* Odd width? */
1555 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1556 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1559 else goto notsupported
;
1567 LPWORD ptr
= (LPWORD
)dstbits
;
1570 /* ==== 24/32 BGR bitmap to 555 BGR dib ==== */
1571 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1573 for (h
= lines
- 1; h
>= 0; h
--) {
1574 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1575 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1577 *ptr
= ((val
>> 9) & 0x7c00) | /* Red */
1578 ((val
>> 6) & 0x03e0) | /* Green */
1579 ((val
>> 3) & 0x001f); /* Blue */
1581 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1584 /* ==== 24/32 RGB bitmap to 555 BGR dib ==== */
1585 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1587 for (h
= lines
- 1; h
>= 0; h
--) {
1588 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1589 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1591 *ptr
= ((val
<< 7) & 0x7c00) | /* Red */
1592 ((val
>> 6) & 0x03e0) | /* Green */
1593 ((val
>> 19) & 0x001f); /* Blue */
1595 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1598 else goto notsupported
;
1603 /* ==== monochrome bitmap to 16 BGR dib ==== */
1605 /* ==== 4 colormap bitmap to 16 BGR dib ==== */
1606 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1608 LPWORD ptr
= (LPWORD
)dstbits
;
1611 for (h
= lines
- 1; h
>= 0; h
--) {
1612 for (x
= 0; x
< dstwidth
; x
++) {
1613 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
1614 *ptr
++ = ((val
.peRed
<< 7) & 0x7c00) |
1615 ((val
.peGreen
<< 2) & 0x03e0) |
1616 ((val
.peBlue
>> 3) & 0x001f);
1618 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1621 else goto notsupported
;
1626 /* ==== 8 colormap bitmap to 16 BGR dib ==== */
1627 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1629 LPWORD ptr
= (LPWORD
)dstbits
;
1633 for (h
= lines
- 1; h
>= 0; h
--) {
1634 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1635 for (x
= 0; x
< dstwidth
; x
++) {
1636 val
= srccolors
[(int)*srcpixel
++];
1637 *ptr
++ = ((val
.peRed
<< 7) & 0x7c00) |
1638 ((val
.peGreen
<< 2) & 0x03e0) |
1639 ((val
.peBlue
>> 3) & 0x001f);
1641 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1644 else goto notsupported
;
1652 LPWORD ptr
= (LPWORD
)dstbits
;
1654 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 16 bit DIB\n",
1655 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1656 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1657 for (h
= lines
- 1; h
>= 0; h
--)
1659 for (x
= 0; x
< dstwidth
; x
++, ptr
++)
1661 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
1662 r
= (BYTE
) GetRValue(pixel
);
1663 g
= (BYTE
) GetGValue(pixel
);
1664 b
= (BYTE
) GetBValue(pixel
);
1665 *ptr
= ( ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f) );
1667 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1675 /***********************************************************************
1676 * X11DRV_DIB_SetImageBits_24
1678 * SetDIBits for a 24-bit deep DIB.
1680 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
1681 DWORD srcwidth
, DWORD dstwidth
, int left
,
1682 DC
*dc
, XImage
*bmpImage
)
1687 /* align to 32 bit */
1688 DWORD linebytes
= (srcwidth
* 3 + 3) & ~3;
1693 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1694 linebytes
= -linebytes
;
1697 switch ( bmpImage
->depth
)
1701 if (bmpImage
->bits_per_pixel
== 24) {
1702 int tocopy
= linebytes
;
1704 BYTE
*ptr
= (BYTE
*)(srcbits
+left
*3);
1706 if (tocopy
< 0 ) tocopy
= -tocopy
;
1707 dstpixel
= bmpImage
->data
+ lines
*tocopy
+ left
*3;
1708 for(h
= lines
; h
-- ; ) {
1710 memcpy(dstpixel
,ptr
,tocopy
);
1718 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 ) /* packed BGR to unpacked BGR */
1720 DWORD
*dstpixel
, val
, buf
;
1721 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1723 int div
= dstwidth
% 4;
1726 for(h
= lines
- 1; h
>= 0; h
--)
1728 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1730 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1732 *dstpixel
++ = buf
&0x00ffffff; /* b1, g1, r1 */
1733 val
= (buf
>> 24); /* b2 */
1735 *dstpixel
++ = (val
| (buf
<<8)) &0x00ffffff; /* g2, r2 */
1736 val
= (buf
>> 16); /* b3, g3 */
1738 *dstpixel
++ = (val
| (buf
<<16)) &0x00ffffff; /* r3 */
1739 *dstpixel
++ = (buf
>> 8); /* b4, g4, r4 */
1741 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1743 *dstpixel
++ = *(DWORD
*)bits
& 0x00ffffff; /* b, g, r */
1745 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1748 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff ) /* packed BGR to unpacked RGB */
1750 DWORD
*dstpixel
, val
, buf
;
1751 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1753 int div
= dstwidth
% 4;
1756 for(h
= lines
- 1; h
>= 0; h
--)
1758 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1760 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1762 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b1, g1, r1 */
1763 val
= ((buf
&0xff000000)>>8); /* b2 */
1765 *dstpixel
++ = val
| ((buf
&0xff)<<8) | ((buf
&0xff00)>>8); /* g2, r2 */
1766 val
= (buf
&0xff0000) | ((buf
&0xff000000)>>16); /* b3, g3 */
1768 *dstpixel
++ = val
| (buf
&0xff); /* r3 */
1769 *dstpixel
++ = ((buf
&0xff00)<<8) | ((buf
&0xff0000)>>8) | (buf
>>24); /* b4, g4, r4 */
1771 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1773 buf
= *(DWORD
*)bits
;
1774 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b, g, r */
1776 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1786 if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f ) /* BGR888 to RGB555 */
1788 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1791 int div
= dstwidth
% 4;
1794 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1795 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1796 for (x
= 0; x
< dstwidth
/4; x
++) {
1797 *dstpixel
++ = (WORD
)((((val
= *ptr
++) << 7) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 19) & 0x1f));
1798 *dstpixel
++ = (WORD
)(((val
>> 17) & 0x7c00) | (((val
= *ptr
++) << 2) & 0x03e0) | ((val
>> 11) & 0x1f));
1799 *dstpixel
++ = (WORD
)(((val
>> 9) & 0x07c00) | ((val
>> 22) & 0x03e0) | (((val
= *ptr
++) >> 3) & 0x1f));
1800 *dstpixel
++ = (WORD
)(((val
>> 1) & 0x07c00) | ((val
>> 14) & 0x03e0) | ((val
>> 27) & 0x1f));
1802 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1803 *dstpixel
++ = (((WORD
)bits
[0] << 7) & 0x07c00) |
1804 (((WORD
)bits
[1] << 2) & 0x03e0) |
1805 (((WORD
)bits
[2] >> 3) & 0x001f);
1806 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1809 else if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 ) /* BGR888 to BGR555 */
1811 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1814 int div
= dstwidth
% 4;
1817 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1818 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1819 for (x
= 0; x
< dstwidth
/4; x
++) {
1820 *dstpixel
++ = (WORD
)((((val
= *ptr
++) >> 3) & 0x1f) | ((val
>> 6) & 0x03e0) | ((val
>> 9) & 0x7c00));
1821 *dstpixel
++ = (WORD
)(((val
>> 27) & 0x1f) | (((val
= *ptr
++) << 2) & 0x03e0) | ((val
>> 1) & 0x7c00));
1822 *dstpixel
++ = (WORD
)(((val
>> 19) & 0x1f) | ((val
>> 22) & 0x03e0) | (((val
= *ptr
++) << 7) & 0x7c00));
1823 *dstpixel
++ = (WORD
)(((val
>> 11) & 0x1f) | ((val
>> 14) & 0x03e0) | ((val
>> 17) & 0x7c00));
1825 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1826 *dstpixel
++ = (((WORD
)bits
[2] << 7) & 0x07c00) |
1827 (((WORD
)bits
[1] << 2) & 0x03e0) |
1828 (((WORD
)bits
[0] >> 3) & 0x001f);
1829 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1839 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1842 int div
= dstwidth
% 4;
1845 if( bmpImage
->blue_mask
== 0x001f && bmpImage
->red_mask
== 0xf800 ) /* BGR888 to BGR565 */
1847 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1848 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1849 for (x
= 0; x
< dstwidth
/4; x
++) {
1850 *dstpixel
++ = (WORD
)((((val
= *ptr
++) >> 3) & 0x1f) | ((val
>> 5) & 0x07e0) | ((val
>> 8) & 0xf800));
1851 *dstpixel
++ = (WORD
)(((val
>> 27) & 0x1f) | (((val
= *ptr
++) << 3) & 0x07e0) | ((val
) & 0xf800));
1852 *dstpixel
++ = (WORD
)(((val
>> 19) & 0x1f) | ((val
>> 21) & 0x07e0) | (((val
= *ptr
++) << 8) & 0xf800));
1853 *dstpixel
++ = (WORD
)(((val
>> 11) & 0x1f) | ((val
>> 13) & 0x07e0) | ((val
>> 16) & 0xf800));
1855 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1856 *dstpixel
++ = (((WORD
)bits
[2] << 8) & 0xf800) |
1857 (((WORD
)bits
[1] << 3) & 0x07e0) |
1858 (((WORD
)bits
[0] >> 3) & 0x001f);
1859 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1862 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x001f ) /* BGR888 to RGB565 */
1864 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1865 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1866 for (x
= 0; x
< dstwidth
/4; x
++) {
1867 *dstpixel
++ = (WORD
)((((val
= *ptr
++) << 8) & 0xf800) | ((val
>> 5) & 0x07e0) | ((val
>> 19) & 0x1f));
1868 *dstpixel
++ = (WORD
)(((val
>> 16) & 0xf800) | (((val
= *ptr
++) << 3) & 0x07e0) | ((val
>> 11) & 0x1f));
1869 *dstpixel
++ = (WORD
)(((val
>> 8) & 0xf800) | ((val
>> 21) & 0x07e0) | (((val
= *ptr
++) >> 3) & 0x1f));
1870 *dstpixel
++ = (WORD
)((val
& 0xf800) | ((val
>> 13) & 0x07e0) | ((val
>> 27) & 0x1f));
1872 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1873 *dstpixel
++ = (((WORD
)bits
[0] << 8) & 0xf800) |
1874 (((WORD
)bits
[1] << 3) & 0x07e0) |
1875 (((WORD
)bits
[2] >> 3) & 0x001f);
1876 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1888 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*3;
1890 for (h
= lines
- 1; h
>= 0; h
--) {
1891 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+=3)
1892 XPutPixel( bmpImage
, x
, h
,
1893 X11DRV_PALETTE_ToPhysical(dc
, RGB(bits
[2], bits
[1], bits
[0])));
1894 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 3;
1901 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
1902 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
1903 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1909 /***********************************************************************
1910 * X11DRV_DIB_GetImageBits_24
1912 * GetDIBits for an 24-bit deep DIB.
1914 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
1915 DWORD dstwidth
, DWORD srcwidth
,
1916 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
1921 /* align to 32 bit */
1922 DWORD linebytes
= (dstwidth
* 3 + 3) & ~3;
1927 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1928 linebytes
= -linebytes
;
1931 switch ( bmpImage
->depth
)
1935 if (bmpImage
->bits_per_pixel
== 24) {
1936 int tocopy
= linebytes
;
1938 BYTE
*ptr
= (LPBYTE
)dstbits
;
1940 if (tocopy
< 0 ) tocopy
= -tocopy
;
1941 srcpixel
= bmpImage
->data
+ lines
*tocopy
;
1942 for(h
= lines
; h
-- ; ) {
1944 memcpy(ptr
,srcpixel
,tocopy
);
1945 ptr
= (LPBYTE
)(dstbits
+=linebytes
);
1952 DWORD
*srcpixel
, buf
;
1954 DWORD
*ptr
=(DWORD
*)dstbits
;
1955 int quotient
= dstwidth
/ 4;
1956 int remainder
= dstwidth
% 4;
1959 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
1960 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 )
1962 for(h
= lines
- 1; h
>= 0; h
--)
1964 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1966 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time*/
1967 buf
= ((*srcpixel
++)&0x00ffffff); /* b1, g1, r1*/
1968 *ptr
++ = buf
| ((*srcpixel
)<<24); /* b2 */
1969 buf
= ((*srcpixel
++>>8)&0x0000ffff); /* g2, r2 */
1970 *ptr
++ = buf
| ((*srcpixel
)<<16); /* b3, g3 */
1971 buf
= ((*srcpixel
++>>16)&0x000000ff); /* r3 */
1972 *ptr
++ = buf
| ((*srcpixel
++)<<8); /* b4, g4, r4 */
1974 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
1977 *(WORD
*)bits
= buf
; /* b, g */
1978 *(bits
+2) = buf
>>16; /* r */
1980 ptr
= (DWORD
*)(dstbits
+=linebytes
);
1984 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
1985 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff )
1987 for(h
= lines
- 1; h
>= 0; h
--)
1989 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1991 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time */
1993 val
= ((buf
&0xff0000)>>16) | (buf
&0xff00) | ((buf
&0xff)<<16); /* b1, g1, r1 */
1995 *ptr
++ = val
| ((buf
&0xff0000)<<8); /* b2 */
1996 val
= ((buf
&0xff00)>>8) | ((buf
&0xff)<<8); /* g2, r2 */
1998 *ptr
++ = val
| (buf
&0xff0000) | ((buf
&0xff00)<<16); /* b3, g3 */
1999 val
= (buf
&0xff); /* r3 */
2001 *ptr
++ = val
| ((buf
&0xff0000)>>8) | ((buf
&0xff00)<<8) | (buf
<<24); /* b4, g4, r4 */
2003 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
2006 *(WORD
*)bits
= (buf
&0xff00) | ((buf
&0xff0000)>>16) ; /* b, g */
2007 *(bits
+2) = buf
; /* r */
2009 ptr
= (DWORD
*)(dstbits
+=linebytes
);
2012 else goto notsupported
;
2019 LPBYTE bits
= dstbits
;
2022 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2023 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 )
2025 for (h
= lines
- 1; h
>= 0; h
--) {
2026 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2027 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2029 bits
[2] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2030 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2031 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2033 bits
= (dstbits
+= linebytes
);
2036 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2037 else if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f )
2039 for (h
= lines
- 1; h
>= 0; h
--) {
2040 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2041 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2043 bits
[0] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2044 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2045 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2047 bits
= (dstbits
+= linebytes
);
2050 else goto notsupported
;
2057 LPBYTE bits
= dstbits
;
2060 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2061 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0xf800 )
2063 for (h
= lines
- 1; h
>= 0; h
--) {
2064 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2065 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2067 bits
[2] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2068 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2069 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2071 bits
= (dstbits
+= linebytes
);
2074 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2075 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x1f )
2077 for (h
= lines
- 1; h
>= 0; h
--) {
2078 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2079 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2081 bits
[0] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2082 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2083 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2085 bits
= (dstbits
+= linebytes
);
2088 else goto notsupported
;
2093 /* ==== monochrome bitmap to 24 BGR dib ==== */
2095 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2096 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2098 LPBYTE bits
= dstbits
;
2101 for (h
= lines
- 1; h
>= 0; h
--) {
2102 for (x
= 0; x
< dstwidth
; x
++) {
2103 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2104 *bits
++ = val
.peBlue
;
2105 *bits
++ = val
.peGreen
;
2106 *bits
++ = val
.peRed
;
2108 bits
= (dstbits
+= linebytes
);
2111 else goto notsupported
;
2116 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2117 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
)
2120 LPBYTE bits
= dstbits
;
2123 for (h
= lines
- 1; h
>= 0; h
--) {
2124 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2125 for (x
= 0; x
< dstwidth
; x
++ ) {
2126 val
= srccolors
[(int)*srcpixel
++];
2127 *bits
++ = val
.peBlue
; /*Blue*/
2128 *bits
++ = val
.peGreen
; /*Green*/
2129 *bits
++ = val
.peRed
; /*Red*/
2131 bits
= (dstbits
+= linebytes
);
2134 else goto notsupported
;
2141 LPBYTE bits
= dstbits
;
2143 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2144 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2145 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2146 for (h
= lines
- 1; h
>= 0; h
--)
2148 for (x
= 0; x
< dstwidth
; x
++, bits
+= 3)
2150 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2151 bits
[0] = GetBValue(pixel
);
2152 bits
[1] = GetGValue(pixel
);
2153 bits
[2] = GetRValue(pixel
);
2155 bits
= (dstbits
+= linebytes
);
2163 /***********************************************************************
2164 * X11DRV_DIB_SetImageBits_32
2166 * SetDIBits for a 32-bit deep DIB.
2168 static void X11DRV_DIB_SetImageBits_32( int lines
, const BYTE
*srcbits
,
2169 DWORD srcwidth
, DWORD dstwidth
, int left
,
2170 DC
*dc
, XImage
*bmpImage
)
2175 DWORD linebytes
= (srcwidth
* 4);
2180 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2181 linebytes
= -linebytes
;
2184 ptr
= (DWORD
*) srcbits
+ left
;
2186 switch ( bmpImage
->depth
)
2190 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2191 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff) {
2192 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+=linebytes
) {
2193 memcpy( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
, srcbits
+ left
*4, dstwidth
*4 );
2197 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2198 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
2202 for (h
= lines
- 1; h
>= 0; h
--) {
2203 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2204 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2205 *dstpixel
++ = ((*ptr
<< 16) & 0xff0000) | (*ptr
& 0xff00) | ((*ptr
>> 16) & 0xff);
2207 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2210 else goto notsupported
;
2215 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2216 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
2220 for (h
= lines
- 1; h
>= 0; h
--) {
2221 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2222 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2223 *dstpixel
++ = (WORD
) (((*ptr
>> 9) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 3) & 0x001f));
2225 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2228 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2229 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2233 for (h
= lines
- 1; h
>= 0; h
--) {
2234 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2235 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2236 *dstpixel
++ = (WORD
) (((*ptr
<< 7) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 19) & 0x001f));
2238 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2241 else goto notsupported
;
2246 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2247 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2251 for (h
= lines
- 1; h
>= 0; h
--) {
2252 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2253 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2254 *dstpixel
++ = (WORD
) (((*ptr
>> 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 3) & 0x001f));
2256 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2259 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2260 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
2264 for (h
= lines
- 1; h
>= 0; h
--) {
2265 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2266 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2267 *dstpixel
++ = (WORD
) (((*ptr
<< 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 19) & 0x001f));
2269 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2272 else goto notsupported
;
2280 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*4;
2282 for (h
= lines
- 1; h
>= 0; h
--) {
2283 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+= 4)
2284 XPutPixel( bmpImage
, x
, h
,
2285 X11DRV_PALETTE_ToPhysical(dc
, RGB( bits
[2], bits
[1], *bits
)));
2286 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 4;
2293 FIXME("32 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
2299 /***********************************************************************
2300 * X11DRV_DIB_GetImageBits_32
2302 * GetDIBits for an 32-bit deep DIB.
2304 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
2305 DWORD dstwidth
, DWORD srcwidth
,
2306 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
2312 /* align to 32 bit */
2313 DWORD linebytes
= (srcwidth
* 4);
2314 DWORD copybytes
= linebytes
;
2319 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2320 linebytes
= -linebytes
;
2325 switch ( bmpImage
->depth
)
2329 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2330 if ( bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff )
2331 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+=linebytes
)
2332 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, copybytes
);
2334 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2335 else if ( bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000 )
2339 for (h
= lines
- 1; h
>= 0; h
--) {
2340 srcbits
= bmpImage
->data
+ h
* bmpImage
->bytes_per_line
;
2341 for (x
= 0; x
< dstwidth
; x
++, bits
+=4, srcbits
+=2) {
2342 *(bits
+ 2) = *srcbits
++;
2343 *(bits
+ 1) = *srcbits
++;
2346 bits
= (dstbits
+= linebytes
);
2349 else goto notsupported
;
2357 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2358 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
2360 for (h
= lines
- 1; h
>= 0; h
--) {
2361 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2362 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2364 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2365 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2366 *bits
= (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2368 bits
= (dstbits
+= linebytes
);
2371 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2372 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2374 for (h
= lines
- 1; h
>= 0; h
--) {
2375 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2376 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2378 *bits
++ = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07));/*Blue*/
2379 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2380 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2382 bits
= (dstbits
+= linebytes
);
2385 else goto notsupported
;
2394 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2395 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2397 for (h
= lines
- 1; h
>= 0; h
--) {
2398 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2399 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2401 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2402 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2403 *bits
= (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2405 bits
= (dstbits
+= linebytes
);
2408 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2409 else if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2411 for (h
= lines
- 1; h
>= 0; h
--) {
2412 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2413 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2415 *bits
++ = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07));/*Blue*/
2416 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2417 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2419 bits
= (dstbits
+= linebytes
);
2422 else goto notsupported
;
2427 /* ==== monochrome bitmap to 32 BGR dib ==== */
2429 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2430 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2434 for (h
= lines
- 1; h
>= 0; h
--) {
2435 for (x
= 0; x
< dstwidth
; x
++) {
2436 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2437 *bits
++ = val
.peBlue
;
2438 *bits
++ = val
.peGreen
;
2439 *bits
++ = val
.peRed
;
2442 bits
= (dstbits
+= linebytes
);
2445 else goto notsupported
;
2450 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2451 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2456 for (h
= lines
- 1; h
>= 0; h
--) {
2457 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2458 for (x
= 0; x
< dstwidth
; x
++) {
2459 val
= srccolors
[(int)*srcpixel
++];
2460 *bits
++ = val
.peBlue
; /*Blue*/
2461 *bits
++ = val
.peGreen
; /*Green*/
2462 *bits
++ = val
.peRed
; /*Red*/
2465 bits
= (dstbits
+= linebytes
);
2468 else goto notsupported
;
2473 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2474 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2475 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2476 for (h
= lines
- 1; h
>= 0; h
--)
2478 for (x
= 0; x
< dstwidth
; x
++, bits
+= 4)
2480 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2481 bits
[0] = GetBValue(pixel
);
2482 bits
[1] = GetGValue(pixel
);
2483 bits
[2] = GetRValue(pixel
);
2485 bits
= (dstbits
+= linebytes
);
2491 /***********************************************************************
2492 * X11DRV_DIB_SetImageBits
2494 * Transfer the bits to an X image.
2495 * Helper function for SetDIBits() and SetDIBitsToDevice().
2496 * The Xlib critical section must be entered before calling this function.
2498 int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2500 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2503 if ( descr
->dc
&& descr
->dc
->w
.flags
& DC_DIRTY
)
2504 CLIPPING_UpdateGCRegion( descr
->dc
);
2507 bmpImage
= descr
->image
;
2509 bmpImage
= XCreateImage( display
, X11DRV_GetVisual(), descr
->depth
, ZPixmap
, 0, NULL
,
2510 descr
->infoWidth
, lines
, 32, 0 );
2511 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2512 if(bmpImage
->data
== NULL
) {
2513 ERR("Out of memory!");
2514 XDestroyImage( bmpImage
);
2519 /* Transfer the pixels */
2520 switch(descr
->infoBpp
)
2523 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
2524 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
2528 if (descr
->compression
) {
2529 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2530 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2531 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2533 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
2534 descr
->infoWidth
, descr
->width
,
2535 descr
->xSrc
, (int *)(descr
->colorMap
),
2538 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
2539 descr
->infoWidth
, descr
->width
,
2540 descr
->xSrc
, (int*)(descr
->colorMap
),
2544 if (descr
->compression
) {
2545 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2546 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2547 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2548 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
2549 descr
->infoWidth
, descr
->width
,
2550 descr
->xSrc
, (int *)(descr
->colorMap
),
2553 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
2554 descr
->infoWidth
, descr
->width
,
2555 descr
->xSrc
, (int *)(descr
->colorMap
),
2560 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
2561 descr
->infoWidth
, descr
->width
,
2562 descr
->xSrc
, descr
->dc
,
2563 descr
->rMask
, descr
->gMask
, descr
->bMask
,
2567 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
2568 descr
->infoWidth
, descr
->width
,
2569 descr
->xSrc
, descr
->dc
, bmpImage
);
2572 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
2573 descr
->infoWidth
, descr
->width
,
2574 descr
->xSrc
, descr
->dc
,
2578 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2584 XShmPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2585 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2586 descr
->width
, descr
->height
, FALSE
);
2587 XSync( display
, 0 );
2590 XPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2591 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2592 descr
->width
, descr
->height
);
2594 if (!descr
->image
) XDestroyImage( bmpImage
);
2598 /***********************************************************************
2599 * X11DRV_DIB_GetImageBits
2601 * Transfer the bits from an X image.
2602 * The Xlib critical section must be entered before calling this function.
2604 int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2606 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2610 bmpImage
= descr
->image
;
2612 bmpImage
= XCreateImage( display
, X11DRV_GetVisual(), descr
->depth
, ZPixmap
, 0, NULL
,
2613 descr
->infoWidth
, lines
, 32, 0 );
2614 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2615 if(bmpImage
->data
== NULL
) {
2616 ERR("Out of memory!");
2617 XDestroyImage( bmpImage
);
2621 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2622 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2623 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2625 /* Transfer the pixels */
2626 switch(descr
->infoBpp
)
2629 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
2630 descr
->infoWidth
, descr
->width
,
2631 descr
->colorMap
, descr
->palentry
,
2636 if (descr
->compression
)
2637 FIXME("Compression not yet supported!\n");
2639 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
2640 descr
->infoWidth
, descr
->width
,
2641 descr
->colorMap
, descr
->palentry
,
2646 if (descr
->compression
)
2647 FIXME("Compression not yet supported!\n");
2649 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
2650 descr
->infoWidth
, descr
->width
,
2651 descr
->colorMap
, descr
->palentry
,
2656 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
2657 descr
->infoWidth
,descr
->width
,
2658 descr
->palentry
, bmpImage
);
2662 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
2663 descr
->infoWidth
,descr
->width
,
2664 descr
->palentry
, bmpImage
);
2668 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
2669 descr
->infoWidth
, descr
->width
,
2670 descr
->palentry
, bmpImage
);
2674 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2678 if (!descr
->image
) XDestroyImage( bmpImage
);
2682 /*************************************************************************
2683 * X11DRV_SetDIBitsToDevice
2686 INT
X11DRV_SetDIBitsToDevice( DC
*dc
, INT xDest
, INT yDest
, DWORD cx
,
2687 DWORD cy
, INT xSrc
, INT ySrc
,
2688 UINT startscan
, UINT lines
, LPCVOID bits
,
2689 const BITMAPINFO
*info
, UINT coloruse
)
2691 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2692 DWORD width
, oldcy
= cy
;
2694 int height
, tmpheight
;
2695 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
2698 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
2699 &descr
.infoBpp
, &descr
.compression
) == -1)
2702 if (height
< 0) height
= -height
;
2703 if (!lines
|| (startscan
>= height
)) return 0;
2704 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2705 if (ySrc
< startscan
) ySrc
= startscan
;
2706 else if (ySrc
>= startscan
+ lines
) return 0;
2707 if (xSrc
>= width
) return 0;
2708 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
2709 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
2710 if (!cx
|| !cy
) return 0;
2712 X11DRV_SetupGCForText( dc
); /* To have the correct colors */
2713 TSXSetFunction(display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->w
.ROPmode
-1]);
2715 switch (descr
.infoBpp
)
2720 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2721 coloruse
== DIB_PAL_COLORS
? dc
: NULL
, coloruse
,
2722 dc
->w
.bitsPerPixel
, info
, &descr
.nColorMap
);
2723 if (!descr
.colorMap
) return 0;
2724 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2728 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2729 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2730 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2735 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2740 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2741 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2742 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2750 descr
.palentry
= NULL
;
2751 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2752 descr
.infoWidth
= width
;
2753 descr
.depth
= dc
->w
.bitsPerPixel
;
2754 descr
.drawable
= physDev
->drawable
;
2755 descr
.gc
= physDev
->gc
;
2757 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
2759 descr
.xDest
= dc
->w
.DCOrgX
+ XLPTODP( dc
, xDest
);
2760 descr
.yDest
= dc
->w
.DCOrgY
+ YLPTODP( dc
, yDest
) +
2761 (tmpheight
>= 0 ? oldcy
-cy
: 0);
2764 descr
.useShm
= FALSE
;
2766 EnterCriticalSection( &X11DRV_CritSection
);
2767 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
2768 LeaveCriticalSection( &X11DRV_CritSection
);
2770 if (descr
.infoBpp
<= 8)
2771 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2775 /***********************************************************************
2776 * X11DRV_DIB_SetDIBits
2778 INT
X11DRV_DIB_SetDIBits(
2779 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2780 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
,
2781 UINT coloruse
, HBITMAP hbitmap
)
2783 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2784 X11DRV_PHYSBITMAP
*pbitmap
;
2785 int height
, tmpheight
;
2790 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
2791 &descr
.infoBpp
, &descr
.compression
) == -1)
2795 if (height
< 0) height
= -height
;
2796 if (!lines
|| (startscan
>= height
))
2799 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2801 switch (descr
.infoBpp
)
2806 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2807 coloruse
== DIB_PAL_COLORS
? descr
.dc
: NULL
, coloruse
,
2808 bmp
->bitmap
.bmBitsPixel
,
2809 info
, &descr
.nColorMap
);
2810 if (!descr
.colorMap
) return 0;
2811 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2815 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2816 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2817 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2822 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2827 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2828 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2829 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2838 X11DRV_CreateBitmap(hbitmap
);
2840 pbitmap
= bmp
->DDBitmap
->physBitmap
;
2844 descr
.palentry
= NULL
;
2845 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2846 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2847 descr
.drawable
= pbitmap
->pixmap
;
2848 descr
.gc
= BITMAP_GC(bmp
);
2852 descr
.yDest
= height
- startscan
- lines
;
2853 descr
.width
= bmp
->bitmap
.bmWidth
;
2854 descr
.height
= lines
;
2855 descr
.useShm
= FALSE
;
2857 EnterCriticalSection( &X11DRV_CritSection
);
2858 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
2859 LeaveCriticalSection( &X11DRV_CritSection
);
2861 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2866 /***********************************************************************
2867 * X11DRV_DIB_GetDIBits
2869 INT
X11DRV_DIB_GetDIBits(
2870 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2871 UINT lines
, LPVOID bits
, BITMAPINFO
*info
,
2872 UINT coloruse
, HBITMAP hbitmap
)
2874 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
2875 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2876 X11DRV_PHYSBITMAP
*pbitmap
;
2877 PALETTEOBJ
* palette
;
2879 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
2880 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
2881 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
2884 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->w
.hPalette
, PALETTE_MAGIC
)))
2887 if( lines
> info
->bmiHeader
.biHeight
) lines
= info
->bmiHeader
.biHeight
;
2888 if( startscan
>= bmp
->bitmap
.bmHeight
) return FALSE
;
2890 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
2891 &descr
.infoBpp
, &descr
.compression
) == -1)
2894 switch (descr
.infoBpp
)
2900 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2904 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2905 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2906 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2910 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2911 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2912 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2918 X11DRV_CreateBitmap(hbitmap
);
2920 pbitmap
= bmp
->DDBitmap
->physBitmap
;
2923 descr
.palentry
= palette
->logpalette
.palPalEntry
;
2925 descr
.lines
= lines
;
2926 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2927 descr
.drawable
= pbitmap
->pixmap
;
2928 descr
.gc
= BITMAP_GC(bmp
);
2930 descr
.ySrc
= startscan
;
2933 descr
.width
= bmp
->bitmap
.bmWidth
;
2934 descr
.height
= bmp
->bitmap
.bmHeight
;
2935 descr
.colorMap
= info
->bmiColors
;
2938 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
2940 descr
.useShm
= FALSE
;
2942 EnterCriticalSection( &X11DRV_CritSection
);
2944 descr
.image
= (XImage
*)CALL_LARGE_STACK( X11DRV_BITMAP_GetXImage
, bmp
);
2945 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
2947 LeaveCriticalSection( &X11DRV_CritSection
);
2949 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
2950 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
2951 info
->bmiHeader
.biWidth
,
2952 info
->bmiHeader
.biHeight
,
2953 info
->bmiHeader
.biBitCount
);
2955 info
->bmiHeader
.biCompression
= 0;
2957 GDI_HEAP_UNLOCK( dc
->w
.hPalette
);
2962 /***********************************************************************
2963 * DIB_DoProtectDIBSection
2965 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
2967 DIBSECTION
*dib
= bmp
->dib
;
2968 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
2969 : -dib
->dsBm
.bmHeight
;
2970 INT totalSize
= dib
->dsBmih
.biSizeImage
? dib
->dsBmih
.biSizeImage
2971 : dib
->dsBm
.bmWidthBytes
* effHeight
;
2974 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
2975 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
2978 /***********************************************************************
2979 * X11DRV_DIB_DoUpdateDIBSection
2981 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
2983 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
2984 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2986 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
2987 &descr
.infoBpp
, &descr
.compression
) == -1)
2991 descr
.palentry
= NULL
;
2992 descr
.image
= dib
->image
;
2993 descr
.colorMap
= (RGBQUAD
*)dib
->colorMap
;
2994 descr
.nColorMap
= dib
->nColorMap
;
2995 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
2996 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2998 switch (descr
.infoBpp
)
3004 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3008 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
3009 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
3010 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
3014 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff;
3015 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0xff00;
3016 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0xff0000;
3021 descr
.drawable
= ((X11DRV_PHYSBITMAP
*)bmp
->DDBitmap
->physBitmap
)->pixmap
;
3022 descr
.gc
= BITMAP_GC(bmp
);
3027 descr
.width
= bmp
->bitmap
.bmWidth
;
3028 descr
.height
= bmp
->bitmap
.bmHeight
;
3029 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
3033 TRACE("Copying from Pixmap to DIB bits\n");
3034 EnterCriticalSection( &X11DRV_CritSection
);
3035 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
3036 LeaveCriticalSection( &X11DRV_CritSection
);
3040 TRACE("Copying from DIB bits to Pixmap\n");
3041 EnterCriticalSection( &X11DRV_CritSection
);
3042 CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
3043 LeaveCriticalSection( &X11DRV_CritSection
);
3047 /***********************************************************************
3048 * X11DRV_DIB_FaultHandler
3050 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
3052 BOOL handled
= FALSE
;
3055 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
3056 if (!bmp
) return FALSE
;
3059 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3061 case X11DRV_DIB_GdiMod
:
3062 TRACE("called in status DIB_GdiMod\n" );
3063 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3064 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3065 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3066 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
3070 case X11DRV_DIB_InSync
:
3071 TRACE("called in status X11DRV_DIB_InSync\n" );
3072 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3073 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_AppMod
;
3077 case X11DRV_DIB_AppMod
:
3078 FIXME("called in status X11DRV_DIB_AppMod: this can't happen!\n" );
3081 case X11DRV_DIB_NoHandler
:
3082 FIXME("called in status DIB_NoHandler: this can't happen!\n" );
3086 GDI_HEAP_UNLOCK( (HBITMAP
)res
);
3090 /***********************************************************************
3091 * X11DRV_DIB_UpdateDIBSection
3093 void X11DRV_DIB_UpdateDIBSection(DC
*dc
, BOOL toDIB
)
3097 /* Ensure this is a Compatible DC that has a DIB section selected */
3100 if (!(dc
->w
.flags
& DC_MEMORY
)) return;
3102 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( dc
->w
.hBitmap
, BITMAP_MAGIC
);
3107 GDI_HEAP_UNLOCK(dc
->w
.hBitmap
);
3113 /* Prepare for access to the DIB by GDI functions */
3115 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3118 case X11DRV_DIB_NoHandler
:
3119 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3122 case X11DRV_DIB_GdiMod
:
3123 TRACE("fromDIB called in status X11DRV_DIB_GdiMod\n" );
3127 case X11DRV_DIB_InSync
:
3128 TRACE("fromDIB called in status X11DRV_DIB_InSync\n" );
3132 case X11DRV_DIB_AppMod
:
3133 TRACE("fromDIB called in status X11DRV_DIB_AppMod\n" );
3134 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3135 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3136 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
3142 /* Acknowledge write access to the DIB by GDI functions */
3144 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3147 case X11DRV_DIB_NoHandler
:
3148 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3151 case X11DRV_DIB_GdiMod
:
3152 TRACE(" toDIB called in status X11DRV_DIB_GdiMod\n" );
3156 case X11DRV_DIB_InSync
:
3157 TRACE(" toDIB called in status X11DRV_DIB_InSync\n" );
3158 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3159 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_GdiMod
;
3162 case X11DRV_DIB_AppMod
:
3163 FIXME(" toDIB called in status X11DRV_DIB_AppMod: "
3164 "this can't happen!\n" );
3169 GDI_HEAP_UNLOCK(dc
->w
.hBitmap
);
3172 /***********************************************************************
3173 * X11DRV_DIB_CreateDIBSection16
3175 HBITMAP16
X11DRV_DIB_CreateDIBSection16(
3176 DC
*dc
, BITMAPINFO
*bmi
, UINT16 usage
,
3177 SEGPTR
*bits
, HANDLE section
,
3180 HBITMAP res
= X11DRV_DIB_CreateDIBSection(dc
, bmi
, usage
, NULL
,
3184 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3185 if ( bmp
&& bmp
->dib
)
3187 DIBSECTION
*dib
= bmp
->dib
;
3188 INT height
= dib
->dsBm
.bmHeight
>= 0 ?
3189 dib
->dsBm
.bmHeight
: -dib
->dsBm
.bmHeight
;
3190 INT size
= dib
->dsBmih
.biSizeImage
?
3191 dib
->dsBmih
.biSizeImage
: dib
->dsBm
.bmWidthBytes
* height
;
3192 if ( dib
->dsBm
.bmBits
)
3194 ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
=
3195 SELECTOR_AllocBlock( dib
->dsBm
.bmBits
, size
,
3196 SEGMENT_DATA
, FALSE
, FALSE
);
3198 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3199 dib
->dsBm
.bmBits
, size
, ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
,
3200 PTR_SEG_OFF_TO_SEGPTR(((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0));
3202 GDI_HEAP_UNLOCK( res
);
3205 *bits
= PTR_SEG_OFF_TO_SEGPTR( ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0 );
3211 /***********************************************************************
3212 * X11DRV_XShmErrorHandler
3215 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
)
3221 /***********************************************************************
3222 * X11DRV_XShmCreateImage
3226 extern BOOL
X11DRV_XShmCreateImage(XImage
** image
, int width
, int height
, int bpp
,
3227 XShmSegmentInfo
* shminfo
)
3229 int (*WineXHandler
)(Display
*, XErrorEvent
*);
3231 *image
= TSXShmCreateImage(display
, X11DRV_GetVisual(), bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
3232 if( *image
!= NULL
)
3234 EnterCriticalSection( &X11DRV_CritSection
);
3235 shminfo
->shmid
= shmget(IPC_PRIVATE
, (*image
)->bytes_per_line
* height
,
3237 if( shminfo
->shmid
!= -1 )
3239 shminfo
->shmaddr
= (*image
)->data
= shmat(shminfo
->shmid
, 0, 0);
3240 if( shminfo
->shmaddr
!= (char*)-1 )
3242 shminfo
->readOnly
= FALSE
;
3243 if( TSXShmAttach( display
, shminfo
) != 0)
3245 /* Reset the error flag */
3247 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
3248 XSync( display
, 0 );
3252 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3254 XSetErrorHandler(WineXHandler
);
3255 LeaveCriticalSection( &X11DRV_CritSection
);
3257 return TRUE
; /* Success! */
3259 /* An error occured */
3261 XSetErrorHandler(WineXHandler
);
3263 shmdt(shminfo
->shmaddr
);
3265 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3268 XDestroyImage(*image
);
3269 LeaveCriticalSection( &X11DRV_CritSection
);
3277 /***********************************************************************
3278 * X11DRV_DIB_CreateDIBSection
3280 HBITMAP
X11DRV_DIB_CreateDIBSection(
3281 DC
*dc
, BITMAPINFO
*bmi
, UINT usage
,
3282 LPVOID
*bits
, HANDLE section
,
3286 BITMAPOBJ
*bmp
= NULL
;
3287 X11DRV_DIBSECTION
*dib
= NULL
;
3288 int *colorMap
= NULL
;
3291 /* Fill BITMAP32 structure with DIB data */
3292 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
3293 INT effHeight
, totalSize
;
3296 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3297 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
3298 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
3300 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
3302 bm
.bmWidth
= bi
->biWidth
;
3303 bm
.bmHeight
= effHeight
;
3304 bm
.bmWidthBytes
= DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
3305 bm
.bmPlanes
= bi
->biPlanes
;
3306 bm
.bmBitsPixel
= bi
->biBitCount
;
3309 /* Get storage location for DIB bits */
3310 totalSize
= bi
->biSizeImage
? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
3313 bm
.bmBits
= MapViewOfFile(section
, FILE_MAP_ALL_ACCESS
,
3314 0L, offset
, totalSize
);
3316 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
3317 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
3319 /* Create Color Map */
3320 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
3321 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? dc
: NULL
,
3322 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
3324 /* Allocate Memory for DIB and fill structure */
3326 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
3329 dib
->dibSection
.dsBm
= bm
;
3330 dib
->dibSection
.dsBmih
= *bi
;
3332 /* Set dsBitfields values */
3333 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
3335 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
3337 else switch( bi
->biBitCount
)
3340 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
3341 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
3342 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
3346 dib
->dibSection
.dsBitfields
[0] = 0xff;
3347 dib
->dibSection
.dsBitfields
[1] = 0xff00;
3348 dib
->dibSection
.dsBitfields
[2] = 0xff0000;
3352 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff;
3353 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0xff00;
3354 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0xff0000;
3357 dib
->dibSection
.dshSection
= section
;
3358 dib
->dibSection
.dsOffset
= offset
;
3360 dib
->status
= X11DRV_DIB_NoHandler
;
3363 dib
->nColorMap
= nColorMap
;
3364 dib
->colorMap
= colorMap
;
3367 /* Create Device Dependent Bitmap and add DIB pointer */
3370 res
= CreateDIBitmap(dc
->hSelf
, bi
, 0, NULL
, bmi
, usage
);
3373 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3376 bmp
->dib
= (DIBSECTION
*) dib
;
3379 X11DRV_CreateBitmap(res
);
3387 if (TSXShmQueryExtension(display
) &&
3388 X11DRV_XShmCreateImage( &dib
->image
, bm
.bmWidth
, effHeight
,
3389 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
) )
3391 ; /* Created Image */
3393 XCREATEIMAGE( dib
->image
, bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
3394 dib
->shminfo
.shmid
= -1;
3398 /* Clean up in case of errors */
3399 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
3401 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3402 res
, bmp
, dib
, bm
.bmBits
);
3406 UnmapViewOfFile(bm
.bmBits
), bm
.bmBits
= NULL
;
3408 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
3411 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
3412 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
3413 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
3414 if (res
) { DeleteObject(res
); res
= 0; }
3417 /* Install fault handler, if possible */
3420 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
3422 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3423 if (dib
) dib
->status
= X11DRV_DIB_InSync
;
3427 /* Return BITMAP handle and storage location */
3428 if (res
) GDI_HEAP_UNLOCK(res
);
3429 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
3433 /***********************************************************************
3434 * X11DRV_DIB_DeleteDIBSection
3436 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
3438 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3442 if (dib
->shminfo
.shmid
!= -1)
3444 TSXShmDetach (display
, &(dib
->shminfo
));
3445 XDestroyImage (dib
->image
);
3446 shmdt (dib
->shminfo
.shmaddr
);
3447 dib
->shminfo
.shmid
= -1;
3450 XDestroyImage( dib
->image
);
3454 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
3458 WORD count
= (GET_SEL_LIMIT( dib
->selector
) >> 16) + 1;
3459 SELECTOR_FreeBlock( dib
->selector
, count
);
3464 /**************************************************************************
3465 * X11DRV_DIB_CreateDIBFromPixmap
3467 * Allocates a packed DIB and copies the Pixmap data into it.
3468 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
3470 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
3473 BITMAPOBJ
*pBmp
= NULL
;
3474 HGLOBAL hPackedDIB
= 0;
3476 /* Allocates an HBITMAP which references the Pixmap passed to us */
3477 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
3480 TRACE("\tCould not create bitmap header for Pixmap\n");
3485 * Create a packed DIB from the Pixmap wrapper bitmap created above.
3486 * A packed DIB contains a BITMAPINFO structure followed immediately by
3487 * an optional color palette and the pixel data.
3489 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
3491 /* Get a pointer to the BITMAPOBJ structure */
3492 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3494 /* We can now get rid of the HBITMAP wrapper we created earlier.
3495 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
3499 /* Manually free the DDBitmap internals to prevent the Pixmap
3500 * from being deleted by DeleteObject.
3502 HeapFree( GetProcessHeap(), 0, pBmp
->DDBitmap
->physBitmap
);
3503 HeapFree( GetProcessHeap(), 0, pBmp
->DDBitmap
);
3504 pBmp
->DDBitmap
= NULL
;
3509 TRACE("\tReturning packed DIB %x\n", hPackedDIB
);
3514 /**************************************************************************
3515 * X11DRV_DIB_CreatePixmapFromDIB
3517 * Creates a Pixmap from a packed DIB
3519 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
3521 Pixmap pixmap
= None
;
3523 BITMAPOBJ
*pBmp
= NULL
;
3524 LPBYTE pPackedDIB
= NULL
;
3525 LPBITMAPINFO pbmi
= NULL
;
3526 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
3527 LPBYTE pbits
= NULL
;
3529 /* Get a pointer to the packed DIB's data */
3530 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
3531 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
3532 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
3533 pbits
= (LPBYTE
)(pPackedDIB
3534 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
3536 /* Create a DDB from the DIB */
3538 hBmp
= CreateDIBitmap(hdc
,
3545 GlobalUnlock(hPackedDIB
);
3547 TRACE("CreateDIBitmap returned %x\n", hBmp
);
3549 /* Retrieve the internal Pixmap from the DDB */
3551 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3553 if (pBmp
->DDBitmap
&& pBmp
->DDBitmap
->physBitmap
)
3555 pixmap
= ((X11DRV_PHYSBITMAP
*)(pBmp
->DDBitmap
->physBitmap
))->pixmap
;
3557 TRACE("NULL Pixmap in DDBitmap->physBitmap!\n");
3559 /* Manually free the BITMAPOBJ internals so that we can steal its pixmap */
3560 HeapFree( GetProcessHeap(), 0, pBmp
->DDBitmap
->physBitmap
);
3561 HeapFree( GetProcessHeap(), 0, pBmp
->DDBitmap
);
3562 pBmp
->DDBitmap
= NULL
; /* Its not a DDB anymore */
3565 /* Delete the DDB we created earlier now that we have stolen its pixmap */
3568 TRACE("\tReturning Pixmap %ld\n", pixmap
);
3572 #endif /* !defined(X_DISPLAY_MISSING) */