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