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