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