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