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