2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
13 # ifdef HAVE_SYS_SHM_H
16 # ifdef HAVE_SYS_IPC_H
19 #endif /* defined(HAVE_LIBXXSHM) */
25 #include "debugtools.h"
29 #include "selectors.h"
32 DEFAULT_DEBUG_CHANNEL(bitmap
)
33 DECLARE_DEBUG_CHANNEL(x11drv
)
35 static int bitmapDepthTable
[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
36 static int ximageDepthTable
[] = { 0, 0, 0, 0, 0, 0, 0 };
38 static int XShmErrorFlag
= 0;
40 /***********************************************************************
43 BOOL
X11DRV_DIB_Init(void)
48 for( i
= 0; bitmapDepthTable
[i
]; i
++ )
50 testimage
= TSXCreateImage(display
, X11DRV_GetVisual(),
51 bitmapDepthTable
[i
], ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
52 if( testimage
) ximageDepthTable
[i
] = testimage
->bits_per_pixel
;
54 TSXDestroyImage(testimage
);
60 /***********************************************************************
61 * X11DRV_DIB_GetXImageWidthBytes
63 * Return the width of an X image in bytes
65 int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
69 if (!ximageDepthTable
[0]) {
72 for( i
= 0; bitmapDepthTable
[i
] ; i
++ )
73 if( bitmapDepthTable
[i
] == depth
)
74 return (4 * ((width
* ximageDepthTable
[i
] + 31)/32));
76 WARN("(%d): Unsupported depth\n", depth
);
80 /***********************************************************************
81 * X11DRV_DIB_BuildColorMap
83 * Build the color map from the bitmap palette. Should not be called
84 * for a >8-bit deep bitmap.
86 int *X11DRV_DIB_BuildColorMap( DC
*dc
, WORD coloruse
, WORD depth
,
87 const BITMAPINFO
*info
, int *nColors
)
94 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
96 colors
= info
->bmiHeader
.biClrUsed
;
97 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
98 colorPtr
= (WORD
*)info
->bmiColors
;
100 else /* assume BITMAPCOREINFO */
102 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
103 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
108 ERR("called with >256 colors!\n");
112 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
113 colors
* sizeof(int) )))
116 if (coloruse
== DIB_RGB_COLORS
)
120 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
122 if (depth
== 1) /* Monochrome */
123 for (i
= 0; i
< colors
; i
++, rgb
++)
124 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
125 rgb
->rgbBlue
> 255*3/2);
127 for (i
= 0; i
< colors
; i
++, rgb
++)
128 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbRed
,
134 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
136 if (depth
== 1) /* Monochrome */
137 for (i
= 0; i
< colors
; i
++, rgb
++)
138 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
139 rgb
->rgbtBlue
> 255*3/2);
141 for (i
= 0; i
< colors
; i
++, rgb
++)
142 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbtRed
,
147 else /* DIB_PAL_COLORS */
149 for (i
= 0; i
< colors
; i
++, colorPtr
++)
150 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(*colorPtr
) );
158 /***********************************************************************
159 * X11DRV_DIB_MapColor
161 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
)
165 for (color
= 0; color
< nPhysMap
; color
++)
166 if (physMap
[color
] == phys
)
169 WARN("Strange color %08x\n", phys
);
174 /*********************************************************************
175 * X11DRV_DIB_GetNearestIndex
177 * Helper for X11DRV_DIB_GetDIBits.
178 * Returns the nearest colour table index for a given RGB.
179 * Nearest is defined by minimizing the sum of the squares.
181 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
183 INT i
, best
= -1, diff
, bestdiff
= -1;
186 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
187 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
188 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
189 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
192 if(best
== -1 || diff
< bestdiff
) {
200 /***********************************************************************
201 * X11DRV_DIB_SetImageBits_1_Line
203 * Handles a single line of 1 bit data.
205 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth
, int left
, int *colors
,
206 XImage
*bmpImage
, int h
, const BYTE
*bits
)
211 if((extra
= (left
& 7)) != 0) {
218 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
219 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--)
222 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
223 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 6) & 1] );
224 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 5) & 1] );
225 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 4) & 1] );
226 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 3) & 1] );
227 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 2) & 1] );
228 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 1) & 1] );
229 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 1] );
234 case 7: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
235 case 6: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
236 case 5: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
237 case 4: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
238 case 3: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
239 case 2: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
240 case 1: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
244 /***********************************************************************
245 * X11DRV_DIB_SetImageBits_1
247 * SetDIBits for a 1-bit deep DIB.
249 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
250 DWORD srcwidth
, DWORD dstwidth
, int left
,
251 int *colors
, XImage
*bmpImage
)
256 DWORD linebytes
= ((srcwidth
+ 31) & ~31) / 8;
259 for (h
= lines
-1; h
>=0; h
--) {
260 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
262 srcbits
+= linebytes
;
266 for (h
= 0; h
< lines
; h
++) {
267 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
269 srcbits
+= linebytes
;
274 /***********************************************************************
275 * X11DRV_DIB_GetImageBits_1
277 * GetDIBits for a 1-bit deep DIB.
279 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
280 DWORD dstwidth
, DWORD srcwidth
,
281 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
289 DWORD linebytes
= ((dstwidth
+ 31) & ~31) / 8;
293 dstbits
= dstbits
+ linebytes
* (lines
- 1);
294 linebytes
= -linebytes
;
299 switch(bmpImage
->depth
) {
302 /* ==== monochrome bitmap to monochrome dib ==== */
304 /* ==== 4 colormap bitmap to monochrome dib ==== */
305 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
309 for (h
= lines
- 1; h
>= 0; h
--) {
310 for (x
= 0; x
< dstwidth
; x
++) {
311 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
312 if (!(x
&7)) *bits
= 0;
313 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2,
316 val
.peBlue
) << (7 - (x
& 7)));
317 if ((x
&7)==7) bits
++;
319 bits
= (dstbits
+= linebytes
);
322 else goto notsupported
;
327 /* ==== 8 colormap bitmap to monochrome dib ==== */
328 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
333 for( h
= lines
- 1; h
>= 0; h
-- ) {
334 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
335 for( x
= 0; x
< dstwidth
; x
++ ) {
336 if (!(x
&7)) *bits
= 0;
337 val
= srccolors
[(int)*srcpixel
++];
338 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 2,
341 val
.peBlue
) << (7-(x
&7)) );
342 if ((x
&7)==7) bits
++;
344 bits
= (dstbits
+= linebytes
);
347 else goto notsupported
;
356 /* ==== 555 BGR bitmap to monochrome dib ==== */
357 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
359 for( h
= lines
- 1; h
>= 0; h
--) {
360 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
361 for( x
= 0; x
< dstwidth
; x
++) {
362 if (!(x
&7)) *bits
= 0;
364 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
365 ((val
>> 7) & 0xf8) |
367 ((val
>> 2) & 0xf8) |
369 ((val
<< 3) & 0xf8) |
370 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
371 if ((x
&7)==7) bits
++;
373 bits
= (dstbits
+= linebytes
);
376 /* ==== 555 RGB bitmap to monochrome dib ==== */
377 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
379 for( h
= lines
- 1; h
>= 0; h
--)
381 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
382 for( x
= 0; x
< dstwidth
; x
++) {
383 if (!(x
&1)) *bits
= 0;
385 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
386 ((val
<< 3) & 0xf8) |
388 ((val
>> 2) & 0xf8) |
390 ((val
>> 7) & 0xf8) |
391 ((val
>> 12) & 0x7) ) << (7-(x
&7)) );
392 if ((x
&7)==7) bits
++;
394 bits
= (dstbits
+= linebytes
);
397 else goto notsupported
;
406 /* ==== 565 BGR bitmap to monochrome dib ==== */
407 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
409 for( h
= lines
- 1; h
>= 0; h
--)
411 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
412 for( x
= 0; x
< dstwidth
; x
++) {
413 if (!(x
&7)) *bits
= 0;
415 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
416 ((val
>> 8) & 0xf8) |
418 ((val
>> 3) & 0xfc) |
420 ((val
<< 3) & 0xf8) |
421 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
422 if ((x
&7)==7) bits
++;
424 bits
= (dstbits
+= linebytes
);
427 /* ==== 565 RGB bitmap to monochrome dib ==== */
428 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
430 for( h
= lines
- 1; h
>= 0; h
--)
432 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
433 for( x
= 0; x
< dstwidth
; x
++) {
434 if (!(x
&7)) *bits
= 0;
436 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
437 ((val
<< 3) & 0xf8) |
439 ((val
>> 3) & 0xfc) |
441 ((val
>> 8) & 0xf8) |
442 ((val
>> 13) & 0x7) ) << (7-(x
&7)) );
443 if ((x
&7)==7) bits
++;
445 bits
= (dstbits
+= linebytes
);
448 else goto notsupported
;
457 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
458 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
460 for (h
= lines
- 1; h
>= 0; h
--)
462 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
463 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
464 if (!(x
&7)) *bits
= 0;
465 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << (7-(x
&7)) );
466 if ((x
&7)==7) bits
++;
468 bits
= (dstbits
+= linebytes
);
471 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
472 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
474 for (h
= lines
- 1; h
>= 0; h
--)
476 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
477 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
478 if (!(x
& 7)) *bits
= 0;
479 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << (7-(x
&7)) );
480 if ((x
& 7) == 7) bits
++;
482 bits
= (dstbits
+= linebytes
);
485 else goto notsupported
;
489 default: /* ? bit bmp -> monochrome DIB */
492 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
494 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
495 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
496 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
498 for( h
= lines
- 1; h
>= 0; h
-- ) {
499 for( x
= 0; x
< dstwidth
; x
++ ) {
500 if (!(x
&7)) *bits
= 0;
501 *bits
|= (XGetPixel( bmpImage
, x
, h
) >= white
)
503 if ((x
&7)==7) bits
++;
505 bits
= (dstbits
+= linebytes
);
512 /***********************************************************************
513 * X11DRV_DIB_SetImageBits_4
515 * SetDIBits for a 4-bit deep DIB.
517 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
518 DWORD srcwidth
, DWORD dstwidth
, int left
,
519 int *colors
, XImage
*bmpImage
)
523 const BYTE
*bits
= srcbits
+ (left
>> 1);
526 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
534 for (h
= lines
-1; h
>= 0; h
--) {
535 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
537 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
538 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
540 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
541 srcbits
+= linebytes
;
542 bits
= srcbits
+ (left
>> 1);
546 for (h
= 0; h
< lines
; h
++) {
547 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
549 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
550 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
552 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
553 srcbits
+= linebytes
;
554 bits
= srcbits
+ (left
>> 1);
561 /***********************************************************************
562 * X11DRV_DIB_GetImageBits_4
564 * GetDIBits for a 4-bit deep DIB.
566 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
567 DWORD srcwidth
, DWORD dstwidth
,
568 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
577 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
582 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
583 linebytes
= -linebytes
;
588 switch(bmpImage
->depth
) {
591 /* ==== monochrome bitmap to 4 colormap dib ==== */
593 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
594 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
598 for (h
= lines
-1; h
>= 0; h
--) {
599 for (x
= 0; x
< dstwidth
; x
++) {
600 if (!(x
&1)) *bits
= 0;
601 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
602 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 16,
605 val
.peBlue
) << (4-((x
&1)<<2)));
606 if ((x
&1)==1) bits
++;
608 bits
= (dstbits
+= linebytes
);
611 else goto notsupported
;
616 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
617 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
621 for( h
= lines
- 1; h
>= 0; h
-- ) {
622 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
623 for( x
= 0; x
< dstwidth
; x
++ ) {
624 if (!(x
&1)) *bits
= 0;
625 val
= srccolors
[(int)*srcpixel
++];
626 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 16,
629 val
.peBlue
) << (4*(1-(x
&1))) );
630 if ((x
&1)==1) bits
++;
632 bits
= (dstbits
+= linebytes
);
635 else goto notsupported
;
644 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
645 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
647 for( h
= lines
- 1; h
>= 0; h
--) {
648 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
649 for( x
= 0; x
< dstwidth
; x
++) {
650 if (!(x
&1)) *bits
= 0;
652 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
653 ((val
>> 7) & 0xf8) |
655 ((val
>> 2) & 0xf8) |
657 ((val
<< 3) & 0xf8) |
658 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
659 if ((x
&1)==1) bits
++;
661 bits
= (dstbits
+= linebytes
);
664 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
665 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
667 for( h
= lines
- 1; h
>= 0; h
--)
669 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
670 for( x
= 0; x
< dstwidth
; x
++) {
671 if (!(x
&1)) *bits
= 0;
673 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
674 ((val
<< 3) & 0xf8) |
676 ((val
>> 2) & 0xfc) |
678 ((val
>> 7) & 0xf8) |
679 ((val
>> 12) & 0x7) ) << ((1-(x
&1))<<2) );
680 if ((x
&1)==1) bits
++;
682 bits
= (dstbits
+= linebytes
);
685 else goto notsupported
;
694 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
695 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
697 for( h
= lines
- 1; h
>= 0; h
--)
699 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
700 for( x
= 0; x
< dstwidth
; x
++) {
701 if (!(x
&1)) *bits
= 0;
703 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
704 ((val
>> 8) & 0xf8) |
706 ((val
>> 3) & 0xfc) |
708 ((val
<< 3) & 0xf8) |
709 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
710 if ((x
&1)==1) bits
++;
712 bits
= (dstbits
+= linebytes
);
715 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
716 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
718 for( h
= lines
- 1; h
>= 0; h
--)
720 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
721 for( x
= 0; x
< dstwidth
; x
++) {
722 if (!(x
&1)) *bits
= 0;
724 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
725 ((val
<< 3) & 0xf8) |
727 ((val
>> 3) & 0xfc) |
729 ((val
>> 8) & 0xf8) |
730 ((val
>> 13) & 0x7) ) << ((1-(x
&1))<<2) );
731 if ((x
&1)==1) bits
++;
733 bits
= (dstbits
+= linebytes
);
736 else goto notsupported
;
745 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
746 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
748 for (h
= lines
- 1; h
>= 0; h
--)
750 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
751 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
752 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << 4) |
753 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[6] , srcpixel
[5], srcpixel
[4]);
754 bits
= (dstbits
+= linebytes
);
757 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
758 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
760 for (h
= lines
- 1; h
>= 0; h
--)
762 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
763 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
764 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << 4) |
765 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[4] , srcpixel
[5], srcpixel
[6]);
766 bits
= (dstbits
+= linebytes
);
769 else goto notsupported
;
773 default: /* ? bit bmp -> 4 bit DIB */
775 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
776 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
777 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
778 for (h
= lines
-1; h
>= 0; h
--) {
779 for (x
= 0; x
< dstwidth
/2; x
++) {
780 *bits
++ = (X11DRV_DIB_MapColor((int *)colors
, 16,
781 XGetPixel( bmpImage
, x
++, h
)) << 4)
782 | (X11DRV_DIB_MapColor((int *)colors
, 16,
783 XGetPixel( bmpImage
, x
++, h
)) & 0x0f);
786 *bits
= (X11DRV_DIB_MapColor((int *)colors
, 16,
787 XGetPixel( bmpImage
, x
++, h
)) << 4);
788 bits
= (dstbits
+= linebytes
);
794 /***********************************************************************
795 * X11DRV_DIB_SetImageBits_RLE4
797 * SetDIBits for a 4-bit deep compressed DIB.
799 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
800 DWORD width
, DWORD dstwidth
,
801 int left
, int *colors
,
804 int x
= 0, c
, length
;
805 const BYTE
*begin
= bits
;
809 while ((int)lines
>= 0) {
811 if (length
) { /* encoded */
819 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>>4]);
827 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
838 case 1: /* eopicture */
844 FIXME_(x11drv
)("x-delta is too large?\n");
850 default: /* absolute */
858 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>> 4]);
866 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
869 if ((bits
- begin
) & 1)
878 /***********************************************************************
879 * X11DRV_DIB_SetImageBits_8
881 * SetDIBits for an 8-bit deep DIB.
883 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
884 DWORD srcwidth
, DWORD dstwidth
, int left
,
885 const int *colors
, XImage
*bmpImage
)
891 /* align to 32 bit */
892 DWORD linebytes
= (srcwidth
+ 3) & ~3;
899 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
900 linebytes
= -linebytes
;
903 bits
= srcbits
+ left
;
905 switch (bmpImage
->depth
) {
908 #if defined(__i386__) && defined(__GNUC__)
909 /* Some X servers might have 32 bit/ 16bit deep pixel */
910 if (lines
&& (dstwidth
!=left
) && (bmpImage
->bits_per_pixel
== 16))
912 for (h
= lines
; h
--; ) {
913 int _cl1
,_cl2
; /* temp outputs for asm below */
914 /* Borrowed from DirectDraw */
915 __asm__
__volatile__(
920 " movw (%%edx,%%eax,4),%%ax\n"
924 :"=S" (bits
), "=D" (_cl1
), "=c" (_cl2
)
926 "D" (bmpImage
->data
+h
*bmpImage
->bytes_per_line
+left
*2),
929 :"eax", "cc", "memory"
931 bits
= (srcbits
+= linebytes
) + left
;
938 break; /* use slow generic case below */
941 for (h
= lines
- 1; h
>= 0; h
--) {
942 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
943 color
= colors
[*bits
];
944 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
946 bits
= (srcbits
+= linebytes
) + left
;
950 /***********************************************************************
951 * X11DRV_DIB_GetImageBits_8
953 * GetDIBits for an 8-bit deep DIB.
955 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
956 DWORD srcwidth
, DWORD dstwidth
,
957 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
964 /* align to 32 bit */
965 DWORD linebytes
= (srcwidth
+ 3) & ~3;
970 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
971 linebytes
= -linebytes
;
978 This condition is true when GetImageBits has been called by UpdateDIBSection.
979 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
980 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
982 if (!srccolors
) goto updatesection
;
984 switch(bmpImage
->depth
) {
987 /* ==== monochrome bitmap to 8 colormap dib ==== */
989 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
990 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
994 for (h
= lines
- 1; h
>= 0; h
--) {
995 for (x
= 0; x
< dstwidth
; x
++) {
996 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
997 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
998 val
.peGreen
, val
.peBlue
);
1000 bits
= (dstbits
+= linebytes
);
1003 else goto notsupported
;
1008 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
1009 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1014 for (h
= lines
- 1; h
>= 0; h
--) {
1015 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1016 for (x
= 0; x
< dstwidth
; x
++) {
1017 val
= srccolors
[(int)*srcpixel
++];
1018 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
1019 val
.peGreen
, val
.peBlue
);
1021 bits
= (dstbits
+= linebytes
);
1024 else goto notsupported
;
1033 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1034 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1036 for( h
= lines
- 1; h
>= 0; h
--)
1038 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1039 for( x
= 0; x
< dstwidth
; x
++ )
1042 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1043 ((val
>> 7) & 0xf8) |
1044 ((val
>> 12) & 0x7),
1045 ((val
>> 2) & 0xf8) |
1047 ((val
<< 3) & 0xf8) |
1048 ((val
>> 2) & 0x7) );
1050 bits
= (dstbits
+= linebytes
);
1053 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1054 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1056 for( h
= lines
- 1; h
>= 0; h
--)
1058 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1059 for( x
= 0; x
< dstwidth
; x
++ )
1062 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1063 ((val
<< 3) & 0xf8) |
1065 ((val
>> 2) & 0xf8) |
1067 ((val
>> 7) & 0xf8) |
1068 ((val
>> 12) & 0x7) );
1070 bits
= (dstbits
+= linebytes
);
1073 else goto notsupported
;
1082 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1083 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
1085 for( h
= lines
- 1; h
>= 0; h
--)
1087 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1088 for( x
= 0; x
< dstwidth
; x
++ )
1091 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1092 ((val
>> 8) & 0xf8) |
1093 ((val
>> 13) & 0x7),
1094 ((val
>> 3) & 0xfc) |
1096 ((val
<< 3) & 0xf8) |
1097 ((val
>> 2) & 0x7) );
1099 bits
= (dstbits
+= linebytes
);
1102 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1103 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1105 for( h
= lines
- 1; h
>= 0; h
--)
1107 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1108 for( x
= 0; x
< dstwidth
; x
++ )
1111 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1112 ((val
<< 3) & 0xf8) |
1114 ((val
>> 3) & 0x00fc) |
1116 ((val
>> 8) & 0x00f8) |
1117 ((val
>> 13) & 0x7) );
1119 bits
= (dstbits
+= linebytes
);
1122 else goto notsupported
;
1131 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1132 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1134 for (h
= lines
- 1; h
>= 0; h
--)
1136 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1137 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1138 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1139 srcpixel
[2] , srcpixel
[1], *srcpixel
);
1140 bits
= (dstbits
+= linebytes
);
1143 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1144 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1146 for (h
= lines
- 1; h
>= 0; h
--)
1148 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1149 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1150 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1151 *srcpixel
, srcpixel
[1], srcpixel
[2]);
1152 bits
= (dstbits
+= linebytes
);
1156 else goto notsupported
;
1160 default: /* ? bit bmp -> 8 bit DIB */
1162 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1163 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1164 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1166 for (h
= lines
- 1; h
>= 0; h
--) {
1167 for (x
= 0; x
< dstwidth
; x
++, bits
++) {
1168 *bits
= X11DRV_DIB_MapColor((int *)colors
, 256,
1169 XGetPixel( bmpImage
, x
, h
) );
1171 bits
= (dstbits
+= linebytes
);
1177 /***********************************************************************
1178 * X11DRV_DIB_SetImageBits_RLE8
1180 * SetDIBits for an 8-bit deep compressed DIB.
1182 * This function rewritten 941113 by James Youngman. WINE blew out when I
1183 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1185 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1186 * 'End of bitmap' escape code. This code is very much laxer in what it
1187 * allows to end the expansion. Possibly too lax. See the note by
1188 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1189 * bitmap should end with RleEnd, but on the other hand, software exists
1190 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1193 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1194 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1198 enum Rle8_EscapeCodes
1201 * Apologies for polluting your file's namespace...
1203 RleEol
= 0, /* End of line */
1204 RleEnd
= 1, /* End of bitmap */
1205 RleDelta
= 2 /* Delta */
1208 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1209 DWORD width
, DWORD dstwidth
,
1210 int left
, int *colors
,
1213 int x
; /* X-positon on each line. Increases. */
1214 int line
; /* Line #. Starts at lines-1, decreases */
1215 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1216 BYTE length
; /* The length pf a run */
1217 BYTE color_index
; /* index into colors[] as read from bits */
1218 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1219 int color
; /* value of colour[color_index] */
1221 if (lines
== 0) /* Let's hope this doesn't happen. */
1225 * Note that the bitmap data is stored by Windows starting at the
1226 * bottom line of the bitmap and going upwards. Within each line,
1227 * the data is stored left-to-right. That's the reason why line
1228 * goes from lines-1 to 0. [JAY]
1238 * If the length byte is not zero (which is the escape value),
1239 * We have a run of length pixels all the same colour. The colour
1240 * index is stored next.
1242 * If the length byte is zero, we need to read the next byte to
1243 * know what to do. [JAY]
1248 * [Run-Length] Encoded mode
1250 color_index
= (*pIn
++); /* Get the colour index. */
1251 color
= colors
[color_index
];
1254 XPutPixel(bmpImage
, x
++, line
, color
);
1259 * Escape codes (may be an absolute sequence though)
1261 escape_code
= (*pIn
++);
1264 case RleEol
: /* =0, end of line */
1271 case RleEnd
: /* =1, end of bitmap */
1274 * Not all RLE8 bitmaps end with this
1275 * code. For example, Paint Shop Pro
1276 * produces some that don't. That's (I think)
1277 * what caused the previous implementation to
1280 line
=-1; /* Cause exit from do loop. */
1284 case RleDelta
: /* =2, a delta */
1287 * Note that deltaing to line 0
1288 * will cause an exit from the loop,
1289 * which may not be what is intended.
1290 * The fact that there is a delta in the bits
1291 * almost certainly implies that there is data
1292 * to follow. You may feel that we should
1293 * jump to the top of the loop to avoid exiting
1296 * TODO: Decide what to do here in that case. [JAY]
1302 TRACE("Delta to last line of bitmap "
1303 "(wrongly?) causes loop exit\n");
1308 default: /* >2, switch to absolute mode */
1313 length
= escape_code
;
1316 color_index
= (*pIn
++);
1317 XPutPixel(bmpImage
, x
++, line
,
1318 colors
[color_index
]);
1322 * If you think for a moment you'll realise that the
1323 * only time we could ever possibly read an odd
1324 * number of bytes is when there is a 0x00 (escape),
1325 * a value >0x02 (absolute mode) and then an odd-
1326 * length run. Therefore this is the only place we
1327 * need to worry about it. Everywhere else the
1328 * bytes are always read in pairs. [JAY]
1330 if (escape_code
& 1)
1331 pIn
++; /* Throw away the pad byte. */
1334 } /* switch (escape_code) : Escape sequence */
1335 } /* process either an encoded sequence or an escape sequence */
1337 /* We expect to come here more than once per line. */
1338 } while (line
>= 0); /* Do this until the bitmap is filled */
1341 * Everybody comes here at the end.
1342 * Check how we exited the loop and print a message if it's a bit odd.
1345 if ( (*(pIn
-2) != 0/*escape*/) || (*(pIn
-1)!= RleEnd
) )
1347 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1348 "bytes were: %02X %02X.\n", (int)*(pIn
-2),(int)*(pIn
-1));
1353 /***********************************************************************
1354 * X11DRV_DIB_SetImageBits_16
1356 * SetDIBits for a 16-bit deep DIB.
1358 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1359 DWORD srcwidth
, DWORD dstwidth
, int left
,
1360 DC
*dc
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1366 /* align to 32 bit */
1367 DWORD linebytes
= (srcwidth
* 2 + 3) & ~3;
1372 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1373 linebytes
= -linebytes
;
1376 switch ( bmpImage
->depth
)
1379 /* using same format as XImage */
1380 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1381 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1382 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1383 else /* We need to do a conversion from a 565 dib */
1385 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1387 int div
= dstwidth
% 2;
1389 for (h
= lines
- 1; h
>= 0; h
--) {
1390 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1391 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1393 *dstpixel
++ = ((val
>> 1) & 0x7fe07fe0) | (val
& 0x001f001f); /* Red & Green & Blue */
1395 if (div
!= 0) /* Odd width? */
1396 *dstpixel
= ((*(WORD
*)ptr
>> 1) & 0x7fe0) | (*(WORD
*)ptr
& 0x001f);
1397 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1403 /* using same format as XImage */
1404 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1405 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1406 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1407 else /* We need to do a conversion from a 555 dib */
1409 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1411 int div
= dstwidth
% 2;
1413 for (h
= lines
- 1; h
>= 0; h
--) {
1414 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1415 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1417 *dstpixel
++ = ((val
<< 1) & 0xffc0ffc0) | ((val
>> 4) & 0x00200020) | /* Red & Green */
1418 (val
& 0x001f001f); /* Blue */
1420 if (div
!= 0) /* Odd width? */
1421 *dstpixel
= ((*(WORD
*)ptr
<< 1) & 0xffc0) | ((*(WORD
*)ptr
>> 4) & 0x0020)
1422 | (*(WORD
*)ptr
& 0x001f);
1423 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1432 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1435 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1436 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1438 for (h
= lines
- 1; h
>= 0; h
--) {
1439 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1440 for (x
= 0; x
< dstwidth
; x
++) {
1443 *dstpixel
++ = ((val
<< 9) & 0xf80000) | ((val
<< 4) & 0x070000) | /* Red */
1444 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1445 ((val
<< 3) & 0x0000f8) | ((val
>> 2) & 0x000007); /* Blue */
1447 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1450 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1451 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1453 for (h
= lines
- 1; h
>= 0; h
--) {
1454 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1455 for (x
= 0; x
< dstwidth
; x
++) {
1458 *dstpixel
++ = ((val
>> 7) & 0x0000f8) | ((val
>> 12) & 0x000007) | /* Red */
1459 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1460 ((val
<< 19) & 0xf80000) | ((val
>> 14) & 0x070000); /* Blue */
1462 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1473 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1477 /* Set color scaling values */
1478 if ( rSrc
== 0x7c00 ) { sc1
= 7; sc2
= 2; } /* 555 dib */
1479 else { sc1
= 8; sc2
= 3; } /* 565 dib */
1481 for (h
= lines
- 1; h
>= 0; h
--) {
1482 for (x
= left
; x
< dstwidth
+left
; x
++) {
1484 XPutPixel( bmpImage
, x
, h
,
1485 X11DRV_PALETTE_ToPhysical(dc
, RGB(((val
& rSrc
) >> sc1
), /* Red */
1486 ((val
& gSrc
) >> sc2
), /* Green */
1487 ((val
& bSrc
) << 3)))); /* Blue */
1489 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
1495 FIXME("16 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
1502 /***********************************************************************
1503 * X11DRV_DIB_GetImageBits_16
1505 * GetDIBits for an 16-bit deep DIB.
1507 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
1508 DWORD dstwidth
, DWORD srcwidth
,
1509 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
1514 /* align to 32 bit */
1515 DWORD linebytes
= (dstwidth
* 2 + 3) & ~3;
1520 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
1521 linebytes
= -linebytes
;
1524 switch ( bmpImage
->depth
)
1527 /* ==== 555 BGR bitmap to 555 BGR dib ==== */
1528 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1529 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+= linebytes
)
1530 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, srcwidth
*2 );
1532 /* ==== 555 RGB bitmap to 555 BGR dib ==== */
1533 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1535 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1537 int div
= srcwidth
% 2;
1539 for (h
= lines
- 1; h
>= 0; h
--) {
1540 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1541 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1543 *ptr
++ = ((val
<< 10) & 0xf800f800) | (val
& 0x03e003e0) | /* Red & Green */
1544 ((val
>> 10) & 0x001f001f); /* Blue */
1546 if (div
!= 0) /* Odd width? */
1547 *ptr
= ((*(WORD
*)srcpixel
<< 1) & 0xffc0) | ((*(WORD
*)srcpixel
>> 4) & 0x0020) |
1548 (*(WORD
*)srcpixel
& 0x001f);
1549 ptr
= (LPDWORD
)(dstbits
+= linebytes
);
1552 else goto notsupported
;
1558 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1560 int div
= srcwidth
% 2;
1562 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1563 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f )
1565 for (h
= lines
- 1; h
>= 0; h
--) {
1566 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1567 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1569 *ptr
++ = ((val
>> 1) & 0x7fe07fe0) | /* Red & Green */
1570 (val
& 0x001f001f); /* Blue */
1572 if (div
!= 0) /* Odd width? */
1573 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1574 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1577 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1578 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1580 for (h
= lines
- 1; h
>= 0; h
--) {
1581 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1582 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1584 *ptr
++ = ((val
<< 10) & 0x7c007c00) | ((val
>> 1) & 0x03e003e0) | /* Red & Green */
1585 ((val
>> 11) & 0x001f001f); /* Blue */
1587 if (div
!= 0) /* Odd width? */
1588 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1589 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1592 else goto notsupported
;
1600 LPWORD ptr
= (LPWORD
)dstbits
;
1603 /* ==== 24/32 BGR bitmap to 555 BGR dib ==== */
1604 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1606 for (h
= lines
- 1; h
>= 0; h
--) {
1607 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1608 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1610 *ptr
= ((val
>> 9) & 0x7c00) | /* Red */
1611 ((val
>> 6) & 0x03e0) | /* Green */
1612 ((val
>> 3) & 0x001f); /* Blue */
1614 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1617 /* ==== 24/32 RGB bitmap to 555 BGR dib ==== */
1618 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1620 for (h
= lines
- 1; h
>= 0; h
--) {
1621 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1622 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1624 *ptr
= ((val
<< 7) & 0x7c00) | /* Red */
1625 ((val
>> 6) & 0x03e0) | /* Green */
1626 ((val
>> 19) & 0x001f); /* Blue */
1628 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1631 else goto notsupported
;
1636 /* ==== monochrome bitmap to 16 BGR dib ==== */
1638 /* ==== 4 colormap bitmap to 16 BGR dib ==== */
1639 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1641 LPWORD ptr
= (LPWORD
)dstbits
;
1644 for (h
= lines
- 1; h
>= 0; h
--) {
1645 for (x
= 0; x
< dstwidth
; x
++) {
1646 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
1647 *ptr
++ = ((val
.peRed
<< 7) & 0x7c00) |
1648 ((val
.peGreen
<< 2) & 0x03e0) |
1649 ((val
.peBlue
>> 3) & 0x001f);
1651 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1654 else goto notsupported
;
1659 /* ==== 8 colormap bitmap to 16 BGR dib ==== */
1660 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1662 LPWORD ptr
= (LPWORD
)dstbits
;
1666 for (h
= lines
- 1; h
>= 0; h
--) {
1667 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1668 for (x
= 0; x
< dstwidth
; x
++) {
1669 val
= srccolors
[(int)*srcpixel
++];
1670 *ptr
++ = ((val
.peRed
<< 7) & 0x7c00) |
1671 ((val
.peGreen
<< 2) & 0x03e0) |
1672 ((val
.peBlue
>> 3) & 0x001f);
1674 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1677 else goto notsupported
;
1685 LPWORD ptr
= (LPWORD
)dstbits
;
1687 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 16 bit DIB\n",
1688 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1689 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1690 for (h
= lines
- 1; h
>= 0; h
--)
1692 for (x
= 0; x
< dstwidth
; x
++, ptr
++)
1694 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
1695 r
= (BYTE
) GetRValue(pixel
);
1696 g
= (BYTE
) GetGValue(pixel
);
1697 b
= (BYTE
) GetBValue(pixel
);
1698 *ptr
= ( ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f) );
1700 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1708 /***********************************************************************
1709 * X11DRV_DIB_SetImageBits_24
1711 * SetDIBits for a 24-bit deep DIB.
1713 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
1714 DWORD srcwidth
, DWORD dstwidth
, int left
,
1715 DC
*dc
, XImage
*bmpImage
)
1720 /* align to 32 bit */
1721 DWORD linebytes
= (srcwidth
* 3 + 3) & ~3;
1726 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1727 linebytes
= -linebytes
;
1730 switch ( bmpImage
->depth
)
1734 if (bmpImage
->bits_per_pixel
== 24) {
1735 int dstlinebytes
= linebytes
;
1737 BYTE
*ptr
= (BYTE
*)(srcbits
+left
*3);
1739 if (dstlinebytes
< 0 ) dstlinebytes
= -dstlinebytes
;
1740 dstpixel
= bmpImage
->data
+ lines
*dstlinebytes
+ left
*3;
1741 for(h
= lines
; h
-- ; ) {
1742 dstpixel
-=dstlinebytes
;
1743 memcpy(dstpixel
,ptr
,dstwidth
*3);
1751 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 ) /* packed BGR to unpacked BGR */
1753 DWORD
*dstpixel
, val
, buf
;
1754 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1756 int div
= dstwidth
% 4;
1759 for(h
= lines
- 1; h
>= 0; h
--)
1761 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1763 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1765 *dstpixel
++ = buf
&0x00ffffff; /* b1, g1, r1 */
1766 val
= (buf
>> 24); /* b2 */
1768 *dstpixel
++ = (val
| (buf
<<8)) &0x00ffffff; /* g2, r2 */
1769 val
= (buf
>> 16); /* b3, g3 */
1771 *dstpixel
++ = (val
| (buf
<<16)) &0x00ffffff; /* r3 */
1772 *dstpixel
++ = (buf
>> 8); /* b4, g4, r4 */
1774 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1776 *dstpixel
++ = *(DWORD
*)bits
& 0x00ffffff; /* b, g, r */
1778 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1781 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff ) /* packed BGR to unpacked RGB */
1783 DWORD
*dstpixel
, val
, buf
;
1784 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1786 int div
= dstwidth
% 4;
1789 for(h
= lines
- 1; h
>= 0; h
--)
1791 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1793 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1795 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b1, g1, r1 */
1796 val
= ((buf
&0xff000000)>>8); /* b2 */
1798 *dstpixel
++ = val
| ((buf
&0xff)<<8) | ((buf
&0xff00)>>8); /* g2, r2 */
1799 val
= (buf
&0xff0000) | ((buf
&0xff000000)>>16); /* b3, g3 */
1801 *dstpixel
++ = val
| (buf
&0xff); /* r3 */
1802 *dstpixel
++ = ((buf
&0xff00)<<8) | ((buf
&0xff0000)>>8) | (buf
>>24); /* b4, g4, r4 */
1804 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1806 buf
= *(DWORD
*)bits
;
1807 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b, g, r */
1809 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1819 if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f ) /* BGR888 to RGB555 */
1821 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1824 int div
= dstwidth
% 4;
1827 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1828 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1829 for (x
= 0; x
< dstwidth
/4; x
++) {
1830 *dstpixel
++ = (WORD
)((((val
= *ptr
++) << 7) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 19) & 0x1f));
1831 *dstpixel
++ = (WORD
)(((val
>> 17) & 0x7c00) | (((val
= *ptr
++) << 2) & 0x03e0) | ((val
>> 11) & 0x1f));
1832 *dstpixel
++ = (WORD
)(((val
>> 9) & 0x07c00) | ((val
>> 22) & 0x03e0) | (((val
= *ptr
++) >> 3) & 0x1f));
1833 *dstpixel
++ = (WORD
)(((val
>> 1) & 0x07c00) | ((val
>> 14) & 0x03e0) | ((val
>> 27) & 0x1f));
1835 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1836 *dstpixel
++ = (((WORD
)bits
[0] << 7) & 0x07c00) |
1837 (((WORD
)bits
[1] << 2) & 0x03e0) |
1838 (((WORD
)bits
[2] >> 3) & 0x001f);
1839 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1842 else if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 ) /* BGR888 to BGR555 */
1844 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1847 int div
= dstwidth
% 4;
1850 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1851 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1852 for (x
= 0; x
< dstwidth
/4; x
++) {
1853 *dstpixel
++ = (WORD
)((((val
= *ptr
++) >> 3) & 0x1f) | ((val
>> 6) & 0x03e0) | ((val
>> 9) & 0x7c00));
1854 *dstpixel
++ = (WORD
)(((val
>> 27) & 0x1f) | (((val
= *ptr
++) << 2) & 0x03e0) | ((val
>> 1) & 0x7c00));
1855 *dstpixel
++ = (WORD
)(((val
>> 19) & 0x1f) | ((val
>> 22) & 0x03e0) | (((val
= *ptr
++) << 7) & 0x7c00));
1856 *dstpixel
++ = (WORD
)(((val
>> 11) & 0x1f) | ((val
>> 14) & 0x03e0) | ((val
>> 17) & 0x7c00));
1858 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1859 *dstpixel
++ = (((WORD
)bits
[2] << 7) & 0x07c00) |
1860 (((WORD
)bits
[1] << 2) & 0x03e0) |
1861 (((WORD
)bits
[0] >> 3) & 0x001f);
1862 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1872 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1875 int div
= dstwidth
% 4;
1878 if( bmpImage
->blue_mask
== 0x001f && bmpImage
->red_mask
== 0xf800 ) /* BGR888 to BGR565 */
1880 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1881 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1882 for (x
= 0; x
< dstwidth
/4; x
++) {
1883 *dstpixel
++ = (WORD
)((((val
= *ptr
++) >> 3) & 0x1f) | ((val
>> 5) & 0x07e0) | ((val
>> 8) & 0xf800));
1884 *dstpixel
++ = (WORD
)(((val
>> 27) & 0x1f) | (((val
= *ptr
++) << 3) & 0x07e0) | ((val
) & 0xf800));
1885 *dstpixel
++ = (WORD
)(((val
>> 19) & 0x1f) | ((val
>> 21) & 0x07e0) | (((val
= *ptr
++) << 8) & 0xf800));
1886 *dstpixel
++ = (WORD
)(((val
>> 11) & 0x1f) | ((val
>> 13) & 0x07e0) | ((val
>> 16) & 0xf800));
1888 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1889 *dstpixel
++ = (((WORD
)bits
[2] << 8) & 0xf800) |
1890 (((WORD
)bits
[1] << 3) & 0x07e0) |
1891 (((WORD
)bits
[0] >> 3) & 0x001f);
1892 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1895 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x001f ) /* BGR888 to RGB565 */
1897 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1898 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1899 for (x
= 0; x
< dstwidth
/4; x
++) {
1900 *dstpixel
++ = (WORD
)((((val
= *ptr
++) << 8) & 0xf800) | ((val
>> 5) & 0x07e0) | ((val
>> 19) & 0x1f));
1901 *dstpixel
++ = (WORD
)(((val
>> 16) & 0xf800) | (((val
= *ptr
++) << 3) & 0x07e0) | ((val
>> 11) & 0x1f));
1902 *dstpixel
++ = (WORD
)(((val
>> 8) & 0xf800) | ((val
>> 21) & 0x07e0) | (((val
= *ptr
++) >> 3) & 0x1f));
1903 *dstpixel
++ = (WORD
)((val
& 0xf800) | ((val
>> 13) & 0x07e0) | ((val
>> 27) & 0x1f));
1905 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1906 *dstpixel
++ = (((WORD
)bits
[0] << 8) & 0xf800) |
1907 (((WORD
)bits
[1] << 3) & 0x07e0) |
1908 (((WORD
)bits
[2] >> 3) & 0x001f);
1909 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1921 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*3;
1923 for (h
= lines
- 1; h
>= 0; h
--) {
1924 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+=3)
1925 XPutPixel( bmpImage
, x
, h
,
1926 X11DRV_PALETTE_ToPhysical(dc
, RGB(bits
[2], bits
[1], bits
[0])));
1927 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 3;
1934 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
1935 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
1936 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1942 /***********************************************************************
1943 * X11DRV_DIB_GetImageBits_24
1945 * GetDIBits for an 24-bit deep DIB.
1947 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
1948 DWORD dstwidth
, DWORD srcwidth
,
1949 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
1954 /* align to 32 bit */
1955 DWORD linebytes
= (dstwidth
* 3 + 3) & ~3;
1960 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1961 linebytes
= -linebytes
;
1964 switch ( bmpImage
->depth
)
1968 if (bmpImage
->bits_per_pixel
== 24) {
1969 int tocopy
= linebytes
;
1971 BYTE
*ptr
= (LPBYTE
)dstbits
;
1973 if (tocopy
< 0 ) tocopy
= -tocopy
;
1974 srcpixel
= bmpImage
->data
+ lines
*tocopy
;
1975 for(h
= lines
; h
-- ; ) {
1977 memcpy(ptr
,srcpixel
,tocopy
);
1978 ptr
= (LPBYTE
)(dstbits
+=linebytes
);
1985 DWORD
*srcpixel
, buf
;
1987 DWORD
*ptr
=(DWORD
*)dstbits
;
1988 int quotient
= dstwidth
/ 4;
1989 int remainder
= dstwidth
% 4;
1992 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
1993 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 )
1995 for(h
= lines
- 1; h
>= 0; h
--)
1997 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1999 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time*/
2000 buf
= ((*srcpixel
++)&0x00ffffff); /* b1, g1, r1*/
2001 *ptr
++ = buf
| ((*srcpixel
)<<24); /* b2 */
2002 buf
= ((*srcpixel
++>>8)&0x0000ffff); /* g2, r2 */
2003 *ptr
++ = buf
| ((*srcpixel
)<<16); /* b3, g3 */
2004 buf
= ((*srcpixel
++>>16)&0x000000ff); /* r3 */
2005 *ptr
++ = buf
| ((*srcpixel
++)<<8); /* b4, g4, r4 */
2007 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
2010 *(WORD
*)bits
= buf
; /* b, g */
2011 *(bits
+2) = buf
>>16; /* r */
2013 ptr
= (DWORD
*)(dstbits
+=linebytes
);
2017 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
2018 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff )
2020 for(h
= lines
- 1; h
>= 0; h
--)
2022 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2024 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time */
2026 val
= ((buf
&0xff0000)>>16) | (buf
&0xff00) | ((buf
&0xff)<<16); /* b1, g1, r1 */
2028 *ptr
++ = val
| ((buf
&0xff0000)<<8); /* b2 */
2029 val
= ((buf
&0xff00)>>8) | ((buf
&0xff)<<8); /* g2, r2 */
2031 *ptr
++ = val
| (buf
&0xff0000) | ((buf
&0xff00)<<16); /* b3, g3 */
2032 val
= (buf
&0xff); /* r3 */
2034 *ptr
++ = val
| ((buf
&0xff0000)>>8) | ((buf
&0xff00)<<8) | (buf
<<24); /* b4, g4, r4 */
2036 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
2039 *(WORD
*)bits
= (buf
&0xff00) | ((buf
&0xff0000)>>16) ; /* b, g */
2040 *(bits
+2) = buf
; /* r */
2042 ptr
= (DWORD
*)(dstbits
+=linebytes
);
2045 else goto notsupported
;
2052 LPBYTE bits
= dstbits
;
2055 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2056 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 )
2058 for (h
= lines
- 1; h
>= 0; h
--) {
2059 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2060 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2062 bits
[2] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2063 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2064 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2066 bits
= (dstbits
+= linebytes
);
2069 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2070 else if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f )
2072 for (h
= lines
- 1; h
>= 0; h
--) {
2073 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2074 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2076 bits
[0] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2077 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2078 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2080 bits
= (dstbits
+= linebytes
);
2083 else goto notsupported
;
2090 LPBYTE bits
= dstbits
;
2093 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2094 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0xf800 )
2096 for (h
= lines
- 1; h
>= 0; h
--) {
2097 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2098 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2100 bits
[2] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2101 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2102 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2104 bits
= (dstbits
+= linebytes
);
2107 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2108 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x1f )
2110 for (h
= lines
- 1; h
>= 0; h
--) {
2111 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2112 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2114 bits
[0] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2115 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2116 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2118 bits
= (dstbits
+= linebytes
);
2121 else goto notsupported
;
2126 /* ==== monochrome bitmap to 24 BGR dib ==== */
2128 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2129 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2131 LPBYTE bits
= dstbits
;
2134 for (h
= lines
- 1; h
>= 0; h
--) {
2135 for (x
= 0; x
< dstwidth
; x
++) {
2136 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2137 *bits
++ = val
.peBlue
;
2138 *bits
++ = val
.peGreen
;
2139 *bits
++ = val
.peRed
;
2141 bits
= (dstbits
+= linebytes
);
2144 else goto notsupported
;
2149 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2150 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
)
2153 LPBYTE bits
= dstbits
;
2156 for (h
= lines
- 1; h
>= 0; h
--) {
2157 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2158 for (x
= 0; x
< dstwidth
; x
++ ) {
2159 val
= srccolors
[(int)*srcpixel
++];
2160 *bits
++ = val
.peBlue
; /*Blue*/
2161 *bits
++ = val
.peGreen
; /*Green*/
2162 *bits
++ = val
.peRed
; /*Red*/
2164 bits
= (dstbits
+= linebytes
);
2167 else goto notsupported
;
2174 LPBYTE bits
= dstbits
;
2176 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2177 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2178 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2179 for (h
= lines
- 1; h
>= 0; h
--)
2181 for (x
= 0; x
< dstwidth
; x
++, bits
+= 3)
2183 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2184 bits
[0] = GetBValue(pixel
);
2185 bits
[1] = GetGValue(pixel
);
2186 bits
[2] = GetRValue(pixel
);
2188 bits
= (dstbits
+= linebytes
);
2196 /***********************************************************************
2197 * X11DRV_DIB_SetImageBits_32
2199 * SetDIBits for a 32-bit deep DIB.
2201 static void X11DRV_DIB_SetImageBits_32( int lines
, const BYTE
*srcbits
,
2202 DWORD srcwidth
, DWORD dstwidth
, int left
,
2203 DC
*dc
, XImage
*bmpImage
)
2208 DWORD linebytes
= (srcwidth
* 4);
2213 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2214 linebytes
= -linebytes
;
2217 ptr
= (DWORD
*) srcbits
+ left
;
2219 switch ( bmpImage
->depth
)
2223 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2224 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff) {
2225 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+=linebytes
) {
2226 memcpy( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
, srcbits
+ left
*4, dstwidth
*4 );
2230 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2231 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
2235 for (h
= lines
- 1; h
>= 0; h
--) {
2236 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2237 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2238 *dstpixel
++ = ((*ptr
<< 16) & 0xff0000) | (*ptr
& 0xff00) | ((*ptr
>> 16) & 0xff);
2240 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2243 else goto notsupported
;
2248 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2249 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
2253 for (h
= lines
- 1; h
>= 0; h
--) {
2254 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2255 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2256 *dstpixel
++ = (WORD
) (((*ptr
>> 9) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 3) & 0x001f));
2258 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2261 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2262 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2266 for (h
= lines
- 1; h
>= 0; h
--) {
2267 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2268 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2269 *dstpixel
++ = (WORD
) (((*ptr
<< 7) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 19) & 0x001f));
2271 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2274 else goto notsupported
;
2279 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2280 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2284 for (h
= lines
- 1; h
>= 0; h
--) {
2285 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2286 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2287 *dstpixel
++ = (WORD
) (((*ptr
>> 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 3) & 0x001f));
2289 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2292 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2293 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
2297 for (h
= lines
- 1; h
>= 0; h
--) {
2298 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2299 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2300 *dstpixel
++ = (WORD
) (((*ptr
<< 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 19) & 0x001f));
2302 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2305 else goto notsupported
;
2313 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*4;
2315 for (h
= lines
- 1; h
>= 0; h
--) {
2316 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+= 4)
2317 XPutPixel( bmpImage
, x
, h
,
2318 X11DRV_PALETTE_ToPhysical(dc
, RGB( bits
[2], bits
[1], *bits
)));
2319 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 4;
2326 FIXME("32 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
2332 /***********************************************************************
2333 * X11DRV_DIB_GetImageBits_32
2335 * GetDIBits for an 32-bit deep DIB.
2337 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
2338 DWORD dstwidth
, DWORD srcwidth
,
2339 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
2345 /* align to 32 bit */
2346 DWORD linebytes
= (srcwidth
* 4);
2347 DWORD copybytes
= linebytes
;
2352 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2353 linebytes
= -linebytes
;
2358 switch ( bmpImage
->depth
)
2362 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2363 if ( bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff )
2364 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+=linebytes
)
2365 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, copybytes
);
2367 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2368 else if ( bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000 )
2372 for (h
= lines
- 1; h
>= 0; h
--) {
2373 srcbits
= bmpImage
->data
+ h
* bmpImage
->bytes_per_line
;
2374 for (x
= 0; x
< dstwidth
; x
++, bits
+=4, srcbits
+=2) {
2375 *(bits
+ 2) = *srcbits
++;
2376 *(bits
+ 1) = *srcbits
++;
2379 bits
= (dstbits
+= linebytes
);
2382 else goto notsupported
;
2390 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2391 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
2393 for (h
= lines
- 1; h
>= 0; h
--) {
2394 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2395 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2397 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2398 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2399 *bits
= (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2401 bits
= (dstbits
+= linebytes
);
2404 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2405 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2407 for (h
= lines
- 1; h
>= 0; h
--) {
2408 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2409 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2411 *bits
++ = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07));/*Blue*/
2412 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2413 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2415 bits
= (dstbits
+= linebytes
);
2418 else goto notsupported
;
2427 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2428 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2430 for (h
= lines
- 1; h
>= 0; h
--) {
2431 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2432 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2434 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2435 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2436 *bits
= (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2438 bits
= (dstbits
+= linebytes
);
2441 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2442 else if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2444 for (h
= lines
- 1; h
>= 0; h
--) {
2445 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2446 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2448 *bits
++ = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07));/*Blue*/
2449 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2450 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2452 bits
= (dstbits
+= linebytes
);
2455 else goto notsupported
;
2460 /* ==== monochrome bitmap to 32 BGR dib ==== */
2462 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2463 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2467 for (h
= lines
- 1; h
>= 0; h
--) {
2468 for (x
= 0; x
< dstwidth
; x
++) {
2469 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2470 *bits
++ = val
.peBlue
;
2471 *bits
++ = val
.peGreen
;
2472 *bits
++ = val
.peRed
;
2475 bits
= (dstbits
+= linebytes
);
2478 else goto notsupported
;
2483 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2484 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2489 for (h
= lines
- 1; h
>= 0; h
--) {
2490 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2491 for (x
= 0; x
< dstwidth
; x
++) {
2492 val
= srccolors
[(int)*srcpixel
++];
2493 *bits
++ = val
.peBlue
; /*Blue*/
2494 *bits
++ = val
.peGreen
; /*Green*/
2495 *bits
++ = val
.peRed
; /*Red*/
2498 bits
= (dstbits
+= linebytes
);
2501 else goto notsupported
;
2506 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2507 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2508 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2509 for (h
= lines
- 1; h
>= 0; h
--)
2511 for (x
= 0; x
< dstwidth
; x
++, bits
+= 4)
2513 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2514 bits
[0] = GetBValue(pixel
);
2515 bits
[1] = GetGValue(pixel
);
2516 bits
[2] = GetRValue(pixel
);
2518 bits
= (dstbits
+= linebytes
);
2524 /***********************************************************************
2525 * X11DRV_DIB_SetImageBits
2527 * Transfer the bits to an X image.
2528 * Helper function for SetDIBits() and SetDIBitsToDevice().
2529 * The Xlib critical section must be entered before calling this function.
2531 int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2533 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2536 if ( descr
->dc
&& descr
->dc
->w
.flags
& DC_DIRTY
)
2537 CLIPPING_UpdateGCRegion( descr
->dc
);
2540 bmpImage
= descr
->image
;
2542 bmpImage
= XCreateImage( display
, X11DRV_GetVisual(), descr
->depth
, ZPixmap
, 0, NULL
,
2543 descr
->infoWidth
, lines
, 32, 0 );
2544 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2545 if(bmpImage
->data
== NULL
) {
2546 ERR("Out of memory!");
2547 XDestroyImage( bmpImage
);
2552 /* Transfer the pixels */
2553 switch(descr
->infoBpp
)
2556 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
2557 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
2561 if (descr
->compression
) {
2562 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2563 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2564 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2566 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
2567 descr
->infoWidth
, descr
->width
,
2568 descr
->xSrc
, (int *)(descr
->colorMap
),
2571 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
2572 descr
->infoWidth
, descr
->width
,
2573 descr
->xSrc
, (int*)(descr
->colorMap
),
2577 if (descr
->compression
) {
2578 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2579 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2580 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2581 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
2582 descr
->infoWidth
, descr
->width
,
2583 descr
->xSrc
, (int *)(descr
->colorMap
),
2586 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
2587 descr
->infoWidth
, descr
->width
,
2588 descr
->xSrc
, (int *)(descr
->colorMap
),
2593 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
2594 descr
->infoWidth
, descr
->width
,
2595 descr
->xSrc
, descr
->dc
,
2596 descr
->rMask
, descr
->gMask
, descr
->bMask
,
2600 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
2601 descr
->infoWidth
, descr
->width
,
2602 descr
->xSrc
, descr
->dc
, bmpImage
);
2605 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
2606 descr
->infoWidth
, descr
->width
,
2607 descr
->xSrc
, descr
->dc
,
2611 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2617 XShmPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2618 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2619 descr
->width
, descr
->height
, FALSE
);
2620 XSync( display
, 0 );
2623 XPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2624 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2625 descr
->width
, descr
->height
);
2627 if (!descr
->image
) XDestroyImage( bmpImage
);
2631 /***********************************************************************
2632 * X11DRV_DIB_GetImageBits
2634 * Transfer the bits from an X image.
2635 * The Xlib critical section must be entered before calling this function.
2637 int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2639 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2643 bmpImage
= descr
->image
;
2645 bmpImage
= XCreateImage( display
, X11DRV_GetVisual(), descr
->depth
, ZPixmap
, 0, NULL
,
2646 descr
->infoWidth
, lines
, 32, 0 );
2647 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2648 if(bmpImage
->data
== NULL
) {
2649 ERR("Out of memory!");
2650 XDestroyImage( bmpImage
);
2654 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2655 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2656 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2658 /* Transfer the pixels */
2659 switch(descr
->infoBpp
)
2662 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
2663 descr
->infoWidth
, descr
->width
,
2664 descr
->colorMap
, descr
->palentry
,
2669 if (descr
->compression
)
2670 FIXME("Compression not yet supported!\n");
2672 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
2673 descr
->infoWidth
, descr
->width
,
2674 descr
->colorMap
, descr
->palentry
,
2679 if (descr
->compression
)
2680 FIXME("Compression not yet supported!\n");
2682 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
2683 descr
->infoWidth
, descr
->width
,
2684 descr
->colorMap
, descr
->palentry
,
2689 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
2690 descr
->infoWidth
,descr
->width
,
2691 descr
->palentry
, bmpImage
);
2695 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
2696 descr
->infoWidth
,descr
->width
,
2697 descr
->palentry
, bmpImage
);
2701 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
2702 descr
->infoWidth
, descr
->width
,
2703 descr
->palentry
, bmpImage
);
2707 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2711 if (!descr
->image
) XDestroyImage( bmpImage
);
2715 /*************************************************************************
2716 * X11DRV_SetDIBitsToDevice
2719 INT
X11DRV_SetDIBitsToDevice( DC
*dc
, INT xDest
, INT yDest
, DWORD cx
,
2720 DWORD cy
, INT xSrc
, INT ySrc
,
2721 UINT startscan
, UINT lines
, LPCVOID bits
,
2722 const BITMAPINFO
*info
, UINT coloruse
)
2724 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2725 DWORD width
, oldcy
= cy
;
2727 int height
, tmpheight
;
2728 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
2731 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
2732 &descr
.infoBpp
, &descr
.compression
) == -1)
2735 if (height
< 0) height
= -height
;
2736 if (!lines
|| (startscan
>= height
)) return 0;
2737 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2738 if (ySrc
< startscan
) ySrc
= startscan
;
2739 else if (ySrc
>= startscan
+ lines
) return 0;
2740 if (xSrc
>= width
) return 0;
2741 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
2742 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
2743 if (!cx
|| !cy
) return 0;
2745 X11DRV_SetupGCForText( dc
); /* To have the correct colors */
2746 TSXSetFunction(display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->w
.ROPmode
-1]);
2748 switch (descr
.infoBpp
)
2753 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2754 coloruse
== DIB_PAL_COLORS
? dc
: NULL
, coloruse
,
2755 dc
->w
.bitsPerPixel
, info
, &descr
.nColorMap
);
2756 if (!descr
.colorMap
) return 0;
2757 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2761 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2762 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2763 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2768 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2773 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2774 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2775 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2783 descr
.palentry
= NULL
;
2784 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2785 descr
.infoWidth
= width
;
2786 descr
.depth
= dc
->w
.bitsPerPixel
;
2787 descr
.drawable
= physDev
->drawable
;
2788 descr
.gc
= physDev
->gc
;
2790 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
2792 descr
.xDest
= dc
->w
.DCOrgX
+ XLPTODP( dc
, xDest
);
2793 descr
.yDest
= dc
->w
.DCOrgY
+ YLPTODP( dc
, yDest
) +
2794 (tmpheight
>= 0 ? oldcy
-cy
: 0);
2797 descr
.useShm
= FALSE
;
2799 EnterCriticalSection( &X11DRV_CritSection
);
2800 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
2801 LeaveCriticalSection( &X11DRV_CritSection
);
2803 if (descr
.infoBpp
<= 8)
2804 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2808 /***********************************************************************
2809 * X11DRV_DIB_SetDIBits
2811 INT
X11DRV_DIB_SetDIBits(
2812 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2813 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
,
2814 UINT coloruse
, HBITMAP hbitmap
)
2816 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2817 int height
, tmpheight
;
2822 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
2823 &descr
.infoBpp
, &descr
.compression
) == -1)
2827 if (height
< 0) height
= -height
;
2828 if (!lines
|| (startscan
>= height
))
2831 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2833 switch (descr
.infoBpp
)
2838 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2839 coloruse
== DIB_PAL_COLORS
? descr
.dc
: NULL
, coloruse
,
2840 bmp
->bitmap
.bmBitsPixel
,
2841 info
, &descr
.nColorMap
);
2842 if (!descr
.colorMap
) return 0;
2843 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2847 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2848 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2849 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2854 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2859 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2860 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2861 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2869 if(!bmp
->physBitmap
)
2870 X11DRV_CreateBitmap(hbitmap
);
2874 descr
.palentry
= NULL
;
2875 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2876 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2877 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
2878 descr
.gc
= BITMAP_GC(bmp
);
2882 descr
.yDest
= height
- startscan
- lines
;
2883 descr
.width
= bmp
->bitmap
.bmWidth
;
2884 descr
.height
= lines
;
2885 descr
.useShm
= FALSE
;
2887 EnterCriticalSection( &X11DRV_CritSection
);
2888 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
2889 LeaveCriticalSection( &X11DRV_CritSection
);
2891 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2896 /***********************************************************************
2897 * X11DRV_DIB_GetDIBits
2899 INT
X11DRV_DIB_GetDIBits(
2900 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2901 UINT lines
, LPVOID bits
, BITMAPINFO
*info
,
2902 UINT coloruse
, HBITMAP hbitmap
)
2904 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
2905 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2906 PALETTEOBJ
* palette
;
2908 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
2909 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
2910 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
2913 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->w
.hPalette
, PALETTE_MAGIC
)))
2916 if( lines
> info
->bmiHeader
.biHeight
) lines
= info
->bmiHeader
.biHeight
;
2917 /* Top-down images have a negative biHeight, the scanlines of theses images
2918 * were inverted in X11DRV_DIB_GetImageBits_xx
2919 * To prevent this we simply change the sign of lines
2920 * (the number of scan lines to copy).
2921 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
2923 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
2925 if( startscan
>= bmp
->bitmap
.bmHeight
) return FALSE
;
2927 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
2928 &descr
.infoBpp
, &descr
.compression
) == -1)
2931 switch (descr
.infoBpp
)
2937 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2941 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2942 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2943 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2947 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2948 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2949 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2954 if(!bmp
->physBitmap
)
2955 X11DRV_CreateBitmap(hbitmap
);
2959 descr
.palentry
= palette
->logpalette
.palPalEntry
;
2961 descr
.lines
= lines
;
2962 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2963 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
2964 descr
.gc
= BITMAP_GC(bmp
);
2966 descr
.ySrc
= startscan
;
2969 descr
.width
= bmp
->bitmap
.bmWidth
;
2970 descr
.height
= bmp
->bitmap
.bmHeight
;
2971 descr
.colorMap
= info
->bmiColors
;
2974 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
2976 descr
.useShm
= FALSE
;
2978 EnterCriticalSection( &X11DRV_CritSection
);
2980 descr
.image
= (XImage
*)CALL_LARGE_STACK( X11DRV_BITMAP_GetXImage
, bmp
);
2981 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
2983 LeaveCriticalSection( &X11DRV_CritSection
);
2985 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
2986 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
2987 info
->bmiHeader
.biWidth
,
2988 info
->bmiHeader
.biHeight
,
2989 info
->bmiHeader
.biBitCount
);
2991 info
->bmiHeader
.biCompression
= 0;
2993 GDI_HEAP_UNLOCK( dc
->w
.hPalette
);
2998 /***********************************************************************
2999 * DIB_DoProtectDIBSection
3001 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
3003 DIBSECTION
*dib
= bmp
->dib
;
3004 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
3005 : -dib
->dsBm
.bmHeight
;
3006 INT totalSize
= dib
->dsBmih
.biSizeImage
? dib
->dsBmih
.biSizeImage
3007 : dib
->dsBm
.bmWidthBytes
* effHeight
;
3010 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
3011 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
3014 /***********************************************************************
3015 * X11DRV_DIB_DoUpdateDIBSection
3017 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
3019 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3020 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3022 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
3023 &descr
.infoBpp
, &descr
.compression
) == -1)
3027 descr
.palentry
= NULL
;
3028 descr
.image
= dib
->image
;
3029 descr
.colorMap
= (RGBQUAD
*)dib
->colorMap
;
3030 descr
.nColorMap
= dib
->nColorMap
;
3031 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
3032 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3034 switch (descr
.infoBpp
)
3040 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3044 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
3045 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
3046 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
3050 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff;
3051 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0xff00;
3052 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0xff0000;
3057 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3058 descr
.gc
= BITMAP_GC(bmp
);
3063 descr
.width
= bmp
->bitmap
.bmWidth
;
3064 descr
.height
= bmp
->bitmap
.bmHeight
;
3065 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
3069 TRACE("Copying from Pixmap to DIB bits\n");
3070 EnterCriticalSection( &X11DRV_CritSection
);
3071 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
3072 LeaveCriticalSection( &X11DRV_CritSection
);
3076 TRACE("Copying from DIB bits to Pixmap\n");
3077 EnterCriticalSection( &X11DRV_CritSection
);
3078 CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
3079 LeaveCriticalSection( &X11DRV_CritSection
);
3083 /***********************************************************************
3084 * X11DRV_DIB_FaultHandler
3086 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
3088 BOOL handled
= FALSE
;
3091 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
3092 if (!bmp
) return FALSE
;
3095 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3097 case X11DRV_DIB_GdiMod
:
3098 TRACE("called in status DIB_GdiMod\n" );
3099 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3100 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3101 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3102 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
3106 case X11DRV_DIB_InSync
:
3107 TRACE("called in status X11DRV_DIB_InSync\n" );
3108 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3109 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_AppMod
;
3113 case X11DRV_DIB_AppMod
:
3114 FIXME("called in status X11DRV_DIB_AppMod: this can't happen!\n" );
3117 case X11DRV_DIB_NoHandler
:
3118 FIXME("called in status DIB_NoHandler: this can't happen!\n" );
3122 GDI_HEAP_UNLOCK( (HBITMAP
)res
);
3126 /***********************************************************************
3127 * X11DRV_DIB_UpdateDIBSection
3129 void X11DRV_DIB_UpdateDIBSection(DC
*dc
, BOOL toDIB
)
3133 /* Ensure this is a Compatible DC that has a DIB section selected */
3136 if (!(dc
->w
.flags
& DC_MEMORY
)) return;
3138 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( dc
->w
.hBitmap
, BITMAP_MAGIC
);
3143 GDI_HEAP_UNLOCK(dc
->w
.hBitmap
);
3149 /* Prepare for access to the DIB by GDI functions */
3151 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3154 case X11DRV_DIB_NoHandler
:
3155 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3158 case X11DRV_DIB_GdiMod
:
3159 TRACE("fromDIB called in status X11DRV_DIB_GdiMod\n" );
3163 case X11DRV_DIB_InSync
:
3164 TRACE("fromDIB called in status X11DRV_DIB_InSync\n" );
3168 case X11DRV_DIB_AppMod
:
3169 TRACE("fromDIB called in status X11DRV_DIB_AppMod\n" );
3170 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3171 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3172 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
3178 /* Acknowledge write access to the DIB by GDI functions */
3180 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3183 case X11DRV_DIB_NoHandler
:
3184 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3187 case X11DRV_DIB_GdiMod
:
3188 TRACE(" toDIB called in status X11DRV_DIB_GdiMod\n" );
3192 case X11DRV_DIB_InSync
:
3193 TRACE(" toDIB called in status X11DRV_DIB_InSync\n" );
3194 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3195 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_GdiMod
;
3198 case X11DRV_DIB_AppMod
:
3199 FIXME(" toDIB called in status X11DRV_DIB_AppMod: "
3200 "this can't happen!\n" );
3205 GDI_HEAP_UNLOCK(dc
->w
.hBitmap
);
3208 /***********************************************************************
3209 * X11DRV_DIB_CreateDIBSection16
3211 HBITMAP16
X11DRV_DIB_CreateDIBSection16(
3212 DC
*dc
, BITMAPINFO
*bmi
, UINT16 usage
,
3213 SEGPTR
*bits
, HANDLE section
,
3214 DWORD offset
, DWORD ovr_pitch
)
3216 HBITMAP res
= X11DRV_DIB_CreateDIBSection(dc
, bmi
, usage
, NULL
,
3217 section
, offset
, ovr_pitch
);
3220 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3221 if ( bmp
&& bmp
->dib
)
3223 DIBSECTION
*dib
= bmp
->dib
;
3224 INT height
= dib
->dsBm
.bmHeight
>= 0 ?
3225 dib
->dsBm
.bmHeight
: -dib
->dsBm
.bmHeight
;
3226 INT size
= dib
->dsBmih
.biSizeImage
?
3227 dib
->dsBmih
.biSizeImage
: dib
->dsBm
.bmWidthBytes
* height
;
3228 if ( dib
->dsBm
.bmBits
)
3230 ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
=
3231 SELECTOR_AllocBlock( dib
->dsBm
.bmBits
, size
,
3232 SEGMENT_DATA
, FALSE
, FALSE
);
3234 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3235 dib
->dsBm
.bmBits
, size
, ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
,
3236 PTR_SEG_OFF_TO_SEGPTR(((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0));
3238 GDI_HEAP_UNLOCK( res
);
3241 *bits
= PTR_SEG_OFF_TO_SEGPTR( ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0 );
3247 /***********************************************************************
3248 * X11DRV_XShmErrorHandler
3251 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
)
3257 /***********************************************************************
3258 * X11DRV_XShmCreateImage
3262 extern BOOL
X11DRV_XShmCreateImage(XImage
** image
, int width
, int height
, int bpp
,
3263 XShmSegmentInfo
* shminfo
)
3265 int (*WineXHandler
)(Display
*, XErrorEvent
*);
3267 *image
= TSXShmCreateImage(display
, X11DRV_GetVisual(), bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
3268 if( *image
!= NULL
)
3270 EnterCriticalSection( &X11DRV_CritSection
);
3271 shminfo
->shmid
= shmget(IPC_PRIVATE
, (*image
)->bytes_per_line
* height
,
3273 if( shminfo
->shmid
!= -1 )
3275 shminfo
->shmaddr
= (*image
)->data
= shmat(shminfo
->shmid
, 0, 0);
3276 if( shminfo
->shmaddr
!= (char*)-1 )
3278 shminfo
->readOnly
= FALSE
;
3279 if( TSXShmAttach( display
, shminfo
) != 0)
3281 /* Reset the error flag */
3283 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
3284 XSync( display
, 0 );
3288 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3290 XSetErrorHandler(WineXHandler
);
3291 LeaveCriticalSection( &X11DRV_CritSection
);
3293 return TRUE
; /* Success! */
3295 /* An error occured */
3297 XSetErrorHandler(WineXHandler
);
3299 shmdt(shminfo
->shmaddr
);
3301 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3304 XDestroyImage(*image
);
3305 LeaveCriticalSection( &X11DRV_CritSection
);
3313 /***********************************************************************
3314 * X11DRV_DIB_CreateDIBSection
3316 HBITMAP
X11DRV_DIB_CreateDIBSection(
3317 DC
*dc
, BITMAPINFO
*bmi
, UINT usage
,
3318 LPVOID
*bits
, HANDLE section
,
3319 DWORD offset
, DWORD ovr_pitch
)
3322 BITMAPOBJ
*bmp
= NULL
;
3323 X11DRV_DIBSECTION
*dib
= NULL
;
3324 int *colorMap
= NULL
;
3327 /* Fill BITMAP32 structure with DIB data */
3328 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
3329 INT effHeight
, totalSize
;
3332 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3333 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
3334 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
3336 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
3338 bm
.bmWidth
= bi
->biWidth
;
3339 bm
.bmHeight
= effHeight
;
3340 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
3341 : DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
3342 bm
.bmPlanes
= bi
->biPlanes
;
3343 bm
.bmBitsPixel
= bi
->biBitCount
;
3346 /* Get storage location for DIB bits */
3347 totalSize
= bi
->biSizeImage
? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
3350 bm
.bmBits
= MapViewOfFile(section
, FILE_MAP_ALL_ACCESS
,
3351 0L, offset
, totalSize
);
3352 else if (ovr_pitch
&& offset
)
3353 bm
.bmBits
= (LPVOID
) offset
;
3356 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
3357 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
3360 /* Create Color Map */
3361 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
3362 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? dc
: NULL
,
3363 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
3365 /* Allocate Memory for DIB and fill structure */
3367 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
3370 dib
->dibSection
.dsBm
= bm
;
3371 dib
->dibSection
.dsBmih
= *bi
;
3373 /* Set dsBitfields values */
3374 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
3376 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
3378 else switch( bi
->biBitCount
)
3381 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
3382 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
3383 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
3387 dib
->dibSection
.dsBitfields
[0] = 0xff;
3388 dib
->dibSection
.dsBitfields
[1] = 0xff00;
3389 dib
->dibSection
.dsBitfields
[2] = 0xff0000;
3393 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff;
3394 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0xff00;
3395 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0xff0000;
3398 dib
->dibSection
.dshSection
= section
;
3399 dib
->dibSection
.dsOffset
= offset
;
3401 dib
->status
= X11DRV_DIB_NoHandler
;
3404 dib
->nColorMap
= nColorMap
;
3405 dib
->colorMap
= colorMap
;
3408 /* Create Device Dependent Bitmap and add DIB pointer */
3411 res
= CreateDIBitmap(dc
->hSelf
, bi
, 0, NULL
, bmi
, usage
);
3414 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3417 bmp
->dib
= (DIBSECTION
*) dib
;
3419 if(!bmp
->physBitmap
)
3420 X11DRV_CreateBitmap(res
);
3428 if (TSXShmQueryExtension(display
) &&
3429 X11DRV_XShmCreateImage( &dib
->image
, bm
.bmWidth
, effHeight
,
3430 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
) )
3432 ; /* Created Image */
3434 XCREATEIMAGE( dib
->image
, bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
3435 dib
->shminfo
.shmid
= -1;
3439 /* Clean up in case of errors */
3440 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
3442 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3443 res
, bmp
, dib
, bm
.bmBits
);
3447 UnmapViewOfFile(bm
.bmBits
), bm
.bmBits
= NULL
;
3449 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
3452 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
3453 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
3454 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
3455 if (res
) { DeleteObject(res
); res
= 0; }
3458 /* Install fault handler, if possible */
3461 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
3463 if (section
|| offset
)
3465 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3466 if (dib
) dib
->status
= X11DRV_DIB_AppMod
;
3470 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3471 if (dib
) dib
->status
= X11DRV_DIB_InSync
;
3476 /* Return BITMAP handle and storage location */
3477 if (res
) GDI_HEAP_UNLOCK(res
);
3478 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
3482 /***********************************************************************
3483 * X11DRV_DIB_DeleteDIBSection
3485 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
3487 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3491 if (dib
->shminfo
.shmid
!= -1)
3493 TSXShmDetach (display
, &(dib
->shminfo
));
3494 XDestroyImage (dib
->image
);
3495 shmdt (dib
->shminfo
.shmaddr
);
3496 dib
->shminfo
.shmid
= -1;
3499 XDestroyImage( dib
->image
);
3503 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
3507 WORD count
= (GET_SEL_LIMIT( dib
->selector
) >> 16) + 1;
3508 SELECTOR_FreeBlock( dib
->selector
, count
);
3513 /**************************************************************************
3514 * X11DRV_DIB_CreateDIBFromPixmap
3516 * Allocates a packed DIB and copies the Pixmap data into it.
3517 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
3519 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
3522 BITMAPOBJ
*pBmp
= NULL
;
3523 HGLOBAL hPackedDIB
= 0;
3525 /* Allocates an HBITMAP which references the Pixmap passed to us */
3526 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
3529 TRACE("\tCould not create bitmap header for Pixmap\n");
3534 * Create a packed DIB from the Pixmap wrapper bitmap created above.
3535 * A packed DIB contains a BITMAPINFO structure followed immediately by
3536 * an optional color palette and the pixel data.
3538 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
3540 /* Get a pointer to the BITMAPOBJ structure */
3541 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3543 /* We can now get rid of the HBITMAP wrapper we created earlier.
3544 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
3548 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
3549 pBmp
->physBitmap
= NULL
;
3555 TRACE("\tReturning packed DIB %x\n", hPackedDIB
);
3560 /**************************************************************************
3561 * X11DRV_DIB_CreatePixmapFromDIB
3563 * Creates a Pixmap from a packed DIB
3565 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
3567 Pixmap pixmap
= None
;
3569 BITMAPOBJ
*pBmp
= NULL
;
3570 LPBYTE pPackedDIB
= NULL
;
3571 LPBITMAPINFO pbmi
= NULL
;
3572 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
3573 LPBYTE pbits
= NULL
;
3575 /* Get a pointer to the packed DIB's data */
3576 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
3577 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
3578 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
3579 pbits
= (LPBYTE
)(pPackedDIB
3580 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
3582 /* Create a DDB from the DIB */
3584 hBmp
= CreateDIBitmap(hdc
,
3591 GlobalUnlock(hPackedDIB
);
3593 TRACE("CreateDIBitmap returned %x\n", hBmp
);
3595 /* Retrieve the internal Pixmap from the DDB */
3597 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3599 pixmap
= (Pixmap
)pBmp
->physBitmap
;
3600 /* clear the physBitmap so that we can steal its pixmap */
3601 pBmp
->physBitmap
= NULL
;
3604 /* Delete the DDB we created earlier now that we have stolen its pixmap */
3607 TRACE("\tReturning Pixmap %ld\n", pixmap
);