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) */
26 #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 /* This structure holds the arguments for DIB_SetImageBits() */
46 PALETTEENTRY
*palentry
;
67 } X11DRV_DIB_IMAGEBITS_DESCR
;
69 /***********************************************************************
72 BOOL
X11DRV_DIB_Init(void)
77 for( i
= 0; bitmapDepthTable
[i
]; i
++ )
79 testimage
= TSXCreateImage(display
, X11DRV_GetVisual(),
80 bitmapDepthTable
[i
], ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
81 if( testimage
) ximageDepthTable
[i
] = testimage
->bits_per_pixel
;
83 TSXDestroyImage(testimage
);
89 /***********************************************************************
90 * X11DRV_DIB_GetXImageWidthBytes
92 * Return the width of an X image in bytes
94 int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
98 if (!ximageDepthTable
[0]) {
101 for( i
= 0; bitmapDepthTable
[i
] ; i
++ )
102 if( bitmapDepthTable
[i
] == depth
)
103 return (4 * ((width
* ximageDepthTable
[i
] + 31)/32));
105 WARN("(%d): Unsupported depth\n", depth
);
109 /***********************************************************************
110 * X11DRV_DIB_GenColorMap
112 * Fills the color map of a bitmap palette. Should not be called
113 * for a >8-bit deep bitmap.
115 int *X11DRV_DIB_GenColorMap( DC
*dc
, int *colorMapping
,
116 WORD coloruse
, WORD depth
, BOOL quads
,
117 const void *colorPtr
, int start
, int end
)
121 if (coloruse
== DIB_RGB_COLORS
)
125 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
127 if (depth
== 1) /* Monochrome */
128 for (i
= start
; i
< end
; i
++, rgb
++)
129 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
130 rgb
->rgbBlue
> 255*3/2);
132 for (i
= start
; i
< end
; i
++, rgb
++)
133 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbRed
,
139 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
141 if (depth
== 1) /* Monochrome */
142 for (i
= start
; i
< end
; i
++, rgb
++)
143 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
144 rgb
->rgbtBlue
> 255*3/2);
146 for (i
= start
; i
< end
; i
++, rgb
++)
147 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbtRed
,
152 else /* DIB_PAL_COLORS */
155 WORD
* index
= (WORD
*)colorPtr
;
157 for (i
= start
; i
< end
; i
++, index
++)
158 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(*index
) );
160 for (i
= start
; i
< end
; i
++)
161 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(i
) );
168 /***********************************************************************
169 * X11DRV_DIB_BuildColorMap
171 * Build the color map from the bitmap palette. Should not be called
172 * for a >8-bit deep bitmap.
174 int *X11DRV_DIB_BuildColorMap( DC
*dc
, WORD coloruse
, WORD depth
,
175 const BITMAPINFO
*info
, int *nColors
)
179 const void *colorPtr
;
182 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
184 colors
= info
->bmiHeader
.biClrUsed
;
185 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
186 colorPtr
= info
->bmiColors
;
188 else /* assume BITMAPCOREINFO */
190 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
191 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
196 ERR("called with >256 colors!\n");
200 /* just so CopyDIBSection doesn't have to create an identity palette */
201 if (coloruse
== (WORD
)-1) colorPtr
= NULL
;
203 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
204 colors
* sizeof(int) )))
208 return X11DRV_DIB_GenColorMap( dc
, colorMapping
, coloruse
, depth
,
209 isInfo
, colorPtr
, 0, colors
);
213 /***********************************************************************
214 * X11DRV_DIB_MapColor
216 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
, int oldcol
)
220 if ((oldcol
< nPhysMap
) && (physMap
[oldcol
] == phys
))
223 for (color
= 0; color
< nPhysMap
; color
++)
224 if (physMap
[color
] == phys
)
227 WARN("Strange color %08x\n", phys
);
232 /*********************************************************************
233 * X11DRV_DIB_GetNearestIndex
235 * Helper for X11DRV_DIB_GetDIBits.
236 * Returns the nearest colour table index for a given RGB.
237 * Nearest is defined by minimizing the sum of the squares.
239 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
241 INT i
, best
= -1, diff
, bestdiff
= -1;
244 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
245 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
246 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
247 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
250 if(best
== -1 || diff
< bestdiff
) {
258 /***********************************************************************
259 * X11DRV_DIB_SetImageBits_1_Line
261 * Handles a single line of 1 bit data.
263 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth
, int left
, int *colors
,
264 XImage
*bmpImage
, int h
, const BYTE
*bits
)
269 if((extra
= (left
& 7)) != 0) {
276 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
277 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--)
280 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
281 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 6) & 1] );
282 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 5) & 1] );
283 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 4) & 1] );
284 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 3) & 1] );
285 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 2) & 1] );
286 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 1) & 1] );
287 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 1] );
292 case 7: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
293 case 6: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
294 case 5: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
295 case 4: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
296 case 3: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
297 case 2: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
298 case 1: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
302 /***********************************************************************
303 * X11DRV_DIB_SetImageBits_1
305 * SetDIBits for a 1-bit deep DIB.
307 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
308 DWORD srcwidth
, DWORD dstwidth
, int left
,
309 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
314 for (h
= lines
-1; h
>=0; h
--) {
315 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
317 srcbits
+= linebytes
;
321 for (h
= 0; h
< lines
; h
++) {
322 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
324 srcbits
+= linebytes
;
329 /***********************************************************************
330 * X11DRV_DIB_GetImageBits_1
332 * GetDIBits for a 1-bit deep DIB.
334 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
335 DWORD dstwidth
, DWORD srcwidth
,
336 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
337 XImage
*bmpImage
, DWORD linebytes
)
345 dstbits
= dstbits
+ linebytes
* (lines
- 1);
346 linebytes
= -linebytes
;
351 switch(bmpImage
->depth
) {
354 /* ==== monochrome bitmap to monochrome dib ==== */
356 /* ==== 4 colormap bitmap to monochrome dib ==== */
357 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
361 for (h
= lines
- 1; h
>= 0; h
--) {
362 for (x
= 0; x
< dstwidth
; x
++) {
363 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
364 if (!(x
&7)) *bits
= 0;
365 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2,
368 val
.peBlue
) << (7 - (x
& 7)));
369 if ((x
&7)==7) bits
++;
371 bits
= (dstbits
+= linebytes
);
374 else goto notsupported
;
379 /* ==== 8 colormap bitmap to monochrome dib ==== */
380 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
385 for( h
= lines
- 1; h
>= 0; h
-- ) {
386 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
387 for( x
= 0; x
< dstwidth
; x
++ ) {
388 if (!(x
&7)) *bits
= 0;
389 val
= srccolors
[(int)*srcpixel
++];
390 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 2,
393 val
.peBlue
) << (7-(x
&7)) );
394 if ((x
&7)==7) bits
++;
396 bits
= (dstbits
+= linebytes
);
399 else goto notsupported
;
408 /* ==== 555 BGR bitmap to monochrome dib ==== */
409 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
411 for( h
= lines
- 1; h
>= 0; h
--) {
412 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
413 for( x
= 0; x
< dstwidth
; x
++) {
414 if (!(x
&7)) *bits
= 0;
416 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
417 ((val
>> 7) & 0xf8) |
419 ((val
>> 2) & 0xf8) |
421 ((val
<< 3) & 0xf8) |
422 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
423 if ((x
&7)==7) bits
++;
425 bits
= (dstbits
+= linebytes
);
428 /* ==== 555 RGB bitmap to monochrome dib ==== */
429 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
431 for( h
= lines
- 1; h
>= 0; h
--)
433 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
434 for( x
= 0; x
< dstwidth
; x
++) {
435 if (!(x
&1)) *bits
= 0;
437 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
438 ((val
<< 3) & 0xf8) |
440 ((val
>> 2) & 0xf8) |
442 ((val
>> 7) & 0xf8) |
443 ((val
>> 12) & 0x7) ) << (7-(x
&7)) );
444 if ((x
&7)==7) bits
++;
446 bits
= (dstbits
+= linebytes
);
449 else goto notsupported
;
458 /* ==== 565 BGR bitmap to monochrome dib ==== */
459 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
461 for( h
= lines
- 1; h
>= 0; h
--)
463 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
464 for( x
= 0; x
< dstwidth
; x
++) {
465 if (!(x
&7)) *bits
= 0;
467 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
468 ((val
>> 8) & 0xf8) |
470 ((val
>> 3) & 0xfc) |
472 ((val
<< 3) & 0xf8) |
473 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
474 if ((x
&7)==7) bits
++;
476 bits
= (dstbits
+= linebytes
);
479 /* ==== 565 RGB bitmap to monochrome dib ==== */
480 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
482 for( h
= lines
- 1; h
>= 0; h
--)
484 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
485 for( x
= 0; x
< dstwidth
; x
++) {
486 if (!(x
&7)) *bits
= 0;
488 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
489 ((val
<< 3) & 0xf8) |
491 ((val
>> 3) & 0xfc) |
493 ((val
>> 8) & 0xf8) |
494 ((val
>> 13) & 0x7) ) << (7-(x
&7)) );
495 if ((x
&7)==7) bits
++;
497 bits
= (dstbits
+= linebytes
);
500 else goto notsupported
;
509 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
510 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
512 for (h
= lines
- 1; h
>= 0; h
--)
514 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
515 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
516 if (!(x
&7)) *bits
= 0;
517 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << (7-(x
&7)) );
518 if ((x
&7)==7) bits
++;
520 bits
= (dstbits
+= linebytes
);
523 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
524 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
526 for (h
= lines
- 1; h
>= 0; h
--)
528 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
529 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
530 if (!(x
& 7)) *bits
= 0;
531 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << (7-(x
&7)) );
532 if ((x
& 7) == 7) bits
++;
534 bits
= (dstbits
+= linebytes
);
537 else goto notsupported
;
541 default: /* ? bit bmp -> monochrome DIB */
544 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
546 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
547 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
548 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
550 for( h
= lines
- 1; h
>= 0; h
-- ) {
551 for( x
= 0; x
< dstwidth
; x
++ ) {
552 if (!(x
&7)) *bits
= 0;
553 *bits
|= (XGetPixel( bmpImage
, x
, h
) >= white
)
555 if ((x
&7)==7) bits
++;
557 bits
= (dstbits
+= linebytes
);
564 /***********************************************************************
565 * X11DRV_DIB_SetImageBits_4
567 * SetDIBits for a 4-bit deep DIB.
569 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
570 DWORD srcwidth
, DWORD dstwidth
, int left
,
571 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
575 const BYTE
*bits
= srcbits
+ (left
>> 1);
583 for (h
= lines
-1; h
>= 0; h
--) {
584 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
586 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
587 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
589 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
590 srcbits
+= linebytes
;
591 bits
= srcbits
+ (left
>> 1);
595 for (h
= 0; h
< lines
; h
++) {
596 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
598 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
599 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
601 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
602 srcbits
+= linebytes
;
603 bits
= srcbits
+ (left
>> 1);
610 /***********************************************************************
611 * X11DRV_DIB_GetImageBits_4
613 * GetDIBits for a 4-bit deep DIB.
615 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
616 DWORD srcwidth
, DWORD dstwidth
,
617 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
618 XImage
*bmpImage
, DWORD linebytes
)
628 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
629 linebytes
= -linebytes
;
634 switch(bmpImage
->depth
) {
637 /* ==== monochrome bitmap to 4 colormap dib ==== */
639 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
640 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
644 for (h
= lines
-1; h
>= 0; h
--) {
645 for (x
= 0; x
< dstwidth
; x
++) {
646 if (!(x
&1)) *bits
= 0;
647 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
648 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 16,
651 val
.peBlue
) << (4-((x
&1)<<2)));
652 if ((x
&1)==1) bits
++;
654 bits
= (dstbits
+= linebytes
);
657 else goto notsupported
;
662 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
663 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
667 for( h
= lines
- 1; h
>= 0; h
-- ) {
668 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
669 for( x
= 0; x
< dstwidth
; x
++ ) {
670 if (!(x
&1)) *bits
= 0;
671 val
= srccolors
[(int)*srcpixel
++];
672 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 16,
675 val
.peBlue
) << (4*(1-(x
&1))) );
676 if ((x
&1)==1) bits
++;
678 bits
= (dstbits
+= linebytes
);
681 else goto notsupported
;
690 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
691 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
693 for( h
= lines
- 1; h
>= 0; h
--) {
694 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
695 for( x
= 0; x
< dstwidth
; x
++) {
696 if (!(x
&1)) *bits
= 0;
698 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
699 ((val
>> 7) & 0xf8) |
701 ((val
>> 2) & 0xf8) |
703 ((val
<< 3) & 0xf8) |
704 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
705 if ((x
&1)==1) bits
++;
707 bits
= (dstbits
+= linebytes
);
710 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
711 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
713 for( h
= lines
- 1; h
>= 0; h
--)
715 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
716 for( x
= 0; x
< dstwidth
; x
++) {
717 if (!(x
&1)) *bits
= 0;
719 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
720 ((val
<< 3) & 0xf8) |
722 ((val
>> 2) & 0xfc) |
724 ((val
>> 7) & 0xf8) |
725 ((val
>> 12) & 0x7) ) << ((1-(x
&1))<<2) );
726 if ((x
&1)==1) bits
++;
728 bits
= (dstbits
+= linebytes
);
731 else goto notsupported
;
740 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
741 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
743 for( h
= lines
- 1; h
>= 0; h
--)
745 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
746 for( x
= 0; x
< dstwidth
; x
++) {
747 if (!(x
&1)) *bits
= 0;
749 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
750 ((val
>> 8) & 0xf8) |
752 ((val
>> 3) & 0xfc) |
754 ((val
<< 3) & 0xf8) |
755 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
756 if ((x
&1)==1) bits
++;
758 bits
= (dstbits
+= linebytes
);
761 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
762 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
764 for( h
= lines
- 1; h
>= 0; h
--)
766 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
767 for( x
= 0; x
< dstwidth
; x
++) {
768 if (!(x
&1)) *bits
= 0;
770 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
771 ((val
<< 3) & 0xf8) |
773 ((val
>> 3) & 0xfc) |
775 ((val
>> 8) & 0xf8) |
776 ((val
>> 13) & 0x7) ) << ((1-(x
&1))<<2) );
777 if ((x
&1)==1) bits
++;
779 bits
= (dstbits
+= linebytes
);
782 else goto notsupported
;
791 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
792 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
794 for (h
= lines
- 1; h
>= 0; h
--)
796 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
797 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
798 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << 4) |
799 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[6] , srcpixel
[5], srcpixel
[4]);
800 bits
= (dstbits
+= linebytes
);
803 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
804 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
806 for (h
= lines
- 1; h
>= 0; h
--)
808 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
809 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
810 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << 4) |
811 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[4] , srcpixel
[5], srcpixel
[6]);
812 bits
= (dstbits
+= linebytes
);
815 else goto notsupported
;
819 default: /* ? bit bmp -> 4 bit DIB */
821 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
822 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
823 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
824 for (h
= lines
-1; h
>= 0; h
--) {
825 for (x
= 0; x
< dstwidth
-1; x
+= 2)
827 *bits
++ = (X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel( bmpImage
, x
, h
), 0) << 4)
828 | (X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel( bmpImage
, x
+1, h
), 0) & 0x0f);
831 *bits
= (X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel( bmpImage
, x
, h
), 0) << 4);
832 bits
= (dstbits
+= linebytes
);
838 /***********************************************************************
839 * X11DRV_DIB_SetImageBits_RLE4
841 * SetDIBits for a 4-bit deep compressed DIB.
843 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
844 DWORD width
, DWORD dstwidth
,
845 int left
, int *colors
,
848 int x
= 0, c
, length
;
849 const BYTE
*begin
= bits
;
853 while ((int)lines
>= 0) {
855 if (length
) { /* encoded */
863 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>>4]);
871 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
882 case 1: /* eopicture */
888 FIXME_(x11drv
)("x-delta is too large?\n");
894 default: /* absolute */
902 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>> 4]);
910 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
913 if ((bits
- begin
) & 1)
922 /***********************************************************************
923 * X11DRV_DIB_SetImageBits_8
925 * SetDIBits for an 8-bit deep DIB.
927 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
928 DWORD srcwidth
, DWORD dstwidth
, int left
,
929 const int *colors
, XImage
*bmpImage
,
941 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
942 linebytes
= -linebytes
;
945 bits
= srcbits
+ left
;
947 switch (bmpImage
->depth
) {
950 #if defined(__i386__) && defined(__GNUC__)
951 /* Some X servers might have 32 bit/ 16bit deep pixel */
952 if (lines
&& (dstwidth
!=left
) && (bmpImage
->bits_per_pixel
== 16))
954 for (h
= lines
; h
--; ) {
955 int _cl1
,_cl2
; /* temp outputs for asm below */
956 /* Borrowed from DirectDraw */
957 __asm__
__volatile__(
962 " movw (%%edx,%%eax,4),%%ax\n"
966 :"=S" (bits
), "=D" (_cl1
), "=c" (_cl2
)
968 "D" (bmpImage
->data
+h
*bmpImage
->bytes_per_line
+left
*2),
971 :"eax", "cc", "memory"
973 bits
= (srcbits
+= linebytes
) + left
;
980 #if defined(__i386__) && defined(__GNUC__)
981 if (lines
&& (dstwidth
!=left
) && (bmpImage
->bits_per_pixel
== 32))
983 for (h
= lines
; h
--; ) {
984 int _cl1
,_cl2
; /* temp outputs for asm below */
985 /* Borrowed from DirectDraw */
986 __asm__
__volatile__(
991 " movl (%%edx,%%eax,4),%%eax\n"
995 :"=S" (bits
), "=D" (_cl1
), "=c" (_cl2
)
997 "D" (bmpImage
->data
+h
*bmpImage
->bytes_per_line
+left
*4),
1000 :"eax", "cc", "memory"
1002 bits
= (srcbits
+= linebytes
) + left
;
1009 break; /* use slow generic case below */
1012 for (h
= lines
- 1; h
>= 0; h
--) {
1013 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
1014 color
= colors
[*bits
];
1015 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
1017 bits
= (srcbits
+= linebytes
) + left
;
1021 /***********************************************************************
1022 * X11DRV_DIB_GetImageBits_8
1024 * GetDIBits for an 8-bit deep DIB.
1026 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
1027 DWORD srcwidth
, DWORD dstwidth
,
1028 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1029 XImage
*bmpImage
, DWORD linebytes
)
1038 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1039 linebytes
= -linebytes
;
1046 This condition is true when GetImageBits has been called by UpdateDIBSection.
1047 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
1048 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
1050 if (!srccolors
) goto updatesection
;
1052 switch(bmpImage
->depth
) {
1055 /* ==== monochrome bitmap to 8 colormap dib ==== */
1057 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
1058 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1062 for (h
= lines
- 1; h
>= 0; h
--) {
1063 for (x
= 0; x
< dstwidth
; x
++) {
1064 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
1065 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
1066 val
.peGreen
, val
.peBlue
);
1068 bits
= (dstbits
+= linebytes
);
1071 else goto notsupported
;
1076 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
1077 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1082 for (h
= lines
- 1; h
>= 0; h
--) {
1083 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1084 for (x
= 0; x
< dstwidth
; x
++) {
1085 val
= srccolors
[(int)*srcpixel
++];
1086 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
1087 val
.peGreen
, val
.peBlue
);
1089 bits
= (dstbits
+= linebytes
);
1092 else goto notsupported
;
1101 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1102 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1104 for( h
= lines
- 1; h
>= 0; h
--)
1106 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1107 for( x
= 0; x
< dstwidth
; x
++ )
1110 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1111 ((val
>> 7) & 0xf8) |
1112 ((val
>> 12) & 0x7),
1113 ((val
>> 2) & 0xf8) |
1115 ((val
<< 3) & 0xf8) |
1116 ((val
>> 2) & 0x7) );
1118 bits
= (dstbits
+= linebytes
);
1121 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1122 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1124 for( h
= lines
- 1; h
>= 0; h
--)
1126 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1127 for( x
= 0; x
< dstwidth
; x
++ )
1130 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1131 ((val
<< 3) & 0xf8) |
1133 ((val
>> 2) & 0xf8) |
1135 ((val
>> 7) & 0xf8) |
1136 ((val
>> 12) & 0x7) );
1138 bits
= (dstbits
+= linebytes
);
1141 else goto notsupported
;
1150 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1151 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
1153 for( h
= lines
- 1; h
>= 0; h
--)
1155 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1156 for( x
= 0; x
< dstwidth
; x
++ )
1159 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1160 ((val
>> 8) & 0xf8) |
1161 ((val
>> 13) & 0x7),
1162 ((val
>> 3) & 0xfc) |
1164 ((val
<< 3) & 0xf8) |
1165 ((val
>> 2) & 0x7) );
1167 bits
= (dstbits
+= linebytes
);
1170 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1171 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1173 for( h
= lines
- 1; h
>= 0; h
--)
1175 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1176 for( x
= 0; x
< dstwidth
; x
++ )
1179 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1180 ((val
<< 3) & 0xf8) |
1182 ((val
>> 3) & 0x00fc) |
1184 ((val
>> 8) & 0x00f8) |
1185 ((val
>> 13) & 0x7) );
1187 bits
= (dstbits
+= linebytes
);
1190 else goto notsupported
;
1199 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1200 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1202 for (h
= lines
- 1; h
>= 0; h
--)
1204 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1205 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1206 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1207 srcpixel
[2] , srcpixel
[1], *srcpixel
);
1208 bits
= (dstbits
+= linebytes
);
1211 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1212 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1214 for (h
= lines
- 1; h
>= 0; h
--)
1216 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1217 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1218 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1219 *srcpixel
, srcpixel
[1], srcpixel
[2]);
1220 bits
= (dstbits
+= linebytes
);
1224 else goto notsupported
;
1228 default: /* ? bit bmp -> 8 bit DIB */
1230 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1231 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1232 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1234 for (h
= lines
- 1; h
>= 0; h
--) {
1235 for (x
= 0; x
< dstwidth
; x
++, bits
++) {
1236 *bits
= X11DRV_DIB_MapColor((int *)colors
, 256,
1237 XGetPixel( bmpImage
, x
, h
), *bits
);
1239 bits
= (dstbits
+= linebytes
);
1245 /***********************************************************************
1246 * X11DRV_DIB_SetImageBits_RLE8
1248 * SetDIBits for an 8-bit deep compressed DIB.
1250 * This function rewritten 941113 by James Youngman. WINE blew out when I
1251 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1253 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1254 * 'End of bitmap' escape code. This code is very much laxer in what it
1255 * allows to end the expansion. Possibly too lax. See the note by
1256 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1257 * bitmap should end with RleEnd, but on the other hand, software exists
1258 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1261 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1262 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1266 enum Rle8_EscapeCodes
1269 * Apologies for polluting your file's namespace...
1271 RleEol
= 0, /* End of line */
1272 RleEnd
= 1, /* End of bitmap */
1273 RleDelta
= 2 /* Delta */
1276 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1277 DWORD width
, DWORD dstwidth
,
1278 int left
, int *colors
,
1281 int x
; /* X-positon on each line. Increases. */
1282 int line
; /* Line #. Starts at lines-1, decreases */
1283 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1284 BYTE length
; /* The length pf a run */
1285 BYTE color_index
; /* index into colors[] as read from bits */
1286 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1287 int color
; /* value of colour[color_index] */
1289 if (lines
== 0) /* Let's hope this doesn't happen. */
1293 * Note that the bitmap data is stored by Windows starting at the
1294 * bottom line of the bitmap and going upwards. Within each line,
1295 * the data is stored left-to-right. That's the reason why line
1296 * goes from lines-1 to 0. [JAY]
1306 * If the length byte is not zero (which is the escape value),
1307 * We have a run of length pixels all the same colour. The colour
1308 * index is stored next.
1310 * If the length byte is zero, we need to read the next byte to
1311 * know what to do. [JAY]
1316 * [Run-Length] Encoded mode
1318 color_index
= (*pIn
++); /* Get the colour index. */
1319 color
= colors
[color_index
];
1328 XPutPixel(bmpImage
, x
++, line
, color
);
1334 * Escape codes (may be an absolute sequence though)
1336 escape_code
= (*pIn
++);
1339 case RleEol
: /* =0, end of line */
1346 case RleEnd
: /* =1, end of bitmap */
1349 * Not all RLE8 bitmaps end with this
1350 * code. For example, Paint Shop Pro
1351 * produces some that don't. That's (I think)
1352 * what caused the previous implementation to
1355 line
=-1; /* Cause exit from do loop. */
1359 case RleDelta
: /* =2, a delta */
1362 * Note that deltaing to line 0
1363 * will cause an exit from the loop,
1364 * which may not be what is intended.
1365 * The fact that there is a delta in the bits
1366 * almost certainly implies that there is data
1367 * to follow. You may feel that we should
1368 * jump to the top of the loop to avoid exiting
1371 * TODO: Decide what to do here in that case. [JAY]
1377 TRACE("Delta to last line of bitmap "
1378 "(wrongly?) causes loop exit\n");
1383 default: /* >2, switch to absolute mode */
1388 length
= escape_code
;
1391 color_index
= (*pIn
++);
1397 XPutPixel(bmpImage
, x
++, line
,
1398 colors
[color_index
]);
1402 * If you think for a moment you'll realise that the
1403 * only time we could ever possibly read an odd
1404 * number of bytes is when there is a 0x00 (escape),
1405 * a value >0x02 (absolute mode) and then an odd-
1406 * length run. Therefore this is the only place we
1407 * need to worry about it. Everywhere else the
1408 * bytes are always read in pairs. [JAY]
1410 if (escape_code
& 1)
1411 pIn
++; /* Throw away the pad byte. */
1414 } /* switch (escape_code) : Escape sequence */
1415 } /* process either an encoded sequence or an escape sequence */
1417 /* We expect to come here more than once per line. */
1418 } while (line
>= 0); /* Do this until the bitmap is filled */
1421 * Everybody comes here at the end.
1422 * Check how we exited the loop and print a message if it's a bit odd.
1425 if ( (*(pIn
-2) != 0/*escape*/) || (*(pIn
-1)!= RleEnd
) )
1427 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1428 "bytes were: %02X %02X.\n", (int)*(pIn
-2),(int)*(pIn
-1));
1433 /***********************************************************************
1434 * X11DRV_DIB_SetImageBits_16
1436 * SetDIBits for a 16-bit deep DIB.
1438 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1439 DWORD srcwidth
, DWORD dstwidth
, int left
,
1440 DC
*dc
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1441 XImage
*bmpImage
, DWORD linebytes
)
1449 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1450 linebytes
= -linebytes
;
1453 switch ( bmpImage
->depth
)
1456 /* using same format as XImage */
1457 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1458 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1459 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1460 else /* We need to do a conversion from a 565 dib */
1462 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1464 int div
= dstwidth
% 2;
1466 for (h
= lines
- 1; h
>= 0; h
--) {
1467 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1468 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1470 *dstpixel
++ = ((val
>> 1) & 0x7fe07fe0) | (val
& 0x001f001f); /* Red & Green & Blue */
1472 if (div
!= 0) /* Odd width? */
1473 *dstpixel
= ((*(WORD
*)ptr
>> 1) & 0x7fe0) | (*(WORD
*)ptr
& 0x001f);
1474 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1480 /* using same format as XImage */
1481 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1482 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1483 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1484 else /* We need to do a conversion from a 555 dib */
1486 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1488 int div
= dstwidth
% 2;
1490 for (h
= lines
- 1; h
>= 0; h
--) {
1491 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1492 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1494 *dstpixel
++ = ((val
<< 1) & 0xffc0ffc0) | ((val
>> 4) & 0x00200020) | /* Red & Green */
1495 (val
& 0x001f001f); /* Blue */
1497 if (div
!= 0) /* Odd width? */
1498 *dstpixel
= ((*(WORD
*)ptr
<< 1) & 0xffc0) | ((*(WORD
*)ptr
>> 4) & 0x0020)
1499 | (*(WORD
*)ptr
& 0x001f);
1500 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1509 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1512 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1514 if ((rSrc
== 0xF800) && (gSrc
== 0x07E0) && (bSrc
== 0x001F)) {
1515 /* ==== 555 RGB dib to 24/32 RGB bitmap ==== */
1516 for (h
= lines
- 1; h
>= 0; h
--) {
1517 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1518 for (x
= 0; x
< dstwidth
; x
++) {
1520 *dstpixel
++ = ((val
<< 8) & 0xF80000) | /* Red */
1521 ((val
<< 5) & 0x00FC00) | /* Green */
1522 ((val
<< 3) & 0x0000FF); /* Blue */
1524 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1527 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1528 for (h
= lines
- 1; h
>= 0; h
--) {
1529 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1530 for (x
= 0; x
< dstwidth
; x
++) {
1533 *dstpixel
++ = ((val
<< 9) & 0xf80000) | ((val
<< 4) & 0x070000) | /* Red */
1534 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1535 ((val
<< 3) & 0x0000f8) | ((val
>> 2) & 0x000007); /* Blue */
1537 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1541 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1542 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1544 for (h
= lines
- 1; h
>= 0; h
--) {
1545 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1546 for (x
= 0; x
< dstwidth
; x
++) {
1549 *dstpixel
++ = ((val
>> 7) & 0x0000f8) | ((val
>> 12) & 0x000007) | /* Red */
1550 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1551 ((val
<< 19) & 0xf80000) | ((val
>> 14) & 0x070000); /* Blue */
1553 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1564 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1568 /* Set color scaling values */
1569 if ( rSrc
== 0x7c00 ) { sc1
= 7; sc2
= 2; } /* 555 dib */
1570 else { sc1
= 8; sc2
= 3; } /* 565 dib */
1572 for (h
= lines
- 1; h
>= 0; h
--) {
1573 for (x
= left
; x
< dstwidth
+left
; x
++) {
1575 XPutPixel( bmpImage
, x
, h
,
1576 X11DRV_PALETTE_ToPhysical(dc
, RGB(((val
& rSrc
) >> sc1
), /* Red */
1577 ((val
& gSrc
) >> sc2
), /* Green */
1578 ((val
& bSrc
) << 3)))); /* Blue */
1580 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
1586 FIXME("16 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
1593 /***********************************************************************
1594 * X11DRV_DIB_GetImageBits_16
1596 * GetDIBits for an 16-bit deep DIB.
1598 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
1599 DWORD dstwidth
, DWORD srcwidth
,
1600 PALETTEENTRY
*srccolors
,
1601 DWORD rDst
, DWORD gDst
, DWORD bDst
,
1602 XImage
*bmpImage
, DWORD dibpitch
)
1607 DWORD linebytes
= dibpitch
;
1612 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
1613 linebytes
= -linebytes
;
1616 /* Set color scaling values */
1617 if ( rDst
== 0x7c00 ) { rsc
= 7; gsc
= 2; } /* 555 dib */
1618 else { rsc
= 8; gsc
= 3; } /* 565 dib */
1620 switch ( bmpImage
->depth
)
1623 /* using same format as XImage */
1624 if (rDst
== bmpImage
->red_mask
&& bDst
== bmpImage
->blue_mask
)
1625 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+= linebytes
)
1626 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, srcwidth
*2 );
1627 /* reversed format (BGR <=> RGB) */
1628 else if (rDst
== bmpImage
->blue_mask
&& bDst
== bmpImage
->red_mask
)
1630 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1632 int div
= srcwidth
% 2;
1634 for (h
= lines
- 1; h
>= 0; h
--) {
1635 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1636 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1638 *ptr
++ = ((val
<< 10) & 0xf800f800) | (val
& 0x03e003e0) | /* Red & Green */
1639 ((val
>> 10) & 0x001f001f); /* Blue */
1641 if (div
!= 0) /* Odd width? */
1642 *ptr
= ((*(WORD
*)srcpixel
<< 1) & 0xffc0) | ((*(WORD
*)srcpixel
>> 4) & 0x0020) |
1643 (*(WORD
*)srcpixel
& 0x001f);
1644 ptr
= (LPDWORD
)(dstbits
+= linebytes
);
1647 else goto notsupported
;
1653 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1655 int div
= srcwidth
% 2;
1657 /* using same format as XImage */
1658 if (rDst
== bmpImage
->red_mask
&& bDst
== bmpImage
->blue_mask
)
1659 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+= linebytes
)
1660 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, srcwidth
*2 );
1661 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1662 else if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f &&
1663 rDst
== 0x7c00 && bDst
== 0x001f)
1665 for (h
= lines
- 1; h
>= 0; h
--) {
1666 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1667 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1669 *ptr
++ = ((val
>> 1) & 0x7fe07fe0) | /* Red & Green */
1670 (val
& 0x001f001f); /* Blue */
1672 if (div
!= 0) /* Odd width? */
1673 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1674 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1677 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1678 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800 &&
1679 rDst
== 0x7c00 && bDst
== 0x001f)
1681 for (h
= lines
- 1; h
>= 0; h
--) {
1682 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1683 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1685 *ptr
++ = ((val
<< 10) & 0x7c007c00) | ((val
>> 1) & 0x03e003e0) | /* Red & Green */
1686 ((val
>> 11) & 0x001f001f); /* Blue */
1688 if (div
!= 0) /* Odd width? */
1689 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1690 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1693 else goto notsupported
;
1701 LPWORD ptr
= (LPWORD
)dstbits
;
1704 /* ==== 24/32 BGR bitmap ==== */
1705 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1707 int rsc2
= 16-rsc
, gsc2
= 8-gsc
;
1708 for (h
= lines
- 1; h
>= 0; h
--) {
1709 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1710 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1712 *ptr
= ((val
>> rsc2
) & rDst
) |
1713 ((val
>> gsc2
) & gDst
) |
1714 ((val
>> 3) & bDst
);
1716 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1719 /* ==== 24/32 RGB bitmap ==== */
1720 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1723 for (h
= lines
- 1; h
>= 0; h
--) {
1724 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1725 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1727 *ptr
= ((val
<< rsc
) & rDst
) |
1728 ((val
>> gsc2
) & gDst
) |
1729 ((val
>> 19) & bDst
);
1731 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1734 else goto notsupported
;
1739 /* ==== monochrome bitmap ==== */
1741 /* ==== 4 colormap bitmap ==== */
1742 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1744 LPWORD ptr
= (LPWORD
)dstbits
;
1747 for (h
= lines
- 1; h
>= 0; h
--) {
1748 for (x
= 0; x
< dstwidth
; x
++) {
1749 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
1750 *ptr
++ = ((val
.peRed
<< rsc
) & rDst
) |
1751 ((val
.peGreen
<< gsc
) & gDst
) |
1752 ((val
.peBlue
>> 3) & bDst
);
1754 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1757 else goto notsupported
;
1762 /* ==== 8 colormap bitmap ==== */
1763 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1765 LPWORD ptr
= (LPWORD
)dstbits
;
1769 for (h
= lines
- 1; h
>= 0; h
--) {
1770 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1771 for (x
= 0; x
< dstwidth
; x
++) {
1772 val
= srccolors
[(int)*srcpixel
++];
1773 *ptr
++ = ((val
.peRed
<< rsc
) & rDst
) |
1774 ((val
.peGreen
<< gsc
) & gDst
) |
1775 ((val
.peBlue
>> 3) & bDst
);
1777 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1780 else goto notsupported
;
1788 LPWORD ptr
= (LPWORD
)dstbits
;
1790 FIXME("from %d bit bitmap with mask R,G,B %lx,%lx,%lx to 16 bit DIB %lx,%lx,%lx\n",
1791 bmpImage
->depth
, bmpImage
->red_mask
,
1792 bmpImage
->green_mask
, bmpImage
->blue_mask
,
1795 for (h
= lines
- 1; h
>= 0; h
--)
1797 for (x
= 0; x
< dstwidth
; x
++, ptr
++)
1799 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
1800 r
= (BYTE
) GetRValue(pixel
);
1801 g
= (BYTE
) GetGValue(pixel
);
1802 b
= (BYTE
) GetBValue(pixel
);
1803 *ptr
= ( ((r
<< rsc
) & rDst
) | ((g
<< gsc
) & gDst
) | ((b
>> 3) & bDst
) );
1805 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1813 /***********************************************************************
1814 * X11DRV_DIB_SetImageBits_24
1816 * SetDIBits for a 24-bit deep DIB.
1818 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
1819 DWORD srcwidth
, DWORD dstwidth
, int left
,
1820 DC
*dc
, XImage
*bmpImage
, DWORD linebytes
)
1828 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1829 linebytes
= -linebytes
;
1832 switch ( bmpImage
->depth
)
1836 if (bmpImage
->bits_per_pixel
== 24) {
1837 int dstlinebytes
= linebytes
;
1839 BYTE
*ptr
= (BYTE
*)(srcbits
+left
*3);
1841 if (dstlinebytes
< 0 ) dstlinebytes
= -dstlinebytes
;
1842 dstpixel
= bmpImage
->data
+ lines
*dstlinebytes
+ left
*3;
1843 for(h
= lines
; h
-- ; ) {
1844 dstpixel
-=dstlinebytes
;
1845 memcpy(dstpixel
,ptr
,dstwidth
*3);
1853 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 ) /* packed BGR to unpacked BGR */
1855 DWORD
*dstpixel
, val
, buf
;
1856 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1858 int div
= dstwidth
% 4;
1861 for(h
= lines
- 1; h
>= 0; h
--)
1863 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1865 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1867 *dstpixel
++ = buf
&0x00ffffff; /* b1, g1, r1 */
1868 val
= (buf
>> 24); /* b2 */
1870 *dstpixel
++ = (val
| (buf
<<8)) &0x00ffffff; /* g2, r2 */
1871 val
= (buf
>> 16); /* b3, g3 */
1873 *dstpixel
++ = (val
| (buf
<<16)) &0x00ffffff; /* r3 */
1874 *dstpixel
++ = (buf
>> 8); /* b4, g4, r4 */
1876 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1878 *dstpixel
++ = *(DWORD
*)bits
& 0x00ffffff; /* b, g, r */
1880 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1883 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff ) /* packed BGR to unpacked RGB */
1885 DWORD
*dstpixel
, val
, buf
;
1886 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1888 int div
= dstwidth
% 4;
1891 for(h
= lines
- 1; h
>= 0; h
--)
1893 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1895 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1897 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b1, g1, r1 */
1898 val
= ((buf
&0xff000000)>>8); /* b2 */
1900 *dstpixel
++ = val
| ((buf
&0xff)<<8) | ((buf
&0xff00)>>8); /* g2, r2 */
1901 val
= (buf
&0xff0000) | ((buf
&0xff000000)>>16); /* b3, g3 */
1903 *dstpixel
++ = val
| (buf
&0xff); /* r3 */
1904 *dstpixel
++ = ((buf
&0xff00)<<8) | ((buf
&0xff0000)>>8) | (buf
>>24); /* b4, g4, r4 */
1906 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1908 buf
= *(DWORD
*)bits
;
1909 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b, g, r */
1911 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1921 if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f ) /* BGR888 to RGB555 */
1923 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1926 int div
= dstwidth
% 4;
1929 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1930 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1931 for (x
= 0; x
< dstwidth
/4; x
++, ptr
+= 3) {
1932 *dstpixel
++ = ((ptr
[0] << 7) & 0x7c00) | ((ptr
[0] >> 6) & 0x03e0) | ((ptr
[0] >> 19) & 0x1f);
1933 *dstpixel
++ = ((ptr
[0] >> 17) & 0x7c00) | ((ptr
[1] << 2) & 0x03e0) | ((ptr
[1] >> 11) & 0x1f);
1934 *dstpixel
++ = ((ptr
[1] >> 9) & 0x07c00) | ((ptr
[1] >> 22) & 0x03e0) | ((ptr
[2] >> 3) & 0x1f);
1935 *dstpixel
++ = ((ptr
[2] >> 1) & 0x07c00) | ((ptr
[2] >> 14) & 0x03e0) | ((ptr
[2] >> 27) & 0x1f);
1937 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1938 *dstpixel
++ = (((WORD
)bits
[0] << 7) & 0x07c00) |
1939 (((WORD
)bits
[1] << 2) & 0x03e0) |
1940 (((WORD
)bits
[2] >> 3) & 0x001f);
1941 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1944 else if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 ) /* BGR888 to BGR555 */
1946 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1949 int div
= dstwidth
% 4;
1952 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1953 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1954 for (x
= 0; x
< dstwidth
/4; x
++, ptr
+= 3) {
1955 *dstpixel
++ = ((ptr
[0] >> 3) & 0x1f) | ((ptr
[0] >> 6) & 0x03e0) | ((ptr
[0] >> 9) & 0x7c00);
1956 *dstpixel
++ = ((ptr
[0] >> 27) & 0x1f) | ((ptr
[1] << 2) & 0x03e0) | ((ptr
[1] >> 1) & 0x7c00);
1957 *dstpixel
++ = ((ptr
[1] >> 19) & 0x1f) | ((ptr
[1] >> 22) & 0x03e0) | ((ptr
[2] << 7) & 0x7c00);
1958 *dstpixel
++ = ((ptr
[2] >> 11) & 0x1f) | ((ptr
[2] >> 14) & 0x03e0) | ((ptr
[2] >> 17) & 0x7c00);
1960 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1961 *dstpixel
++ = (((WORD
)bits
[2] << 7) & 0x07c00) |
1962 (((WORD
)bits
[1] << 2) & 0x03e0) |
1963 (((WORD
)bits
[0] >> 3) & 0x001f);
1964 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1974 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1977 int div
= dstwidth
% 4;
1980 if( bmpImage
->blue_mask
== 0x001f && bmpImage
->red_mask
== 0xf800 ) /* BGR888 to BGR565 */
1982 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1983 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1984 for (x
= 0; x
< dstwidth
/4; x
++, ptr
+= 3) {
1985 *dstpixel
++ = ((ptr
[0] >> 3) & 0x1f) | ((ptr
[0] >> 5) & 0x07e0) | ((ptr
[0] >> 8) & 0xf800);
1986 *dstpixel
++ = ((ptr
[0] >> 27) & 0x1f) | ((ptr
[1] << 3) & 0x07e0) | (ptr
[1] & 0xf800);
1987 *dstpixel
++ = ((ptr
[1] >> 19) & 0x1f) | ((ptr
[1] >> 21) & 0x07e0) | ((ptr
[2] << 8) & 0xf800);
1988 *dstpixel
++ = ((ptr
[2] >> 11) & 0x1f) | ((ptr
[2] >> 13) & 0x07e0) | ((ptr
[2] >> 16) & 0xf800);
1990 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1991 *dstpixel
++ = (((WORD
)bits
[2] << 8) & 0xf800) |
1992 (((WORD
)bits
[1] << 3) & 0x07e0) |
1993 (((WORD
)bits
[0] >> 3) & 0x001f);
1994 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1997 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x001f ) /* BGR888 to RGB565 */
1999 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
2000 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
2001 for (x
= 0; x
< dstwidth
/4; x
++, ptr
+= 3) {
2002 *dstpixel
++ = ((ptr
[0] << 8) & 0xf800) | ((ptr
[0] >> 5) & 0x07e0) | ((ptr
[0] >> 19) & 0x1f);
2003 *dstpixel
++ = ((ptr
[0] >> 16) & 0xf800) | ((ptr
[1] << 3) & 0x07e0) | ((ptr
[1] >> 11) & 0x1f);
2004 *dstpixel
++ = ((ptr
[1] >> 8) & 0xf800) | ((ptr
[1] >> 21) & 0x07e0) | ((ptr
[2] >> 3) & 0x1f);
2005 *dstpixel
++ = (ptr
[2] & 0xf800) | ((ptr
[2] >> 13) & 0x07e0) | ((ptr
[2] >> 27) & 0x1f);
2007 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
2008 *dstpixel
++ = (((WORD
)bits
[0] << 8) & 0xf800) |
2009 (((WORD
)bits
[1] << 3) & 0x07e0) |
2010 (((WORD
)bits
[2] >> 3) & 0x001f);
2011 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
2023 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*3;
2025 for (h
= lines
- 1; h
>= 0; h
--) {
2026 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+=3)
2027 XPutPixel( bmpImage
, x
, h
,
2028 X11DRV_PALETTE_ToPhysical(dc
, RGB(bits
[2], bits
[1], bits
[0])));
2029 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 3;
2036 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
2037 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
2038 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2044 /***********************************************************************
2045 * X11DRV_DIB_GetImageBits_24
2047 * GetDIBits for an 24-bit deep DIB.
2049 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
2050 DWORD dstwidth
, DWORD srcwidth
,
2051 PALETTEENTRY
*srccolors
,
2052 XImage
*bmpImage
, DWORD linebytes
)
2060 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2061 linebytes
= -linebytes
;
2064 switch ( bmpImage
->depth
)
2068 if (bmpImage
->bits_per_pixel
== 24) {
2069 int tocopy
= linebytes
;
2071 BYTE
*ptr
= (LPBYTE
)dstbits
;
2073 if (tocopy
< 0 ) tocopy
= -tocopy
;
2074 srcpixel
= bmpImage
->data
+ lines
*tocopy
;
2075 for(h
= lines
; h
-- ; ) {
2077 memcpy(ptr
,srcpixel
,tocopy
);
2078 ptr
= (LPBYTE
)(dstbits
+=linebytes
);
2085 DWORD
*srcpixel
, buf
;
2087 DWORD
*ptr
=(DWORD
*)dstbits
;
2088 int quotient
= dstwidth
/ 4;
2089 int remainder
= dstwidth
% 4;
2092 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
2093 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 )
2095 for(h
= lines
- 1; h
>= 0; h
--)
2097 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2099 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time */
2100 buf
= ((*srcpixel
++)&0x00ffffff); /* b1, g1, r1*/
2101 *ptr
++ = buf
| ((*srcpixel
)<<24); /* b2 */
2102 buf
= ((*srcpixel
++>>8)&0x0000ffff); /* g2, r2 */
2103 *ptr
++ = buf
| ((*srcpixel
)<<16); /* b3, g3 */
2104 buf
= ((*srcpixel
++>>16)&0x000000ff); /* r3 */
2105 *ptr
++ = buf
| ((*srcpixel
++)<<8); /* b4, g4, r4 */
2107 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
2110 *(WORD
*)bits
= buf
; /* b, g */
2111 *(bits
+2) = buf
>>16; /* r */
2113 ptr
= (DWORD
*)(dstbits
+=linebytes
);
2117 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
2118 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff )
2120 for(h
= lines
- 1; h
>= 0; h
--)
2122 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2124 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time */
2126 val
= ((buf
&0xff0000)>>16) | (buf
&0xff00) | ((buf
&0xff)<<16); /* b1, g1, r1 */
2128 *ptr
++ = val
| ((buf
&0xff0000)<<8); /* b2 */
2129 val
= ((buf
&0xff00)>>8) | ((buf
&0xff)<<8); /* g2, r2 */
2131 *ptr
++ = val
| (buf
&0xff0000) | ((buf
&0xff00)<<16); /* b3, g3 */
2132 val
= (buf
&0xff); /* r3 */
2134 *ptr
++ = val
| ((buf
&0xff0000)>>8) | ((buf
&0xff00)<<8) | (buf
<<24); /* b4, g4, r4 */
2136 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
2139 *(WORD
*)bits
= (buf
&0xff00) | ((buf
&0xff0000)>>16) ; /* b, g */
2140 *(bits
+2) = buf
; /* r */
2142 ptr
= (DWORD
*)(dstbits
+=linebytes
);
2145 else goto notsupported
;
2152 LPBYTE bits
= dstbits
;
2155 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2156 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 )
2158 for (h
= lines
- 1; h
>= 0; h
--) {
2159 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2160 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2162 bits
[2] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2163 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2164 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2166 bits
= (dstbits
+= linebytes
);
2169 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2170 else if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f )
2172 for (h
= lines
- 1; h
>= 0; h
--) {
2173 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2174 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2176 bits
[0] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2177 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2178 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2180 bits
= (dstbits
+= linebytes
);
2183 else goto notsupported
;
2190 LPBYTE bits
= dstbits
;
2193 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2194 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0xf800 )
2196 for (h
= lines
- 1; h
>= 0; h
--) {
2197 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2198 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2200 bits
[2] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2201 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2202 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2204 bits
= (dstbits
+= linebytes
);
2207 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2208 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x1f )
2210 for (h
= lines
- 1; h
>= 0; h
--) {
2211 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2212 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2214 bits
[0] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2215 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2216 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2218 bits
= (dstbits
+= linebytes
);
2221 else goto notsupported
;
2226 /* ==== monochrome bitmap to 24 BGR dib ==== */
2228 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2229 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2231 LPBYTE bits
= dstbits
;
2234 for (h
= lines
- 1; h
>= 0; h
--) {
2235 for (x
= 0; x
< dstwidth
; x
++) {
2236 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2237 *bits
++ = val
.peBlue
;
2238 *bits
++ = val
.peGreen
;
2239 *bits
++ = val
.peRed
;
2241 bits
= (dstbits
+= linebytes
);
2244 else goto notsupported
;
2249 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2250 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
)
2253 LPBYTE bits
= dstbits
;
2256 for (h
= lines
- 1; h
>= 0; h
--) {
2257 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2258 for (x
= 0; x
< dstwidth
; x
++ ) {
2259 val
= srccolors
[(int)*srcpixel
++];
2260 *bits
++ = val
.peBlue
; /*Blue*/
2261 *bits
++ = val
.peGreen
; /*Green*/
2262 *bits
++ = val
.peRed
; /*Red*/
2264 bits
= (dstbits
+= linebytes
);
2267 else goto notsupported
;
2274 LPBYTE bits
= dstbits
;
2276 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2277 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2278 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2279 for (h
= lines
- 1; h
>= 0; h
--)
2281 for (x
= 0; x
< dstwidth
; x
++, bits
+= 3)
2283 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2284 bits
[0] = GetBValue(pixel
);
2285 bits
[1] = GetGValue(pixel
);
2286 bits
[2] = GetRValue(pixel
);
2288 bits
= (dstbits
+= linebytes
);
2296 /***********************************************************************
2297 * X11DRV_DIB_SetImageBits_32
2299 * SetDIBits for a 32-bit deep DIB.
2301 static void X11DRV_DIB_SetImageBits_32( int lines
, const BYTE
*srcbits
,
2302 DWORD srcwidth
, DWORD dstwidth
, int left
,
2303 DC
*dc
, XImage
*bmpImage
,
2312 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2313 linebytes
= -linebytes
;
2316 ptr
= (DWORD
*) srcbits
+ left
;
2318 switch ( bmpImage
->depth
)
2321 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2322 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff) {
2323 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+=linebytes
) {
2324 memcpy( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
, srcbits
+ left
*4, dstwidth
*4 );
2328 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2329 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
2333 for (h
= lines
- 1; h
>= 0; h
--) {
2334 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2335 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2336 *dstpixel
++ = ((*ptr
<< 16) & 0xff0000) | (*ptr
& 0xff00) | ((*ptr
>> 16) & 0xff);
2338 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2341 else goto notsupported
;
2346 /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
2347 /* we need to check that source mask matches destination */
2348 if (bmpImage
->bits_per_pixel
== 32)
2350 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+=linebytes
) {
2351 memcpy( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
, srcbits
+ left
*4, dstwidth
*4 );
2358 ptr
= (DWORD
*) srcbits
+ left
;
2359 bptr
= bmpImage
->data
;
2361 for (h
= lines
- 1; h
>= 0; h
--) {
2362 for (x
= 0; x
< dstwidth
; x
++) {
2363 /* *ptr is a 32bit value */
2364 /* bptr points to first of 3 bytes */
2365 *bptr
++ = (*ptr
>> 16) & 0xff;
2366 *bptr
++ = (*ptr
>> 8) & 0xff;
2367 *bptr
++ = (*ptr
) & 0xff;
2370 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2376 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2377 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f) {
2380 for (h
= lines
- 1; h
>= 0; h
--) {
2381 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2382 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2383 *dstpixel
++ = (WORD
) (((*ptr
>> 9) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 3) & 0x001f));
2385 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2388 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2389 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2393 for (h
= lines
- 1; h
>= 0; h
--) {
2394 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2395 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2396 *dstpixel
++ = (WORD
) (((*ptr
<< 7) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 19) & 0x001f));
2398 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2401 else goto notsupported
;
2406 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2407 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2411 for (h
= lines
- 1; h
>= 0; h
--) {
2412 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2413 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2414 *dstpixel
++ = (WORD
) (((*ptr
>> 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 3) & 0x001f));
2416 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2419 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2420 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
2424 for (h
= lines
- 1; h
>= 0; h
--) {
2425 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2426 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2427 *dstpixel
++ = (WORD
) (((*ptr
<< 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 19) & 0x001f));
2429 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2432 else goto notsupported
;
2440 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*4;
2442 for (h
= lines
- 1; h
>= 0; h
--) {
2443 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+= 4)
2444 XPutPixel( bmpImage
, x
, h
,
2445 X11DRV_PALETTE_ToPhysical(dc
, RGB( bits
[2], bits
[1], *bits
)));
2446 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 4;
2453 FIXME("32 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
2459 /***********************************************************************
2460 * X11DRV_DIB_GetImageBits_32
2462 * GetDIBits for an 32-bit deep DIB.
2464 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
2465 DWORD dstwidth
, DWORD srcwidth
,
2466 PALETTEENTRY
*srccolors
,
2467 XImage
*bmpImage
, DWORD linebytes
)
2473 DWORD copybytes
= srcwidth
* 4;
2478 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2479 linebytes
= -linebytes
;
2484 switch ( bmpImage
->depth
)
2487 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2488 if ( bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff )
2489 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+=linebytes
)
2490 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, copybytes
);
2492 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2493 else if ( bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000 )
2497 for (h
= lines
- 1; h
>= 0; h
--) {
2498 srcbits
= bmpImage
->data
+ h
* bmpImage
->bytes_per_line
;
2499 for (x
= 0; x
< dstwidth
; x
++, bits
+=4, srcbits
+=2) {
2500 *(bits
+ 2) = *srcbits
++;
2501 *(bits
+ 1) = *srcbits
++;
2504 bits
= (dstbits
+= linebytes
);
2507 else goto notsupported
;
2511 /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */
2512 /* we need to check that source mask matches destination */
2518 srcpixel
= (DWORD
*) dstbits
;
2519 bptr
= bmpImage
->data
;
2521 for (h
= lines
- 1; h
>= 0; h
--) {
2522 for (x
= 0; x
< dstwidth
; x
++) {
2523 /* *srcpixel is a 32bit value */
2524 /* bptr points to first of 3 bytes */
2526 srcdata
= srcdata
<< 8 | *bptr
++;
2527 srcdata
= srcdata
<< 8 | *bptr
++;
2528 srcdata
= srcdata
<< 8 | *bptr
++;
2530 *srcpixel
++ = srcdata
;
2532 srcpixel
= (DWORD
*) (dstbits
+= linebytes
);
2542 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2543 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
2545 for (h
= lines
- 1; h
>= 0; h
--) {
2546 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2547 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2549 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2550 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2551 *bits
= (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2553 bits
= (dstbits
+= linebytes
);
2556 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2557 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2559 for (h
= lines
- 1; h
>= 0; h
--) {
2560 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2561 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2563 *bits
++ = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07));/*Blue*/
2564 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2565 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2567 bits
= (dstbits
+= linebytes
);
2570 else goto notsupported
;
2579 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2580 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2582 for (h
= lines
- 1; h
>= 0; h
--) {
2583 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2584 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2586 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2587 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2588 *bits
= (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2590 bits
= (dstbits
+= linebytes
);
2593 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2594 else if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2596 for (h
= lines
- 1; h
>= 0; h
--) {
2597 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2598 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2600 *bits
++ = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07));/*Blue*/
2601 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2602 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2604 bits
= (dstbits
+= linebytes
);
2607 else goto notsupported
;
2612 /* ==== monochrome bitmap to 32 BGR dib ==== */
2614 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2615 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2619 for (h
= lines
- 1; h
>= 0; h
--) {
2620 for (x
= 0; x
< dstwidth
; x
++) {
2621 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2622 *bits
++ = val
.peBlue
;
2623 *bits
++ = val
.peGreen
;
2624 *bits
++ = val
.peRed
;
2627 bits
= (dstbits
+= linebytes
);
2630 else goto notsupported
;
2635 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2636 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2641 for (h
= lines
- 1; h
>= 0; h
--) {
2642 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2643 for (x
= 0; x
< dstwidth
; x
++) {
2644 val
= srccolors
[(int)*srcpixel
++];
2645 *bits
++ = val
.peBlue
; /*Blue*/
2646 *bits
++ = val
.peGreen
; /*Green*/
2647 *bits
++ = val
.peRed
; /*Red*/
2650 bits
= (dstbits
+= linebytes
);
2653 else goto notsupported
;
2658 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2659 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2660 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2661 for (h
= lines
- 1; h
>= 0; h
--)
2663 for (x
= 0; x
< dstwidth
; x
++, bits
+= 4)
2665 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2666 bits
[0] = GetBValue(pixel
);
2667 bits
[1] = GetGValue(pixel
);
2668 bits
[2] = GetRValue(pixel
);
2670 bits
= (dstbits
+= linebytes
);
2676 /***********************************************************************
2677 * X11DRV_DIB_SetImageBits
2679 * Transfer the bits to an X image.
2680 * Helper function for SetDIBits() and SetDIBitsToDevice().
2682 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2684 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2689 bmpImage
= descr
->image
;
2691 bmpImage
= XCreateImage( display
, X11DRV_GetVisual(), descr
->depth
, ZPixmap
, 0, NULL
,
2692 descr
->infoWidth
, lines
, 32, 0 );
2693 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2694 if(bmpImage
->data
== NULL
) {
2695 ERR("Out of memory!\n");
2696 XDestroyImage( bmpImage
);
2697 wine_tsx11_unlock();
2702 /* Transfer the pixels */
2703 switch(descr
->infoBpp
)
2706 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
2707 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
2708 bmpImage
, descr
->dibpitch
);
2711 if (descr
->compression
) {
2712 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2713 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2714 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2716 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
2717 descr
->infoWidth
, descr
->width
,
2718 descr
->xSrc
, (int *)(descr
->colorMap
),
2721 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
2722 descr
->infoWidth
, descr
->width
,
2723 descr
->xSrc
, (int*)(descr
->colorMap
),
2724 bmpImage
, descr
->dibpitch
);
2727 if (descr
->compression
) {
2728 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2729 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2730 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2731 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
2732 descr
->infoWidth
, descr
->width
,
2733 descr
->xSrc
, (int *)(descr
->colorMap
),
2736 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
2737 descr
->infoWidth
, descr
->width
,
2738 descr
->xSrc
, (int *)(descr
->colorMap
),
2739 bmpImage
, descr
->dibpitch
);
2743 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
2744 descr
->infoWidth
, descr
->width
,
2745 descr
->xSrc
, descr
->dc
,
2746 descr
->rMask
, descr
->gMask
, descr
->bMask
,
2747 bmpImage
, descr
->dibpitch
);
2750 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
2751 descr
->infoWidth
, descr
->width
,
2752 descr
->xSrc
, descr
->dc
, bmpImage
,
2756 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
2757 descr
->infoWidth
, descr
->width
,
2758 descr
->xSrc
, descr
->dc
,
2759 bmpImage
, descr
->dibpitch
);
2762 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2766 TRACE("XPutImage(%p,%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
2767 display
, descr
->drawable
, descr
->gc
, bmpImage
,
2768 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2769 descr
->width
, descr
->height
);
2772 XShmPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2773 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2774 descr
->width
, descr
->height
, FALSE
);
2775 XSync( display
, 0 );
2778 XPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2779 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2780 descr
->width
, descr
->height
);
2782 if (!descr
->image
) XDestroyImage( bmpImage
);
2783 wine_tsx11_unlock();
2787 /***********************************************************************
2788 * X11DRV_DIB_GetImageBits
2790 * Transfer the bits from an X image.
2792 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2794 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2799 bmpImage
= descr
->image
;
2801 bmpImage
= XCreateImage( display
, X11DRV_GetVisual(), descr
->depth
, ZPixmap
, 0, NULL
,
2802 descr
->infoWidth
, lines
, 32, 0 );
2803 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2804 if(bmpImage
->data
== NULL
) {
2805 ERR("Out of memory!\n");
2806 XDestroyImage( bmpImage
);
2807 wine_tsx11_unlock();
2812 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
2813 display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
, descr
->width
,
2814 lines
, AllPlanes
, ZPixmap
, bmpImage
, descr
->xDest
, descr
->yDest
);
2815 XGetSubImage( display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
2816 descr
->width
, lines
, AllPlanes
, ZPixmap
,
2817 bmpImage
, descr
->xDest
, descr
->yDest
);
2819 /* Transfer the pixels */
2820 switch(descr
->infoBpp
)
2823 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
2824 descr
->infoWidth
, descr
->width
,
2825 descr
->colorMap
, descr
->palentry
,
2826 bmpImage
, descr
->dibpitch
);
2830 if (descr
->compression
)
2831 FIXME("Compression not yet supported!\n");
2833 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
2834 descr
->infoWidth
, descr
->width
,
2835 descr
->colorMap
, descr
->palentry
,
2836 bmpImage
, descr
->dibpitch
);
2840 if (descr
->compression
)
2841 FIXME("Compression not yet supported!\n");
2843 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
2844 descr
->infoWidth
, descr
->width
,
2845 descr
->colorMap
, descr
->palentry
,
2846 bmpImage
, descr
->dibpitch
);
2850 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
2851 descr
->infoWidth
,descr
->width
,
2853 descr
->rMask
, descr
->gMask
, descr
->bMask
,
2854 bmpImage
, descr
->dibpitch
);
2858 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
2859 descr
->infoWidth
,descr
->width
,
2860 descr
->palentry
, bmpImage
, descr
->dibpitch
);
2864 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
2865 descr
->infoWidth
, descr
->width
,
2866 descr
->palentry
, bmpImage
, descr
->dibpitch
);
2870 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2874 if (!descr
->image
) XDestroyImage( bmpImage
);
2875 wine_tsx11_unlock();
2879 /*************************************************************************
2880 * X11DRV_SetDIBitsToDevice
2883 INT
X11DRV_SetDIBitsToDevice( DC
*dc
, INT xDest
, INT yDest
, DWORD cx
,
2884 DWORD cy
, INT xSrc
, INT ySrc
,
2885 UINT startscan
, UINT lines
, LPCVOID bits
,
2886 const BITMAPINFO
*info
, UINT coloruse
)
2888 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2889 DWORD width
, oldcy
= cy
;
2891 int height
, tmpheight
;
2892 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
2895 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
2896 &descr
.infoBpp
, &descr
.compression
) == -1)
2899 if (height
< 0) height
= -height
;
2900 if (!lines
|| (startscan
>= height
)) return 0;
2901 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2902 if (ySrc
< startscan
) ySrc
= startscan
;
2903 else if (ySrc
>= startscan
+ lines
) return 0;
2904 if (xSrc
>= width
) return 0;
2905 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
2906 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
2907 if (!cx
|| !cy
) return 0;
2909 X11DRV_SetupGCForText( dc
); /* To have the correct colors */
2910 TSXSetFunction(display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->ROPmode
-1]);
2912 switch (descr
.infoBpp
)
2917 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2918 coloruse
== DIB_PAL_COLORS
? dc
: NULL
, coloruse
,
2919 dc
->bitsPerPixel
, 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 descr
.palentry
= NULL
;
2948 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2949 descr
.infoWidth
= width
;
2950 descr
.depth
= dc
->bitsPerPixel
;
2951 descr
.drawable
= physDev
->drawable
;
2952 descr
.gc
= physDev
->gc
;
2954 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
2956 descr
.xDest
= dc
->DCOrgX
+ XLPTODP( dc
, xDest
);
2957 descr
.yDest
= dc
->DCOrgY
+ YLPTODP( dc
, yDest
) +
2958 (tmpheight
>= 0 ? oldcy
-cy
: 0);
2961 descr
.useShm
= FALSE
;
2962 descr
.dibpitch
= ((width
* descr
.infoBpp
+ 31) &~31) / 8;
2964 result
= X11DRV_DIB_SetImageBits( &descr
);
2966 if (descr
.infoBpp
<= 8)
2967 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2971 /***********************************************************************
2972 * X11DRV_DIB_SetDIBits
2974 INT
X11DRV_DIB_SetDIBits(
2975 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2976 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
,
2977 UINT coloruse
, HBITMAP hbitmap
)
2979 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2980 int height
, tmpheight
;
2985 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
2986 &descr
.infoBpp
, &descr
.compression
) == -1)
2990 if (height
< 0) height
= -height
;
2991 if (!lines
|| (startscan
>= height
))
2994 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2996 switch (descr
.infoBpp
)
3001 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
3002 coloruse
== DIB_PAL_COLORS
? descr
.dc
: NULL
, coloruse
,
3003 bmp
->bitmap
.bmBitsPixel
,
3004 info
, &descr
.nColorMap
);
3005 if (!descr
.colorMap
) return 0;
3006 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3010 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3011 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3012 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3017 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3022 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3023 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
3024 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
3032 if(!bmp
->physBitmap
)
3033 X11DRV_CreateBitmap(hbitmap
);
3037 descr
.palentry
= NULL
;
3038 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
3039 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3040 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3041 descr
.gc
= BITMAP_GC(bmp
);
3045 descr
.yDest
= height
- startscan
- lines
;
3046 descr
.width
= bmp
->bitmap
.bmWidth
;
3047 descr
.height
= lines
;
3048 descr
.useShm
= FALSE
;
3049 descr
.dibpitch
= ((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8;
3050 result
= X11DRV_DIB_SetImageBits( &descr
);
3052 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
3057 /***********************************************************************
3058 * X11DRV_DIB_GetDIBits
3060 INT
X11DRV_DIB_GetDIBits(
3061 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
3062 UINT lines
, LPVOID bits
, BITMAPINFO
*info
,
3063 UINT coloruse
, HBITMAP hbitmap
)
3065 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3066 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3067 PALETTEOBJ
* palette
;
3070 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3071 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
3072 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
3075 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->hPalette
, PALETTE_MAGIC
)))
3078 if( lines
> bmp
->bitmap
.bmHeight
) lines
= bmp
->bitmap
.bmHeight
;
3080 height
= info
->bmiHeader
.biHeight
;
3081 if (height
< 0) height
= -height
;
3082 if( lines
> height
) lines
= height
;
3083 /* Top-down images have a negative biHeight, the scanlines of theses images
3084 * were inverted in X11DRV_DIB_GetImageBits_xx
3085 * To prevent this we simply change the sign of lines
3086 * (the number of scan lines to copy).
3087 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3089 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
3091 if( startscan
>= bmp
->bitmap
.bmHeight
)
3097 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
3098 &descr
.infoBpp
, &descr
.compression
) == -1)
3104 switch (descr
.infoBpp
)
3110 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3114 descr
.rMask
= 0x7c00;
3115 descr
.gMask
= 0x03e0;
3116 descr
.bMask
= 0x001f;
3120 descr
.rMask
= 0xff0000;
3121 descr
.gMask
= 0xff00;
3127 if(!bmp
->physBitmap
)
3128 X11DRV_CreateBitmap(hbitmap
);
3132 descr
.palentry
= palette
->logpalette
.palPalEntry
;
3135 descr
.lines
= lines
;
3136 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3137 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3138 descr
.gc
= BITMAP_GC(bmp
);
3139 descr
.width
= bmp
->bitmap
.bmWidth
;
3140 descr
.height
= bmp
->bitmap
.bmHeight
;
3141 descr
.colorMap
= info
->bmiColors
;
3146 if (descr
.lines
> 0)
3148 descr
.ySrc
= (descr
.height
-1) - (startscan
+ (lines
-1));
3152 descr
.ySrc
= startscan
;
3154 #ifdef HAVE_LIBXXSHM
3155 descr
.useShm
= dib
? (dib
->shminfo
.shmid
!= -1) : FALSE
;
3157 descr
.useShm
= FALSE
;
3159 descr
.dibpitch
= dib
? (dib
->dibSection
.dsBm
.bmWidthBytes
)
3160 : (((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8);
3162 X11DRV_DIB_GetImageBits( &descr
);
3164 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
3165 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
3166 info
->bmiHeader
.biWidth
,
3167 info
->bmiHeader
.biHeight
,
3168 info
->bmiHeader
.biBitCount
);
3170 info
->bmiHeader
.biCompression
= 0;
3171 if (descr
.compression
== BI_BITFIELDS
)
3173 *(DWORD
*)info
->bmiColors
= descr
.rMask
;
3174 *((DWORD
*)info
->bmiColors
+1) = descr
.gMask
;
3175 *((DWORD
*)info
->bmiColors
+2) = descr
.bMask
;
3179 GDI_ReleaseObj( dc
->hPalette
);
3184 /***********************************************************************
3185 * DIB_DoProtectDIBSection
3187 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
3189 DIBSECTION
*dib
= bmp
->dib
;
3190 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
3191 : -dib
->dsBm
.bmHeight
;
3192 /* use the biSizeImage data as the memory size only if we're dealing with a
3193 compressed image where the value is set. Otherwise, calculate based on
3195 INT totalSize
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
3196 ? dib
->dsBmih
.biSizeImage
3197 : dib
->dsBm
.bmWidthBytes
* effHeight
;
3200 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
3201 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
3204 /***********************************************************************
3205 * X11DRV_DIB_DoUpdateDIBSection
3207 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
,
3208 void *colorMap
, int nColorMap
,
3210 DWORD xSrc
, DWORD ySrc
,
3211 DWORD xDest
, DWORD yDest
,
3212 DWORD width
, DWORD height
)
3214 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3215 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3217 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
3218 &descr
.infoBpp
, &descr
.compression
) == -1)
3222 descr
.palentry
= NULL
;
3223 descr
.image
= dib
->image
;
3224 descr
.colorMap
= colorMap
;
3225 descr
.nColorMap
= nColorMap
;
3226 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
3227 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3229 switch (descr
.infoBpp
)
3235 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3239 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
3240 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
3241 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
3245 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff;
3246 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0xff00;
3247 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0xff0000;
3252 descr
.drawable
= dest
;
3253 descr
.gc
= BITMAP_GC(bmp
);
3256 descr
.xDest
= xDest
;
3257 descr
.yDest
= yDest
;
3258 descr
.width
= width
;
3259 descr
.height
= height
;
3260 #ifdef HAVE_LIBXXSHM
3261 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
3263 descr
.useShm
= FALSE
;
3265 descr
.dibpitch
= dib
->dibSection
.dsBm
.bmWidthBytes
;
3269 TRACE("Copying from Pixmap to DIB bits\n");
3270 X11DRV_DIB_GetImageBits( &descr
);
3274 TRACE("Copying from DIB bits to Pixmap\n");
3275 X11DRV_DIB_SetImageBits( &descr
);
3279 /***********************************************************************
3280 * X11DRV_DIB_CopyDIBSection
3282 void X11DRV_DIB_CopyDIBSection(DC
*dcSrc
, DC
*dcDst
,
3283 DWORD xSrc
, DWORD ySrc
,
3284 DWORD xDest
, DWORD yDest
,
3285 DWORD width
, DWORD height
)
3288 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dcDst
->physDev
;
3289 int nColorMap
= 0, *colorMap
= NULL
, aColorMap
= FALSE
;
3291 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc
, dcDst
,
3292 xSrc
, ySrc
, xDest
, yDest
, width
, height
);
3293 /* this function is meant as an optimization for BitBlt,
3294 * not to be called otherwise */
3295 if (!(dcSrc
->flags
& DC_MEMORY
)) {
3296 ERR("called for non-memory source DC!?\n");
3300 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( dcSrc
->hBitmap
, BITMAP_MAGIC
);
3301 if (!(bmp
&& bmp
->dib
)) {
3302 ERR("called for non-DIBSection!?\n");
3303 GDI_ReleaseObj( dcSrc
->hBitmap
);
3306 /* while BitBlt should already have made sure we only get
3307 * positive values, we should check for oversize values */
3308 if ((xSrc
< bmp
->bitmap
.bmWidth
) &&
3309 (ySrc
< bmp
->bitmap
.bmHeight
)) {
3310 if (xSrc
+ width
> bmp
->bitmap
.bmWidth
)
3311 width
= bmp
->bitmap
.bmWidth
- xSrc
;
3312 if (ySrc
+ height
> bmp
->bitmap
.bmHeight
)
3313 height
= bmp
->bitmap
.bmHeight
- ySrc
;
3314 /* if the source bitmap is 8bpp or less, we're supposed to use the
3315 * DC's palette for color conversion (not the DIB color table) */
3316 if (bmp
->dib
->dsBm
.bmBitsPixel
<= 8) {
3317 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3318 if ((!dcSrc
->hPalette
) ||
3319 (dcSrc
->hPalette
== GetStockObject(DEFAULT_PALETTE
))) {
3320 /* HACK: no palette has been set in the source DC,
3321 * use the DIB colormap instead - this is necessary in some
3322 * cases since we need to do depth conversion in some places
3323 * where real Windows can just copy data straight over */
3324 colorMap
= dib
->colorMap
;
3325 nColorMap
= dib
->nColorMap
;
3327 colorMap
= X11DRV_DIB_BuildColorMap( dcSrc
, (WORD
)-1,
3328 bmp
->dib
->dsBm
.bmBitsPixel
,
3329 (BITMAPINFO
*)&(bmp
->dib
->dsBmih
),
3331 if (colorMap
) aColorMap
= TRUE
;
3334 /* perform the copy */
3335 X11DRV_DIB_DoCopyDIBSection(bmp
, FALSE
, colorMap
, nColorMap
,
3336 physDev
->drawable
, xSrc
, ySrc
, xDest
, yDest
,
3338 /* free color mapping */
3340 HeapFree(GetProcessHeap(), 0, colorMap
);
3342 GDI_ReleaseObj( dcSrc
->hBitmap
);
3345 /***********************************************************************
3346 * X11DRV_DIB_DoUpdateDIBSection
3348 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
3350 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3351 X11DRV_DIB_DoCopyDIBSection(bmp
, toDIB
, dib
->colorMap
, dib
->nColorMap
,
3352 (Drawable
)bmp
->physBitmap
, 0, 0, 0, 0,
3353 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
3356 /***********************************************************************
3357 * X11DRV_DIB_FaultHandler
3359 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
3364 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
3365 if (!bmp
) return FALSE
;
3367 state
= X11DRV_DIB_Lock(bmp
, DIB_Status_None
, FALSE
);
3368 if (state
!= DIB_Status_InSync
) {
3369 /* no way to tell whether app needs read or write yet,
3371 X11DRV_DIB_Coerce(bmp
, DIB_Status_InSync
, FALSE
);
3373 /* hm, apparently the app must have write access */
3374 X11DRV_DIB_Coerce(bmp
, DIB_Status_AppMod
, FALSE
);
3376 X11DRV_DIB_Unlock(bmp
, TRUE
);
3378 GDI_ReleaseObj( (HBITMAP
)res
);
3382 /***********************************************************************
3385 INT
X11DRV_DIB_Coerce(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
3387 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3388 INT ret
= DIB_Status_None
;
3391 EnterCriticalSection(&(dib
->lock
));
3394 case DIB_Status_GdiMod
:
3395 /* GDI access - request to draw on pixmap */
3396 switch (dib
->status
)
3399 case DIB_Status_None
:
3400 dib
->p_status
= DIB_Status_GdiMod
;
3401 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3404 case DIB_Status_GdiMod
:
3405 TRACE("GdiMod requested in status GdiMod\n" );
3408 case DIB_Status_InSync
:
3409 TRACE("GdiMod requested in status InSync\n" );
3410 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3411 dib
->status
= DIB_Status_GdiMod
;
3412 dib
->p_status
= DIB_Status_InSync
;
3415 case DIB_Status_AuxMod
:
3416 TRACE("GdiMod requested in status AuxMod\n" );
3417 if (lossy
) dib
->status
= DIB_Status_GdiMod
;
3418 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_GdiMod
);
3419 dib
->p_status
= DIB_Status_AuxMod
;
3420 if (dib
->status
!= DIB_Status_AppMod
) {
3421 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3424 /* fall through if copy_aux() had to change to AppMod state */
3426 case DIB_Status_AppMod
:
3427 TRACE("GdiMod requested in status AppMod\n" );
3429 /* make it readonly to avoid app changing data while we copy */
3430 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3431 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3433 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3434 dib
->p_status
= DIB_Status_AppMod
;
3435 dib
->status
= DIB_Status_GdiMod
;
3440 case DIB_Status_InSync
:
3441 /* App access - request access to read DIB surface */
3442 /* (typically called from signal handler) */
3443 switch (dib
->status
)
3446 case DIB_Status_None
:
3447 /* shouldn't happen from signal handler */
3450 case DIB_Status_AuxMod
:
3451 TRACE("InSync requested in status AuxMod\n" );
3452 if (lossy
) dib
->status
= DIB_Status_InSync
;
3454 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3455 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_InSync
);
3457 if (dib
->status
!= DIB_Status_GdiMod
) {
3458 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3461 /* fall through if copy_aux() had to change to GdiMod state */
3463 case DIB_Status_GdiMod
:
3464 TRACE("InSync requested in status GdiMod\n" );
3466 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3467 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3469 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3470 dib
->status
= DIB_Status_InSync
;
3473 case DIB_Status_InSync
:
3474 TRACE("InSync requested in status InSync\n" );
3475 /* shouldn't happen from signal handler */
3478 case DIB_Status_AppMod
:
3479 TRACE("InSync requested in status AppMod\n" );
3480 /* no reason to do anything here, and this
3481 * shouldn't happen from signal handler */
3486 case DIB_Status_AppMod
:
3487 /* App access - request access to write DIB surface */
3488 /* (typically called from signal handler) */
3489 switch (dib
->status
)
3492 case DIB_Status_None
:
3493 /* shouldn't happen from signal handler */
3496 case DIB_Status_AuxMod
:
3497 TRACE("AppMod requested in status AuxMod\n" );
3498 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3499 if (lossy
) dib
->status
= DIB_Status_AppMod
;
3500 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
3501 if (dib
->status
!= DIB_Status_GdiMod
)
3503 /* fall through if copy_aux() had to change to GdiMod state */
3505 case DIB_Status_GdiMod
:
3506 TRACE("AppMod requested in status GdiMod\n" );
3507 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3508 if (!lossy
) X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3509 dib
->status
= DIB_Status_AppMod
;
3512 case DIB_Status_InSync
:
3513 TRACE("AppMod requested in status InSync\n" );
3514 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3515 dib
->status
= DIB_Status_AppMod
;
3518 case DIB_Status_AppMod
:
3519 TRACE("AppMod requested in status AppMod\n" );
3520 /* shouldn't happen from signal handler */
3525 case DIB_Status_AuxMod
:
3526 if (dib
->status
== DIB_Status_None
) {
3527 dib
->p_status
= req
;
3529 if (dib
->status
!= DIB_Status_AuxMod
)
3530 dib
->p_status
= dib
->status
;
3531 dib
->status
= DIB_Status_AuxMod
;
3534 /* it is up to the caller to do the copy/conversion, probably
3535 * using the return value to decide where to copy from */
3537 LeaveCriticalSection(&(dib
->lock
));
3542 /***********************************************************************
3545 INT
X11DRV_DIB_Lock(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
3547 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3548 INT ret
= DIB_Status_None
;
3551 TRACE("Locking %p from thread %08lx\n", bmp
, GetCurrentThreadId());
3552 EnterCriticalSection(&(dib
->lock
));
3554 if (req
!= DIB_Status_None
)
3555 X11DRV_DIB_Coerce(bmp
, req
, lossy
);
3560 /***********************************************************************
3563 void X11DRV_DIB_Unlock(BITMAPOBJ
*bmp
, BOOL commit
)
3565 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3568 switch (dib
->status
)
3571 case DIB_Status_None
:
3572 /* in case anyone is wondering, this is the "signal handler doesn't
3573 * work" case, where we always have to be ready for app access */
3575 switch (dib
->p_status
)
3577 case DIB_Status_AuxMod
:
3578 TRACE("Unlocking and syncing from AuxMod\n" );
3579 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
3580 if (dib
->status
!= DIB_Status_None
) {
3581 dib
->p_status
= dib
->status
;
3582 dib
->status
= DIB_Status_None
;
3584 if (dib
->p_status
!= DIB_Status_GdiMod
)
3586 /* fall through if copy_aux() had to change to GdiMod state */
3588 case DIB_Status_GdiMod
:
3589 TRACE("Unlocking and syncing from GdiMod\n" );
3590 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3594 TRACE("Unlocking without needing to sync\n" );
3598 else TRACE("Unlocking with no changes\n");
3599 dib
->p_status
= DIB_Status_None
;
3602 case DIB_Status_GdiMod
:
3603 TRACE("Unlocking in status GdiMod\n" );
3604 /* DIB was protected in Coerce */
3606 /* no commit, revert to InSync if applicable */
3607 if ((dib
->p_status
== DIB_Status_InSync
) ||
3608 (dib
->p_status
== DIB_Status_AppMod
)) {
3609 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3610 dib
->status
= DIB_Status_InSync
;
3615 case DIB_Status_InSync
:
3616 TRACE("Unlocking in status InSync\n" );
3617 /* DIB was already protected in Coerce */
3620 case DIB_Status_AppMod
:
3621 TRACE("Unlocking in status AppMod\n" );
3622 /* DIB was already protected in Coerce */
3623 /* this case is ordinary only called from the signal handler,
3624 * so we don't bother to check for !commit */
3627 case DIB_Status_AuxMod
:
3628 TRACE("Unlocking in status AuxMod\n" );
3630 /* DIB may need protection now */
3631 if ((dib
->p_status
== DIB_Status_InSync
) ||
3632 (dib
->p_status
== DIB_Status_AppMod
))
3633 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3635 /* no commit, revert to previous state */
3636 if (dib
->p_status
!= DIB_Status_None
)
3637 dib
->status
= dib
->p_status
;
3638 /* no protections changed */
3640 dib
->p_status
= DIB_Status_None
;
3643 LeaveCriticalSection(&(dib
->lock
));
3644 TRACE("Unlocked %p\n", bmp
);
3648 /***********************************************************************
3649 * X11DRV_CoerceDIBSection2
3651 INT
X11DRV_CoerceDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
3656 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3657 if (!bmp
) return DIB_Status_None
;
3658 ret
= X11DRV_DIB_Coerce(bmp
, req
, lossy
);
3659 GDI_ReleaseObj( hBmp
);
3663 /***********************************************************************
3664 * X11DRV_LockDIBSection2
3666 INT
X11DRV_LockDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
3671 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3672 if (!bmp
) return DIB_Status_None
;
3673 ret
= X11DRV_DIB_Lock(bmp
, req
, lossy
);
3674 GDI_ReleaseObj( hBmp
);
3678 /***********************************************************************
3679 * X11DRV_UnlockDIBSection2
3681 void X11DRV_UnlockDIBSection2(HBITMAP hBmp
, BOOL commit
)
3685 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3687 X11DRV_DIB_Unlock(bmp
, commit
);
3688 GDI_ReleaseObj( hBmp
);
3691 /***********************************************************************
3692 * X11DRV_CoerceDIBSection
3694 INT
X11DRV_CoerceDIBSection(DC
*dc
, INT req
, BOOL lossy
)
3696 if (!dc
) return DIB_Status_None
;
3697 return X11DRV_CoerceDIBSection2( dc
->hBitmap
, req
, lossy
);
3700 /***********************************************************************
3701 * X11DRV_LockDIBSection
3703 INT
X11DRV_LockDIBSection(DC
*dc
, INT req
, BOOL lossy
)
3705 if (!dc
) return DIB_Status_None
;
3706 if (!(dc
->flags
& DC_MEMORY
)) return DIB_Status_None
;
3708 return X11DRV_LockDIBSection2( dc
->hBitmap
, req
, lossy
);
3711 /***********************************************************************
3712 * X11DRV_UnlockDIBSection
3714 void X11DRV_UnlockDIBSection(DC
*dc
, BOOL commit
)
3717 if (!(dc
->flags
& DC_MEMORY
)) return;
3719 X11DRV_UnlockDIBSection2( dc
->hBitmap
, commit
);
3722 /***********************************************************************
3723 * X11DRV_DIB_CreateDIBSection16
3725 HBITMAP16
X11DRV_DIB_CreateDIBSection16(
3726 DC
*dc
, BITMAPINFO
*bmi
, UINT16 usage
,
3727 SEGPTR
*bits
, HANDLE section
,
3728 DWORD offset
, DWORD ovr_pitch
)
3730 HBITMAP res
= X11DRV_DIB_CreateDIBSection(dc
, bmi
, usage
, NULL
,
3731 section
, offset
, ovr_pitch
);
3734 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3735 if ( bmp
&& bmp
->dib
)
3737 DIBSECTION
*dib
= bmp
->dib
;
3738 INT height
= dib
->dsBm
.bmHeight
>= 0 ?
3739 dib
->dsBm
.bmHeight
: -dib
->dsBm
.bmHeight
;
3740 /* same as above - only use biSizeImage as the correct size if it a
3741 compressed image and it's currently non-zero. In other cases, use
3742 width * height as the value. */
3743 INT size
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
3744 ? dib
->dsBmih
.biSizeImage
3745 : dib
->dsBm
.bmWidthBytes
* height
;
3746 if ( dib
->dsBm
.bmBits
)
3748 ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
=
3749 SELECTOR_AllocBlock( dib
->dsBm
.bmBits
, size
, WINE_LDT_FLAGS_DATA
);
3751 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3752 dib
->dsBm
.bmBits
, size
, ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
,
3753 MAKESEGPTR(((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0));
3755 *bits
= MAKESEGPTR( ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0 );
3757 if (bmp
) GDI_ReleaseObj( res
);
3763 /***********************************************************************
3764 * X11DRV_XShmErrorHandler
3767 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
)
3773 /***********************************************************************
3774 * X11DRV_XShmCreateImage
3778 #ifdef HAVE_LIBXXSHM
3779 extern BOOL
X11DRV_XShmCreateImage(XImage
** image
, int width
, int height
, int bpp
,
3780 XShmSegmentInfo
* shminfo
)
3782 int (*WineXHandler
)(Display
*, XErrorEvent
*);
3784 *image
= TSXShmCreateImage(display
, X11DRV_GetVisual(), bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
3785 if( *image
!= NULL
)
3788 shminfo
->shmid
= shmget(IPC_PRIVATE
, (*image
)->bytes_per_line
* height
,
3790 if( shminfo
->shmid
!= -1 )
3792 shminfo
->shmaddr
= (*image
)->data
= shmat(shminfo
->shmid
, 0, 0);
3793 if( shminfo
->shmaddr
!= (char*)-1 )
3795 shminfo
->readOnly
= FALSE
;
3796 if( TSXShmAttach( display
, shminfo
) != 0)
3798 /* Reset the error flag */
3800 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
3801 XSync( display
, 0 );
3805 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3807 XSetErrorHandler(WineXHandler
);
3808 wine_tsx11_unlock();
3809 return TRUE
; /* Success! */
3811 /* An error occured */
3813 XSetErrorHandler(WineXHandler
);
3815 shmdt(shminfo
->shmaddr
);
3817 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3820 XDestroyImage(*image
);
3821 wine_tsx11_unlock();
3825 #endif /* HAVE_LIBXXSHM */
3829 /***********************************************************************
3830 * X11DRV_DIB_CreateDIBSection
3832 HBITMAP
X11DRV_DIB_CreateDIBSection(
3833 DC
*dc
, BITMAPINFO
*bmi
, UINT usage
,
3834 LPVOID
*bits
, HANDLE section
,
3835 DWORD offset
, DWORD ovr_pitch
)
3838 BITMAPOBJ
*bmp
= NULL
;
3839 X11DRV_DIBSECTION
*dib
= NULL
;
3840 int *colorMap
= NULL
;
3843 /* Fill BITMAP32 structure with DIB data */
3844 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
3845 INT effHeight
, totalSize
;
3847 LPVOID mapBits
= NULL
;
3849 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3850 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
3851 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
3853 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
3855 bm
.bmWidth
= bi
->biWidth
;
3856 bm
.bmHeight
= effHeight
;
3857 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
3858 : DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
3859 bm
.bmPlanes
= bi
->biPlanes
;
3860 bm
.bmBitsPixel
= bi
->biBitCount
;
3863 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
3864 we're dealing with a compressed bitmap. Otherwise, use width * height. */
3865 totalSize
= bi
->biSizeImage
&& bi
->biCompression
!= BI_RGB
3866 ? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
3870 SYSTEM_INFO SystemInfo
;
3874 GetSystemInfo( &SystemInfo
);
3875 mapOffset
= offset
- (offset
% SystemInfo
.dwAllocationGranularity
);
3876 mapSize
= totalSize
+ (offset
- mapOffset
);
3877 mapBits
= MapViewOfFile( section
,
3878 FILE_MAP_ALL_ACCESS
,
3882 bm
.bmBits
= (char *)mapBits
+ (offset
- mapOffset
);
3884 else if (ovr_pitch
&& offset
)
3885 bm
.bmBits
= (LPVOID
) offset
;
3888 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
3889 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
3892 /* Create Color Map */
3893 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
3894 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? dc
: NULL
,
3895 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
3897 /* Allocate Memory for DIB and fill structure */
3899 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
3902 dib
->dibSection
.dsBm
= bm
;
3903 dib
->dibSection
.dsBmih
= *bi
;
3904 dib
->dibSection
.dsBmih
.biSizeImage
= totalSize
;
3906 /* Set dsBitfields values */
3907 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
3909 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
3911 else switch( bi
->biBitCount
)
3914 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
3915 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
3916 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
3920 dib
->dibSection
.dsBitfields
[0] = 0xff;
3921 dib
->dibSection
.dsBitfields
[1] = 0xff00;
3922 dib
->dibSection
.dsBitfields
[2] = 0xff0000;
3926 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff;
3927 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0xff00;
3928 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0xff0000;
3931 dib
->dibSection
.dshSection
= section
;
3932 dib
->dibSection
.dsOffset
= offset
;
3934 dib
->status
= DIB_Status_None
;
3937 dib
->nColorMap
= nColorMap
;
3938 dib
->colorMap
= colorMap
;
3941 /* Create Device Dependent Bitmap and add DIB pointer */
3944 res
= CreateDIBitmap(dc
->hSelf
, bi
, 0, NULL
, bmi
, usage
);
3947 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3950 bmp
->dib
= (DIBSECTION
*) dib
;
3952 if(!bmp
->physBitmap
)
3953 X11DRV_CreateBitmap(res
);
3961 #ifdef HAVE_LIBXXSHM
3962 if (TSXShmQueryExtension(display
) &&
3963 X11DRV_XShmCreateImage( &dib
->image
, bm
.bmWidth
, effHeight
,
3964 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
) )
3966 ; /* Created Image */
3968 XCREATEIMAGE( dib
->image
, bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
3969 dib
->shminfo
.shmid
= -1;
3972 XCREATEIMAGE( dib
->image
, bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
3976 /* Clean up in case of errors */
3977 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
3979 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3980 res
, bmp
, dib
, bm
.bmBits
);
3984 UnmapViewOfFile(mapBits
), bm
.bmBits
= NULL
;
3986 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
3989 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
3990 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
3991 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
3992 if (bmp
) { GDI_ReleaseObj(res
); bmp
= NULL
; }
3993 if (res
) { DeleteObject(res
); res
= 0; }
3997 /* Install fault handler, if possible */
3998 InitializeCriticalSection(&(dib
->lock
));
3999 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
4001 if (section
|| offset
)
4003 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4004 if (dib
) dib
->status
= DIB_Status_AppMod
;
4008 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4009 if (dib
) dib
->status
= DIB_Status_InSync
;
4014 /* Return BITMAP handle and storage location */
4015 if (bmp
) GDI_ReleaseObj(res
);
4016 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
4020 /***********************************************************************
4021 * X11DRV_DIB_DeleteDIBSection
4023 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
4025 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4029 #ifdef HAVE_LIBXXSHM
4030 if (dib
->shminfo
.shmid
!= -1)
4032 TSXShmDetach (display
, &(dib
->shminfo
));
4033 XDestroyImage (dib
->image
);
4034 shmdt (dib
->shminfo
.shmaddr
);
4035 dib
->shminfo
.shmid
= -1;
4039 XDestroyImage( dib
->image
);
4043 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
4045 if (dib
->selector
) SELECTOR_FreeBlock( dib
->selector
);
4046 DeleteCriticalSection(&(dib
->lock
));
4049 /***********************************************************************
4050 * X11DRV_DIB_SetDIBColorTable
4052 UINT
X11DRV_DIB_SetDIBColorTable(BITMAPOBJ
*bmp
, DC
*dc
, UINT start
, UINT count
, const RGBQUAD
*colors
)
4054 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4056 if (dib
&& dib
->colorMap
) {
4057 X11DRV_DIB_GenColorMap( dc
, dib
->colorMap
, DIB_RGB_COLORS
, dib
->dibSection
.dsBm
.bmBitsPixel
,
4058 TRUE
, colors
, start
, count
+ start
);
4064 /***********************************************************************
4065 * X11DRV_DIB_GetDIBColorTable
4067 UINT
X11DRV_DIB_GetDIBColorTable(BITMAPOBJ
*bmp
, DC
*dc
, UINT start
, UINT count
, RGBQUAD
*colors
)
4069 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4071 if (dib
&& dib
->colorMap
) {
4072 int i
, end
= count
+ start
;
4073 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
4074 for (i
= start
; i
< end
; i
++,colors
++) {
4075 COLORREF col
= X11DRV_PALETTE_ToLogical( dib
->colorMap
[i
] );
4076 colors
->rgbBlue
= GetBValue(col
);
4077 colors
->rgbGreen
= GetGValue(col
);
4078 colors
->rgbRed
= GetRValue(col
);
4079 colors
->rgbReserved
= 0;
4087 /**************************************************************************
4088 * X11DRV_DIB_CreateDIBFromPixmap
4090 * Allocates a packed DIB and copies the Pixmap data into it.
4091 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
4093 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
4096 BITMAPOBJ
*pBmp
= NULL
;
4097 HGLOBAL hPackedDIB
= 0;
4099 /* Allocates an HBITMAP which references the Pixmap passed to us */
4100 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
4103 TRACE("\tCould not create bitmap header for Pixmap\n");
4108 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4109 * A packed DIB contains a BITMAPINFO structure followed immediately by
4110 * an optional color palette and the pixel data.
4112 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
4114 /* Get a pointer to the BITMAPOBJ structure */
4115 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4117 /* We can now get rid of the HBITMAP wrapper we created earlier.
4118 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4122 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4123 pBmp
->physBitmap
= NULL
;
4126 GDI_ReleaseObj( hBmp
);
4130 TRACE("\tReturning packed DIB %x\n", hPackedDIB
);
4135 /**************************************************************************
4136 * X11DRV_DIB_CreatePixmapFromDIB
4138 * Creates a Pixmap from a packed DIB
4140 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
4142 Pixmap pixmap
= None
;
4144 BITMAPOBJ
*pBmp
= NULL
;
4145 LPBYTE pPackedDIB
= NULL
;
4146 LPBITMAPINFO pbmi
= NULL
;
4147 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
4148 LPBYTE pbits
= NULL
;
4150 /* Get a pointer to the packed DIB's data */
4151 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
4152 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
4153 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
4154 pbits
= (LPBYTE
)(pPackedDIB
4155 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
4157 /* Create a DDB from the DIB */
4159 hBmp
= CreateDIBitmap(hdc
,
4166 GlobalUnlock(hPackedDIB
);
4168 TRACE("CreateDIBitmap returned %x\n", hBmp
);
4170 /* Retrieve the internal Pixmap from the DDB */
4172 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4174 pixmap
= (Pixmap
)pBmp
->physBitmap
;
4175 /* clear the physBitmap so that we can steal its pixmap */
4176 pBmp
->physBitmap
= NULL
;
4179 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4180 GDI_ReleaseObj( hBmp
);
4183 TRACE("\tReturning Pixmap %ld\n", pixmap
);