Ignore RLE data that goes past the line end (found by Uwe Bonnes).
[wine] / graphics / x11drv / dib.c
1 /*
2  * X11DRV device-independent bitmaps
3  *
4  * Copyright 1993,1994  Alexandre Julliard
5  */
6
7 #include "config.h"
8
9 #include "ts_xlib.h"
10 #include "ts_xutil.h"
11 #ifdef HAVE_LIBXXSHM
12 # include "ts_xshm.h"
13 # ifdef HAVE_SYS_SHM_H
14 #  include <sys/shm.h>
15 # endif
16 # ifdef HAVE_SYS_IPC_H
17 #  include <sys/ipc.h>
18 # endif
19 #endif /* defined(HAVE_LIBXXSHM) */
20
21 #include <stdlib.h>
22 #include <string.h>
23 #include "windef.h"
24 #include "bitmap.h"
25 #include "x11drv.h"
26 #include "debugtools.h"
27 #include "gdi.h"
28 #include "palette.h"
29 #include "global.h"
30
31 DEFAULT_DEBUG_CHANNEL(bitmap);
32 DECLARE_DEBUG_CHANNEL(x11drv);
33
34 static int ximageDepthTable[32];
35
36 #ifdef HAVE_LIBXXSHM
37 static int XShmErrorFlag = 0;
38 #endif
39
40 /* This structure holds the arguments for DIB_SetImageBits() */
41 typedef struct
42 {
43     struct tagDC   *dc;
44     LPCVOID         bits;
45     XImage         *image;
46     PALETTEENTRY   *palentry;
47     int             lines;
48     DWORD           infoWidth;
49     WORD            depth;
50     WORD            infoBpp;
51     WORD            compression;
52     RGBQUAD        *colorMap;
53     int             nColorMap;
54     Drawable        drawable;
55     GC              gc;
56     int             xSrc;
57     int             ySrc;
58     int             xDest;
59     int             yDest;
60     int             width;
61     int             height;
62     DWORD           rMask;
63     DWORD           gMask;
64     DWORD           bMask;
65     BOOL            useShm;
66     int             dibpitch;
67 } X11DRV_DIB_IMAGEBITS_DESCR;
68
69
70 enum Rle_EscapeCodes
71 {
72   RLE_EOL   = 0, /* End of line */
73   RLE_END   = 1, /* End of bitmap */
74   RLE_DELTA = 2  /* Delta */
75 };
76
77 /***********************************************************************
78  *           X11DRV_DIB_GetXImageWidthBytes
79  *
80  * Return the width of an X image in bytes
81  */
82 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
83 {
84     if (!depth || depth > 32) goto error;
85
86     if (!ximageDepthTable[depth-1])
87     {
88         XImage *testimage = XCreateImage( gdi_display, visual, depth,
89                                           ZPixmap, 0, NULL, 1, 1, 32, 20 );
90         if (testimage)
91         {
92             ximageDepthTable[depth-1] = testimage->bits_per_pixel;
93             XDestroyImage( testimage );
94         }
95         else ximageDepthTable[depth-1] = -1;
96     }
97     if (ximageDepthTable[depth-1] != -1)
98         return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
99
100  error:
101     WARN( "(%d): Unsupported depth\n", depth );
102     return 4 * width;
103 }
104
105
106 /***********************************************************************
107  *           X11DRV_DIB_CreateXImage
108  *
109  * Create an X image.
110  */
111 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
112 {
113     int width_bytes;
114     XImage *image;
115
116     wine_tsx11_lock();
117     width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
118     image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
119                           calloc( height, width_bytes ),
120                           width, height, 32, width_bytes );
121     wine_tsx11_unlock();
122     return image;
123 }
124
125
126 /***********************************************************************
127  *           X11DRV_DIB_GenColorMap
128  *
129  * Fills the color map of a bitmap palette. Should not be called
130  * for a >8-bit deep bitmap.
131  */
132 int *X11DRV_DIB_GenColorMap( DC *dc, int *colorMapping,
133                              WORD coloruse, WORD depth, BOOL quads,
134                              const void *colorPtr, int start, int end )
135 {
136     int i;
137
138     if (coloruse == DIB_RGB_COLORS)
139     {
140         if (quads)
141         {
142             RGBQUAD * rgb = (RGBQUAD *)colorPtr;
143
144             if (depth == 1)  /* Monochrome */
145                 for (i = start; i < end; i++, rgb++)
146                     colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
147                                        rgb->rgbBlue > 255*3/2);
148             else
149                 for (i = start; i < end; i++, rgb++)
150                     colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbRed,
151                                                                 rgb->rgbGreen,
152                                                                 rgb->rgbBlue));
153         }
154         else
155         {
156             RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
157
158             if (depth == 1)  /* Monochrome */
159                 for (i = start; i < end; i++, rgb++)
160                     colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
161                                        rgb->rgbtBlue > 255*3/2);
162             else
163                 for (i = start; i < end; i++, rgb++)
164                     colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbtRed,
165                                                                rgb->rgbtGreen,
166                                                                rgb->rgbtBlue));
167         }
168     }
169     else  /* DIB_PAL_COLORS */
170     {
171         if (colorPtr) {
172             WORD * index = (WORD *)colorPtr;
173
174             for (i = start; i < end; i++, index++)
175                 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) );
176         } else {
177             for (i = start; i < end; i++)
178                 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(i) );
179         }
180     }
181
182     return colorMapping;
183 }
184
185 /***********************************************************************
186  *           X11DRV_DIB_BuildColorMap
187  *
188  * Build the color map from the bitmap palette. Should not be called
189  * for a >8-bit deep bitmap.
190  */
191 int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth, 
192                                const BITMAPINFO *info, int *nColors )
193 {
194     int colors;
195     BOOL isInfo;
196     const void *colorPtr;
197     int *colorMapping;
198
199     if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
200     {
201         colors = info->bmiHeader.biClrUsed;
202         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
203         colorPtr = info->bmiColors;
204     }
205     else  /* assume BITMAPCOREINFO */
206     {
207         colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
208         colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
209     }
210
211     if (colors > 256)
212     {
213         ERR("called with >256 colors!\n");
214         return NULL;
215     }
216
217     /* just so CopyDIBSection doesn't have to create an identity palette */
218     if (coloruse == (WORD)-1) colorPtr = NULL;
219
220     if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
221                                           colors * sizeof(int) ))) 
222         return NULL;
223
224     *nColors = colors;
225     return X11DRV_DIB_GenColorMap( dc, colorMapping, coloruse, depth,
226                                    isInfo, colorPtr, 0, colors);
227 }
228
229
230 /***********************************************************************
231  *           X11DRV_DIB_MapColor
232  */
233 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
234 {
235     int color;
236
237     if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
238         return oldcol;
239
240     for (color = 0; color < nPhysMap; color++)
241         if (physMap[color] == phys)
242             return color;
243
244     WARN("Strange color %08x\n", phys);
245     return 0;
246 }
247
248
249 /*********************************************************************
250  *         X11DRV_DIB_GetNearestIndex
251  *
252  * Helper for X11DRV_DIB_GetDIBits.
253  * Returns the nearest colour table index for a given RGB.
254  * Nearest is defined by minimizing the sum of the squares.
255  */
256 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
257 {
258     INT i, best = -1, diff, bestdiff = -1;
259     RGBQUAD *color;
260
261     for(color = colormap, i = 0; i < numColors; color++, i++) {
262         diff = (r - color->rgbRed) * (r - color->rgbRed) +
263                (g - color->rgbGreen) * (g - color->rgbGreen) +
264                (b - color->rgbBlue) * (b - color->rgbBlue);
265         if(diff == 0)
266             return i;
267         if(best == -1 || diff < bestdiff) {
268             best = i;
269             bestdiff = diff;
270         }
271     }
272     return best;
273 }
274
275 /***********************************************************************
276  *           X11DRV_DIB_SetImageBits_1_Line
277  *
278  * Handles a single line of 1 bit data.
279  */
280 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
281                                     XImage *bmpImage, int h, const BYTE *bits)
282 {
283     BYTE pix, extra;
284     DWORD i, x;
285
286     if((extra = (left & 7)) != 0) {
287         left &= ~7;
288         dstwidth += extra;
289     }
290
291     bits += left >> 3;
292
293     /* FIXME: should avoid putting x<left pixels (minor speed issue) */
294     for (i = dstwidth/8, x = left; i > 0; i--)
295     {
296         pix = *bits++;
297         XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
298         XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
299         XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
300         XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
301         XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
302         XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
303         XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
304         XPutPixel( bmpImage, x++, h, colors[pix & 1] );
305     }
306     pix = *bits;
307     switch(dstwidth & 7)
308     {
309     case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
310     case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
311     case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
312     case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
313     case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
314     case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
315     case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
316     }
317 }
318
319 /***********************************************************************
320  *           X11DRV_DIB_SetImageBits_1
321  *
322  * SetDIBits for a 1-bit deep DIB.
323  */
324 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
325                                 DWORD srcwidth, DWORD dstwidth, int left,
326                                 int *colors, XImage *bmpImage, DWORD linebytes)
327 {
328     int h;
329
330     if (lines > 0) {
331         for (h = lines-1; h >=0; h--) {
332             X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
333                                            srcbits);
334             srcbits += linebytes;
335         }
336     } else {
337         lines = -lines;
338         for (h = 0; h < lines; h++) {
339             X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
340                                            srcbits);
341             srcbits += linebytes;
342         }
343     }
344 }
345
346 /***********************************************************************
347  *           X11DRV_DIB_GetImageBits_1
348  *
349  * GetDIBits for a 1-bit deep DIB.
350  */
351 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
352                                        DWORD dstwidth, DWORD srcwidth,
353                                        RGBQUAD *colors, PALETTEENTRY *srccolors, 
354                                 XImage *bmpImage, DWORD linebytes )
355 {
356     DWORD x;
357     int h;
358     BYTE *bits;
359
360     if (lines < 0 ) {
361         lines = -lines;
362         dstbits = dstbits + linebytes * (lines - 1);
363         linebytes = -linebytes;
364     }
365
366     bits = dstbits;
367
368     switch(bmpImage->depth) {
369
370     case 1:
371        /* ==== monochrome bitmap to monochrome dib ==== */
372     case 4:
373        /* ==== 4 colormap bitmap to monochrome dib ==== */
374        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
375          { 
376            PALETTEENTRY val;
377
378            for (h = lines - 1; h >= 0; h--) {
379              for (x = 0; x < dstwidth; x++) {
380                val = srccolors[XGetPixel(bmpImage, x, h)];
381                if (!(x&7)) *bits = 0;
382                *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, 
383                                                     val.peRed,
384                                                     val.peGreen, 
385                                                     val.peBlue) << (7 - (x & 7)));
386                if ((x&7)==7) bits++;
387              }
388              bits = (dstbits += linebytes);
389            }
390          }
391        else goto notsupported;
392        
393        break;
394       
395     case 8:
396       /* ==== 8 colormap bitmap to monochrome dib ==== */
397       if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
398       {
399         BYTE *srcpixel;
400         PALETTEENTRY val;
401
402        for( h = lines- 1; h >= 0; h-- ) {
403           srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
404           for( x = 0; x < dstwidth; x++ ) {
405             if (!(x&7)) *bits = 0;
406             val = srccolors[(int)*srcpixel++];
407             *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 2,
408                                                   val.peRed,
409                                                   val.peGreen,
410                                                   val.peBlue) << (7-(x&7)) );
411             if ((x&7)==7) bits++;
412           }
413           bits = (dstbits += linebytes);
414         }
415       }
416       else goto notsupported;
417
418       break;
419       
420     case 15:
421       {
422         LPWORD srcpixel;
423         WORD val;
424         
425         /* ==== 555 BGR bitmap to monochrome dib ==== */
426         if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
427         {
428           for( h = lines - 1; h >= 0; h--) {
429                 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
430                 for( x = 0; x < dstwidth; x++) {
431                   if (!(x&7)) *bits = 0;
432                   val = *srcpixel++;
433                   *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2, 
434                                                         ((val >> 7) & 0xf8) |
435                                                         ((val >> 12) & 0x7),
436                                                         ((val >> 2) & 0xf8) |
437                                                         ((val >> 7) & 0x3),
438                                                         ((val << 3) & 0xf8) |
439                                                         ((val >> 2) & 0x7) ) << (7-(x&7)) );
440                   if ((x&7)==7) bits++;
441                 }
442                 bits = (dstbits += linebytes);
443             }
444         }
445         /* ==== 555 RGB bitmap to monochrome dib ==== */
446         else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
447         {
448             for( h = lines - 1; h >= 0; h--) 
449             {
450                 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
451                 for( x = 0; x < dstwidth; x++) {
452                   if (!(x&1)) *bits = 0;
453                   val = *srcpixel++;
454                   *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2, 
455                                                         ((val << 3) & 0xf8) |
456                                                         ((val >> 2) & 0x7),
457                                                         ((val >> 2) & 0xf8) |
458                                                         ((val >> 7) & 0x3),
459                                                         ((val >> 7) & 0xf8) |
460                                                         ((val >> 12) &  0x7) ) << (7-(x&7)) );
461                   if ((x&7)==7) bits++;
462                 }
463                 bits = (dstbits += linebytes);
464             }
465         }
466         else goto notsupported;
467       }
468       break;
469  
470     case 16:
471       {
472         LPWORD srcpixel;
473         WORD val;
474
475         /* ==== 565 BGR bitmap to monochrome dib ==== */
476         if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f) 
477         {
478             for( h = lines - 1; h >= 0; h--) 
479             {
480                 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
481                 for( x = 0; x < dstwidth; x++) {
482                   if (!(x&7)) *bits = 0;
483                   val = *srcpixel++;
484                   *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2, 
485                                                         ((val >> 8) & 0xf8) |
486                                                         ((val >> 13) & 0x7),
487                                                         ((val >> 3) & 0xfc) |
488                                                         ((val >> 9) & 0x3),
489                                                         ((val << 3) & 0xf8) |
490                                                         ((val >> 2) & 0x7) ) << (7-(x&7)) );
491                   if ((x&7)==7) bits++;
492                 }
493                 bits = (dstbits += linebytes);
494             }
495         }
496         /* ==== 565 RGB bitmap to monochrome dib ==== */
497         else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
498         {
499             for( h = lines - 1; h >= 0; h--) 
500             {
501                 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
502                 for( x = 0; x < dstwidth; x++) {
503                   if (!(x&7)) *bits = 0;
504                   val = *srcpixel++;
505                   *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2, 
506                                                         ((val << 3) & 0xf8) |
507                                                         ((val >> 2) & 0x7),
508                                                         ((val >> 3) & 0xfc) |
509                                                         ((val >> 9) & 0x3),
510                                                         ((val >> 8) & 0xf8) |
511                                                         ((val >> 13) &  0x7) ) << (7-(x&7)) );
512                   if ((x&7)==7) bits++;
513                 }
514                 bits = (dstbits += linebytes);
515             }
516         }
517         else goto notsupported;
518       }
519       break;
520       
521     case 24: 
522     case 32:
523       {
524         BYTE *srcpixel;
525         
526         /* ==== 24/32 BGR bitmap to monochrome dib ==== */
527         if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
528         {        
529           for (h = lines - 1; h >= 0; h--)
530           {
531             srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
532             for (x = 0; x < dstwidth; x++, srcpixel+=4) {
533               if (!(x&7)) *bits = 0;
534               *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[2] , srcpixel[1], srcpixel[0]) << (7-(x&7)) );
535               if ((x&7)==7) bits++;
536             }
537             bits = (dstbits += linebytes);
538           }
539         } 
540         /* ==== 24/32 RGB bitmap to monochrome dib ==== */
541         else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
542         {
543           for (h = lines - 1; h >= 0; h--)
544           {
545             srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
546             for (x = 0; x < dstwidth; x++, srcpixel+=4) { 
547                        if (!(x & 7)) *bits = 0;
548                        *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[0] , srcpixel[1], srcpixel[2]) << (7-(x&7)) );
549                        if ((x & 7) == 7) bits++;
550             }
551             bits = (dstbits += linebytes);
552           }
553         }
554         else goto notsupported;
555       }
556       break;
557
558     default: /* ? bit bmp -> monochrome DIB */
559     notsupported:
560       {
561         unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
562
563         FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
564               bmpImage->bits_per_pixel, (int)bmpImage->red_mask, 
565               (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
566       
567         for( h = lines - 1; h >= 0; h-- ) {
568           for( x = 0; x < dstwidth; x++ ) {
569             if (!(x&7)) *bits = 0;
570             *bits |= (XGetPixel( bmpImage, x, h) >= white) 
571               << (7 - (x&7));
572             if ((x&7)==7) bits++;
573           }
574           bits = (dstbits += linebytes);
575         }
576       }
577       break;
578     }
579 }
580
581 /***********************************************************************
582  *           X11DRV_DIB_SetImageBits_4
583  *
584  * SetDIBits for a 4-bit deep DIB.
585  */
586 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
587                                 DWORD srcwidth, DWORD dstwidth, int left,
588                                 int *colors, XImage *bmpImage, DWORD linebytes)
589 {
590     DWORD i, x;
591     int h;
592     const BYTE *bits = srcbits + (left >> 1);
593   
594     if(left & 1) {
595         left--;
596         dstwidth++;
597     }
598
599     if (lines > 0) {
600         for (h = lines-1; h >= 0; h--) {
601             for (i = dstwidth/2, x = left; i > 0; i--) {
602                 BYTE pix = *bits++;
603                 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
604                 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
605             }
606             if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
607             srcbits += linebytes;
608             bits         = srcbits + (left >> 1);
609         }
610     } else {
611         lines = -lines;
612         for (h = 0; h < lines; h++) {
613             for (i = dstwidth/2, x = left; i > 0; i--) {
614                 BYTE pix = *bits++;
615                 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
616                 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
617             }
618             if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
619             srcbits += linebytes;
620             bits         = srcbits + (left >> 1);
621         }
622     }
623 }
624
625
626
627 /***********************************************************************
628  *           X11DRV_DIB_GetImageBits_4
629  *
630  * GetDIBits for a 4-bit deep DIB.
631  */
632 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
633                                        DWORD srcwidth, DWORD dstwidth,
634                                        RGBQUAD *colors, PALETTEENTRY *srccolors, 
635                                        XImage *bmpImage, DWORD linebytes )
636 {
637     DWORD x;
638     int h;
639     BYTE *bits;
640     LPBYTE srcpixel;
641
642     if (lines < 0 )
643     {
644        lines = -lines;
645        dstbits = dstbits + ( linebytes * (lines-1) );
646        linebytes = -linebytes;
647     }
648
649     bits = dstbits;
650
651     switch(bmpImage->depth) {
652
653      case 1:
654         /* ==== monochrome bitmap to 4 colormap dib ==== */
655      case 4:
656        /* ==== 4 colormap bitmap to 4 colormap dib ==== */
657        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
658          {
659            PALETTEENTRY val;
660            
661        for (h = lines-1; h >= 0; h--) {
662              for (x = 0; x < dstwidth; x++) {
663                if (!(x&1)) *bits = 0;
664                val = srccolors[XGetPixel(bmpImage, x, h)];
665                *bits |= (X11DRV_DIB_GetNearestIndex(colors, 16, 
666                                                     val.peRed,
667                                                     val.peGreen, 
668                                                     val.peBlue) << (4-((x&1)<<2)));
669                if ((x&1)==1) bits++;
670            }
671              bits = (dstbits += linebytes);
672        }
673          }
674        else goto notsupported;
675        
676        break;
677       
678     case 8:
679       /* ==== 8 colormap bitmap to 4 colormap dib ==== */
680       if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
681       {
682         PALETTEENTRY val;
683
684         for( h = lines - 1; h >= 0; h-- ) {
685           srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
686           for( x = 0; x < dstwidth; x++ ) {
687             if (!(x&1)) *bits = 0;
688             val = srccolors[(int)*srcpixel++];
689             *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 16,
690                                                   val.peRed,
691                                                   val.peGreen,
692                                                   val.peBlue) << (4*(1-(x&1))) );
693             if ((x&1)==1) bits++;
694           }
695           bits = (dstbits += linebytes);
696         }
697       }
698       else goto notsupported;
699
700       break;
701       
702     case 15:
703       {
704         LPWORD srcpixel;
705         WORD val;
706         
707         /* ==== 555 BGR bitmap to 4 colormap dib ==== */
708         if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
709         {
710           for( h = lines - 1; h >= 0; h--) {
711                 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
712                 for( x = 0; x < dstwidth; x++) {
713                   if (!(x&1)) *bits = 0;
714                   val = *srcpixel++;
715                   *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16, 
716                                                         ((val >> 7) & 0xf8) |
717                                                         ((val >> 12) & 0x7),
718                                                         ((val >> 2) & 0xf8) |
719                                                         ((val >> 7) & 0x3),
720                                                         ((val << 3) & 0xf8) |
721                                                         ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
722                   if ((x&1)==1) bits++;
723                 }
724                 bits = (dstbits += linebytes);
725             }
726         }
727         /* ==== 555 RGB bitmap to 4 colormap dib ==== */
728         else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
729         {
730             for( h = lines - 1; h >= 0; h--) 
731             {
732                 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
733                 for( x = 0; x < dstwidth; x++) {
734                   if (!(x&1)) *bits = 0;
735                   val = *srcpixel++;
736                   *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16, 
737                                                         ((val << 3) & 0xf8) |
738                                                         ((val >> 2) & 0x7),
739                                                         ((val >> 2) & 0xfc) |
740                                                         ((val >> 7) & 0x3),
741                                                         ((val >> 7) & 0xf8) |
742                                                         ((val >> 12) &  0x7) ) << ((1-(x&1))<<2) );
743                   if ((x&1)==1) bits++;
744                 }
745                 bits = (dstbits += linebytes);
746             }
747         }
748         else goto notsupported;
749       }
750       break;
751  
752     case 16:
753       {
754         LPWORD srcpixel;
755         WORD val;
756
757         /* ==== 565 BGR bitmap to 4 colormap dib ==== */
758         if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f) 
759         {
760             for( h = lines - 1; h >= 0; h--) 
761             {
762                 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
763                 for( x = 0; x < dstwidth; x++) {
764                   if (!(x&1)) *bits = 0;
765                   val = *srcpixel++;
766                   *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16, 
767                                                         ((val >> 8) & 0xf8) |
768                                                         ((val >> 13) & 0x7),
769                                                         ((val >> 3) & 0xfc) |
770                                                         ((val >> 9) & 0x3),
771                                                         ((val << 3) & 0xf8) |
772                                                         ((val >> 2) & 0x7) )  << ((1-(x&1))<<2) );
773                   if ((x&1)==1) bits++;
774                 }
775                 bits = (dstbits += linebytes);
776             }
777         }
778         /* ==== 565 RGB bitmap to 4 colormap dib ==== */
779         else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
780         {
781             for( h = lines - 1; h >= 0; h--) 
782             {
783                 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
784                 for( x = 0; x < dstwidth; x++) {
785                   if (!(x&1)) *bits = 0;
786                   val = *srcpixel++;
787                   *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16, 
788                                                         ((val << 3) & 0xf8) |
789                                                         ((val >> 2) & 0x7),
790                                                         ((val >> 3) & 0xfc) |
791                                                         ((val >> 9) & 0x3),
792                                                         ((val >> 8) & 0xf8) |
793                                                         ((val >> 13) &  0x7) ) << ((1-(x&1))<<2) );
794                   if ((x&1)==1) bits++;
795                 }
796                 bits = (dstbits += linebytes);
797             }
798         }
799         else goto notsupported;
800       }
801       break;
802       
803     case 24: 
804     case 32:
805       {
806         BYTE *srcpixel;
807         
808         /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
809         if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
810         {        
811           for (h = lines - 1; h >= 0; h--)
812           {
813             srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
814             for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
815               *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[2] , srcpixel[1], srcpixel[0]) << 4) |
816                          X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[6] , srcpixel[5], srcpixel[4]);
817             bits = (dstbits += linebytes);
818           }
819         } 
820         /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
821         else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
822         {
823           for (h = lines - 1; h >= 0; h--)
824           {
825             srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
826             for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
827               *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[0] , srcpixel[1], srcpixel[2]) << 4) |
828                          X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[4] , srcpixel[5], srcpixel[6]);
829             bits = (dstbits += linebytes);
830           }
831         }
832         else goto notsupported;
833       }
834       break;
835
836     default: /* ? bit bmp -> 4 bit DIB */
837     notsupported:
838       FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
839             bmpImage->bits_per_pixel, (int)bmpImage->red_mask, 
840             (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
841       for (h = lines-1; h >= 0; h--) {
842           for (x = 0; x < dstwidth-1; x += 2)
843           {
844               *bits++ = (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x, h ), 0) << 4)
845                   | (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x+1, h ), 0) & 0x0f);
846           }
847           if (dstwidth & 1)
848               *bits = (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x, h ), 0) << 4);
849           bits = (dstbits += linebytes);
850        }
851       break;
852     }
853 }
854
855 /***********************************************************************
856  *           X11DRV_DIB_SetImageBits_RLE4
857  *
858  * SetDIBits for a 4-bit deep compressed DIB.
859  */
860 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
861                                           DWORD width, DWORD dstwidth,
862                                           int left, int *colors,
863                                           XImage *bmpImage )
864 {
865     int x = 0, y = lines - 1, c, length;
866     const BYTE *begin = bits;
867
868     while (y >= 0)
869     {
870         length = *bits++;
871         if (length) {   /* encoded */
872             c = *bits++;
873             while (length--) {
874                 if (x >= width) break;
875                 XPutPixel(bmpImage, x++, y, colors[c >> 4]);
876                 if (!length--) break;
877                 if (x >= width) break;
878                 XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
879             }
880         } else {
881             length = *bits++;
882             switch (length)
883             {
884             case RLE_EOL:
885                 x = 0;
886                 y--;
887                 break;
888
889             case RLE_END:
890                 return;
891
892             case RLE_DELTA:
893                 x += *bits++;
894                 y -= *bits++;
895                 break;
896
897             default: /* absolute */
898                 while (length--) {
899                     c = *bits++;
900                     if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
901                     if (!length--) break;
902                     if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
903                 }
904                 if ((bits - begin) & 1)
905                     bits++;
906             }
907         }
908     }
909 }
910
911
912
913 /***********************************************************************
914  *           X11DRV_DIB_SetImageBits_8
915  *
916  * SetDIBits for an 8-bit deep DIB.
917  */
918 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
919                                 DWORD srcwidth, DWORD dstwidth, int left,
920                                 const int *colors, XImage *bmpImage,
921                                 DWORD linebytes )
922 {
923     DWORD x;
924     int h, color;
925     const BYTE *bits;
926
927     dstwidth += left;
928
929     if (lines < 0 )
930     {
931         lines = -lines;
932         srcbits = srcbits + ( linebytes * (lines-1) );
933         linebytes = -linebytes;
934     }
935
936     bits = srcbits + left;
937
938     switch (bmpImage->depth) {
939     case 15:
940     case 16:
941 #if defined(__i386__) && defined(__GNUC__)
942         /* Some X servers might have 32 bit/ 16bit deep pixel */
943         if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 16))
944         {
945             for (h = lines ; h--; ) {
946                 int _cl1,_cl2; /* temp outputs for asm below */
947                 /* Borrowed from DirectDraw */
948                 __asm__ __volatile__(
949                 "xor %%eax,%%eax\n"
950                 "cld\n"
951                 "1:\n"
952                 "    lodsb\n"
953                 "    movw (%%edx,%%eax,4),%%ax\n"
954                 "    stosw\n"
955                 "      xor %%eax,%%eax\n"
956                 "    loop 1b\n"
957                 :"=S" (bits), "=D" (_cl1), "=c" (_cl2)
958                 :"S" (bits),
959                  "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*2),
960                  "c" (dstwidth-left),
961                  "d" (colors)
962                 :"eax", "cc", "memory"
963                 );
964                 bits = (srcbits += linebytes) + left;
965             }
966             return;
967         }
968         break;
969 #endif
970     case 24:
971 #if defined(__i386__) && defined(__GNUC__)
972         if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 32))
973         {
974             for (h = lines ; h--; ) {
975                 int _cl1,_cl2; /* temp outputs for asm below */
976                 /* Borrowed from DirectDraw */
977                 __asm__ __volatile__(
978                 "xor %%eax,%%eax\n"
979                 "cld\n"
980                 "1:\n"
981                 "    lodsb\n"
982                 "    movl (%%edx,%%eax,4),%%eax\n"
983                 "    stosl\n"
984                 "      xor %%eax,%%eax\n"
985                 "    loop 1b\n"
986                 :"=S" (bits), "=D" (_cl1), "=c" (_cl2)
987                 :"S" (bits),
988                  "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*4),
989                  "c" (dstwidth-left),
990                  "d" (colors)
991                 :"eax", "cc", "memory"
992                 );
993                 bits = (srcbits += linebytes) + left;
994             }
995             return;
996         }
997         break;
998 #endif
999     default:
1000         break; /* use slow generic case below */
1001     }
1002
1003     for (h = lines - 1; h >= 0; h--) {
1004         for (x = left; x < dstwidth; x++, bits++) {
1005             color = colors[*bits];          
1006             XPutPixel( bmpImage, x, h, colors[*bits] );
1007         }
1008         bits = (srcbits += linebytes) + left;
1009     }
1010 }
1011
1012 /***********************************************************************
1013  *           X11DRV_DIB_GetImageBits_8
1014  *
1015  * GetDIBits for an 8-bit deep DIB.
1016  */
1017 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
1018                                        DWORD srcwidth, DWORD dstwidth,
1019                                        RGBQUAD *colors, PALETTEENTRY *srccolors, 
1020                                        XImage *bmpImage, DWORD linebytes )
1021 {
1022     DWORD x;
1023     int h;
1024     BYTE *bits;
1025
1026     if (lines < 0 )
1027     {
1028        lines = -lines;
1029        dstbits = dstbits + ( linebytes * (lines-1) );
1030        linebytes = -linebytes;
1031     }
1032
1033     bits = dstbits;
1034
1035     /* 
1036        Hack for now 
1037        This condition is true when GetImageBits has been called by UpdateDIBSection.
1038        For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
1039        for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
1040     */
1041     if (!srccolors) goto updatesection;
1042
1043     switch(bmpImage->depth) {
1044
1045     case 1:
1046         /* ==== monochrome bitmap to 8 colormap dib ==== */
1047     case 4:
1048        /* ==== 4 colormap bitmap to 8 colormap dib ==== */
1049        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1050          {
1051            PALETTEENTRY val;
1052
1053     for (h = lines - 1; h >= 0; h--) {
1054              for (x = 0; x < dstwidth; x++) {
1055                val = srccolors[XGetPixel(bmpImage, x, h)];
1056                *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1057                                                     val.peGreen, val.peBlue);
1058              }
1059              bits = (dstbits += linebytes);
1060            }
1061          }
1062        else goto notsupported;
1063        
1064        break;
1065     
1066      case 8:
1067        /* ==== 8 colormap bitmap to 8 colormap dib ==== */
1068        if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1069          {
1070            BYTE *srcpixel;
1071            PALETTEENTRY val;
1072            
1073            for (h = lines - 1; h >= 0; h--) {
1074              srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1075              for (x = 0; x < dstwidth; x++) {
1076                val = srccolors[(int)*srcpixel++];
1077                *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed, 
1078                                                     val.peGreen, val.peBlue);
1079              }
1080              bits = (dstbits += linebytes);
1081            }
1082          }
1083        else goto notsupported;
1084        
1085        break;
1086
1087       case 15:
1088       {
1089         LPWORD srcpixel;
1090         WORD val;
1091         
1092         /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1093         if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
1094         {
1095             for( h = lines - 1; h >= 0; h--) 
1096             {
1097                 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1098                 for( x = 0; x < dstwidth; x++ )
1099                 {
1100                   val = *srcpixel++;
1101                   *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256, 
1102                                                         ((val >> 7) & 0xf8) |
1103                                                         ((val >> 12) & 0x7),
1104                                                         ((val >> 2) & 0xf8) |
1105                                                         ((val >> 7) & 0x3),
1106                                                         ((val << 3) & 0xf8) |
1107                                                         ((val >> 2) & 0x7) );
1108                 }
1109                 bits = (dstbits += linebytes);
1110             }
1111         }
1112         /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1113         else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
1114         {
1115             for( h = lines - 1; h >= 0; h--) 
1116             {
1117                 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1118                 for( x = 0; x < dstwidth; x++ )
1119                 {
1120                   val = *srcpixel++;
1121                   *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256, 
1122                                                         ((val << 3) & 0xf8) |
1123                                                         ((val >> 2) & 0x7),
1124                                                         ((val >> 2) & 0xf8) |
1125                                                         ((val >> 7) & 0x3),
1126                                                         ((val >> 7) & 0xf8) |
1127                                                         ((val >> 12) &  0x7) );
1128                 }
1129                 bits = (dstbits += linebytes);
1130             }
1131         }
1132         else goto notsupported;
1133       }
1134       break;
1135
1136       case 16:
1137       {
1138         LPWORD srcpixel;
1139         WORD val;
1140         
1141         /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1142         if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
1143         {
1144             for( h = lines - 1; h >= 0; h--) 
1145             {
1146                 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1147                 for( x = 0; x < dstwidth; x++ )
1148                 {
1149                   val = *srcpixel++;
1150                   *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256, 
1151                                                         ((val >> 8) & 0xf8) |
1152                                                         ((val >> 13) & 0x7),
1153                                                         ((val >> 3) & 0xfc) |
1154                                                         ((val >> 9) & 0x3),
1155                                                         ((val << 3) & 0xf8) |
1156                                                         ((val >> 2) & 0x7) );
1157                 }
1158                 bits = (dstbits += linebytes);
1159             }
1160         }
1161         /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1162         else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
1163         {
1164             for( h = lines - 1; h >= 0; h--) 
1165             {
1166                 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1167                 for( x = 0; x < dstwidth; x++ )
1168                 {
1169                   val = *srcpixel++;
1170                   *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256, 
1171                                                         ((val << 3) & 0xf8) |
1172                                                         ((val >> 2) & 0x7),
1173                                                         ((val >> 3) & 0x00fc) |
1174                                                         ((val >> 9) & 0x3),
1175                                                         ((val >> 8) & 0x00f8) |
1176                                                         ((val >> 13) &  0x7) );
1177                 }
1178                 bits = (dstbits += linebytes);
1179             }
1180         }
1181         else goto notsupported;
1182       }
1183       break;
1184       
1185       case 24: 
1186       case 32:
1187       {
1188         BYTE *srcpixel;
1189         
1190         /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1191         if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1192         {
1193           for (h = lines - 1; h >= 0; h--)
1194             {
1195               srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1196               for (x = 0; x < dstwidth; x++, srcpixel+=4)
1197                 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, 
1198                                                      srcpixel[2] , srcpixel[1], *srcpixel);
1199               bits = (dstbits += linebytes);
1200             }
1201         }
1202         /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1203         else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1204         {
1205           for (h = lines - 1; h >= 0; h--)
1206             {
1207               srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1208               for (x = 0; x < dstwidth; x++, srcpixel+=4)
1209                 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, 
1210                                                      *srcpixel, srcpixel[1], srcpixel[2]);
1211               bits = (dstbits += linebytes);
1212             }
1213           
1214         }
1215         else goto notsupported;
1216       }
1217       break;
1218
1219     default: /* ? bit bmp -> 8 bit DIB */
1220     notsupported:
1221       FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1222             bmpImage->depth, (int)bmpImage->red_mask, 
1223             (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1224     updatesection:
1225       for (h = lines - 1; h >= 0; h--) {
1226         for (x = 0; x < dstwidth; x++, bits++) {
1227           *bits = X11DRV_DIB_MapColor((int *)colors, 256,
1228                                          XGetPixel( bmpImage, x, h ), *bits);
1229         }
1230         bits = (dstbits += linebytes);
1231       }
1232       break;
1233     }
1234 }
1235
1236 /***********************************************************************
1237  *            X11DRV_DIB_SetImageBits_RLE8
1238  *
1239  * SetDIBits for an 8-bit deep compressed DIB.
1240  *
1241  * This function rewritten 941113 by James Youngman.  WINE blew out when I
1242  * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.  
1243  *
1244  * This was because the algorithm assumed that all RLE8 bitmaps end with the  
1245  * 'End of bitmap' escape code.  This code is very much laxer in what it
1246  * allows to end the expansion.  Possibly too lax.  See the note by 
1247  * case RleDelta.  BTW, MS's documentation implies that a correct RLE8
1248  * bitmap should end with RleEnd, but on the other hand, software exists 
1249  * that produces ones that don't and Windows 3.1 doesn't complain a bit
1250  * about it.
1251  *
1252  * (No) apologies for my English spelling.  [Emacs users: c-indent-level=4].
1253  *                      James A. Youngman <mbcstjy@afs.man.ac.uk>
1254  *                                              [JAY]
1255  */
1256 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1257                                           DWORD width, DWORD dstwidth,
1258                                           int left, int *colors,
1259                                           XImage *bmpImage )
1260 {
1261     int x;                      /* X-positon on each line.  Increases. */
1262     int y;                      /* Line #.  Starts at lines-1, decreases */
1263     const BYTE *pIn = bits;     /* Pointer to current position in bits */
1264     BYTE length;                /* The length pf a run */
1265     BYTE escape_code;           /* See enum Rle8_EscapeCodes.*/
1266
1267     /*
1268      * Note that the bitmap data is stored by Windows starting at the
1269      * bottom line of the bitmap and going upwards.  Within each line,
1270      * the data is stored left-to-right.  That's the reason why line
1271      * goes from lines-1 to 0.                  [JAY]
1272      */
1273
1274     x = 0;
1275     y = lines - 1;
1276     while (y >= 0)
1277     {
1278         length = *pIn++;
1279
1280         /* 
1281          * If the length byte is not zero (which is the escape value),
1282          * We have a run of length pixels all the same colour.  The colour 
1283          * index is stored next. 
1284          *
1285          * If the length byte is zero, we need to read the next byte to
1286          * know what to do.                     [JAY]
1287          */
1288         if (length != 0)
1289         {
1290             /* 
1291              * [Run-Length] Encoded mode 
1292              */
1293             int color = colors[*pIn++];
1294             while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
1295         }
1296         else
1297         {
1298             /* 
1299              * Escape codes (may be an absolute sequence though)
1300              */
1301             escape_code = (*pIn++);
1302             switch(escape_code)
1303             {
1304             case RLE_EOL:
1305                 x = 0;
1306                 y--;
1307                 break;
1308
1309             case RLE_END:
1310                 /* Not all RLE8 bitmaps end with this code.  For
1311                  * example, Paint Shop Pro produces some that don't.
1312                  * That's (I think) what caused the previous
1313                  * implementation to fail.  [JAY]
1314                  */
1315                 return;
1316
1317             case RLE_DELTA:
1318                 x += (*pIn++);
1319                 y -= (*pIn++);
1320                 break;
1321
1322             default:  /* switch to absolute mode */
1323                 length = escape_code;
1324                 while (length--)
1325                 {
1326                     int color = colors[*pIn++];
1327                     if (x >= dstwidth)
1328                     {
1329                         pIn += length;
1330                         break;
1331                     }
1332                     XPutPixel(bmpImage, x++, y, color);
1333                 }
1334                 /*
1335                  * If you think for a moment you'll realise that the
1336                  * only time we could ever possibly read an odd
1337                  * number of bytes is when there is a 0x00 (escape),
1338                  * a value >0x02 (absolute mode) and then an odd-
1339                  * length run.  Therefore this is the only place we
1340                  * need to worry about it.  Everywhere else the
1341                  * bytes are always read in pairs.  [JAY]
1342                  */
1343                 if (escape_code & 1) pIn++; /* Throw away the pad byte. */
1344                 break;
1345             } /* switch (escape_code) : Escape sequence */
1346         }
1347     }
1348 }
1349
1350
1351 /***********************************************************************
1352  *           X11DRV_DIB_SetImageBits_16
1353  *
1354  * SetDIBits for a 16-bit deep DIB.
1355  */
1356 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1357                                  DWORD srcwidth, DWORD dstwidth, int left,
1358                                        DC *dc, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1359                                        XImage *bmpImage, DWORD linebytes )
1360 {
1361     DWORD x;
1362     int h;
1363   
1364     if (lines < 0 )
1365     {
1366         lines = -lines;
1367         srcbits = srcbits + ( linebytes * (lines-1));
1368         linebytes = -linebytes;
1369     }
1370         
1371     switch ( bmpImage->depth )
1372     {
1373         case 15:
1374             /* using same format as XImage */
1375             if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1376                 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1377                     memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1378             else     /* We need to do a conversion from a 565 dib */
1379             {
1380                 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1381                 DWORD val;
1382                 int div = dstwidth % 2;
1383
1384                 for (h = lines - 1; h >= 0; h--) {
1385                     dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1386                     for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1387                         val = *ptr++;
1388                         *dstpixel++ =   ((val >> 1) & 0x7fe07fe0) | (val & 0x001f001f); /* Red & Green & Blue */
1389                     }
1390                     if (div != 0) /* Odd width? */
1391                         *dstpixel = ((*(WORD *)ptr >> 1) & 0x7fe0) | (*(WORD *)ptr & 0x001f);
1392                     ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1393                 }
1394             }
1395             break;
1396
1397         case 16:
1398             /* using same format as XImage */
1399             if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1400                 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1401                     memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1402             else     /* We need to do a conversion from a 555 dib */
1403             {
1404                 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1405                 DWORD val;
1406                 int div = dstwidth % 2;
1407
1408                 for (h = lines - 1; h >= 0; h--) {
1409                     dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1410                     for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1411                         val = *ptr++;
1412                         *dstpixel++ = ((val << 1) & 0xffc0ffc0) | ((val >> 4) & 0x00200020) | /* Red & Green */
1413                           (val & 0x001f001f);                             /* Blue */
1414                     }
1415                     if (div != 0) /* Odd width? */
1416                         *dstpixel = ((*(WORD *)ptr << 1) & 0xffc0) | ((*(WORD *)ptr >> 4) & 0x0020)
1417                                     | (*(WORD *)ptr & 0x001f);
1418                     ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1419                 }
1420             }
1421             break;
1422
1423         case 24:
1424         case 32:
1425             {
1426                 DWORD  *dstpixel;
1427                 LPWORD ptr = (LPWORD)srcbits + left;
1428                 DWORD val;
1429
1430                 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1431                 {
1432                   if ((rSrc == 0xF800) && (gSrc == 0x07E0) && (bSrc == 0x001F)) {
1433                     /* ==== 555 RGB dib to 24/32 RGB bitmap ==== */
1434                     for (h = lines - 1; h >= 0; h--) {
1435                       dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1436                       for (x = 0; x < dstwidth; x++) {
1437                         val = *ptr++;
1438                         *dstpixel++ = ((val << 8) & 0xF80000) | /* Red */
1439                                       ((val << 5) & 0x00FC00) | /* Green */
1440                                       ((val << 3) & 0x0000FF);  /* Blue */
1441                       }
1442                       ptr = (LPWORD)(srcbits += linebytes) + left;
1443                     }
1444                   } else {
1445                     /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1446                     for (h = lines - 1; h >= 0; h--) {
1447                       dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1448                       for (x = 0; x < dstwidth; x++) {
1449                         
1450                         val = *ptr++;
1451                         *dstpixel++ = ((val << 9) & 0xf80000) | ((val << 4) & 0x070000) | /* Red */
1452                           ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1453                           ((val << 3) & 0x0000f8) | ((val >> 2) & 0x000007);      /* Blue */
1454                       }
1455                       ptr = (LPWORD)(srcbits += linebytes) + left;
1456                     }
1457                   }
1458                 }
1459                 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1460                 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1461                 {
1462                   for (h = lines - 1; h >= 0; h--) {
1463                     dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1464                     for (x = 0; x < dstwidth; x++) {
1465
1466                         val = *ptr++;
1467                         *dstpixel++ = ((val >> 7) & 0x0000f8) | ((val >> 12) & 0x000007) | /* Red */
1468                           ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1469                           ((val << 19) & 0xf80000) | ((val >> 14) & 0x070000);      /* Blue */
1470                     }
1471                     ptr = (LPWORD)(srcbits += linebytes) + left;
1472                   }
1473                 }
1474
1475             }
1476             break;
1477
1478         case 1:
1479         case 4:
1480         case 8:
1481             {
1482                 LPWORD ptr = (LPWORD)srcbits + left;
1483                 WORD val;
1484                 int sc1, sc2;
1485
1486                 /* Set color scaling values */
1487                 if ( rSrc == 0x7c00 ) { sc1 = 7; sc2 = 2; }             /* 555 dib */
1488                 else { sc1 = 8; sc2 = 3; }                              /* 565 dib */
1489
1490                 for (h = lines - 1; h >= 0; h--) {
1491                     for (x = left; x < dstwidth+left; x++) {
1492                         val = *ptr++;
1493                         XPutPixel( bmpImage, x, h,
1494                                    X11DRV_PALETTE_ToPhysical(dc, RGB(((val & rSrc) >> sc1),  /* Red */
1495                                                                      ((val & gSrc) >> sc2),  /* Green */
1496                                                                      ((val & bSrc) << 3)))); /* Blue */
1497                     }
1498                     ptr = (LPWORD) (srcbits += linebytes) + left;
1499                 }
1500             }
1501             break;
1502
1503         default:
1504             FIXME("16 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
1505         break;
1506
1507     }
1508 }
1509
1510
1511 /***********************************************************************
1512  *           X11DRV_DIB_GetImageBits_16
1513  *
1514  * GetDIBits for an 16-bit deep DIB.
1515  */
1516 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
1517                                         DWORD dstwidth, DWORD srcwidth,
1518                                         PALETTEENTRY *srccolors,
1519                                         DWORD rDst, DWORD gDst, DWORD bDst,
1520                                         XImage *bmpImage, DWORD dibpitch )
1521 {
1522     DWORD x;
1523     int h, rsc, gsc;
1524
1525     DWORD linebytes = dibpitch;
1526
1527     if (lines < 0 )
1528     {
1529         lines = -lines;
1530         dstbits = dstbits + ( linebytes * (lines-1));
1531         linebytes = -linebytes;
1532     }
1533
1534     /* Set color scaling values */
1535     if ( rDst == 0x7c00 ) { rsc = 7; gsc = 2; }             /* 555 dib */
1536     else { rsc = 8; gsc = 3; }                              /* 565 dib */
1537
1538     switch ( bmpImage->depth )
1539     {
1540         case 15:
1541             /* using same format as XImage */
1542             if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1543                 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1544                     memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1545             /* reversed format (BGR <=> RGB) */
1546             else if (rDst == bmpImage->blue_mask && bDst == bmpImage->red_mask)
1547             {
1548                 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1549                 DWORD val;
1550                 int div = srcwidth % 2;
1551
1552                 for (h = lines - 1; h >= 0; h--) {
1553                     srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1554                     for (x = 0; x < srcwidth/2; x++) {  /* Do 2 pixels at a time */
1555                         val = *srcpixel++;
1556                         *ptr++ = ((val << 10) & 0xf800f800) | (val & 0x03e003e0) |        /* Red & Green */
1557                           ((val >> 10) & 0x001f001f);                                     /* Blue */
1558                     }
1559                     if (div != 0) /* Odd width? */
1560                         *ptr = ((*(WORD *)srcpixel << 1) & 0xffc0) | ((*(WORD *)srcpixel >> 4) & 0x0020) |
1561                                (*(WORD *)srcpixel & 0x001f);
1562                     ptr = (LPDWORD)(dstbits += linebytes);
1563                }
1564            }
1565            else goto notsupported;
1566
1567            break;
1568
1569        case 16:
1570            {
1571            LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1572            DWORD val;
1573            int div = srcwidth % 2;
1574
1575            /* using same format as XImage */
1576            if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1577                for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1578                    memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1579            /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1580            else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f &&
1581                     rDst == 0x7c00 && bDst == 0x001f)
1582            {
1583                for (h = lines - 1; h >= 0; h--) {
1584                    srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1585                    for (x = 0; x < srcwidth/2; x++) {  /* Do 2 pixels at a time */
1586                        val = *srcpixel++;
1587                        *ptr++ = ((val >> 1) & 0x7fe07fe0) |                    /* Red & Green */
1588                          (val & 0x001f001f);                                   /* Blue */
1589                    }
1590                    if (div != 0) /* Odd width? */
1591                        *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1592                    ptr = (LPDWORD) (dstbits += linebytes);
1593                }
1594            }
1595            /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1596            else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800 &&
1597                     rDst == 0x7c00 && bDst == 0x001f)
1598            {
1599                for (h = lines - 1; h >= 0; h--) {
1600                    srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1601                    for (x = 0; x < srcwidth/2; x++) {  /* Do 2 pixels at a time */
1602                        val = *srcpixel++;
1603                        *ptr++ = ((val << 10) & 0x7c007c00) | ((val >> 1) & 0x03e003e0) |   /* Red & Green */
1604                          ((val >> 11) & 0x001f001f);                                       /* Blue */
1605                    }
1606                    if (div != 0) /* Odd width? */
1607                        *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1608                    ptr = (LPDWORD) (dstbits += linebytes);
1609                }
1610                }
1611            else goto notsupported;
1612            }
1613            break;
1614
1615        case 24:
1616        case 32:
1617            {
1618                DWORD  *srcpixel;
1619                LPWORD ptr = (LPWORD)dstbits;
1620                DWORD val;
1621
1622                /* ==== 24/32 BGR bitmap ==== */
1623                if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1624                {
1625                    int rsc2 = 16-rsc, gsc2 = 8-gsc;
1626                    for (h = lines - 1; h >= 0; h--) {
1627                        srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1628                        for (x = 0; x < srcwidth; x++, ptr++) {
1629                            val = *srcpixel++;
1630                            *ptr = ((val >> rsc2) & rDst) |
1631                                   ((val >> gsc2) & gDst) |
1632                                   ((val >> 3) & bDst);
1633                        }
1634                        ptr = (LPWORD)(dstbits += linebytes);
1635                    }
1636                }
1637                /* ==== 24/32 RGB bitmap ==== */
1638                else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1639                {
1640                    int gsc2 = 8-gsc;
1641                    for (h = lines - 1; h >= 0; h--) {
1642                        srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1643                        for (x = 0; x < srcwidth; x++, ptr++) {
1644                            val = *srcpixel++;
1645                            *ptr = ((val << rsc) & rDst) |
1646                                   ((val >> gsc2) & gDst) |
1647                                   ((val >> 19) & bDst);
1648                        }
1649                        ptr = (LPWORD) (dstbits += linebytes);
1650                    }
1651                }
1652                else goto notsupported;
1653            }
1654            break;
1655
1656        case 1:
1657             /* ==== monochrome bitmap ==== */
1658        case 4:
1659             /* ==== 4 colormap bitmap ==== */
1660             if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1661             {
1662                 LPWORD ptr = (LPWORD)dstbits;
1663                 PALETTEENTRY val;
1664
1665                 for (h = lines - 1; h >= 0; h--) {
1666                   for (x = 0; x < dstwidth; x++) {
1667                     val = srccolors[XGetPixel(bmpImage, x, h)];
1668                     *ptr++ = ((val.peRed << rsc) & rDst) | 
1669                              ((val.peGreen << gsc) & gDst) |
1670                              ((val.peBlue >> 3) & bDst);
1671                   }
1672                   ptr = (LPWORD)(dstbits += linebytes);
1673                 }
1674             }
1675             else goto notsupported;
1676
1677             break;
1678
1679         case 8:
1680             /* ==== 8 colormap bitmap ==== */
1681             if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1682             {
1683                 LPWORD ptr = (LPWORD)dstbits;
1684                 BYTE *srcpixel;
1685                 PALETTEENTRY val;
1686
1687                for (h = lines - 1; h >= 0; h--) {
1688                   srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1689                   for (x = 0; x < dstwidth; x++) {
1690                     val = srccolors[(int)*srcpixel++];
1691                     *ptr++ = ((val.peRed << rsc) & rDst) | 
1692                              ((val.peGreen << gsc) & gDst) |
1693                              ((val.peBlue >> 3) & bDst);
1694                    }
1695                   ptr = (LPWORD)(dstbits += linebytes);
1696                }
1697            }
1698             else goto notsupported;
1699
1700            break;
1701
1702        default:
1703        notsupported:
1704             {
1705               BYTE r,g, b;
1706               LPWORD ptr = (LPWORD)dstbits;
1707
1708               FIXME("from %d bit bitmap with mask R,G,B %lx,%lx,%lx to 16 bit DIB %lx,%lx,%lx\n",
1709                     bmpImage->depth, bmpImage->red_mask, 
1710                     bmpImage->green_mask, bmpImage->blue_mask,
1711                     rDst, gDst, bDst);
1712
1713               for (h = lines - 1; h >= 0; h--)
1714                 {
1715                   for (x = 0; x < dstwidth; x++, ptr++)
1716                     {
1717                       COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
1718                       r = (BYTE) GetRValue(pixel);
1719                       g = (BYTE) GetGValue(pixel);
1720                       b = (BYTE) GetBValue(pixel);
1721                       *ptr = ( ((r << rsc) & rDst) | ((g << gsc) & gDst) | ((b >> 3) & bDst) );
1722                     }
1723                   ptr = (LPWORD) (dstbits += linebytes);
1724                 }
1725             }
1726            break;
1727    }
1728 }
1729
1730
1731 /***********************************************************************
1732  *           X11DRV_DIB_SetImageBits_24
1733  *
1734  * SetDIBits for a 24-bit deep DIB.
1735  */
1736 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
1737                                  DWORD srcwidth, DWORD dstwidth, int left,
1738                                  DC *dc, XImage *bmpImage, DWORD linebytes )
1739 {
1740     DWORD x;
1741     int h;
1742   
1743     if (lines < 0 )
1744     {
1745         lines = -lines;
1746         srcbits = srcbits + linebytes * (lines - 1);
1747         linebytes = -linebytes;
1748     }
1749
1750     switch ( bmpImage->depth )
1751     {
1752         case 24:
1753             {
1754                 if (bmpImage->bits_per_pixel == 24) {
1755                         int dstlinebytes = linebytes;
1756                         BYTE *dstpixel;
1757                         BYTE *ptr = (BYTE *)(srcbits+left*3);
1758
1759                         if (dstlinebytes < 0 ) dstlinebytes = -dstlinebytes;
1760                         dstpixel = bmpImage->data + lines*dstlinebytes + left*3;
1761                         for(h = lines ; h-- ; ) {
1762                                 dstpixel-=dstlinebytes;
1763                                 memcpy(dstpixel,ptr,dstwidth*3);
1764                                 ptr +=linebytes;
1765                         }
1766                         break;
1767                 }
1768             }
1769         case 32:
1770             {
1771                 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 )  /* packed BGR to unpacked BGR */
1772                 {
1773                     DWORD *dstpixel, val, buf;
1774                     DWORD *ptr = (DWORD *)(srcbits + left*3);
1775                     BYTE *bits;
1776                     int div = dstwidth % 4;
1777                     int divk;
1778
1779                     for(h = lines - 1; h >= 0; h--)
1780                     {
1781                         dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1782
1783                         for (x = 0; x < dstwidth/4; x++) {   /* do 3 dwords source, 4 dwords dest at a time */
1784                             buf = *ptr++;
1785                             *dstpixel++ = buf&0x00ffffff;                  /* b1, g1, r1 */
1786                             val = (buf >> 24);                             /* b2 */
1787                             buf = *ptr++;
1788                             *dstpixel++ = (val | (buf<<8)) &0x00ffffff;    /* g2, r2 */
1789                             val = (buf >> 16);                             /* b3, g3 */
1790                             buf = *ptr++;
1791                             *dstpixel++ = (val | (buf<<16)) &0x00ffffff;   /* r3 */
1792                             *dstpixel++ = (buf >> 8);                      /* b4, g4, r4 */
1793                         }
1794                         for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1795                         {
1796                             *dstpixel++ = *(DWORD*)bits & 0x00ffffff;      /* b, g, r */
1797                         }
1798                         ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1799                     }
1800                 }
1801                 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff )  /* packed BGR to unpacked RGB */
1802                 {
1803                     DWORD *dstpixel, val, buf;
1804                     DWORD *ptr = (DWORD *)(srcbits + left*3);
1805                     BYTE *bits;
1806                     int div = dstwidth % 4;
1807                     int divk;
1808
1809                     for(h = lines - 1; h >= 0; h--)
1810                     {
1811                         dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1812
1813                         for (x = 0; x < dstwidth/4; x++) {   /* do 3 dwords source, 4 dwords dest at a time */
1814                             buf = *ptr++;
1815                             *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16);  /* b1, g1, r1 */
1816                             val = ((buf&0xff000000)>>8);                                           /* b2 */
1817                             buf = *ptr++;
1818                             *dstpixel++ = val | ((buf&0xff)<<8) | ((buf&0xff00)>>8);               /* g2, r2 */
1819                             val = (buf&0xff0000) | ((buf&0xff000000)>>16);                         /* b3, g3 */
1820                             buf = *ptr++;
1821                             *dstpixel++ = val | (buf&0xff);                                        /* r3 */
1822                             *dstpixel++ = ((buf&0xff00)<<8) | ((buf&0xff0000)>>8) | (buf>>24);     /* b4, g4, r4 */
1823                         }
1824                         for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1825                         {
1826                             buf = *(DWORD*)bits;
1827                             *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16);  /* b, g, r */
1828                         }
1829                         ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1830                     }
1831                 }
1832                 else
1833                     goto notsupported;
1834             }
1835             break;
1836
1837         case 15:
1838             {
1839                 if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f )   /* BGR888 to RGB555 */
1840                 {
1841                     DWORD  *ptr = (DWORD *)(srcbits + left*3);
1842                     LPBYTE bits;
1843                     LPWORD dstpixel;
1844                     int div = dstwidth % 4;
1845                     int divk;
1846
1847                     for (h = lines - 1; h >= 0; h--) {              /* Do 4 pixels at a time */
1848                         dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1849                         for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1850                             *dstpixel++ = ((ptr[0] << 7) & 0x7c00)  | ((ptr[0] >> 6) & 0x03e0)  | ((ptr[0] >> 19) & 0x1f);
1851                             *dstpixel++ = ((ptr[0] >> 17) & 0x7c00) | ((ptr[1] << 2) & 0x03e0)  | ((ptr[1] >> 11) & 0x1f);
1852                             *dstpixel++ = ((ptr[1] >> 9) & 0x07c00) | ((ptr[1] >> 22) & 0x03e0) | ((ptr[2] >> 3) & 0x1f);
1853                             *dstpixel++ = ((ptr[2] >> 1) & 0x07c00) | ((ptr[2] >> 14) & 0x03e0) | ((ptr[2] >> 27) & 0x1f);
1854                         }
1855                         for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3)  /* dstwidth not divisible by 4? */
1856                             *dstpixel++ = (((WORD)bits[0] << 7) & 0x07c00) |
1857                                             (((WORD)bits[1] << 2) & 0x03e0) |
1858                                             (((WORD)bits[2] >> 3) & 0x001f);
1859                         ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1860                     }
1861                 }
1862                 else if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 )   /* BGR888 to BGR555 */
1863                 {
1864                     DWORD  *ptr = (DWORD *)(srcbits + left*3);
1865                     LPBYTE bits;
1866                     LPWORD dstpixel;
1867                     int div = dstwidth % 4;
1868                     int divk;
1869
1870                     for (h = lines - 1; h >= 0; h--) {              /* Do 4 pixels at a time */
1871                         dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1872                         for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1873                             *dstpixel++ = ((ptr[0] >> 3) & 0x1f)  | ((ptr[0] >> 6) & 0x03e0)  | ((ptr[0] >> 9) & 0x7c00);
1874                             *dstpixel++ = ((ptr[0] >> 27) & 0x1f) | ((ptr[1] << 2) & 0x03e0)  | ((ptr[1] >> 1) & 0x7c00);
1875                             *dstpixel++ = ((ptr[1] >> 19) & 0x1f) | ((ptr[1] >> 22) & 0x03e0) | ((ptr[2] << 7) & 0x7c00);
1876                             *dstpixel++ = ((ptr[2] >> 11) & 0x1f) | ((ptr[2] >> 14) & 0x03e0) | ((ptr[2] >> 17) & 0x7c00);
1877                         }
1878                         for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3)  /* dstwidth not divisible by 4? */
1879                             *dstpixel++ = (((WORD)bits[2] << 7) & 0x07c00) |
1880                                             (((WORD)bits[1] << 2) & 0x03e0) |
1881                                             (((WORD)bits[0] >> 3) & 0x001f);
1882                         ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1883                     }
1884                 }
1885                 else
1886                     goto notsupported;
1887             }
1888             break;
1889
1890         case 16:
1891             {
1892                 DWORD  *ptr = (DWORD *)(srcbits + left*3);
1893                 LPBYTE bits;
1894                 LPWORD dstpixel;
1895                 int div = dstwidth % 4;
1896                 int divk;
1897
1898                 if( bmpImage->blue_mask == 0x001f && bmpImage->red_mask == 0xf800 )    /* BGR888 to BGR565 */
1899                 {
1900                     for (h = lines - 1; h >= 0; h--) {              /* Do 4 pixels at a time */
1901                         dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1902                         for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1903                             *dstpixel++ = ((ptr[0] >> 3) & 0x1f)  | ((ptr[0] >> 5) & 0x07e0)  | ((ptr[0] >> 8) & 0xf800);
1904                             *dstpixel++ = ((ptr[0] >> 27) & 0x1f) | ((ptr[1] << 3) & 0x07e0)  | (ptr[1] & 0xf800);
1905                             *dstpixel++ = ((ptr[1] >> 19) & 0x1f) | ((ptr[1] >> 21) & 0x07e0) | ((ptr[2] << 8) & 0xf800);
1906                             *dstpixel++ = ((ptr[2] >> 11) & 0x1f) | ((ptr[2] >> 13) & 0x07e0) | ((ptr[2] >> 16) & 0xf800);
1907                         }
1908                         for (   bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3)  /* dstwidth is not divisible by 4? */
1909                             *dstpixel++ = (((WORD)bits[2] << 8) & 0xf800) |
1910                                             (((WORD)bits[1] << 3) & 0x07e0) |
1911                                             (((WORD)bits[0] >> 3) & 0x001f);
1912                         ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1913                     }
1914                 }
1915                 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x001f ) /* BGR888 to RGB565 */
1916                 {
1917                     for (h = lines - 1; h >= 0; h--) {              /* Do 4 pixels at a time */
1918                         dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1919                         for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1920                             *dstpixel++ = ((ptr[0] << 8) & 0xf800)  | ((ptr[0] >> 5) & 0x07e0)  | ((ptr[0] >> 19) & 0x1f);
1921                             *dstpixel++ = ((ptr[0] >> 16) & 0xf800) | ((ptr[1] << 3) & 0x07e0)  | ((ptr[1] >> 11) & 0x1f);
1922                             *dstpixel++ = ((ptr[1] >> 8) & 0xf800)  | ((ptr[1] >> 21) & 0x07e0) | ((ptr[2] >> 3) & 0x1f);
1923                             *dstpixel++ = (ptr[2] & 0xf800)         | ((ptr[2] >> 13) & 0x07e0) | ((ptr[2] >> 27) & 0x1f);
1924                         }
1925                         for (   bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3)  /* dstwidth is not divisible by 4? */
1926                             *dstpixel++ = (((WORD)bits[0] << 8) & 0xf800) |
1927                                             (((WORD)bits[1] << 3) & 0x07e0) |
1928                                             (((WORD)bits[2] >> 3) & 0x001f);
1929                         ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1930                     }
1931                 }
1932                 else
1933                     goto notsupported;
1934             }
1935             break;
1936          
1937         case 1:
1938         case 4:
1939         case 8:
1940             {
1941                 LPBYTE bits = (LPBYTE)srcbits + left*3;
1942
1943                 for (h = lines - 1; h >= 0; h--) {
1944                     for (x = left; x < dstwidth+left; x++, bits+=3)
1945                         XPutPixel( bmpImage, x, h, 
1946                                    X11DRV_PALETTE_ToPhysical(dc, RGB(bits[2], bits[1], bits[0])));
1947                     bits = (LPBYTE)(srcbits += linebytes) + left * 3;
1948                 }
1949             }
1950             break;
1951
1952         default:
1953         notsupported:
1954             FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
1955                   bmpImage->bits_per_pixel, (int)bmpImage->red_mask, 
1956                   (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1957             break;
1958     }
1959 }
1960
1961
1962 /***********************************************************************
1963  *           X11DRV_DIB_GetImageBits_24
1964  *
1965  * GetDIBits for an 24-bit deep DIB.
1966  */
1967 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
1968                                         DWORD dstwidth, DWORD srcwidth,
1969                                         PALETTEENTRY *srccolors,
1970                                         XImage *bmpImage, DWORD linebytes )
1971 {
1972     DWORD x, val;
1973     int h;
1974
1975     if (lines < 0 )
1976     {
1977         lines = -lines;
1978         dstbits = dstbits + ( linebytes * (lines-1) );
1979         linebytes = -linebytes;
1980     }
1981
1982     switch ( bmpImage->depth )
1983     {
1984         case 24:
1985             {
1986                 if (bmpImage->bits_per_pixel == 24) {
1987                         int tocopy = linebytes;
1988                         BYTE *srcpixel;
1989                         BYTE *ptr = (LPBYTE)dstbits;
1990
1991                         if (tocopy < 0 ) tocopy = -tocopy;
1992                         srcpixel = bmpImage->data + lines*tocopy;
1993                         for(h = lines ; h-- ; ) {
1994                                 srcpixel-=tocopy;
1995                                 memcpy(ptr,srcpixel,tocopy);
1996                                 ptr = (LPBYTE)(dstbits+=linebytes);
1997                         }
1998                         break;
1999                 }
2000             }
2001         case 32:
2002             {
2003                     DWORD  *srcpixel, buf;
2004                     LPBYTE bits;
2005             DWORD *ptr=(DWORD *)dstbits;
2006                     int quotient = dstwidth / 4;
2007                     int remainder = dstwidth % 4;
2008                     int remk;
2009
2010             /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
2011             if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 )
2012             {
2013                     for(h = lines - 1; h >= 0; h--)
2014                     {
2015                   srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2016
2017                         for (x = 0; x < quotient; x++) {     /* do 4 dwords source, 3 dwords dest at a time */
2018                           buf = ((*srcpixel++)&0x00ffffff);      /* b1, g1, r1*/
2019                           *ptr++ = buf | ((*srcpixel)<<24);      /* b2 */
2020                           buf = ((*srcpixel++>>8)&0x0000ffff);   /* g2, r2 */
2021                           *ptr++ = buf | ((*srcpixel)<<16);      /* b3, g3 */
2022                           buf = ((*srcpixel++>>16)&0x000000ff);  /* r3 */
2023                           *ptr++ = buf | ((*srcpixel++)<<8);     /* b4, g4, r4 */
2024                         }
2025                         for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2026                         {
2027                             buf=*srcpixel++;
2028                             *(WORD*)bits = buf;                    /* b, g */
2029                           *(bits+2) = buf>>16;                   /* r */
2030                         }
2031                   ptr = (DWORD*)(dstbits+=linebytes);
2032                     }
2033
2034                 }
2035             /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
2036             else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff )
2037                 {
2038                     for(h = lines - 1; h >= 0; h--)
2039                     {
2040                   srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2041
2042                         for (x = 0; x < quotient; x++) {     /* do 4 dwords source, 3 dwords dest at a time */
2043                             buf = *srcpixel++;
2044                             val = ((buf&0xff0000)>>16) | (buf&0xff00) | ((buf&0xff)<<16);       /* b1, g1, r1 */
2045                             buf = *srcpixel++;
2046                             *ptr++ = val | ((buf&0xff0000)<<8);                                 /* b2 */
2047                             val = ((buf&0xff00)>>8) | ((buf&0xff)<<8);                          /* g2, r2 */
2048                             buf = *srcpixel++;
2049                             *ptr++ = val | (buf&0xff0000) | ((buf&0xff00)<<16);                 /* b3, g3 */
2050                             val = (buf&0xff);                                                   /* r3 */
2051                             buf = *srcpixel++;
2052                             *ptr++ = val | ((buf&0xff0000)>>8) | ((buf&0xff00)<<8) | (buf<<24); /* b4, g4, r4 */
2053                         }
2054                         for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2055                         {
2056                             buf=*srcpixel++;
2057                             *(WORD*)bits = (buf&0xff00) | ((buf&0xff0000)>>16) ;                /* b, g */
2058                             *(bits+2) = buf;                                                    /* r */
2059                         }
2060                   ptr = (DWORD*)(dstbits+=linebytes);
2061                     }
2062                 }
2063             else goto notsupported;
2064             }
2065             break;
2066
2067         case 15:
2068             {
2069                 LPWORD srcpixel;
2070             LPBYTE bits = dstbits;
2071                 WORD val;
2072
2073             /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2074             if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 )  
2075                 {
2076                     for (h = lines - 1; h >= 0; h--) {
2077                   srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2078                         for (x = 0; x < srcwidth; x++, bits += 3) {
2079                             val = *srcpixel++;
2080                             bits[2] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));           /*Red*/
2081                             bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));            /*Green*/
2082                             bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));            /*Blue*/
2083                         }
2084                   bits = (dstbits += linebytes);
2085                     }
2086                 }
2087             /* ==== 555 RGB bitmap to 24 RGB dib==== */
2088             else if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f )
2089                 {
2090                     for (h = lines - 1; h >= 0; h--) {
2091                   srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2092                         for (x = 0; x < srcwidth; x++, bits += 3) {
2093                             val = *srcpixel++;
2094                             bits[0] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));           /*Red*/
2095                             bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));            /*Green*/
2096                             bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));            /*Blue*/
2097                         }
2098                   bits = (dstbits += linebytes);
2099                     }
2100                 }
2101             else goto notsupported;
2102             }
2103             break;
2104
2105         case 16:
2106             {
2107                 LPWORD srcpixel;
2108             LPBYTE bits = dstbits;
2109                 WORD val;
2110
2111             /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2112             if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0xf800 )
2113                 {
2114                     for (h = lines - 1; h >= 0; h--) {
2115                   srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2116                         for (x = 0; x < srcwidth; x++, bits += 3) {
2117                             val = *srcpixel++;
2118                             bits[2] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));           /*Red*/
2119                             bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03));            /*Green*/
2120                             bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));            /*Blue*/
2121                         }
2122                   bits = (dstbits += linebytes);
2123                     }
2124                 }
2125             /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2126             else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x1f )
2127                 {
2128                     for (h = lines - 1; h >= 0; h--) {
2129                   srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2130                         for (x = 0; x < srcwidth; x++, bits += 3) {
2131                             val = *srcpixel++;
2132                             bits[0] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));           /*Red*/
2133                             bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03));            /*Green*/
2134                             bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));            /*Blue*/
2135                         }
2136                   bits = (dstbits += linebytes);
2137                     }
2138                 }
2139             else  goto notsupported;
2140             }
2141             break;
2142
2143         case 1:
2144             /* ==== monochrome bitmap to 24 BGR dib ==== */
2145         case 4:
2146             /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2147             if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2148             {
2149                 LPBYTE bits = dstbits;
2150                 PALETTEENTRY val;
2151
2152                 for (h = lines - 1; h >= 0; h--) {
2153                   for (x = 0; x < dstwidth; x++) {
2154                     val = srccolors[XGetPixel(bmpImage, x, h)];
2155                     *bits++ = val.peBlue;
2156                     *bits++ = val.peGreen;
2157                     *bits++ = val.peRed;
2158                   }
2159                   bits = (dstbits += linebytes);
2160                 }
2161             }
2162             else goto notsupported;
2163
2164             break;
2165
2166         case 8:
2167             /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2168             if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors)
2169             {
2170                 BYTE *srcpixel;
2171                 LPBYTE bits = dstbits;
2172                 PALETTEENTRY val;
2173
2174                 for (h = lines - 1; h >= 0; h--) {
2175                   srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2176                   for (x = 0; x < dstwidth; x++ ) {
2177                     val = srccolors[(int)*srcpixel++];
2178                     *bits++ = val.peBlue;               /*Blue*/
2179                     *bits++ = val.peGreen;              /*Green*/
2180                     *bits++ = val.peRed;                /*Red*/
2181                     }
2182                   bits = (dstbits += linebytes);
2183                 }
2184             }
2185             else goto notsupported;
2186
2187             break;
2188
2189         default:
2190         notsupported:
2191             {
2192               LPBYTE bits = dstbits;
2193
2194             FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2195                   bmpImage->depth, (int)bmpImage->red_mask, 
2196                   (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2197               for (h = lines - 1; h >= 0; h--)
2198                 {
2199                   for (x = 0; x < dstwidth; x++, bits += 3)
2200                     {
2201                       COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2202                       bits[0] = GetBValue(pixel);
2203                       bits[1] = GetGValue(pixel);
2204                       bits[2] = GetRValue(pixel);
2205                     }
2206                   bits = (dstbits += linebytes);
2207                 }
2208             }
2209             break;
2210     }
2211 }
2212
2213
2214 /***********************************************************************
2215  *           X11DRV_DIB_SetImageBits_32
2216  *
2217  * SetDIBits for a 32-bit deep DIB.
2218  */
2219 static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
2220                                  DWORD srcwidth, DWORD dstwidth, int left,
2221                                         DC *dc, XImage *bmpImage,
2222                                         DWORD linebytes )
2223 {
2224     DWORD x, *ptr;
2225     int h;
2226   
2227     if (lines < 0 )
2228     {
2229        lines = -lines;
2230        srcbits = srcbits + ( linebytes * (lines-1) );
2231        linebytes = -linebytes;
2232     }
2233
2234     ptr = (DWORD *) srcbits + left;
2235
2236     switch ( bmpImage->depth )
2237     {
2238         case 32:
2239             /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2240             if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) {
2241                 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2242                     memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2243                 }
2244             }
2245
2246             /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2247             else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
2248             {
2249                 DWORD *dstpixel;
2250
2251                 for (h = lines - 1; h >= 0; h--) {
2252                     dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2253                     for (x = 0; x < dstwidth; x++, ptr++) {
2254                         *dstpixel++ =   ((*ptr << 16) & 0xff0000) | (*ptr & 0xff00) | ((*ptr >> 16) & 0xff);
2255                     }
2256                     ptr = (DWORD *) (srcbits += linebytes) + left;
2257                 }
2258             }
2259             else goto notsupported;
2260
2261             break;
2262
2263         case 24:
2264             /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
2265             /* we need to check that source mask matches destination */
2266             if (bmpImage->bits_per_pixel == 32)
2267             {
2268                 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2269                     memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2270                 }
2271             }
2272             else
2273             {
2274                 BYTE  *bptr;
2275
2276                 ptr = (DWORD *) srcbits + left;
2277                 bptr = bmpImage->data;
2278
2279                 for (h = lines - 1; h >= 0; h--) {
2280                     for (x = 0; x < dstwidth; x++) {
2281                          /* *ptr is a 32bit value */
2282                          /* bptr points to first of 3 bytes */
2283                         *bptr++ = (*ptr >> 16) & 0xff;
2284                         *bptr++ = (*ptr >>  8) & 0xff;
2285                         *bptr++ = (*ptr      ) & 0xff;
2286                         ptr++;
2287                     }
2288                     ptr = (DWORD *) (srcbits += linebytes) + left;
2289                 }
2290             }
2291             break;
2292         
2293         case 15:
2294             /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2295             if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f) {
2296                 LPWORD  dstpixel;
2297
2298                 for (h = lines - 1; h >= 0; h--) {
2299                     dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2300                     for (x = 0; x < dstwidth; x++, ptr++) {
2301                         *dstpixel++ = (WORD) (((*ptr >> 9) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 3) & 0x001f));
2302                     }
2303                     ptr = (DWORD *) (srcbits += linebytes) + left;
2304                 }
2305             }
2306             /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2307             else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2308             {
2309                 LPWORD  dstpixel;
2310
2311                 for (h = lines - 1; h >= 0; h--) {
2312                     dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2313                     for (x = 0; x < dstwidth; x++, ptr++) {
2314                         *dstpixel++ = (WORD) (((*ptr << 7) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 19) & 0x001f));
2315                     }
2316                     ptr = (DWORD *) (srcbits += linebytes) + left;
2317                 }
2318             }
2319             else goto notsupported;
2320
2321             break;
2322
2323         case 16:
2324             /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2325             if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2326             {
2327                 LPWORD  dstpixel;
2328
2329                 for (h = lines - 1; h >= 0; h--) {
2330                     dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2331                     for (x = 0; x < dstwidth; x++, ptr++) {
2332                         *dstpixel++ = (WORD) (((*ptr >> 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 3) & 0x001f));
2333                     }
2334                     ptr = (DWORD *) (srcbits += linebytes) + left;
2335                 }
2336             }
2337             /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2338             else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
2339             {
2340                 LPWORD dstpixel;
2341
2342                 for (h = lines - 1; h >= 0; h--) {
2343                     dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2344                     for (x = 0; x < dstwidth; x++, ptr++) {
2345                         *dstpixel++ = (WORD) (((*ptr << 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 19) & 0x001f));
2346                     }
2347                     ptr = (DWORD *) (srcbits += linebytes) + left;
2348                 }
2349             }
2350             else goto notsupported;
2351
2352             break;
2353
2354         case 1:
2355         case 4:
2356         case 8:
2357             {
2358                 LPBYTE bits = (LPBYTE)srcbits + left*4;
2359
2360                 for (h = lines - 1; h >= 0; h--) {
2361                     for (x = left; x < dstwidth+left; x++, bits += 4)
2362                         XPutPixel( bmpImage, x, h,
2363                                    X11DRV_PALETTE_ToPhysical(dc, RGB( bits[2],  bits[1], *bits )));
2364                     bits = (LPBYTE)(srcbits += linebytes) + left * 4;
2365                 }
2366             }
2367             break;
2368
2369        default:
2370        notsupported:
2371             FIXME("32 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
2372             break;
2373     }
2374
2375 }
2376
2377 /***********************************************************************
2378  *           X11DRV_DIB_GetImageBits_32
2379  *
2380  * GetDIBits for an 32-bit deep DIB.
2381  */
2382 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
2383                                         DWORD dstwidth, DWORD srcwidth,
2384                                         PALETTEENTRY *srccolors,
2385                                         XImage *bmpImage, DWORD linebytes )
2386 {
2387     DWORD x;
2388     int h;
2389     BYTE *bits;
2390
2391     DWORD copybytes = srcwidth * 4;
2392
2393     if (lines < 0 )
2394     {
2395         lines = -lines;
2396         dstbits = dstbits + ( linebytes * (lines-1) );
2397         linebytes = -linebytes;
2398     }
2399
2400     bits = dstbits;
2401
2402     switch ( bmpImage->depth )
2403     {
2404         case 32:
2405             /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2406             if ( bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff )
2407                 for (h = lines - 1; h >= 0; h--, dstbits+=linebytes)
2408                     memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, copybytes );
2409
2410             /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2411             else if ( bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000 )
2412             {
2413                 LPBYTE srcbits;
2414
2415                 for (h = lines - 1; h >= 0; h--) {
2416                     srcbits = bmpImage->data + h * bmpImage->bytes_per_line;
2417                     for (x = 0; x < dstwidth; x++, bits+=4, srcbits+=2) {
2418                         *(bits + 2) = *srcbits++;
2419                         *(bits + 1) = *srcbits++;
2420                         *bits = *srcbits;
2421                     }
2422                     bits = (dstbits += linebytes);
2423                 }
2424             }
2425             else goto notsupported;
2426             break;
2427
2428         case 24:
2429             /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */
2430             /* we need to check that source mask matches destination */
2431             {
2432                 DWORD *srcpixel;
2433                 BYTE  *bptr;
2434                 DWORD srcdata;
2435
2436                 srcpixel = (DWORD *) dstbits;
2437                 bptr = bmpImage->data;
2438
2439                 for (h = lines - 1; h >= 0; h--) {
2440                     for (x = 0; x < dstwidth; x++) {
2441                         /* *srcpixel is a 32bit value */
2442                                                 /* bptr points to first of 3 bytes */
2443                         srcdata = 0;
2444                                                 srcdata = srcdata << 8 | *bptr++;
2445                                                 srcdata = srcdata << 8 | *bptr++;       
2446                         srcdata = srcdata << 8 | *bptr++;       
2447
2448                         *srcpixel++ = srcdata;
2449                     }
2450                     srcpixel = (DWORD *) (dstbits += linebytes);
2451                                 }
2452             }
2453             break;
2454
2455         case 15:
2456             {
2457                 LPWORD srcpixel;
2458                 WORD val;
2459
2460             /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2461             if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
2462             {
2463               for (h = lines - 1; h >= 0; h--) {
2464                 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2465                 for (x = 0; x < dstwidth; x++, bits+=2) {
2466                   val = *srcpixel++;
2467                   *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2468                   *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2469                   *bits = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));  /*Red*/
2470                 }
2471                 bits = (dstbits += linebytes);
2472               }
2473             }
2474             /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2475             else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2476             {
2477                 for (h = lines - 1; h >= 0; h--) {
2478                 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2479                 for (x = 0; x < dstwidth; x++, bits+=2) {
2480                         val = *srcpixel++;
2481                   *bits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));/*Blue*/
2482                   *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2483                   *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03));   /*Red*/
2484                 }
2485                 bits = (dstbits += linebytes);
2486                     }
2487                 }
2488             else goto notsupported;
2489             }
2490             break;
2491
2492         case 16:
2493             {
2494                 LPWORD srcpixel;
2495                 WORD val;
2496
2497             /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2498             if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2499             {
2500                 for (h = lines - 1; h >= 0; h--) {
2501                 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2502                 for (x = 0; x < srcwidth; x++, bits+=2) {
2503                         val = *srcpixel++;
2504                   *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2505                   *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2506                   *bits = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));  /*Red*/
2507                 }
2508                 bits = (dstbits += linebytes);
2509               }
2510             }
2511             /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2512             else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2513             {
2514               for (h = lines - 1; h >= 0; h--) {
2515                 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2516                 for (x = 0; x < srcwidth; x++, bits+=2) {
2517                   val = *srcpixel++;
2518                   *bits++ = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));/*Blue*/
2519                   *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2520                   *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03));   /*Red*/
2521                 }
2522                 bits = (dstbits += linebytes);
2523                     }
2524                 }
2525             else goto notsupported;
2526             }
2527             break;
2528
2529         case 1:
2530             /* ==== monochrome bitmap to 32 BGR dib ==== */
2531         case 4:
2532             /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2533             if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2534             {
2535                 PALETTEENTRY val;
2536
2537                 for (h = lines - 1; h >= 0; h--) {
2538                   for (x = 0; x < dstwidth; x++) {
2539                     val = srccolors[XGetPixel(bmpImage, x, h)];
2540                     *bits++ = val.peBlue;
2541                     *bits++ = val.peGreen;
2542                     *bits++ = val.peRed;
2543                     *bits++ = 0;
2544                   }
2545                   bits = (dstbits += linebytes);
2546                 }
2547             }
2548             else goto notsupported;
2549
2550             break;
2551
2552         case 8:
2553             /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2554             if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2555             {
2556                 BYTE *srcpixel;
2557                 PALETTEENTRY val;
2558
2559                 for (h = lines - 1; h >= 0; h--) {
2560                   srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2561                   for (x = 0; x < dstwidth; x++) {
2562                     val = srccolors[(int)*srcpixel++];
2563                     *bits++ = val.peBlue;               /*Blue*/
2564                     *bits++ = val.peGreen;              /*Green*/
2565                     *bits++ = val.peRed;                /*Red*/
2566                     *bits++ = 0;
2567                     }
2568                   bits = (dstbits += linebytes);
2569                 }
2570             }
2571             else goto notsupported;
2572             break;
2573
2574         default:
2575         notsupported:
2576             FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2577                   bmpImage->depth, (int)bmpImage->red_mask, 
2578                   (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2579             for (h = lines - 1; h >= 0; h--)
2580               {
2581                 for (x = 0; x < dstwidth; x++, bits += 4)
2582                   {
2583                     COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2584                     bits[0] = GetBValue(pixel);
2585                     bits[1] = GetGValue(pixel);
2586                     bits[2] = GetRValue(pixel);
2587                   }
2588                 bits = (dstbits += linebytes);
2589               }
2590             break;
2591     }
2592 }
2593
2594 /***********************************************************************
2595  *           X11DRV_DIB_SetImageBits
2596  *
2597  * Transfer the bits to an X image.
2598  * Helper function for SetDIBits() and SetDIBitsToDevice().
2599  */
2600 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2601 {
2602     int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2603     XImage *bmpImage;
2604
2605     wine_tsx11_lock();
2606     if (descr->image)
2607         bmpImage = descr->image;
2608     else {
2609         bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
2610                                  descr->infoWidth, lines, 32, 0 );
2611         bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2612         if(bmpImage->data == NULL) {
2613             ERR("Out of memory!\n");
2614             XDestroyImage( bmpImage );
2615             wine_tsx11_unlock();
2616             return lines;
2617         }
2618     }
2619
2620       /* Transfer the pixels */
2621     switch(descr->infoBpp)
2622     {
2623     case 1:
2624         X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
2625                                    descr->width, descr->xSrc, (int *)(descr->colorMap),
2626                                    bmpImage, descr->dibpitch );
2627         break;
2628     case 4:
2629         if (descr->compression) {
2630             XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
2631                           descr->width, descr->height, AllPlanes, ZPixmap, 
2632                           bmpImage, descr->xSrc, descr->ySrc );
2633
2634             X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
2635                                           descr->infoWidth, descr->width,
2636                                           descr->xSrc, (int *)(descr->colorMap),
2637                                           bmpImage );
2638         } else
2639             X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
2640                                        descr->infoWidth, descr->width,
2641                                        descr->xSrc, (int*)(descr->colorMap),
2642                                        bmpImage, descr->dibpitch );
2643         break;
2644     case 8:
2645         if (descr->compression) {
2646             XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
2647                           descr->width, descr->height, AllPlanes, ZPixmap, 
2648                           bmpImage, descr->xSrc, descr->ySrc );
2649             X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
2650                                           descr->infoWidth, descr->width,
2651                                           descr->xSrc, (int *)(descr->colorMap), 
2652                                           bmpImage );
2653         } else
2654             X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
2655                                        descr->infoWidth, descr->width,
2656                                        descr->xSrc, (int *)(descr->colorMap),
2657                                        bmpImage, descr->dibpitch );
2658         break;
2659     case 15:
2660     case 16:
2661         X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
2662                                     descr->infoWidth, descr->width,
2663                                    descr->xSrc, descr->dc,
2664                                    descr->rMask, descr->gMask, descr->bMask,
2665                                    bmpImage, descr->dibpitch);
2666         break;
2667     case 24:
2668         X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
2669                                     descr->infoWidth, descr->width,
2670                                     descr->xSrc, descr->dc, bmpImage,
2671                                     descr->dibpitch);
2672         break;
2673     case 32:
2674         X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
2675                                     descr->infoWidth, descr->width,
2676                                    descr->xSrc, descr->dc,
2677                                    bmpImage, descr->dibpitch);
2678         break;
2679     default:
2680         WARN("(%d): Invalid depth\n", descr->infoBpp );
2681         break;
2682     }
2683
2684     TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
2685      descr->drawable, descr->gc, bmpImage,
2686      descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2687      descr->width, descr->height);
2688 #ifdef HAVE_LIBXXSHM
2689     if (descr->useShm)
2690     {
2691         XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
2692                       descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2693                       descr->width, descr->height, FALSE );
2694         XSync( gdi_display, 0 );
2695     }
2696     else
2697 #endif
2698         XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
2699                    descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2700                    descr->width, descr->height );
2701
2702     if (!descr->image) XDestroyImage( bmpImage );
2703     wine_tsx11_unlock();
2704     return lines;
2705 }
2706
2707 /***********************************************************************
2708  *           X11DRV_DIB_GetImageBits
2709  *
2710  * Transfer the bits from an X image.
2711  */
2712 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2713 {
2714     int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2715     XImage *bmpImage;
2716
2717     wine_tsx11_lock(); 
2718    if (descr->image)
2719         bmpImage = descr->image;
2720     else {
2721         bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
2722                                  descr->infoWidth, lines, 32, 0 );
2723         bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2724         if(bmpImage->data == NULL) {
2725             ERR("Out of memory!\n");
2726             XDestroyImage( bmpImage );
2727             wine_tsx11_unlock();
2728             return lines;
2729         }
2730     }
2731
2732     TRACE("XGetSubImage(%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
2733      descr->drawable, descr->xSrc, descr->ySrc, descr->width,
2734      lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
2735     XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
2736                   descr->width, lines, AllPlanes, ZPixmap,
2737                   bmpImage, descr->xDest, descr->yDest );
2738
2739       /* Transfer the pixels */
2740     switch(descr->infoBpp)
2741     {
2742     case 1:
2743           X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits, 
2744                                      descr->infoWidth, descr->width,
2745                                      descr->colorMap, descr->palentry, 
2746                                      bmpImage, descr->dibpitch );
2747        break;
2748
2749     case 4:
2750        if (descr->compression)
2751            FIXME("Compression not yet supported!\n");
2752        else
2753            X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits, 
2754                                       descr->infoWidth, descr->width, 
2755                                       descr->colorMap, descr->palentry, 
2756                                       bmpImage, descr->dibpitch );
2757        break;
2758
2759     case 8:
2760        if (descr->compression)
2761            FIXME("Compression not yet supported!\n");
2762        else
2763            X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
2764                                       descr->infoWidth, descr->width,
2765                                       descr->colorMap, descr->palentry,
2766                                       bmpImage, descr->dibpitch );
2767        break;
2768     case 15:
2769     case 16:
2770        X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
2771                                    descr->infoWidth,descr->width,
2772                                    descr->palentry,
2773                                    descr->rMask, descr->gMask, descr->bMask,
2774                                    bmpImage, descr->dibpitch );
2775        break;
2776
2777     case 24:
2778        X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
2779                                    descr->infoWidth,descr->width,
2780                                    descr->palentry, bmpImage, descr->dibpitch);
2781        break;
2782
2783     case 32:
2784        X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
2785                                    descr->infoWidth, descr->width,
2786                                    descr->palentry, bmpImage, descr->dibpitch);
2787        break;
2788
2789     default:
2790         WARN("(%d): Invalid depth\n", descr->infoBpp );
2791         break;
2792     }
2793
2794     if (!descr->image) XDestroyImage( bmpImage );
2795     wine_tsx11_unlock();
2796     return lines;
2797 }
2798
2799 /*************************************************************************
2800  *              X11DRV_SetDIBitsToDevice
2801  *
2802  */
2803 INT X11DRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx,
2804                                 DWORD cy, INT xSrc, INT ySrc,
2805                                 UINT startscan, UINT lines, LPCVOID bits,
2806                                 const BITMAPINFO *info, UINT coloruse )
2807 {
2808     X11DRV_DIB_IMAGEBITS_DESCR descr;
2809     DWORD width, oldcy = cy;
2810     INT result;
2811     int height, tmpheight;
2812     X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
2813
2814
2815     if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, 
2816                            &descr.infoBpp, &descr.compression ) == -1)
2817         return 0;
2818     tmpheight = height;
2819     if (height < 0) height = -height;
2820     if (!lines || (startscan >= height)) return 0;
2821     if (startscan + lines > height) lines = height - startscan;
2822     if (ySrc < startscan) ySrc = startscan;
2823     else if (ySrc >= startscan + lines) return 0;
2824     if (xSrc >= width) return 0;
2825     if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
2826     if (xSrc + cx >= width) cx = width - xSrc;
2827     if (!cx || !cy) return 0;
2828
2829     X11DRV_SetupGCForText( dc );  /* To have the correct colors */
2830     TSXSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);
2831
2832     switch (descr.infoBpp)
2833     {
2834        case 1:
2835        case 4:
2836        case 8:
2837                descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap( 
2838                                             coloruse == DIB_PAL_COLORS ? dc : NULL, coloruse,
2839                                             dc->bitsPerPixel, info, &descr.nColorMap );
2840                if (!descr.colorMap) return 0;
2841                descr.rMask = descr.gMask = descr.bMask = 0;
2842                break;
2843        case 15:
2844        case 16:
2845                descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2846                descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0x03e0;
2847                descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0x001f;
2848                descr.colorMap = 0;
2849                break;
2850
2851        case 24:
2852                descr.rMask = descr.gMask = descr.bMask = 0;
2853                descr.colorMap = 0;
2854                break;
2855
2856        case 32:
2857                descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2858                descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0xff00;
2859                descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0xff;
2860                descr.colorMap = 0;
2861                break;
2862     }
2863
2864     descr.dc        = dc;
2865     descr.bits      = bits;
2866     descr.image     = NULL;
2867     descr.palentry  = NULL;
2868     descr.lines     = tmpheight >= 0 ? lines : -lines;
2869     descr.infoWidth = width;
2870     descr.depth     = dc->bitsPerPixel;
2871     descr.drawable  = physDev->drawable;
2872     descr.gc        = physDev->gc;
2873     descr.xSrc      = xSrc;
2874     descr.ySrc      = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy) 
2875                                      : ySrc - startscan;
2876     descr.xDest     = dc->DCOrgX + XLPTODP( dc, xDest );
2877     descr.yDest     = dc->DCOrgY + YLPTODP( dc, yDest ) +
2878                                      (tmpheight >= 0 ? oldcy-cy : 0);
2879     descr.width     = cx;
2880     descr.height    = cy;
2881     descr.useShm    = FALSE;
2882     descr.dibpitch  = ((width * descr.infoBpp + 31) &~31) / 8;
2883
2884     result = X11DRV_DIB_SetImageBits( &descr );
2885
2886     if (descr.infoBpp <= 8)
2887        HeapFree(GetProcessHeap(), 0, descr.colorMap);
2888     return result;
2889 }
2890
2891 /***********************************************************************
2892  *           X11DRV_DIB_SetDIBits
2893  */
2894 INT X11DRV_DIB_SetDIBits(
2895   BITMAPOBJ *bmp, DC *dc, UINT startscan,
2896   UINT lines, LPCVOID bits, const BITMAPINFO *info,
2897   UINT coloruse, HBITMAP hbitmap)
2898 {
2899   X11DRV_DIB_IMAGEBITS_DESCR descr;
2900   int height, tmpheight;
2901   INT result;
2902
2903   descr.dc = dc;
2904
2905   if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
2906                          &descr.infoBpp, &descr.compression ) == -1)
2907       return 0;
2908
2909   tmpheight = height;
2910   if (height < 0) height = -height;
2911   if (!lines || (startscan >= height))
2912       return 0;
2913
2914   if (startscan + lines > height) lines = height - startscan;
2915
2916   switch (descr.infoBpp)
2917   {
2918        case 1:
2919        case 4:
2920        case 8:
2921                descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
2922                         coloruse == DIB_PAL_COLORS ? descr.dc : NULL, coloruse,
2923                                                           bmp->bitmap.bmBitsPixel,
2924                                                           info, &descr.nColorMap );
2925                if (!descr.colorMap) return 0;
2926                descr.rMask = descr.gMask = descr.bMask = 0;
2927                break;
2928        case 15:
2929        case 16:
2930                descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2931                descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0x03e0;
2932                descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0x001f;
2933                descr.colorMap = 0;
2934                break;
2935
2936        case 24:
2937                descr.rMask = descr.gMask = descr.bMask = 0;
2938                descr.colorMap = 0;
2939                break;
2940
2941        case 32:
2942                descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2943                descr.gMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0xff00;
2944                descr.bMask = (descr.compression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 2) : 0xff;
2945                descr.colorMap = 0;
2946                break;
2947
2948        default: break;
2949   }
2950
2951   /* HACK for now */
2952   if(!bmp->physBitmap)
2953     X11DRV_CreateBitmap(hbitmap);
2954
2955   descr.bits      = bits;
2956   descr.image     = NULL;
2957   descr.palentry  = NULL;
2958   descr.lines     = tmpheight >= 0 ? lines : -lines;
2959   descr.depth     = bmp->bitmap.bmBitsPixel;
2960   descr.drawable  = (Pixmap)bmp->physBitmap;
2961   descr.gc        = BITMAP_GC(bmp);
2962   descr.xSrc      = 0;
2963   descr.ySrc      = 0;
2964   descr.xDest     = 0;
2965   descr.yDest     = height - startscan - lines;
2966   descr.width     = bmp->bitmap.bmWidth;
2967   descr.height    = lines;
2968   descr.useShm    = FALSE;
2969   descr.dibpitch  = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
2970   result = X11DRV_DIB_SetImageBits( &descr );
2971
2972   if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
2973
2974   return result;
2975 }
2976
2977 /***********************************************************************
2978  *           X11DRV_DIB_GetDIBits
2979  */
2980 INT X11DRV_DIB_GetDIBits(
2981   BITMAPOBJ *bmp, DC *dc, UINT startscan, 
2982   UINT lines, LPVOID bits, BITMAPINFO *info,
2983   UINT coloruse, HBITMAP hbitmap)
2984 {
2985   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
2986   X11DRV_DIB_IMAGEBITS_DESCR descr;
2987   PALETTEOBJ * palette;
2988   int height;
2989   
2990   TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
2991         lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
2992         (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
2993         startscan );
2994
2995   if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
2996       return 0;
2997
2998   if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
2999
3000   height = info->bmiHeader.biHeight;
3001   if (height < 0) height = -height;
3002   if( lines > height ) lines = height;
3003   /* Top-down images have a negative biHeight, the scanlines of theses images
3004    * were inverted in X11DRV_DIB_GetImageBits_xx
3005    * To prevent this we simply change the sign of lines
3006    * (the number of scan lines to copy).
3007    * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3008    */
3009   if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
3010
3011   if( startscan >= bmp->bitmap.bmHeight )
3012   {
3013       lines = 0;
3014       goto done;
3015   }
3016   
3017   if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
3018                         &descr.infoBpp, &descr.compression ) == -1)
3019   {
3020       lines = 0;
3021       goto done;
3022   }
3023
3024   switch (descr.infoBpp)
3025   {
3026       case 1:
3027       case 4:
3028       case 8:
3029       case 24:
3030           descr.rMask = descr.gMask = descr.bMask = 0;
3031           break;
3032       case 15:
3033       case 16:
3034           descr.rMask = 0x7c00;
3035           descr.gMask = 0x03e0;
3036           descr.bMask = 0x001f;
3037           break;
3038   
3039       case 32:
3040           descr.rMask = 0xff0000;
3041           descr.gMask = 0xff00;
3042           descr.bMask = 0xff;
3043           break;
3044   }
3045
3046   /* Hack for now */
3047   if(!bmp->physBitmap)
3048     X11DRV_CreateBitmap(hbitmap);
3049
3050
3051   descr.dc        = dc;
3052   descr.palentry  = palette->logpalette.palPalEntry;
3053   descr.bits      = bits;
3054   descr.image     = NULL;
3055   descr.lines     = lines;
3056   descr.depth     = bmp->bitmap.bmBitsPixel;
3057   descr.drawable  = (Pixmap)bmp->physBitmap;
3058   descr.gc        = BITMAP_GC(bmp);
3059   descr.width     = bmp->bitmap.bmWidth;
3060   descr.height    = bmp->bitmap.bmHeight;
3061   descr.colorMap  = info->bmiColors;
3062   descr.xDest     = 0;
3063   descr.yDest     = 0;
3064   descr.xSrc      = 0;
3065   
3066   if (descr.lines > 0)
3067   {
3068      descr.ySrc = (descr.height-1) - (startscan + (lines-1));
3069   }
3070   else
3071   {
3072      descr.ySrc = startscan;
3073   }
3074 #ifdef HAVE_LIBXXSHM
3075   descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
3076 #else
3077   descr.useShm = FALSE;
3078 #endif
3079   descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
3080                        : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
3081
3082   X11DRV_DIB_GetImageBits( &descr );
3083
3084   if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
3085       info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
3086                                          info->bmiHeader.biWidth,
3087                                          info->bmiHeader.biHeight,
3088                                          info->bmiHeader.biBitCount );
3089
3090   info->bmiHeader.biCompression = 0;
3091   if (descr.compression == BI_BITFIELDS)
3092   {
3093     *(DWORD *)info->bmiColors = descr.rMask;
3094     *((DWORD *)info->bmiColors+1) = descr.gMask;
3095     *((DWORD *)info->bmiColors+2) = descr.bMask;
3096   }
3097
3098 done:
3099   GDI_ReleaseObj( dc->hPalette );
3100  
3101   return lines;
3102 }
3103
3104 /***********************************************************************
3105  *           DIB_DoProtectDIBSection
3106  */
3107 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
3108 {
3109     DIBSECTION *dib = bmp->dib;
3110     INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
3111                                              : -dib->dsBm.bmHeight;
3112     /* use the biSizeImage data as the memory size only if we're dealing with a
3113        compressed image where the value is set.  Otherwise, calculate based on
3114        width * height */
3115     INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
3116                          ? dib->dsBmih.biSizeImage
3117                          : dib->dsBm.bmWidthBytes * effHeight;
3118     DWORD old_prot;
3119
3120     VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
3121     TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
3122 }
3123
3124 /***********************************************************************
3125  *           X11DRV_DIB_DoUpdateDIBSection
3126  */
3127 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
3128                                         void *colorMap, int nColorMap,
3129                                         Drawable dest,
3130                                         DWORD xSrc, DWORD ySrc,
3131                                         DWORD xDest, DWORD yDest,
3132                                         DWORD width, DWORD height)
3133 {
3134   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3135   X11DRV_DIB_IMAGEBITS_DESCR descr;
3136   
3137   if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
3138                          &descr.infoBpp, &descr.compression ) == -1)
3139     return;
3140
3141   descr.dc        = NULL;
3142   descr.palentry  = NULL;
3143   descr.image     = dib->image;
3144   descr.colorMap  = colorMap;
3145   descr.nColorMap = nColorMap;
3146   descr.bits      = dib->dibSection.dsBm.bmBits;
3147   descr.depth     = bmp->bitmap.bmBitsPixel;
3148   
3149   switch (descr.infoBpp)
3150   {
3151     case 1:
3152     case 4:
3153     case 8:
3154     case 24:
3155       descr.rMask = descr.gMask = descr.bMask = 0;
3156       break;
3157     case 15:
3158     case 16:
3159       descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
3160       descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
3161       descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
3162       break;
3163
3164     case 32:
3165       descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff;
3166       descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0xff00;
3167       descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0xff0000;
3168       break;
3169   }
3170
3171   /* Hack for now */
3172   descr.drawable  = dest;
3173   descr.gc        = BITMAP_GC(bmp);
3174   descr.xSrc      = xSrc;
3175   descr.ySrc      = ySrc;
3176   descr.xDest     = xDest;
3177   descr.yDest     = yDest;
3178   descr.width     = width;
3179   descr.height    = height;
3180 #ifdef HAVE_LIBXXSHM
3181   descr.useShm = (dib->shminfo.shmid != -1);
3182 #else
3183   descr.useShm = FALSE;
3184 #endif
3185   descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
3186
3187   if (toDIB)
3188     {
3189       TRACE("Copying from Pixmap to DIB bits\n");
3190       X11DRV_DIB_GetImageBits( &descr );
3191     }
3192   else
3193     {
3194       TRACE("Copying from DIB bits to Pixmap\n"); 
3195       X11DRV_DIB_SetImageBits( &descr );
3196     }
3197 }
3198
3199 /***********************************************************************
3200  *           X11DRV_DIB_CopyDIBSection
3201  */
3202 void X11DRV_DIB_CopyDIBSection(DC *dcSrc, DC *dcDst,
3203                                DWORD xSrc, DWORD ySrc,
3204                                DWORD xDest, DWORD yDest,
3205                                DWORD width, DWORD height)
3206 {
3207   BITMAPOBJ *bmp;
3208   X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcDst->physDev;
3209   int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
3210
3211   TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst,
3212     xSrc, ySrc, xDest, yDest, width, height);
3213   /* this function is meant as an optimization for BitBlt,
3214    * not to be called otherwise */
3215   if (!(dcSrc->flags & DC_MEMORY)) {
3216     ERR("called for non-memory source DC!?\n");
3217     return;
3218   }
3219
3220   bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC );
3221   if (!(bmp && bmp->dib)) {
3222     ERR("called for non-DIBSection!?\n");
3223     GDI_ReleaseObj( dcSrc->hBitmap );
3224     return;
3225   }
3226   /* while BitBlt should already have made sure we only get
3227    * positive values, we should check for oversize values */
3228   if ((xSrc < bmp->bitmap.bmWidth) &&
3229       (ySrc < bmp->bitmap.bmHeight)) {
3230     if (xSrc + width > bmp->bitmap.bmWidth)
3231       width = bmp->bitmap.bmWidth - xSrc;
3232     if (ySrc + height > bmp->bitmap.bmHeight)
3233       height = bmp->bitmap.bmHeight - ySrc;
3234     /* if the source bitmap is 8bpp or less, we're supposed to use the
3235      * DC's palette for color conversion (not the DIB color table) */
3236     if (bmp->dib->dsBm.bmBitsPixel <= 8) {
3237       X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3238       if ((!dcSrc->hPalette) ||
3239           (dcSrc->hPalette == GetStockObject(DEFAULT_PALETTE))) {
3240         /* HACK: no palette has been set in the source DC,
3241          * use the DIB colormap instead - this is necessary in some
3242          * cases since we need to do depth conversion in some places
3243          * where real Windows can just copy data straight over */
3244         colorMap = dib->colorMap;
3245         nColorMap = dib->nColorMap;
3246       } else {
3247         colorMap = X11DRV_DIB_BuildColorMap( dcSrc, (WORD)-1,
3248                                              bmp->dib->dsBm.bmBitsPixel,
3249                                              (BITMAPINFO*)&(bmp->dib->dsBmih),
3250                                              &nColorMap );
3251         if (colorMap) aColorMap = TRUE;
3252       }
3253     }
3254     /* perform the copy */
3255     X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
3256                                 physDev->drawable, xSrc, ySrc, xDest, yDest,
3257                                 width, height);
3258     /* free color mapping */
3259     if (aColorMap)
3260       HeapFree(GetProcessHeap(), 0, colorMap);
3261   }
3262   GDI_ReleaseObj( dcSrc->hBitmap );
3263 }
3264
3265 /***********************************************************************
3266  *           X11DRV_DIB_DoUpdateDIBSection
3267  */
3268 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
3269 {
3270   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3271   X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
3272                               (Drawable)bmp->physBitmap, 0, 0, 0, 0,
3273                               bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
3274 }
3275
3276 /***********************************************************************
3277  *           X11DRV_DIB_FaultHandler
3278  */
3279 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
3280 {
3281   BITMAPOBJ *bmp;
3282   INT state;
3283   
3284   bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
3285   if (!bmp) return FALSE;
3286
3287   state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
3288   if (state != DIB_Status_InSync) {
3289     /* no way to tell whether app needs read or write yet,
3290      * try read first */
3291     X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
3292   } else {
3293     /* hm, apparently the app must have write access */
3294     X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
3295   }
3296   X11DRV_DIB_Unlock(bmp, TRUE);
3297
3298   GDI_ReleaseObj( (HBITMAP)res );
3299   return TRUE;
3300 }
3301
3302 /***********************************************************************
3303  *           X11DRV_DIB_Coerce
3304  */
3305 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
3306 {
3307   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3308   INT ret = DIB_Status_None;
3309
3310   if (dib) {
3311     EnterCriticalSection(&(dib->lock));
3312     ret = dib->status;
3313     switch (req) {
3314     case DIB_Status_GdiMod:
3315       /* GDI access - request to draw on pixmap */
3316       switch (dib->status)
3317       {
3318         default:
3319         case DIB_Status_None:
3320           dib->p_status = DIB_Status_GdiMod;
3321           X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3322           break;
3323
3324         case DIB_Status_GdiMod:
3325           TRACE("GdiMod requested in status GdiMod\n" );
3326           break;
3327
3328         case DIB_Status_InSync:
3329           TRACE("GdiMod requested in status InSync\n" );
3330           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3331           dib->status = DIB_Status_GdiMod;
3332           dib->p_status = DIB_Status_InSync;
3333           break;
3334
3335         case DIB_Status_AuxMod:
3336           TRACE("GdiMod requested in status AuxMod\n" );
3337           if (lossy) dib->status = DIB_Status_GdiMod;
3338           else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
3339           dib->p_status = DIB_Status_AuxMod;
3340           if (dib->status != DIB_Status_AppMod) {
3341             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3342             break;
3343           }
3344           /* fall through if copy_aux() had to change to AppMod state */
3345
3346         case DIB_Status_AppMod:
3347           TRACE("GdiMod requested in status AppMod\n" );
3348           if (!lossy) {
3349             /* make it readonly to avoid app changing data while we copy */
3350             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3351             X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3352           }
3353           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3354           dib->p_status = DIB_Status_AppMod;
3355           dib->status = DIB_Status_GdiMod;
3356           break;
3357       }
3358       break;
3359
3360     case DIB_Status_InSync:
3361       /* App access - request access to read DIB surface */
3362       /* (typically called from signal handler) */
3363       switch (dib->status)
3364       {
3365         default:
3366         case DIB_Status_None:
3367           /* shouldn't happen from signal handler */
3368           break;
3369
3370         case DIB_Status_AuxMod:
3371           TRACE("InSync requested in status AuxMod\n" );
3372           if (lossy) dib->status = DIB_Status_InSync;
3373           else {
3374             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3375             (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
3376           }
3377           if (dib->status != DIB_Status_GdiMod) {
3378             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3379             break;
3380           }
3381           /* fall through if copy_aux() had to change to GdiMod state */
3382
3383         case DIB_Status_GdiMod:
3384           TRACE("InSync requested in status GdiMod\n" );
3385           if (!lossy) {
3386             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3387             X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3388           }
3389           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3390           dib->status = DIB_Status_InSync;
3391           break;
3392
3393         case DIB_Status_InSync:
3394           TRACE("InSync requested in status InSync\n" );
3395           /* shouldn't happen from signal handler */
3396           break;
3397
3398         case DIB_Status_AppMod:
3399           TRACE("InSync requested in status AppMod\n" );
3400           /* no reason to do anything here, and this
3401            * shouldn't happen from signal handler */
3402           break;
3403       }
3404       break;
3405
3406     case DIB_Status_AppMod:
3407       /* App access - request access to write DIB surface */
3408       /* (typically called from signal handler) */
3409       switch (dib->status)
3410       {
3411         default:
3412         case DIB_Status_None:
3413           /* shouldn't happen from signal handler */
3414           break;
3415
3416         case DIB_Status_AuxMod:
3417           TRACE("AppMod requested in status AuxMod\n" );
3418           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3419           if (lossy) dib->status = DIB_Status_AppMod;
3420           else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
3421           if (dib->status != DIB_Status_GdiMod)
3422             break;
3423           /* fall through if copy_aux() had to change to GdiMod state */
3424
3425         case DIB_Status_GdiMod:
3426           TRACE("AppMod requested in status GdiMod\n" );
3427           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3428           if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3429           dib->status = DIB_Status_AppMod;
3430           break;
3431
3432         case DIB_Status_InSync:
3433           TRACE("AppMod requested in status InSync\n" );
3434           X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3435           dib->status = DIB_Status_AppMod;
3436           break;
3437
3438         case DIB_Status_AppMod:
3439           TRACE("AppMod requested in status AppMod\n" );
3440           /* shouldn't happen from signal handler */
3441           break;
3442       }
3443       break;
3444
3445     case DIB_Status_AuxMod:
3446       if (dib->status == DIB_Status_None) {
3447         dib->p_status = req;
3448       } else {
3449         if (dib->status != DIB_Status_AuxMod)
3450           dib->p_status = dib->status;
3451         dib->status = DIB_Status_AuxMod;
3452       }
3453       break;
3454       /* it is up to the caller to do the copy/conversion, probably
3455        * using the return value to decide where to copy from */
3456     }
3457     LeaveCriticalSection(&(dib->lock));
3458   }
3459   return ret;
3460 }
3461
3462 /***********************************************************************
3463  *           X11DRV_DIB_Lock
3464  */
3465 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
3466 {
3467   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3468   INT ret = DIB_Status_None;
3469
3470   if (dib) {
3471     TRACE("Locking %p from thread %08lx\n", bmp, GetCurrentThreadId());
3472     EnterCriticalSection(&(dib->lock));
3473     ret = dib->status;
3474     if (req != DIB_Status_None)
3475       X11DRV_DIB_Coerce(bmp, req, lossy);
3476   }
3477   return ret;
3478 }
3479
3480 /***********************************************************************
3481  *           X11DRV_DIB_Unlock
3482  */
3483 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
3484 {
3485   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3486
3487   if (dib) {
3488     switch (dib->status)
3489     {
3490       default:
3491       case DIB_Status_None:
3492         /* in case anyone is wondering, this is the "signal handler doesn't
3493          * work" case, where we always have to be ready for app access */
3494         if (commit) {
3495           switch (dib->p_status)
3496           {
3497             case DIB_Status_AuxMod:
3498               TRACE("Unlocking and syncing from AuxMod\n" );
3499               (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
3500               if (dib->status != DIB_Status_None) {
3501                 dib->p_status = dib->status;
3502                 dib->status = DIB_Status_None;
3503               }
3504               if (dib->p_status != DIB_Status_GdiMod)
3505                 break;
3506               /* fall through if copy_aux() had to change to GdiMod state */
3507
3508             case DIB_Status_GdiMod:
3509               TRACE("Unlocking and syncing from GdiMod\n" );
3510               X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3511               break;
3512
3513             default:
3514               TRACE("Unlocking without needing to sync\n" );
3515               break;
3516           }
3517         }
3518         else TRACE("Unlocking with no changes\n");
3519         dib->p_status = DIB_Status_None;
3520         break;
3521
3522       case DIB_Status_GdiMod:
3523         TRACE("Unlocking in status GdiMod\n" );
3524         /* DIB was protected in Coerce */
3525         if (!commit) {
3526           /* no commit, revert to InSync if applicable */
3527           if ((dib->p_status == DIB_Status_InSync) ||
3528               (dib->p_status == DIB_Status_AppMod)) {
3529             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3530             dib->status = DIB_Status_InSync;
3531           }
3532         }
3533         break;
3534
3535       case DIB_Status_InSync:
3536         TRACE("Unlocking in status InSync\n" );
3537         /* DIB was already protected in Coerce */
3538         break;
3539
3540       case DIB_Status_AppMod:
3541         TRACE("Unlocking in status AppMod\n" );
3542         /* DIB was already protected in Coerce */
3543         /* this case is ordinary only called from the signal handler,
3544          * so we don't bother to check for !commit */
3545         break;
3546
3547       case DIB_Status_AuxMod:
3548         TRACE("Unlocking in status AuxMod\n" );
3549         if (commit) {
3550           /* DIB may need protection now */
3551           if ((dib->p_status == DIB_Status_InSync) ||
3552               (dib->p_status == DIB_Status_AppMod))
3553             X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3554         } else {
3555           /* no commit, revert to previous state */
3556           if (dib->p_status != DIB_Status_None)
3557             dib->status = dib->p_status;
3558           /* no protections changed */
3559         }
3560         dib->p_status = DIB_Status_None;
3561         break;
3562     }
3563     LeaveCriticalSection(&(dib->lock));
3564     TRACE("Unlocked %p\n", bmp);
3565   }
3566 }
3567
3568 /***********************************************************************
3569  *           X11DRV_CoerceDIBSection2
3570  */
3571 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
3572 {
3573   BITMAPOBJ *bmp;
3574   INT ret;
3575
3576   bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3577   if (!bmp) return DIB_Status_None;
3578   ret = X11DRV_DIB_Coerce(bmp, req, lossy);
3579   GDI_ReleaseObj( hBmp );
3580   return ret;
3581 }
3582
3583 /***********************************************************************
3584  *           X11DRV_LockDIBSection2
3585  */
3586 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
3587 {
3588   BITMAPOBJ *bmp;
3589   INT ret;
3590
3591   bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3592   if (!bmp) return DIB_Status_None;
3593   ret = X11DRV_DIB_Lock(bmp, req, lossy);
3594   GDI_ReleaseObj( hBmp );
3595   return ret;
3596 }
3597
3598 /***********************************************************************
3599  *           X11DRV_UnlockDIBSection2
3600  */
3601 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
3602 {
3603   BITMAPOBJ *bmp;
3604
3605   bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3606   if (!bmp) return;
3607   X11DRV_DIB_Unlock(bmp, commit);
3608   GDI_ReleaseObj( hBmp );
3609 }
3610
3611 /***********************************************************************
3612  *           X11DRV_CoerceDIBSection
3613  */
3614 INT X11DRV_CoerceDIBSection(DC *dc, INT req, BOOL lossy)
3615 {
3616   if (!dc) return DIB_Status_None;
3617   return X11DRV_CoerceDIBSection2( dc->hBitmap, req, lossy );
3618 }
3619
3620 /***********************************************************************
3621  *           X11DRV_LockDIBSection
3622  */
3623 INT X11DRV_LockDIBSection(DC *dc, INT req, BOOL lossy)
3624 {
3625   if (!dc) return DIB_Status_None;
3626   if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;
3627
3628   return X11DRV_LockDIBSection2( dc->hBitmap, req, lossy );
3629 }
3630
3631 /***********************************************************************
3632  *           X11DRV_UnlockDIBSection
3633  */
3634 void X11DRV_UnlockDIBSection(DC *dc, BOOL commit)
3635 {
3636   if (!dc) return;
3637   if (!(dc->flags & DC_MEMORY)) return;
3638
3639   X11DRV_UnlockDIBSection2( dc->hBitmap, commit );
3640 }
3641
3642
3643 #ifdef HAVE_LIBXXSHM
3644 /***********************************************************************
3645  *           X11DRV_XShmErrorHandler
3646  *
3647  */
3648 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) 
3649 {
3650     XShmErrorFlag = 1;
3651     return 0;
3652 }
3653
3654 /***********************************************************************
3655  *           X11DRV_XShmCreateImage
3656  *
3657  */
3658 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
3659                                        XShmSegmentInfo* shminfo)
3660 {
3661     int (*WineXHandler)(Display *, XErrorEvent *);
3662     XImage *image;
3663
3664     wine_tsx11_lock();
3665     image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
3666     if (image)
3667     {
3668         shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
3669                                   IPC_CREAT|0700);
3670         if( shminfo->shmid != -1 )
3671         {
3672             shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
3673             if( shminfo->shmaddr != (char*)-1 )
3674             {
3675                 shminfo->readOnly = FALSE;
3676                 if( XShmAttach( gdi_display, shminfo ) != 0)
3677                 {
3678                     /* Reset the error flag */
3679                     XShmErrorFlag = 0;
3680                     WineXHandler = XSetErrorHandler(XShmErrorHandler);
3681                     XSync( gdi_display, 0 );
3682
3683                     if (!XShmErrorFlag)
3684                     {
3685                         shmctl(shminfo->shmid, IPC_RMID, 0);
3686
3687                         XSetErrorHandler(WineXHandler);
3688                         wine_tsx11_unlock();
3689                         return image; /* Success! */
3690                     }
3691                     /* An error occured */
3692                     XShmErrorFlag = 0;
3693                     XSetErrorHandler(WineXHandler);
3694                 }
3695                 shmdt(shminfo->shmaddr);
3696             }
3697             shmctl(shminfo->shmid, IPC_RMID, 0);
3698         }
3699         XFlush(gdi_display);
3700         XDestroyImage(image);
3701         image = NULL;
3702     }
3703     wine_tsx11_unlock();
3704     return image;
3705 }
3706 #endif /* HAVE_LIBXXSHM */
3707
3708
3709 /***********************************************************************
3710  *           X11DRV_DIB_CreateDIBSection
3711  */
3712 HBITMAP X11DRV_DIB_CreateDIBSection(
3713   DC *dc, BITMAPINFO *bmi, UINT usage,
3714   LPVOID *bits, HANDLE section,
3715   DWORD offset, DWORD ovr_pitch)
3716 {
3717   HBITMAP res = 0;
3718   BITMAPOBJ *bmp = NULL;
3719   X11DRV_DIBSECTION *dib = NULL;
3720   int *colorMap = NULL;
3721   int nColorMap;
3722   
3723   /* Fill BITMAP32 structure with DIB data */
3724   BITMAPINFOHEADER *bi = &bmi->bmiHeader;
3725   INT effHeight, totalSize;
3726   BITMAP bm;
3727   LPVOID mapBits = NULL;
3728   
3729   TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3730         bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
3731         bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
3732   
3733   effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
3734   bm.bmType = 0;
3735   bm.bmWidth = bi->biWidth;
3736   bm.bmHeight = effHeight;
3737   bm.bmWidthBytes = ovr_pitch ? ovr_pitch
3738                               : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
3739   bm.bmPlanes = bi->biPlanes;
3740   bm.bmBitsPixel = bi->biBitCount;
3741   bm.bmBits = NULL;
3742   
3743   /* Get storage location for DIB bits.  Only use biSizeImage if it's valid and
3744      we're dealing with a compressed bitmap.  Otherwise, use width * height. */
3745   totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
3746     ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
3747   
3748   if (section)
3749   {
3750       SYSTEM_INFO SystemInfo;
3751       DWORD mapOffset;
3752       INT mapSize;
3753
3754       GetSystemInfo( &SystemInfo );
3755       mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
3756       mapSize = totalSize + (offset - mapOffset);
3757       mapBits = MapViewOfFile( section,
3758                                FILE_MAP_ALL_ACCESS, 
3759                                0L,
3760                                mapOffset,
3761                                mapSize );
3762       bm.bmBits = (char *)mapBits + (offset - mapOffset);
3763   }
3764   else if (ovr_pitch && offset)
3765     bm.bmBits = (LPVOID) offset;
3766   else {
3767     offset = 0;
3768     bm.bmBits = VirtualAlloc(NULL, totalSize, 
3769                              MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
3770   }
3771   
3772   /* Create Color Map */
3773   if (bm.bmBits && bm.bmBitsPixel <= 8)
3774       colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? dc : NULL, 
3775                                 usage, bm.bmBitsPixel, bmi, &nColorMap );
3776
3777   /* Allocate Memory for DIB and fill structure */
3778   if (bm.bmBits)
3779     dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
3780   if (dib)
3781     {
3782       dib->dibSection.dsBm = bm;
3783       dib->dibSection.dsBmih = *bi;
3784       dib->dibSection.dsBmih.biSizeImage = totalSize;
3785
3786       /* Set dsBitfields values */
3787        if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
3788        {
3789            dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
3790        }
3791        else switch( bi->biBitCount )
3792        {
3793            case 16:
3794                dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
3795                dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
3796                dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
3797                break;
3798
3799            case 24:
3800                dib->dibSection.dsBitfields[0] = 0xff;
3801                dib->dibSection.dsBitfields[1] = 0xff00;
3802                dib->dibSection.dsBitfields[2] = 0xff0000;
3803                break;
3804
3805            case 32:
3806                dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
3807                dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
3808                dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
3809                break;
3810        }
3811       dib->dibSection.dshSection = section;
3812       dib->dibSection.dsOffset = offset;
3813       
3814       dib->status    = DIB_Status_None;
3815       dib->nColorMap = nColorMap;
3816       dib->colorMap  = colorMap;
3817     }
3818   
3819   /* Create Device Dependent Bitmap and add DIB pointer */
3820   if (dib) 
3821     {
3822       res = CreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
3823       if (res)
3824         {
3825           bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3826           if (bmp)
3827             {
3828               bmp->dib = (DIBSECTION *) dib;
3829               /* HACK for now */
3830               if(!bmp->physBitmap)
3831                 X11DRV_CreateBitmap(res); 
3832             }
3833         }
3834     }
3835   
3836   /* Create XImage */
3837   if (dib && bmp)
3838   {
3839 #ifdef HAVE_LIBXXSHM
3840       if (TSXShmQueryExtension(gdi_display) &&
3841           (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
3842                                                 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
3843       {
3844         ; /* Created Image */
3845       } else {
3846           dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3847           dib->shminfo.shmid = -1;
3848       }
3849 #else
3850       dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3851 #endif
3852   }
3853   
3854   /* Clean up in case of errors */
3855   if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
3856     {
3857       TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3858             res, bmp, dib, bm.bmBits);
3859       if (bm.bmBits)
3860         {
3861           if (section)
3862             UnmapViewOfFile(mapBits), bm.bmBits = NULL;
3863           else if (!offset)
3864             VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
3865         }
3866       
3867       if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
3868       if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
3869       if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
3870       if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
3871       if (res) { DeleteObject(res); res = 0; }
3872     }
3873   else if (bm.bmBits)
3874     {
3875       /* Install fault handler, if possible */
3876       InitializeCriticalSection(&(dib->lock));
3877       if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
3878         {
3879           if (section || offset)
3880             {
3881               X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3882               if (dib) dib->status = DIB_Status_AppMod;
3883             }
3884           else
3885             {
3886               X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3887               if (dib) dib->status = DIB_Status_InSync;
3888             }
3889         }
3890     }
3891
3892   /* Return BITMAP handle and storage location */
3893   if (bmp) GDI_ReleaseObj(res);
3894   if (bm.bmBits && bits) *bits = bm.bmBits;
3895   return res;
3896 }
3897
3898 /***********************************************************************
3899  *           X11DRV_DIB_DeleteDIBSection
3900  */
3901 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
3902 {
3903   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3904
3905   if (dib->image) 
3906   {
3907 #ifdef HAVE_LIBXXSHM
3908       if (dib->shminfo.shmid != -1)
3909       {
3910           TSXShmDetach (gdi_display, &(dib->shminfo));
3911           XDestroyImage (dib->image);
3912           shmdt (dib->shminfo.shmaddr);
3913           dib->shminfo.shmid = -1;
3914       }
3915       else
3916 #endif
3917           XDestroyImage( dib->image );
3918   }
3919   
3920   if (dib->colorMap)
3921     HeapFree(GetProcessHeap(), 0, dib->colorMap);
3922
3923   DeleteCriticalSection(&(dib->lock));
3924 }
3925
3926 /***********************************************************************
3927  *           X11DRV_DIB_SetDIBColorTable
3928  */
3929 UINT X11DRV_DIB_SetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, const RGBQUAD *colors)
3930 {
3931   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3932
3933   if (dib && dib->colorMap) {
3934     /*
3935      * Changing color table might change the mapping between
3936      * DIB colors and X11 colors and thus alter the visible state
3937      * of the bitmap object.
3938      */
3939     X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
3940     X11DRV_DIB_GenColorMap( dc, dib->colorMap, DIB_RGB_COLORS, 
3941                            dib->dibSection.dsBm.bmBitsPixel,
3942                             TRUE, colors, start, count + start );
3943     X11DRV_DIB_Unlock(bmp, TRUE);
3944     return count;
3945   }
3946   return 0;
3947 }
3948
3949 /***********************************************************************
3950  *           X11DRV_DIB_GetDIBColorTable
3951  */
3952 UINT X11DRV_DIB_GetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, RGBQUAD *colors)
3953 {
3954   X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3955
3956   if (dib && dib->colorMap) {
3957     int i, end = count + start;
3958     if (end > dib->nColorMap) end = dib->nColorMap;
3959     for (i = start; i < end; i++,colors++) {
3960       COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
3961       colors->rgbBlue  = GetBValue(col);
3962       colors->rgbGreen = GetGValue(col);
3963       colors->rgbRed   = GetRValue(col);
3964       colors->rgbReserved = 0;
3965     }
3966     return end-start;
3967   }
3968   return 0;
3969 }
3970
3971
3972 /**************************************************************************
3973  *              X11DRV_DIB_CreateDIBFromPixmap
3974  *
3975  *  Allocates a packed DIB and copies the Pixmap data into it.
3976  *  If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
3977  */
3978 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
3979 {
3980     HBITMAP hBmp = 0;
3981     BITMAPOBJ *pBmp = NULL;
3982     HGLOBAL hPackedDIB = 0;
3983
3984     /* Allocates an HBITMAP which references the Pixmap passed to us */
3985     hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
3986     if (!hBmp)
3987     {
3988         TRACE("\tCould not create bitmap header for Pixmap\n");
3989         goto END;
3990     }
3991
3992     /*
3993      * Create a packed DIB from the Pixmap wrapper bitmap created above.
3994      * A packed DIB contains a BITMAPINFO structure followed immediately by
3995      * an optional color palette and the pixel data.
3996      */
3997     hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
3998     
3999     /* Get a pointer to the BITMAPOBJ structure */
4000     pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4001
4002     /* We can now get rid of the HBITMAP wrapper we created earlier.
4003      * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4004      */
4005     if (!bDeletePixmap)
4006     {
4007         /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4008         pBmp->physBitmap = NULL;
4009         pBmp->funcs = NULL;
4010     }
4011     GDI_ReleaseObj( hBmp );
4012     DeleteObject(hBmp);  
4013     
4014 END:
4015     TRACE("\tReturning packed DIB %x\n", hPackedDIB);
4016     return hPackedDIB;
4017 }
4018
4019
4020 /**************************************************************************
4021  *                 X11DRV_DIB_CreatePixmapFromDIB
4022  *
4023  *    Creates a Pixmap from a packed DIB
4024  */
4025 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
4026 {
4027     Pixmap pixmap = None;
4028     HBITMAP hBmp = 0;
4029     BITMAPOBJ *pBmp = NULL;
4030     LPBYTE pPackedDIB = NULL;
4031     LPBITMAPINFO pbmi = NULL;
4032     LPBITMAPINFOHEADER pbmiHeader = NULL;
4033     LPBYTE pbits = NULL;
4034     
4035     /* Get a pointer to the packed DIB's data  */
4036     pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
4037     pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
4038     pbmi = (LPBITMAPINFO)pPackedDIB;
4039     pbits = (LPBYTE)(pPackedDIB
4040                      + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
4041     
4042     /* Create a DDB from the DIB */
4043      
4044     hBmp = CreateDIBitmap(hdc,
4045                           pbmiHeader,
4046                           CBM_INIT,
4047                           (LPVOID)pbits,
4048                           pbmi,
4049                           DIB_RGB_COLORS);
4050
4051     GlobalUnlock(hPackedDIB);
4052
4053     TRACE("CreateDIBitmap returned %x\n", hBmp);
4054
4055     /* Retrieve the internal Pixmap from the DDB */
4056      
4057     pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4058
4059     pixmap = (Pixmap)pBmp->physBitmap;
4060     /* clear the physBitmap so that we can steal its pixmap */
4061     pBmp->physBitmap = NULL;
4062     pBmp->funcs = NULL;
4063
4064     /* Delete the DDB we created earlier now that we have stolen its pixmap */
4065     GDI_ReleaseObj( hBmp );
4066     DeleteObject(hBmp);
4067     
4068     TRACE("\tReturning Pixmap %ld\n", pixmap);
4069     return pixmap;
4070 }