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