2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
13 # ifdef HAVE_SYS_SHM_H
16 # ifdef HAVE_SYS_IPC_H
19 #endif /* defined(HAVE_LIBXXSHM) */
25 #include "debugtools.h"
29 #include "selectors.h"
32 DEFAULT_DEBUG_CHANNEL(bitmap
)
33 DECLARE_DEBUG_CHANNEL(x11drv
)
35 static int bitmapDepthTable
[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
36 static int ximageDepthTable
[] = { 0, 0, 0, 0, 0, 0, 0 };
38 static int XShmErrorFlag
= 0;
40 /***********************************************************************
43 BOOL
X11DRV_DIB_Init(void)
48 for( i
= 0; bitmapDepthTable
[i
]; i
++ )
50 testimage
= TSXCreateImage(display
, X11DRV_GetVisual(),
51 bitmapDepthTable
[i
], ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
52 if( testimage
) ximageDepthTable
[i
] = testimage
->bits_per_pixel
;
54 TSXDestroyImage(testimage
);
60 /***********************************************************************
61 * X11DRV_DIB_GetXImageWidthBytes
63 * Return the width of an X image in bytes
65 int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
69 if (!ximageDepthTable
[0]) {
72 for( i
= 0; bitmapDepthTable
[i
] ; i
++ )
73 if( bitmapDepthTable
[i
] == depth
)
74 return (4 * ((width
* ximageDepthTable
[i
] + 31)/32));
76 WARN("(%d): Unsupported depth\n", depth
);
80 /***********************************************************************
81 * X11DRV_DIB_BuildColorMap
83 * Build the color map from the bitmap palette. Should not be called
84 * for a >8-bit deep bitmap.
86 int *X11DRV_DIB_BuildColorMap( DC
*dc
, WORD coloruse
, WORD depth
,
87 const BITMAPINFO
*info
, int *nColors
)
94 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
96 colors
= info
->bmiHeader
.biClrUsed
;
97 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
98 colorPtr
= (WORD
*)info
->bmiColors
;
100 else /* assume BITMAPCOREINFO */
102 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
103 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
108 ERR("called with >256 colors!\n");
112 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
113 colors
* sizeof(int) )))
116 if (coloruse
== DIB_RGB_COLORS
)
120 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
122 if (depth
== 1) /* Monochrome */
123 for (i
= 0; i
< colors
; i
++, rgb
++)
124 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
125 rgb
->rgbBlue
> 255*3/2);
127 for (i
= 0; i
< colors
; i
++, rgb
++)
128 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbRed
,
134 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
136 if (depth
== 1) /* Monochrome */
137 for (i
= 0; i
< colors
; i
++, rgb
++)
138 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
139 rgb
->rgbtBlue
> 255*3/2);
141 for (i
= 0; i
< colors
; i
++, rgb
++)
142 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbtRed
,
147 else /* DIB_PAL_COLORS */
149 for (i
= 0; i
< colors
; i
++, colorPtr
++)
150 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(*colorPtr
) );
158 /***********************************************************************
159 * X11DRV_DIB_MapColor
161 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
)
165 for (color
= 0; color
< nPhysMap
; color
++)
166 if (physMap
[color
] == phys
)
169 WARN("Strange color %08x\n", phys
);
174 /*********************************************************************
175 * X11DRV_DIB_GetNearestIndex
177 * Helper for X11DRV_DIB_GetDIBits.
178 * Returns the nearest colour table index for a given RGB.
179 * Nearest is defined by minimizing the sum of the squares.
181 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
183 INT i
, best
= -1, diff
, bestdiff
= -1;
186 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
187 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
188 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
189 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
192 if(best
== -1 || diff
< bestdiff
) {
200 /***********************************************************************
201 * X11DRV_DIB_SetImageBits_1_Line
203 * Handles a single line of 1 bit data.
205 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth
, int left
, int *colors
,
206 XImage
*bmpImage
, int h
, const BYTE
*bits
)
211 if((extra
= (left
& 7)) != 0) {
218 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
219 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--)
222 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
223 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 6) & 1] );
224 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 5) & 1] );
225 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 4) & 1] );
226 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 3) & 1] );
227 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 2) & 1] );
228 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 1) & 1] );
229 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 1] );
234 case 7: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
235 case 6: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
236 case 5: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
237 case 4: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
238 case 3: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
239 case 2: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
240 case 1: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
244 /***********************************************************************
245 * X11DRV_DIB_SetImageBits_1
247 * SetDIBits for a 1-bit deep DIB.
249 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
250 DWORD srcwidth
, DWORD dstwidth
, int left
,
251 int *colors
, XImage
*bmpImage
)
256 DWORD linebytes
= ((srcwidth
+ 31) & ~31) / 8;
259 for (h
= lines
-1; h
>=0; h
--) {
260 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
262 srcbits
+= linebytes
;
266 for (h
= 0; h
< lines
; h
++) {
267 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
269 srcbits
+= linebytes
;
274 /***********************************************************************
275 * X11DRV_DIB_GetImageBits_1
277 * GetDIBits for a 1-bit deep DIB.
279 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
280 DWORD dstwidth
, DWORD srcwidth
,
281 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
289 DWORD linebytes
= ((dstwidth
+ 31) & ~31) / 8;
293 dstbits
= dstbits
+ linebytes
* (lines
- 1);
294 linebytes
= -linebytes
;
299 switch(bmpImage
->depth
) {
302 /* ==== monochrome bitmap to monochrome dib ==== */
304 /* ==== 4 colormap bitmap to monochrome dib ==== */
305 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
309 for (h
= lines
- 1; h
>= 0; h
--) {
310 for (x
= 0; x
< dstwidth
; x
++) {
311 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
312 if (!(x
&7)) *bits
= 0;
313 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2,
316 val
.peBlue
) << (7 - (x
& 7)));
317 if ((x
&7)==7) bits
++;
319 bits
= (dstbits
+= linebytes
);
322 else goto notsupported
;
327 /* ==== 8 colormap bitmap to monochrome dib ==== */
328 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
333 for( h
= lines
- 1; h
>= 0; h
-- ) {
334 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
335 for( x
= 0; x
< dstwidth
; x
++ ) {
336 if (!(x
&7)) *bits
= 0;
337 val
= srccolors
[(int)*srcpixel
++];
338 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 2,
341 val
.peBlue
) << (7-(x
&7)) );
342 if ((x
&7)==7) bits
++;
344 bits
= (dstbits
+= linebytes
);
347 else goto notsupported
;
356 /* ==== 555 BGR bitmap to monochrome dib ==== */
357 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
359 for( h
= lines
- 1; h
>= 0; h
--) {
360 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
361 for( x
= 0; x
< dstwidth
; x
++) {
362 if (!(x
&7)) *bits
= 0;
364 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
365 ((val
>> 7) & 0xf8) |
367 ((val
>> 2) & 0xf8) |
369 ((val
<< 3) & 0xf8) |
370 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
371 if ((x
&7)==7) bits
++;
373 bits
= (dstbits
+= linebytes
);
376 /* ==== 555 RGB bitmap to monochrome dib ==== */
377 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
379 for( h
= lines
- 1; h
>= 0; h
--)
381 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
382 for( x
= 0; x
< dstwidth
; x
++) {
383 if (!(x
&1)) *bits
= 0;
385 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
386 ((val
<< 3) & 0xf8) |
388 ((val
>> 2) & 0xf8) |
390 ((val
>> 7) & 0xf8) |
391 ((val
>> 12) & 0x7) ) << (7-(x
&7)) );
392 if ((x
&7)==7) bits
++;
394 bits
= (dstbits
+= linebytes
);
397 else goto notsupported
;
406 /* ==== 565 BGR bitmap to monochrome dib ==== */
407 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
409 for( h
= lines
- 1; h
>= 0; h
--)
411 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
412 for( x
= 0; x
< dstwidth
; x
++) {
413 if (!(x
&7)) *bits
= 0;
415 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
416 ((val
>> 8) & 0xf8) |
418 ((val
>> 3) & 0xfc) |
420 ((val
<< 3) & 0xf8) |
421 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
422 if ((x
&7)==7) bits
++;
424 bits
= (dstbits
+= linebytes
);
427 /* ==== 565 RGB bitmap to monochrome dib ==== */
428 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
430 for( h
= lines
- 1; h
>= 0; h
--)
432 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
433 for( x
= 0; x
< dstwidth
; x
++) {
434 if (!(x
&7)) *bits
= 0;
436 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
437 ((val
<< 3) & 0xf8) |
439 ((val
>> 3) & 0xfc) |
441 ((val
>> 8) & 0xf8) |
442 ((val
>> 13) & 0x7) ) << (7-(x
&7)) );
443 if ((x
&7)==7) bits
++;
445 bits
= (dstbits
+= linebytes
);
448 else goto notsupported
;
457 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
458 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
460 for (h
= lines
- 1; h
>= 0; h
--)
462 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
463 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
464 if (!(x
&7)) *bits
= 0;
465 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << (7-(x
&7)) );
466 if ((x
&7)==7) bits
++;
468 bits
= (dstbits
+= linebytes
);
471 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
472 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
474 for (h
= lines
- 1; h
>= 0; h
--)
476 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
477 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
478 if (!(x
& 7)) *bits
= 0;
479 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << (7-(x
&7)) );
480 if ((x
& 7) == 7) bits
++;
482 bits
= (dstbits
+= linebytes
);
485 else goto notsupported
;
489 default: /* ? bit bmp -> monochrome DIB */
492 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
494 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
495 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
496 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
498 for( h
= lines
- 1; h
>= 0; h
-- ) {
499 for( x
= 0; x
< dstwidth
; x
++ ) {
500 if (!(x
&7)) *bits
= 0;
501 *bits
|= (XGetPixel( bmpImage
, x
, h
) >= white
)
503 if ((x
&7)==7) bits
++;
505 bits
= (dstbits
+= linebytes
);
512 /***********************************************************************
513 * X11DRV_DIB_SetImageBits_4
515 * SetDIBits for a 4-bit deep DIB.
517 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
518 DWORD srcwidth
, DWORD dstwidth
, int left
,
519 int *colors
, XImage
*bmpImage
)
523 const BYTE
*bits
= srcbits
+ (left
>> 1);
526 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
534 for (h
= lines
-1; h
>= 0; h
--) {
535 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
537 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
538 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
540 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
541 srcbits
+= linebytes
;
542 bits
= srcbits
+ (left
>> 1);
546 for (h
= 0; h
< lines
; h
++) {
547 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
549 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
550 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
552 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
553 srcbits
+= linebytes
;
554 bits
= srcbits
+ (left
>> 1);
561 /***********************************************************************
562 * X11DRV_DIB_GetImageBits_4
564 * GetDIBits for a 4-bit deep DIB.
566 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
567 DWORD srcwidth
, DWORD dstwidth
,
568 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
577 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
582 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
583 linebytes
= -linebytes
;
588 switch(bmpImage
->depth
) {
591 /* ==== monochrome bitmap to 4 colormap dib ==== */
593 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
594 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
598 for (h
= lines
-1; h
>= 0; h
--) {
599 for (x
= 0; x
< dstwidth
; x
++) {
600 if (!(x
&1)) *bits
= 0;
601 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
602 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 16,
605 val
.peBlue
) << (4-((x
&1)<<2)));
606 if ((x
&1)==1) bits
++;
608 bits
= (dstbits
+= linebytes
);
611 else goto notsupported
;
616 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
617 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
621 for( h
= lines
- 1; h
>= 0; h
-- ) {
622 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
623 for( x
= 0; x
< dstwidth
; x
++ ) {
624 if (!(x
&1)) *bits
= 0;
625 val
= srccolors
[(int)*srcpixel
++];
626 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 16,
629 val
.peBlue
) << (4*(1-(x
&1))) );
630 if ((x
&1)==1) bits
++;
632 bits
= (dstbits
+= linebytes
);
635 else goto notsupported
;
644 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
645 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
647 for( h
= lines
- 1; h
>= 0; h
--) {
648 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
649 for( x
= 0; x
< dstwidth
; x
++) {
650 if (!(x
&1)) *bits
= 0;
652 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
653 ((val
>> 7) & 0xf8) |
655 ((val
>> 2) & 0xf8) |
657 ((val
<< 3) & 0xf8) |
658 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
659 if ((x
&1)==1) bits
++;
661 bits
= (dstbits
+= linebytes
);
664 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
665 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
667 for( h
= lines
- 1; h
>= 0; h
--)
669 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
670 for( x
= 0; x
< dstwidth
; x
++) {
671 if (!(x
&1)) *bits
= 0;
673 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
674 ((val
<< 3) & 0xf8) |
676 ((val
>> 2) & 0xfc) |
678 ((val
>> 7) & 0xf8) |
679 ((val
>> 12) & 0x7) ) << ((1-(x
&1))<<2) );
680 if ((x
&1)==1) bits
++;
682 bits
= (dstbits
+= linebytes
);
685 else goto notsupported
;
694 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
695 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
697 for( h
= lines
- 1; h
>= 0; h
--)
699 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
700 for( x
= 0; x
< dstwidth
; x
++) {
701 if (!(x
&1)) *bits
= 0;
703 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
704 ((val
>> 8) & 0xf8) |
706 ((val
>> 3) & 0xfc) |
708 ((val
<< 3) & 0xf8) |
709 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
710 if ((x
&1)==1) bits
++;
712 bits
= (dstbits
+= linebytes
);
715 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
716 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
718 for( h
= lines
- 1; h
>= 0; h
--)
720 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
721 for( x
= 0; x
< dstwidth
; x
++) {
722 if (!(x
&1)) *bits
= 0;
724 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
725 ((val
<< 3) & 0xf8) |
727 ((val
>> 3) & 0xfc) |
729 ((val
>> 8) & 0xf8) |
730 ((val
>> 13) & 0x7) ) << ((1-(x
&1))<<2) );
731 if ((x
&1)==1) bits
++;
733 bits
= (dstbits
+= linebytes
);
736 else goto notsupported
;
745 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
746 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
748 for (h
= lines
- 1; h
>= 0; h
--)
750 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
751 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
752 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << 4) |
753 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[6] , srcpixel
[5], srcpixel
[4]);
754 bits
= (dstbits
+= linebytes
);
757 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
758 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
760 for (h
= lines
- 1; h
>= 0; h
--)
762 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
763 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
764 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << 4) |
765 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[4] , srcpixel
[5], srcpixel
[6]);
766 bits
= (dstbits
+= linebytes
);
769 else goto notsupported
;
773 default: /* ? bit bmp -> 4 bit DIB */
775 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
776 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
777 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
778 for (h
= lines
-1; h
>= 0; h
--) {
779 for (x
= 0; x
< dstwidth
/2; x
++) {
780 *bits
++ = (X11DRV_DIB_MapColor((int *)colors
, 16,
781 XGetPixel( bmpImage
, x
++, h
)) << 4)
782 | (X11DRV_DIB_MapColor((int *)colors
, 16,
783 XGetPixel( bmpImage
, x
++, h
)) & 0x0f);
786 *bits
= (X11DRV_DIB_MapColor((int *)colors
, 16,
787 XGetPixel( bmpImage
, x
++, h
)) << 4);
788 bits
= (dstbits
+= linebytes
);
794 /***********************************************************************
795 * X11DRV_DIB_SetImageBits_RLE4
797 * SetDIBits for a 4-bit deep compressed DIB.
799 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
800 DWORD width
, DWORD dstwidth
,
801 int left
, int *colors
,
804 int x
= 0, c
, length
;
805 const BYTE
*begin
= bits
;
809 while ((int)lines
>= 0) {
811 if (length
) { /* encoded */
819 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>>4]);
827 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
838 case 1: /* eopicture */
844 FIXME_(x11drv
)("x-delta is too large?\n");
850 default: /* absolute */
858 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>> 4]);
866 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
869 if ((bits
- begin
) & 1)
878 /***********************************************************************
879 * X11DRV_DIB_SetImageBits_8
881 * SetDIBits for an 8-bit deep DIB.
883 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
884 DWORD srcwidth
, DWORD dstwidth
, int left
,
885 int *colors
, XImage
*bmpImage
)
891 /* align to 32 bit */
892 DWORD linebytes
= (srcwidth
+ 3) & ~3;
899 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
900 linebytes
= -linebytes
;
903 bits
= srcbits
+ left
;
905 for (h
= lines
- 1; h
>= 0; h
--) {
906 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
907 color
= colors
[*bits
];
908 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
910 bits
= (srcbits
+= linebytes
) + left
;
914 /***********************************************************************
915 * X11DRV_DIB_GetImageBits_8
917 * GetDIBits for an 8-bit deep DIB.
919 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
920 DWORD srcwidth
, DWORD dstwidth
,
921 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
928 /* align to 32 bit */
929 DWORD linebytes
= (srcwidth
+ 3) & ~3;
934 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
935 linebytes
= -linebytes
;
942 This condition is true when GetImageBits has been called by UpdateDIBSection.
943 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
944 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
946 if (!srccolors
) goto updatesection
;
948 switch(bmpImage
->depth
) {
951 /* ==== monochrome bitmap to 8 colormap dib ==== */
953 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
954 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
958 for (h
= lines
- 1; h
>= 0; h
--) {
959 for (x
= 0; x
< dstwidth
; x
++) {
960 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
961 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
962 val
.peGreen
, val
.peBlue
);
964 bits
= (dstbits
+= linebytes
);
967 else goto notsupported
;
972 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
973 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
978 for (h
= lines
- 1; h
>= 0; h
--) {
979 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
980 for (x
= 0; x
< dstwidth
; x
++) {
981 val
= srccolors
[(int)*srcpixel
++];
982 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
983 val
.peGreen
, val
.peBlue
);
985 bits
= (dstbits
+= linebytes
);
988 else goto notsupported
;
997 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
998 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1000 for( h
= lines
- 1; h
>= 0; h
--)
1002 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1003 for( x
= 0; x
< dstwidth
; x
++ )
1006 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1007 ((val
>> 7) & 0xf8) |
1008 ((val
>> 12) & 0x7),
1009 ((val
>> 2) & 0xf8) |
1011 ((val
<< 3) & 0xf8) |
1012 ((val
>> 2) & 0x7) );
1014 bits
= (dstbits
+= linebytes
);
1017 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1018 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1020 for( h
= lines
- 1; h
>= 0; h
--)
1022 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1023 for( x
= 0; x
< dstwidth
; x
++ )
1026 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1027 ((val
<< 3) & 0xf8) |
1029 ((val
>> 2) & 0xf8) |
1031 ((val
>> 7) & 0xf8) |
1032 ((val
>> 12) & 0x7) );
1034 bits
= (dstbits
+= linebytes
);
1037 else goto notsupported
;
1046 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1047 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
1049 for( h
= lines
- 1; h
>= 0; h
--)
1051 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1052 for( x
= 0; x
< dstwidth
; x
++ )
1055 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1056 ((val
>> 8) & 0xf8) |
1057 ((val
>> 13) & 0x7),
1058 ((val
>> 3) & 0xfc) |
1060 ((val
<< 3) & 0xf8) |
1061 ((val
>> 2) & 0x7) );
1063 bits
= (dstbits
+= linebytes
);
1066 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1067 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1069 for( h
= lines
- 1; h
>= 0; h
--)
1071 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1072 for( x
= 0; x
< dstwidth
; x
++ )
1075 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1076 ((val
<< 3) & 0xf8) |
1078 ((val
>> 3) & 0x00fc) |
1080 ((val
>> 8) & 0x00f8) |
1081 ((val
>> 13) & 0x7) );
1083 bits
= (dstbits
+= linebytes
);
1086 else goto notsupported
;
1095 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1096 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1098 for (h
= lines
- 1; h
>= 0; h
--)
1100 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1101 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1102 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1103 srcpixel
[2] , srcpixel
[1], *srcpixel
);
1104 bits
= (dstbits
+= linebytes
);
1107 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1108 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1110 for (h
= lines
- 1; h
>= 0; h
--)
1112 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1113 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1114 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1115 *srcpixel
, srcpixel
[1], srcpixel
[2]);
1116 bits
= (dstbits
+= linebytes
);
1120 else goto notsupported
;
1124 default: /* ? bit bmp -> 8 bit DIB */
1126 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1127 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1128 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1130 for (h
= lines
- 1; h
>= 0; h
--) {
1131 for (x
= 0; x
< dstwidth
; x
++, bits
++) {
1132 *bits
= X11DRV_DIB_MapColor((int *)colors
, 256,
1133 XGetPixel( bmpImage
, x
, h
) );
1135 bits
= (dstbits
+= linebytes
);
1141 /***********************************************************************
1142 * X11DRV_DIB_SetImageBits_RLE8
1144 * SetDIBits for an 8-bit deep compressed DIB.
1146 * This function rewritten 941113 by James Youngman. WINE blew out when I
1147 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1149 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1150 * 'End of bitmap' escape code. This code is very much laxer in what it
1151 * allows to end the expansion. Possibly too lax. See the note by
1152 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1153 * bitmap should end with RleEnd, but on the other hand, software exists
1154 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1157 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1158 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1162 enum Rle8_EscapeCodes
1165 * Apologies for polluting your file's namespace...
1167 RleEol
= 0, /* End of line */
1168 RleEnd
= 1, /* End of bitmap */
1169 RleDelta
= 2 /* Delta */
1172 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1173 DWORD width
, DWORD dstwidth
,
1174 int left
, int *colors
,
1177 int x
; /* X-positon on each line. Increases. */
1178 int line
; /* Line #. Starts at lines-1, decreases */
1179 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1180 BYTE length
; /* The length pf a run */
1181 BYTE color_index
; /* index into colors[] as read from bits */
1182 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1183 int color
; /* value of colour[color_index] */
1185 if (lines
== 0) /* Let's hope this doesn't happen. */
1189 * Note that the bitmap data is stored by Windows starting at the
1190 * bottom line of the bitmap and going upwards. Within each line,
1191 * the data is stored left-to-right. That's the reason why line
1192 * goes from lines-1 to 0. [JAY]
1202 * If the length byte is not zero (which is the escape value),
1203 * We have a run of length pixels all the same colour. The colour
1204 * index is stored next.
1206 * If the length byte is zero, we need to read the next byte to
1207 * know what to do. [JAY]
1212 * [Run-Length] Encoded mode
1214 color_index
= (*pIn
++); /* Get the colour index. */
1215 color
= colors
[color_index
];
1218 XPutPixel(bmpImage
, x
++, line
, color
);
1223 * Escape codes (may be an absolute sequence though)
1225 escape_code
= (*pIn
++);
1228 case RleEol
: /* =0, end of line */
1235 case RleEnd
: /* =1, end of bitmap */
1238 * Not all RLE8 bitmaps end with this
1239 * code. For example, Paint Shop Pro
1240 * produces some that don't. That's (I think)
1241 * what caused the previous implementation to
1244 line
=-1; /* Cause exit from do loop. */
1248 case RleDelta
: /* =2, a delta */
1251 * Note that deltaing to line 0
1252 * will cause an exit from the loop,
1253 * which may not be what is intended.
1254 * The fact that there is a delta in the bits
1255 * almost certainly implies that there is data
1256 * to follow. You may feel that we should
1257 * jump to the top of the loop to avoid exiting
1260 * TODO: Decide what to do here in that case. [JAY]
1266 TRACE("Delta to last line of bitmap "
1267 "(wrongly?) causes loop exit\n");
1272 default: /* >2, switch to absolute mode */
1277 length
= escape_code
;
1280 color_index
= (*pIn
++);
1281 XPutPixel(bmpImage
, x
++, line
,
1282 colors
[color_index
]);
1286 * If you think for a moment you'll realise that the
1287 * only time we could ever possibly read an odd
1288 * number of bytes is when there is a 0x00 (escape),
1289 * a value >0x02 (absolute mode) and then an odd-
1290 * length run. Therefore this is the only place we
1291 * need to worry about it. Everywhere else the
1292 * bytes are always read in pairs. [JAY]
1294 if (escape_code
& 1)
1295 pIn
++; /* Throw away the pad byte. */
1298 } /* switch (escape_code) : Escape sequence */
1299 } /* process either an encoded sequence or an escape sequence */
1301 /* We expect to come here more than once per line. */
1302 } while (line
>= 0); /* Do this until the bitmap is filled */
1305 * Everybody comes here at the end.
1306 * Check how we exited the loop and print a message if it's a bit odd.
1309 if ( (*(pIn
-2) != 0/*escape*/) || (*(pIn
-1)!= RleEnd
) )
1311 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1312 "bytes were: %02X %02X.\n", (int)*(pIn
-2),(int)*(pIn
-1));
1317 /***********************************************************************
1318 * X11DRV_DIB_SetImageBits_16
1320 * SetDIBits for a 16-bit deep DIB.
1322 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1323 DWORD srcwidth
, DWORD dstwidth
, int left
,
1324 DC
*dc
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1330 /* align to 32 bit */
1331 DWORD linebytes
= (srcwidth
* 2 + 3) & ~3;
1336 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1337 linebytes
= -linebytes
;
1340 switch ( bmpImage
->depth
)
1343 /* using same format as XImage */
1344 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1345 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1346 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1347 else /* We need to do a conversion from a 565 dib */
1349 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1351 int div
= dstwidth
% 2;
1353 for (h
= lines
- 1; h
>= 0; h
--) {
1354 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1355 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1357 *dstpixel
++ = ((val
>> 1) & 0x7fe07fe0) | (val
& 0x001f001f); /* Red & Green & Blue */
1359 if (div
!= 0) /* Odd width? */
1360 *dstpixel
= ((*(WORD
*)ptr
>> 1) & 0x7fe0) | (*(WORD
*)ptr
& 0x001f);
1361 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1367 /* using same format as XImage */
1368 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1369 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1370 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1371 else /* We need to do a conversion from a 555 dib */
1373 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1375 int div
= dstwidth
% 2;
1377 for (h
= lines
- 1; h
>= 0; h
--) {
1378 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1379 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1381 *dstpixel
++ = ((val
<< 1) & 0xffc0ffc0) | ((val
>> 4) & 0x00200020) | /* Red & Green */
1382 (val
& 0x001f001f); /* Blue */
1384 if (div
!= 0) /* Odd width? */
1385 *dstpixel
= ((*(WORD
*)ptr
<< 1) & 0xffc0) | ((*(WORD
*)ptr
>> 4) & 0x0020)
1386 | (*(WORD
*)ptr
& 0x001f);
1387 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1396 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1399 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1400 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1402 for (h
= lines
- 1; h
>= 0; h
--) {
1403 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1404 for (x
= 0; x
< dstwidth
; x
++) {
1407 *dstpixel
++ = ((val
<< 9) & 0xf80000) | ((val
<< 4) & 0x070000) | /* Red */
1408 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1409 ((val
<< 3) & 0x0000f8) | ((val
>> 2) & 0x000007); /* Blue */
1411 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1414 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1415 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1417 for (h
= lines
- 1; h
>= 0; h
--) {
1418 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1419 for (x
= 0; x
< dstwidth
; x
++) {
1422 *dstpixel
++ = ((val
>> 7) & 0x0000f8) | ((val
>> 12) & 0x000007) | /* Red */
1423 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1424 ((val
<< 19) & 0xf80000) | ((val
>> 14) & 0x070000); /* Blue */
1426 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1437 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1441 /* Set color scaling values */
1442 if ( rSrc
== 0x7c00 ) { sc1
= 7; sc2
= 2; } /* 555 dib */
1443 else { sc1
= 8; sc2
= 3; } /* 565 dib */
1445 for (h
= lines
- 1; h
>= 0; h
--) {
1446 for (x
= left
; x
< dstwidth
+left
; x
++) {
1448 XPutPixel( bmpImage
, x
, h
,
1449 X11DRV_PALETTE_ToPhysical(dc
, RGB(((val
& rSrc
) >> sc1
), /* Red */
1450 ((val
& gSrc
) >> sc2
), /* Green */
1451 ((val
& bSrc
) << 3)))); /* Blue */
1453 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
1459 FIXME("16 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
1466 /***********************************************************************
1467 * X11DRV_DIB_GetImageBits_16
1469 * GetDIBits for an 16-bit deep DIB.
1471 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
1472 DWORD dstwidth
, DWORD srcwidth
,
1473 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
1478 /* align to 32 bit */
1479 DWORD linebytes
= (dstwidth
* 2 + 3) & ~3;
1484 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
1485 linebytes
= -linebytes
;
1488 switch ( bmpImage
->depth
)
1491 /* ==== 555 BGR bitmap to 555 BGR dib ==== */
1492 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1493 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+= linebytes
)
1494 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, srcwidth
*2 );
1496 /* ==== 555 RGB bitmap to 555 BGR dib ==== */
1497 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1499 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1501 int div
= srcwidth
% 2;
1503 for (h
= lines
- 1; h
>= 0; h
--) {
1504 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1505 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1507 *ptr
++ = ((val
<< 10) & 0xf800f800) | (val
& 0x03e003e0) | /* Red & Green */
1508 ((val
>> 10) & 0x001f001f); /* Blue */
1510 if (div
!= 0) /* Odd width? */
1511 *ptr
= ((*(WORD
*)srcpixel
<< 1) & 0xffc0) | ((*(WORD
*)srcpixel
>> 4) & 0x0020) |
1512 (*(WORD
*)srcpixel
& 0x001f);
1513 ptr
= (LPDWORD
)(dstbits
+= linebytes
);
1516 else goto notsupported
;
1522 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1524 int div
= srcwidth
% 2;
1526 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1527 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f )
1529 for (h
= lines
- 1; h
>= 0; h
--) {
1530 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1531 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1533 *ptr
++ = ((val
>> 1) & 0x7fe07fe0) | /* Red & Green */
1534 (val
& 0x001f001f); /* Blue */
1536 if (div
!= 0) /* Odd width? */
1537 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1538 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1541 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1542 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1544 for (h
= lines
- 1; h
>= 0; h
--) {
1545 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1546 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1548 *ptr
++ = ((val
<< 10) & 0x7c007c00) | ((val
>> 1) & 0x03e003e0) | /* Red & Green */
1549 ((val
>> 11) & 0x001f001f); /* Blue */
1551 if (div
!= 0) /* Odd width? */
1552 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1553 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1556 else goto notsupported
;
1564 LPWORD ptr
= (LPWORD
)dstbits
;
1567 /* ==== 24/32 BGR bitmap to 555 BGR dib ==== */
1568 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1570 for (h
= lines
- 1; h
>= 0; h
--) {
1571 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1572 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1574 *ptr
= ((val
>> 9) & 0x7c00) | /* Red */
1575 ((val
>> 6) & 0x03e0) | /* Green */
1576 ((val
>> 3) & 0x001f); /* Blue */
1578 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1581 /* ==== 24/32 RGB bitmap to 555 BGR dib ==== */
1582 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1584 for (h
= lines
- 1; h
>= 0; h
--) {
1585 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1586 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1588 *ptr
= ((val
<< 7) & 0x7c00) | /* Red */
1589 ((val
>> 6) & 0x03e0) | /* Green */
1590 ((val
>> 19) & 0x001f); /* Blue */
1592 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1595 else goto notsupported
;
1600 /* ==== monochrome bitmap to 16 BGR dib ==== */
1602 /* ==== 4 colormap bitmap to 16 BGR dib ==== */
1603 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1605 LPWORD ptr
= (LPWORD
)dstbits
;
1608 for (h
= lines
- 1; h
>= 0; h
--) {
1609 for (x
= 0; x
< dstwidth
; x
++) {
1610 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
1611 *ptr
++ = ((val
.peRed
<< 7) & 0x7c00) |
1612 ((val
.peGreen
<< 2) & 0x03e0) |
1613 ((val
.peBlue
>> 3) & 0x001f);
1615 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1618 else goto notsupported
;
1623 /* ==== 8 colormap bitmap to 16 BGR dib ==== */
1624 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1626 LPWORD ptr
= (LPWORD
)dstbits
;
1630 for (h
= lines
- 1; h
>= 0; h
--) {
1631 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1632 for (x
= 0; x
< dstwidth
; x
++) {
1633 val
= srccolors
[(int)*srcpixel
++];
1634 *ptr
++ = ((val
.peRed
<< 7) & 0x7c00) |
1635 ((val
.peGreen
<< 2) & 0x03e0) |
1636 ((val
.peBlue
>> 3) & 0x001f);
1638 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1641 else goto notsupported
;
1649 LPWORD ptr
= (LPWORD
)dstbits
;
1651 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 16 bit DIB\n",
1652 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1653 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1654 for (h
= lines
- 1; h
>= 0; h
--)
1656 for (x
= 0; x
< dstwidth
; x
++, ptr
++)
1658 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
1659 r
= (BYTE
) GetRValue(pixel
);
1660 g
= (BYTE
) GetGValue(pixel
);
1661 b
= (BYTE
) GetBValue(pixel
);
1662 *ptr
= ( ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f) );
1664 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1672 /***********************************************************************
1673 * X11DRV_DIB_SetImageBits_24
1675 * SetDIBits for a 24-bit deep DIB.
1677 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
1678 DWORD srcwidth
, DWORD dstwidth
, int left
,
1679 DC
*dc
, XImage
*bmpImage
)
1684 /* align to 32 bit */
1685 DWORD linebytes
= (srcwidth
* 3 + 3) & ~3;
1690 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1691 linebytes
= -linebytes
;
1694 switch ( bmpImage
->depth
)
1698 if (bmpImage
->bits_per_pixel
== 24) {
1699 int dstlinebytes
= linebytes
;
1701 BYTE
*ptr
= (BYTE
*)(srcbits
+left
*3);
1703 if (dstlinebytes
< 0 ) dstlinebytes
= -dstlinebytes
;
1704 dstpixel
= bmpImage
->data
+ lines
*dstlinebytes
+ left
*3;
1705 for(h
= lines
; h
-- ; ) {
1706 dstpixel
-=dstlinebytes
;
1707 memcpy(dstpixel
,ptr
,dstwidth
*3);
1715 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 ) /* packed BGR to unpacked BGR */
1717 DWORD
*dstpixel
, val
, buf
;
1718 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1720 int div
= dstwidth
% 4;
1723 for(h
= lines
- 1; h
>= 0; h
--)
1725 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1727 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1729 *dstpixel
++ = buf
&0x00ffffff; /* b1, g1, r1 */
1730 val
= (buf
>> 24); /* b2 */
1732 *dstpixel
++ = (val
| (buf
<<8)) &0x00ffffff; /* g2, r2 */
1733 val
= (buf
>> 16); /* b3, g3 */
1735 *dstpixel
++ = (val
| (buf
<<16)) &0x00ffffff; /* r3 */
1736 *dstpixel
++ = (buf
>> 8); /* b4, g4, r4 */
1738 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1740 *dstpixel
++ = *(DWORD
*)bits
& 0x00ffffff; /* b, g, r */
1742 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1745 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff ) /* packed BGR to unpacked RGB */
1747 DWORD
*dstpixel
, val
, buf
;
1748 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1750 int div
= dstwidth
% 4;
1753 for(h
= lines
- 1; h
>= 0; h
--)
1755 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1757 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1759 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b1, g1, r1 */
1760 val
= ((buf
&0xff000000)>>8); /* b2 */
1762 *dstpixel
++ = val
| ((buf
&0xff)<<8) | ((buf
&0xff00)>>8); /* g2, r2 */
1763 val
= (buf
&0xff0000) | ((buf
&0xff000000)>>16); /* b3, g3 */
1765 *dstpixel
++ = val
| (buf
&0xff); /* r3 */
1766 *dstpixel
++ = ((buf
&0xff00)<<8) | ((buf
&0xff0000)>>8) | (buf
>>24); /* b4, g4, r4 */
1768 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1770 buf
= *(DWORD
*)bits
;
1771 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b, g, r */
1773 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1783 if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f ) /* BGR888 to RGB555 */
1785 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1788 int div
= dstwidth
% 4;
1791 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1792 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1793 for (x
= 0; x
< dstwidth
/4; x
++) {
1794 *dstpixel
++ = (WORD
)((((val
= *ptr
++) << 7) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 19) & 0x1f));
1795 *dstpixel
++ = (WORD
)(((val
>> 17) & 0x7c00) | (((val
= *ptr
++) << 2) & 0x03e0) | ((val
>> 11) & 0x1f));
1796 *dstpixel
++ = (WORD
)(((val
>> 9) & 0x07c00) | ((val
>> 22) & 0x03e0) | (((val
= *ptr
++) >> 3) & 0x1f));
1797 *dstpixel
++ = (WORD
)(((val
>> 1) & 0x07c00) | ((val
>> 14) & 0x03e0) | ((val
>> 27) & 0x1f));
1799 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1800 *dstpixel
++ = (((WORD
)bits
[0] << 7) & 0x07c00) |
1801 (((WORD
)bits
[1] << 2) & 0x03e0) |
1802 (((WORD
)bits
[2] >> 3) & 0x001f);
1803 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1806 else if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 ) /* BGR888 to BGR555 */
1808 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1811 int div
= dstwidth
% 4;
1814 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1815 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1816 for (x
= 0; x
< dstwidth
/4; x
++) {
1817 *dstpixel
++ = (WORD
)((((val
= *ptr
++) >> 3) & 0x1f) | ((val
>> 6) & 0x03e0) | ((val
>> 9) & 0x7c00));
1818 *dstpixel
++ = (WORD
)(((val
>> 27) & 0x1f) | (((val
= *ptr
++) << 2) & 0x03e0) | ((val
>> 1) & 0x7c00));
1819 *dstpixel
++ = (WORD
)(((val
>> 19) & 0x1f) | ((val
>> 22) & 0x03e0) | (((val
= *ptr
++) << 7) & 0x7c00));
1820 *dstpixel
++ = (WORD
)(((val
>> 11) & 0x1f) | ((val
>> 14) & 0x03e0) | ((val
>> 17) & 0x7c00));
1822 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1823 *dstpixel
++ = (((WORD
)bits
[2] << 7) & 0x07c00) |
1824 (((WORD
)bits
[1] << 2) & 0x03e0) |
1825 (((WORD
)bits
[0] >> 3) & 0x001f);
1826 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1836 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1839 int div
= dstwidth
% 4;
1842 if( bmpImage
->blue_mask
== 0x001f && bmpImage
->red_mask
== 0xf800 ) /* BGR888 to BGR565 */
1844 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1845 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1846 for (x
= 0; x
< dstwidth
/4; x
++) {
1847 *dstpixel
++ = (WORD
)((((val
= *ptr
++) >> 3) & 0x1f) | ((val
>> 5) & 0x07e0) | ((val
>> 8) & 0xf800));
1848 *dstpixel
++ = (WORD
)(((val
>> 27) & 0x1f) | (((val
= *ptr
++) << 3) & 0x07e0) | ((val
) & 0xf800));
1849 *dstpixel
++ = (WORD
)(((val
>> 19) & 0x1f) | ((val
>> 21) & 0x07e0) | (((val
= *ptr
++) << 8) & 0xf800));
1850 *dstpixel
++ = (WORD
)(((val
>> 11) & 0x1f) | ((val
>> 13) & 0x07e0) | ((val
>> 16) & 0xf800));
1852 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1853 *dstpixel
++ = (((WORD
)bits
[2] << 8) & 0xf800) |
1854 (((WORD
)bits
[1] << 3) & 0x07e0) |
1855 (((WORD
)bits
[0] >> 3) & 0x001f);
1856 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1859 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x001f ) /* BGR888 to RGB565 */
1861 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1862 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1863 for (x
= 0; x
< dstwidth
/4; x
++) {
1864 *dstpixel
++ = (WORD
)((((val
= *ptr
++) << 8) & 0xf800) | ((val
>> 5) & 0x07e0) | ((val
>> 19) & 0x1f));
1865 *dstpixel
++ = (WORD
)(((val
>> 16) & 0xf800) | (((val
= *ptr
++) << 3) & 0x07e0) | ((val
>> 11) & 0x1f));
1866 *dstpixel
++ = (WORD
)(((val
>> 8) & 0xf800) | ((val
>> 21) & 0x07e0) | (((val
= *ptr
++) >> 3) & 0x1f));
1867 *dstpixel
++ = (WORD
)((val
& 0xf800) | ((val
>> 13) & 0x07e0) | ((val
>> 27) & 0x1f));
1869 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1870 *dstpixel
++ = (((WORD
)bits
[0] << 8) & 0xf800) |
1871 (((WORD
)bits
[1] << 3) & 0x07e0) |
1872 (((WORD
)bits
[2] >> 3) & 0x001f);
1873 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1885 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*3;
1887 for (h
= lines
- 1; h
>= 0; h
--) {
1888 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+=3)
1889 XPutPixel( bmpImage
, x
, h
,
1890 X11DRV_PALETTE_ToPhysical(dc
, RGB(bits
[2], bits
[1], bits
[0])));
1891 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 3;
1898 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
1899 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
1900 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1906 /***********************************************************************
1907 * X11DRV_DIB_GetImageBits_24
1909 * GetDIBits for an 24-bit deep DIB.
1911 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
1912 DWORD dstwidth
, DWORD srcwidth
,
1913 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
1918 /* align to 32 bit */
1919 DWORD linebytes
= (dstwidth
* 3 + 3) & ~3;
1924 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1925 linebytes
= -linebytes
;
1928 switch ( bmpImage
->depth
)
1932 if (bmpImage
->bits_per_pixel
== 24) {
1933 int tocopy
= linebytes
;
1935 BYTE
*ptr
= (LPBYTE
)dstbits
;
1937 if (tocopy
< 0 ) tocopy
= -tocopy
;
1938 srcpixel
= bmpImage
->data
+ lines
*tocopy
;
1939 for(h
= lines
; h
-- ; ) {
1941 memcpy(ptr
,srcpixel
,tocopy
);
1942 ptr
= (LPBYTE
)(dstbits
+=linebytes
);
1949 DWORD
*srcpixel
, buf
;
1951 DWORD
*ptr
=(DWORD
*)dstbits
;
1952 int quotient
= dstwidth
/ 4;
1953 int remainder
= dstwidth
% 4;
1956 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
1957 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 )
1959 for(h
= lines
- 1; h
>= 0; h
--)
1961 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1963 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time*/
1964 buf
= ((*srcpixel
++)&0x00ffffff); /* b1, g1, r1*/
1965 *ptr
++ = buf
| ((*srcpixel
)<<24); /* b2 */
1966 buf
= ((*srcpixel
++>>8)&0x0000ffff); /* g2, r2 */
1967 *ptr
++ = buf
| ((*srcpixel
)<<16); /* b3, g3 */
1968 buf
= ((*srcpixel
++>>16)&0x000000ff); /* r3 */
1969 *ptr
++ = buf
| ((*srcpixel
++)<<8); /* b4, g4, r4 */
1971 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
1974 *(WORD
*)bits
= buf
; /* b, g */
1975 *(bits
+2) = buf
>>16; /* r */
1977 ptr
= (DWORD
*)(dstbits
+=linebytes
);
1981 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
1982 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff )
1984 for(h
= lines
- 1; h
>= 0; h
--)
1986 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1988 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time */
1990 val
= ((buf
&0xff0000)>>16) | (buf
&0xff00) | ((buf
&0xff)<<16); /* b1, g1, r1 */
1992 *ptr
++ = val
| ((buf
&0xff0000)<<8); /* b2 */
1993 val
= ((buf
&0xff00)>>8) | ((buf
&0xff)<<8); /* g2, r2 */
1995 *ptr
++ = val
| (buf
&0xff0000) | ((buf
&0xff00)<<16); /* b3, g3 */
1996 val
= (buf
&0xff); /* r3 */
1998 *ptr
++ = val
| ((buf
&0xff0000)>>8) | ((buf
&0xff00)<<8) | (buf
<<24); /* b4, g4, r4 */
2000 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
2003 *(WORD
*)bits
= (buf
&0xff00) | ((buf
&0xff0000)>>16) ; /* b, g */
2004 *(bits
+2) = buf
; /* r */
2006 ptr
= (DWORD
*)(dstbits
+=linebytes
);
2009 else goto notsupported
;
2016 LPBYTE bits
= dstbits
;
2019 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2020 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 )
2022 for (h
= lines
- 1; h
>= 0; h
--) {
2023 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2024 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2026 bits
[2] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2027 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2028 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2030 bits
= (dstbits
+= linebytes
);
2033 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2034 else if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f )
2036 for (h
= lines
- 1; h
>= 0; h
--) {
2037 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2038 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2040 bits
[0] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2041 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2042 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2044 bits
= (dstbits
+= linebytes
);
2047 else goto notsupported
;
2054 LPBYTE bits
= dstbits
;
2057 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2058 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0xf800 )
2060 for (h
= lines
- 1; h
>= 0; h
--) {
2061 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2062 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2064 bits
[2] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2065 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2066 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2068 bits
= (dstbits
+= linebytes
);
2071 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2072 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x1f )
2074 for (h
= lines
- 1; h
>= 0; h
--) {
2075 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2076 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2078 bits
[0] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2079 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2080 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2082 bits
= (dstbits
+= linebytes
);
2085 else goto notsupported
;
2090 /* ==== monochrome bitmap to 24 BGR dib ==== */
2092 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2093 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2095 LPBYTE bits
= dstbits
;
2098 for (h
= lines
- 1; h
>= 0; h
--) {
2099 for (x
= 0; x
< dstwidth
; x
++) {
2100 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2101 *bits
++ = val
.peBlue
;
2102 *bits
++ = val
.peGreen
;
2103 *bits
++ = val
.peRed
;
2105 bits
= (dstbits
+= linebytes
);
2108 else goto notsupported
;
2113 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2114 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
)
2117 LPBYTE bits
= dstbits
;
2120 for (h
= lines
- 1; h
>= 0; h
--) {
2121 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2122 for (x
= 0; x
< dstwidth
; x
++ ) {
2123 val
= srccolors
[(int)*srcpixel
++];
2124 *bits
++ = val
.peBlue
; /*Blue*/
2125 *bits
++ = val
.peGreen
; /*Green*/
2126 *bits
++ = val
.peRed
; /*Red*/
2128 bits
= (dstbits
+= linebytes
);
2131 else goto notsupported
;
2138 LPBYTE bits
= dstbits
;
2140 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2141 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2142 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2143 for (h
= lines
- 1; h
>= 0; h
--)
2145 for (x
= 0; x
< dstwidth
; x
++, bits
+= 3)
2147 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2148 bits
[0] = GetBValue(pixel
);
2149 bits
[1] = GetGValue(pixel
);
2150 bits
[2] = GetRValue(pixel
);
2152 bits
= (dstbits
+= linebytes
);
2160 /***********************************************************************
2161 * X11DRV_DIB_SetImageBits_32
2163 * SetDIBits for a 32-bit deep DIB.
2165 static void X11DRV_DIB_SetImageBits_32( int lines
, const BYTE
*srcbits
,
2166 DWORD srcwidth
, DWORD dstwidth
, int left
,
2167 DC
*dc
, XImage
*bmpImage
)
2172 DWORD linebytes
= (srcwidth
* 4);
2177 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2178 linebytes
= -linebytes
;
2181 ptr
= (DWORD
*) srcbits
+ left
;
2183 switch ( bmpImage
->depth
)
2187 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2188 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff) {
2189 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+=linebytes
) {
2190 memcpy( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
, srcbits
+ left
*4, dstwidth
*4 );
2194 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2195 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
2199 for (h
= lines
- 1; h
>= 0; h
--) {
2200 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2201 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2202 *dstpixel
++ = ((*ptr
<< 16) & 0xff0000) | (*ptr
& 0xff00) | ((*ptr
>> 16) & 0xff);
2204 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2207 else goto notsupported
;
2212 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2213 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
2217 for (h
= lines
- 1; h
>= 0; h
--) {
2218 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2219 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2220 *dstpixel
++ = (WORD
) (((*ptr
>> 9) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 3) & 0x001f));
2222 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2225 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2226 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2230 for (h
= lines
- 1; h
>= 0; h
--) {
2231 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2232 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2233 *dstpixel
++ = (WORD
) (((*ptr
<< 7) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 19) & 0x001f));
2235 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2238 else goto notsupported
;
2243 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2244 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2248 for (h
= lines
- 1; h
>= 0; h
--) {
2249 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2250 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2251 *dstpixel
++ = (WORD
) (((*ptr
>> 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 3) & 0x001f));
2253 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2256 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2257 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
2261 for (h
= lines
- 1; h
>= 0; h
--) {
2262 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2263 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2264 *dstpixel
++ = (WORD
) (((*ptr
<< 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 19) & 0x001f));
2266 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2269 else goto notsupported
;
2277 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*4;
2279 for (h
= lines
- 1; h
>= 0; h
--) {
2280 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+= 4)
2281 XPutPixel( bmpImage
, x
, h
,
2282 X11DRV_PALETTE_ToPhysical(dc
, RGB( bits
[2], bits
[1], *bits
)));
2283 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 4;
2290 FIXME("32 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
2296 /***********************************************************************
2297 * X11DRV_DIB_GetImageBits_32
2299 * GetDIBits for an 32-bit deep DIB.
2301 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
2302 DWORD dstwidth
, DWORD srcwidth
,
2303 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
2309 /* align to 32 bit */
2310 DWORD linebytes
= (srcwidth
* 4);
2311 DWORD copybytes
= linebytes
;
2316 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2317 linebytes
= -linebytes
;
2322 switch ( bmpImage
->depth
)
2326 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2327 if ( bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff )
2328 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+=linebytes
)
2329 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, copybytes
);
2331 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2332 else if ( bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000 )
2336 for (h
= lines
- 1; h
>= 0; h
--) {
2337 srcbits
= bmpImage
->data
+ h
* bmpImage
->bytes_per_line
;
2338 for (x
= 0; x
< dstwidth
; x
++, bits
+=4, srcbits
+=2) {
2339 *(bits
+ 2) = *srcbits
++;
2340 *(bits
+ 1) = *srcbits
++;
2343 bits
= (dstbits
+= linebytes
);
2346 else goto notsupported
;
2354 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2355 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
2357 for (h
= lines
- 1; h
>= 0; h
--) {
2358 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2359 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2361 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2362 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2363 *bits
= (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2365 bits
= (dstbits
+= linebytes
);
2368 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2369 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2371 for (h
= lines
- 1; h
>= 0; h
--) {
2372 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2373 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2375 *bits
++ = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07));/*Blue*/
2376 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2377 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2379 bits
= (dstbits
+= linebytes
);
2382 else goto notsupported
;
2391 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2392 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2394 for (h
= lines
- 1; h
>= 0; h
--) {
2395 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2396 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2398 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2399 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2400 *bits
= (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2402 bits
= (dstbits
+= linebytes
);
2405 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2406 else if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2408 for (h
= lines
- 1; h
>= 0; h
--) {
2409 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2410 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2412 *bits
++ = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07));/*Blue*/
2413 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2414 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2416 bits
= (dstbits
+= linebytes
);
2419 else goto notsupported
;
2424 /* ==== monochrome bitmap to 32 BGR dib ==== */
2426 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2427 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2431 for (h
= lines
- 1; h
>= 0; h
--) {
2432 for (x
= 0; x
< dstwidth
; x
++) {
2433 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2434 *bits
++ = val
.peBlue
;
2435 *bits
++ = val
.peGreen
;
2436 *bits
++ = val
.peRed
;
2439 bits
= (dstbits
+= linebytes
);
2442 else goto notsupported
;
2447 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2448 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2453 for (h
= lines
- 1; h
>= 0; h
--) {
2454 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2455 for (x
= 0; x
< dstwidth
; x
++) {
2456 val
= srccolors
[(int)*srcpixel
++];
2457 *bits
++ = val
.peBlue
; /*Blue*/
2458 *bits
++ = val
.peGreen
; /*Green*/
2459 *bits
++ = val
.peRed
; /*Red*/
2462 bits
= (dstbits
+= linebytes
);
2465 else goto notsupported
;
2470 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2471 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2472 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2473 for (h
= lines
- 1; h
>= 0; h
--)
2475 for (x
= 0; x
< dstwidth
; x
++, bits
+= 4)
2477 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2478 bits
[0] = GetBValue(pixel
);
2479 bits
[1] = GetGValue(pixel
);
2480 bits
[2] = GetRValue(pixel
);
2482 bits
= (dstbits
+= linebytes
);
2488 /***********************************************************************
2489 * X11DRV_DIB_SetImageBits
2491 * Transfer the bits to an X image.
2492 * Helper function for SetDIBits() and SetDIBitsToDevice().
2493 * The Xlib critical section must be entered before calling this function.
2495 int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2497 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2500 if ( descr
->dc
&& descr
->dc
->w
.flags
& DC_DIRTY
)
2501 CLIPPING_UpdateGCRegion( descr
->dc
);
2504 bmpImage
= descr
->image
;
2506 bmpImage
= XCreateImage( display
, X11DRV_GetVisual(), descr
->depth
, ZPixmap
, 0, NULL
,
2507 descr
->infoWidth
, lines
, 32, 0 );
2508 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2509 if(bmpImage
->data
== NULL
) {
2510 ERR("Out of memory!");
2511 XDestroyImage( bmpImage
);
2516 /* Transfer the pixels */
2517 switch(descr
->infoBpp
)
2520 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
2521 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
2525 if (descr
->compression
) {
2526 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2527 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2528 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2530 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
2531 descr
->infoWidth
, descr
->width
,
2532 descr
->xSrc
, (int *)(descr
->colorMap
),
2535 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
2536 descr
->infoWidth
, descr
->width
,
2537 descr
->xSrc
, (int*)(descr
->colorMap
),
2541 if (descr
->compression
) {
2542 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2543 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2544 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2545 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
2546 descr
->infoWidth
, descr
->width
,
2547 descr
->xSrc
, (int *)(descr
->colorMap
),
2550 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
2551 descr
->infoWidth
, descr
->width
,
2552 descr
->xSrc
, (int *)(descr
->colorMap
),
2557 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
2558 descr
->infoWidth
, descr
->width
,
2559 descr
->xSrc
, descr
->dc
,
2560 descr
->rMask
, descr
->gMask
, descr
->bMask
,
2564 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
2565 descr
->infoWidth
, descr
->width
,
2566 descr
->xSrc
, descr
->dc
, bmpImage
);
2569 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
2570 descr
->infoWidth
, descr
->width
,
2571 descr
->xSrc
, descr
->dc
,
2575 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2581 XShmPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2582 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2583 descr
->width
, descr
->height
, FALSE
);
2584 XSync( display
, 0 );
2587 XPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2588 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2589 descr
->width
, descr
->height
);
2591 if (!descr
->image
) XDestroyImage( bmpImage
);
2595 /***********************************************************************
2596 * X11DRV_DIB_GetImageBits
2598 * Transfer the bits from an X image.
2599 * The Xlib critical section must be entered before calling this function.
2601 int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2603 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2607 bmpImage
= descr
->image
;
2609 bmpImage
= XCreateImage( display
, X11DRV_GetVisual(), descr
->depth
, ZPixmap
, 0, NULL
,
2610 descr
->infoWidth
, lines
, 32, 0 );
2611 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2612 if(bmpImage
->data
== NULL
) {
2613 ERR("Out of memory!");
2614 XDestroyImage( bmpImage
);
2618 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2619 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2620 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2622 /* Transfer the pixels */
2623 switch(descr
->infoBpp
)
2626 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
2627 descr
->infoWidth
, descr
->width
,
2628 descr
->colorMap
, descr
->palentry
,
2633 if (descr
->compression
)
2634 FIXME("Compression not yet supported!\n");
2636 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
2637 descr
->infoWidth
, descr
->width
,
2638 descr
->colorMap
, descr
->palentry
,
2643 if (descr
->compression
)
2644 FIXME("Compression not yet supported!\n");
2646 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
2647 descr
->infoWidth
, descr
->width
,
2648 descr
->colorMap
, descr
->palentry
,
2653 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
2654 descr
->infoWidth
,descr
->width
,
2655 descr
->palentry
, bmpImage
);
2659 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
2660 descr
->infoWidth
,descr
->width
,
2661 descr
->palentry
, bmpImage
);
2665 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
2666 descr
->infoWidth
, descr
->width
,
2667 descr
->palentry
, bmpImage
);
2671 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2675 if (!descr
->image
) XDestroyImage( bmpImage
);
2679 /*************************************************************************
2680 * X11DRV_SetDIBitsToDevice
2683 INT
X11DRV_SetDIBitsToDevice( DC
*dc
, INT xDest
, INT yDest
, DWORD cx
,
2684 DWORD cy
, INT xSrc
, INT ySrc
,
2685 UINT startscan
, UINT lines
, LPCVOID bits
,
2686 const BITMAPINFO
*info
, UINT coloruse
)
2688 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2689 DWORD width
, oldcy
= cy
;
2691 int height
, tmpheight
;
2692 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
2695 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
2696 &descr
.infoBpp
, &descr
.compression
) == -1)
2699 if (height
< 0) height
= -height
;
2700 if (!lines
|| (startscan
>= height
)) return 0;
2701 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2702 if (ySrc
< startscan
) ySrc
= startscan
;
2703 else if (ySrc
>= startscan
+ lines
) return 0;
2704 if (xSrc
>= width
) return 0;
2705 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
2706 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
2707 if (!cx
|| !cy
) return 0;
2709 X11DRV_SetupGCForText( dc
); /* To have the correct colors */
2710 TSXSetFunction(display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->w
.ROPmode
-1]);
2712 switch (descr
.infoBpp
)
2717 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2718 coloruse
== DIB_PAL_COLORS
? dc
: NULL
, coloruse
,
2719 dc
->w
.bitsPerPixel
, info
, &descr
.nColorMap
);
2720 if (!descr
.colorMap
) return 0;
2721 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2725 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2726 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2727 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2732 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2737 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2738 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2739 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2747 descr
.palentry
= NULL
;
2748 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2749 descr
.infoWidth
= width
;
2750 descr
.depth
= dc
->w
.bitsPerPixel
;
2751 descr
.drawable
= physDev
->drawable
;
2752 descr
.gc
= physDev
->gc
;
2754 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
2756 descr
.xDest
= dc
->w
.DCOrgX
+ XLPTODP( dc
, xDest
);
2757 descr
.yDest
= dc
->w
.DCOrgY
+ YLPTODP( dc
, yDest
) +
2758 (tmpheight
>= 0 ? oldcy
-cy
: 0);
2761 descr
.useShm
= FALSE
;
2763 EnterCriticalSection( &X11DRV_CritSection
);
2764 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
2765 LeaveCriticalSection( &X11DRV_CritSection
);
2767 if (descr
.infoBpp
<= 8)
2768 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2772 /***********************************************************************
2773 * X11DRV_DIB_SetDIBits
2775 INT
X11DRV_DIB_SetDIBits(
2776 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2777 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
,
2778 UINT coloruse
, HBITMAP hbitmap
)
2780 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2781 int height
, tmpheight
;
2786 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
2787 &descr
.infoBpp
, &descr
.compression
) == -1)
2791 if (height
< 0) height
= -height
;
2792 if (!lines
|| (startscan
>= height
))
2795 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2797 switch (descr
.infoBpp
)
2802 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2803 coloruse
== DIB_PAL_COLORS
? descr
.dc
: NULL
, coloruse
,
2804 bmp
->bitmap
.bmBitsPixel
,
2805 info
, &descr
.nColorMap
);
2806 if (!descr
.colorMap
) return 0;
2807 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2811 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2812 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2813 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2818 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2823 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2824 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2825 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2833 if(!bmp
->physBitmap
)
2834 X11DRV_CreateBitmap(hbitmap
);
2838 descr
.palentry
= NULL
;
2839 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2840 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2841 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
2842 descr
.gc
= BITMAP_GC(bmp
);
2846 descr
.yDest
= height
- startscan
- lines
;
2847 descr
.width
= bmp
->bitmap
.bmWidth
;
2848 descr
.height
= lines
;
2849 descr
.useShm
= FALSE
;
2851 EnterCriticalSection( &X11DRV_CritSection
);
2852 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
2853 LeaveCriticalSection( &X11DRV_CritSection
);
2855 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2860 /***********************************************************************
2861 * X11DRV_DIB_GetDIBits
2863 INT
X11DRV_DIB_GetDIBits(
2864 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2865 UINT lines
, LPVOID bits
, BITMAPINFO
*info
,
2866 UINT coloruse
, HBITMAP hbitmap
)
2868 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
2869 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2870 PALETTEOBJ
* palette
;
2872 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
2873 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
2874 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
2877 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->w
.hPalette
, PALETTE_MAGIC
)))
2880 if( lines
> info
->bmiHeader
.biHeight
) lines
= info
->bmiHeader
.biHeight
;
2881 /* Top-down images have a negative biHeight, the scanlines of theses images
2882 * were inverted in X11DRV_DIB_GetImageBits_xx
2883 * To prevent this we simply change the sign of lines
2884 * (the number of scan lines to copy).
2885 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
2887 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
2889 if( startscan
>= bmp
->bitmap
.bmHeight
) return FALSE
;
2891 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
2892 &descr
.infoBpp
, &descr
.compression
) == -1)
2895 switch (descr
.infoBpp
)
2901 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2905 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2906 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2907 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2911 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2912 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2913 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2918 if(!bmp
->physBitmap
)
2919 X11DRV_CreateBitmap(hbitmap
);
2923 descr
.palentry
= palette
->logpalette
.palPalEntry
;
2925 descr
.lines
= lines
;
2926 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2927 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
2928 descr
.gc
= BITMAP_GC(bmp
);
2930 descr
.ySrc
= startscan
;
2933 descr
.width
= bmp
->bitmap
.bmWidth
;
2934 descr
.height
= bmp
->bitmap
.bmHeight
;
2935 descr
.colorMap
= info
->bmiColors
;
2938 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
2940 descr
.useShm
= FALSE
;
2942 EnterCriticalSection( &X11DRV_CritSection
);
2944 descr
.image
= (XImage
*)CALL_LARGE_STACK( X11DRV_BITMAP_GetXImage
, bmp
);
2945 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
2947 LeaveCriticalSection( &X11DRV_CritSection
);
2949 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
2950 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
2951 info
->bmiHeader
.biWidth
,
2952 info
->bmiHeader
.biHeight
,
2953 info
->bmiHeader
.biBitCount
);
2955 info
->bmiHeader
.biCompression
= 0;
2957 GDI_HEAP_UNLOCK( dc
->w
.hPalette
);
2962 /***********************************************************************
2963 * DIB_DoProtectDIBSection
2965 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
2967 DIBSECTION
*dib
= bmp
->dib
;
2968 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
2969 : -dib
->dsBm
.bmHeight
;
2970 INT totalSize
= dib
->dsBmih
.biSizeImage
? dib
->dsBmih
.biSizeImage
2971 : dib
->dsBm
.bmWidthBytes
* effHeight
;
2974 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
2975 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
2978 /***********************************************************************
2979 * X11DRV_DIB_DoUpdateDIBSection
2981 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
2983 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
2984 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2986 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
2987 &descr
.infoBpp
, &descr
.compression
) == -1)
2991 descr
.palentry
= NULL
;
2992 descr
.image
= dib
->image
;
2993 descr
.colorMap
= (RGBQUAD
*)dib
->colorMap
;
2994 descr
.nColorMap
= dib
->nColorMap
;
2995 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
2996 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2998 switch (descr
.infoBpp
)
3004 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3008 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
3009 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
3010 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
3014 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff;
3015 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0xff00;
3016 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0xff0000;
3021 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3022 descr
.gc
= BITMAP_GC(bmp
);
3027 descr
.width
= bmp
->bitmap
.bmWidth
;
3028 descr
.height
= bmp
->bitmap
.bmHeight
;
3029 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
3033 TRACE("Copying from Pixmap to DIB bits\n");
3034 EnterCriticalSection( &X11DRV_CritSection
);
3035 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
3036 LeaveCriticalSection( &X11DRV_CritSection
);
3040 TRACE("Copying from DIB bits to Pixmap\n");
3041 EnterCriticalSection( &X11DRV_CritSection
);
3042 CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
3043 LeaveCriticalSection( &X11DRV_CritSection
);
3047 /***********************************************************************
3048 * X11DRV_DIB_FaultHandler
3050 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
3052 BOOL handled
= FALSE
;
3055 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
3056 if (!bmp
) return FALSE
;
3059 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3061 case X11DRV_DIB_GdiMod
:
3062 TRACE("called in status DIB_GdiMod\n" );
3063 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3064 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3065 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3066 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
3070 case X11DRV_DIB_InSync
:
3071 TRACE("called in status X11DRV_DIB_InSync\n" );
3072 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3073 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_AppMod
;
3077 case X11DRV_DIB_AppMod
:
3078 FIXME("called in status X11DRV_DIB_AppMod: this can't happen!\n" );
3081 case X11DRV_DIB_NoHandler
:
3082 FIXME("called in status DIB_NoHandler: this can't happen!\n" );
3086 GDI_HEAP_UNLOCK( (HBITMAP
)res
);
3090 /***********************************************************************
3091 * X11DRV_DIB_UpdateDIBSection
3093 void X11DRV_DIB_UpdateDIBSection(DC
*dc
, BOOL toDIB
)
3097 /* Ensure this is a Compatible DC that has a DIB section selected */
3100 if (!(dc
->w
.flags
& DC_MEMORY
)) return;
3102 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( dc
->w
.hBitmap
, BITMAP_MAGIC
);
3107 GDI_HEAP_UNLOCK(dc
->w
.hBitmap
);
3113 /* Prepare for access to the DIB by GDI functions */
3115 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3118 case X11DRV_DIB_NoHandler
:
3119 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3122 case X11DRV_DIB_GdiMod
:
3123 TRACE("fromDIB called in status X11DRV_DIB_GdiMod\n" );
3127 case X11DRV_DIB_InSync
:
3128 TRACE("fromDIB called in status X11DRV_DIB_InSync\n" );
3132 case X11DRV_DIB_AppMod
:
3133 TRACE("fromDIB called in status X11DRV_DIB_AppMod\n" );
3134 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3135 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3136 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
3142 /* Acknowledge write access to the DIB by GDI functions */
3144 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3147 case X11DRV_DIB_NoHandler
:
3148 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3151 case X11DRV_DIB_GdiMod
:
3152 TRACE(" toDIB called in status X11DRV_DIB_GdiMod\n" );
3156 case X11DRV_DIB_InSync
:
3157 TRACE(" toDIB called in status X11DRV_DIB_InSync\n" );
3158 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3159 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_GdiMod
;
3162 case X11DRV_DIB_AppMod
:
3163 FIXME(" toDIB called in status X11DRV_DIB_AppMod: "
3164 "this can't happen!\n" );
3169 GDI_HEAP_UNLOCK(dc
->w
.hBitmap
);
3172 /***********************************************************************
3173 * X11DRV_DIB_CreateDIBSection16
3175 HBITMAP16
X11DRV_DIB_CreateDIBSection16(
3176 DC
*dc
, BITMAPINFO
*bmi
, UINT16 usage
,
3177 SEGPTR
*bits
, HANDLE section
,
3178 DWORD offset
, DWORD ovr_pitch
)
3180 HBITMAP res
= X11DRV_DIB_CreateDIBSection(dc
, bmi
, usage
, NULL
,
3181 section
, offset
, ovr_pitch
);
3184 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3185 if ( bmp
&& bmp
->dib
)
3187 DIBSECTION
*dib
= bmp
->dib
;
3188 INT height
= dib
->dsBm
.bmHeight
>= 0 ?
3189 dib
->dsBm
.bmHeight
: -dib
->dsBm
.bmHeight
;
3190 INT size
= dib
->dsBmih
.biSizeImage
?
3191 dib
->dsBmih
.biSizeImage
: dib
->dsBm
.bmWidthBytes
* height
;
3192 if ( dib
->dsBm
.bmBits
)
3194 ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
=
3195 SELECTOR_AllocBlock( dib
->dsBm
.bmBits
, size
,
3196 SEGMENT_DATA
, FALSE
, FALSE
);
3198 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3199 dib
->dsBm
.bmBits
, size
, ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
,
3200 PTR_SEG_OFF_TO_SEGPTR(((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0));
3202 GDI_HEAP_UNLOCK( res
);
3205 *bits
= PTR_SEG_OFF_TO_SEGPTR( ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0 );
3211 /***********************************************************************
3212 * X11DRV_XShmErrorHandler
3215 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
)
3221 /***********************************************************************
3222 * X11DRV_XShmCreateImage
3226 extern BOOL
X11DRV_XShmCreateImage(XImage
** image
, int width
, int height
, int bpp
,
3227 XShmSegmentInfo
* shminfo
)
3229 int (*WineXHandler
)(Display
*, XErrorEvent
*);
3231 *image
= TSXShmCreateImage(display
, X11DRV_GetVisual(), bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
3232 if( *image
!= NULL
)
3234 EnterCriticalSection( &X11DRV_CritSection
);
3235 shminfo
->shmid
= shmget(IPC_PRIVATE
, (*image
)->bytes_per_line
* height
,
3237 if( shminfo
->shmid
!= -1 )
3239 shminfo
->shmaddr
= (*image
)->data
= shmat(shminfo
->shmid
, 0, 0);
3240 if( shminfo
->shmaddr
!= (char*)-1 )
3242 shminfo
->readOnly
= FALSE
;
3243 if( TSXShmAttach( display
, shminfo
) != 0)
3245 /* Reset the error flag */
3247 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
3248 XSync( display
, 0 );
3252 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3254 XSetErrorHandler(WineXHandler
);
3255 LeaveCriticalSection( &X11DRV_CritSection
);
3257 return TRUE
; /* Success! */
3259 /* An error occured */
3261 XSetErrorHandler(WineXHandler
);
3263 shmdt(shminfo
->shmaddr
);
3265 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3268 XDestroyImage(*image
);
3269 LeaveCriticalSection( &X11DRV_CritSection
);
3277 /***********************************************************************
3278 * X11DRV_DIB_CreateDIBSection
3280 HBITMAP
X11DRV_DIB_CreateDIBSection(
3281 DC
*dc
, BITMAPINFO
*bmi
, UINT usage
,
3282 LPVOID
*bits
, HANDLE section
,
3283 DWORD offset
, DWORD ovr_pitch
)
3286 BITMAPOBJ
*bmp
= NULL
;
3287 X11DRV_DIBSECTION
*dib
= NULL
;
3288 int *colorMap
= NULL
;
3291 /* Fill BITMAP32 structure with DIB data */
3292 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
3293 INT effHeight
, totalSize
;
3296 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3297 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
3298 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
3300 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
3302 bm
.bmWidth
= bi
->biWidth
;
3303 bm
.bmHeight
= effHeight
;
3304 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
3305 : DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
3306 bm
.bmPlanes
= bi
->biPlanes
;
3307 bm
.bmBitsPixel
= bi
->biBitCount
;
3310 /* Get storage location for DIB bits */
3311 totalSize
= bi
->biSizeImage
? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
3314 bm
.bmBits
= MapViewOfFile(section
, FILE_MAP_ALL_ACCESS
,
3315 0L, offset
, totalSize
);
3316 else if (ovr_pitch
&& offset
)
3317 bm
.bmBits
= (LPVOID
) offset
;
3320 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
3321 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
3324 /* Create Color Map */
3325 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
3326 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? dc
: NULL
,
3327 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
3329 /* Allocate Memory for DIB and fill structure */
3331 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
3334 dib
->dibSection
.dsBm
= bm
;
3335 dib
->dibSection
.dsBmih
= *bi
;
3337 /* Set dsBitfields values */
3338 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
3340 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
3342 else switch( bi
->biBitCount
)
3345 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
3346 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
3347 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
3351 dib
->dibSection
.dsBitfields
[0] = 0xff;
3352 dib
->dibSection
.dsBitfields
[1] = 0xff00;
3353 dib
->dibSection
.dsBitfields
[2] = 0xff0000;
3357 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff;
3358 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0xff00;
3359 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0xff0000;
3362 dib
->dibSection
.dshSection
= section
;
3363 dib
->dibSection
.dsOffset
= offset
;
3365 dib
->status
= X11DRV_DIB_NoHandler
;
3368 dib
->nColorMap
= nColorMap
;
3369 dib
->colorMap
= colorMap
;
3372 /* Create Device Dependent Bitmap and add DIB pointer */
3375 res
= CreateDIBitmap(dc
->hSelf
, bi
, 0, NULL
, bmi
, usage
);
3378 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3381 bmp
->dib
= (DIBSECTION
*) dib
;
3383 if(!bmp
->physBitmap
)
3384 X11DRV_CreateBitmap(res
);
3392 if (TSXShmQueryExtension(display
) &&
3393 X11DRV_XShmCreateImage( &dib
->image
, bm
.bmWidth
, effHeight
,
3394 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
) )
3396 ; /* Created Image */
3398 XCREATEIMAGE( dib
->image
, bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
3399 dib
->shminfo
.shmid
= -1;
3403 /* Clean up in case of errors */
3404 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
3406 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3407 res
, bmp
, dib
, bm
.bmBits
);
3411 UnmapViewOfFile(bm
.bmBits
), bm
.bmBits
= NULL
;
3413 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
3416 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
3417 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
3418 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
3419 if (res
) { DeleteObject(res
); res
= 0; }
3422 /* Install fault handler, if possible */
3425 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
3427 if (section
|| offset
)
3429 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3430 if (dib
) dib
->status
= X11DRV_DIB_AppMod
;
3434 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3435 if (dib
) dib
->status
= X11DRV_DIB_InSync
;
3440 /* Return BITMAP handle and storage location */
3441 if (res
) GDI_HEAP_UNLOCK(res
);
3442 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
3446 /***********************************************************************
3447 * X11DRV_DIB_DeleteDIBSection
3449 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
3451 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3455 if (dib
->shminfo
.shmid
!= -1)
3457 TSXShmDetach (display
, &(dib
->shminfo
));
3458 XDestroyImage (dib
->image
);
3459 shmdt (dib
->shminfo
.shmaddr
);
3460 dib
->shminfo
.shmid
= -1;
3463 XDestroyImage( dib
->image
);
3467 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
3471 WORD count
= (GET_SEL_LIMIT( dib
->selector
) >> 16) + 1;
3472 SELECTOR_FreeBlock( dib
->selector
, count
);
3477 /**************************************************************************
3478 * X11DRV_DIB_CreateDIBFromPixmap
3480 * Allocates a packed DIB and copies the Pixmap data into it.
3481 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
3483 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
3486 BITMAPOBJ
*pBmp
= NULL
;
3487 HGLOBAL hPackedDIB
= 0;
3489 /* Allocates an HBITMAP which references the Pixmap passed to us */
3490 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
3493 TRACE("\tCould not create bitmap header for Pixmap\n");
3498 * Create a packed DIB from the Pixmap wrapper bitmap created above.
3499 * A packed DIB contains a BITMAPINFO structure followed immediately by
3500 * an optional color palette and the pixel data.
3502 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
3504 /* Get a pointer to the BITMAPOBJ structure */
3505 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3507 /* We can now get rid of the HBITMAP wrapper we created earlier.
3508 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
3512 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
3513 pBmp
->physBitmap
= NULL
;
3519 TRACE("\tReturning packed DIB %x\n", hPackedDIB
);
3524 /**************************************************************************
3525 * X11DRV_DIB_CreatePixmapFromDIB
3527 * Creates a Pixmap from a packed DIB
3529 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
3531 Pixmap pixmap
= None
;
3533 BITMAPOBJ
*pBmp
= NULL
;
3534 LPBYTE pPackedDIB
= NULL
;
3535 LPBITMAPINFO pbmi
= NULL
;
3536 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
3537 LPBYTE pbits
= NULL
;
3539 /* Get a pointer to the packed DIB's data */
3540 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
3541 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
3542 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
3543 pbits
= (LPBYTE
)(pPackedDIB
3544 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
3546 /* Create a DDB from the DIB */
3548 hBmp
= CreateDIBitmap(hdc
,
3555 GlobalUnlock(hPackedDIB
);
3557 TRACE("CreateDIBitmap returned %x\n", hBmp
);
3559 /* Retrieve the internal Pixmap from the DDB */
3561 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3563 pixmap
= (Pixmap
)pBmp
->physBitmap
;
3564 /* clear the physBitmap so that we can steal its pixmap */
3565 pBmp
->physBitmap
= NULL
;
3568 /* Delete the DDB we created earlier now that we have stolen its pixmap */
3571 TRACE("\tReturning Pixmap %ld\n", pixmap
);