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