2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
13 # ifdef HAVE_SYS_SHM_H
16 # ifdef HAVE_SYS_IPC_H
19 #endif /* defined(HAVE_LIBXXSHM) */
26 #include "debugtools.h"
31 DEFAULT_DEBUG_CHANNEL(bitmap
);
32 DECLARE_DEBUG_CHANNEL(x11drv
);
34 static int ximageDepthTable
[32];
37 static int XShmErrorFlag
= 0;
40 /* This structure holds the arguments for DIB_SetImageBits() */
46 PALETTEENTRY
*palentry
;
67 } X11DRV_DIB_IMAGEBITS_DESCR
;
70 /***********************************************************************
71 * X11DRV_DIB_GetXImageWidthBytes
73 * Return the width of an X image in bytes
75 inline static int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
77 if (!depth
|| depth
> 32) goto error
;
79 if (!ximageDepthTable
[depth
-1])
81 XImage
*testimage
= XCreateImage( gdi_display
, visual
, depth
,
82 ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
85 ximageDepthTable
[depth
-1] = testimage
->bits_per_pixel
;
86 XDestroyImage( testimage
);
88 else ximageDepthTable
[depth
-1] = -1;
90 if (ximageDepthTable
[depth
-1] != -1)
91 return (4 * ((width
* ximageDepthTable
[depth
-1] + 31) / 32));
94 WARN( "(%d): Unsupported depth\n", depth
);
99 /***********************************************************************
100 * X11DRV_DIB_CreateXImage
104 XImage
*X11DRV_DIB_CreateXImage( int width
, int height
, int depth
)
110 width_bytes
= X11DRV_DIB_GetXImageWidthBytes( width
, depth
);
111 image
= XCreateImage( gdi_display
, visual
, depth
, ZPixmap
, 0,
112 calloc( height
, width_bytes
),
113 width
, height
, 32, width_bytes
);
119 /***********************************************************************
120 * X11DRV_DIB_GenColorMap
122 * Fills the color map of a bitmap palette. Should not be called
123 * for a >8-bit deep bitmap.
125 int *X11DRV_DIB_GenColorMap( DC
*dc
, int *colorMapping
,
126 WORD coloruse
, WORD depth
, BOOL quads
,
127 const void *colorPtr
, int start
, int end
)
131 if (coloruse
== DIB_RGB_COLORS
)
135 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
137 if (depth
== 1) /* Monochrome */
138 for (i
= start
; i
< end
; i
++, rgb
++)
139 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
140 rgb
->rgbBlue
> 255*3/2);
142 for (i
= start
; i
< end
; i
++, rgb
++)
143 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbRed
,
149 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
151 if (depth
== 1) /* Monochrome */
152 for (i
= start
; i
< end
; i
++, rgb
++)
153 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
154 rgb
->rgbtBlue
> 255*3/2);
156 for (i
= start
; i
< end
; i
++, rgb
++)
157 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbtRed
,
162 else /* DIB_PAL_COLORS */
165 WORD
* index
= (WORD
*)colorPtr
;
167 for (i
= start
; i
< end
; i
++, index
++)
168 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(*index
) );
170 for (i
= start
; i
< end
; i
++)
171 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(i
) );
178 /***********************************************************************
179 * X11DRV_DIB_BuildColorMap
181 * Build the color map from the bitmap palette. Should not be called
182 * for a >8-bit deep bitmap.
184 int *X11DRV_DIB_BuildColorMap( DC
*dc
, WORD coloruse
, WORD depth
,
185 const BITMAPINFO
*info
, int *nColors
)
189 const void *colorPtr
;
192 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
194 colors
= info
->bmiHeader
.biClrUsed
;
195 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
196 colorPtr
= info
->bmiColors
;
198 else /* assume BITMAPCOREINFO */
200 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
201 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
206 ERR("called with >256 colors!\n");
210 /* just so CopyDIBSection doesn't have to create an identity palette */
211 if (coloruse
== (WORD
)-1) colorPtr
= NULL
;
213 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
214 colors
* sizeof(int) )))
218 return X11DRV_DIB_GenColorMap( dc
, colorMapping
, coloruse
, depth
,
219 isInfo
, colorPtr
, 0, colors
);
223 /***********************************************************************
224 * X11DRV_DIB_MapColor
226 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
, int oldcol
)
230 if ((oldcol
< nPhysMap
) && (physMap
[oldcol
] == phys
))
233 for (color
= 0; color
< nPhysMap
; color
++)
234 if (physMap
[color
] == phys
)
237 WARN("Strange color %08x\n", phys
);
242 /*********************************************************************
243 * X11DRV_DIB_GetNearestIndex
245 * Helper for X11DRV_DIB_GetDIBits.
246 * Returns the nearest colour table index for a given RGB.
247 * Nearest is defined by minimizing the sum of the squares.
249 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
251 INT i
, best
= -1, diff
, bestdiff
= -1;
254 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
255 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
256 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
257 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
260 if(best
== -1 || diff
< bestdiff
) {
268 /***********************************************************************
269 * X11DRV_DIB_SetImageBits_1_Line
271 * Handles a single line of 1 bit data.
273 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth
, int left
, int *colors
,
274 XImage
*bmpImage
, int h
, const BYTE
*bits
)
279 if((extra
= (left
& 7)) != 0) {
286 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
287 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--)
290 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
291 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 6) & 1] );
292 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 5) & 1] );
293 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 4) & 1] );
294 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 3) & 1] );
295 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 2) & 1] );
296 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 1) & 1] );
297 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 1] );
302 case 7: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
303 case 6: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
304 case 5: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
305 case 4: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
306 case 3: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
307 case 2: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
308 case 1: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
312 /***********************************************************************
313 * X11DRV_DIB_SetImageBits_1
315 * SetDIBits for a 1-bit deep DIB.
317 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
318 DWORD srcwidth
, DWORD dstwidth
, int left
,
319 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
324 for (h
= lines
-1; h
>=0; h
--) {
325 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
327 srcbits
+= linebytes
;
331 for (h
= 0; h
< lines
; h
++) {
332 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
334 srcbits
+= linebytes
;
339 /***********************************************************************
340 * X11DRV_DIB_GetImageBits_1
342 * GetDIBits for a 1-bit deep DIB.
344 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
345 DWORD dstwidth
, DWORD srcwidth
,
346 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
347 XImage
*bmpImage
, DWORD linebytes
)
355 dstbits
= dstbits
+ linebytes
* (lines
- 1);
356 linebytes
= -linebytes
;
361 switch(bmpImage
->depth
) {
364 /* ==== monochrome bitmap to monochrome dib ==== */
366 /* ==== 4 colormap bitmap to monochrome dib ==== */
367 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
371 for (h
= lines
- 1; h
>= 0; h
--) {
372 for (x
= 0; x
< dstwidth
; x
++) {
373 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
374 if (!(x
&7)) *bits
= 0;
375 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2,
378 val
.peBlue
) << (7 - (x
& 7)));
379 if ((x
&7)==7) bits
++;
381 bits
= (dstbits
+= linebytes
);
384 else goto notsupported
;
389 /* ==== 8 colormap bitmap to monochrome dib ==== */
390 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
395 for( h
= lines
- 1; h
>= 0; h
-- ) {
396 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
397 for( x
= 0; x
< dstwidth
; x
++ ) {
398 if (!(x
&7)) *bits
= 0;
399 val
= srccolors
[(int)*srcpixel
++];
400 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 2,
403 val
.peBlue
) << (7-(x
&7)) );
404 if ((x
&7)==7) bits
++;
406 bits
= (dstbits
+= linebytes
);
409 else goto notsupported
;
418 /* ==== 555 BGR bitmap to monochrome dib ==== */
419 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
421 for( h
= lines
- 1; h
>= 0; h
--) {
422 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
423 for( x
= 0; x
< dstwidth
; x
++) {
424 if (!(x
&7)) *bits
= 0;
426 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
427 ((val
>> 7) & 0xf8) |
429 ((val
>> 2) & 0xf8) |
431 ((val
<< 3) & 0xf8) |
432 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
433 if ((x
&7)==7) bits
++;
435 bits
= (dstbits
+= linebytes
);
438 /* ==== 555 RGB bitmap to monochrome dib ==== */
439 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
441 for( h
= lines
- 1; h
>= 0; h
--)
443 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
444 for( x
= 0; x
< dstwidth
; x
++) {
445 if (!(x
&1)) *bits
= 0;
447 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
448 ((val
<< 3) & 0xf8) |
450 ((val
>> 2) & 0xf8) |
452 ((val
>> 7) & 0xf8) |
453 ((val
>> 12) & 0x7) ) << (7-(x
&7)) );
454 if ((x
&7)==7) bits
++;
456 bits
= (dstbits
+= linebytes
);
459 else goto notsupported
;
468 /* ==== 565 BGR bitmap to monochrome dib ==== */
469 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
471 for( h
= lines
- 1; h
>= 0; h
--)
473 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
474 for( x
= 0; x
< dstwidth
; x
++) {
475 if (!(x
&7)) *bits
= 0;
477 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
478 ((val
>> 8) & 0xf8) |
480 ((val
>> 3) & 0xfc) |
482 ((val
<< 3) & 0xf8) |
483 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
484 if ((x
&7)==7) bits
++;
486 bits
= (dstbits
+= linebytes
);
489 /* ==== 565 RGB bitmap to monochrome dib ==== */
490 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
492 for( h
= lines
- 1; h
>= 0; h
--)
494 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
495 for( x
= 0; x
< dstwidth
; x
++) {
496 if (!(x
&7)) *bits
= 0;
498 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
499 ((val
<< 3) & 0xf8) |
501 ((val
>> 3) & 0xfc) |
503 ((val
>> 8) & 0xf8) |
504 ((val
>> 13) & 0x7) ) << (7-(x
&7)) );
505 if ((x
&7)==7) bits
++;
507 bits
= (dstbits
+= linebytes
);
510 else goto notsupported
;
519 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
520 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
522 for (h
= lines
- 1; h
>= 0; h
--)
524 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
525 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
526 if (!(x
&7)) *bits
= 0;
527 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << (7-(x
&7)) );
528 if ((x
&7)==7) bits
++;
530 bits
= (dstbits
+= linebytes
);
533 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
534 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
536 for (h
= lines
- 1; h
>= 0; h
--)
538 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
539 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
540 if (!(x
& 7)) *bits
= 0;
541 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << (7-(x
&7)) );
542 if ((x
& 7) == 7) bits
++;
544 bits
= (dstbits
+= linebytes
);
547 else goto notsupported
;
551 default: /* ? bit bmp -> monochrome DIB */
554 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
556 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
557 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
558 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
560 for( h
= lines
- 1; h
>= 0; h
-- ) {
561 for( x
= 0; x
< dstwidth
; x
++ ) {
562 if (!(x
&7)) *bits
= 0;
563 *bits
|= (XGetPixel( bmpImage
, x
, h
) >= white
)
565 if ((x
&7)==7) bits
++;
567 bits
= (dstbits
+= linebytes
);
574 /***********************************************************************
575 * X11DRV_DIB_SetImageBits_4
577 * SetDIBits for a 4-bit deep DIB.
579 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
580 DWORD srcwidth
, DWORD dstwidth
, int left
,
581 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
585 const BYTE
*bits
= srcbits
+ (left
>> 1);
593 for (h
= lines
-1; h
>= 0; h
--) {
594 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
596 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
597 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
599 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
600 srcbits
+= linebytes
;
601 bits
= srcbits
+ (left
>> 1);
605 for (h
= 0; h
< lines
; h
++) {
606 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
608 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
609 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
611 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
612 srcbits
+= linebytes
;
613 bits
= srcbits
+ (left
>> 1);
620 /***********************************************************************
621 * X11DRV_DIB_GetImageBits_4
623 * GetDIBits for a 4-bit deep DIB.
625 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
626 DWORD srcwidth
, DWORD dstwidth
,
627 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
628 XImage
*bmpImage
, DWORD linebytes
)
638 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
639 linebytes
= -linebytes
;
644 switch(bmpImage
->depth
) {
647 /* ==== monochrome bitmap to 4 colormap dib ==== */
649 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
650 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
654 for (h
= lines
-1; h
>= 0; h
--) {
655 for (x
= 0; x
< dstwidth
; x
++) {
656 if (!(x
&1)) *bits
= 0;
657 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
658 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 16,
661 val
.peBlue
) << (4-((x
&1)<<2)));
662 if ((x
&1)==1) bits
++;
664 bits
= (dstbits
+= linebytes
);
667 else goto notsupported
;
672 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
673 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
677 for( h
= lines
- 1; h
>= 0; h
-- ) {
678 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
679 for( x
= 0; x
< dstwidth
; x
++ ) {
680 if (!(x
&1)) *bits
= 0;
681 val
= srccolors
[(int)*srcpixel
++];
682 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 16,
685 val
.peBlue
) << (4*(1-(x
&1))) );
686 if ((x
&1)==1) bits
++;
688 bits
= (dstbits
+= linebytes
);
691 else goto notsupported
;
700 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
701 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
703 for( h
= lines
- 1; h
>= 0; h
--) {
704 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
705 for( x
= 0; x
< dstwidth
; x
++) {
706 if (!(x
&1)) *bits
= 0;
708 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
709 ((val
>> 7) & 0xf8) |
711 ((val
>> 2) & 0xf8) |
713 ((val
<< 3) & 0xf8) |
714 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
715 if ((x
&1)==1) bits
++;
717 bits
= (dstbits
+= linebytes
);
720 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
721 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
723 for( h
= lines
- 1; h
>= 0; h
--)
725 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
726 for( x
= 0; x
< dstwidth
; x
++) {
727 if (!(x
&1)) *bits
= 0;
729 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
730 ((val
<< 3) & 0xf8) |
732 ((val
>> 2) & 0xfc) |
734 ((val
>> 7) & 0xf8) |
735 ((val
>> 12) & 0x7) ) << ((1-(x
&1))<<2) );
736 if ((x
&1)==1) bits
++;
738 bits
= (dstbits
+= linebytes
);
741 else goto notsupported
;
750 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
751 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
753 for( h
= lines
- 1; h
>= 0; h
--)
755 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
756 for( x
= 0; x
< dstwidth
; x
++) {
757 if (!(x
&1)) *bits
= 0;
759 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
760 ((val
>> 8) & 0xf8) |
762 ((val
>> 3) & 0xfc) |
764 ((val
<< 3) & 0xf8) |
765 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
766 if ((x
&1)==1) bits
++;
768 bits
= (dstbits
+= linebytes
);
771 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
772 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
774 for( h
= lines
- 1; h
>= 0; h
--)
776 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
777 for( x
= 0; x
< dstwidth
; x
++) {
778 if (!(x
&1)) *bits
= 0;
780 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
781 ((val
<< 3) & 0xf8) |
783 ((val
>> 3) & 0xfc) |
785 ((val
>> 8) & 0xf8) |
786 ((val
>> 13) & 0x7) ) << ((1-(x
&1))<<2) );
787 if ((x
&1)==1) bits
++;
789 bits
= (dstbits
+= linebytes
);
792 else goto notsupported
;
801 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
802 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
804 for (h
= lines
- 1; h
>= 0; h
--)
806 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
807 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
808 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << 4) |
809 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[6] , srcpixel
[5], srcpixel
[4]);
810 bits
= (dstbits
+= linebytes
);
813 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
814 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
816 for (h
= lines
- 1; h
>= 0; h
--)
818 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
819 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
820 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << 4) |
821 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[4] , srcpixel
[5], srcpixel
[6]);
822 bits
= (dstbits
+= linebytes
);
825 else goto notsupported
;
829 default: /* ? bit bmp -> 4 bit DIB */
831 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
832 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
833 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
834 for (h
= lines
-1; h
>= 0; h
--) {
835 for (x
= 0; x
< dstwidth
-1; x
+= 2)
837 *bits
++ = (X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel( bmpImage
, x
, h
), 0) << 4)
838 | (X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel( bmpImage
, x
+1, h
), 0) & 0x0f);
841 *bits
= (X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel( bmpImage
, x
, h
), 0) << 4);
842 bits
= (dstbits
+= linebytes
);
848 /***********************************************************************
849 * X11DRV_DIB_SetImageBits_RLE4
851 * SetDIBits for a 4-bit deep compressed DIB.
853 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
854 DWORD width
, DWORD dstwidth
,
855 int left
, int *colors
,
858 int x
= 0, c
, length
;
859 const BYTE
*begin
= bits
;
863 while ((int)lines
>= 0) {
865 if (length
) { /* encoded */
873 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>>4]);
881 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
892 case 1: /* eopicture */
898 FIXME_(x11drv
)("x-delta is too large?\n");
904 default: /* absolute */
912 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>> 4]);
920 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
923 if ((bits
- begin
) & 1)
932 /***********************************************************************
933 * X11DRV_DIB_SetImageBits_8
935 * SetDIBits for an 8-bit deep DIB.
937 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
938 DWORD srcwidth
, DWORD dstwidth
, int left
,
939 const int *colors
, XImage
*bmpImage
,
951 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
952 linebytes
= -linebytes
;
955 bits
= srcbits
+ left
;
957 switch (bmpImage
->depth
) {
960 #if defined(__i386__) && defined(__GNUC__)
961 /* Some X servers might have 32 bit/ 16bit deep pixel */
962 if (lines
&& (dstwidth
!=left
) && (bmpImage
->bits_per_pixel
== 16))
964 for (h
= lines
; h
--; ) {
965 int _cl1
,_cl2
; /* temp outputs for asm below */
966 /* Borrowed from DirectDraw */
967 __asm__
__volatile__(
972 " movw (%%edx,%%eax,4),%%ax\n"
976 :"=S" (bits
), "=D" (_cl1
), "=c" (_cl2
)
978 "D" (bmpImage
->data
+h
*bmpImage
->bytes_per_line
+left
*2),
981 :"eax", "cc", "memory"
983 bits
= (srcbits
+= linebytes
) + left
;
990 #if defined(__i386__) && defined(__GNUC__)
991 if (lines
&& (dstwidth
!=left
) && (bmpImage
->bits_per_pixel
== 32))
993 for (h
= lines
; h
--; ) {
994 int _cl1
,_cl2
; /* temp outputs for asm below */
995 /* Borrowed from DirectDraw */
996 __asm__
__volatile__(
1001 " movl (%%edx,%%eax,4),%%eax\n"
1003 " xor %%eax,%%eax\n"
1005 :"=S" (bits
), "=D" (_cl1
), "=c" (_cl2
)
1007 "D" (bmpImage
->data
+h
*bmpImage
->bytes_per_line
+left
*4),
1008 "c" (dstwidth
-left
),
1010 :"eax", "cc", "memory"
1012 bits
= (srcbits
+= linebytes
) + left
;
1019 break; /* use slow generic case below */
1022 for (h
= lines
- 1; h
>= 0; h
--) {
1023 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
1024 color
= colors
[*bits
];
1025 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
1027 bits
= (srcbits
+= linebytes
) + left
;
1031 /***********************************************************************
1032 * X11DRV_DIB_GetImageBits_8
1034 * GetDIBits for an 8-bit deep DIB.
1036 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
1037 DWORD srcwidth
, DWORD dstwidth
,
1038 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1039 XImage
*bmpImage
, DWORD linebytes
)
1048 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1049 linebytes
= -linebytes
;
1056 This condition is true when GetImageBits has been called by UpdateDIBSection.
1057 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
1058 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
1060 if (!srccolors
) goto updatesection
;
1062 switch(bmpImage
->depth
) {
1065 /* ==== monochrome bitmap to 8 colormap dib ==== */
1067 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
1068 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1072 for (h
= lines
- 1; h
>= 0; h
--) {
1073 for (x
= 0; x
< dstwidth
; x
++) {
1074 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
1075 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
1076 val
.peGreen
, val
.peBlue
);
1078 bits
= (dstbits
+= linebytes
);
1081 else goto notsupported
;
1086 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
1087 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1092 for (h
= lines
- 1; h
>= 0; h
--) {
1093 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1094 for (x
= 0; x
< dstwidth
; x
++) {
1095 val
= srccolors
[(int)*srcpixel
++];
1096 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
1097 val
.peGreen
, val
.peBlue
);
1099 bits
= (dstbits
+= linebytes
);
1102 else goto notsupported
;
1111 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1112 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1114 for( h
= lines
- 1; h
>= 0; h
--)
1116 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1117 for( x
= 0; x
< dstwidth
; x
++ )
1120 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1121 ((val
>> 7) & 0xf8) |
1122 ((val
>> 12) & 0x7),
1123 ((val
>> 2) & 0xf8) |
1125 ((val
<< 3) & 0xf8) |
1126 ((val
>> 2) & 0x7) );
1128 bits
= (dstbits
+= linebytes
);
1131 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1132 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1134 for( h
= lines
- 1; h
>= 0; h
--)
1136 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1137 for( x
= 0; x
< dstwidth
; x
++ )
1140 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1141 ((val
<< 3) & 0xf8) |
1143 ((val
>> 2) & 0xf8) |
1145 ((val
>> 7) & 0xf8) |
1146 ((val
>> 12) & 0x7) );
1148 bits
= (dstbits
+= linebytes
);
1151 else goto notsupported
;
1160 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1161 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
1163 for( h
= lines
- 1; h
>= 0; h
--)
1165 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1166 for( x
= 0; x
< dstwidth
; x
++ )
1169 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1170 ((val
>> 8) & 0xf8) |
1171 ((val
>> 13) & 0x7),
1172 ((val
>> 3) & 0xfc) |
1174 ((val
<< 3) & 0xf8) |
1175 ((val
>> 2) & 0x7) );
1177 bits
= (dstbits
+= linebytes
);
1180 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1181 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1183 for( h
= lines
- 1; h
>= 0; h
--)
1185 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1186 for( x
= 0; x
< dstwidth
; x
++ )
1189 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1190 ((val
<< 3) & 0xf8) |
1192 ((val
>> 3) & 0x00fc) |
1194 ((val
>> 8) & 0x00f8) |
1195 ((val
>> 13) & 0x7) );
1197 bits
= (dstbits
+= linebytes
);
1200 else goto notsupported
;
1209 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1210 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1212 for (h
= lines
- 1; h
>= 0; h
--)
1214 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1215 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1216 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1217 srcpixel
[2] , srcpixel
[1], *srcpixel
);
1218 bits
= (dstbits
+= linebytes
);
1221 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1222 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1224 for (h
= lines
- 1; h
>= 0; h
--)
1226 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1227 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1228 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1229 *srcpixel
, srcpixel
[1], srcpixel
[2]);
1230 bits
= (dstbits
+= linebytes
);
1234 else goto notsupported
;
1238 default: /* ? bit bmp -> 8 bit DIB */
1240 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1241 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1242 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1244 for (h
= lines
- 1; h
>= 0; h
--) {
1245 for (x
= 0; x
< dstwidth
; x
++, bits
++) {
1246 *bits
= X11DRV_DIB_MapColor((int *)colors
, 256,
1247 XGetPixel( bmpImage
, x
, h
), *bits
);
1249 bits
= (dstbits
+= linebytes
);
1255 /***********************************************************************
1256 * X11DRV_DIB_SetImageBits_RLE8
1258 * SetDIBits for an 8-bit deep compressed DIB.
1260 * This function rewritten 941113 by James Youngman. WINE blew out when I
1261 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1263 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1264 * 'End of bitmap' escape code. This code is very much laxer in what it
1265 * allows to end the expansion. Possibly too lax. See the note by
1266 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1267 * bitmap should end with RleEnd, but on the other hand, software exists
1268 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1271 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1272 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1276 enum Rle8_EscapeCodes
1279 * Apologies for polluting your file's namespace...
1281 RleEol
= 0, /* End of line */
1282 RleEnd
= 1, /* End of bitmap */
1283 RleDelta
= 2 /* Delta */
1286 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1287 DWORD width
, DWORD dstwidth
,
1288 int left
, int *colors
,
1291 int x
; /* X-positon on each line. Increases. */
1292 int line
; /* Line #. Starts at lines-1, decreases */
1293 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1294 BYTE length
; /* The length pf a run */
1295 BYTE color_index
; /* index into colors[] as read from bits */
1296 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1297 int color
; /* value of colour[color_index] */
1299 if (lines
== 0) /* Let's hope this doesn't happen. */
1303 * Note that the bitmap data is stored by Windows starting at the
1304 * bottom line of the bitmap and going upwards. Within each line,
1305 * the data is stored left-to-right. That's the reason why line
1306 * goes from lines-1 to 0. [JAY]
1316 * If the length byte is not zero (which is the escape value),
1317 * We have a run of length pixels all the same colour. The colour
1318 * index is stored next.
1320 * If the length byte is zero, we need to read the next byte to
1321 * know what to do. [JAY]
1326 * [Run-Length] Encoded mode
1328 color_index
= (*pIn
++); /* Get the colour index. */
1329 color
= colors
[color_index
];
1338 XPutPixel(bmpImage
, x
++, line
, color
);
1344 * Escape codes (may be an absolute sequence though)
1346 escape_code
= (*pIn
++);
1349 case RleEol
: /* =0, end of line */
1356 case RleEnd
: /* =1, end of bitmap */
1359 * Not all RLE8 bitmaps end with this
1360 * code. For example, Paint Shop Pro
1361 * produces some that don't. That's (I think)
1362 * what caused the previous implementation to
1365 line
=-1; /* Cause exit from do loop. */
1369 case RleDelta
: /* =2, a delta */
1372 * Note that deltaing to line 0
1373 * will cause an exit from the loop,
1374 * which may not be what is intended.
1375 * The fact that there is a delta in the bits
1376 * almost certainly implies that there is data
1377 * to follow. You may feel that we should
1378 * jump to the top of the loop to avoid exiting
1381 * TODO: Decide what to do here in that case. [JAY]
1387 TRACE("Delta to last line of bitmap "
1388 "(wrongly?) causes loop exit\n");
1393 default: /* >2, switch to absolute mode */
1398 length
= escape_code
;
1401 color_index
= (*pIn
++);
1407 XPutPixel(bmpImage
, x
++, line
,
1408 colors
[color_index
]);
1412 * If you think for a moment you'll realise that the
1413 * only time we could ever possibly read an odd
1414 * number of bytes is when there is a 0x00 (escape),
1415 * a value >0x02 (absolute mode) and then an odd-
1416 * length run. Therefore this is the only place we
1417 * need to worry about it. Everywhere else the
1418 * bytes are always read in pairs. [JAY]
1420 if (escape_code
& 1)
1421 pIn
++; /* Throw away the pad byte. */
1424 } /* switch (escape_code) : Escape sequence */
1425 } /* process either an encoded sequence or an escape sequence */
1427 /* We expect to come here more than once per line. */
1428 } while (line
>= 0); /* Do this until the bitmap is filled */
1431 * Everybody comes here at the end.
1432 * Check how we exited the loop and print a message if it's a bit odd.
1435 if ( (*(pIn
-2) != 0/*escape*/) || (*(pIn
-1)!= RleEnd
) )
1437 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1438 "bytes were: %02X %02X.\n", (int)*(pIn
-2),(int)*(pIn
-1));
1443 /***********************************************************************
1444 * X11DRV_DIB_SetImageBits_16
1446 * SetDIBits for a 16-bit deep DIB.
1448 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1449 DWORD srcwidth
, DWORD dstwidth
, int left
,
1450 DC
*dc
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1451 XImage
*bmpImage
, DWORD linebytes
)
1459 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1460 linebytes
= -linebytes
;
1463 switch ( bmpImage
->depth
)
1466 /* using same format as XImage */
1467 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1468 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1469 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1470 else /* We need to do a conversion from a 565 dib */
1472 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1474 int div
= dstwidth
% 2;
1476 for (h
= lines
- 1; h
>= 0; h
--) {
1477 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1478 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1480 *dstpixel
++ = ((val
>> 1) & 0x7fe07fe0) | (val
& 0x001f001f); /* Red & Green & Blue */
1482 if (div
!= 0) /* Odd width? */
1483 *dstpixel
= ((*(WORD
*)ptr
>> 1) & 0x7fe0) | (*(WORD
*)ptr
& 0x001f);
1484 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1490 /* using same format as XImage */
1491 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1492 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1493 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1494 else /* We need to do a conversion from a 555 dib */
1496 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1498 int div
= dstwidth
% 2;
1500 for (h
= lines
- 1; h
>= 0; h
--) {
1501 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1502 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1504 *dstpixel
++ = ((val
<< 1) & 0xffc0ffc0) | ((val
>> 4) & 0x00200020) | /* Red & Green */
1505 (val
& 0x001f001f); /* Blue */
1507 if (div
!= 0) /* Odd width? */
1508 *dstpixel
= ((*(WORD
*)ptr
<< 1) & 0xffc0) | ((*(WORD
*)ptr
>> 4) & 0x0020)
1509 | (*(WORD
*)ptr
& 0x001f);
1510 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1519 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1522 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1524 if ((rSrc
== 0xF800) && (gSrc
== 0x07E0) && (bSrc
== 0x001F)) {
1525 /* ==== 555 RGB dib to 24/32 RGB bitmap ==== */
1526 for (h
= lines
- 1; h
>= 0; h
--) {
1527 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1528 for (x
= 0; x
< dstwidth
; x
++) {
1530 *dstpixel
++ = ((val
<< 8) & 0xF80000) | /* Red */
1531 ((val
<< 5) & 0x00FC00) | /* Green */
1532 ((val
<< 3) & 0x0000FF); /* Blue */
1534 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1537 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1538 for (h
= lines
- 1; h
>= 0; h
--) {
1539 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1540 for (x
= 0; x
< dstwidth
; x
++) {
1543 *dstpixel
++ = ((val
<< 9) & 0xf80000) | ((val
<< 4) & 0x070000) | /* Red */
1544 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1545 ((val
<< 3) & 0x0000f8) | ((val
>> 2) & 0x000007); /* Blue */
1547 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1551 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1552 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1554 for (h
= lines
- 1; h
>= 0; h
--) {
1555 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1556 for (x
= 0; x
< dstwidth
; x
++) {
1559 *dstpixel
++ = ((val
>> 7) & 0x0000f8) | ((val
>> 12) & 0x000007) | /* Red */
1560 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1561 ((val
<< 19) & 0xf80000) | ((val
>> 14) & 0x070000); /* Blue */
1563 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1574 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1578 /* Set color scaling values */
1579 if ( rSrc
== 0x7c00 ) { sc1
= 7; sc2
= 2; } /* 555 dib */
1580 else { sc1
= 8; sc2
= 3; } /* 565 dib */
1582 for (h
= lines
- 1; h
>= 0; h
--) {
1583 for (x
= left
; x
< dstwidth
+left
; x
++) {
1585 XPutPixel( bmpImage
, x
, h
,
1586 X11DRV_PALETTE_ToPhysical(dc
, RGB(((val
& rSrc
) >> sc1
), /* Red */
1587 ((val
& gSrc
) >> sc2
), /* Green */
1588 ((val
& bSrc
) << 3)))); /* Blue */
1590 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
1596 FIXME("16 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
1603 /***********************************************************************
1604 * X11DRV_DIB_GetImageBits_16
1606 * GetDIBits for an 16-bit deep DIB.
1608 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
1609 DWORD dstwidth
, DWORD srcwidth
,
1610 PALETTEENTRY
*srccolors
,
1611 DWORD rDst
, DWORD gDst
, DWORD bDst
,
1612 XImage
*bmpImage
, DWORD dibpitch
)
1617 DWORD linebytes
= dibpitch
;
1622 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
1623 linebytes
= -linebytes
;
1626 /* Set color scaling values */
1627 if ( rDst
== 0x7c00 ) { rsc
= 7; gsc
= 2; } /* 555 dib */
1628 else { rsc
= 8; gsc
= 3; } /* 565 dib */
1630 switch ( bmpImage
->depth
)
1633 /* using same format as XImage */
1634 if (rDst
== bmpImage
->red_mask
&& bDst
== bmpImage
->blue_mask
)
1635 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+= linebytes
)
1636 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, srcwidth
*2 );
1637 /* reversed format (BGR <=> RGB) */
1638 else if (rDst
== bmpImage
->blue_mask
&& bDst
== bmpImage
->red_mask
)
1640 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1642 int div
= srcwidth
% 2;
1644 for (h
= lines
- 1; h
>= 0; h
--) {
1645 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1646 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1648 *ptr
++ = ((val
<< 10) & 0xf800f800) | (val
& 0x03e003e0) | /* Red & Green */
1649 ((val
>> 10) & 0x001f001f); /* Blue */
1651 if (div
!= 0) /* Odd width? */
1652 *ptr
= ((*(WORD
*)srcpixel
<< 1) & 0xffc0) | ((*(WORD
*)srcpixel
>> 4) & 0x0020) |
1653 (*(WORD
*)srcpixel
& 0x001f);
1654 ptr
= (LPDWORD
)(dstbits
+= linebytes
);
1657 else goto notsupported
;
1663 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1665 int div
= srcwidth
% 2;
1667 /* using same format as XImage */
1668 if (rDst
== bmpImage
->red_mask
&& bDst
== bmpImage
->blue_mask
)
1669 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+= linebytes
)
1670 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, srcwidth
*2 );
1671 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1672 else if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f &&
1673 rDst
== 0x7c00 && bDst
== 0x001f)
1675 for (h
= lines
- 1; h
>= 0; h
--) {
1676 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1677 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1679 *ptr
++ = ((val
>> 1) & 0x7fe07fe0) | /* Red & Green */
1680 (val
& 0x001f001f); /* Blue */
1682 if (div
!= 0) /* Odd width? */
1683 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1684 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1687 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1688 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800 &&
1689 rDst
== 0x7c00 && bDst
== 0x001f)
1691 for (h
= lines
- 1; h
>= 0; h
--) {
1692 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1693 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1695 *ptr
++ = ((val
<< 10) & 0x7c007c00) | ((val
>> 1) & 0x03e003e0) | /* Red & Green */
1696 ((val
>> 11) & 0x001f001f); /* Blue */
1698 if (div
!= 0) /* Odd width? */
1699 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1700 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1703 else goto notsupported
;
1711 LPWORD ptr
= (LPWORD
)dstbits
;
1714 /* ==== 24/32 BGR bitmap ==== */
1715 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1717 int rsc2
= 16-rsc
, gsc2
= 8-gsc
;
1718 for (h
= lines
- 1; h
>= 0; h
--) {
1719 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1720 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1722 *ptr
= ((val
>> rsc2
) & rDst
) |
1723 ((val
>> gsc2
) & gDst
) |
1724 ((val
>> 3) & bDst
);
1726 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1729 /* ==== 24/32 RGB bitmap ==== */
1730 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1733 for (h
= lines
- 1; h
>= 0; h
--) {
1734 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1735 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1737 *ptr
= ((val
<< rsc
) & rDst
) |
1738 ((val
>> gsc2
) & gDst
) |
1739 ((val
>> 19) & bDst
);
1741 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1744 else goto notsupported
;
1749 /* ==== monochrome bitmap ==== */
1751 /* ==== 4 colormap bitmap ==== */
1752 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1754 LPWORD ptr
= (LPWORD
)dstbits
;
1757 for (h
= lines
- 1; h
>= 0; h
--) {
1758 for (x
= 0; x
< dstwidth
; x
++) {
1759 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
1760 *ptr
++ = ((val
.peRed
<< rsc
) & rDst
) |
1761 ((val
.peGreen
<< gsc
) & gDst
) |
1762 ((val
.peBlue
>> 3) & bDst
);
1764 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1767 else goto notsupported
;
1772 /* ==== 8 colormap bitmap ==== */
1773 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1775 LPWORD ptr
= (LPWORD
)dstbits
;
1779 for (h
= lines
- 1; h
>= 0; h
--) {
1780 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1781 for (x
= 0; x
< dstwidth
; x
++) {
1782 val
= srccolors
[(int)*srcpixel
++];
1783 *ptr
++ = ((val
.peRed
<< rsc
) & rDst
) |
1784 ((val
.peGreen
<< gsc
) & gDst
) |
1785 ((val
.peBlue
>> 3) & bDst
);
1787 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1790 else goto notsupported
;
1798 LPWORD ptr
= (LPWORD
)dstbits
;
1800 FIXME("from %d bit bitmap with mask R,G,B %lx,%lx,%lx to 16 bit DIB %lx,%lx,%lx\n",
1801 bmpImage
->depth
, bmpImage
->red_mask
,
1802 bmpImage
->green_mask
, bmpImage
->blue_mask
,
1805 for (h
= lines
- 1; h
>= 0; h
--)
1807 for (x
= 0; x
< dstwidth
; x
++, ptr
++)
1809 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
1810 r
= (BYTE
) GetRValue(pixel
);
1811 g
= (BYTE
) GetGValue(pixel
);
1812 b
= (BYTE
) GetBValue(pixel
);
1813 *ptr
= ( ((r
<< rsc
) & rDst
) | ((g
<< gsc
) & gDst
) | ((b
>> 3) & bDst
) );
1815 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1823 /***********************************************************************
1824 * X11DRV_DIB_SetImageBits_24
1826 * SetDIBits for a 24-bit deep DIB.
1828 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
1829 DWORD srcwidth
, DWORD dstwidth
, int left
,
1830 DC
*dc
, XImage
*bmpImage
, DWORD linebytes
)
1838 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1839 linebytes
= -linebytes
;
1842 switch ( bmpImage
->depth
)
1846 if (bmpImage
->bits_per_pixel
== 24) {
1847 int dstlinebytes
= linebytes
;
1849 BYTE
*ptr
= (BYTE
*)(srcbits
+left
*3);
1851 if (dstlinebytes
< 0 ) dstlinebytes
= -dstlinebytes
;
1852 dstpixel
= bmpImage
->data
+ lines
*dstlinebytes
+ left
*3;
1853 for(h
= lines
; h
-- ; ) {
1854 dstpixel
-=dstlinebytes
;
1855 memcpy(dstpixel
,ptr
,dstwidth
*3);
1863 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 ) /* packed BGR to unpacked BGR */
1865 DWORD
*dstpixel
, val
, buf
;
1866 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1868 int div
= dstwidth
% 4;
1871 for(h
= lines
- 1; h
>= 0; h
--)
1873 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1875 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1877 *dstpixel
++ = buf
&0x00ffffff; /* b1, g1, r1 */
1878 val
= (buf
>> 24); /* b2 */
1880 *dstpixel
++ = (val
| (buf
<<8)) &0x00ffffff; /* g2, r2 */
1881 val
= (buf
>> 16); /* b3, g3 */
1883 *dstpixel
++ = (val
| (buf
<<16)) &0x00ffffff; /* r3 */
1884 *dstpixel
++ = (buf
>> 8); /* b4, g4, r4 */
1886 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1888 *dstpixel
++ = *(DWORD
*)bits
& 0x00ffffff; /* b, g, r */
1890 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1893 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff ) /* packed BGR to unpacked RGB */
1895 DWORD
*dstpixel
, val
, buf
;
1896 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1898 int div
= dstwidth
% 4;
1901 for(h
= lines
- 1; h
>= 0; h
--)
1903 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1905 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1907 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b1, g1, r1 */
1908 val
= ((buf
&0xff000000)>>8); /* b2 */
1910 *dstpixel
++ = val
| ((buf
&0xff)<<8) | ((buf
&0xff00)>>8); /* g2, r2 */
1911 val
= (buf
&0xff0000) | ((buf
&0xff000000)>>16); /* b3, g3 */
1913 *dstpixel
++ = val
| (buf
&0xff); /* r3 */
1914 *dstpixel
++ = ((buf
&0xff00)<<8) | ((buf
&0xff0000)>>8) | (buf
>>24); /* b4, g4, r4 */
1916 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1918 buf
= *(DWORD
*)bits
;
1919 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b, g, r */
1921 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1931 if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f ) /* BGR888 to RGB555 */
1933 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1936 int div
= dstwidth
% 4;
1939 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1940 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1941 for (x
= 0; x
< dstwidth
/4; x
++, ptr
+= 3) {
1942 *dstpixel
++ = ((ptr
[0] << 7) & 0x7c00) | ((ptr
[0] >> 6) & 0x03e0) | ((ptr
[0] >> 19) & 0x1f);
1943 *dstpixel
++ = ((ptr
[0] >> 17) & 0x7c00) | ((ptr
[1] << 2) & 0x03e0) | ((ptr
[1] >> 11) & 0x1f);
1944 *dstpixel
++ = ((ptr
[1] >> 9) & 0x07c00) | ((ptr
[1] >> 22) & 0x03e0) | ((ptr
[2] >> 3) & 0x1f);
1945 *dstpixel
++ = ((ptr
[2] >> 1) & 0x07c00) | ((ptr
[2] >> 14) & 0x03e0) | ((ptr
[2] >> 27) & 0x1f);
1947 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1948 *dstpixel
++ = (((WORD
)bits
[0] << 7) & 0x07c00) |
1949 (((WORD
)bits
[1] << 2) & 0x03e0) |
1950 (((WORD
)bits
[2] >> 3) & 0x001f);
1951 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1954 else if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 ) /* BGR888 to BGR555 */
1956 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1959 int div
= dstwidth
% 4;
1962 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1963 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1964 for (x
= 0; x
< dstwidth
/4; x
++, ptr
+= 3) {
1965 *dstpixel
++ = ((ptr
[0] >> 3) & 0x1f) | ((ptr
[0] >> 6) & 0x03e0) | ((ptr
[0] >> 9) & 0x7c00);
1966 *dstpixel
++ = ((ptr
[0] >> 27) & 0x1f) | ((ptr
[1] << 2) & 0x03e0) | ((ptr
[1] >> 1) & 0x7c00);
1967 *dstpixel
++ = ((ptr
[1] >> 19) & 0x1f) | ((ptr
[1] >> 22) & 0x03e0) | ((ptr
[2] << 7) & 0x7c00);
1968 *dstpixel
++ = ((ptr
[2] >> 11) & 0x1f) | ((ptr
[2] >> 14) & 0x03e0) | ((ptr
[2] >> 17) & 0x7c00);
1970 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1971 *dstpixel
++ = (((WORD
)bits
[2] << 7) & 0x07c00) |
1972 (((WORD
)bits
[1] << 2) & 0x03e0) |
1973 (((WORD
)bits
[0] >> 3) & 0x001f);
1974 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1984 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1987 int div
= dstwidth
% 4;
1990 if( bmpImage
->blue_mask
== 0x001f && bmpImage
->red_mask
== 0xf800 ) /* BGR888 to BGR565 */
1992 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1993 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1994 for (x
= 0; x
< dstwidth
/4; x
++, ptr
+= 3) {
1995 *dstpixel
++ = ((ptr
[0] >> 3) & 0x1f) | ((ptr
[0] >> 5) & 0x07e0) | ((ptr
[0] >> 8) & 0xf800);
1996 *dstpixel
++ = ((ptr
[0] >> 27) & 0x1f) | ((ptr
[1] << 3) & 0x07e0) | (ptr
[1] & 0xf800);
1997 *dstpixel
++ = ((ptr
[1] >> 19) & 0x1f) | ((ptr
[1] >> 21) & 0x07e0) | ((ptr
[2] << 8) & 0xf800);
1998 *dstpixel
++ = ((ptr
[2] >> 11) & 0x1f) | ((ptr
[2] >> 13) & 0x07e0) | ((ptr
[2] >> 16) & 0xf800);
2000 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
2001 *dstpixel
++ = (((WORD
)bits
[2] << 8) & 0xf800) |
2002 (((WORD
)bits
[1] << 3) & 0x07e0) |
2003 (((WORD
)bits
[0] >> 3) & 0x001f);
2004 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
2007 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x001f ) /* BGR888 to RGB565 */
2009 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
2010 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
2011 for (x
= 0; x
< dstwidth
/4; x
++, ptr
+= 3) {
2012 *dstpixel
++ = ((ptr
[0] << 8) & 0xf800) | ((ptr
[0] >> 5) & 0x07e0) | ((ptr
[0] >> 19) & 0x1f);
2013 *dstpixel
++ = ((ptr
[0] >> 16) & 0xf800) | ((ptr
[1] << 3) & 0x07e0) | ((ptr
[1] >> 11) & 0x1f);
2014 *dstpixel
++ = ((ptr
[1] >> 8) & 0xf800) | ((ptr
[1] >> 21) & 0x07e0) | ((ptr
[2] >> 3) & 0x1f);
2015 *dstpixel
++ = (ptr
[2] & 0xf800) | ((ptr
[2] >> 13) & 0x07e0) | ((ptr
[2] >> 27) & 0x1f);
2017 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
2018 *dstpixel
++ = (((WORD
)bits
[0] << 8) & 0xf800) |
2019 (((WORD
)bits
[1] << 3) & 0x07e0) |
2020 (((WORD
)bits
[2] >> 3) & 0x001f);
2021 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
2033 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*3;
2035 for (h
= lines
- 1; h
>= 0; h
--) {
2036 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+=3)
2037 XPutPixel( bmpImage
, x
, h
,
2038 X11DRV_PALETTE_ToPhysical(dc
, RGB(bits
[2], bits
[1], bits
[0])));
2039 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 3;
2046 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
2047 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
2048 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2054 /***********************************************************************
2055 * X11DRV_DIB_GetImageBits_24
2057 * GetDIBits for an 24-bit deep DIB.
2059 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
2060 DWORD dstwidth
, DWORD srcwidth
,
2061 PALETTEENTRY
*srccolors
,
2062 XImage
*bmpImage
, DWORD linebytes
)
2070 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2071 linebytes
= -linebytes
;
2074 switch ( bmpImage
->depth
)
2078 if (bmpImage
->bits_per_pixel
== 24) {
2079 int tocopy
= linebytes
;
2081 BYTE
*ptr
= (LPBYTE
)dstbits
;
2083 if (tocopy
< 0 ) tocopy
= -tocopy
;
2084 srcpixel
= bmpImage
->data
+ lines
*tocopy
;
2085 for(h
= lines
; h
-- ; ) {
2087 memcpy(ptr
,srcpixel
,tocopy
);
2088 ptr
= (LPBYTE
)(dstbits
+=linebytes
);
2095 DWORD
*srcpixel
, buf
;
2097 DWORD
*ptr
=(DWORD
*)dstbits
;
2098 int quotient
= dstwidth
/ 4;
2099 int remainder
= dstwidth
% 4;
2102 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
2103 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 )
2105 for(h
= lines
- 1; h
>= 0; h
--)
2107 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2109 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time */
2110 buf
= ((*srcpixel
++)&0x00ffffff); /* b1, g1, r1*/
2111 *ptr
++ = buf
| ((*srcpixel
)<<24); /* b2 */
2112 buf
= ((*srcpixel
++>>8)&0x0000ffff); /* g2, r2 */
2113 *ptr
++ = buf
| ((*srcpixel
)<<16); /* b3, g3 */
2114 buf
= ((*srcpixel
++>>16)&0x000000ff); /* r3 */
2115 *ptr
++ = buf
| ((*srcpixel
++)<<8); /* b4, g4, r4 */
2117 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
2120 *(WORD
*)bits
= buf
; /* b, g */
2121 *(bits
+2) = buf
>>16; /* r */
2123 ptr
= (DWORD
*)(dstbits
+=linebytes
);
2127 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
2128 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff )
2130 for(h
= lines
- 1; h
>= 0; h
--)
2132 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2134 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time */
2136 val
= ((buf
&0xff0000)>>16) | (buf
&0xff00) | ((buf
&0xff)<<16); /* b1, g1, r1 */
2138 *ptr
++ = val
| ((buf
&0xff0000)<<8); /* b2 */
2139 val
= ((buf
&0xff00)>>8) | ((buf
&0xff)<<8); /* g2, r2 */
2141 *ptr
++ = val
| (buf
&0xff0000) | ((buf
&0xff00)<<16); /* b3, g3 */
2142 val
= (buf
&0xff); /* r3 */
2144 *ptr
++ = val
| ((buf
&0xff0000)>>8) | ((buf
&0xff00)<<8) | (buf
<<24); /* b4, g4, r4 */
2146 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
2149 *(WORD
*)bits
= (buf
&0xff00) | ((buf
&0xff0000)>>16) ; /* b, g */
2150 *(bits
+2) = buf
; /* r */
2152 ptr
= (DWORD
*)(dstbits
+=linebytes
);
2155 else goto notsupported
;
2162 LPBYTE bits
= dstbits
;
2165 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2166 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 )
2168 for (h
= lines
- 1; h
>= 0; h
--) {
2169 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2170 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2172 bits
[2] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2173 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2174 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2176 bits
= (dstbits
+= linebytes
);
2179 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2180 else if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f )
2182 for (h
= lines
- 1; h
>= 0; h
--) {
2183 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2184 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2186 bits
[0] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2187 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2188 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2190 bits
= (dstbits
+= linebytes
);
2193 else goto notsupported
;
2200 LPBYTE bits
= dstbits
;
2203 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2204 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0xf800 )
2206 for (h
= lines
- 1; h
>= 0; h
--) {
2207 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2208 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2210 bits
[2] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2211 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2212 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2214 bits
= (dstbits
+= linebytes
);
2217 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2218 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x1f )
2220 for (h
= lines
- 1; h
>= 0; h
--) {
2221 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2222 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2224 bits
[0] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2225 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2226 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2228 bits
= (dstbits
+= linebytes
);
2231 else goto notsupported
;
2236 /* ==== monochrome bitmap to 24 BGR dib ==== */
2238 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2239 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2241 LPBYTE bits
= dstbits
;
2244 for (h
= lines
- 1; h
>= 0; h
--) {
2245 for (x
= 0; x
< dstwidth
; x
++) {
2246 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2247 *bits
++ = val
.peBlue
;
2248 *bits
++ = val
.peGreen
;
2249 *bits
++ = val
.peRed
;
2251 bits
= (dstbits
+= linebytes
);
2254 else goto notsupported
;
2259 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2260 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
)
2263 LPBYTE bits
= dstbits
;
2266 for (h
= lines
- 1; h
>= 0; h
--) {
2267 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2268 for (x
= 0; x
< dstwidth
; x
++ ) {
2269 val
= srccolors
[(int)*srcpixel
++];
2270 *bits
++ = val
.peBlue
; /*Blue*/
2271 *bits
++ = val
.peGreen
; /*Green*/
2272 *bits
++ = val
.peRed
; /*Red*/
2274 bits
= (dstbits
+= linebytes
);
2277 else goto notsupported
;
2284 LPBYTE bits
= dstbits
;
2286 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2287 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2288 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2289 for (h
= lines
- 1; h
>= 0; h
--)
2291 for (x
= 0; x
< dstwidth
; x
++, bits
+= 3)
2293 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2294 bits
[0] = GetBValue(pixel
);
2295 bits
[1] = GetGValue(pixel
);
2296 bits
[2] = GetRValue(pixel
);
2298 bits
= (dstbits
+= linebytes
);
2306 /***********************************************************************
2307 * X11DRV_DIB_SetImageBits_32
2309 * SetDIBits for a 32-bit deep DIB.
2311 static void X11DRV_DIB_SetImageBits_32( int lines
, const BYTE
*srcbits
,
2312 DWORD srcwidth
, DWORD dstwidth
, int left
,
2313 DC
*dc
, XImage
*bmpImage
,
2322 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2323 linebytes
= -linebytes
;
2326 ptr
= (DWORD
*) srcbits
+ left
;
2328 switch ( bmpImage
->depth
)
2331 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2332 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff) {
2333 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+=linebytes
) {
2334 memcpy( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
, srcbits
+ left
*4, dstwidth
*4 );
2338 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2339 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
2343 for (h
= lines
- 1; h
>= 0; h
--) {
2344 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2345 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2346 *dstpixel
++ = ((*ptr
<< 16) & 0xff0000) | (*ptr
& 0xff00) | ((*ptr
>> 16) & 0xff);
2348 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2351 else goto notsupported
;
2356 /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
2357 /* we need to check that source mask matches destination */
2358 if (bmpImage
->bits_per_pixel
== 32)
2360 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+=linebytes
) {
2361 memcpy( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
, srcbits
+ left
*4, dstwidth
*4 );
2368 ptr
= (DWORD
*) srcbits
+ left
;
2369 bptr
= bmpImage
->data
;
2371 for (h
= lines
- 1; h
>= 0; h
--) {
2372 for (x
= 0; x
< dstwidth
; x
++) {
2373 /* *ptr is a 32bit value */
2374 /* bptr points to first of 3 bytes */
2375 *bptr
++ = (*ptr
>> 16) & 0xff;
2376 *bptr
++ = (*ptr
>> 8) & 0xff;
2377 *bptr
++ = (*ptr
) & 0xff;
2380 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2386 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2387 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f) {
2390 for (h
= lines
- 1; h
>= 0; h
--) {
2391 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2392 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2393 *dstpixel
++ = (WORD
) (((*ptr
>> 9) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 3) & 0x001f));
2395 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2398 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2399 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2403 for (h
= lines
- 1; h
>= 0; h
--) {
2404 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2405 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2406 *dstpixel
++ = (WORD
) (((*ptr
<< 7) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 19) & 0x001f));
2408 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2411 else goto notsupported
;
2416 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2417 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2421 for (h
= lines
- 1; h
>= 0; h
--) {
2422 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2423 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2424 *dstpixel
++ = (WORD
) (((*ptr
>> 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 3) & 0x001f));
2426 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2429 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2430 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
2434 for (h
= lines
- 1; h
>= 0; h
--) {
2435 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2436 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2437 *dstpixel
++ = (WORD
) (((*ptr
<< 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 19) & 0x001f));
2439 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2442 else goto notsupported
;
2450 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*4;
2452 for (h
= lines
- 1; h
>= 0; h
--) {
2453 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+= 4)
2454 XPutPixel( bmpImage
, x
, h
,
2455 X11DRV_PALETTE_ToPhysical(dc
, RGB( bits
[2], bits
[1], *bits
)));
2456 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 4;
2463 FIXME("32 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
2469 /***********************************************************************
2470 * X11DRV_DIB_GetImageBits_32
2472 * GetDIBits for an 32-bit deep DIB.
2474 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
2475 DWORD dstwidth
, DWORD srcwidth
,
2476 PALETTEENTRY
*srccolors
,
2477 XImage
*bmpImage
, DWORD linebytes
)
2483 DWORD copybytes
= srcwidth
* 4;
2488 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2489 linebytes
= -linebytes
;
2494 switch ( bmpImage
->depth
)
2497 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2498 if ( bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff )
2499 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+=linebytes
)
2500 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, copybytes
);
2502 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2503 else if ( bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000 )
2507 for (h
= lines
- 1; h
>= 0; h
--) {
2508 srcbits
= bmpImage
->data
+ h
* bmpImage
->bytes_per_line
;
2509 for (x
= 0; x
< dstwidth
; x
++, bits
+=4, srcbits
+=2) {
2510 *(bits
+ 2) = *srcbits
++;
2511 *(bits
+ 1) = *srcbits
++;
2514 bits
= (dstbits
+= linebytes
);
2517 else goto notsupported
;
2521 /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */
2522 /* we need to check that source mask matches destination */
2528 srcpixel
= (DWORD
*) dstbits
;
2529 bptr
= bmpImage
->data
;
2531 for (h
= lines
- 1; h
>= 0; h
--) {
2532 for (x
= 0; x
< dstwidth
; x
++) {
2533 /* *srcpixel is a 32bit value */
2534 /* bptr points to first of 3 bytes */
2536 srcdata
= srcdata
<< 8 | *bptr
++;
2537 srcdata
= srcdata
<< 8 | *bptr
++;
2538 srcdata
= srcdata
<< 8 | *bptr
++;
2540 *srcpixel
++ = srcdata
;
2542 srcpixel
= (DWORD
*) (dstbits
+= linebytes
);
2552 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2553 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
2555 for (h
= lines
- 1; h
>= 0; h
--) {
2556 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2557 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2559 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2560 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2561 *bits
= (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2563 bits
= (dstbits
+= linebytes
);
2566 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2567 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2569 for (h
= lines
- 1; h
>= 0; h
--) {
2570 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2571 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2573 *bits
++ = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07));/*Blue*/
2574 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2575 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2577 bits
= (dstbits
+= linebytes
);
2580 else goto notsupported
;
2589 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2590 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2592 for (h
= lines
- 1; h
>= 0; h
--) {
2593 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2594 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2596 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2597 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2598 *bits
= (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2600 bits
= (dstbits
+= linebytes
);
2603 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2604 else if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2606 for (h
= lines
- 1; h
>= 0; h
--) {
2607 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2608 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2610 *bits
++ = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07));/*Blue*/
2611 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2612 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2614 bits
= (dstbits
+= linebytes
);
2617 else goto notsupported
;
2622 /* ==== monochrome bitmap to 32 BGR dib ==== */
2624 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2625 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2629 for (h
= lines
- 1; h
>= 0; h
--) {
2630 for (x
= 0; x
< dstwidth
; x
++) {
2631 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2632 *bits
++ = val
.peBlue
;
2633 *bits
++ = val
.peGreen
;
2634 *bits
++ = val
.peRed
;
2637 bits
= (dstbits
+= linebytes
);
2640 else goto notsupported
;
2645 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2646 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2651 for (h
= lines
- 1; h
>= 0; h
--) {
2652 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2653 for (x
= 0; x
< dstwidth
; x
++) {
2654 val
= srccolors
[(int)*srcpixel
++];
2655 *bits
++ = val
.peBlue
; /*Blue*/
2656 *bits
++ = val
.peGreen
; /*Green*/
2657 *bits
++ = val
.peRed
; /*Red*/
2660 bits
= (dstbits
+= linebytes
);
2663 else goto notsupported
;
2668 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2669 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2670 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2671 for (h
= lines
- 1; h
>= 0; h
--)
2673 for (x
= 0; x
< dstwidth
; x
++, bits
+= 4)
2675 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2676 bits
[0] = GetBValue(pixel
);
2677 bits
[1] = GetGValue(pixel
);
2678 bits
[2] = GetRValue(pixel
);
2680 bits
= (dstbits
+= linebytes
);
2686 /***********************************************************************
2687 * X11DRV_DIB_SetImageBits
2689 * Transfer the bits to an X image.
2690 * Helper function for SetDIBits() and SetDIBitsToDevice().
2692 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2694 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2699 bmpImage
= descr
->image
;
2701 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
2702 descr
->infoWidth
, lines
, 32, 0 );
2703 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2704 if(bmpImage
->data
== NULL
) {
2705 ERR("Out of memory!\n");
2706 XDestroyImage( bmpImage
);
2707 wine_tsx11_unlock();
2712 /* Transfer the pixels */
2713 switch(descr
->infoBpp
)
2716 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
2717 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
2718 bmpImage
, descr
->dibpitch
);
2721 if (descr
->compression
) {
2722 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2723 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2724 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2726 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
2727 descr
->infoWidth
, descr
->width
,
2728 descr
->xSrc
, (int *)(descr
->colorMap
),
2731 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
2732 descr
->infoWidth
, descr
->width
,
2733 descr
->xSrc
, (int*)(descr
->colorMap
),
2734 bmpImage
, descr
->dibpitch
);
2737 if (descr
->compression
) {
2738 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2739 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2740 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2741 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
2742 descr
->infoWidth
, descr
->width
,
2743 descr
->xSrc
, (int *)(descr
->colorMap
),
2746 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
2747 descr
->infoWidth
, descr
->width
,
2748 descr
->xSrc
, (int *)(descr
->colorMap
),
2749 bmpImage
, descr
->dibpitch
);
2753 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
2754 descr
->infoWidth
, descr
->width
,
2755 descr
->xSrc
, descr
->dc
,
2756 descr
->rMask
, descr
->gMask
, descr
->bMask
,
2757 bmpImage
, descr
->dibpitch
);
2760 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
2761 descr
->infoWidth
, descr
->width
,
2762 descr
->xSrc
, descr
->dc
, bmpImage
,
2766 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
2767 descr
->infoWidth
, descr
->width
,
2768 descr
->xSrc
, descr
->dc
,
2769 bmpImage
, descr
->dibpitch
);
2772 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2776 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
2777 descr
->drawable
, descr
->gc
, bmpImage
,
2778 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2779 descr
->width
, descr
->height
);
2780 #ifdef HAVE_LIBXXSHM
2783 XShmPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
2784 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2785 descr
->width
, descr
->height
, FALSE
);
2786 XSync( gdi_display
, 0 );
2790 XPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
2791 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2792 descr
->width
, descr
->height
);
2794 if (!descr
->image
) XDestroyImage( bmpImage
);
2795 wine_tsx11_unlock();
2799 /***********************************************************************
2800 * X11DRV_DIB_GetImageBits
2802 * Transfer the bits from an X image.
2804 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2806 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2811 bmpImage
= descr
->image
;
2813 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
2814 descr
->infoWidth
, lines
, 32, 0 );
2815 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2816 if(bmpImage
->data
== NULL
) {
2817 ERR("Out of memory!\n");
2818 XDestroyImage( bmpImage
);
2819 wine_tsx11_unlock();
2824 TRACE("XGetSubImage(%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
2825 descr
->drawable
, descr
->xSrc
, descr
->ySrc
, descr
->width
,
2826 lines
, AllPlanes
, ZPixmap
, bmpImage
, descr
->xDest
, descr
->yDest
);
2827 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
2828 descr
->width
, lines
, AllPlanes
, ZPixmap
,
2829 bmpImage
, descr
->xDest
, descr
->yDest
);
2831 /* Transfer the pixels */
2832 switch(descr
->infoBpp
)
2835 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
2836 descr
->infoWidth
, descr
->width
,
2837 descr
->colorMap
, descr
->palentry
,
2838 bmpImage
, descr
->dibpitch
);
2842 if (descr
->compression
)
2843 FIXME("Compression not yet supported!\n");
2845 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
2846 descr
->infoWidth
, descr
->width
,
2847 descr
->colorMap
, descr
->palentry
,
2848 bmpImage
, descr
->dibpitch
);
2852 if (descr
->compression
)
2853 FIXME("Compression not yet supported!\n");
2855 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
2856 descr
->infoWidth
, descr
->width
,
2857 descr
->colorMap
, descr
->palentry
,
2858 bmpImage
, descr
->dibpitch
);
2862 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
2863 descr
->infoWidth
,descr
->width
,
2865 descr
->rMask
, descr
->gMask
, descr
->bMask
,
2866 bmpImage
, descr
->dibpitch
);
2870 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
2871 descr
->infoWidth
,descr
->width
,
2872 descr
->palentry
, bmpImage
, descr
->dibpitch
);
2876 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
2877 descr
->infoWidth
, descr
->width
,
2878 descr
->palentry
, bmpImage
, descr
->dibpitch
);
2882 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2886 if (!descr
->image
) XDestroyImage( bmpImage
);
2887 wine_tsx11_unlock();
2891 /*************************************************************************
2892 * X11DRV_SetDIBitsToDevice
2895 INT
X11DRV_SetDIBitsToDevice( DC
*dc
, INT xDest
, INT yDest
, DWORD cx
,
2896 DWORD cy
, INT xSrc
, INT ySrc
,
2897 UINT startscan
, UINT lines
, LPCVOID bits
,
2898 const BITMAPINFO
*info
, UINT coloruse
)
2900 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2901 DWORD width
, oldcy
= cy
;
2903 int height
, tmpheight
;
2904 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
2907 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
2908 &descr
.infoBpp
, &descr
.compression
) == -1)
2911 if (height
< 0) height
= -height
;
2912 if (!lines
|| (startscan
>= height
)) return 0;
2913 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2914 if (ySrc
< startscan
) ySrc
= startscan
;
2915 else if (ySrc
>= startscan
+ lines
) return 0;
2916 if (xSrc
>= width
) return 0;
2917 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
2918 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
2919 if (!cx
|| !cy
) return 0;
2921 X11DRV_SetupGCForText( dc
); /* To have the correct colors */
2922 TSXSetFunction(gdi_display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->ROPmode
-1]);
2924 switch (descr
.infoBpp
)
2929 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2930 coloruse
== DIB_PAL_COLORS
? dc
: NULL
, coloruse
,
2931 dc
->bitsPerPixel
, info
, &descr
.nColorMap
);
2932 if (!descr
.colorMap
) return 0;
2933 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2937 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2938 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2939 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2944 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2949 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2950 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2951 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2959 descr
.palentry
= NULL
;
2960 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2961 descr
.infoWidth
= width
;
2962 descr
.depth
= dc
->bitsPerPixel
;
2963 descr
.drawable
= physDev
->drawable
;
2964 descr
.gc
= physDev
->gc
;
2966 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
2968 descr
.xDest
= dc
->DCOrgX
+ XLPTODP( dc
, xDest
);
2969 descr
.yDest
= dc
->DCOrgY
+ YLPTODP( dc
, yDest
) +
2970 (tmpheight
>= 0 ? oldcy
-cy
: 0);
2973 descr
.useShm
= FALSE
;
2974 descr
.dibpitch
= ((width
* descr
.infoBpp
+ 31) &~31) / 8;
2976 result
= X11DRV_DIB_SetImageBits( &descr
);
2978 if (descr
.infoBpp
<= 8)
2979 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2983 /***********************************************************************
2984 * X11DRV_DIB_SetDIBits
2986 INT
X11DRV_DIB_SetDIBits(
2987 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2988 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
,
2989 UINT coloruse
, HBITMAP hbitmap
)
2991 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2992 int height
, tmpheight
;
2997 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
2998 &descr
.infoBpp
, &descr
.compression
) == -1)
3002 if (height
< 0) height
= -height
;
3003 if (!lines
|| (startscan
>= height
))
3006 if (startscan
+ lines
> height
) lines
= height
- startscan
;
3008 switch (descr
.infoBpp
)
3013 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
3014 coloruse
== DIB_PAL_COLORS
? descr
.dc
: NULL
, coloruse
,
3015 bmp
->bitmap
.bmBitsPixel
,
3016 info
, &descr
.nColorMap
);
3017 if (!descr
.colorMap
) return 0;
3018 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3022 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3023 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3024 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3029 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3034 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3035 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
3036 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
3044 if(!bmp
->physBitmap
)
3045 X11DRV_CreateBitmap(hbitmap
);
3049 descr
.palentry
= NULL
;
3050 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
3051 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3052 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3053 descr
.gc
= BITMAP_GC(bmp
);
3057 descr
.yDest
= height
- startscan
- lines
;
3058 descr
.width
= bmp
->bitmap
.bmWidth
;
3059 descr
.height
= lines
;
3060 descr
.useShm
= FALSE
;
3061 descr
.dibpitch
= ((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8;
3062 result
= X11DRV_DIB_SetImageBits( &descr
);
3064 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
3069 /***********************************************************************
3070 * X11DRV_DIB_GetDIBits
3072 INT
X11DRV_DIB_GetDIBits(
3073 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
3074 UINT lines
, LPVOID bits
, BITMAPINFO
*info
,
3075 UINT coloruse
, HBITMAP hbitmap
)
3077 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3078 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3079 PALETTEOBJ
* palette
;
3082 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3083 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
3084 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
3087 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->hPalette
, PALETTE_MAGIC
)))
3090 if( lines
> bmp
->bitmap
.bmHeight
) lines
= bmp
->bitmap
.bmHeight
;
3092 height
= info
->bmiHeader
.biHeight
;
3093 if (height
< 0) height
= -height
;
3094 if( lines
> height
) lines
= height
;
3095 /* Top-down images have a negative biHeight, the scanlines of theses images
3096 * were inverted in X11DRV_DIB_GetImageBits_xx
3097 * To prevent this we simply change the sign of lines
3098 * (the number of scan lines to copy).
3099 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3101 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
3103 if( startscan
>= bmp
->bitmap
.bmHeight
)
3109 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
3110 &descr
.infoBpp
, &descr
.compression
) == -1)
3116 switch (descr
.infoBpp
)
3122 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3126 descr
.rMask
= 0x7c00;
3127 descr
.gMask
= 0x03e0;
3128 descr
.bMask
= 0x001f;
3132 descr
.rMask
= 0xff0000;
3133 descr
.gMask
= 0xff00;
3139 if(!bmp
->physBitmap
)
3140 X11DRV_CreateBitmap(hbitmap
);
3144 descr
.palentry
= palette
->logpalette
.palPalEntry
;
3147 descr
.lines
= lines
;
3148 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3149 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3150 descr
.gc
= BITMAP_GC(bmp
);
3151 descr
.width
= bmp
->bitmap
.bmWidth
;
3152 descr
.height
= bmp
->bitmap
.bmHeight
;
3153 descr
.colorMap
= info
->bmiColors
;
3158 if (descr
.lines
> 0)
3160 descr
.ySrc
= (descr
.height
-1) - (startscan
+ (lines
-1));
3164 descr
.ySrc
= startscan
;
3166 #ifdef HAVE_LIBXXSHM
3167 descr
.useShm
= dib
? (dib
->shminfo
.shmid
!= -1) : FALSE
;
3169 descr
.useShm
= FALSE
;
3171 descr
.dibpitch
= dib
? (dib
->dibSection
.dsBm
.bmWidthBytes
)
3172 : (((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8);
3174 X11DRV_DIB_GetImageBits( &descr
);
3176 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
3177 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
3178 info
->bmiHeader
.biWidth
,
3179 info
->bmiHeader
.biHeight
,
3180 info
->bmiHeader
.biBitCount
);
3182 info
->bmiHeader
.biCompression
= 0;
3183 if (descr
.compression
== BI_BITFIELDS
)
3185 *(DWORD
*)info
->bmiColors
= descr
.rMask
;
3186 *((DWORD
*)info
->bmiColors
+1) = descr
.gMask
;
3187 *((DWORD
*)info
->bmiColors
+2) = descr
.bMask
;
3191 GDI_ReleaseObj( dc
->hPalette
);
3196 /***********************************************************************
3197 * DIB_DoProtectDIBSection
3199 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
3201 DIBSECTION
*dib
= bmp
->dib
;
3202 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
3203 : -dib
->dsBm
.bmHeight
;
3204 /* use the biSizeImage data as the memory size only if we're dealing with a
3205 compressed image where the value is set. Otherwise, calculate based on
3207 INT totalSize
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
3208 ? dib
->dsBmih
.biSizeImage
3209 : dib
->dsBm
.bmWidthBytes
* effHeight
;
3212 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
3213 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
3216 /***********************************************************************
3217 * X11DRV_DIB_DoUpdateDIBSection
3219 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
,
3220 void *colorMap
, int nColorMap
,
3222 DWORD xSrc
, DWORD ySrc
,
3223 DWORD xDest
, DWORD yDest
,
3224 DWORD width
, DWORD height
)
3226 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3227 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3229 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
3230 &descr
.infoBpp
, &descr
.compression
) == -1)
3234 descr
.palentry
= NULL
;
3235 descr
.image
= dib
->image
;
3236 descr
.colorMap
= colorMap
;
3237 descr
.nColorMap
= nColorMap
;
3238 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
3239 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3241 switch (descr
.infoBpp
)
3247 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3251 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
3252 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
3253 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
3257 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff;
3258 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0xff00;
3259 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0xff0000;
3264 descr
.drawable
= dest
;
3265 descr
.gc
= BITMAP_GC(bmp
);
3268 descr
.xDest
= xDest
;
3269 descr
.yDest
= yDest
;
3270 descr
.width
= width
;
3271 descr
.height
= height
;
3272 #ifdef HAVE_LIBXXSHM
3273 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
3275 descr
.useShm
= FALSE
;
3277 descr
.dibpitch
= dib
->dibSection
.dsBm
.bmWidthBytes
;
3281 TRACE("Copying from Pixmap to DIB bits\n");
3282 X11DRV_DIB_GetImageBits( &descr
);
3286 TRACE("Copying from DIB bits to Pixmap\n");
3287 X11DRV_DIB_SetImageBits( &descr
);
3291 /***********************************************************************
3292 * X11DRV_DIB_CopyDIBSection
3294 void X11DRV_DIB_CopyDIBSection(DC
*dcSrc
, DC
*dcDst
,
3295 DWORD xSrc
, DWORD ySrc
,
3296 DWORD xDest
, DWORD yDest
,
3297 DWORD width
, DWORD height
)
3300 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dcDst
->physDev
;
3301 int nColorMap
= 0, *colorMap
= NULL
, aColorMap
= FALSE
;
3303 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc
, dcDst
,
3304 xSrc
, ySrc
, xDest
, yDest
, width
, height
);
3305 /* this function is meant as an optimization for BitBlt,
3306 * not to be called otherwise */
3307 if (!(dcSrc
->flags
& DC_MEMORY
)) {
3308 ERR("called for non-memory source DC!?\n");
3312 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( dcSrc
->hBitmap
, BITMAP_MAGIC
);
3313 if (!(bmp
&& bmp
->dib
)) {
3314 ERR("called for non-DIBSection!?\n");
3315 GDI_ReleaseObj( dcSrc
->hBitmap
);
3318 /* while BitBlt should already have made sure we only get
3319 * positive values, we should check for oversize values */
3320 if ((xSrc
< bmp
->bitmap
.bmWidth
) &&
3321 (ySrc
< bmp
->bitmap
.bmHeight
)) {
3322 if (xSrc
+ width
> bmp
->bitmap
.bmWidth
)
3323 width
= bmp
->bitmap
.bmWidth
- xSrc
;
3324 if (ySrc
+ height
> bmp
->bitmap
.bmHeight
)
3325 height
= bmp
->bitmap
.bmHeight
- ySrc
;
3326 /* if the source bitmap is 8bpp or less, we're supposed to use the
3327 * DC's palette for color conversion (not the DIB color table) */
3328 if (bmp
->dib
->dsBm
.bmBitsPixel
<= 8) {
3329 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3330 if ((!dcSrc
->hPalette
) ||
3331 (dcSrc
->hPalette
== GetStockObject(DEFAULT_PALETTE
))) {
3332 /* HACK: no palette has been set in the source DC,
3333 * use the DIB colormap instead - this is necessary in some
3334 * cases since we need to do depth conversion in some places
3335 * where real Windows can just copy data straight over */
3336 colorMap
= dib
->colorMap
;
3337 nColorMap
= dib
->nColorMap
;
3339 colorMap
= X11DRV_DIB_BuildColorMap( dcSrc
, (WORD
)-1,
3340 bmp
->dib
->dsBm
.bmBitsPixel
,
3341 (BITMAPINFO
*)&(bmp
->dib
->dsBmih
),
3343 if (colorMap
) aColorMap
= TRUE
;
3346 /* perform the copy */
3347 X11DRV_DIB_DoCopyDIBSection(bmp
, FALSE
, colorMap
, nColorMap
,
3348 physDev
->drawable
, xSrc
, ySrc
, xDest
, yDest
,
3350 /* free color mapping */
3352 HeapFree(GetProcessHeap(), 0, colorMap
);
3354 GDI_ReleaseObj( dcSrc
->hBitmap
);
3357 /***********************************************************************
3358 * X11DRV_DIB_DoUpdateDIBSection
3360 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
3362 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3363 X11DRV_DIB_DoCopyDIBSection(bmp
, toDIB
, dib
->colorMap
, dib
->nColorMap
,
3364 (Drawable
)bmp
->physBitmap
, 0, 0, 0, 0,
3365 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
3368 /***********************************************************************
3369 * X11DRV_DIB_FaultHandler
3371 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
3376 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
3377 if (!bmp
) return FALSE
;
3379 state
= X11DRV_DIB_Lock(bmp
, DIB_Status_None
, FALSE
);
3380 if (state
!= DIB_Status_InSync
) {
3381 /* no way to tell whether app needs read or write yet,
3383 X11DRV_DIB_Coerce(bmp
, DIB_Status_InSync
, FALSE
);
3385 /* hm, apparently the app must have write access */
3386 X11DRV_DIB_Coerce(bmp
, DIB_Status_AppMod
, FALSE
);
3388 X11DRV_DIB_Unlock(bmp
, TRUE
);
3390 GDI_ReleaseObj( (HBITMAP
)res
);
3394 /***********************************************************************
3397 INT
X11DRV_DIB_Coerce(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
3399 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3400 INT ret
= DIB_Status_None
;
3403 EnterCriticalSection(&(dib
->lock
));
3406 case DIB_Status_GdiMod
:
3407 /* GDI access - request to draw on pixmap */
3408 switch (dib
->status
)
3411 case DIB_Status_None
:
3412 dib
->p_status
= DIB_Status_GdiMod
;
3413 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3416 case DIB_Status_GdiMod
:
3417 TRACE("GdiMod requested in status GdiMod\n" );
3420 case DIB_Status_InSync
:
3421 TRACE("GdiMod requested in status InSync\n" );
3422 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3423 dib
->status
= DIB_Status_GdiMod
;
3424 dib
->p_status
= DIB_Status_InSync
;
3427 case DIB_Status_AuxMod
:
3428 TRACE("GdiMod requested in status AuxMod\n" );
3429 if (lossy
) dib
->status
= DIB_Status_GdiMod
;
3430 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_GdiMod
);
3431 dib
->p_status
= DIB_Status_AuxMod
;
3432 if (dib
->status
!= DIB_Status_AppMod
) {
3433 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3436 /* fall through if copy_aux() had to change to AppMod state */
3438 case DIB_Status_AppMod
:
3439 TRACE("GdiMod requested in status AppMod\n" );
3441 /* make it readonly to avoid app changing data while we copy */
3442 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3443 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3445 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3446 dib
->p_status
= DIB_Status_AppMod
;
3447 dib
->status
= DIB_Status_GdiMod
;
3452 case DIB_Status_InSync
:
3453 /* App access - request access to read DIB surface */
3454 /* (typically called from signal handler) */
3455 switch (dib
->status
)
3458 case DIB_Status_None
:
3459 /* shouldn't happen from signal handler */
3462 case DIB_Status_AuxMod
:
3463 TRACE("InSync requested in status AuxMod\n" );
3464 if (lossy
) dib
->status
= DIB_Status_InSync
;
3466 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3467 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_InSync
);
3469 if (dib
->status
!= DIB_Status_GdiMod
) {
3470 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3473 /* fall through if copy_aux() had to change to GdiMod state */
3475 case DIB_Status_GdiMod
:
3476 TRACE("InSync requested in status GdiMod\n" );
3478 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3479 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3481 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3482 dib
->status
= DIB_Status_InSync
;
3485 case DIB_Status_InSync
:
3486 TRACE("InSync requested in status InSync\n" );
3487 /* shouldn't happen from signal handler */
3490 case DIB_Status_AppMod
:
3491 TRACE("InSync requested in status AppMod\n" );
3492 /* no reason to do anything here, and this
3493 * shouldn't happen from signal handler */
3498 case DIB_Status_AppMod
:
3499 /* App access - request access to write DIB surface */
3500 /* (typically called from signal handler) */
3501 switch (dib
->status
)
3504 case DIB_Status_None
:
3505 /* shouldn't happen from signal handler */
3508 case DIB_Status_AuxMod
:
3509 TRACE("AppMod requested in status AuxMod\n" );
3510 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3511 if (lossy
) dib
->status
= DIB_Status_AppMod
;
3512 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
3513 if (dib
->status
!= DIB_Status_GdiMod
)
3515 /* fall through if copy_aux() had to change to GdiMod state */
3517 case DIB_Status_GdiMod
:
3518 TRACE("AppMod requested in status GdiMod\n" );
3519 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3520 if (!lossy
) X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3521 dib
->status
= DIB_Status_AppMod
;
3524 case DIB_Status_InSync
:
3525 TRACE("AppMod requested in status InSync\n" );
3526 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3527 dib
->status
= DIB_Status_AppMod
;
3530 case DIB_Status_AppMod
:
3531 TRACE("AppMod requested in status AppMod\n" );
3532 /* shouldn't happen from signal handler */
3537 case DIB_Status_AuxMod
:
3538 if (dib
->status
== DIB_Status_None
) {
3539 dib
->p_status
= req
;
3541 if (dib
->status
!= DIB_Status_AuxMod
)
3542 dib
->p_status
= dib
->status
;
3543 dib
->status
= DIB_Status_AuxMod
;
3546 /* it is up to the caller to do the copy/conversion, probably
3547 * using the return value to decide where to copy from */
3549 LeaveCriticalSection(&(dib
->lock
));
3554 /***********************************************************************
3557 INT
X11DRV_DIB_Lock(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
3559 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3560 INT ret
= DIB_Status_None
;
3563 TRACE("Locking %p from thread %08lx\n", bmp
, GetCurrentThreadId());
3564 EnterCriticalSection(&(dib
->lock
));
3566 if (req
!= DIB_Status_None
)
3567 X11DRV_DIB_Coerce(bmp
, req
, lossy
);
3572 /***********************************************************************
3575 void X11DRV_DIB_Unlock(BITMAPOBJ
*bmp
, BOOL commit
)
3577 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3580 switch (dib
->status
)
3583 case DIB_Status_None
:
3584 /* in case anyone is wondering, this is the "signal handler doesn't
3585 * work" case, where we always have to be ready for app access */
3587 switch (dib
->p_status
)
3589 case DIB_Status_AuxMod
:
3590 TRACE("Unlocking and syncing from AuxMod\n" );
3591 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
3592 if (dib
->status
!= DIB_Status_None
) {
3593 dib
->p_status
= dib
->status
;
3594 dib
->status
= DIB_Status_None
;
3596 if (dib
->p_status
!= DIB_Status_GdiMod
)
3598 /* fall through if copy_aux() had to change to GdiMod state */
3600 case DIB_Status_GdiMod
:
3601 TRACE("Unlocking and syncing from GdiMod\n" );
3602 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3606 TRACE("Unlocking without needing to sync\n" );
3610 else TRACE("Unlocking with no changes\n");
3611 dib
->p_status
= DIB_Status_None
;
3614 case DIB_Status_GdiMod
:
3615 TRACE("Unlocking in status GdiMod\n" );
3616 /* DIB was protected in Coerce */
3618 /* no commit, revert to InSync if applicable */
3619 if ((dib
->p_status
== DIB_Status_InSync
) ||
3620 (dib
->p_status
== DIB_Status_AppMod
)) {
3621 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3622 dib
->status
= DIB_Status_InSync
;
3627 case DIB_Status_InSync
:
3628 TRACE("Unlocking in status InSync\n" );
3629 /* DIB was already protected in Coerce */
3632 case DIB_Status_AppMod
:
3633 TRACE("Unlocking in status AppMod\n" );
3634 /* DIB was already protected in Coerce */
3635 /* this case is ordinary only called from the signal handler,
3636 * so we don't bother to check for !commit */
3639 case DIB_Status_AuxMod
:
3640 TRACE("Unlocking in status AuxMod\n" );
3642 /* DIB may need protection now */
3643 if ((dib
->p_status
== DIB_Status_InSync
) ||
3644 (dib
->p_status
== DIB_Status_AppMod
))
3645 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3647 /* no commit, revert to previous state */
3648 if (dib
->p_status
!= DIB_Status_None
)
3649 dib
->status
= dib
->p_status
;
3650 /* no protections changed */
3652 dib
->p_status
= DIB_Status_None
;
3655 LeaveCriticalSection(&(dib
->lock
));
3656 TRACE("Unlocked %p\n", bmp
);
3660 /***********************************************************************
3661 * X11DRV_CoerceDIBSection2
3663 INT
X11DRV_CoerceDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
3668 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3669 if (!bmp
) return DIB_Status_None
;
3670 ret
= X11DRV_DIB_Coerce(bmp
, req
, lossy
);
3671 GDI_ReleaseObj( hBmp
);
3675 /***********************************************************************
3676 * X11DRV_LockDIBSection2
3678 INT
X11DRV_LockDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
3683 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3684 if (!bmp
) return DIB_Status_None
;
3685 ret
= X11DRV_DIB_Lock(bmp
, req
, lossy
);
3686 GDI_ReleaseObj( hBmp
);
3690 /***********************************************************************
3691 * X11DRV_UnlockDIBSection2
3693 void X11DRV_UnlockDIBSection2(HBITMAP hBmp
, BOOL commit
)
3697 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3699 X11DRV_DIB_Unlock(bmp
, commit
);
3700 GDI_ReleaseObj( hBmp
);
3703 /***********************************************************************
3704 * X11DRV_CoerceDIBSection
3706 INT
X11DRV_CoerceDIBSection(DC
*dc
, INT req
, BOOL lossy
)
3708 if (!dc
) return DIB_Status_None
;
3709 return X11DRV_CoerceDIBSection2( dc
->hBitmap
, req
, lossy
);
3712 /***********************************************************************
3713 * X11DRV_LockDIBSection
3715 INT
X11DRV_LockDIBSection(DC
*dc
, INT req
, BOOL lossy
)
3717 if (!dc
) return DIB_Status_None
;
3718 if (!(dc
->flags
& DC_MEMORY
)) return DIB_Status_None
;
3720 return X11DRV_LockDIBSection2( dc
->hBitmap
, req
, lossy
);
3723 /***********************************************************************
3724 * X11DRV_UnlockDIBSection
3726 void X11DRV_UnlockDIBSection(DC
*dc
, BOOL commit
)
3729 if (!(dc
->flags
& DC_MEMORY
)) return;
3731 X11DRV_UnlockDIBSection2( dc
->hBitmap
, commit
);
3735 #ifdef HAVE_LIBXXSHM
3736 /***********************************************************************
3737 * X11DRV_XShmErrorHandler
3740 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
)
3746 /***********************************************************************
3747 * X11DRV_XShmCreateImage
3750 static XImage
*X11DRV_XShmCreateImage( int width
, int height
, int bpp
,
3751 XShmSegmentInfo
* shminfo
)
3753 int (*WineXHandler
)(Display
*, XErrorEvent
*);
3757 image
= XShmCreateImage(gdi_display
, visual
, bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
3760 shminfo
->shmid
= shmget(IPC_PRIVATE
, image
->bytes_per_line
* height
,
3762 if( shminfo
->shmid
!= -1 )
3764 shminfo
->shmaddr
= image
->data
= shmat(shminfo
->shmid
, 0, 0);
3765 if( shminfo
->shmaddr
!= (char*)-1 )
3767 shminfo
->readOnly
= FALSE
;
3768 if( XShmAttach( gdi_display
, shminfo
) != 0)
3770 /* Reset the error flag */
3772 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
3773 XSync( gdi_display
, 0 );
3777 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3779 XSetErrorHandler(WineXHandler
);
3780 wine_tsx11_unlock();
3781 return image
; /* Success! */
3783 /* An error occured */
3785 XSetErrorHandler(WineXHandler
);
3787 shmdt(shminfo
->shmaddr
);
3789 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3791 XFlush(gdi_display
);
3792 XDestroyImage(image
);
3795 wine_tsx11_unlock();
3798 #endif /* HAVE_LIBXXSHM */
3801 /***********************************************************************
3802 * X11DRV_DIB_CreateDIBSection
3804 HBITMAP
X11DRV_DIB_CreateDIBSection(
3805 DC
*dc
, BITMAPINFO
*bmi
, UINT usage
,
3806 LPVOID
*bits
, HANDLE section
,
3807 DWORD offset
, DWORD ovr_pitch
)
3810 BITMAPOBJ
*bmp
= NULL
;
3811 X11DRV_DIBSECTION
*dib
= NULL
;
3812 int *colorMap
= NULL
;
3815 /* Fill BITMAP32 structure with DIB data */
3816 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
3817 INT effHeight
, totalSize
;
3819 LPVOID mapBits
= NULL
;
3821 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3822 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
3823 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
3825 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
3827 bm
.bmWidth
= bi
->biWidth
;
3828 bm
.bmHeight
= effHeight
;
3829 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
3830 : DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
3831 bm
.bmPlanes
= bi
->biPlanes
;
3832 bm
.bmBitsPixel
= bi
->biBitCount
;
3835 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
3836 we're dealing with a compressed bitmap. Otherwise, use width * height. */
3837 totalSize
= bi
->biSizeImage
&& bi
->biCompression
!= BI_RGB
3838 ? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
3842 SYSTEM_INFO SystemInfo
;
3846 GetSystemInfo( &SystemInfo
);
3847 mapOffset
= offset
- (offset
% SystemInfo
.dwAllocationGranularity
);
3848 mapSize
= totalSize
+ (offset
- mapOffset
);
3849 mapBits
= MapViewOfFile( section
,
3850 FILE_MAP_ALL_ACCESS
,
3854 bm
.bmBits
= (char *)mapBits
+ (offset
- mapOffset
);
3856 else if (ovr_pitch
&& offset
)
3857 bm
.bmBits
= (LPVOID
) offset
;
3860 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
3861 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
3864 /* Create Color Map */
3865 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
3866 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? dc
: NULL
,
3867 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
3869 /* Allocate Memory for DIB and fill structure */
3871 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
3874 dib
->dibSection
.dsBm
= bm
;
3875 dib
->dibSection
.dsBmih
= *bi
;
3876 dib
->dibSection
.dsBmih
.biSizeImage
= totalSize
;
3878 /* Set dsBitfields values */
3879 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
3881 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
3883 else switch( bi
->biBitCount
)
3886 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
3887 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
3888 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
3892 dib
->dibSection
.dsBitfields
[0] = 0xff;
3893 dib
->dibSection
.dsBitfields
[1] = 0xff00;
3894 dib
->dibSection
.dsBitfields
[2] = 0xff0000;
3898 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff;
3899 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0xff00;
3900 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0xff0000;
3903 dib
->dibSection
.dshSection
= section
;
3904 dib
->dibSection
.dsOffset
= offset
;
3906 dib
->status
= DIB_Status_None
;
3907 dib
->nColorMap
= nColorMap
;
3908 dib
->colorMap
= colorMap
;
3911 /* Create Device Dependent Bitmap and add DIB pointer */
3914 res
= CreateDIBitmap(dc
->hSelf
, bi
, 0, NULL
, bmi
, usage
);
3917 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3920 bmp
->dib
= (DIBSECTION
*) dib
;
3922 if(!bmp
->physBitmap
)
3923 X11DRV_CreateBitmap(res
);
3931 #ifdef HAVE_LIBXXSHM
3932 if (TSXShmQueryExtension(gdi_display
) &&
3933 (dib
->image
= X11DRV_XShmCreateImage( bm
.bmWidth
, effHeight
,
3934 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
)) )
3936 ; /* Created Image */
3938 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
3939 dib
->shminfo
.shmid
= -1;
3942 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
3946 /* Clean up in case of errors */
3947 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
3949 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3950 res
, bmp
, dib
, bm
.bmBits
);
3954 UnmapViewOfFile(mapBits
), bm
.bmBits
= NULL
;
3956 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
3959 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
3960 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
3961 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
3962 if (bmp
) { GDI_ReleaseObj(res
); bmp
= NULL
; }
3963 if (res
) { DeleteObject(res
); res
= 0; }
3967 /* Install fault handler, if possible */
3968 InitializeCriticalSection(&(dib
->lock
));
3969 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
3971 if (section
|| offset
)
3973 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3974 if (dib
) dib
->status
= DIB_Status_AppMod
;
3978 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3979 if (dib
) dib
->status
= DIB_Status_InSync
;
3984 /* Return BITMAP handle and storage location */
3985 if (bmp
) GDI_ReleaseObj(res
);
3986 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
3990 /***********************************************************************
3991 * X11DRV_DIB_DeleteDIBSection
3993 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
3995 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3999 #ifdef HAVE_LIBXXSHM
4000 if (dib
->shminfo
.shmid
!= -1)
4002 TSXShmDetach (gdi_display
, &(dib
->shminfo
));
4003 XDestroyImage (dib
->image
);
4004 shmdt (dib
->shminfo
.shmaddr
);
4005 dib
->shminfo
.shmid
= -1;
4009 XDestroyImage( dib
->image
);
4013 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
4015 DeleteCriticalSection(&(dib
->lock
));
4018 /***********************************************************************
4019 * X11DRV_DIB_SetDIBColorTable
4021 UINT
X11DRV_DIB_SetDIBColorTable(BITMAPOBJ
*bmp
, DC
*dc
, UINT start
, UINT count
, const RGBQUAD
*colors
)
4023 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4025 if (dib
&& dib
->colorMap
) {
4027 * Changing color table might change the mapping between
4028 * DIB colors and X11 colors and thus alter the visible state
4029 * of the bitmap object.
4031 X11DRV_DIB_Lock(bmp
, DIB_Status_AppMod
, FALSE
);
4032 X11DRV_DIB_GenColorMap( dc
, dib
->colorMap
, DIB_RGB_COLORS
,
4033 dib
->dibSection
.dsBm
.bmBitsPixel
,
4034 TRUE
, colors
, start
, count
+ start
);
4035 X11DRV_DIB_Unlock(bmp
, TRUE
);
4041 /***********************************************************************
4042 * X11DRV_DIB_GetDIBColorTable
4044 UINT
X11DRV_DIB_GetDIBColorTable(BITMAPOBJ
*bmp
, DC
*dc
, UINT start
, UINT count
, RGBQUAD
*colors
)
4046 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4048 if (dib
&& dib
->colorMap
) {
4049 int i
, end
= count
+ start
;
4050 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
4051 for (i
= start
; i
< end
; i
++,colors
++) {
4052 COLORREF col
= X11DRV_PALETTE_ToLogical( dib
->colorMap
[i
] );
4053 colors
->rgbBlue
= GetBValue(col
);
4054 colors
->rgbGreen
= GetGValue(col
);
4055 colors
->rgbRed
= GetRValue(col
);
4056 colors
->rgbReserved
= 0;
4064 /**************************************************************************
4065 * X11DRV_DIB_CreateDIBFromPixmap
4067 * Allocates a packed DIB and copies the Pixmap data into it.
4068 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
4070 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
4073 BITMAPOBJ
*pBmp
= NULL
;
4074 HGLOBAL hPackedDIB
= 0;
4076 /* Allocates an HBITMAP which references the Pixmap passed to us */
4077 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
4080 TRACE("\tCould not create bitmap header for Pixmap\n");
4085 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4086 * A packed DIB contains a BITMAPINFO structure followed immediately by
4087 * an optional color palette and the pixel data.
4089 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
4091 /* Get a pointer to the BITMAPOBJ structure */
4092 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4094 /* We can now get rid of the HBITMAP wrapper we created earlier.
4095 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4099 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4100 pBmp
->physBitmap
= NULL
;
4103 GDI_ReleaseObj( hBmp
);
4107 TRACE("\tReturning packed DIB %x\n", hPackedDIB
);
4112 /**************************************************************************
4113 * X11DRV_DIB_CreatePixmapFromDIB
4115 * Creates a Pixmap from a packed DIB
4117 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
4119 Pixmap pixmap
= None
;
4121 BITMAPOBJ
*pBmp
= NULL
;
4122 LPBYTE pPackedDIB
= NULL
;
4123 LPBITMAPINFO pbmi
= NULL
;
4124 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
4125 LPBYTE pbits
= NULL
;
4127 /* Get a pointer to the packed DIB's data */
4128 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
4129 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
4130 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
4131 pbits
= (LPBYTE
)(pPackedDIB
4132 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
4134 /* Create a DDB from the DIB */
4136 hBmp
= CreateDIBitmap(hdc
,
4143 GlobalUnlock(hPackedDIB
);
4145 TRACE("CreateDIBitmap returned %x\n", hBmp
);
4147 /* Retrieve the internal Pixmap from the DDB */
4149 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4151 pixmap
= (Pixmap
)pBmp
->physBitmap
;
4152 /* clear the physBitmap so that we can steal its pixmap */
4153 pBmp
->physBitmap
= NULL
;
4156 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4157 GDI_ReleaseObj( hBmp
);
4160 TRACE("\tReturning Pixmap %ld\n", pixmap
);