Fix the case of product and company names.
[wine] / graphics / x11drv / dib.c
1 /*
2  * X11DRV device-independent bitmaps
3  *
4  * Copyright 1993,1994  Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include "ts_xlib.h"
24 #ifdef HAVE_LIBXXSHM
25 #include <X11/extensions/XShm.h>
26 # ifdef HAVE_SYS_SHM_H
27 #  include <sys/shm.h>
28 # endif
29 # ifdef HAVE_SYS_IPC_H
30 #  include <sys/ipc.h>
31 # endif
32 #endif /* defined(HAVE_LIBXXSHM) */
33
34 #include <stdarg.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include "windef.h"
38 #include "winbase.h"
39 #include "bitmap.h"
40 #include "x11drv.h"
41 #include "wine/debug.h"
42 #include "gdi.h"
43 #include "palette.h"
44 #include "global.h"
45
46 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
47 WINE_DECLARE_DEBUG_CHANNEL(x11drv);
48
49 static int ximageDepthTable[32];
50
51 /* This structure holds the arguments for DIB_SetImageBits() */
52 typedef struct
53 {
54     X11DRV_PDEVICE *physDev;
55     LPCVOID         bits;
56     XImage         *image;
57     PALETTEENTRY   *palentry;
58     int             lines;
59     DWORD           infoWidth;
60     WORD            depth;
61     WORD            infoBpp;
62     WORD            compression;
63     RGBQUAD        *colorMap;
64     int             nColorMap;
65     Drawable        drawable;
66     GC              gc;
67     int             xSrc;
68     int             ySrc;
69     int             xDest;
70     int             yDest;
71     int             width;
72     int             height;
73     DWORD           rMask;
74     DWORD           gMask;
75     DWORD           bMask;
76     BOOL            useShm;
77     int             dibpitch;
78 } X11DRV_DIB_IMAGEBITS_DESCR;
79
80
81 enum Rle_EscapeCodes
82 {
83   RLE_EOL   = 0, /* End of line */
84   RLE_END   = 1, /* End of bitmap */
85   RLE_DELTA = 2  /* Delta */
86 };
87
88 /***********************************************************************
89  *           X11DRV_DIB_GetXImageWidthBytes
90  *
91  * Return the width of an X image in bytes
92  */
93 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
94 {
95     if (!depth || depth > 32) goto error;
96
97     if (!ximageDepthTable[depth-1])
98     {
99         XImage *testimage = XCreateImage( gdi_display, visual, depth,
100                                           ZPixmap, 0, NULL, 1, 1, 32, 20 );
101         if (testimage)
102         {
103             ximageDepthTable[depth-1] = testimage->bits_per_pixel;
104             XDestroyImage( testimage );
105         }
106         else ximageDepthTable[depth-1] = -1;
107     }
108     if (ximageDepthTable[depth-1] != -1)
109         return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
110
111  error:
112     WARN( "(%d): Unsupported depth\n", depth );
113     return 4 * width;
114 }
115
116
117 /***********************************************************************
118  *           X11DRV_DIB_CreateXImage
119  *
120  * Create an X image.
121  */
122 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
123 {
124     int width_bytes;
125     XImage *image;
126
127     wine_tsx11_lock();
128     width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
129     image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
130                           calloc( height, width_bytes ),
131                           width, height, 32, width_bytes );
132     wine_tsx11_unlock();
133     return image;
134 }
135
136
137 /***********************************************************************
138  *           DIB_GetBitmapInfo
139  *
140  * Get the info from a bitmap header.
141  * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
142  */
143 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
144                               int *height, WORD *bpp, WORD *compr )
145 {
146     if (header->biSize == sizeof(BITMAPCOREHEADER))
147     {
148         BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
149         *width  = core->bcWidth;
150         *height = core->bcHeight;
151         *bpp    = core->bcBitCount;
152         *compr  = 0;
153         return 0;
154     }
155     if (header->biSize >= sizeof(BITMAPINFOHEADER))
156     {
157         *width  = header->biWidth;
158         *height = header->biHeight;
159         *bpp    = header->biBitCount;
160         *compr  = header->biCompression;
161         return 1;
162     }
163     ERR("(%ld): unknown/wrong size for header\n", header->biSize );
164     return -1;
165 }
166
167
168 /***********************************************************************
169  *           X11DRV_DIB_GenColorMap
170  *
171  * Fills the color map of a bitmap palette. Should not be called
172  * for a >8-bit deep bitmap.
173  */
174 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
175                              WORD coloruse, WORD depth, BOOL quads,
176                              const void *colorPtr, int start, int end )
177 {
178     int i;
179
180     if (coloruse == DIB_RGB_COLORS)
181     {
182         int max = 1 << depth;
183
184         if (end > max) end = max;
185
186         if (quads)
187         {
188             RGBQUAD * rgb = (RGBQUAD *)colorPtr;
189
190             if (depth == 1)  /* Monochrome */
191                 for (i = start; i < end; i++, rgb++)
192                     colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
193                                        rgb->rgbBlue > 255*3/2);
194             else
195                 for (i = start; i < end; i++, rgb++)
196                     colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbRed,
197                                                                 rgb->rgbGreen,
198                                                                 rgb->rgbBlue));
199         }
200         else
201         {
202             RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
203
204             if (depth == 1)  /* Monochrome */
205                 for (i = start; i < end; i++, rgb++)
206                     colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
207                                        rgb->rgbtBlue > 255*3/2);
208             else
209                 for (i = start; i < end; i++, rgb++)
210                     colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbtRed,
211                                                                rgb->rgbtGreen,
212                                                                rgb->rgbtBlue));
213         }
214     }
215     else  /* DIB_PAL_COLORS */
216     {
217         if (colorPtr) {
218             WORD * index = (WORD *)colorPtr;
219
220             for (i = start; i < end; i++, index++)
221                 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(*index) );
222         } else {
223             for (i = start; i < end; i++)
224                 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(i) );
225         }
226     }
227
228     return colorMapping;
229 }
230
231 /***********************************************************************
232  *           X11DRV_DIB_BuildColorMap
233  *
234  * Build the color map from the bitmap palette. Should not be called
235  * for a >8-bit deep bitmap.
236  */
237 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
238                                const BITMAPINFO *info, int *nColors )
239 {
240     int colors;
241     BOOL isInfo;
242     const void *colorPtr;
243     int *colorMapping;
244
245     if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
246     {
247         colors = info->bmiHeader.biClrUsed;
248         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
249         colorPtr = info->bmiColors;
250     }
251     else  /* assume BITMAPCOREINFO */
252     {
253         colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
254         colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
255     }
256
257     if (colors > 256)
258     {
259         ERR("called with >256 colors!\n");
260         return NULL;
261     }
262
263     /* just so CopyDIBSection doesn't have to create an identity palette */
264     if (coloruse == (WORD)-1) colorPtr = NULL;
265
266     if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
267                                           colors * sizeof(int) )))
268         return NULL;
269
270     *nColors = colors;
271     return X11DRV_DIB_GenColorMap( physDev, colorMapping, coloruse, depth,
272                                    isInfo, colorPtr, 0, colors);
273 }
274
275
276 /***********************************************************************
277  *           X11DRV_DIB_MapColor
278  */
279 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
280 {
281     int color;
282
283     if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
284         return oldcol;
285
286     for (color = 0; color < nPhysMap; color++)
287         if (physMap[color] == phys)
288             return color;
289
290     WARN("Strange color %08x\n", phys);
291     return 0;
292 }
293
294
295 /*********************************************************************
296  *         X11DRV_DIB_GetNearestIndex
297  *
298  * Helper for X11DRV_DIB_GetDIBits.
299  * Returns the nearest colour table index for a given RGB.
300  * Nearest is defined by minimizing the sum of the squares.
301  */
302 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
303 {
304     INT i, best = -1, diff, bestdiff = -1;
305     RGBQUAD *color;
306
307     for(color = colormap, i = 0; i < numColors; color++, i++) {
308         diff = (r - color->rgbRed) * (r - color->rgbRed) +
309                (g - color->rgbGreen) * (g - color->rgbGreen) +
310                (b - color->rgbBlue) * (b - color->rgbBlue);
311         if(diff == 0)
312             return i;
313         if(best == -1 || diff < bestdiff) {
314             best = i;
315             bestdiff = diff;
316         }
317     }
318     return best;
319 }
320 /*********************************************************************
321  *         X11DRV_DIB_MaskToShift
322  *
323  * Helper for X11DRV_DIB_GetDIBits.
324  * Returns the by how many bits to shift a given color so that it is
325  * in the proper position.
326  */
327 static INT X11DRV_DIB_MaskToShift(DWORD mask)
328 {
329     int shift;
330
331     if (mask==0)
332         return 0;
333
334     shift=0;
335     while ((mask&1)==0) {
336         mask>>=1;
337         shift++;
338     }
339     return shift;
340 }
341
342 /***********************************************************************
343  *           X11DRV_DIB_Convert_any_asis
344  *
345  * All X11DRV_DIB_Convert_Xxx functions take at least the following
346  * parameters:
347  * - width
348  *   This is the width in pixel of the surface to copy. This may be less
349  *   than the full width of the image.
350  * - height
351  *   The number of lines to copy. This may be less than the full height
352  *   of the image. This is always >0.
353  * - srcbits
354  *   Points to the first byte containing data to be copied. If the source
355  *   surface starts are coordinates (x,y) then this is:
356  *   image_ptr+x*bytes_pre_pixel+y*bytes_per_line
357  *   (with further adjustments for top-down/bottom-up images)
358  * - srclinebytes
359  *   This is the number of bytes per line. It may be >0 or <0 depending on
360  *   whether this is a top-down or bottom-up image.
361  * - dstbits
362  *   Same as srcbits but for the destination
363  * - dstlinebytes
364  *   Same as srclinebytes but for the destination.
365  *
366  * Notes:
367  * - The supported Dib formats are: pal1, pal4, pal8, rgb555, bgr555,
368  *   rgb565, bgr565, rgb888 and any 32bit (0888) format.
369  *   The supported XImage (Bmp) formats are: pal1, pal4, pal8,
370  *   rgb555, bgr555, rgb565, bgr565, rgb888, bgr888, rgb0888, bgr0888.
371  * - Rgb formats are those for which the masks are such that:
372  *   red_mask > green_mask > blue_mask
373  * - Bgr formats are those for which the masks sort in the other direction.
374  * - Many conversion functions handle both rgb->bgr and bgr->rgb conversions
375  *   so the comments use h, g, l to mean respectively the source color in the
376  *   high bits, the green, and the source color in the low bits.
377  */
378 static void X11DRV_DIB_Convert_any_asis(int width, int height,
379                                     int bytes_per_pixel,
380                                     const void* srcbits, int srclinebytes,
381                                     void* dstbits, int dstlinebytes)
382 {
383     int y;
384
385     width*=bytes_per_pixel;
386     for (y=0; y<height; y++) {
387         memcpy(dstbits, srcbits, width);
388         srcbits = (char*)srcbits + srclinebytes;
389         dstbits = (char*)dstbits + dstlinebytes;
390     }
391 }
392
393 /*
394  * 15 bit conversions
395  */
396
397 static void X11DRV_DIB_Convert_555_reverse(int width, int height,
398                                     const void* srcbits, int srclinebytes,
399                                     void* dstbits, int dstlinebytes)
400 {
401     const DWORD* srcpixel;
402     DWORD* dstpixel;
403     int x,y;
404
405     for (y=0; y<height; y++) {
406         srcpixel=srcbits;
407         dstpixel=dstbits;
408         for (x=0; x<width/2; x++) {
409             /* Do 2 pixels at a time */
410             DWORD srcval;
411             srcval=*srcpixel++;
412             *dstpixel++=((srcval << 10) & 0x7c007c00) | /* h */
413                         ( srcval        & 0x03e003e0) | /* g */
414                         ((srcval >> 10) & 0x001f001f);  /* l */
415         }
416         if (width&1) {
417             /* And the the odd pixel */
418             WORD srcval;
419             srcval=*((WORD*)srcpixel);
420             *((WORD*)dstpixel)=((srcval << 10) & 0x7c00) | /* h */
421                                ( srcval        & 0x03e0) | /* g */
422                                ((srcval >> 10) & 0x001f);  /* l */
423         }
424         srcbits = (char*)srcbits + srclinebytes;
425         dstbits = (char*)dstbits + dstlinebytes;
426     }
427 }
428
429 static void X11DRV_DIB_Convert_555_to_565_asis(int width, int height,
430                                     const void* srcbits, int srclinebytes,
431                                     void* dstbits, int dstlinebytes)
432 {
433     const DWORD* srcpixel;
434     DWORD* dstpixel;
435     int x,y;
436
437     for (y=0; y<height; y++) {
438         srcpixel=srcbits;
439         dstpixel=dstbits;
440         for (x=0; x<width/2; x++) {
441             /* Do 2 pixels at a time */
442             DWORD srcval;
443             srcval=*srcpixel++;
444             *dstpixel++=((srcval << 1) & 0xffc0ffc0) | /* h, g */
445                         ((srcval >> 4) & 0x00200020) | /* g - 1 bit */
446                         ( srcval       & 0x001f001f);  /* l */
447         }
448         if (width&1) {
449             /* And the the odd pixel */
450             WORD srcval;
451             srcval=*((WORD*)srcpixel);
452             *((WORD*)dstpixel)=((srcval << 1) & 0xffc0) | /* h, g */
453                                ((srcval >> 4) & 0x0020) | /* g - 1 bit */
454                                 (srcval       & 0x001f);  /* l */
455         }
456         srcbits = (char*)srcbits + srclinebytes;
457         dstbits = (char*)dstbits + dstlinebytes;
458     }
459 }
460
461 static void X11DRV_DIB_Convert_555_to_565_reverse(int width, int height,
462                                     const void* srcbits, int srclinebytes,
463                                     void* dstbits, int dstlinebytes)
464 {
465     const DWORD* srcpixel;
466     DWORD* dstpixel;
467     int x,y;
468
469     for (y=0; y<height; y++) {
470         srcpixel=srcbits;
471         dstpixel=dstbits;
472         for (x=0; x<width/2; x++) {
473             /* Do 2 pixels at a time */
474             DWORD srcval;
475             srcval=*srcpixel++;
476             *dstpixel++=((srcval >> 10) & 0x001f001f) | /* h */
477                         ((srcval <<  1) & 0x07c007c0) | /* g */
478                         ((srcval >>  4) & 0x00200020) | /* g - 1 bit */
479                         ((srcval << 11) & 0xf800f800);  /* l */
480         }
481         if (width&1) {
482             /* And the the odd pixel */
483             WORD srcval;
484             srcval=*((WORD*)srcpixel);
485             *((WORD*)dstpixel)=((srcval >> 10) & 0x001f) | /* h */
486                                ((srcval <<  1) & 0x07c0) | /* g */
487                                ((srcval >>  4) & 0x0020) | /* g - 1 bit */
488                                ((srcval << 11) & 0xf800);  /* l */
489         }
490         srcbits = (char*)srcbits + srclinebytes;
491         dstbits = (char*)dstbits + dstlinebytes;
492     }
493 }
494
495 static void X11DRV_DIB_Convert_555_to_888_asis(int width, int height,
496                                     const void* srcbits, int srclinebytes,
497                                     void* dstbits, int dstlinebytes)
498 {
499     const WORD* srcpixel;
500     BYTE* dstpixel;
501     int x,y;
502
503     for (y=0; y<height; y++) {
504         srcpixel=srcbits;
505         dstpixel=dstbits;
506         for (x=0; x<width; x++) {
507             WORD srcval;
508             srcval=*srcpixel++;
509             dstpixel[0]=((srcval <<  3) & 0xf8) | /* l */
510                         ((srcval >>  2) & 0x07);  /* l - 3 bits */
511             dstpixel[1]=((srcval >>  2) & 0xf8) | /* g */
512                         ((srcval >>  7) & 0x07);  /* g - 3 bits */
513             dstpixel[2]=((srcval >>  7) & 0xf8) | /* h */
514                         ((srcval >> 12) & 0x07);  /* h - 3 bits */
515             dstpixel+=3;
516         }
517         srcbits = (char*)srcbits + srclinebytes;
518         dstbits = (char*)dstbits + dstlinebytes;
519     }
520 }
521
522 static void X11DRV_DIB_Convert_555_to_888_reverse(int width, int height,
523                                     const void* srcbits, int srclinebytes,
524                                     void* dstbits, int dstlinebytes)
525 {
526     const WORD* srcpixel;
527     BYTE* dstpixel;
528     int x,y;
529
530     for (y=0; y<height; y++) {
531         srcpixel=srcbits;
532         dstpixel=dstbits;
533         for (x=0; x<width; x++) {
534             WORD srcval;
535             srcval=*srcpixel++;
536             dstpixel[0]=((srcval >>  7) & 0xf8) | /* h */
537                         ((srcval >> 12) & 0x07);  /* h - 3 bits */
538             dstpixel[1]=((srcval >>  2) & 0xf8) | /* g */
539                         ((srcval >>  7) & 0x07);  /* g - 3 bits */
540             dstpixel[2]=((srcval <<  3) & 0xf8) | /* l */
541                         ((srcval >>  2) & 0x07);  /* l - 3 bits */
542             dstpixel+=3;
543         }
544         srcbits = (char*)srcbits + srclinebytes;
545         dstbits = (char*)dstbits + dstlinebytes;
546     }
547 }
548
549 static void X11DRV_DIB_Convert_555_to_0888_asis(int width, int height,
550                                     const void* srcbits, int srclinebytes,
551                                     void* dstbits, int dstlinebytes)
552 {
553     const WORD* srcpixel;
554     DWORD* dstpixel;
555     int x,y;
556
557     for (y=0; y<height; y++) {
558         srcpixel=srcbits;
559         dstpixel=dstbits;
560         for (x=0; x<width; x++) {
561             WORD srcval;
562             srcval=*srcpixel++;
563             *dstpixel++=((srcval << 9) & 0xf80000) | /* h */
564                         ((srcval << 4) & 0x070000) | /* h - 3 bits */
565                         ((srcval << 6) & 0x00f800) | /* g */
566                         ((srcval << 1) & 0x000700) | /* g - 3 bits */
567                         ((srcval << 3) & 0x0000f8) | /* l */
568                         ((srcval >> 2) & 0x000007);  /* l - 3 bits */
569         }
570         srcbits = (char*)srcbits + srclinebytes;
571         dstbits = (char*)dstbits + dstlinebytes;
572     }
573 }
574
575 static void X11DRV_DIB_Convert_555_to_0888_reverse(int width, int height,
576                                     const void* srcbits, int srclinebytes,
577                                     void* dstbits, int dstlinebytes)
578 {
579     const WORD* srcpixel;
580     DWORD* dstpixel;
581     int x,y;
582
583     for (y=0; y<height; y++) {
584         srcpixel=srcbits;
585         dstpixel=dstbits;
586         for (x=0; x<width; x++) {
587             WORD srcval;
588             srcval=*srcpixel++;
589             *dstpixel++=((srcval >>  7) & 0x0000f8) | /* h */
590                         ((srcval >> 12) & 0x000007) | /* h - 3 bits */
591                         ((srcval <<  6) & 0x00f800) | /* g */
592                         ((srcval <<  1) & 0x000700) | /* g - 3 bits */
593                         ((srcval << 19) & 0xf80000) | /* l */
594                         ((srcval << 14) & 0x070000);  /* l - 3 bits */
595         }
596         srcbits = (char*)srcbits + srclinebytes;
597         dstbits = (char*)dstbits + dstlinebytes;
598     }
599 }
600
601 static void X11DRV_DIB_Convert_5x5_to_any0888(int width, int height,
602                                     const void* srcbits, int srclinebytes,
603                                     WORD rsrc, WORD gsrc, WORD bsrc,
604                                     void* dstbits, int dstlinebytes,
605                                     DWORD rdst, DWORD gdst, DWORD bdst)
606 {
607     int rRightShift1,gRightShift1,bRightShift1;
608     int rRightShift2,gRightShift2,bRightShift2;
609     BYTE gMask1,gMask2;
610     int rLeftShift,gLeftShift,bLeftShift;
611     const WORD* srcpixel;
612     DWORD* dstpixel;
613     int x,y;
614
615     /* Note, the source pixel value is shifted left by 16 bits so that
616      * we know we will always have to shift right to extract the components.
617      */
618     rRightShift1=16+X11DRV_DIB_MaskToShift(rsrc)-3;
619     gRightShift1=16+X11DRV_DIB_MaskToShift(gsrc)-3;
620     bRightShift1=16+X11DRV_DIB_MaskToShift(bsrc)-3;
621     rRightShift2=rRightShift1+5;
622     gRightShift2=gRightShift1+5;
623     bRightShift2=bRightShift1+5;
624     if (gsrc==0x03e0) {
625         /* Green has 5 bits, like the others */
626         gMask1=0xf8;
627         gMask2=0x07;
628     } else {
629         /* Green has 6 bits, not 5. Compensate. */
630         gRightShift1++;
631         gRightShift2+=2;
632         gMask1=0xfc;
633         gMask2=0x03;
634     }
635
636     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
637     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
638     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
639
640     for (y=0; y<height; y++) {
641         srcpixel=srcbits;
642         dstpixel=dstbits;
643         for (x=0; x<width; x++) {
644             DWORD srcval;
645             BYTE red,green,blue;
646             srcval=*srcpixel++ << 16;
647             red=  ((srcval >> rRightShift1) & 0xf8) |
648                   ((srcval >> rRightShift2) & 0x07);
649             green=((srcval >> gRightShift1) & gMask1) |
650                   ((srcval >> gRightShift2) & gMask2);
651             blue= ((srcval >> bRightShift1) & 0xf8) |
652                   ((srcval >> bRightShift2) & 0x07);
653             *dstpixel++=(red   << rLeftShift) |
654                         (green << gLeftShift) |
655                         (blue  << bLeftShift);
656         }
657         srcbits = (char*)srcbits + srclinebytes;
658         dstbits = (char*)dstbits + dstlinebytes;
659     }
660 }
661
662 /*
663  * 16 bits conversions
664  */
665
666 static void X11DRV_DIB_Convert_565_reverse(int width, int height,
667                                     const void* srcbits, int srclinebytes,
668                                     void* dstbits, int dstlinebytes)
669 {
670     const DWORD* srcpixel;
671     DWORD* dstpixel;
672     int x,y;
673
674     for (y=0; y<height; y++) {
675         srcpixel=srcbits;
676         dstpixel=dstbits;
677         for (x=0; x<width/2; x++) {
678             /* Do 2 pixels at a time */
679             DWORD srcval;
680             srcval=*srcpixel++;
681             *dstpixel++=((srcval << 11) & 0xf800f800) | /* h */
682                         ( srcval        & 0x07e007e0) | /* g */
683                         ((srcval >> 11) & 0x001f001f);  /* l */
684         }
685         if (width&1) {
686             /* And the the odd pixel */
687             WORD srcval;
688             srcval=*((WORD*)srcpixel);
689             *((WORD*)dstpixel)=((srcval << 11) & 0xf800) | /* h */
690                                ( srcval        & 0x07e0) | /* g */
691                                ((srcval >> 11) & 0x001f);  /* l */
692         }
693         srcbits = (char*)srcbits + srclinebytes;
694         dstbits = (char*)dstbits + dstlinebytes;
695     }
696 }
697
698 static void X11DRV_DIB_Convert_565_to_555_asis(int width, int height,
699                                     const void* srcbits, int srclinebytes,
700                                     void* dstbits, int dstlinebytes)
701 {
702     const DWORD* srcpixel;
703     DWORD* dstpixel;
704     int x,y;
705
706     for (y=0; y<height; y++) {
707         srcpixel=srcbits;
708         dstpixel=dstbits;
709         for (x=0; x<width/2; x++) {
710             /* Do 2 pixels at a time */
711             DWORD srcval;
712             srcval=*srcpixel++;
713             *dstpixel++=((srcval >> 1) & 0x7fe07fe0) | /* h, g */
714                         ( srcval       & 0x001f001f);  /* l */
715         }
716         if (width&1) {
717             /* And the the odd pixel */
718             WORD srcval;
719             srcval=*((WORD*)srcpixel);
720             *((WORD*)dstpixel)=((srcval >> 1) & 0x7fe0) | /* h, g */
721                                ( srcval       & 0x001f);  /* l */
722         }
723         srcbits = (char*)srcbits + srclinebytes;
724         dstbits = (char*)dstbits + dstlinebytes;
725     }
726 }
727
728 static void X11DRV_DIB_Convert_565_to_555_reverse(int width, int height,
729                                     const void* srcbits, int srclinebytes,
730                                     void* dstbits, int dstlinebytes)
731 {
732     const DWORD* srcpixel;
733     DWORD* dstpixel;
734     int x,y;
735
736     for (y=0; y<height; y++) {
737         srcpixel=srcbits;
738         dstpixel=dstbits;
739         for (x=0; x<width/2; x++) {
740             /* Do 2 pixels at a time */
741             DWORD srcval;
742             srcval=*srcpixel++;
743             *dstpixel++=((srcval >> 11) & 0x001f001f) | /* h */
744                         ((srcval >>  1) & 0x03e003e0) | /* g */
745                         ((srcval << 10) & 0x7c007c00);  /* l */
746         }
747         if (width&1) {
748             /* And the the odd pixel */
749             WORD srcval;
750             srcval=*((WORD*)srcpixel);
751             *((WORD*)dstpixel)=((srcval >> 11) & 0x001f) | /* h */
752                                ((srcval >>  1) & 0x03e0) | /* g */
753                                ((srcval << 10) & 0x7c00);  /* l */
754         }
755         srcbits = (char*)srcbits + srclinebytes;
756         dstbits = (char*)dstbits + dstlinebytes;
757     }
758 }
759
760 static void X11DRV_DIB_Convert_565_to_888_asis(int width, int height,
761                                     const void* srcbits, int srclinebytes,
762                                     void* dstbits, int dstlinebytes)
763 {
764     const WORD* srcpixel;
765     BYTE* dstpixel;
766     int x,y;
767
768     for (y=0; y<height; y++) {
769         srcpixel=srcbits;
770         dstpixel=dstbits;
771         for (x=0; x<width; x++) {
772             WORD srcval;
773             srcval=*srcpixel++;
774             dstpixel[0]=((srcval <<  3) & 0xf8) | /* l */
775                         ((srcval >>  2) & 0x07);  /* l - 3 bits */
776             dstpixel[1]=((srcval >>  3) & 0xfc) | /* g */
777                         ((srcval >>  9) & 0x03);  /* g - 2 bits */
778             dstpixel[2]=((srcval >>  8) & 0xf8) | /* h */
779                         ((srcval >> 13) & 0x07);  /* h - 3 bits */
780             dstpixel+=3;
781         }
782         srcbits = (char*)srcbits + srclinebytes;
783         dstbits = (char*)dstbits + dstlinebytes;
784     }
785 }
786
787 static void X11DRV_DIB_Convert_565_to_888_reverse(int width, int height,
788                                     const void* srcbits, int srclinebytes,
789                                     void* dstbits, int dstlinebytes)
790 {
791     const WORD* srcpixel;
792     BYTE* dstpixel;
793     int x,y;
794
795     for (y=0; y<height; y++) {
796         srcpixel=srcbits;
797         dstpixel=dstbits;
798         for (x=0; x<width; x++) {
799             WORD srcval;
800             srcval=*srcpixel++;
801             dstpixel[0]=((srcval >>  8) & 0xf8) | /* h */
802                         ((srcval >> 13) & 0x07);  /* h - 3 bits */
803             dstpixel[1]=((srcval >>  3) & 0xfc) | /* g */
804                         ((srcval >>  9) & 0x03);  /* g - 2 bits */
805             dstpixel[2]=((srcval <<  3) & 0xf8) | /* l */
806                         ((srcval >>  2) & 0x07);  /* l - 3 bits */
807             dstpixel+=3;
808         }
809         srcbits = (char*)srcbits + srclinebytes;
810         dstbits = (char*)dstbits + dstlinebytes;
811     }
812 }
813
814 static void X11DRV_DIB_Convert_565_to_0888_asis(int width, int height,
815                                     const void* srcbits, int srclinebytes,
816                                     void* dstbits, int dstlinebytes)
817 {
818     const WORD* srcpixel;
819     DWORD* dstpixel;
820     int x,y;
821
822     for (y=0; y<height; y++) {
823         srcpixel=srcbits;
824         dstpixel=dstbits;
825         for (x=0; x<width; x++) {
826             WORD srcval;
827             srcval=*srcpixel++;
828             *dstpixel++=((srcval << 8) & 0xf80000) | /* h */
829                         ((srcval << 3) & 0x070000) | /* h - 3 bits */
830                         ((srcval << 5) & 0x00fc00) | /* g */
831                         ((srcval >> 1) & 0x000300) | /* g - 2 bits */
832                         ((srcval << 3) & 0x0000f8) | /* l */
833                         ((srcval >> 2) & 0x000007);  /* l - 3 bits */
834         }
835         srcbits = (char*)srcbits + srclinebytes;
836         dstbits = (char*)dstbits + dstlinebytes;
837     }
838 }
839
840 static void X11DRV_DIB_Convert_565_to_0888_reverse(int width, int height,
841                                     const void* srcbits, int srclinebytes,
842                                     void* dstbits, int dstlinebytes)
843 {
844     const WORD* srcpixel;
845     DWORD* dstpixel;
846     int x,y;
847
848     for (y=0; y<height; y++) {
849         srcpixel=srcbits;
850         dstpixel=dstbits;
851         for (x=0; x<width; x++) {
852             WORD srcval;
853             srcval=*srcpixel++;
854             *dstpixel++=((srcval >>  8) & 0x0000f8) | /* h */
855                         ((srcval >> 13) & 0x000007) | /* h - 3 bits */
856                         ((srcval <<  5) & 0x00fc00) | /* g */
857                         ((srcval >>  1) & 0x000300) | /* g - 2 bits */
858                         ((srcval << 19) & 0xf80000) | /* l */
859                         ((srcval << 14) & 0x070000);  /* l - 3 bits */
860         }
861         srcbits = (char*)srcbits + srclinebytes;
862         dstbits = (char*)dstbits + dstlinebytes;
863     }
864 }
865
866 /*
867  * 24 bit conversions
868  */
869
870 static void X11DRV_DIB_Convert_888_reverse(int width, int height,
871                                     const void* srcbits, int srclinebytes,
872                                     void* dstbits, int dstlinebytes)
873 {
874     const BYTE* srcpixel;
875     BYTE* dstpixel;
876     int x,y;
877
878     for (y=0; y<height; y++) {
879         srcpixel=srcbits;
880         dstpixel=dstbits;
881         for (x=0; x<width; x++) {
882             dstpixel[0]=srcpixel[2];
883             dstpixel[1]=srcpixel[1];
884             dstpixel[2]=srcpixel[0];
885             srcpixel+=3;
886             dstpixel+=3;
887         }
888         srcbits = (char*)srcbits + srclinebytes;
889         dstbits = (char*)dstbits + dstlinebytes;
890     }
891 }
892
893 static void X11DRV_DIB_Convert_888_to_555_asis(int width, int height,
894                                     const void* srcbits, int srclinebytes,
895                                     void* dstbits, int dstlinebytes)
896 {
897     const DWORD* srcpixel;
898     const BYTE* srcbyte;
899     WORD* dstpixel;
900     int x,y;
901     int oddwidth;
902
903     oddwidth=width & 3;
904     width=width/4;
905     for (y=0; y<height; y++) {
906         srcpixel=srcbits;
907         dstpixel=dstbits;
908         for (x=0; x<width; x++) {
909             /* Do 4 pixels at a time: 3 dwords in and 4 words out */
910             DWORD srcval1,srcval2;
911             srcval1=srcpixel[0];
912             dstpixel[0]=((srcval1 >>  3) & 0x001f) | /* l1 */
913                         ((srcval1 >>  6) & 0x03e0) | /* g1 */
914                         ((srcval1 >>  9) & 0x7c00);  /* h1 */
915             srcval2=srcpixel[1];
916             dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
917                         ((srcval2 <<  2) & 0x03e0) | /* g2 */
918                         ((srcval2 >>  1) & 0x7c00);  /* h2 */
919             srcval1=srcpixel[2];
920             dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
921                         ((srcval2 >> 22) & 0x03e0) | /* g3 */
922                         ((srcval1 <<  7) & 0x7c00);  /* h3 */
923             dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
924                         ((srcval1 >> 14) & 0x03e0) | /* g4 */
925                         ((srcval1 >> 17) & 0x7c00);  /* h4 */
926             srcpixel+=3;
927             dstpixel+=4;
928         }
929         /* And now up to 3 odd pixels */
930         srcbyte=(LPBYTE)srcpixel;
931         for (x=0; x<oddwidth; x++) {
932             WORD dstval;
933             dstval =((srcbyte[0] >> 3) & 0x001f);    /* l */
934             dstval|=((srcbyte[1] << 2) & 0x03e0);    /* g */
935             dstval|=((srcbyte[2] << 7) & 0x7c00);    /* h */
936             *dstpixel++=dstval;
937             srcbyte+=3;
938         }
939         srcbits = (char*)srcbits + srclinebytes;
940         dstbits = (char*)dstbits + dstlinebytes;
941     }
942 }
943
944 static void X11DRV_DIB_Convert_888_to_555_reverse(int width, int height,
945                                     const void* srcbits, int srclinebytes,
946                                     void* dstbits, int dstlinebytes)
947 {
948     const DWORD* srcpixel;
949     const BYTE* srcbyte;
950     WORD* dstpixel;
951     int x,y;
952     int oddwidth;
953
954     oddwidth=width & 3;
955     width=width/4;
956     for (y=0; y<height; y++) {
957         srcpixel=srcbits;
958         dstpixel=dstbits;
959         for (x=0; x<width; x++) {
960             /* Do 4 pixels at a time: 3 dwords in and 4 words out */
961             DWORD srcval1,srcval2;
962             srcval1=srcpixel[0];
963             dstpixel[0]=((srcval1 <<  7) & 0x7c00) | /* l1 */
964                         ((srcval1 >>  6) & 0x03e0) | /* g1 */
965                         ((srcval1 >> 19) & 0x001f);  /* h1 */
966             srcval2=srcpixel[1];
967             dstpixel[1]=((srcval1 >> 17) & 0x7c00) | /* l2 */
968                         ((srcval2 <<  2) & 0x03e0) | /* g2 */
969                         ((srcval2 >> 11) & 0x001f);  /* h2 */
970             srcval1=srcpixel[2];
971             dstpixel[2]=((srcval2 >>  9) & 0x7c00) | /* l3 */
972                         ((srcval2 >> 22) & 0x03e0) | /* g3 */
973                         ((srcval1 >>  3) & 0x001f);  /* h3 */
974             dstpixel[3]=((srcval1 >>  1) & 0x7c00) | /* l4 */
975                         ((srcval1 >> 14) & 0x03e0) | /* g4 */
976                         ((srcval1 >> 27) & 0x001f);  /* h4 */
977             srcpixel+=3;
978             dstpixel+=4;
979         }
980         /* And now up to 3 odd pixels */
981         srcbyte=(LPBYTE)srcpixel;
982         for (x=0; x<oddwidth; x++) {
983             WORD dstval;
984             dstval =((srcbyte[0] << 7) & 0x7c00);    /* l */
985             dstval|=((srcbyte[1] << 2) & 0x03e0);    /* g */
986             dstval|=((srcbyte[2] >> 3) & 0x001f);    /* h */
987             *dstpixel++=dstval;
988             srcbyte+=3;
989         }
990         srcbits = (char*)srcbits + srclinebytes;
991         dstbits = (char*)dstbits + dstlinebytes;
992     }
993 }
994
995 static void X11DRV_DIB_Convert_888_to_565_asis(int width, int height,
996                                     const void* srcbits, int srclinebytes,
997                                     void* dstbits, int dstlinebytes)
998 {
999     const DWORD* srcpixel;
1000     const BYTE* srcbyte;
1001     WORD* dstpixel;
1002     int x,y;
1003     int oddwidth;
1004
1005     oddwidth=width & 3;
1006     width=width/4;
1007     for (y=0; y<height; y++) {
1008         srcpixel=srcbits;
1009         dstpixel=dstbits;
1010         for (x=0; x<width; x++) {
1011             /* Do 4 pixels at a time: 3 dwords in and 4 words out */
1012             DWORD srcval1,srcval2;
1013             srcval1=srcpixel[0];
1014             dstpixel[0]=((srcval1 >>  3) & 0x001f) | /* l1 */
1015                         ((srcval1 >>  5) & 0x07e0) | /* g1 */
1016                         ((srcval1 >>  8) & 0xf800);  /* h1 */
1017             srcval2=srcpixel[1];
1018             dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
1019                         ((srcval2 <<  3) & 0x07e0) | /* g2 */
1020                         ( srcval2        & 0xf800);  /* h2 */
1021             srcval1=srcpixel[2];
1022             dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
1023                         ((srcval2 >> 21) & 0x07e0) | /* g3 */
1024                         ((srcval1 <<  8) & 0xf800);  /* h3 */
1025             dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
1026                         ((srcval1 >> 13) & 0x07e0) | /* g4 */
1027                         ((srcval1 >> 16) & 0xf800);  /* h4 */
1028             srcpixel+=3;
1029             dstpixel+=4;
1030         }
1031         /* And now up to 3 odd pixels */
1032         srcbyte=(LPBYTE)srcpixel;
1033         for (x=0; x<oddwidth; x++) {
1034             WORD dstval;
1035             dstval =((srcbyte[0] >> 3) & 0x001f);    /* l */
1036             dstval|=((srcbyte[1] << 3) & 0x07e0);    /* g */
1037             dstval|=((srcbyte[2] << 8) & 0xf800);    /* h */
1038             *dstpixel++=dstval;
1039             srcbyte+=3;
1040         }
1041         srcbits = (char*)srcbits + srclinebytes;
1042         dstbits = (char*)dstbits + dstlinebytes;
1043     }
1044 }
1045
1046 static void X11DRV_DIB_Convert_888_to_565_reverse(int width, int height,
1047                                     const void* srcbits, int srclinebytes,
1048                                     void* dstbits, int dstlinebytes)
1049 {
1050     const DWORD* srcpixel;
1051     const BYTE* srcbyte;
1052     WORD* dstpixel;
1053     int x,y;
1054     int oddwidth;
1055
1056     oddwidth=width & 3;
1057     width=width/4;
1058     for (y=0; y<height; y++) {
1059         srcpixel=srcbits;
1060         dstpixel=dstbits;
1061         for (x=0; x<width; x++) {
1062             /* Do 4 pixels at a time: 3 dwords in and 4 words out */
1063             DWORD srcval1,srcval2;
1064             srcval1=srcpixel[0];
1065             dstpixel[0]=((srcval1 <<  8) & 0xf800) | /* l1 */
1066                         ((srcval1 >>  5) & 0x07e0) | /* g1 */
1067                         ((srcval1 >> 19) & 0x001f);  /* h1 */
1068             srcval2=srcpixel[1];
1069             dstpixel[1]=((srcval1 >> 16) & 0xf800) | /* l2 */
1070                         ((srcval2 <<  3) & 0x07e0) | /* g2 */
1071                         ((srcval2 >> 11) & 0x001f);  /* h2 */
1072             srcval1=srcpixel[2];
1073             dstpixel[2]=((srcval2 >>  8) & 0xf800) | /* l3 */
1074                         ((srcval2 >> 21) & 0x07e0) | /* g3 */
1075                         ((srcval1 >>  3) & 0x001f);  /* h3 */
1076             dstpixel[3]=(srcval1         & 0xf800) | /* l4 */
1077                         ((srcval1 >> 13) & 0x07e0) | /* g4 */
1078                         ((srcval1 >> 27) & 0x001f);  /* h4 */
1079             srcpixel+=3;
1080             dstpixel+=4;
1081         }
1082         /* And now up to 3 odd pixels */
1083         srcbyte=(LPBYTE)srcpixel;
1084         for (x=0; x<oddwidth; x++) {
1085             WORD dstval;
1086             dstval =((srcbyte[0] << 8) & 0xf800);    /* l */
1087             dstval|=((srcbyte[1] << 3) & 0x07e0);    /* g */
1088             dstval|=((srcbyte[2] >> 3) & 0x001f);    /* h */
1089             *dstpixel++=dstval;
1090             srcbyte+=3;
1091         }
1092         srcbits = (char*)srcbits + srclinebytes;
1093         dstbits = (char*)dstbits + dstlinebytes;
1094     }
1095 }
1096
1097 static void X11DRV_DIB_Convert_888_to_0888_asis(int width, int height,
1098                                     const void* srcbits, int srclinebytes,
1099                                     void* dstbits, int dstlinebytes)
1100 {
1101     const DWORD* srcpixel;
1102     DWORD* dstpixel;
1103     int x,y;
1104     int oddwidth;
1105
1106     oddwidth=width & 3;
1107     width=width/4;
1108     for (y=0; y<height; y++) {
1109         srcpixel=srcbits;
1110         dstpixel=dstbits;
1111         for (x=0; x<width; x++) {
1112             /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1113             DWORD srcval1,srcval2;
1114             srcval1=srcpixel[0];
1115             dstpixel[0]=( srcval1        & 0x00ffffff);  /* h1, g1, l1 */
1116             srcval2=srcpixel[1];
1117             dstpixel[1]=( srcval1 >> 24) |              /* l2 */
1118                         ((srcval2 <<  8) & 0x00ffff00); /* h2, g2 */
1119             srcval1=srcpixel[2];
1120             dstpixel[2]=( srcval2 >> 16) |              /* g3, l3 */
1121                         ((srcval1 << 16) & 0x00ff0000); /* h3 */
1122             dstpixel[3]=( srcval1 >>  8);               /* h4, g4, l4 */
1123             srcpixel+=3;
1124             dstpixel+=4;
1125         }
1126         /* And now up to 3 odd pixels */
1127         for (x=0; x<oddwidth; x++) {
1128             DWORD srcval;
1129             srcval=*srcpixel;
1130             srcpixel=(LPDWORD)(((char*)srcpixel)+3);
1131             *dstpixel++=( srcval         & 0x00ffffff); /* h, g, l */
1132         }
1133         srcbits = (char*)srcbits + srclinebytes;
1134         dstbits = (char*)dstbits + dstlinebytes;
1135     }
1136 }
1137
1138 static void X11DRV_DIB_Convert_888_to_0888_reverse(int width, int height,
1139                                     const void* srcbits, int srclinebytes,
1140                                     void* dstbits, int dstlinebytes)
1141 {
1142     const DWORD* srcpixel;
1143     DWORD* dstpixel;
1144     int x,y;
1145     int oddwidth;
1146
1147     oddwidth=width & 3;
1148     width=width/4;
1149     for (y=0; y<height; y++) {
1150         srcpixel=srcbits;
1151         dstpixel=dstbits;
1152         for (x=0; x<width; x++) {
1153             /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1154             DWORD srcval1,srcval2;
1155
1156             srcval1=srcpixel[0];
1157             dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */
1158                         ( srcval1        & 0x00ff00) | /* g1 */
1159                         ((srcval1 << 16) & 0xff0000);  /* l1 */
1160             srcval2=srcpixel[1];
1161             dstpixel[1]=((srcval1 >>  8) & 0xff0000) | /* l2 */
1162                         ((srcval2 <<  8) & 0x00ff00) | /* g2 */
1163                         ((srcval2 >>  8) & 0x0000ff);  /* h2 */
1164             srcval1=srcpixel[2];
1165             dstpixel[2]=( srcval2        & 0xff0000) | /* l3 */
1166                         ((srcval2 >> 16) & 0x00ff00) | /* g3 */
1167                         ( srcval1        & 0x0000ff);  /* h3 */
1168             dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */
1169                         ((srcval1 >>  8) & 0x00ff00) | /* g4 */
1170                         ((srcval1 <<  8) & 0xff0000);  /* l4 */
1171             srcpixel+=3;
1172             dstpixel+=4;
1173         }
1174         /* And now up to 3 odd pixels */
1175         for (x=0; x<oddwidth; x++) {
1176             DWORD srcval;
1177             srcval=*srcpixel;
1178             srcpixel=(LPDWORD)(((char*)srcpixel)+3);
1179             *dstpixel++=((srcval  >> 16) & 0x0000ff) | /* h */
1180                         ( srcval         & 0x00ff00) | /* g */
1181                         ((srcval  << 16) & 0xff0000);  /* l */
1182         }
1183         srcbits = (char*)srcbits + srclinebytes;
1184         dstbits = (char*)dstbits + dstlinebytes;
1185     }
1186 }
1187
1188 static void X11DRV_DIB_Convert_rgb888_to_any0888(int width, int height,
1189                                     const void* srcbits, int srclinebytes,
1190                                     void* dstbits, int dstlinebytes,
1191                                     DWORD rdst, DWORD gdst, DWORD bdst)
1192 {
1193     int rLeftShift,gLeftShift,bLeftShift;
1194     const BYTE* srcpixel;
1195     DWORD* dstpixel;
1196     int x,y;
1197
1198     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1199     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1200     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1201     for (y=0; y<height; y++) {
1202         srcpixel=srcbits;
1203         dstpixel=dstbits;
1204         for (x=0; x<width; x++) {
1205             *dstpixel++=(srcpixel[0] << bLeftShift) | /* b */
1206                         (srcpixel[1] << gLeftShift) | /* g */
1207                         (srcpixel[2] << rLeftShift);  /* r */
1208             srcpixel+=3;
1209         }
1210         srcbits = (char*)srcbits + srclinebytes;
1211         dstbits = (char*)dstbits + dstlinebytes;
1212     }
1213 }
1214
1215 static void X11DRV_DIB_Convert_bgr888_to_any0888(int width, int height,
1216                                     const void* srcbits, int srclinebytes,
1217                                     void* dstbits, int dstlinebytes,
1218                                     DWORD rdst, DWORD gdst, DWORD bdst)
1219 {
1220     int rLeftShift,gLeftShift,bLeftShift;
1221     const BYTE* srcpixel;
1222     DWORD* dstpixel;
1223     int x,y;
1224
1225     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1226     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1227     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1228     for (y=0; y<height; y++) {
1229         srcpixel=srcbits;
1230         dstpixel=dstbits;
1231         for (x=0; x<width; x++) {
1232             *dstpixel++=(srcpixel[0] << rLeftShift) | /* r */
1233                         (srcpixel[1] << gLeftShift) | /* g */
1234                         (srcpixel[2] << bLeftShift);  /* b */
1235             srcpixel+=3;
1236         }
1237         srcbits = (char*)srcbits + srclinebytes;
1238         dstbits = (char*)dstbits + dstlinebytes;
1239     }
1240 }
1241
1242 /*
1243  * 32 bit conversions
1244  */
1245
1246 static void X11DRV_DIB_Convert_0888_reverse(int width, int height,
1247                                     const void* srcbits, int srclinebytes,
1248                                     void* dstbits, int dstlinebytes)
1249 {
1250     const DWORD* srcpixel;
1251     DWORD* dstpixel;
1252     int x,y;
1253
1254     for (y=0; y<height; y++) {
1255         srcpixel=srcbits;
1256         dstpixel=dstbits;
1257         for (x=0; x<width; x++) {
1258             DWORD srcval;
1259             srcval=*srcpixel++;
1260             *dstpixel++=((srcval << 16) & 0x00ff0000) | /* h */
1261                         ( srcval        & 0x0000ff00) | /* g */
1262                         ((srcval >> 16) & 0x000000ff);  /* l */
1263         }
1264         srcbits = (char*)srcbits + srclinebytes;
1265         dstbits = (char*)dstbits + dstlinebytes;
1266     }
1267 }
1268
1269 static void X11DRV_DIB_Convert_0888_any(int width, int height,
1270                                     const void* srcbits, int srclinebytes,
1271                                     DWORD rsrc, DWORD gsrc, DWORD bsrc,
1272                                     void* dstbits, int dstlinebytes,
1273                                     DWORD rdst, DWORD gdst, DWORD bdst)
1274 {
1275     int rRightShift,gRightShift,bRightShift;
1276     int rLeftShift,gLeftShift,bLeftShift;
1277     const DWORD* srcpixel;
1278     DWORD* dstpixel;
1279     int x,y;
1280
1281     rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1282     gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1283     bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1284     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1285     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1286     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1287     for (y=0; y<height; y++) {
1288         srcpixel=srcbits;
1289         dstpixel=dstbits;
1290         for (x=0; x<width; x++) {
1291             DWORD srcval;
1292             srcval=*srcpixel++;
1293             *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) |
1294                         (((srcval >> gRightShift) & 0xff) << gLeftShift) |
1295                         (((srcval >> bRightShift) & 0xff) << bLeftShift);
1296         }
1297         srcbits = (char*)srcbits + srclinebytes;
1298         dstbits = (char*)dstbits + dstlinebytes;
1299     }
1300 }
1301
1302 static void X11DRV_DIB_Convert_0888_to_555_asis(int width, int height,
1303                                     const void* srcbits, int srclinebytes,
1304                                     void* dstbits, int dstlinebytes)
1305 {
1306     const DWORD* srcpixel;
1307     WORD* dstpixel;
1308     int x,y;
1309
1310     for (y=0; y<height; y++) {
1311         srcpixel=srcbits;
1312         dstpixel=dstbits;
1313         for (x=0; x<width; x++) {
1314             DWORD srcval;
1315             srcval=*srcpixel++;
1316             *dstpixel++=((srcval >> 9) & 0x7c00) | /* h */
1317                         ((srcval >> 6) & 0x03e0) | /* g */
1318                         ((srcval >> 3) & 0x001f);  /* l */
1319         }
1320         srcbits = (char*)srcbits + srclinebytes;
1321         dstbits = (char*)dstbits + dstlinebytes;
1322     }
1323 }
1324
1325 static void X11DRV_DIB_Convert_0888_to_555_reverse(int width, int height,
1326                                     const void* srcbits, int srclinebytes,
1327                                     void* dstbits, int dstlinebytes)
1328 {
1329     const DWORD* srcpixel;
1330     WORD* dstpixel;
1331     int x,y;
1332
1333     for (y=0; y<height; y++) {
1334         srcpixel=srcbits;
1335         dstpixel=dstbits;
1336         for (x=0; x<width; x++) {
1337             DWORD srcval;
1338             srcval=*srcpixel++;
1339             *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1340                         ((srcval >>  6) & 0x03e0) | /* g */
1341                         ((srcval <<  7) & 0x7c00);  /* l */
1342         }
1343         srcbits = (char*)srcbits + srclinebytes;
1344         dstbits = (char*)dstbits + dstlinebytes;
1345     }
1346 }
1347
1348 static void X11DRV_DIB_Convert_0888_to_565_asis(int width, int height,
1349                                     const void* srcbits, int srclinebytes,
1350                                     void* dstbits, int dstlinebytes)
1351 {
1352     const DWORD* srcpixel;
1353     WORD* dstpixel;
1354     int x,y;
1355
1356     for (y=0; y<height; y++) {
1357         srcpixel=srcbits;
1358         dstpixel=dstbits;
1359         for (x=0; x<width; x++) {
1360             DWORD srcval;
1361             srcval=*srcpixel++;
1362             *dstpixel++=((srcval >> 8) & 0xf800) | /* h */
1363                         ((srcval >> 5) & 0x07e0) | /* g */
1364                         ((srcval >> 3) & 0x001f);  /* l */
1365         }
1366         srcbits = (char*)srcbits + srclinebytes;
1367         dstbits = (char*)dstbits + dstlinebytes;
1368     }
1369 }
1370
1371 static void X11DRV_DIB_Convert_0888_to_565_reverse(int width, int height,
1372                                     const void* srcbits, int srclinebytes,
1373                                     void* dstbits, int dstlinebytes)
1374 {
1375     const DWORD* srcpixel;
1376     WORD* dstpixel;
1377     int x,y;
1378
1379     for (y=0; y<height; y++) {
1380         srcpixel=srcbits;
1381         dstpixel=dstbits;
1382         for (x=0; x<width; x++) {
1383             DWORD srcval;
1384             srcval=*srcpixel++;
1385             *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1386                         ((srcval >>  5) & 0x07e0) | /* g */
1387                         ((srcval <<  8) & 0xf800);  /* l */
1388         }
1389         srcbits = (char*)srcbits + srclinebytes;
1390         dstbits = (char*)dstbits + dstlinebytes;
1391     }
1392 }
1393
1394 static void X11DRV_DIB_Convert_any0888_to_5x5(int width, int height,
1395                                     const void* srcbits, int srclinebytes,
1396                                     DWORD rsrc, DWORD gsrc, DWORD bsrc,
1397                                     void* dstbits, int dstlinebytes,
1398                                     WORD rdst, WORD gdst, WORD bdst)
1399 {
1400     int rRightShift,gRightShift,bRightShift;
1401     int rLeftShift,gLeftShift,bLeftShift;
1402     const DWORD* srcpixel;
1403     WORD* dstpixel;
1404     int x,y;
1405
1406     /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1407      * contains 0x11223344.
1408      * - first we shift 0x11223344 right by rRightShift to bring the most
1409      *   significant bits of the red components in the bottom 5 (or 6) bits
1410      *   -> 0x4488c
1411      * - then we remove non red bits by anding with the modified rdst (0x1f)
1412      *   -> 0x0c
1413      * - finally shift these bits left by rLeftShift so that they end up in
1414      *   the right place
1415      *   -> 0x3000
1416      */
1417     rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3;
1418     gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1419     gRightShift+=(gdst==0x07e0?2:3);
1420     bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3;
1421
1422     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1423     rdst=rdst >> rLeftShift;
1424     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1425     gdst=gdst >> gLeftShift;
1426     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1427     bdst=bdst >> bLeftShift;
1428
1429     for (y=0; y<height; y++) {
1430         srcpixel=srcbits;
1431         dstpixel=dstbits;
1432         for (x=0; x<width; x++) {
1433             DWORD srcval;
1434             srcval=*srcpixel++;
1435             *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) |
1436                         (((srcval >> gRightShift) & gdst) << gLeftShift) |
1437                         (((srcval >> bRightShift) & bdst) << bLeftShift);
1438         }
1439         srcbits = (char*)srcbits + srclinebytes;
1440         dstbits = (char*)dstbits + dstlinebytes;
1441     }
1442 }
1443
1444 static void X11DRV_DIB_Convert_0888_to_888_asis(int width, int height,
1445                                     const void* srcbits, int srclinebytes,
1446                                     void* dstbits, int dstlinebytes)
1447 {
1448     const DWORD* srcpixel;
1449     DWORD* dstpixel;
1450     BYTE* dstbyte;
1451     int x,y;
1452     int oddwidth;
1453
1454     oddwidth=width & 3;
1455     width=width/4;
1456     for (y=0; y<height; y++) {
1457         srcpixel=srcbits;
1458         dstpixel=dstbits;
1459         for (x=0; x<width; x++) {
1460             /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1461             DWORD srcval;
1462             srcval=((*srcpixel++)       & 0x00ffffff);  /* h1, g1, l1*/
1463             *dstpixel++=srcval | ((*srcpixel)   << 24); /* h2 */
1464             srcval=((*srcpixel++ >> 8 ) & 0x0000ffff);  /* g2, l2 */
1465             *dstpixel++=srcval | ((*srcpixel)   << 16); /* h3, g3 */
1466             srcval=((*srcpixel++ >> 16) & 0x000000ff);  /* l3 */
1467             *dstpixel++=srcval | ((*srcpixel++) << 8);  /* h4, g4, l4 */
1468         }
1469         /* And now up to 3 odd pixels */
1470         dstbyte=(BYTE*)dstpixel;
1471         for (x=0; x<oddwidth; x++) {
1472             DWORD srcval;
1473             srcval=*srcpixel++;
1474             *((WORD*)dstbyte)++=srcval;                 /* h, g */
1475             *dstbyte++=srcval >> 16;                    /* l */
1476         }
1477         srcbits = (char*)srcbits + srclinebytes;
1478         dstbits = (char*)dstbits + dstlinebytes;
1479     }
1480 }
1481
1482 static void X11DRV_DIB_Convert_0888_to_888_reverse(int width, int height,
1483                                     const void* srcbits, int srclinebytes,
1484                                     void* dstbits, int dstlinebytes)
1485 {
1486     const DWORD* srcpixel;
1487     DWORD* dstpixel;
1488     BYTE* dstbyte;
1489     int x,y;
1490     int oddwidth;
1491
1492     oddwidth=width & 3;
1493     width=width/4;
1494     for (y=0; y<height; y++) {
1495         srcpixel=srcbits;
1496         dstpixel=dstbits;
1497         for (x=0; x<width; x++) {
1498             /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1499             DWORD srcval1,srcval2;
1500             srcval1=*srcpixel++;
1501             srcval2=    ((srcval1 >> 16) & 0x000000ff) | /* h1 */
1502                         ( srcval1        & 0x0000ff00) | /* g1 */
1503                         ((srcval1 << 16) & 0x00ff0000);  /* l1 */
1504             srcval1=*srcpixel++;
1505             *dstpixel++=srcval2 |
1506                         ((srcval1 <<  8) & 0xff000000);  /* h2 */
1507             srcval2=    ((srcval1 >>  8) & 0x000000ff) | /* g2 */
1508                         ((srcval1 <<  8) & 0x0000ff00);  /* l2 */
1509             srcval1=*srcpixel++;
1510             *dstpixel++=srcval2 |
1511                         ( srcval1        & 0x00ff0000) | /* h3 */
1512                         ((srcval1 << 16) & 0xff000000);  /* g3 */
1513             srcval2=    ( srcval1        & 0x000000ff);  /* l3 */
1514             srcval1=*srcpixel++;
1515             *dstpixel++=srcval2 |
1516                         ((srcval1 >>  8) & 0x0000ff00) | /* h4 */
1517                         ((srcval1 <<  8) & 0x00ff0000) | /* g4 */
1518                         ( srcval1 << 24);                /* l4 */
1519         }
1520         /* And now up to 3 odd pixels */
1521         dstbyte=(BYTE*)dstpixel;
1522         for (x=0; x<oddwidth; x++) {
1523             DWORD srcval;
1524             srcval=*srcpixel++;
1525             *((WORD*)dstbyte)++=((srcval >> 16) & 0x00ff) | /* h */
1526                                 (srcval         & 0xff00);  /* g */
1527             *dstbyte++=srcval;                              /* l */
1528         }
1529         srcbits = (char*)srcbits + srclinebytes;
1530         dstbits = (char*)dstbits + dstlinebytes;
1531     }
1532 }
1533
1534 static void X11DRV_DIB_Convert_any0888_to_rgb888(int width, int height,
1535                                     const void* srcbits, int srclinebytes,
1536                                     DWORD rsrc, DWORD gsrc, DWORD bsrc,
1537                                     void* dstbits, int dstlinebytes)
1538 {
1539     int rRightShift,gRightShift,bRightShift;
1540     const DWORD* srcpixel;
1541     BYTE* dstpixel;
1542     int x,y;
1543
1544     rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1545     gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1546     bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1547     for (y=0; y<height; y++) {
1548         srcpixel=srcbits;
1549         dstpixel=dstbits;
1550         for (x=0; x<width; x++) {
1551             DWORD srcval;
1552             srcval=*srcpixel++;
1553             dstpixel[0]=(srcval >> bRightShift); /* b */
1554             dstpixel[1]=(srcval >> gRightShift); /* g */
1555             dstpixel[2]=(srcval >> rRightShift); /* r */
1556             dstpixel+=3;
1557         }
1558         srcbits = (char*)srcbits + srclinebytes;
1559         dstbits = (char*)dstbits + dstlinebytes;
1560     }
1561 }
1562
1563 static void X11DRV_DIB_Convert_any0888_to_bgr888(int width, int height,
1564                                     const void* srcbits, int srclinebytes,
1565                                     DWORD rsrc, DWORD gsrc, DWORD bsrc,
1566                                     void* dstbits, int dstlinebytes)
1567 {
1568     int rRightShift,gRightShift,bRightShift;
1569     const DWORD* srcpixel;
1570     BYTE* dstpixel;
1571     int x,y;
1572
1573     rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1574     gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1575     bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1576     for (y=0; y<height; y++) {
1577         srcpixel=srcbits;
1578         dstpixel=dstbits;
1579         for (x=0; x<width; x++) {
1580             DWORD srcval;
1581             srcval=*srcpixel++;
1582             dstpixel[0]=(srcval >> rRightShift); /* r */
1583             dstpixel[1]=(srcval >> gRightShift); /* g */
1584             dstpixel[2]=(srcval >> bRightShift); /* b */
1585             dstpixel+=3;
1586         }
1587         srcbits = (char*)srcbits + srclinebytes;
1588         dstbits = (char*)dstbits + dstlinebytes;
1589     }
1590 }
1591
1592 /***********************************************************************
1593  *           X11DRV_DIB_SetImageBits_1
1594  *
1595  * SetDIBits for a 1-bit deep DIB.
1596  */
1597 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
1598                                 DWORD srcwidth, DWORD dstwidth, int left,
1599                                 int *colors, XImage *bmpImage, DWORD linebytes)
1600 {
1601     int h;
1602     const BYTE* srcbyte;
1603     BYTE srcval, extra;
1604     DWORD i, x;
1605
1606     if (lines < 0 ) {
1607         lines = -lines;
1608         srcbits = srcbits + linebytes * (lines - 1);
1609         linebytes = -linebytes;
1610     }
1611
1612     if ((extra = (left & 7)) != 0) {
1613         left &= ~7;
1614         dstwidth += extra;
1615     }
1616     srcbits += left >> 3;
1617
1618     /* ==== pal 1 dib -> any bmp format ==== */
1619     for (h = lines-1; h >=0; h--) {
1620         srcbyte=srcbits;
1621         /* FIXME: should avoid putting x<left pixels (minor speed issue) */
1622         for (i = dstwidth/8, x = left; i > 0; i--) {
1623             srcval=*srcbyte++;
1624             XPutPixel( bmpImage, x++, h, colors[ srcval >> 7] );
1625             XPutPixel( bmpImage, x++, h, colors[(srcval >> 6) & 1] );
1626             XPutPixel( bmpImage, x++, h, colors[(srcval >> 5) & 1] );
1627             XPutPixel( bmpImage, x++, h, colors[(srcval >> 4) & 1] );
1628             XPutPixel( bmpImage, x++, h, colors[(srcval >> 3) & 1] );
1629             XPutPixel( bmpImage, x++, h, colors[(srcval >> 2) & 1] );
1630             XPutPixel( bmpImage, x++, h, colors[(srcval >> 1) & 1] );
1631             XPutPixel( bmpImage, x++, h, colors[ srcval       & 1] );
1632         }
1633         if (dstwidth % 8){
1634             srcval=*srcbyte;
1635             switch (dstwidth & 7)
1636             {
1637             case 7: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1638             case 6: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1639             case 5: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1640             case 4: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1641             case 3: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1642             case 2: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1643             case 1: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]);
1644             }
1645         }
1646         srcbits += linebytes;
1647     }
1648 }
1649
1650 /***********************************************************************
1651  *           X11DRV_DIB_GetImageBits_1
1652  *
1653  * GetDIBits for a 1-bit deep DIB.
1654  */
1655 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
1656                                        DWORD dstwidth, DWORD srcwidth,
1657                                        RGBQUAD *colors, PALETTEENTRY *srccolors,
1658                                 XImage *bmpImage, DWORD linebytes )
1659 {
1660     DWORD x;
1661     int h;
1662
1663     if (lines < 0 ) {
1664         lines = -lines;
1665         dstbits = dstbits + linebytes * (lines - 1);
1666         linebytes = -linebytes;
1667     }
1668
1669     switch (bmpImage->depth)
1670     {
1671     case 1:
1672     case 4:
1673         if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1674             /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
1675             BYTE* dstbyte;
1676
1677             for (h=lines-1; h>=0; h--) {
1678                 BYTE dstval;
1679                 dstbyte=dstbits;
1680                 dstval=0;
1681                 for (x=0; x<dstwidth; x++) {
1682                     PALETTEENTRY srcval;
1683                     srcval=srccolors[XGetPixel(bmpImage, x, h)];
1684                     dstval|=(X11DRV_DIB_GetNearestIndex
1685                              (colors, 2,
1686                               srcval.peRed,
1687                               srcval.peGreen,
1688                               srcval.peBlue) << (7 - (x & 7)));
1689                     if ((x&7)==7) {
1690                         *dstbyte++=dstval;
1691                         dstval=0;
1692                     }
1693                 }
1694                 if ((dstwidth&7)!=0) {
1695                     *dstbyte=dstval;
1696                 }
1697                 dstbits += linebytes;
1698             }
1699         } else {
1700             goto notsupported;
1701         }
1702         break;
1703
1704     case 8:
1705         if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1706             /* ==== pal 8 bmp -> pal 1 dib ==== */
1707             const void* srcbits;
1708             const BYTE* srcpixel;
1709             BYTE* dstbyte;
1710
1711             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1712
1713             for (h=0; h<lines; h++) {
1714                 BYTE dstval;
1715                 srcpixel=srcbits;
1716                 dstbyte=dstbits;
1717                 dstval=0;
1718                 for (x=0; x<dstwidth; x++) {
1719                     PALETTEENTRY srcval;
1720                     srcval=srccolors[(int)*srcpixel++];
1721                     dstval|=(X11DRV_DIB_GetNearestIndex
1722                              (colors, 2,
1723                               srcval.peRed,
1724                               srcval.peGreen,
1725                               srcval.peBlue) << (7-(x&7)) );
1726                     if ((x&7)==7) {
1727                         *dstbyte++=dstval;
1728                         dstval=0;
1729                     }
1730                 }
1731                 if ((dstwidth&7)!=0) {
1732                     *dstbyte=dstval;
1733                 }
1734                 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1735                 dstbits += linebytes;
1736             }
1737         } else {
1738             goto notsupported;
1739         }
1740         break;
1741
1742     case 15:
1743     case 16:
1744         {
1745             const void* srcbits;
1746             const WORD* srcpixel;
1747             BYTE* dstbyte;
1748
1749             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1750
1751             if (bmpImage->green_mask==0x03e0) {
1752                 if (bmpImage->red_mask==0x7c00) {
1753                     /* ==== rgb 555 bmp -> pal 1 dib ==== */
1754                     for (h=0; h<lines; h++) {
1755                         BYTE dstval;
1756                         srcpixel=srcbits;
1757                         dstbyte=dstbits;
1758                         dstval=0;
1759                         for (x=0; x<dstwidth; x++) {
1760                             WORD srcval;
1761                             srcval=*srcpixel++;
1762                             dstval|=(X11DRV_DIB_GetNearestIndex
1763                                      (colors, 2,
1764                                       ((srcval >>  7) & 0xf8) | /* r */
1765                                       ((srcval >> 12) & 0x07),
1766                                       ((srcval >>  2) & 0xf8) | /* g */
1767                                       ((srcval >>  7) & 0x07),
1768                                       ((srcval <<  3) & 0xf8) | /* b */
1769                                       ((srcval >>  2) & 0x07) ) << (7-(x&7)) );
1770                             if ((x&7)==7) {
1771                                 *dstbyte++=dstval;
1772                                 dstval=0;
1773                             }
1774                         }
1775                         if ((dstwidth&7)!=0) {
1776                             *dstbyte=dstval;
1777                         }
1778                         srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1779                         dstbits += linebytes;
1780                     }
1781                 } else if (bmpImage->blue_mask==0x7c00) {
1782                     /* ==== bgr 555 bmp -> pal 1 dib ==== */
1783                     for (h=0; h<lines; h++) {
1784                         WORD dstval;
1785                         srcpixel=srcbits;
1786                         dstbyte=dstbits;
1787                         dstval=0;
1788                         for (x=0; x<dstwidth; x++) {
1789                             BYTE srcval;
1790                             srcval=*srcpixel++;
1791                             dstval|=(X11DRV_DIB_GetNearestIndex
1792                                      (colors, 2,
1793                                       ((srcval <<  3) & 0xf8) | /* r */
1794                                       ((srcval >>  2) & 0x07),
1795                                       ((srcval >>  2) & 0xf8) | /* g */
1796                                       ((srcval >>  7) & 0x07),
1797                                       ((srcval >>  7) & 0xf8) | /* b */
1798                                       ((srcval >> 12) & 0x07) ) << (7-(x&7)) );
1799                             if ((x&7)==7) {
1800                                 *dstbyte++=dstval;
1801                                 dstval=0;
1802                             }
1803                         }
1804                         if ((dstwidth&7)!=0) {
1805                             *dstbyte=dstval;
1806                         }
1807                         srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1808                         dstbits += linebytes;
1809                     }
1810                 } else {
1811                     goto notsupported;
1812                 }
1813             } else if (bmpImage->green_mask==0x07e0) {
1814                 if (bmpImage->red_mask==0xf800) {
1815                     /* ==== rgb 565 bmp -> pal 1 dib ==== */
1816                     for (h=0; h<lines; h++) {
1817                         BYTE dstval;
1818                         srcpixel=srcbits;
1819                         dstbyte=dstbits;
1820                         dstval=0;
1821                         for (x=0; x<dstwidth; x++) {
1822                             WORD srcval;
1823                             srcval=*srcpixel++;
1824                             dstval|=(X11DRV_DIB_GetNearestIndex
1825                                      (colors, 2,
1826                                       ((srcval >>  8) & 0xf8) | /* r */
1827                                       ((srcval >> 13) & 0x07),
1828                                       ((srcval >>  3) & 0xfc) | /* g */
1829                                       ((srcval >>  9) & 0x03),
1830                                       ((srcval <<  3) & 0xf8) | /* b */
1831                                       ((srcval >>  2) & 0x07) ) << (7-(x&7)) );
1832                             if ((x&7)==7) {
1833                                 *dstbyte++=dstval;
1834                                 dstval=0;
1835                             }
1836                         }
1837                         if ((dstwidth&7)!=0) {
1838                             *dstbyte=dstval;
1839                         }
1840                         srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1841                         dstbits += linebytes;
1842                     }
1843                 } else if (bmpImage->blue_mask==0xf800) {
1844                     /* ==== bgr 565 bmp -> pal 1 dib ==== */
1845                     for (h=0; h<lines; h++) {
1846                         BYTE dstval;
1847                         srcpixel=srcbits;
1848                         dstbyte=dstbits;
1849                         dstval=0;
1850                         for (x=0; x<dstwidth; x++) {
1851                             WORD srcval;
1852                             srcval=*srcpixel++;
1853                             dstval|=(X11DRV_DIB_GetNearestIndex
1854                                      (colors, 2,
1855                                       ((srcval <<  3) & 0xf8) | /* r */
1856                                       ((srcval >>  2) & 0x07),
1857                                       ((srcval >>  3) & 0xfc) | /* g */
1858                                       ((srcval >>  9) & 0x03),
1859                                       ((srcval >>  8) & 0xf8) | /* b */
1860                                       ((srcval >> 13) & 0x07) ) << (7-(x&7)) );
1861                             if ((x&7)==7) {
1862                                 *dstbyte++=dstval;
1863                                 dstval=0;
1864                             }
1865                         }
1866                         if ((dstwidth&7)!=0) {
1867                             *dstbyte=dstval;
1868                         }
1869                         srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1870                         dstbits += linebytes;
1871                     }
1872                 } else {
1873                     goto notsupported;
1874                 }
1875             } else {
1876                 goto notsupported;
1877             }
1878         }
1879         break;
1880
1881     case 24:
1882     case 32:
1883         {
1884             const void* srcbits;
1885             const BYTE *srcbyte;
1886             BYTE* dstbyte;
1887             int bytes_per_pixel;
1888
1889             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1890             bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
1891
1892             if (bmpImage->green_mask!=0x00ff00 ||
1893                 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1894                 goto notsupported;
1895             } else if (bmpImage->blue_mask==0xff) {
1896                 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
1897                 for (h=0; h<lines; h++) {
1898                     BYTE dstval;
1899                     srcbyte=srcbits;
1900                     dstbyte=dstbits;
1901                     dstval=0;
1902                     for (x=0; x<dstwidth; x++) {
1903                         dstval|=(X11DRV_DIB_GetNearestIndex
1904                                  (colors, 2,
1905                                   srcbyte[2],
1906                                   srcbyte[1],
1907                                   srcbyte[0]) << (7-(x&7)) );
1908                         srcbyte+=bytes_per_pixel;
1909                         if ((x&7)==7) {
1910                             *dstbyte++=dstval;
1911                             dstval=0;
1912                         }
1913                     }
1914                     if ((dstwidth&7)!=0) {
1915                         *dstbyte=dstval;
1916                     }
1917                     srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1918                     dstbits += linebytes;
1919                 }
1920             } else {
1921                 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
1922                 for (h=0; h<lines; h++) {
1923                     BYTE dstval;
1924                     srcbyte=srcbits;
1925                     dstbyte=dstbits;
1926                     dstval=0;
1927                     for (x=0; x<dstwidth; x++) {
1928                         dstval|=(X11DRV_DIB_GetNearestIndex
1929                                  (colors, 2,
1930                                   srcbyte[0],
1931                                   srcbyte[1],
1932                                   srcbyte[2]) << (7-(x&7)) );
1933                         srcbyte+=bytes_per_pixel;
1934                         if ((x&7)==7) {
1935                             *dstbyte++=dstval;
1936                             dstval=0;
1937                         }
1938                     }
1939                     if ((dstwidth&7)!=0) {
1940                         *dstbyte=dstval;
1941                     }
1942                     srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1943                     dstbits += linebytes;
1944                 }
1945             }
1946         }
1947         break;
1948
1949     default:
1950     notsupported:
1951         {
1952             BYTE* dstbyte;
1953             unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
1954
1955             /* ==== any bmp format -> pal 1 dib ==== */
1956             WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
1957                   bmpImage->bits_per_pixel, bmpImage->red_mask,
1958                   bmpImage->green_mask, bmpImage->blue_mask );
1959
1960             for (h=lines-1; h>=0; h--) {
1961                 BYTE dstval;
1962                 dstbyte=dstbits;
1963                 dstval=0;
1964                 for (x=0; x<dstwidth; x++) {
1965                     dstval|=(XGetPixel( bmpImage, x, h) >= white) << (7 - (x&7));
1966                     if ((x&7)==7) {
1967                         *dstbyte++=dstval;
1968                         dstval=0;
1969                     }
1970                 }
1971                 if ((dstwidth&7)!=0) {
1972                     *dstbyte=dstval;
1973                 }
1974                 dstbits += linebytes;
1975             }
1976         }
1977         break;
1978     }
1979 }
1980
1981 /***********************************************************************
1982  *           X11DRV_DIB_SetImageBits_4
1983  *
1984  * SetDIBits for a 4-bit deep DIB.
1985  */
1986 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
1987                                 DWORD srcwidth, DWORD dstwidth, int left,
1988                                 int *colors, XImage *bmpImage, DWORD linebytes)
1989 {
1990     int h;
1991     const BYTE* srcbyte;
1992     DWORD i, x;
1993
1994     if (lines < 0 ) {
1995         lines = -lines;
1996         srcbits = srcbits + linebytes * (lines - 1);
1997         linebytes = -linebytes;
1998     }
1999
2000     if (left & 1) {
2001         left--;
2002         dstwidth++;
2003     }
2004     srcbits += left >> 1;
2005
2006     /* ==== pal 4 dib -> any bmp format ==== */
2007     for (h = lines-1; h >= 0; h--) {
2008         srcbyte=srcbits;
2009         for (i = dstwidth/2, x = left; i > 0; i--) {
2010             BYTE srcval=*srcbyte++;
2011             XPutPixel( bmpImage, x++, h, colors[srcval >> 4] );
2012             XPutPixel( bmpImage, x++, h, colors[srcval & 0x0f] );
2013         }
2014         if (dstwidth & 1)
2015             XPutPixel( bmpImage, x, h, colors[*srcbyte >> 4] );
2016         srcbits += linebytes;
2017     }
2018 }
2019
2020
2021
2022 /***********************************************************************
2023  *           X11DRV_DIB_GetImageBits_4
2024  *
2025  * GetDIBits for a 4-bit deep DIB.
2026  */
2027 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
2028                                        DWORD srcwidth, DWORD dstwidth,
2029                                        RGBQUAD *colors, PALETTEENTRY *srccolors,
2030                                        XImage *bmpImage, DWORD linebytes )
2031 {
2032     DWORD x;
2033     int h;
2034     BYTE *bits;
2035
2036     if (lines < 0 )
2037     {
2038        lines = -lines;
2039        dstbits = dstbits + ( linebytes * (lines-1) );
2040        linebytes = -linebytes;
2041     }
2042
2043     bits = dstbits;
2044
2045     switch (bmpImage->depth) {
2046     case 1:
2047     case 4:
2048         if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2049             /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
2050             BYTE* dstbyte;
2051
2052             for (h = lines-1; h >= 0; h--) {
2053                 BYTE dstval;
2054                 dstbyte=dstbits;
2055                 dstval=0;
2056                 for (x = 0; x < dstwidth; x++) {
2057                     PALETTEENTRY srcval;
2058                     srcval=srccolors[XGetPixel(bmpImage, x, h)];
2059                     dstval|=(X11DRV_DIB_GetNearestIndex
2060                              (colors, 16,
2061                               srcval.peRed,
2062                               srcval.peGreen,
2063                               srcval.peBlue) << (4-((x&1)<<2)));
2064                     if ((x&1)==1) {
2065                         *dstbyte++=dstval;
2066                         dstval=0;
2067                     }
2068                 }
2069                 if ((dstwidth&1)!=0) {
2070                     *dstbyte=dstval;
2071                 }
2072                 dstbits += linebytes;
2073             }
2074         } else {
2075             goto notsupported;
2076         }
2077         break;
2078
2079     case 8:
2080         if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2081             /* ==== pal 8 bmp -> pal 4 dib ==== */
2082             const void* srcbits;
2083             const BYTE *srcpixel;
2084             BYTE* dstbyte;
2085
2086             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2087             for (h=0; h<lines; h++) {
2088                 BYTE dstval;
2089                 srcpixel=srcbits;
2090                 dstbyte=dstbits;
2091                 dstval=0;
2092                 for (x=0; x<dstwidth; x++) {
2093                     PALETTEENTRY srcval;
2094                     srcval = srccolors[(int)*srcpixel++];
2095                     dstval|=(X11DRV_DIB_GetNearestIndex
2096                              (colors, 16,
2097                               srcval.peRed,
2098                               srcval.peGreen,
2099                               srcval.peBlue) << (4*(1-(x&1))) );
2100                     if ((x&1)==1) {
2101                         *dstbyte++=dstval;
2102                         dstval=0;
2103                     }
2104                 }
2105                 if ((dstwidth&1)!=0) {
2106                     *dstbyte=dstval;
2107                 }
2108                 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2109                 dstbits += linebytes;
2110             }
2111         } else {
2112             goto notsupported;
2113         }
2114         break;
2115
2116     case 15:
2117     case 16:
2118         {
2119             const void* srcbits;
2120             const WORD* srcpixel;
2121             BYTE* dstbyte;
2122
2123             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2124
2125             if (bmpImage->green_mask==0x03e0) {
2126                 if (bmpImage->red_mask==0x7c00) {
2127                     /* ==== rgb 555 bmp -> pal 4 dib ==== */
2128                     for (h=0; h<lines; h++) {
2129                         BYTE dstval;
2130                         srcpixel=srcbits;
2131                         dstbyte=dstbits;
2132                         dstval=0;
2133                         for (x=0; x<dstwidth; x++) {
2134                             WORD srcval;
2135                             srcval=*srcpixel++;
2136                             dstval|=(X11DRV_DIB_GetNearestIndex
2137                                      (colors, 16,
2138                                       ((srcval >>  7) & 0xf8) | /* r */
2139                                       ((srcval >> 12) & 0x07),
2140                                       ((srcval >>  2) & 0xf8) | /* g */
2141                                       ((srcval >>  7) & 0x07),
2142                                       ((srcval <<  3) & 0xf8) | /* b */
2143                                       ((srcval >>  2) & 0x07) ) << ((1-(x&1))<<2) );
2144                             if ((x&1)==1) {
2145                                 *dstbyte++=dstval;
2146                                 dstval=0;
2147                             }
2148                         }
2149                         if ((dstwidth&1)!=0) {
2150                             *dstbyte=dstval;
2151                         }
2152                         srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2153                         dstbits += linebytes;
2154                     }
2155                 } else if (bmpImage->blue_mask==0x7c00) {
2156                     /* ==== bgr 555 bmp -> pal 4 dib ==== */
2157                     for (h=0; h<lines; h++) {
2158                         WORD dstval;
2159                         srcpixel=srcbits;
2160                         dstbyte=dstbits;
2161                         dstval=0;
2162                         for (x=0; x<dstwidth; x++) {
2163                             WORD srcval;
2164                             srcval=*srcpixel++;
2165                             dstval|=(X11DRV_DIB_GetNearestIndex
2166                                      (colors, 16,
2167                                       ((srcval <<  3) & 0xf8) | /* r */
2168                                       ((srcval >>  2) & 0x07),
2169                                       ((srcval >>  2) & 0xf8) | /* g */
2170                                       ((srcval >>  7) & 0x07),
2171                                       ((srcval >>  7) & 0xf8) | /* b */
2172                                       ((srcval >> 12) & 0x07) ) << ((1-(x&1))<<2) );
2173                             if ((x&1)==1) {
2174                                 *dstbyte++=dstval;
2175                                 dstval=0;
2176                             }
2177                         }
2178                         if ((dstwidth&1)!=0) {
2179                             *dstbyte=dstval;
2180                         }
2181                         srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2182                         dstbits += linebytes;
2183                     }
2184                 } else {
2185                     goto notsupported;
2186                 }
2187             } else if (bmpImage->green_mask==0x07e0) {
2188                 if (bmpImage->red_mask==0xf800) {
2189                     /* ==== rgb 565 bmp -> pal 4 dib ==== */
2190                     for (h=0; h<lines; h++) {
2191                         BYTE dstval;
2192                         srcpixel=srcbits;
2193                         dstbyte=dstbits;
2194                         dstval=0;
2195                         for (x=0; x<dstwidth; x++) {
2196                             WORD srcval;
2197                             srcval=*srcpixel++;
2198                             dstval|=(X11DRV_DIB_GetNearestIndex
2199                                      (colors, 16,
2200                                       ((srcval >>  8) & 0xf8) | /* r */
2201                                       ((srcval >> 13) & 0x07),
2202                                       ((srcval >>  3) & 0xfc) | /* g */
2203                                       ((srcval >>  9) & 0x03),
2204                                       ((srcval <<  3) & 0xf8) | /* b */
2205                                       ((srcval >>  2) & 0x07) ) << ((1-(x&1))<<2) );
2206                             if ((x&1)==1) {
2207                                 *dstbyte++=dstval;
2208                                 dstval=0;
2209                             }
2210                         }
2211                         if ((dstwidth&1)!=0) {
2212                             *dstbyte=dstval;
2213                         }
2214                         srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2215                         dstbits += linebytes;
2216                     }
2217                 } else if (bmpImage->blue_mask==0xf800) {
2218                     /* ==== bgr 565 bmp -> pal 4 dib ==== */
2219                     for (h=0; h<lines; h++) {
2220                         WORD dstval;
2221                         srcpixel=srcbits;
2222                         dstbyte=dstbits;
2223                         dstval=0;
2224                         for (x=0; x<dstwidth; x++) {
2225                             WORD srcval;
2226                             srcval=*srcpixel++;
2227                             dstval|=(X11DRV_DIB_GetNearestIndex
2228                                      (colors, 16,
2229                                       ((srcval <<  3) & 0xf8) | /* r */
2230                                       ((srcval >>  2) & 0x07),
2231                                       ((srcval >>  3) & 0xfc) | /* g */
2232                                       ((srcval >>  9) & 0x03),
2233                                       ((srcval >>  8) & 0xf8) | /* b */
2234                                       ((srcval >> 13) & 0x07) ) << ((1-(x&1))<<2) );
2235                             if ((x&1)==1) {
2236                                 *dstbyte++=dstval;
2237                                 dstval=0;
2238                             }
2239                         }
2240                         if ((dstwidth&1)!=0) {
2241                             *dstbyte=dstval;
2242                         }
2243                         srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2244                         dstbits += linebytes;
2245                     }
2246                 } else {
2247                     goto notsupported;
2248                 }
2249             } else {
2250                 goto notsupported;
2251             }
2252         }
2253         break;
2254
2255     case 24:
2256         if (bmpImage->bits_per_pixel==24) {
2257             const void* srcbits;
2258             const BYTE *srcbyte;
2259             BYTE* dstbyte;
2260
2261             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2262
2263             if (bmpImage->green_mask!=0x00ff00 ||
2264                 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2265                 goto notsupported;
2266             } else if (bmpImage->blue_mask==0xff) {
2267                 /* ==== rgb 888 bmp -> pal 4 dib ==== */
2268                 for (h=0; h<lines; h++) {
2269                     srcbyte=srcbits;
2270                     dstbyte=dstbits;
2271                     for (x=0; x<dstwidth/2; x++) {
2272                         /* Do 2 pixels at a time */
2273                         *dstbyte++=(X11DRV_DIB_GetNearestIndex
2274                                     (colors, 16,
2275                                      srcbyte[2],
2276                                      srcbyte[1],
2277                                      srcbyte[0]) << 4) |
2278                                     X11DRV_DIB_GetNearestIndex
2279                                     (colors, 16,
2280                                      srcbyte[5],
2281                                      srcbyte[4],
2282                                      srcbyte[3]);
2283                         srcbyte+=6;
2284                     }
2285                     if (dstwidth&1) {
2286                         /* And the the odd pixel */
2287                         *dstbyte++=(X11DRV_DIB_GetNearestIndex
2288                                     (colors, 16,
2289                                      srcbyte[2],
2290                                      srcbyte[1],
2291                                      srcbyte[0]) << 4);
2292                     }
2293                     srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2294                     dstbits += linebytes;
2295                 }
2296             } else {
2297                 /* ==== bgr 888 bmp -> pal 4 dib ==== */
2298                 for (h=0; h<lines; h++) {
2299                     srcbyte=srcbits;
2300                     dstbyte=dstbits;
2301                     for (x=0; x<dstwidth/2; x++) {
2302                         /* Do 2 pixels at a time */
2303                         *dstbyte++=(X11DRV_DIB_GetNearestIndex
2304                                     (colors, 16,
2305                                      srcbyte[0],
2306                                      srcbyte[1],
2307                                      srcbyte[2]) << 4) |
2308                                     X11DRV_DIB_GetNearestIndex
2309                                     (colors, 16,
2310                                      srcbyte[3],
2311                                      srcbyte[4],
2312                                      srcbyte[5]);
2313                         srcbyte+=6;
2314                     }
2315                     if (dstwidth&1) {
2316                         /* And the the odd pixel */
2317                         *dstbyte++=(X11DRV_DIB_GetNearestIndex
2318                                     (colors, 16,
2319                                      srcbyte[0],
2320                                      srcbyte[1],
2321                                      srcbyte[2]) << 4);
2322                     }
2323                     srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2324                     dstbits += linebytes;
2325                 }
2326             }
2327             break;
2328         }
2329         /* Fall through */
2330
2331     case 32:
2332         {
2333             const void* srcbits;
2334             const BYTE *srcbyte;
2335             BYTE* dstbyte;
2336
2337             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2338
2339             if (bmpImage->green_mask!=0x00ff00 ||
2340                 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2341                 goto notsupported;
2342             } else if (bmpImage->blue_mask==0xff) {
2343                 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
2344                 for (h=0; h<lines; h++) {
2345                     srcbyte=srcbits;
2346                     dstbyte=dstbits;
2347                     for (x=0; x<dstwidth/2; x++) {
2348                         /* Do 2 pixels at a time */
2349                         *dstbyte++=(X11DRV_DIB_GetNearestIndex
2350                                     (colors, 16,
2351                                      srcbyte[2],
2352                                      srcbyte[1],
2353                                      srcbyte[0]) << 4) |
2354                                     X11DRV_DIB_GetNearestIndex
2355                                     (colors, 16,
2356                                      srcbyte[6],
2357                                      srcbyte[5],
2358                                      srcbyte[4]);
2359                         srcbyte+=8;
2360                     }
2361                     if (dstwidth&1) {
2362                         /* And the the odd pixel */
2363                         *dstbyte++=(X11DRV_DIB_GetNearestIndex
2364                                     (colors, 16,
2365                                      srcbyte[2],
2366                                      srcbyte[1],
2367                                      srcbyte[0]) << 4);
2368                     }
2369                     srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2370                     dstbits += linebytes;
2371                 }
2372             } else {
2373                 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
2374                 for (h=0; h<lines; h++) {
2375                     srcbyte=srcbits;
2376                     dstbyte=dstbits;
2377                     for (x=0; x<dstwidth/2; x++) {
2378                         /* Do 2 pixels at a time */
2379                         *dstbyte++=(X11DRV_DIB_GetNearestIndex
2380                                     (colors, 16,
2381                                      srcbyte[0],
2382                                      srcbyte[1],
2383                                      srcbyte[2]) << 4) |
2384                                     X11DRV_DIB_GetNearestIndex
2385                                     (colors, 16,
2386                                      srcbyte[4],
2387                                      srcbyte[5],
2388                                      srcbyte[6]);
2389                         srcbyte+=8;
2390                     }
2391                     if (dstwidth&1) {
2392                         /* And the the odd pixel */
2393                         *dstbyte++=(X11DRV_DIB_GetNearestIndex
2394                                     (colors, 16,
2395                                      srcbyte[0],
2396                                      srcbyte[1],
2397                                      srcbyte[2]) << 4);
2398                     }
2399                     srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2400                     dstbits += linebytes;
2401                 }
2402             }
2403         }
2404         break;
2405
2406     default:
2407     notsupported:
2408         {
2409             BYTE* dstbyte;
2410
2411             /* ==== any bmp format -> pal 4 dib ==== */
2412             WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
2413                   bmpImage->bits_per_pixel, bmpImage->red_mask,
2414                   bmpImage->green_mask, bmpImage->blue_mask );
2415             for (h=lines-1; h>=0; h--) {
2416                 dstbyte=dstbits;
2417                 for (x=0; x<(dstwidth & ~1); x+=2) {
2418                     *dstbyte++=(X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4) |
2419                         X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x+1, h), 0);
2420                 }
2421                 if (dstwidth & 1) {
2422                     *dstbyte=(X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4);
2423                 }
2424                 dstbits += linebytes;
2425             }
2426         }
2427         break;
2428     }
2429 }
2430
2431 /***********************************************************************
2432  *           X11DRV_DIB_SetImageBits_RLE4
2433  *
2434  * SetDIBits for a 4-bit deep compressed DIB.
2435  */
2436 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
2437                                           DWORD width, DWORD dstwidth,
2438                                           int left, int *colors,
2439                                           XImage *bmpImage )
2440 {
2441     int x = 0, y = lines - 1, c, length;
2442     const BYTE *begin = bits;
2443
2444     while (y >= 0)
2445     {
2446         length = *bits++;
2447         if (length) {   /* encoded */
2448             c = *bits++;
2449             while (length--) {
2450                 if (x >= width) break;
2451                 XPutPixel(bmpImage, x++, y, colors[c >> 4]);
2452                 if (!length--) break;
2453                 if (x >= width) break;
2454                 XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
2455             }
2456         } else {
2457             length = *bits++;
2458             switch (length)
2459             {
2460             case RLE_EOL:
2461                 x = 0;
2462                 y--;
2463                 break;
2464
2465             case RLE_END:
2466                 return;
2467
2468             case RLE_DELTA:
2469                 x += *bits++;
2470                 y -= *bits++;
2471                 break;
2472
2473             default: /* absolute */
2474                 while (length--) {
2475                     c = *bits++;
2476                     if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
2477                     if (!length--) break;
2478                     if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
2479                 }
2480                 if ((bits - begin) & 1)
2481                     bits++;
2482             }
2483         }
2484     }
2485 }
2486
2487
2488
2489 /***********************************************************************
2490  *           X11DRV_DIB_SetImageBits_8
2491  *
2492  * SetDIBits for an 8-bit deep DIB.
2493  */
2494 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
2495                                 DWORD srcwidth, DWORD dstwidth, int left,
2496                                 const int *colors, XImage *bmpImage,
2497                                 DWORD linebytes )
2498 {
2499     DWORD x;
2500     int h;
2501     const BYTE* srcbyte;
2502     BYTE* dstbits;
2503
2504     if (lines < 0 )
2505     {
2506         lines = -lines;
2507         srcbits = srcbits + linebytes * (lines-1);
2508         linebytes = -linebytes;
2509     }
2510     srcbits += left;
2511     srcbyte = srcbits;
2512
2513     switch (bmpImage->depth) {
2514     case 15:
2515     case 16:
2516 #if defined(__i386__) && defined(__GNUC__)
2517         /* Some X servers might have 32 bit/ 16bit deep pixel */
2518         if (lines && dstwidth && (bmpImage->bits_per_pixel == 16) &&
2519             (ImageByteOrder(gdi_display)==LSBFirst) )
2520         {
2521             dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2522             /* FIXME: Does this really handle all these cases correctly? */
2523             /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
2524             for (h = lines ; h--; ) {
2525                 int _cl1,_cl2; /* temp outputs for asm below */
2526                 /* Borrowed from DirectDraw */
2527                 __asm__ __volatile__(
2528                 "xor %%eax,%%eax\n"
2529                 "cld\n"
2530                 "1:\n"
2531                 "    lodsb\n"
2532                 "    movw (%%edx,%%eax,4),%%ax\n"
2533                 "    stosw\n"
2534                 "      xor %%eax,%%eax\n"
2535                 "    loop 1b\n"
2536                 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
2537                 :"S" (srcbyte),
2538                  "D" (dstbits),
2539                  "c" (dstwidth),
2540                  "d" (colors)
2541                 :"eax", "cc", "memory"
2542                 );
2543                 srcbyte = (srcbits += linebytes);
2544                 dstbits -= bmpImage->bytes_per_line;
2545             }
2546             return;
2547         }
2548         break;
2549 #endif
2550     case 24:
2551     case 32:
2552 #if defined(__i386__) && defined(__GNUC__)
2553         if (lines && dstwidth && (bmpImage->bits_per_pixel == 32) &&
2554             (ImageByteOrder(gdi_display)==LSBFirst) )
2555         {
2556             dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2557             /* FIXME: Does this really handle both cases correctly? */
2558             /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
2559             for (h = lines ; h--; ) {
2560                 int _cl1,_cl2; /* temp outputs for asm below */
2561                 /* Borrowed from DirectDraw */
2562                 __asm__ __volatile__(
2563                 "xor %%eax,%%eax\n"
2564                 "cld\n"
2565                 "1:\n"
2566                 "    lodsb\n"
2567                 "    movl (%%edx,%%eax,4),%%eax\n"
2568                 "    stosl\n"
2569                 "      xor %%eax,%%eax\n"
2570                 "    loop 1b\n"
2571                 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
2572                 :"S" (srcbyte),
2573                  "D" (dstbits),
2574                  "c" (dstwidth),
2575                  "d" (colors)
2576                 :"eax", "cc", "memory"
2577                 );
2578                 srcbyte = (srcbits += linebytes);
2579                 dstbits -= bmpImage->bytes_per_line;
2580             }
2581             return;
2582         }
2583         break;
2584 #endif
2585     default:
2586         break; /* use slow generic case below */
2587     }
2588
2589     /* ==== pal 8 dib -> any bmp format ==== */
2590     for (h=lines-1; h>=0; h--) {
2591         for (x=left; x<dstwidth+left; x++) {
2592             XPutPixel(bmpImage, x, h, colors[*srcbyte++]);
2593         }
2594         srcbyte = (srcbits += linebytes);
2595     }
2596 }
2597
2598 /***********************************************************************
2599  *           X11DRV_DIB_GetImageBits_8
2600  *
2601  * GetDIBits for an 8-bit deep DIB.
2602  */
2603 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
2604                                        DWORD srcwidth, DWORD dstwidth,
2605                                        RGBQUAD *colors, PALETTEENTRY *srccolors,
2606                                        XImage *bmpImage, DWORD linebytes )
2607 {
2608     DWORD x;
2609     int h;
2610     BYTE* dstbyte;
2611
2612     if (lines < 0 )
2613     {
2614        lines = -lines;
2615        dstbits = dstbits + ( linebytes * (lines-1) );
2616        linebytes = -linebytes;
2617     }
2618
2619     /*
2620      * Hack for now
2621      * This condition is true when GetImageBits has been called by
2622      * UpdateDIBSection. For now, GetNearestIndex is too slow to support
2623      * 256 colormaps, so we'll just use for for GetDIBits calls.
2624      * (In somes cases, in a updateDIBSection, the returned colors are bad too)
2625      */
2626     if (!srccolors) goto updatesection;
2627
2628     switch (bmpImage->depth) {
2629     case 1:
2630     case 4:
2631         if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2632
2633             /* ==== pal 1 bmp -> pal 8 dib ==== */
2634             /* ==== pal 4 bmp -> pal 8 dib ==== */
2635             for (h=lines-1; h>=0; h--) {
2636                 dstbyte=dstbits;
2637                 for (x=0; x<dstwidth; x++) {
2638                     PALETTEENTRY srcval;
2639                     srcval=srccolors[XGetPixel(bmpImage, x, h)];
2640                     *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
2641                                                           srcval.peRed,
2642                                                           srcval.peGreen,
2643                                                           srcval.peBlue);
2644                 }
2645                 dstbits += linebytes;
2646             }
2647         } else {
2648             goto notsupported;
2649         }
2650         break;
2651
2652     case 8:
2653        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2654             /* ==== pal 8 bmp -> pal 8 dib ==== */
2655            const void* srcbits;
2656            const BYTE* srcpixel;
2657
2658            srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2659            for (h=0; h<lines; h++) {
2660                srcpixel=srcbits;
2661                dstbyte=dstbits;
2662                for (x = 0; x < dstwidth; x++) {
2663                    PALETTEENTRY srcval;
2664                    srcval=srccolors[(int)*srcpixel++];
2665                    *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
2666                                                          srcval.peRed,
2667                                                          srcval.peGreen,
2668                                                          srcval.peBlue);
2669                }
2670                srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2671                dstbits += linebytes;
2672            }
2673        } else {
2674            goto notsupported;
2675        }
2676        break;
2677
2678     case 15:
2679     case 16:
2680         {
2681             const void* srcbits;
2682             const WORD* srcpixel;
2683             BYTE* dstbyte;
2684
2685             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2686
2687             if (bmpImage->green_mask==0x03e0) {
2688                 if (bmpImage->red_mask==0x7c00) {
2689                     /* ==== rgb 555 bmp -> pal 8 dib ==== */
2690                     for (h=0; h<lines; h++) {
2691                         srcpixel=srcbits;
2692                         dstbyte=dstbits;
2693                         for (x=0; x<dstwidth; x++) {
2694                             WORD srcval;
2695                             srcval=*srcpixel++;
2696                             *dstbyte++=X11DRV_DIB_GetNearestIndex
2697                                 (colors, 256,
2698                                  ((srcval >>  7) & 0xf8) | /* r */
2699                                  ((srcval >> 12) & 0x07),
2700                                  ((srcval >>  2) & 0xf8) | /* g */
2701                                  ((srcval >>  7) & 0x07),
2702                                  ((srcval <<  3) & 0xf8) | /* b */
2703                                  ((srcval >>  2) & 0x07) );
2704                         }
2705                         srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2706                         dstbits += linebytes;
2707                     }
2708                 } else if (bmpImage->blue_mask==0x7c00) {
2709                     /* ==== bgr 555 bmp -> pal 8 dib ==== */
2710                     for (h=0; h<lines; h++) {
2711                         srcpixel=srcbits;
2712                         dstbyte=dstbits;
2713                         for (x=0; x<dstwidth; x++) {
2714                             WORD srcval;
2715                             srcval=*srcpixel++;
2716                             *dstbyte++=X11DRV_DIB_GetNearestIndex
2717                                 (colors, 256,
2718                                  ((srcval <<  3) & 0xf8) | /* r */
2719                                  ((srcval >>  2) & 0x07),
2720                                  ((srcval >>  2) & 0xf8) | /* g */
2721                                  ((srcval >>  7) & 0x07),
2722                                  ((srcval >>  7) & 0xf8) | /* b */
2723                                  ((srcval >> 12) & 0x07) );
2724                         }
2725                         srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2726                         dstbits += linebytes;
2727                     }
2728                 } else {
2729                     goto notsupported;
2730                 }
2731             } else if (bmpImage->green_mask==0x07e0) {
2732                 if (bmpImage->red_mask==0xf800) {
2733                     /* ==== rgb 565 bmp -> pal 8 dib ==== */
2734                     for (h=0; h<lines; h++) {
2735                         srcpixel=srcbits;
2736                         dstbyte=dstbits;
2737                         for (x=0; x<dstwidth; x++) {
2738                             WORD srcval;
2739                             srcval=*srcpixel++;
2740                             *dstbyte++=X11DRV_DIB_GetNearestIndex
2741                                 (colors, 256,
2742                                  ((srcval >>  8) & 0xf8) | /* r */
2743                                  ((srcval >> 13) & 0x07),
2744                                  ((srcval >>  3) & 0xfc) | /* g */
2745                                  ((srcval >>  9) & 0x03),
2746                                  ((srcval <<  3) & 0xf8) | /* b */
2747                                  ((srcval >>  2) & 0x07) );
2748                         }
2749                         srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2750                         dstbits += linebytes;
2751                     }
2752                 } else if (bmpImage->blue_mask==0xf800) {
2753                     /* ==== bgr 565 bmp -> pal 8 dib ==== */
2754                     for (h=0; h<lines; h++) {
2755                         srcpixel=srcbits;
2756                         dstbyte=dstbits;
2757                         for (x=0; x<dstwidth; x++) {
2758                             WORD srcval;
2759                             srcval=*srcpixel++;
2760                             *dstbyte++=X11DRV_DIB_GetNearestIndex
2761                                 (colors, 256,
2762                                  ((srcval <<  3) & 0xf8) | /* r */
2763                                  ((srcval >>  2) & 0x07),
2764                                  ((srcval >>  3) & 0xfc) | /* g */
2765                                  ((srcval >>  9) & 0x03),
2766                                  ((srcval >>  8) & 0xf8) | /* b */
2767                                  ((srcval >> 13) & 0x07) );
2768                         }
2769                         srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2770                         dstbits += linebytes;
2771                     }
2772                 } else {
2773                     goto notsupported;
2774                 }
2775             } else {
2776                 goto notsupported;
2777             }
2778         }
2779         break;
2780
2781     case 24:
2782     case 32:
2783         {
2784             const void* srcbits;
2785             const BYTE *srcbyte;
2786             BYTE* dstbyte;
2787             int bytes_per_pixel;
2788
2789             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2790             bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
2791
2792             if (bmpImage->green_mask!=0x00ff00 ||
2793                 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2794                 goto notsupported;
2795             } else if (bmpImage->blue_mask==0xff) {
2796                 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
2797                 for (h=0; h<lines; h++) {
2798                     srcbyte=srcbits;
2799                     dstbyte=dstbits;
2800                     for (x=0; x<dstwidth; x++) {
2801                         *dstbyte++=X11DRV_DIB_GetNearestIndex
2802                             (colors, 256,
2803                              srcbyte[2],
2804                              srcbyte[1],
2805                              srcbyte[0]);
2806                         srcbyte+=bytes_per_pixel;
2807                     }
2808                     srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2809                     dstbits += linebytes;
2810                 }
2811             } else {
2812                 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
2813                 for (h=0; h<lines; h++) {
2814                     srcbyte=srcbits;
2815                     dstbyte=dstbits;
2816                     for (x=0; x<dstwidth; x++) {
2817                         *dstbyte++=X11DRV_DIB_GetNearestIndex
2818                             (colors, 256,
2819                              srcbyte[0],
2820                              srcbyte[1],
2821                              srcbyte[2]);
2822                         srcbyte+=bytes_per_pixel;
2823                     }
2824                     srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2825                     dstbits += linebytes;
2826                 }
2827             }
2828         }
2829         break;
2830
2831     default:
2832     notsupported:
2833         WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
2834               bmpImage->depth, bmpImage->red_mask,
2835               bmpImage->green_mask, bmpImage->blue_mask );
2836     updatesection:
2837         /* ==== any bmp format -> pal 8 dib ==== */
2838         for (h=lines-1; h>=0; h--) {
2839             dstbyte=dstbits;
2840             for (x=0; x<dstwidth; x++) {
2841                 *dstbyte=X11DRV_DIB_MapColor
2842                     ((int*)colors, 256,
2843                      XGetPixel(bmpImage, x, h), *dstbyte);
2844                 dstbyte++;
2845             }
2846             dstbits += linebytes;
2847         }
2848         break;
2849     }
2850 }
2851
2852 /***********************************************************************
2853  *            X11DRV_DIB_SetImageBits_RLE8
2854  *
2855  * SetDIBits for an 8-bit deep compressed DIB.
2856  *
2857  * This function rewritten 941113 by James Youngman.  WINE blew out when I
2858  * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
2859  *
2860  * This was because the algorithm assumed that all RLE8 bitmaps end with the
2861  * 'End of bitmap' escape code.  This code is very much laxer in what it
2862  * allows to end the expansion.  Possibly too lax.  See the note by
2863  * case RleDelta.  BTW, MS's documentation implies that a correct RLE8
2864  * bitmap should end with RleEnd, but on the other hand, software exists
2865  * that produces ones that don't and Windows 3.1 doesn't complain a bit
2866  * about it.
2867  *
2868  * (No) apologies for my English spelling.  [Emacs users: c-indent-level=4].
2869  *                      James A. Youngman <mbcstjy@afs.man.ac.uk>
2870  *                                              [JAY]
2871  */
2872 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
2873                                           DWORD width, DWORD dstwidth,
2874                                           int left, int *colors,
2875                                           XImage *bmpImage )
2876 {
2877     int x;                      /* X-positon on each line.  Increases. */
2878     int y;                      /* Line #.  Starts at lines-1, decreases */
2879     const BYTE *pIn = bits;     /* Pointer to current position in bits */
2880     BYTE length;                /* The length pf a run */
2881     BYTE escape_code;           /* See enum Rle8_EscapeCodes.*/
2882
2883     /*
2884      * Note that the bitmap data is stored by Windows starting at the
2885      * bottom line of the bitmap and going upwards.  Within each line,
2886      * the data is stored left-to-right.  That's the reason why line
2887      * goes from lines-1 to 0.                  [JAY]
2888      */
2889
2890     x = 0;
2891     y = lines - 1;
2892     while (y >= 0)
2893     {
2894         length = *pIn++;
2895
2896         /*
2897          * If the length byte is not zero (which is the escape value),
2898          * We have a run of length pixels all the same colour.  The colour
2899          * index is stored next.
2900          *
2901          * If the length byte is zero, we need to read the next byte to
2902          * know what to do.                     [JAY]
2903          */
2904         if (length != 0)
2905         {
2906             /*
2907              * [Run-Length] Encoded mode
2908              */
2909             int color = colors[*pIn++];
2910             while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
2911         }
2912         else
2913         {
2914             /*
2915              * Escape codes (may be an absolute sequence though)
2916              */
2917             escape_code = (*pIn++);
2918             switch(escape_code)
2919             {
2920             case RLE_EOL:
2921                 x = 0;
2922                 y--;
2923                 break;
2924
2925             case RLE_END:
2926                 /* Not all RLE8 bitmaps end with this code.  For
2927                  * example, Paint Shop Pro produces some that don't.
2928                  * That's (I think) what caused the previous
2929                  * implementation to fail.  [JAY]
2930                  */
2931                 return;
2932
2933             case RLE_DELTA:
2934                 x += (*pIn++);
2935                 y -= (*pIn++);
2936                 break;
2937
2938             default:  /* switch to absolute mode */
2939                 length = escape_code;
2940                 while (length--)
2941                 {
2942                     int color = colors[*pIn++];
2943                     if (x >= dstwidth)
2944                     {
2945                         pIn += length;
2946                         break;
2947                     }
2948                     XPutPixel(bmpImage, x++, y, color);
2949                 }
2950                 /*
2951                  * If you think for a moment you'll realise that the
2952                  * only time we could ever possibly read an odd
2953                  * number of bytes is when there is a 0x00 (escape),
2954                  * a value >0x02 (absolute mode) and then an odd-
2955                  * length run.  Therefore this is the only place we
2956                  * need to worry about it.  Everywhere else the
2957                  * bytes are always read in pairs.  [JAY]
2958                  */
2959                 if (escape_code & 1) pIn++; /* Throw away the pad byte. */
2960                 break;
2961             } /* switch (escape_code) : Escape sequence */
2962         }
2963     }
2964 }
2965
2966
2967 /***********************************************************************
2968  *           X11DRV_DIB_SetImageBits_16
2969  *
2970  * SetDIBits for a 16-bit deep DIB.
2971  */
2972 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
2973                                  DWORD srcwidth, DWORD dstwidth, int left,
2974                                        X11DRV_PDEVICE *physDev, DWORD rSrc, DWORD gSrc, DWORD bSrc,
2975                                        XImage *bmpImage, DWORD linebytes )
2976 {
2977     DWORD x;
2978     int h;
2979
2980     if (lines < 0 )
2981     {
2982         lines = -lines;
2983         srcbits = srcbits + ( linebytes * (lines-1));
2984         linebytes = -linebytes;
2985     }
2986
2987     switch (bmpImage->depth)
2988     {
2989     case 15:
2990     case 16:
2991         {
2992             char* dstbits;
2993
2994             srcbits=srcbits+left*2;
2995             dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2996
2997             if (bmpImage->green_mask==0x03e0) {
2998                 if (gSrc==bmpImage->green_mask) {
2999                     if (rSrc==bmpImage->red_mask) {
3000                         /* ==== rgb 555 dib -> rgb 555 bmp ==== */
3001                         /* ==== bgr 555 dib -> bgr 555 bmp ==== */
3002                         X11DRV_DIB_Convert_any_asis
3003                             (dstwidth,lines,2,
3004                              srcbits,linebytes,
3005                              dstbits,-bmpImage->bytes_per_line);
3006                     } else if (rSrc==bmpImage->blue_mask) {
3007                         /* ==== rgb 555 dib -> bgr 555 bmp ==== */
3008                         /* ==== bgr 555 dib -> rgb 555 bmp ==== */
3009                         X11DRV_DIB_Convert_555_reverse
3010                             (dstwidth,lines,
3011                              srcbits,linebytes,
3012                              dstbits,-bmpImage->bytes_per_line);
3013                     }
3014                 } else {
3015                     if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
3016                         /* ==== rgb 565 dib -> rgb 555 bmp ==== */
3017                         /* ==== bgr 565 dib -> bgr 555 bmp ==== */
3018                         X11DRV_DIB_Convert_565_to_555_asis
3019                             (dstwidth,lines,
3020                              srcbits,linebytes,
3021                              dstbits,-bmpImage->bytes_per_line);
3022                     } else {
3023                         /* ==== rgb 565 dib -> bgr 555 bmp ==== */
3024                         /* ==== bgr 565 dib -> rgb 555 bmp ==== */
3025                         X11DRV_DIB_Convert_565_to_555_reverse
3026                             (dstwidth,lines,
3027                              srcbits,linebytes,
3028                              dstbits,-bmpImage->bytes_per_line);
3029                     }
3030                 }
3031             } else if (bmpImage->green_mask==0x07e0) {
3032                 if (gSrc==bmpImage->green_mask) {
3033                     if (rSrc==bmpImage->red_mask) {
3034                         /* ==== rgb 565 dib -> rgb 565 bmp ==== */
3035                         /* ==== bgr 565 dib -> bgr 565 bmp ==== */
3036                         X11DRV_DIB_Convert_any_asis
3037                             (dstwidth,lines,2,
3038                              srcbits,linebytes,
3039                              dstbits,-bmpImage->bytes_per_line);
3040                     } else {
3041                         /* ==== rgb 565 dib -> bgr 565 bmp ==== */
3042                         /* ==== bgr 565 dib -> rgb 565 bmp ==== */
3043                         X11DRV_DIB_Convert_565_reverse
3044                             (dstwidth,lines,
3045                              srcbits,linebytes,
3046                              dstbits,-bmpImage->bytes_per_line);
3047                     }
3048                 } else {
3049                     if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
3050                         /* ==== rgb 555 dib -> rgb 565 bmp ==== */
3051                         /* ==== bgr 555 dib -> bgr 565 bmp ==== */
3052                         X11DRV_DIB_Convert_555_to_565_asis
3053                             (dstwidth,lines,
3054                              srcbits,linebytes,
3055                              dstbits,-bmpImage->bytes_per_line);
3056                     } else {
3057                         /* ==== rgb 555 dib -> bgr 565 bmp ==== */
3058                         /* ==== bgr 555 dib -> rgb 565 bmp ==== */
3059                         X11DRV_DIB_Convert_555_to_565_reverse
3060                             (dstwidth,lines,
3061                              srcbits,linebytes,
3062                              dstbits,-bmpImage->bytes_per_line);
3063                     }
3064                 }
3065             } else {
3066                 goto notsupported;
3067             }
3068         }
3069         break;
3070
3071     case 24:
3072         if (bmpImage->bits_per_pixel==24) {
3073             char* dstbits;
3074
3075             srcbits=srcbits+left*2;
3076             dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3077
3078             if (bmpImage->green_mask!=0x00ff00 ||
3079                 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3080                 goto notsupported;
3081             } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
3082                        (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
3083                 if (gSrc==0x03e0) {
3084                     /* ==== rgb 555 dib -> rgb 888 bmp ==== */
3085                     /* ==== bgr 555 dib -> bgr 888 bmp ==== */
3086                     X11DRV_DIB_Convert_555_to_888_asis
3087                         (dstwidth,lines,
3088                          srcbits,linebytes,
3089                          dstbits,-bmpImage->bytes_per_line);
3090                 } else {
3091                     /* ==== rgb 565 dib -> rgb 888 bmp ==== */
3092                     /* ==== bgr 565 dib -> bgr 888 bmp ==== */
3093                     X11DRV_DIB_Convert_565_to_888_asis
3094                         (dstwidth,lines,
3095                          srcbits,linebytes,
3096                          dstbits,-bmpImage->bytes_per_line);
3097                 }
3098             } else {
3099                 if (gSrc==0x03e0) {
3100                     /* ==== rgb 555 dib -> bgr 888 bmp ==== */
3101                     /* ==== bgr 555 dib -> rgb 888 bmp ==== */
3102                     X11DRV_DIB_Convert_555_to_888_reverse
3103                         (dstwidth,lines,
3104                          srcbits,linebytes,
3105                          dstbits,-bmpImage->bytes_per_line);
3106                 } else {
3107                     /* ==== rgb 565 dib -> bgr 888 bmp ==== */
3108                     /* ==== bgr 565 dib -> rgb 888 bmp ==== */
3109                     X11DRV_DIB_Convert_565_to_888_reverse
3110                         (dstwidth,lines,
3111                          srcbits,linebytes,
3112                          dstbits,-bmpImage->bytes_per_line);
3113                 }
3114             }
3115             break;
3116         }
3117         /* Fall through */
3118
3119     case 32:
3120         {
3121             char* dstbits;
3122
3123             srcbits=srcbits+left*2;
3124             dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
3125
3126             if (bmpImage->green_mask!=0x00ff00 ||
3127                 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3128                 goto notsupported;
3129             } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
3130                        (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
3131                 if (gSrc==0x03e0) {
3132                     /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
3133                     /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
3134                     X11DRV_DIB_Convert_555_to_0888_asis
3135                         (dstwidth,lines,
3136                          srcbits,linebytes,
3137                          dstbits,-bmpImage->bytes_per_line);
3138                 } else {
3139                     /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
3140                     /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
3141                     X11DRV_DIB_Convert_565_to_0888_asis
3142                         (dstwidth,lines,
3143                          srcbits,linebytes,
3144                          dstbits,-bmpImage->bytes_per_line);
3145                 }
3146             } else {
3147                 if (gSrc==0x03e0) {
3148                     /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
3149                     /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
3150                     X11DRV_DIB_Convert_555_to_0888_reverse
3151                         (dstwidth,lines,
3152                          srcbits,linebytes,
3153                          dstbits,-bmpImage->bytes_per_line);
3154                 } else {
3155                     /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
3156                     /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
3157                     X11DRV_DIB_Convert_565_to_0888_reverse
3158                         (dstwidth,lines,
3159                          srcbits,linebytes,
3160                          dstbits,-bmpImage->bytes_per_line);
3161                 }
3162             }
3163         }
3164         break;
3165
3166     default:
3167     notsupported:
3168         WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3169               rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3170               bmpImage->green_mask, bmpImage->blue_mask );
3171         /* fall through */
3172     case 1:
3173     case 4:
3174     case 8:
3175         {
3176             /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
3177             const WORD* srcpixel;
3178             int rShift1,gShift1,bShift1;
3179             int rShift2,gShift2,bShift2;
3180             BYTE gMask1,gMask2;
3181
3182             /* Set color scaling values */
3183             rShift1=16+X11DRV_DIB_MaskToShift(rSrc)-3;
3184             gShift1=16+X11DRV_DIB_MaskToShift(gSrc)-3;
3185             bShift1=16+X11DRV_DIB_MaskToShift(bSrc)-3;
3186             rShift2=rShift1+5;
3187             gShift2=gShift1+5;
3188             bShift2=bShift1+5;
3189             if (gSrc==0x03e0) {
3190                 /* Green has 5 bits, like the others */
3191                 gMask1=0xf8;
3192                 gMask2=0x07;
3193             } else {
3194                 /* Green has 6 bits, not 5. Compensate. */
3195                 gShift1++;
3196                 gShift2+=2;
3197                 gMask1=0xfc;
3198                 gMask2=0x03;
3199             }
3200
3201             srcbits+=2*left;
3202
3203             /* We could split it into four separate cases to optimize
3204              * but it is probably not worth it.
3205              */
3206             for (h=lines-1; h>=0; h--) {
3207                 srcpixel=(const WORD*)srcbits;
3208                 for (x=left; x<dstwidth+left; x++) {
3209                     DWORD srcval;
3210                     BYTE red,green,blue;
3211                     srcval=*srcpixel++ << 16;
3212                     red=  ((srcval >> rShift1) & 0xf8) |
3213                         ((srcval >> rShift2) & 0x07);
3214                     green=((srcval >> gShift1) & gMask1) |
3215                         ((srcval >> gShift2) & gMask2);
3216                     blue= ((srcval >> bShift1) & 0xf8) |
3217                         ((srcval >> bShift2) & 0x07);
3218                     XPutPixel(bmpImage, x, h,
3219                               X11DRV_PALETTE_ToPhysical
3220                               (physDev, RGB(red,green,blue)));
3221                 }
3222                 srcbits += linebytes;
3223             }
3224         }
3225         break;
3226     }
3227 }
3228
3229
3230 /***********************************************************************
3231  *           X11DRV_DIB_GetImageBits_16
3232  *
3233  * GetDIBits for an 16-bit deep DIB.
3234  */
3235 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
3236                                         DWORD dstwidth, DWORD srcwidth,
3237                                         PALETTEENTRY *srccolors,
3238                                         DWORD rDst, DWORD gDst, DWORD bDst,
3239                                         XImage *bmpImage, DWORD dibpitch )
3240 {
3241     DWORD x;
3242     int h;
3243
3244     DWORD linebytes = dibpitch;
3245
3246     if (lines < 0 )
3247     {
3248         lines = -lines;
3249         dstbits = dstbits + ( linebytes * (lines-1));
3250         linebytes = -linebytes;
3251     }
3252
3253     switch (bmpImage->depth)
3254     {
3255     case 15:
3256     case 16:
3257         {
3258             const char* srcbits;
3259
3260             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3261
3262             if (bmpImage->green_mask==0x03e0) {
3263                 if (gDst==bmpImage->green_mask) {
3264                     if (rDst==bmpImage->red_mask) {
3265                         /* ==== rgb 555 bmp -> rgb 555 dib ==== */
3266                         /* ==== bgr 555 bmp -> bgr 555 dib ==== */
3267                         X11DRV_DIB_Convert_any_asis
3268                             (dstwidth,lines,2,
3269                              srcbits,-bmpImage->bytes_per_line,
3270                              dstbits,linebytes);
3271                     } else {
3272                         /* ==== rgb 555 bmp -> bgr 555 dib ==== */
3273                         /* ==== bgr 555 bmp -> rgb 555 dib ==== */
3274                         X11DRV_DIB_Convert_555_reverse
3275                             (dstwidth,lines,
3276                              srcbits,-bmpImage->bytes_per_line,
3277                              dstbits,linebytes);
3278                     }
3279                 } else {
3280                     if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
3281                         /* ==== rgb 555 bmp -> rgb 565 dib ==== */
3282                         /* ==== bgr 555 bmp -> bgr 565 dib ==== */
3283                         X11DRV_DIB_Convert_555_to_565_asis
3284                             (dstwidth,lines,
3285                              srcbits,-bmpImage->bytes_per_line,
3286                              dstbits,linebytes);
3287                     } else {
3288                         /* ==== rgb 555 bmp -> bgr 565 dib ==== */
3289                         /* ==== bgr 555 bmp -> rgb 565 dib ==== */
3290                         X11DRV_DIB_Convert_555_to_565_reverse
3291                             (dstwidth,lines,
3292                              srcbits,-bmpImage->bytes_per_line,
3293                              dstbits,linebytes);
3294                     }
3295                 }
3296             } else if (bmpImage->green_mask==0x07e0) {
3297                 if (gDst==bmpImage->green_mask) {
3298                     if (rDst == bmpImage->red_mask) {
3299                         /* ==== rgb 565 bmp -> rgb 565 dib ==== */
3300                         /* ==== bgr 565 bmp -> bgr 565 dib ==== */
3301                         X11DRV_DIB_Convert_any_asis
3302                             (dstwidth,lines,2,
3303                              srcbits,-bmpImage->bytes_per_line,
3304                              dstbits,linebytes);
3305                     } else {
3306                         /* ==== rgb 565 bmp -> bgr 565 dib ==== */
3307                         /* ==== bgr 565 bmp -> rgb 565 dib ==== */
3308                         X11DRV_DIB_Convert_565_reverse
3309                             (dstwidth,lines,
3310                              srcbits,-bmpImage->bytes_per_line,
3311                              dstbits,linebytes);
3312                     }
3313                 } else {
3314                     if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
3315                         /* ==== rgb 565 bmp -> rgb 555 dib ==== */
3316                         /* ==== bgr 565 bmp -> bgr 555 dib ==== */
3317                         X11DRV_DIB_Convert_565_to_555_asis
3318                             (dstwidth,lines,
3319                              srcbits,-bmpImage->bytes_per_line,
3320                              dstbits,linebytes);
3321                     } else {
3322                         /* ==== rgb 565 bmp -> bgr 555 dib ==== */
3323                         /* ==== bgr 565 bmp -> rgb 555 dib ==== */
3324                         X11DRV_DIB_Convert_565_to_555_reverse
3325                             (dstwidth,lines,
3326                              srcbits,-bmpImage->bytes_per_line,
3327                              dstbits,linebytes);
3328                     }
3329                 }
3330             } else {
3331                 goto notsupported;
3332             }
3333         }
3334         break;
3335
3336     case 24:
3337         if (bmpImage->bits_per_pixel == 24) {
3338             const char* srcbits;
3339
3340             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3341
3342             if (bmpImage->green_mask!=0x00ff00 ||
3343                 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3344                 goto notsupported;
3345             } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
3346                     (bDst==0x1f && bmpImage->blue_mask==0xff)) {
3347                 if (gDst==0x03e0) {
3348                     /* ==== rgb 888 bmp -> rgb 555 dib ==== */
3349                     /* ==== bgr 888 bmp -> bgr 555 dib ==== */
3350                     X11DRV_DIB_Convert_888_to_555_asis
3351                         (dstwidth,lines,
3352                          srcbits,-bmpImage->bytes_per_line,
3353                          dstbits,linebytes);
3354                 } else {
3355                     /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3356                     /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3357                     X11DRV_DIB_Convert_888_to_565_asis
3358                         (dstwidth,lines,
3359                          srcbits,-bmpImage->bytes_per_line,
3360                          dstbits,linebytes);
3361                 }
3362             } else {
3363                 if (gDst==0x03e0) {
3364                     /* ==== rgb 888 bmp -> bgr 555 dib ==== */
3365                     /* ==== bgr 888 bmp -> rgb 555 dib ==== */
3366                     X11DRV_DIB_Convert_888_to_555_reverse
3367                         (dstwidth,lines,
3368                          srcbits,-bmpImage->bytes_per_line,
3369                          dstbits,linebytes);
3370                 } else {
3371                     /* ==== rgb 888 bmp -> bgr 565 dib ==== */
3372                     /* ==== bgr 888 bmp -> rgb 565 dib ==== */
3373                     X11DRV_DIB_Convert_888_to_565_reverse
3374                         (dstwidth,lines,
3375                          srcbits,-bmpImage->bytes_per_line,
3376                          dstbits,linebytes);
3377                 }
3378             }
3379             break;
3380         }
3381         /* Fall through */
3382
3383     case 32:
3384         {
3385             const char* srcbits;
3386
3387             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3388
3389             if (bmpImage->green_mask!=0x00ff00 ||
3390                 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3391                 goto notsupported;
3392             } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
3393                        (bDst==0x1f && bmpImage->blue_mask==0xff)) {
3394                 if (gDst==0x03e0) {
3395                     /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
3396                     /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
3397                     X11DRV_DIB_Convert_0888_to_555_asis
3398                         (dstwidth,lines,
3399                          srcbits,-bmpImage->bytes_per_line,
3400                          dstbits,linebytes);
3401                 } else {
3402                     /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
3403                     /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
3404                     X11DRV_DIB_Convert_0888_to_565_asis
3405                         (dstwidth,lines,
3406                          srcbits,-bmpImage->bytes_per_line,
3407                          dstbits,linebytes);
3408                 }
3409             } else {
3410                 if (gDst==0x03e0) {
3411                     /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
3412                     /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
3413                     X11DRV_DIB_Convert_0888_to_555_reverse
3414                         (dstwidth,lines,
3415                          srcbits,-bmpImage->bytes_per_line,
3416                          dstbits,linebytes);
3417                 } else {
3418                     /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
3419                     /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
3420                     X11DRV_DIB_Convert_0888_to_565_reverse
3421                         (dstwidth,lines,
3422                          srcbits,-bmpImage->bytes_per_line,
3423                          dstbits,linebytes);
3424                 }
3425             }
3426         }
3427         break;
3428
3429     case 1:
3430     case 4:
3431         if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3432             /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
3433             int rShift,gShift,bShift;
3434             WORD* dstpixel;
3435
3436             /* Shift everything 16 bits left so that all shifts are >0,
3437              * even for BGR DIBs. Then a single >> 16 will bring everything
3438              * back into place.
3439              */
3440             rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3441             gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3442             bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3443             if (gDst==0x07e0) {
3444                 /* 6 bits for the green */
3445                 gShift++;
3446             }
3447             rDst=rDst << 16;
3448             gDst=gDst << 16;
3449             bDst=bDst << 16;
3450             for (h = lines - 1; h >= 0; h--) {
3451                 dstpixel=(LPWORD)dstbits;
3452                 for (x = 0; x < dstwidth; x++) {
3453                     PALETTEENTRY srcval;
3454                     DWORD dstval;
3455                     srcval=srccolors[XGetPixel(bmpImage, x, h)];
3456                     dstval=((srcval.peRed   << rShift) & rDst) |
3457                            ((srcval.peGreen << gShift) & gDst) |
3458                            ((srcval.peBlue  << bShift) & bDst);
3459                     *dstpixel++=dstval >> 16;
3460                 }
3461                 dstbits += linebytes;
3462             }
3463         } else {
3464             goto notsupported;
3465         }
3466         break;
3467
3468     case 8:
3469         if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3470             /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
3471             int rShift,gShift,bShift;
3472             const BYTE* srcbits;
3473             const BYTE* srcpixel;
3474             WORD* dstpixel;
3475
3476             /* Shift everything 16 bits left so that all shifts are >0,
3477              * even for BGR DIBs. Then a single >> 16 will bring everything
3478              * back into place.
3479              */
3480             rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3481             gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3482             bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3483             if (gDst==0x07e0) {
3484                 /* 6 bits for the green */
3485                 gShift++;
3486             }
3487             rDst=rDst << 16;
3488             gDst=gDst << 16;
3489             bDst=bDst << 16;
3490             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3491             for (h=0; h<lines; h++) {
3492                 srcpixel=srcbits;
3493                 dstpixel=(LPWORD)dstbits;
3494                 for (x = 0; x < dstwidth; x++) {
3495                     PALETTEENTRY srcval;
3496                     DWORD dstval;
3497                     srcval=srccolors[(int)*srcpixel++];
3498                     dstval=((srcval.peRed   << rShift) & rDst) |
3499                            ((srcval.peGreen << gShift) & gDst) |
3500                            ((srcval.peBlue  << bShift) & bDst);
3501                     *dstpixel++=dstval >> 16;
3502                 }
3503                 srcbits -= bmpImage->bytes_per_line;
3504                 dstbits += linebytes;
3505             }
3506         } else {
3507             goto notsupported;
3508         }
3509         break;
3510
3511     default:
3512     notsupported:
3513         {
3514             /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
3515             int rShift,gShift,bShift;
3516             WORD* dstpixel;
3517
3518             WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
3519                   bmpImage->depth, bmpImage->red_mask,
3520                   bmpImage->green_mask, bmpImage->blue_mask,
3521                   rDst, gDst, bDst);
3522
3523             /* Shift everything 16 bits left so that all shifts are >0,
3524              * even for BGR DIBs. Then a single >> 16 will bring everything
3525              * back into place.
3526              */
3527             rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3528             gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3529             bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3530             if (gDst==0x07e0) {
3531                 /* 6 bits for the green */
3532                 gShift++;
3533             }
3534             rDst=rDst << 16;
3535             gDst=gDst << 16;
3536             bDst=bDst << 16;
3537             for (h = lines - 1; h >= 0; h--) {
3538                 dstpixel=(LPWORD)dstbits;
3539                 for (x = 0; x < dstwidth; x++) {
3540                     COLORREF srcval;
3541                     DWORD dstval;
3542                     srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
3543                     dstval=((GetRValue(srcval) << rShift) & rDst) |
3544                            ((GetGValue(srcval) << gShift) & gDst) |
3545                            ((GetBValue(srcval) << bShift) & bDst);
3546                     *dstpixel++=dstval >> 16;
3547                 }
3548                 dstbits += linebytes;
3549             }
3550         }
3551         break;
3552     }
3553 }
3554
3555
3556 /***********************************************************************
3557  *           X11DRV_DIB_SetImageBits_24
3558  *
3559  * SetDIBits for a 24-bit deep DIB.
3560  */
3561 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
3562                                  DWORD srcwidth, DWORD dstwidth, int left,
3563                                  X11DRV_PDEVICE *physDev,
3564                                  DWORD rSrc, DWORD gSrc, DWORD bSrc,
3565                                  XImage *bmpImage, DWORD linebytes )
3566 {
3567     DWORD x;
3568     int h;
3569
3570     if (lines < 0 )
3571     {
3572         lines = -lines;
3573         srcbits = srcbits + linebytes * (lines - 1);
3574         linebytes = -linebytes;
3575     }
3576
3577     switch (bmpImage->depth)
3578     {
3579     case 24:
3580         if (bmpImage->bits_per_pixel==24) {
3581             char* dstbits;
3582
3583             srcbits=srcbits+left*3;
3584             dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3585
3586             if (bmpImage->green_mask!=0x00ff00 ||
3587                 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3588                 goto notsupported;
3589             } else if (rSrc==bmpImage->red_mask) {
3590                 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
3591                 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
3592                 X11DRV_DIB_Convert_any_asis
3593                     (dstwidth,lines,3,
3594                      srcbits,linebytes,
3595                      dstbits,-bmpImage->bytes_per_line);
3596             } else {
3597                 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
3598                 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
3599                 X11DRV_DIB_Convert_888_reverse
3600                     (dstwidth,lines,
3601                      srcbits,linebytes,
3602                      dstbits,-bmpImage->bytes_per_line);
3603             }
3604             break;
3605         }
3606         /* fall through */
3607
3608     case 32:
3609         {
3610             char* dstbits;
3611
3612             srcbits=srcbits+left*3;
3613             dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
3614
3615             if (bmpImage->green_mask!=0x00ff00 ||
3616                 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3617                 goto notsupported;
3618             } else if (rSrc==bmpImage->red_mask) {
3619                 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
3620                 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
3621                 X11DRV_DIB_Convert_888_to_0888_asis
3622                     (dstwidth,lines,
3623                      srcbits,linebytes,
3624                      dstbits,-bmpImage->bytes_per_line);
3625             } else {
3626                 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
3627                 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
3628                 X11DRV_DIB_Convert_888_to_0888_reverse
3629                     (dstwidth,lines,
3630                      srcbits,linebytes,
3631                      dstbits,-bmpImage->bytes_per_line);
3632             }
3633             break;
3634         }
3635
3636     case 15:
3637     case 16:
3638         {
3639             char* dstbits;
3640
3641             srcbits=srcbits+left*3;
3642             dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
3643
3644             if (bmpImage->green_mask==0x03e0) {
3645                 if ((rSrc==0xff0000 && bmpImage->red_mask==0x7f00) ||
3646                     (bSrc==0xff0000 && bmpImage->blue_mask==0x7f00)) {
3647                     /* ==== rgb 888 dib -> rgb 555 bmp ==== */
3648                     /* ==== bgr 888 dib -> bgr 555 bmp ==== */
3649                     X11DRV_DIB_Convert_888_to_555_asis
3650                         (dstwidth,lines,
3651                          srcbits,linebytes,
3652                          dstbits,-bmpImage->bytes_per_line);
3653                 } else if ((rSrc==0xff && bmpImage->red_mask==0x7f00) ||
3654                            (bSrc==0xff && bmpImage->blue_mask==0x7f00)) {
3655                     /* ==== rgb 888 dib -> bgr 555 bmp ==== */
3656                     /* ==== bgr 888 dib -> rgb 555 bmp ==== */
3657                     X11DRV_DIB_Convert_888_to_555_reverse
3658                         (dstwidth,lines,
3659                          srcbits,linebytes,
3660                          dstbits,-bmpImage->bytes_per_line);
3661                 } else {
3662                     goto notsupported;
3663                 }
3664             } else if (bmpImage->green_mask==0x07e0) {
3665                 if ((rSrc==0xff0000 && bmpImage->red_mask==0xf800) ||
3666                     (bSrc==0xff0000 && bmpImage->blue_mask==0xf800)) {
3667                     /* ==== rgb 888 dib -> rgb 565 bmp ==== */
3668                     /* ==== bgr 888 dib -> bgr 565 bmp ==== */
3669                     X11DRV_DIB_Convert_888_to_565_asis
3670                         (dstwidth,lines,
3671                          srcbits,linebytes,
3672                          dstbits,-bmpImage->bytes_per_line);
3673                 } else if ((rSrc==0xff && bmpImage->red_mask==0xf800) ||
3674                            (bSrc==0xff && bmpImage->blue_mask==0xf800)) {
3675                     /* ==== rgb 888 dib -> bgr 565 bmp ==== */
3676                     /* ==== bgr 888 dib -> rgb 565 bmp ==== */
3677                     X11DRV_DIB_Convert_888_to_565_reverse
3678                         (dstwidth,lines,
3679                          srcbits,linebytes,
3680                          dstbits,-bmpImage->bytes_per_line);
3681                 } else {
3682                     goto notsupported;
3683                 }
3684             } else {
3685                 goto notsupported;
3686             }
3687         }
3688         break;
3689
3690     default:
3691     notsupported:
3692         WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3693               rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3694               bmpImage->green_mask, bmpImage->blue_mask );
3695         /* fall through */
3696     case 1:
3697     case 4:
3698     case 8:
3699         {
3700             /* ==== rgb 888 dib -> any bmp bormat ==== */
3701             const BYTE* srcbyte;
3702
3703             /* Windows only supports one 24bpp DIB format: RGB888 */
3704             srcbits+=left*3;
3705             for (h = lines - 1; h >= 0; h--) {
3706                 srcbyte=(const BYTE*)srcbits;
3707                 for (x = left; x < dstwidth+left; x++) {
3708                     XPutPixel(bmpImage, x, h,
3709                               X11DRV_PALETTE_ToPhysical
3710                               (physDev, RGB(srcbyte[2], srcbyte[1], srcbyte[0])));
3711                     srcbyte+=3;
3712                 }
3713                 srcbits += linebytes;
3714             }
3715         }
3716         break;
3717     }
3718 }
3719
3720
3721 /***********************************************************************
3722  *           X11DRV_DIB_GetImageBits_24
3723  *
3724  * GetDIBits for an 24-bit deep DIB.
3725  */
3726 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
3727                                         DWORD dstwidth, DWORD srcwidth,
3728                                         PALETTEENTRY *srccolors,
3729                                         DWORD rDst, DWORD gDst, DWORD bDst,
3730                                         XImage *bmpImage, DWORD linebytes )
3731 {
3732     DWORD x;
3733     int h;
3734
3735     if (lines < 0 )
3736     {
3737         lines = -lines;
3738         dstbits = dstbits + ( linebytes * (lines-1) );
3739         linebytes = -linebytes;
3740     }
3741
3742     switch (bmpImage->depth)
3743     {
3744     case 24:
3745         if (bmpImage->bits_per_pixel==24) {
3746             const char* srcbits;
3747
3748             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3749
3750             if (bmpImage->green_mask!=0x00ff00 ||
3751                 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3752                 goto notsupported;
3753             } else if (rDst==bmpImage->red_mask) {
3754                 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
3755                 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
3756                 X11DRV_DIB_Convert_any_asis
3757                     (dstwidth,lines,3,
3758                      srcbits,-bmpImage->bytes_per_line,
3759                      dstbits,linebytes);
3760             } else {
3761                 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
3762                 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
3763                 X11DRV_DIB_Convert_888_reverse
3764                     (dstwidth,lines,
3765                      srcbits,-bmpImage->bytes_per_line,
3766                      dstbits,linebytes);
3767             }
3768             break;
3769         }
3770         /* fall through */
3771
3772     case 32:
3773         {
3774             const char* srcbits;
3775
3776             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3777
3778             if (bmpImage->green_mask!=0x00ff00 ||
3779                 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3780                 goto notsupported;
3781             } else if (rDst==bmpImage->red_mask) {
3782                 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3783                 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3784                 X11DRV_DIB_Convert_0888_to_888_asis
3785                     (dstwidth,lines,
3786                      srcbits,-bmpImage->bytes_per_line,
3787                      dstbits,linebytes);
3788             } else {
3789                 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3790                 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3791                 X11DRV_DIB_Convert_0888_to_888_reverse
3792                     (dstwidth,lines,
3793                      srcbits,-bmpImage->bytes_per_line,
3794                      dstbits,linebytes);
3795             }
3796             break;
3797         }
3798
3799     case 15:
3800     case 16:
3801         {
3802             const char* srcbits;
3803
3804             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3805
3806             if (bmpImage->green_mask==0x03e0) {
3807                 if ((rDst==0xff0000 && bmpImage->red_mask==0x7f00) ||
3808                     (bDst==0xff0000 && bmpImage->blue_mask==0x7f00)) {
3809                     /* ==== rgb 555 bmp -> rgb 888 dib ==== */
3810                     /* ==== bgr 555 bmp -> bgr 888 dib ==== */
3811                     X11DRV_DIB_Convert_555_to_888_asis
3812                         (dstwidth,lines,
3813                          srcbits,-bmpImage->bytes_per_line,
3814                          dstbits,linebytes);
3815                 } else if ((rDst==0xff && bmpImage->red_mask==0x7f00) ||
3816                            (bDst==0xff && bmpImage->blue_mask==0x7f00)) {
3817                     /* ==== rgb 555 bmp -> bgr 888 dib ==== */
3818                     /* ==== bgr 555 bmp -> rgb 888 dib ==== */
3819                     X11DRV_DIB_Convert_555_to_888_reverse
3820                         (dstwidth,lines,
3821                          srcbits,-bmpImage->bytes_per_line,
3822                          dstbits,linebytes);
3823                 } else {
3824                     goto notsupported;
3825                 }
3826             } else if (bmpImage->green_mask==0x07e0) {
3827                 if ((rDst==0xff0000 && bmpImage->red_mask==0xf800) ||
3828                     (bDst==0xff0000 && bmpImage->blue_mask==0xf800)) {
3829                     /* ==== rgb 565 bmp -> rgb 888 dib ==== */
3830                     /* ==== bgr 565 bmp -> bgr 888 dib ==== */
3831                     X11DRV_DIB_Convert_565_to_888_asis
3832                         (dstwidth,lines,
3833                          srcbits,-bmpImage->bytes_per_line,
3834                          dstbits,linebytes);
3835                 } else if ((rDst==0xff && bmpImage->red_mask==0xf800) ||
3836                            (bDst==0xff && bmpImage->blue_mask==0xf800)) {
3837                     /* ==== rgb 565 bmp -> bgr 888 dib ==== */
3838                     /* ==== bgr 565 bmp -> rgb 888 dib ==== */
3839                     X11DRV_DIB_Convert_565_to_888_reverse
3840                         (dstwidth,lines,
3841                          srcbits,-bmpImage->bytes_per_line,
3842                          dstbits,linebytes);
3843                 } else {
3844                     goto notsupported;
3845                 }
3846             } else {
3847                 goto notsupported;
3848             }
3849         }
3850         break;
3851
3852     case 1:
3853     case 4:
3854         if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3855             /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
3856             BYTE* dstbyte;
3857
3858             /* Windows only supports one 24bpp DIB format: rgb 888 */
3859             for (h = lines - 1; h >= 0; h--) {
3860                 dstbyte=dstbits;
3861                 for (x = 0; x < dstwidth; x++) {
3862                     PALETTEENTRY srcval;
3863                     srcval=srccolors[XGetPixel(bmpImage, x, h)];
3864                     dstbyte[0]=srcval.peBlue;
3865                     dstbyte[1]=srcval.peGreen;
3866                     dstbyte[2]=srcval.peRed;
3867                     dstbyte+=3;
3868                 }
3869                 dstbits += linebytes;
3870             }
3871         } else {
3872             goto notsupported;
3873         }
3874         break;
3875
3876     case 8:
3877         if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors) {
3878             /* ==== pal 8 bmp -> rgb 888 dib ==== */
3879             const void* srcbits;
3880             const BYTE* srcpixel;
3881             BYTE* dstbyte;
3882
3883             /* Windows only supports one 24bpp DIB format: rgb 888 */
3884             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3885             for (h = lines - 1; h >= 0; h--) {
3886                 srcpixel=srcbits;
3887                 dstbyte=dstbits;
3888                 for (x = 0; x < dstwidth; x++ ) {
3889                     PALETTEENTRY srcval;
3890                     srcval=srccolors[(int)*srcpixel++];
3891                     dstbyte[0]=srcval.peBlue;
3892                     dstbyte[1]=srcval.peGreen;
3893                     dstbyte[2]=srcval.peRed;
3894                     dstbyte+=3;
3895                 }
3896                 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
3897                 dstbits += linebytes;
3898             }
3899         } else {
3900             goto notsupported;
3901         }
3902         break;
3903
3904     default:
3905     notsupported:
3906         {
3907             /* ==== any bmp format -> 888 dib ==== */
3908             BYTE* dstbyte;
3909
3910             WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
3911                   bmpImage->depth, bmpImage->red_mask,
3912                   bmpImage->green_mask, bmpImage->blue_mask,
3913                   rDst, gDst, bDst );
3914
3915             /* Windows only supports one 24bpp DIB format: rgb 888 */
3916             for (h = lines - 1; h >= 0; h--) {
3917                 dstbyte=dstbits;
3918                 for (x = 0; x < dstwidth; x++) {
3919                     COLORREF srcval=X11DRV_PALETTE_ToLogical
3920                         (XGetPixel( bmpImage, x, h ));
3921                     dstbyte[0]=GetBValue(srcval);
3922                     dstbyte[1]=GetGValue(srcval);
3923                     dstbyte[2]=GetRValue(srcval);
3924                     dstbyte+=3;
3925                 }
3926                 dstbits += linebytes;
3927             }
3928         }
3929         break;
3930     }
3931 }
3932
3933
3934 /***********************************************************************
3935  *           X11DRV_DIB_SetImageBits_32
3936  *
3937  * SetDIBits for a 32-bit deep DIB.
3938  */
3939 static void X11DRV_DIB_SetImageBits_32(int lines, const BYTE *srcbits,
3940                                        DWORD srcwidth, DWORD dstwidth, int left,
3941                                        X11DRV_PDEVICE *physDev,
3942                                        DWORD rSrc, DWORD gSrc, DWORD bSrc,
3943                                        XImage *bmpImage,
3944                                        DWORD linebytes)
3945 {
3946     DWORD x, *ptr;
3947     int h;
3948
3949     if (lines < 0 )
3950     {
3951        lines = -lines;
3952        srcbits = srcbits + ( linebytes * (lines-1) );
3953        linebytes = -linebytes;
3954     }
3955
3956     ptr = (DWORD *) srcbits + left;
3957
3958     switch (bmpImage->depth)
3959     {
3960     case 24:
3961         if (bmpImage->bits_per_pixel==24) {
3962             char* dstbits;
3963
3964             srcbits=srcbits+left*4;
3965             dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3966
3967             if (rSrc==bmpImage->red_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->blue_mask) {
3968                 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
3969                 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
3970                 X11DRV_DIB_Convert_0888_to_888_asis
3971                     (dstwidth,lines,
3972                      srcbits,linebytes,
3973                      dstbits,-bmpImage->bytes_per_line);
3974             } else if (bmpImage->green_mask!=0x00ff00 ||
3975                        (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3976                 goto notsupported;
3977                 /* the tests below assume sane bmpImage masks */
3978             } else if (rSrc==bmpImage->blue_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->red_mask) {
3979                 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
3980                 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
3981                 X11DRV_DIB_Convert_0888_to_888_reverse
3982                     (dstwidth,lines,
3983                      srcbits,linebytes,
3984                      dstbits,-bmpImage->bytes_per_line);
3985             } else if (bmpImage->blue_mask==0xff) {
3986                 /* ==== any 0888 dib -> rgb 888 bmp ==== */
3987                 X11DRV_DIB_Convert_any0888_to_rgb888
3988                     (dstwidth,lines,
3989                      srcbits,linebytes,
3990                      rSrc,gSrc,bSrc,
3991                      dstbits,-bmpImage->bytes_per_line);
3992             } else {
3993                 /* ==== any 0888 dib -> bgr 888 bmp ==== */
3994                 X11DRV_DIB_Convert_any0888_to_bgr888
3995                     (dstwidth,lines,
3996                      srcbits,linebytes,
3997                      rSrc,gSrc,bSrc,
3998                      dstbits,-bmpImage->bytes_per_line);
3999             }
4000             break;
4001         }
4002         /* fall through */
4003
4004     case 32:
4005         {
4006             char* dstbits;
4007
4008             srcbits=srcbits+left*4;
4009             dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
4010
4011             if (gSrc==bmpImage->green_mask) {
4012                 if (rSrc==bmpImage->red_mask && bSrc==bmpImage->blue_mask) {
4013                     /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
4014                     /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
4015                     X11DRV_DIB_Convert_any_asis
4016                         (dstwidth,lines,4,
4017                          srcbits,linebytes,
4018                          dstbits,-bmpImage->bytes_per_line);
4019                 } else if (bmpImage->green_mask!=0x00ff00 ||
4020                            (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4021                     goto notsupported;
4022                     /* the tests below assume sane bmpImage masks */
4023                 } else if (rSrc==bmpImage->blue_mask && bSrc==bmpImage->red_mask) {
4024                     /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
4025                     /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
4026                     X11DRV_DIB_Convert_0888_reverse
4027                         (dstwidth,lines,
4028                          srcbits,linebytes,
4029                          dstbits,-bmpImage->bytes_per_line);
4030                 } else {
4031                     /* ==== any 0888 dib -> any 0888 bmp ==== */
4032                     X11DRV_DIB_Convert_0888_any
4033                         (dstwidth,lines,
4034                          srcbits,linebytes,
4035                          rSrc,gSrc,bSrc,
4036                          dstbits,-bmpImage->bytes_per_line,
4037                          bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4038                 }
4039             } else if (bmpImage->green_mask!=0x00ff00 ||
4040                        (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4041                 goto notsupported;
4042                 /* the tests below assume sane bmpImage masks */
4043             } else {
4044                 /* ==== any 0888 dib -> any 0888 bmp ==== */
4045                 X11DRV_DIB_Convert_0888_any
4046                     (dstwidth,lines,
4047                      srcbits,linebytes,
4048                      rSrc,gSrc,bSrc,
4049                      dstbits,-bmpImage->bytes_per_line,
4050                      bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4051             }
4052         }
4053         break;
4054
4055     case 15:
4056     case 16:
4057         {
4058             char* dstbits;
4059
4060             srcbits=srcbits+left*4;
4061             dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
4062
4063             if (rSrc==0xff0000 && gSrc==0x00ff00 && bSrc==0x0000ff) {
4064                 if (bmpImage->green_mask==0x03e0) {
4065                     if (bmpImage->red_mask==0x7f00) {
4066                         /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
4067                         X11DRV_DIB_Convert_0888_to_555_asis
4068                             (dstwidth,lines,
4069                              srcbits,linebytes,
4070                              dstbits,-bmpImage->bytes_per_line);
4071                     } else if (bmpImage->blue_mask==0x7f00) {
4072                         /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
4073                         X11DRV_DIB_Convert_0888_to_555_reverse
4074                             (dstwidth,lines,
4075                              srcbits,linebytes,
4076                              dstbits,-bmpImage->bytes_per_line);
4077                     } else {
4078                         goto notsupported;
4079                     }
4080                 } else if (bmpImage->green_mask==0x07e0) {
4081                     if (bmpImage->red_mask==0xf800) {
4082                         /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
4083                         X11DRV_DIB_Convert_0888_to_565_asis
4084                             (dstwidth,lines,
4085                              srcbits,linebytes,
4086                              dstbits,-bmpImage->bytes_per_line);
4087                     } else if (bmpImage->blue_mask==0xf800) {
4088                         /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
4089                         X11DRV_DIB_Convert_0888_to_565_reverse
4090                             (dstwidth,lines,
4091                              srcbits,linebytes,
4092                              dstbits,-bmpImage->bytes_per_line);
4093                     } else {
4094                         goto notsupported;
4095                     }
4096                 } else {
4097                     goto notsupported;
4098                 }
4099             } else if (rSrc==0x0000ff && gSrc==0x00ff00 && bSrc==0xff0000) {
4100                 if (bmpImage->green_mask==0x03e0) {
4101                     if (bmpImage->blue_mask==0x7f00) {
4102                         /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
4103                         X11DRV_DIB_Convert_0888_to_555_asis
4104                             (dstwidth,lines,
4105                              srcbits,linebytes,
4106                              dstbits,-bmpImage->bytes_per_line);
4107                     } else if (bmpImage->red_mask==0x7f00) {
4108                         /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
4109                         X11DRV_DIB_Convert_0888_to_555_reverse
4110                             (dstwidth,lines,
4111                              srcbits,linebytes,
4112                              dstbits,-bmpImage->bytes_per_line);
4113                     } else {
4114                         goto notsupported;
4115                     }
4116                 } else if (bmpImage->green_mask==0x07e0) {
4117                     if (bmpImage->blue_mask==0xf800) {
4118                         /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
4119                         X11DRV_DIB_Convert_0888_to_565_asis
4120                             (dstwidth,lines,
4121                              srcbits,linebytes,
4122                              dstbits,-bmpImage->bytes_per_line);
4123                     } else if (bmpImage->red_mask==0xf800) {
4124                         /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
4125                         X11DRV_DIB_Convert_0888_to_565_reverse
4126                             (dstwidth,lines,
4127                              srcbits,linebytes,
4128                              dstbits,-bmpImage->bytes_per_line);
4129                     } else {
4130                         goto notsupported;
4131                     }
4132                 } else {
4133                     goto notsupported;
4134                 }
4135             } else {
4136                 if (bmpImage->green_mask==0x03e0 &&
4137                     (bmpImage->red_mask==0x7f00 ||
4138                      bmpImage->blue_mask==0x7f00)) {
4139                     /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
4140                     X11DRV_DIB_Convert_any0888_to_5x5
4141                         (dstwidth,lines,
4142                          srcbits,linebytes,
4143                          rSrc,gSrc,bSrc,
4144                          dstbits,-bmpImage->bytes_per_line,
4145                          bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4146                 } else if (bmpImage->green_mask==0x07e0 &&
4147                            (bmpImage->red_mask==0xf800 ||
4148                             bmpImage->blue_mask==0xf800)) {
4149                     /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
4150                     X11DRV_DIB_Convert_any0888_to_5x5
4151                         (dstwidth,lines,
4152                          srcbits,linebytes,
4153                          rSrc,gSrc,bSrc,
4154                          dstbits,-bmpImage->bytes_per_line,
4155                          bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4156                 } else {
4157                     goto notsupported;
4158                 }
4159             }
4160         }
4161         break;
4162
4163     default:
4164     notsupported:
4165         WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
4166               rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
4167               bmpImage->green_mask, bmpImage->blue_mask );
4168         /* fall through */
4169     case 1:
4170     case 4:
4171     case 8:
4172         {
4173             /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
4174             const DWORD* srcpixel;
4175             int rShift,gShift,bShift;
4176
4177             rShift=X11DRV_DIB_MaskToShift(rSrc);
4178             gShift=X11DRV_DIB_MaskToShift(gSrc);
4179             bShift=X11DRV_DIB_MaskToShift(bSrc);
4180             srcbits+=left*4;
4181             for (h = lines - 1; h >= 0; h--) {
4182                 srcpixel=(const DWORD*)srcbits;
4183                 for (x = left; x < dstwidth+left; x++) {
4184                     DWORD srcvalue;
4185                     BYTE red,green,blue;
4186                     srcvalue=*srcpixel++;
4187                     red=  (srcvalue >> rShift) & 0xff;
4188                     green=(srcvalue >> gShift) & 0xff;
4189                     blue= (srcvalue >> bShift) & 0xff;
4190                     XPutPixel(bmpImage, x, h, X11DRV_PALETTE_ToPhysical
4191                               (physDev, RGB(red,green,blue)));
4192                 }
4193                 srcbits += linebytes;
4194             }
4195         }
4196         break;
4197     }
4198
4199 }
4200
4201 /***********************************************************************
4202  *           X11DRV_DIB_GetImageBits_32
4203  *
4204  * GetDIBits for an 32-bit deep DIB.
4205  */
4206 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
4207                                         DWORD dstwidth, DWORD srcwidth,
4208                                         PALETTEENTRY *srccolors,
4209                                         DWORD rDst, DWORD gDst, DWORD bDst,
4210                                         XImage *bmpImage, DWORD linebytes )
4211 {
4212     DWORD x;
4213     int h;
4214     BYTE *bits;
4215
4216     if (lines < 0 )
4217     {
4218         lines = -lines;
4219         dstbits = dstbits + ( linebytes * (lines-1) );
4220         linebytes = -linebytes;
4221     }
4222
4223     bits = dstbits;
4224
4225     switch (bmpImage->depth)
4226     {
4227     case 24:
4228         if (bmpImage->bits_per_pixel==24) {
4229             const void* srcbits;
4230
4231             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4232
4233             if (rDst==bmpImage->red_mask && gDst==bmpImage->green_mask && bDst==bmpImage->blue_mask) {
4234                 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
4235                 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
4236                 X11DRV_DIB_Convert_888_to_0888_asis
4237                     (dstwidth,lines,
4238                      srcbits,-bmpImage->bytes_per_line,
4239                      dstbits,linebytes);
4240             } else if (bmpImage->green_mask!=0x00ff00 ||
4241                        (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4242                 goto notsupported;
4243                 /* the tests below assume sane bmpImage masks */
4244             } else if (rDst==bmpImage->blue_mask && gDst==bmpImage->green_mask && bDst==bmpImage->red_mask) {
4245                 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
4246                 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
4247                 X11DRV_DIB_Convert_888_to_0888_reverse
4248                     (dstwidth,lines,
4249                      srcbits,-bmpImage->bytes_per_line,
4250                      dstbits,linebytes);
4251             } else if (bmpImage->blue_mask==0xff) {
4252                 /* ==== rgb 888 bmp -> any 0888 dib ==== */
4253                 X11DRV_DIB_Convert_rgb888_to_any0888
4254                     (dstwidth,lines,
4255                      srcbits,-bmpImage->bytes_per_line,
4256                      dstbits,linebytes,
4257                      rDst,gDst,bDst);
4258             } else {
4259                 /* ==== bgr 888 bmp -> any 0888 dib ==== */
4260                 X11DRV_DIB_Convert_bgr888_to_any0888
4261                     (dstwidth,lines,
4262                      srcbits,-bmpImage->bytes_per_line,
4263                      dstbits,linebytes,
4264                      rDst,gDst,bDst);
4265             }
4266             break;
4267         }
4268         /* fall through */
4269
4270     case 32:
4271         {
4272             const char* srcbits;
4273
4274             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4275
4276             if (gDst==bmpImage->green_mask) {
4277                 if (rDst==bmpImage->red_mask && bDst==bmpImage->blue_mask) {
4278                     /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
4279                     /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
4280                     X11DRV_DIB_Convert_any_asis
4281                         (dstwidth,lines,4,
4282                          srcbits,-bmpImage->bytes_per_line,
4283                          dstbits,linebytes);
4284                 } else if (bmpImage->green_mask!=0x00ff00 ||
4285                            (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4286                     goto notsupported;
4287                     /* the tests below assume sane bmpImage masks */
4288                 } else if (rDst==bmpImage->blue_mask && bDst==bmpImage->red_mask) {
4289                     /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
4290                     /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
4291                     X11DRV_DIB_Convert_0888_reverse
4292                         (dstwidth,lines,
4293                          srcbits,-bmpImage->bytes_per_line,
4294                          dstbits,linebytes);
4295                 } else {
4296                     /* ==== any 0888 bmp -> any 0888 dib ==== */
4297                     X11DRV_DIB_Convert_0888_any
4298                         (dstwidth,lines,
4299                          srcbits,-bmpImage->bytes_per_line,
4300                          bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4301                          dstbits,linebytes,
4302                          rDst,gDst,bDst);
4303                 }
4304             } else if (bmpImage->green_mask!=0x00ff00 ||
4305                        (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4306                 goto notsupported;
4307                 /* the tests below assume sane bmpImage masks */
4308             } else {
4309                 /* ==== any 0888 bmp -> any 0888 dib ==== */
4310                 X11DRV_DIB_Convert_0888_any
4311                     (dstwidth,lines,
4312                      srcbits,-bmpImage->bytes_per_line,
4313                      bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4314                      dstbits,linebytes,
4315                      rDst,gDst,bDst);
4316             }
4317         }
4318         break;
4319
4320     case 15:
4321     case 16:
4322         {
4323             const char* srcbits;
4324
4325             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4326
4327             if (rDst==0xff0000 && gDst==0x00ff00 && bDst==0x0000ff) {
4328                 if (bmpImage->green_mask==0x03e0) {
4329                     if (bmpImage->red_mask==0x7f00) {
4330                         /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
4331                         X11DRV_DIB_Convert_555_to_0888_asis
4332                             (dstwidth,lines,
4333                              srcbits,-bmpImage->bytes_per_line,
4334                              dstbits,linebytes);
4335                     } else if (bmpImage->blue_mask==0x7f00) {
4336                         /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
4337                         X11DRV_DIB_Convert_555_to_0888_reverse
4338                             (dstwidth,lines,
4339                              srcbits,-bmpImage->bytes_per_line,
4340                              dstbits,linebytes);
4341                     } else {
4342                         goto notsupported;
4343                     }
4344                 } else if (bmpImage->green_mask==0x07e0) {
4345                     if (bmpImage->red_mask==0xf800) {
4346                         /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
4347                         X11DRV_DIB_Convert_565_to_0888_asis
4348                             (dstwidth,lines,
4349                              srcbits,-bmpImage->bytes_per_line,
4350                              dstbits,linebytes);
4351                     } else if (bmpImage->blue_mask==0xf800) {
4352                         /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
4353                         X11DRV_DIB_Convert_565_to_0888_reverse
4354                             (dstwidth,lines,
4355                              srcbits,-bmpImage->bytes_per_line,
4356                              dstbits,linebytes);
4357                     } else {
4358                         goto notsupported;
4359                     }
4360                 } else {
4361                     goto notsupported;
4362                 }
4363             } else if (rDst==0x0000ff && gDst==0x00ff00 && bDst==0xff0000) {
4364                 if (bmpImage->green_mask==0x03e0) {
4365                     if (bmpImage->blue_mask==0x7f00) {
4366                         /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
4367                         X11DRV_DIB_Convert_555_to_0888_asis
4368                             (dstwidth,lines,
4369                              srcbits,-bmpImage->bytes_per_line,
4370                              dstbits,linebytes);
4371                     } else if (bmpImage->red_mask==0x7f00) {
4372                         /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
4373                         X11DRV_DIB_Convert_555_to_0888_reverse
4374                             (dstwidth,lines,
4375                              srcbits,-bmpImage->bytes_per_line,
4376                              dstbits,linebytes);
4377                     } else {
4378                         goto notsupported;
4379                     }
4380                 } else if (bmpImage->green_mask==0x07e0) {
4381                     if (bmpImage->blue_mask==0xf800) {
4382                         /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
4383                         X11DRV_DIB_Convert_565_to_0888_asis
4384                             (dstwidth,lines,
4385                              srcbits,-bmpImage->bytes_per_line,
4386                              dstbits,linebytes);
4387                     } else if (bmpImage->red_mask==0xf800) {
4388                         /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
4389                         X11DRV_DIB_Convert_565_to_0888_reverse
4390                             (dstwidth,lines,
4391                              srcbits,-bmpImage->bytes_per_line,
4392                              dstbits,linebytes);
4393                     } else {
4394                         goto notsupported;
4395                     }
4396                 } else {
4397                     goto notsupported;
4398                 }
4399             } else {
4400                 if (bmpImage->green_mask==0x03e0 &&
4401                     (bmpImage->red_mask==0x7f00 ||
4402                      bmpImage->blue_mask==0x7f00)) {
4403                     /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
4404                     X11DRV_DIB_Convert_5x5_to_any0888
4405                         (dstwidth,lines,
4406                          srcbits,-bmpImage->bytes_per_line,
4407                          bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4408                          dstbits,linebytes,
4409                          rDst,gDst,bDst);
4410                 } else if (bmpImage->green_mask==0x07e0 &&
4411                            (bmpImage->red_mask==0xf800 ||
4412                             bmpImage->blue_mask==0xf800)) {
4413                     /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
4414                     X11DRV_DIB_Convert_5x5_to_any0888
4415                         (dstwidth,lines,
4416                          srcbits,-bmpImage->bytes_per_line,
4417                          bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4418                          dstbits,linebytes,
4419                          rDst,gDst,bDst);
4420                 } else {
4421                     goto notsupported;
4422                 }
4423             }
4424         }
4425         break;
4426
4427     case 1:
4428     case 4:
4429         if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
4430             /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
4431             int rShift,gShift,bShift;
4432             DWORD* dstpixel;
4433
4434             rShift=X11DRV_DIB_MaskToShift(rDst);
4435             gShift=X11DRV_DIB_MaskToShift(gDst);
4436             bShift=X11DRV_DIB_MaskToShift(bDst);
4437             for (h = lines - 1; h >= 0; h--) {
4438                 dstpixel=(DWORD*)dstbits;
4439                 for (x = 0; x < dstwidth; x++) {
4440                     PALETTEENTRY srcval;
4441                     srcval = srccolors[XGetPixel(bmpImage, x, h)];
4442                     *dstpixel++=(srcval.peRed   << rShift) |
4443                                 (srcval.peGreen << gShift) |
4444                                 (srcval.peBlue  << bShift);
4445                 }
4446                 dstbits += linebytes;
4447             }
4448         } else {
4449             goto notsupported;
4450         }
4451         break;
4452
4453     case 8:
4454         if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
4455             /* ==== pal 8 bmp -> any 0888 dib ==== */
4456             int rShift,gShift,bShift;
4457             const void* srcbits;
4458             const BYTE* srcpixel;
4459             DWORD* dstpixel;
4460
4461             rShift=X11DRV_DIB_MaskToShift(rDst);
4462             gShift=X11DRV_DIB_MaskToShift(gDst);
4463             bShift=X11DRV_DIB_MaskToShift(bDst);
4464             srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4465             for (h = lines - 1; h >= 0; h--) {
4466                 srcpixel=srcbits;
4467                 dstpixel=(DWORD*)dstbits;
4468                 for (x = 0; x < dstwidth; x++) {
4469                     PALETTEENTRY srcval;
4470                     srcval=srccolors[(int)*srcpixel++];
4471                     *dstpixel++=(srcval.peRed   << rShift) |
4472                                 (srcval.peGreen << gShift) |
4473                                 (srcval.peBlue  << bShift);
4474                 }
4475                 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
4476                 dstbits += linebytes;
4477             }
4478         } else {
4479             goto notsupported;
4480         }
4481         break;
4482
4483     default:
4484     notsupported:
4485         {
4486             /* ==== any bmp format -> any 0888 dib ==== */
4487             int rShift,gShift,bShift;
4488             DWORD* dstpixel;
4489
4490             WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
4491                   bmpImage->depth, bmpImage->red_mask,
4492                   bmpImage->green_mask, bmpImage->blue_mask,
4493                   rDst,gDst,bDst);
4494
4495             rShift=X11DRV_DIB_MaskToShift(rDst);
4496             gShift=X11DRV_DIB_MaskToShift(gDst);
4497             bShift=X11DRV_DIB_MaskToShift(bDst);
4498             for (h = lines - 1; h >= 0; h--) {
4499                 dstpixel=(DWORD*)dstbits;
4500                 for (x = 0; x < dstwidth; x++) {
4501                     COLORREF srcval;
4502                     srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
4503                     *dstpixel++=(GetRValue(srcval) << rShift) |
4504                                 (GetGValue(srcval) << gShift) |
4505                                 (GetBValue(srcval) << bShift);
4506                 }
4507                 dstbits += linebytes;
4508             }
4509         }
4510         break;
4511     }
4512 }
4513
4514 /***********************************************************************
4515  *           X11DRV_DIB_SetImageBits
4516  *
4517  * Transfer the bits to an X image.
4518  * Helper function for SetDIBits() and SetDIBitsToDevice().
4519  */
4520 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
4521 {
4522     int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
4523     XImage *bmpImage;
4524
4525     wine_tsx11_lock();
4526     if (descr->image)
4527         bmpImage = descr->image;
4528     else {
4529         bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
4530                                  descr->infoWidth, lines, 32, 0 );
4531         bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
4532         if(bmpImage->data == NULL) {
4533             ERR("Out of memory!\n");
4534             XDestroyImage( bmpImage );
4535             wine_tsx11_unlock();
4536             return lines;
4537         }
4538     }
4539
4540     TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
4541           descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
4542     TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
4543           bmpImage->depth,bmpImage->bits_per_pixel,
4544           bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4545
4546       /* Transfer the pixels */
4547     switch(descr->infoBpp)
4548     {
4549     case 1:
4550         X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
4551                                    descr->width, descr->xSrc, (int *)(descr->colorMap),
4552                                    bmpImage, descr->dibpitch );
4553         break;
4554     case 4:
4555         if (descr->compression) {
4556             XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
4557                           descr->width, descr->height, AllPlanes, ZPixmap,
4558                           bmpImage, descr->xSrc, descr->ySrc );
4559
4560             X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
4561                                           descr->infoWidth, descr->width,
4562                                           descr->xSrc, (int *)(descr->colorMap),
4563                                           bmpImage );
4564         } else
4565             X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
4566                                        descr->infoWidth, descr->width,
4567                                        descr->xSrc, (int*)(descr->colorMap),
4568                                        bmpImage, descr->dibpitch );
4569         break;
4570     case 8:
4571         if (descr->compression) {
4572             XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
4573                           descr->width, descr->height, AllPlanes, ZPixmap,
4574                           bmpImage, descr->xSrc, descr->ySrc );
4575             X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
4576                                           descr->infoWidth, descr->width,
4577                                           descr->xSrc, (int *)(descr->colorMap),
4578                                           bmpImage );
4579         } else
4580             X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
4581                                        descr->infoWidth, descr->width,
4582                                        descr->xSrc, (int *)(descr->colorMap),
4583                                        bmpImage, descr->dibpitch );
4584         break;
4585     case 15:
4586     case 16:
4587         X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
4588                                     descr->infoWidth, descr->width,
4589                                    descr->xSrc, descr->physDev,
4590                                    descr->rMask, descr->gMask, descr->bMask,
4591                                    bmpImage, descr->dibpitch);
4592         break;
4593     case 24:
4594         X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
4595                                     descr->infoWidth, descr->width,
4596                                     descr->xSrc, descr->physDev,
4597                                     descr->rMask, descr->gMask, descr->bMask,
4598                                     bmpImage, descr->dibpitch);
4599         break;
4600     case 32:
4601         X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
4602                                     descr->infoWidth, descr->width,
4603                                    descr->xSrc, descr->physDev,
4604                                    descr->rMask, descr->gMask, descr->bMask,
4605                                    bmpImage, descr->dibpitch);
4606         break;
4607     default:
4608         WARN("(%d): Invalid depth\n", descr->infoBpp );
4609         break;
4610     }
4611
4612     TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
4613      descr->drawable, descr->gc, bmpImage,
4614      descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4615      descr->width, descr->height);
4616 #ifdef HAVE_LIBXXSHM
4617     if (descr->useShm)
4618     {
4619         XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
4620                       descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4621                       descr->width, descr->height, FALSE );
4622         XSync( gdi_display, 0 );
4623     }
4624     else
4625 #endif
4626         XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
4627                    descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4628                    descr->width, descr->height );
4629
4630     if (!descr->image) XDestroyImage( bmpImage );
4631     wine_tsx11_unlock();
4632     return lines;
4633 }
4634
4635 /***********************************************************************
4636  *           X11DRV_DIB_GetImageBits
4637  *
4638  * Transfer the bits from an X image.
4639  */
4640 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
4641 {
4642     int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
4643     XImage *bmpImage;
4644
4645     wine_tsx11_lock();
4646    if (descr->image)
4647         bmpImage = descr->image;
4648     else {
4649         bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
4650                                  descr->infoWidth, lines, 32, 0 );
4651         bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
4652         if(bmpImage->data == NULL) {
4653             ERR("Out of memory!\n");
4654             XDestroyImage( bmpImage );
4655             wine_tsx11_unlock();
4656             return lines;
4657         }
4658     }
4659
4660 #ifdef HAVE_LIBXXSHM
4661     if (descr->useShm)
4662     {
4663         int saveRed, saveGreen, saveBlue;
4664
4665         TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
4666                             gdi_display, descr->drawable, bmpImage,
4667                             descr->xSrc, descr->ySrc, AllPlanes);
4668
4669         /* We must save and restore the bmpImage's masks in order
4670          * to preserve them across the call to XShmGetImage, which
4671          * decides to eleminate them since it doesn't happen to know
4672          * what the format of the image is supposed to be, even though
4673          * we do. */
4674         saveRed = bmpImage->red_mask;
4675         saveBlue= bmpImage->blue_mask;
4676         saveGreen = bmpImage->green_mask;
4677
4678         XShmGetImage( gdi_display, descr->drawable, bmpImage,
4679                       descr->xSrc, descr->ySrc, AllPlanes);
4680
4681         bmpImage->red_mask = saveRed;
4682         bmpImage->blue_mask = saveBlue;
4683         bmpImage->green_mask = saveGreen;
4684     }
4685     else
4686 #endif /* HAVE_LIBXXSHM */
4687     {
4688         TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
4689               gdi_display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
4690               lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
4691         XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
4692                       descr->width, lines, AllPlanes, ZPixmap,
4693                       bmpImage, descr->xDest, descr->yDest );
4694     }
4695
4696     TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
4697           descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
4698     TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
4699           bmpImage->depth,bmpImage->bits_per_pixel,
4700           bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4701       /* Transfer the pixels */
4702     switch(descr->infoBpp)
4703     {
4704     case 1:
4705           X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
4706                                      descr->infoWidth, descr->width,
4707                                      descr->colorMap, descr->palentry,
4708                                      bmpImage, descr->dibpitch );
4709        break;
4710
4711     case 4:
4712        if (descr->compression)
4713            FIXME("Compression not yet supported!\n");
4714        else
4715            X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
4716                                       descr->infoWidth, descr->width,
4717                                       descr->colorMap, descr->palentry,
4718                                       bmpImage, descr->dibpitch );
4719        break;
4720
4721     case 8:
4722        if (descr->compression)
4723            FIXME("Compression not yet supported!\n");
4724        else
4725            X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
4726                                       descr->infoWidth, descr->width,
4727                                       descr->colorMap, descr->palentry,
4728                                       bmpImage, descr->dibpitch );
4729        break;
4730     case 15:
4731     case 16:
4732        X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
4733                                    descr->infoWidth,descr->width,
4734                                    descr->palentry,
4735                                    descr->rMask, descr->gMask, descr->bMask,
4736                                    bmpImage, descr->dibpitch );
4737        break;
4738
4739     case 24:
4740        X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
4741                                    descr->infoWidth,descr->width,
4742                                    descr->palentry,
4743                                    descr->rMask, descr->gMask, descr->bMask,
4744                                    bmpImage, descr->dibpitch);
4745        break;
4746
4747     case 32:
4748        X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
4749                                    descr->infoWidth, descr->width,
4750                                    descr->palentry,
4751                                    descr->rMask, descr->gMask, descr->bMask,
4752                                    bmpImage, descr->dibpitch);
4753        break;
4754
4755     default:
4756         WARN("(%d): Invalid depth\n", descr->infoBpp );
4757         break;
4758     }
4759
4760     if (!descr->image) XDestroyImage( bmpImage );
4761     wine_tsx11_unlock();
4762     return lines;
4763 }
4764
4765 /*************************************************************************
4766  *              X11DRV_SetDIBitsToDevice
4767  *
4768  */
4769 INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWORD cx,
4770                                 DWORD cy, INT xSrc, INT ySrc,
4771                                 UINT startscan, UINT lines, LPCVOID bits,
4772                                 const BITMAPINFO *info, UINT coloruse )
4773 {
4774     X11DRV_DIB_IMAGEBITS_DESCR descr;
4775     DWORD width;
4776     INT result;
4777     int height;
4778     BOOL top_down;
4779     POINT pt;
4780     DC *dc = physDev->dc;
4781
4782     if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
4783                            &descr.infoBpp, &descr.compression ) == -1)
4784         return 0;
4785     top_down = (height < 0);
4786     if (top_down) height = -height;
4787
4788     pt.x = xDest;
4789     pt.y = yDest;
4790     LPtoDP(physDev->hdc, &pt, 1);
4791
4792     if (!lines || (startscan >= height)) return 0;
4793     if (!top_down && startscan + lines > height) lines = height - startscan;
4794
4795     /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
4796      * and clamp all values to fit inside [startscan,startscan+lines]
4797      */
4798     if (ySrc + cy <= startscan + lines)
4799     {
4800         INT y = startscan + lines - (ySrc + cy);
4801         if (ySrc < startscan) cy -= (startscan - ySrc);
4802         if (!top_down)
4803         {
4804             /* avoid getting unnecessary lines */
4805             ySrc = 0;
4806             if (y >= lines) return 0;
4807             lines -= y;
4808         }
4809         else
4810         {
4811             if (y >= lines) return lines;
4812             ySrc = y;  /* need to get all lines in top down mode */
4813         }
4814     }
4815     else
4816     {
4817         if (ySrc >= startscan + lines) return lines;
4818         pt.y += ySrc + cy - (startscan + lines);
4819         cy = startscan + lines - ySrc;
4820         ySrc = 0;
4821         if (cy > lines) cy = lines;
4822     }
4823     if (xSrc >= width) return lines;
4824     if (xSrc + cx >= width) cx = width - xSrc;
4825     if (!cx || !cy) return lines;
4826
4827     X11DRV_SetupGCForText( physDev );  /* To have the correct colors */
4828     TSXSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);
4829
4830     switch (descr.infoBpp)
4831     {
4832        case 1:
4833        case 4:
4834        case 8:
4835                descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
4836                                             coloruse == DIB_PAL_COLORS ? physDev : NULL, coloruse,
4837                                             dc->bitsPerPixel, info, &descr.nColorMap );
4838                if (!descr.colorMap) return 0;
4839                descr.rMask = descr.gMask = descr.bMask = 0;
4840                break;
4841        case 15:
4842        case 16:
4843                descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
4844                descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0x03e0;
4845                descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0x001f;
4846                descr.colorMap = 0;
4847                break;
4848
4849        case 24:
4850        case 32:
4851                descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors       : 0xff0000;
4852                descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
4853                descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
4854                descr.colorMap = 0;
4855                break;
4856     }
4857
4858     descr.physDev   = physDev;
4859     descr.bits      = bits;
4860     descr.image     = NULL;
4861     descr.palentry  = NULL;
4862     descr.lines     = top_down ? -lines : lines;
4863     descr.infoWidth = width;
4864     descr.depth     = dc->bitsPerPixel;
4865     descr.drawable  = physDev->drawable;
4866     descr.gc        = physDev->gc;
4867     descr.xSrc      = xSrc;
4868     descr.ySrc      = ySrc;
4869     descr.xDest     = physDev->org.x + pt.x;
4870     descr.yDest     = physDev->org.y + pt.y;
4871     descr.width     = cx;
4872     descr.height    = cy;
4873     descr.useShm    = FALSE;
4874     descr.dibpitch  = ((width * descr.infoBpp + 31) &~31) / 8;
4875
4876     result = X11DRV_DIB_SetImageBits( &descr );
4877
4878     if (descr.infoBpp <= 8)
4879        HeapFree(GetProcessHeap(), 0, descr.colorMap);
4880     return result;
4881 }
4882
4883 /***********************************************************************
4884  *           SetDIBits   (X11DRV.@)
4885  */
4886 INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
4887                       UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse )
4888 {
4889   X11DRV_DIB_IMAGEBITS_DESCR descr;
4890   BITMAPOBJ *bmp;
4891   int height, tmpheight;
4892   INT result;
4893
4894   descr.physDev = physDev;
4895
4896   if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
4897                          &descr.infoBpp, &descr.compression ) == -1)
4898       return 0;
4899
4900   tmpheight = height;
4901   if (height < 0) height = -height;
4902   if (!lines || (startscan >= height))
4903       return 0;
4904
4905   if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
4906
4907   if (startscan + lines > height) lines = height - startscan;
4908
4909   switch (descr.infoBpp)
4910   {
4911        case 1:
4912        case 4:
4913        case 8:
4914                descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
4915                         coloruse == DIB_PAL_COLORS ? descr.physDev : NULL, coloruse,
4916                                                           bmp->bitmap.bmBitsPixel,
4917                                                           info, &descr.nColorMap );
4918                if (!descr.colorMap)
4919                {
4920                    GDI_ReleaseObj( hbitmap );
4921                    return 0;
4922                }
4923                descr.rMask = descr.gMask = descr.bMask = 0;
4924                break;
4925        case 15:
4926        case 16:
4927                descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
4928                descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
4929                descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
4930                descr.colorMap = 0;
4931                break;
4932
4933        case 24:
4934        case 32:
4935                descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors       : 0xff0000;
4936                descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
4937                descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
4938                descr.colorMap = 0;
4939                break;
4940
4941        default: break;
4942   }
4943
4944   descr.bits      = bits;
4945   descr.image     = NULL;
4946   descr.palentry  = NULL;
4947   descr.lines     = tmpheight >= 0 ? lines : -lines;
4948   descr.depth     = bmp->bitmap.bmBitsPixel;
4949   descr.drawable  = (Pixmap)bmp->physBitmap;
4950   descr.gc        = BITMAP_GC(bmp);
4951   descr.xSrc      = 0;
4952   descr.ySrc      = 0;
4953   descr.xDest     = 0;
4954   descr.yDest     = height - startscan - lines;
4955   descr.width     = bmp->bitmap.bmWidth;
4956   descr.height    = lines;
4957   descr.useShm    = FALSE;
4958   descr.dibpitch  = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
4959   X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
4960   result = X11DRV_DIB_SetImageBits( &descr );
4961   X11DRV_DIB_Unlock(bmp, TRUE);
4962
4963   if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
4964
4965   GDI_ReleaseObj( hbitmap );
4966   return result;
4967 }
4968
4969 /***********************************************************************
4970  *           GetDIBits   (X11DRV.@)
4971  */
4972 INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, UINT lines,
4973                       LPVOID bits, BITMAPINFO *info, UINT coloruse )
4974 {
4975   X11DRV_DIBSECTION *dib;
4976   X11DRV_DIB_IMAGEBITS_DESCR descr;
4977   PALETTEOBJ * palette;
4978   BITMAPOBJ *bmp;
4979   int height;
4980   DC *dc = physDev->dc;
4981
4982   if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
4983       return 0;
4984   if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
4985   {
4986       GDI_ReleaseObj( dc->hPalette );
4987       return 0;
4988   }
4989   dib = (X11DRV_DIBSECTION *) bmp->dib;
4990
4991   TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
4992         lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
4993         (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
4994         startscan );
4995
4996   if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
4997
4998   height = info->bmiHeader.biHeight;
4999   if (height < 0) height = -height;
5000   if( lines > height ) lines = height;
5001   /* Top-down images have a negative biHeight, the scanlines of theses images
5002    * were inverted in X11DRV_DIB_GetImageBits_xx
5003    * To prevent this we simply change the sign of lines
5004    * (the number of scan lines to copy).
5005    * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
5006    */
5007   if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
5008
5009   if( startscan >= bmp->bitmap.bmHeight )
5010   {
5011       lines = 0;
5012       goto done;
5013   }
5014
5015   if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
5016                         &descr.infoBpp, &descr.compression ) == -1)
5017   {
5018       lines = 0;
5019       goto done;
5020   }
5021
5022   switch (descr.infoBpp)
5023   {
5024       case 1:
5025       case 4:
5026       case 8:
5027           descr.rMask= descr.gMask = descr.bMask = 0;
5028           break;
5029       case 15:
5030       case 16:
5031           descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
5032           descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0x03e0;
5033           descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0x001f;
5034           break;
5035       case 24:
5036       case 32:
5037           descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
5038           descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0x00ff00;
5039           descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0x0000ff;
5040           break;
5041   }
5042
5043   descr.physDev   = physDev;
5044   descr.palentry  = palette->logpalette.palPalEntry;
5045   descr.bits      = bits;
5046   descr.image     = NULL;
5047   descr.lines     = lines;
5048   descr.depth     = bmp->bitmap.bmBitsPixel;
5049   descr.drawable  = (Pixmap)bmp->physBitmap;
5050   descr.gc        = BITMAP_GC(bmp);
5051   descr.width     = bmp->bitmap.bmWidth;
5052   descr.height    = bmp->bitmap.bmHeight;
5053   descr.colorMap  = info->bmiColors;
5054   descr.xDest     = 0;
5055   descr.yDest     = 0;
5056   descr.xSrc      = 0;
5057
5058   if (descr.lines > 0)
5059   {
5060      descr.ySrc = (descr.height-1) - (startscan + (lines-1));
5061   }
5062   else
5063   {
5064      descr.ySrc = startscan;
5065   }
5066 #ifdef HAVE_LIBXXSHM
5067   descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
5068 #else
5069   descr.useShm = FALSE;
5070 #endif
5071   descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
5072                        : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
5073
5074   X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
5075   X11DRV_DIB_GetImageBits( &descr );
5076   X11DRV_DIB_Unlock(bmp, TRUE);
5077
5078   if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
5079       info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
5080                                          info->bmiHeader.biWidth,
5081                                          info->bmiHeader.biHeight,
5082                                          info->bmiHeader.biBitCount );
5083
5084   if (descr.compression == BI_BITFIELDS)
5085   {
5086     *(DWORD *)info->bmiColors = descr.rMask;
5087     *((DWORD *)info->bmiColors+1) = descr.gMask;
5088     *((DWORD *)info->bmiColors+2) = descr.bMask;
5089   }
5090   else
5091   {
5092     /* if RLE or JPEG compression were supported,
5093      * this line would be invalid. */
5094     info->bmiHeader.biCompression = 0;
5095   }
5096
5097 done:
5098   GDI_ReleaseObj( dc->hPalette );
5099   GDI_ReleaseObj( hbitmap );
5100   return lines;
5101 }
5102
5103 /***********************************************************************
5104  *           DIB_DoProtectDIBSection
5105  */
5106 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
5107 {
5108     DIBSECTION *dib = bmp->dib;
5109     INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
5110                                              : -dib->dsBm.bmHeight;
5111     /* use the biSizeImage data as the memory size only if we're dealing with a
5112        compressed image where the value is set.  Otherwise, calculate based on
5113        width * height */
5114     INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
5115                          ? dib->dsBmih.biSizeImage
5116                          : dib->dsBm.bmWidthBytes * effHeight;
5117     DWORD old_prot;
5118
5119     VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
5120     TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
5121 }
5122
5123 /***********************************************************************
5124  *           X11DRV_DIB_DoUpdateDIBSection
5125  */
5126 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
5127                                         void *colorMap, int nColorMap,
5128                                         Drawable dest,
5129                                         DWORD xSrc, DWORD ySrc,
5130                                         DWORD xDest, DWORD yDest,
5131                                         DWORD width, DWORD height)
5132 {
5133   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5134   X11DRV_DIB_IMAGEBITS_DESCR descr;
5135
5136   if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
5137                          &descr.infoBpp, &descr.compression ) == -1)
5138     return;
5139
5140   descr.physDev   = NULL;
5141   descr.palentry  = NULL;
5142   descr.image     = dib->image;
5143   descr.colorMap  = colorMap;
5144   descr.nColorMap = nColorMap;
5145   descr.bits      = dib->dibSection.dsBm.bmBits;
5146   descr.depth     = bmp->bitmap.bmBitsPixel;
5147
5148   switch (descr.infoBpp)
5149   {
5150     case 1:
5151     case 4:
5152     case 8:
5153       descr.rMask = descr.gMask = descr.bMask = 0;
5154       break;
5155     case 15:
5156     case 16:
5157       descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
5158       descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
5159       descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
5160       break;
5161
5162     case 24:
5163     case 32:
5164       descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff0000;
5165       descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x00ff00;
5166       descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x0000ff;
5167       break;
5168   }
5169
5170   /* Hack for now */
5171   descr.drawable  = dest;
5172   descr.gc        = BITMAP_GC(bmp);
5173   descr.xSrc      = xSrc;
5174   descr.ySrc      = ySrc;
5175   descr.xDest     = xDest;
5176   descr.yDest     = yDest;
5177   descr.width     = width;
5178   descr.height    = height;
5179 #ifdef HAVE_LIBXXSHM
5180   descr.useShm = (dib->shminfo.shmid != -1);
5181 #else
5182   descr.useShm = FALSE;
5183 #endif
5184   descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
5185
5186   if (toDIB)
5187     {
5188       TRACE("Copying from Pixmap to DIB bits\n");
5189       X11DRV_DIB_GetImageBits( &descr );
5190     }
5191   else
5192     {
5193       TRACE("Copying from DIB bits to Pixmap\n");
5194       X11DRV_DIB_SetImageBits( &descr );
5195     }
5196 }
5197
5198 /***********************************************************************
5199  *           X11DRV_DIB_CopyDIBSection
5200  */
5201 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
5202                                DWORD xSrc, DWORD ySrc, DWORD xDest, DWORD yDest,
5203                                DWORD width, DWORD height)
5204 {
5205   BITMAPOBJ *bmp;
5206   DC *dcSrc = physDevSrc->dc;
5207   DC *dcDst = physDevDst->dc;
5208   int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
5209
5210   TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst,
5211     xSrc, ySrc, xDest, yDest, width, height);
5212   /* this function is meant as an optimization for BitBlt,
5213    * not to be called otherwise */
5214   if (GetObjectType( physDevSrc->hdc ) != OBJ_MEMDC) {
5215     ERR("called for non-memory source DC!?\n");
5216     return;
5217   }
5218
5219   bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC );
5220   if (!(bmp && bmp->dib)) {
5221     ERR("called for non-DIBSection!?\n");
5222     GDI_ReleaseObj( dcSrc->hBitmap );
5223     return;
5224   }
5225   /* while BitBlt should already have made sure we only get
5226    * positive values, we should check for oversize values */
5227   if ((xSrc < bmp->bitmap.bmWidth) &&
5228       (ySrc < bmp->bitmap.bmHeight)) {
5229     if (xSrc + width > bmp->bitmap.bmWidth)
5230       width = bmp->bitmap.bmWidth - xSrc;
5231     if (ySrc + height > bmp->bitmap.bmHeight)
5232       height = bmp->bitmap.bmHeight - ySrc;
5233     /* if the source bitmap is 8bpp or less, we're supposed to use the
5234      * DC's palette for color conversion (not the DIB color table) */
5235     if (bmp->dib->dsBm.bmBitsPixel <= 8) {
5236       X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5237       if ((!dcSrc->hPalette) ||
5238           (dcSrc->hPalette == GetStockObject(DEFAULT_PALETTE))) {
5239         /* HACK: no palette has been set in the source DC,
5240          * use the DIB colormap instead - this is necessary in some
5241          * cases since we need to do depth conversion in some places
5242          * where real Windows can just copy data straight over */
5243         colorMap = dib->colorMap;
5244         nColorMap = dib->nColorMap;
5245       } else {
5246         colorMap = X11DRV_DIB_BuildColorMap( physDevSrc, (WORD)-1,
5247                                              bmp->dib->dsBm.bmBitsPixel,
5248                                              (BITMAPINFO*)&(bmp->dib->dsBmih),
5249                                              &nColorMap );
5250         if (colorMap) aColorMap = TRUE;
5251       }
5252     }
5253     /* perform the copy */
5254     X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
5255                                 physDevDst->drawable, xSrc, ySrc,
5256                                 physDevDst->org.x + xDest, physDevDst->org.y + yDest,
5257                                 width, height);
5258     /* free color mapping */
5259     if (aColorMap)
5260       HeapFree(GetProcessHeap(), 0, colorMap);
5261   }
5262   GDI_ReleaseObj( dcSrc->hBitmap );
5263 }
5264
5265 /***********************************************************************
5266  *           X11DRV_DIB_DoUpdateDIBSection
5267  */
5268 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
5269 {
5270   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5271   X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
5272                               (Drawable)bmp->physBitmap, 0, 0, 0, 0,
5273                               bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
5274 }
5275
5276 /***********************************************************************
5277  *           X11DRV_DIB_FaultHandler
5278  */
5279 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
5280 {
5281   BITMAPOBJ *bmp;
5282   INT state;
5283
5284   bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
5285   if (!bmp) return FALSE;
5286
5287   state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
5288   if (state != DIB_Status_InSync) {
5289     /* no way to tell whether app needs read or write yet,
5290      * try read first */
5291     X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
5292   } else {
5293     /* hm, apparently the app must have write access */
5294     X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
5295   }
5296   X11DRV_DIB_Unlock(bmp, TRUE);
5297
5298   GDI_ReleaseObj( (HBITMAP)res );
5299   return TRUE;
5300 }
5301
5302 /***********************************************************************
5303  *           X11DRV_DIB_Coerce
5304  */
5305 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
5306 {
5307   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5308   INT ret = DIB_Status_None;
5309
5310   if (dib) {
5311     EnterCriticalSection(&(dib->lock));
5312     ret = dib->status;
5313     switch (req) {
5314     case DIB_Status_GdiMod:
5315       /* GDI access - request to draw on pixmap */
5316       switch (dib->status)
5317       {
5318         default:
5319         case DIB_Status_None:
5320           dib->p_status = DIB_Status_GdiMod;
5321           X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
5322           break;
5323
5324         case DIB_Status_GdiMod:
5325           TRACE("GdiMod requested in status GdiMod\n" );
5326           break;
5327
5328         case DIB_Status_InSync:
5329           TRACE("GdiMod requested in status InSync\n" );
5330           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5331           dib->status = DIB_Status_GdiMod;
5332           dib->p_status = DIB_Status_InSync;
5333           break;
5334
5335         case DIB_Status_AuxMod:
5336           TRACE("GdiMod requested in status AuxMod\n" );
5337           if (lossy) dib->status = DIB_Status_GdiMod;
5338           else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
5339           dib->p_status = DIB_Status_AuxMod;
5340           if (dib->status != DIB_Status_AppMod) {
5341             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5342             break;
5343           }
5344           /* fall through if copy_aux() had to change to AppMod state */
5345
5346         case DIB_Status_AppMod:
5347           TRACE("GdiMod requested in status AppMod\n" );
5348           if (!lossy) {
5349             /* make it readonly to avoid app changing data while we copy */
5350             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5351             X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
5352           }
5353           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5354           dib->p_status = DIB_Status_AppMod;
5355           dib->status = DIB_Status_GdiMod;
5356           break;
5357       }
5358       break;
5359
5360     case DIB_Status_InSync:
5361       /* App access - request access to read DIB surface */
5362       /* (typically called from signal handler) */
5363       switch (dib->status)
5364       {
5365         default:
5366         case DIB_Status_None:
5367           /* shouldn't happen from signal handler */
5368           break;
5369
5370         case DIB_Status_AuxMod:
5371           TRACE("InSync requested in status AuxMod\n" );
5372           if (lossy) dib->status = DIB_Status_InSync;
5373           else {
5374             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5375             (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
5376           }
5377           if (dib->status != DIB_Status_GdiMod) {
5378             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5379             break;
5380           }
5381           /* fall through if copy_aux() had to change to GdiMod state */
5382
5383         case DIB_Status_GdiMod:
5384           TRACE("InSync requested in status GdiMod\n" );
5385           if (!lossy) {
5386             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5387             X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5388           }
5389           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5390           dib->status = DIB_Status_InSync;
5391           break;
5392
5393         case DIB_Status_InSync:
5394           TRACE("InSync requested in status InSync\n" );
5395           /* shouldn't happen from signal handler */
5396           break;
5397
5398         case DIB_Status_AppMod:
5399           TRACE("InSync requested in status AppMod\n" );
5400           /* no reason to do anything here, and this
5401            * shouldn't happen from signal handler */
5402           break;
5403       }
5404       break;
5405
5406     case DIB_Status_AppMod:
5407       /* App access - request access to write DIB surface */
5408       /* (typically called from signal handler) */
5409       switch (dib->status)
5410       {
5411         default:
5412         case DIB_Status_None:
5413           /* shouldn't happen from signal handler */
5414           break;
5415
5416         case DIB_Status_AuxMod:
5417           TRACE("AppMod requested in status AuxMod\n" );
5418           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5419           if (lossy) dib->status = DIB_Status_AppMod;
5420           else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
5421           if (dib->status != DIB_Status_GdiMod)
5422             break;
5423           /* fall through if copy_aux() had to change to GdiMod state */
5424
5425         case DIB_Status_GdiMod:
5426           TRACE("AppMod requested in status GdiMod\n" );
5427           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5428           if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5429           dib->status = DIB_Status_AppMod;
5430           break;
5431
5432         case DIB_Status_InSync:
5433           TRACE("AppMod requested in status InSync\n" );
5434           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5435           dib->status = DIB_Status_AppMod;
5436           break;
5437
5438         case DIB_Status_AppMod:
5439           TRACE("AppMod requested in status AppMod\n" );
5440           /* shouldn't happen from signal handler */
5441           break;
5442       }
5443       break;
5444
5445     case DIB_Status_AuxMod:
5446       if (dib->status == DIB_Status_None) {
5447         dib->p_status = req;
5448       } else {
5449         if (dib->status != DIB_Status_AuxMod)
5450           dib->p_status = dib->status;
5451         dib->status = DIB_Status_AuxMod;
5452       }
5453       break;
5454       /* it is up to the caller to do the copy/conversion, probably
5455        * using the return value to decide where to copy from */
5456     }
5457     LeaveCriticalSection(&(dib->lock));
5458   }
5459   return ret;
5460 }
5461
5462 /***********************************************************************
5463  *           X11DRV_DIB_Lock
5464  */
5465 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
5466 {
5467   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5468   INT ret = DIB_Status_None;
5469
5470   if (dib) {
5471     TRACE("Locking %p from thread %04lx\n", bmp, GetCurrentThreadId());
5472     EnterCriticalSection(&(dib->lock));
5473     ret = dib->status;
5474     if (req != DIB_Status_None)
5475       X11DRV_DIB_Coerce(bmp, req, lossy);
5476   }
5477   return ret;
5478 }
5479
5480 /***********************************************************************
5481  *           X11DRV_DIB_Unlock
5482  */
5483 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
5484 {
5485   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5486
5487   if (dib) {
5488     switch (dib->status)
5489     {
5490       default:
5491       case DIB_Status_None:
5492         /* in case anyone is wondering, this is the "signal handler doesn't
5493          * work" case, where we always have to be ready for app access */
5494         if (commit) {
5495           switch (dib->p_status)
5496           {
5497             case DIB_Status_AuxMod:
5498               TRACE("Unlocking and syncing from AuxMod\n" );
5499               (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
5500               if (dib->status != DIB_Status_None) {
5501                 dib->p_status = dib->status;
5502                 dib->status = DIB_Status_None;
5503               }
5504               if (dib->p_status != DIB_Status_GdiMod)
5505                 break;
5506               /* fall through if copy_aux() had to change to GdiMod state */
5507
5508             case DIB_Status_GdiMod:
5509               TRACE("Unlocking and syncing from GdiMod\n" );
5510               X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5511               break;
5512
5513             default:
5514               TRACE("Unlocking without needing to sync\n" );
5515               break;
5516           }
5517         }
5518         else TRACE("Unlocking with no changes\n");
5519         dib->p_status = DIB_Status_None;
5520         break;
5521
5522       case DIB_Status_GdiMod:
5523         TRACE("Unlocking in status GdiMod\n" );
5524         /* DIB was protected in Coerce */
5525         if (!commit) {
5526           /* no commit, revert to InSync if applicable */
5527           if ((dib->p_status == DIB_Status_InSync) ||
5528               (dib->p_status == DIB_Status_AppMod)) {
5529             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5530             dib->status = DIB_Status_InSync;
5531           }
5532         }
5533         break;
5534
5535       case DIB_Status_InSync:
5536         TRACE("Unlocking in status InSync\n" );
5537         /* DIB was already protected in Coerce */
5538         break;
5539
5540       case DIB_Status_AppMod:
5541         TRACE("Unlocking in status AppMod\n" );
5542         /* DIB was already protected in Coerce */
5543         /* this case is ordinary only called from the signal handler,
5544          * so we don't bother to check for !commit */
5545         break;
5546
5547       case DIB_Status_AuxMod:
5548         TRACE("Unlocking in status AuxMod\n" );
5549         if (commit) {
5550           /* DIB may need protection now */
5551           if ((dib->p_status == DIB_Status_InSync) ||
5552               (dib->p_status == DIB_Status_AppMod))
5553             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5554         } else {
5555           /* no commit, revert to previous state */
5556           if (dib->p_status != DIB_Status_None)
5557             dib->status = dib->p_status;
5558           /* no protections changed */
5559         }
5560         dib->p_status = DIB_Status_None;
5561         break;
5562     }
5563     LeaveCriticalSection(&(dib->lock));
5564     TRACE("Unlocked %p\n", bmp);
5565   }
5566 }
5567
5568 /***********************************************************************
5569  *           X11DRV_CoerceDIBSection2
5570  */
5571 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
5572 {
5573   BITMAPOBJ *bmp;
5574   INT ret;
5575
5576   bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5577   if (!bmp) return DIB_Status_None;
5578   ret = X11DRV_DIB_Coerce(bmp, req, lossy);
5579   GDI_ReleaseObj( hBmp );
5580   return ret;
5581 }
5582
5583 /***********************************************************************
5584  *           X11DRV_LockDIBSection2
5585  */
5586 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
5587 {
5588   BITMAPOBJ *bmp;
5589   INT ret;
5590
5591   bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5592   if (!bmp) return DIB_Status_None;
5593   ret = X11DRV_DIB_Lock(bmp, req, lossy);
5594   GDI_ReleaseObj( hBmp );
5595   return ret;
5596 }
5597
5598 /***********************************************************************
5599  *           X11DRV_UnlockDIBSection2
5600  */
5601 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
5602 {
5603   BITMAPOBJ *bmp;
5604
5605   bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5606   if (!bmp) return;
5607   X11DRV_DIB_Unlock(bmp, commit);
5608   GDI_ReleaseObj( hBmp );
5609 }
5610
5611 /***********************************************************************
5612  *           X11DRV_CoerceDIBSection
5613  */
5614 INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
5615 {
5616   if (!physDev) return DIB_Status_None;
5617   return X11DRV_CoerceDIBSection2( physDev->dc->hBitmap, req, lossy );
5618 }
5619
5620 /***********************************************************************
5621  *           X11DRV_LockDIBSection
5622  */
5623 INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
5624 {
5625   if (!physDev) return DIB_Status_None;
5626   if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return DIB_Status_None;
5627
5628   return X11DRV_LockDIBSection2( physDev->dc->hBitmap, req, lossy );
5629 }
5630
5631 /***********************************************************************
5632  *           X11DRV_UnlockDIBSection
5633  */
5634 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev, BOOL commit)
5635 {
5636   if (!physDev) return;
5637   if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return;
5638
5639   X11DRV_UnlockDIBSection2( physDev->dc->hBitmap, commit );
5640 }
5641
5642
5643 #ifdef HAVE_LIBXXSHM
5644 /***********************************************************************
5645  *           X11DRV_XShmErrorHandler
5646  *
5647  */
5648 static int XShmErrorHandler( Display *dpy, XErrorEvent *event, void *arg )
5649 {
5650     return 1;  /* FIXME: should check event contents */
5651 }
5652
5653 /***********************************************************************
5654  *           X11DRV_XShmCreateImage
5655  *
5656  */
5657 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
5658                                        XShmSegmentInfo* shminfo)
5659 {
5660     XImage *image;
5661
5662     image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
5663     if (image)
5664     {
5665         shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
5666                                   IPC_CREAT|0700);
5667         if( shminfo->shmid != -1 )
5668         {
5669             shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
5670             if( shminfo->shmaddr != (char*)-1 )
5671             {
5672                 BOOL ok;
5673
5674                 shminfo->readOnly = FALSE;
5675                 X11DRV_expect_error( gdi_display, XShmErrorHandler, NULL );
5676                 ok = (XShmAttach( gdi_display, shminfo ) != 0);
5677                 if (X11DRV_check_error()) ok = FALSE;
5678                 if (ok)
5679                 {
5680                     shmctl(shminfo->shmid, IPC_RMID, 0);
5681                     return image; /* Success! */
5682                 }
5683                 /* An error occurred */
5684                 shmdt(shminfo->shmaddr);
5685             }
5686             shmctl(shminfo->shmid, IPC_RMID, 0);
5687         }
5688         XFlush(gdi_display);
5689         XDestroyImage(image);
5690         image = NULL;
5691     }
5692     return image;
5693 }
5694 #endif /* HAVE_LIBXXSHM */
5695
5696
5697 /***********************************************************************
5698  *           X11DRV_DIB_CreateDIBSection
5699  */
5700 HBITMAP X11DRV_DIB_CreateDIBSection(
5701   X11DRV_PDEVICE *physDev, BITMAPINFO *bmi, UINT usage,
5702   LPVOID *bits, HANDLE section,
5703   DWORD offset, DWORD ovr_pitch)
5704 {
5705   HBITMAP res = 0;
5706   BITMAPOBJ *bmp = NULL;
5707   X11DRV_DIBSECTION *dib = NULL;
5708   int *colorMap = NULL;
5709   int nColorMap;
5710
5711   /* Fill BITMAP32 structure with DIB data */
5712   BITMAPINFOHEADER *bi = &bmi->bmiHeader;
5713   INT effHeight, totalSize;
5714   BITMAP bm;
5715   LPVOID mapBits = NULL;
5716
5717   TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
5718         bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
5719         bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
5720
5721   effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
5722   bm.bmType = 0;
5723   bm.bmWidth = bi->biWidth;
5724   bm.bmHeight = effHeight;
5725   bm.bmWidthBytes = ovr_pitch ? ovr_pitch
5726                               : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
5727   bm.bmPlanes = bi->biPlanes;
5728   bm.bmBitsPixel = bi->biBitCount;
5729   bm.bmBits = NULL;
5730
5731   /* Get storage location for DIB bits.  Only use biSizeImage if it's valid and
5732      we're dealing with a compressed bitmap.  Otherwise, use width * height. */
5733   totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
5734     ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
5735
5736   if (section)
5737   {
5738       SYSTEM_INFO SystemInfo;
5739       DWORD mapOffset;
5740       INT mapSize;
5741
5742       GetSystemInfo( &SystemInfo );
5743       mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
5744       mapSize = totalSize + (offset - mapOffset);
5745       mapBits = MapViewOfFile( section,
5746                                FILE_MAP_ALL_ACCESS,
5747                                0L,
5748                                mapOffset,
5749                                mapSize );
5750       bm.bmBits = (char *)mapBits + (offset - mapOffset);
5751   }
5752   else if (ovr_pitch && offset)
5753     bm.bmBits = (LPVOID) offset;
5754   else {
5755     offset = 0;
5756     bm.bmBits = VirtualAlloc(NULL, totalSize,
5757                              MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
5758   }
5759
5760   /* Create Color Map */
5761   if (bm.bmBits && bm.bmBitsPixel <= 8)
5762       colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? physDev : NULL,
5763                                            usage, bm.bmBitsPixel, bmi, &nColorMap );
5764
5765   /* Allocate Memory for DIB and fill structure */
5766   if (bm.bmBits)
5767     dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
5768   if (dib)
5769     {
5770       dib->dibSection.dsBm = bm;
5771       dib->dibSection.dsBmih = *bi;
5772       dib->dibSection.dsBmih.biSizeImage = totalSize;
5773
5774       /* Set dsBitfields values */
5775        if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
5776        {
5777            dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
5778        }
5779        else switch( bi->biBitCount )
5780        {
5781            case 15:
5782            case 16:
5783                dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
5784                dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
5785                dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
5786                break;
5787
5788            case 24:
5789            case 32:
5790                dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors       : 0xff0000;
5791                dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x00ff00;
5792                dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x0000ff;
5793                break;
5794        }
5795       dib->dibSection.dshSection = section;
5796       dib->dibSection.dsOffset = offset;
5797
5798       dib->status    = DIB_Status_None;
5799       dib->nColorMap = nColorMap;
5800       dib->colorMap  = colorMap;
5801     }
5802
5803   /* Create Device Dependent Bitmap and add DIB pointer */
5804   if (dib)
5805     {
5806       res = CreateDIBitmap(physDev->hdc, bi, 0, NULL, bmi, usage);
5807       if (res)
5808         {
5809           bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
5810           if (bmp) bmp->dib = (DIBSECTION *) dib;
5811         }
5812     }
5813
5814   /* Create XImage */
5815   if (dib && bmp)
5816   {
5817       wine_tsx11_lock();
5818 #ifdef HAVE_LIBXXSHM
5819       if (XShmQueryExtension(gdi_display) &&
5820           (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
5821                                                 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
5822       {
5823         ; /* Created Image */
5824       } else {
5825           dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
5826           dib->shminfo.shmid = -1;
5827       }
5828 #else
5829       dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
5830 #endif
5831       wine_tsx11_unlock();
5832   }
5833
5834   /* Clean up in case of errors */
5835   if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
5836     {
5837       TRACE("got an error res=%p, bmp=%p, dib=%p, bm.bmBits=%p\n",
5838             res, bmp, dib, bm.bmBits);
5839       if (bm.bmBits)
5840         {
5841           if (section)
5842             UnmapViewOfFile(mapBits), bm.bmBits = NULL;
5843           else if (!offset)
5844             VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
5845         }
5846
5847       if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
5848       if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
5849       if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
5850       if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
5851       if (res) { DeleteObject(res); res = 0; }
5852     }
5853   else if (bm.bmBits)
5854     {
5855       /* Install fault handler, if possible */
5856       InitializeCriticalSection(&(dib->lock));
5857       if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
5858         {
5859           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5860           if (dib) dib->status = DIB_Status_AppMod;
5861         }
5862     }
5863
5864   /* Return BITMAP handle and storage location */
5865   if (bmp) GDI_ReleaseObj(res);
5866   if (bm.bmBits && bits) *bits = bm.bmBits;
5867   return res;
5868 }
5869
5870 /***********************************************************************
5871  *           X11DRV_DIB_DeleteDIBSection
5872  */
5873 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
5874 {
5875   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5876
5877   if (dib->image)
5878   {
5879       wine_tsx11_lock();
5880 #ifdef HAVE_LIBXXSHM
5881       if (dib->shminfo.shmid != -1)
5882       {
5883           XShmDetach (gdi_display, &(dib->shminfo));
5884           XDestroyImage (dib->image);
5885           shmdt (dib->shminfo.shmaddr);
5886           dib->shminfo.shmid = -1;
5887       }
5888       else
5889 #endif
5890           XDestroyImage( dib->image );
5891       wine_tsx11_unlock();
5892   }
5893
5894   if (dib->colorMap)
5895     HeapFree(GetProcessHeap(), 0, dib->colorMap);
5896
5897   DeleteCriticalSection(&(dib->lock));
5898 }
5899
5900 /***********************************************************************
5901  *           SetDIBColorTable   (X11DRV.@)
5902  */
5903 UINT X11DRV_SetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, const RGBQUAD *colors )
5904 {
5905     BITMAPOBJ * bmp;
5906     X11DRV_DIBSECTION *dib;
5907     UINT ret = 0;
5908
5909     if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( physDev->dc->hBitmap, BITMAP_MAGIC ))) return 0;
5910     dib = (X11DRV_DIBSECTION *) bmp->dib;
5911
5912     if (dib && dib->colorMap) {
5913         UINT end = count + start;
5914         if (end > dib->nColorMap) end = dib->nColorMap;
5915         /*
5916          * Changing color table might change the mapping between
5917          * DIB colors and X11 colors and thus alter the visible state
5918          * of the bitmap object.
5919          */
5920         X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
5921         X11DRV_DIB_GenColorMap( physDev, dib->colorMap, DIB_RGB_COLORS,
5922                                 dib->dibSection.dsBm.bmBitsPixel,
5923                                 TRUE, colors, start, end );
5924         X11DRV_DIB_Unlock(bmp, TRUE);
5925         ret = end - start;
5926     }
5927     GDI_ReleaseObj( physDev->dc->hBitmap );
5928     return ret;
5929 }
5930
5931 /***********************************************************************
5932  *           GetDIBColorTable   (X11DRV.@)
5933  */
5934 UINT X11DRV_GetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, RGBQUAD *colors )
5935 {
5936     BITMAPOBJ * bmp;
5937     X11DRV_DIBSECTION *dib;
5938     UINT ret = 0;
5939
5940     if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( physDev->dc->hBitmap, BITMAP_MAGIC ))) return 0;
5941     dib = (X11DRV_DIBSECTION *) bmp->dib;
5942
5943     if (dib && dib->colorMap) {
5944         UINT i, end = count + start;
5945         if (end > dib->nColorMap) end = dib->nColorMap;
5946         for (i = start; i < end; i++,colors++) {
5947             COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
5948             colors->rgbBlue  = GetBValue(col);
5949             colors->rgbGreen = GetGValue(col);
5950             colors->rgbRed   = GetRValue(col);
5951             colors->rgbReserved = 0;
5952         }
5953         ret = end-start;
5954     }
5955     GDI_ReleaseObj( physDev->dc->hBitmap );
5956     return ret;
5957 }
5958
5959
5960 /**************************************************************************
5961  *              X11DRV_DIB_CreateDIBFromPixmap
5962  *
5963  *  Allocates a packed DIB and copies the Pixmap data into it.
5964  *  If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
5965  */
5966 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
5967 {
5968     HBITMAP hBmp = 0;
5969     BITMAPOBJ *pBmp = NULL;
5970     HGLOBAL hPackedDIB = 0;
5971
5972     /* Allocates an HBITMAP which references the Pixmap passed to us */
5973     hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
5974     if (!hBmp)
5975     {
5976         TRACE("\tCould not create bitmap header for Pixmap\n");
5977         goto END;
5978     }
5979
5980     /*
5981      * Create a packed DIB from the Pixmap wrapper bitmap created above.
5982      * A packed DIB contains a BITMAPINFO structure followed immediately by
5983      * an optional color palette and the pixel data.
5984      */
5985     hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
5986
5987     /* Get a pointer to the BITMAPOBJ structure */
5988     pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5989
5990     /* We can now get rid of the HBITMAP wrapper we created earlier.
5991      * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
5992      */
5993     if (!bDeletePixmap)
5994     {
5995         /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
5996         pBmp->physBitmap = NULL;
5997         pBmp->funcs = NULL;
5998     }
5999     GDI_ReleaseObj( hBmp );
6000     DeleteObject(hBmp);
6001
6002 END:
6003     TRACE("\tReturning packed DIB %p\n", hPackedDIB);
6004     return hPackedDIB;
6005 }
6006
6007
6008 /**************************************************************************
6009  *                 X11DRV_DIB_CreatePixmapFromDIB
6010  *
6011  *    Creates a Pixmap from a packed DIB
6012  */
6013 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
6014 {
6015     Pixmap pixmap = None;
6016     HBITMAP hBmp = 0;
6017     BITMAPOBJ *pBmp = NULL;
6018     LPBYTE pPackedDIB = NULL;
6019     LPBITMAPINFO pbmi = NULL;
6020     LPBITMAPINFOHEADER pbmiHeader = NULL;
6021     LPBYTE pbits = NULL;
6022
6023     /* Get a pointer to the packed DIB's data  */
6024     pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
6025     pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
6026     pbmi = (LPBITMAPINFO)pPackedDIB;
6027     pbits = (LPBYTE)(pPackedDIB
6028                      + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
6029
6030     /* Create a DDB from the DIB */
6031
6032     hBmp = CreateDIBitmap(hdc,
6033                           pbmiHeader,
6034                           CBM_INIT,
6035                           (LPVOID)pbits,
6036                           pbmi,
6037                           DIB_RGB_COLORS);
6038
6039     GlobalUnlock(hPackedDIB);
6040
6041     TRACE("CreateDIBitmap returned %p\n", hBmp);
6042
6043     /* Retrieve the internal Pixmap from the DDB */
6044
6045     pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
6046
6047     pixmap = (Pixmap)pBmp->physBitmap;
6048     /* clear the physBitmap so that we can steal its pixmap */
6049     pBmp->physBitmap = NULL;
6050     pBmp->funcs = NULL;
6051
6052     /* Delete the DDB we created earlier now that we have stolen its pixmap */
6053     GDI_ReleaseObj( hBmp );
6054     DeleteObject(hBmp);
6055
6056     TRACE("\tReturning Pixmap %ld\n", pixmap);
6057     return pixmap;
6058 }