kernel32/tests: Better check the NT path returned by QueryFullProcessImageName().
[wine] / dlls / winex11.drv / xrender.c
1 /*
2  * Functions to use the XRender extension
3  *
4  * Copyright 2001, 2002 Huw D M Davies for CodeWeavers
5  * Copyright 2009 Roderick Colenbrander
6  * Copyright 2011 Alexandre Julliard
7  *
8  * Some parts also:
9  * Copyright 2000 Keith Packard, member of The XFree86 Project, Inc.
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 #include "config.h"
26 #include "wine/port.h"
27
28 #include <assert.h>
29 #include <stdarg.h>
30 #include <string.h>
31 #include <stdlib.h>
32
33 #include "windef.h"
34 #include "winbase.h"
35 #include "x11drv.h"
36 #include "winternl.h"
37 #include "wine/library.h"
38 #include "wine/unicode.h"
39 #include "wine/debug.h"
40
41 int using_client_side_fonts = FALSE;
42
43 WINE_DEFAULT_DEBUG_CHANNEL(xrender);
44
45 #ifdef SONAME_LIBXRENDER
46
47 static BOOL X11DRV_XRender_Installed = FALSE;
48
49 #include <X11/Xlib.h>
50 #include <X11/extensions/Xrender.h>
51
52 #ifndef RepeatNone  /* added in 0.10 */
53 #define RepeatNone    0
54 #define RepeatNormal  1
55 #define RepeatPad     2
56 #define RepeatReflect 3
57 #endif
58
59 enum wxr_format
60 {
61   WXR_FORMAT_MONO,
62   WXR_FORMAT_GRAY,
63   WXR_FORMAT_X1R5G5B5,
64   WXR_FORMAT_X1B5G5R5,
65   WXR_FORMAT_R5G6B5,
66   WXR_FORMAT_B5G6R5,
67   WXR_FORMAT_R8G8B8,
68   WXR_FORMAT_B8G8R8,
69   WXR_FORMAT_A8R8G8B8,
70   WXR_FORMAT_B8G8R8A8,
71   WXR_FORMAT_X8R8G8B8,
72   WXR_FORMAT_B8G8R8X8,
73   WXR_NB_FORMATS,
74   WXR_INVALID_FORMAT = WXR_NB_FORMATS
75 };
76
77 typedef struct wine_xrender_format_template
78 {
79     unsigned int depth;
80     unsigned int alpha;
81     unsigned int alphaMask;
82     unsigned int red;
83     unsigned int redMask;
84     unsigned int green;
85     unsigned int greenMask;
86     unsigned int blue;
87     unsigned int blueMask;
88 } WineXRenderFormatTemplate;
89
90 static const WineXRenderFormatTemplate wxr_formats_template[WXR_NB_FORMATS] =
91 {
92     /* Format               depth   alpha   mask    red     mask    green   mask    blue    mask*/
93 /* WXR_FORMAT_MONO     */ { 1,      0,      0x01,   0,      0,      0,      0,      0,      0       },
94 /* WXR_FORMAT_GRAY     */ { 8,      0,      0xff,   0,      0,      0,      0,      0,      0       },
95 /* WXR_FORMAT_X1R5G5B5 */ { 16,     0,      0,      10,     0x1f,   5,      0x1f,   0,      0x1f    },
96 /* WXR_FORMAT_X1B5G5R5 */ { 16,     0,      0,      0,      0x1f,   5,      0x1f,   10,     0x1f    },
97 /* WXR_FORMAT_R5G6B5   */ { 16,     0,      0,      11,     0x1f,   5,      0x3f,   0,      0x1f    },
98 /* WXR_FORMAT_B5G6R5   */ { 16,     0,      0,      0,      0x1f,   5,      0x3f,   11,     0x1f    },
99 /* WXR_FORMAT_R8G8B8   */ { 24,     0,      0,      16,     0xff,   8,      0xff,   0,      0xff    },
100 /* WXR_FORMAT_B8G8R8   */ { 24,     0,      0,      0,      0xff,   8,      0xff,   16,     0xff    },
101 /* WXR_FORMAT_A8R8G8B8 */ { 32,     24,     0xff,   16,     0xff,   8,      0xff,   0,      0xff    },
102 /* WXR_FORMAT_B8G8R8A8 */ { 32,     0,      0xff,   8,      0xff,   16,     0xff,   24,     0xff    },
103 /* WXR_FORMAT_X8R8G8B8 */ { 32,     0,      0,      16,     0xff,   8,      0xff,   0,      0xff    },
104 /* WXR_FORMAT_B8G8R8X8 */ { 32,     0,      0,      8,      0xff,   16,     0xff,   24,     0xff    },
105 };
106
107 static const ColorShifts wxr_color_shifts[WXR_NB_FORMATS] =
108 {
109     /* format                phys red    phys green  phys blue   log red     log green   log blue */
110 /* WXR_FORMAT_MONO     */ { { 0,0,0 },  { 0,0,0 },  { 0,0,0 },  { 0,0,0 },  { 0,0,0 },  { 0,0,0 }  },
111 /* WXR_FORMAT_GRAY     */ { { 0,0,0 },  { 0,0,0 },  { 0,0,0 },  { 0,0,0 },  { 0,0,0 },  { 0,0,0 }  },
112 /* WXR_FORMAT_X1R5G5B5 */ { {10,5,31},  { 5,5,31},  { 0,5,31},  {10,5,31},  { 5,5,31},  { 0,5,31}  },
113 /* WXR_FORMAT_X1B5G5R5 */ { { 0,5,31},  { 5,5,31},  {10,5,31},  { 0,5,31},  { 5,5,31},  {10,5,31}  },
114 /* WXR_FORMAT_R5G6B5   */ { {11,5,31},  { 5,6,63},  { 0,5,31},  {11,5,31},  { 5,6,63},  { 0,5,31}  },
115 /* WXR_FORMAT_B5G6R5   */ { { 0,5,31},  { 5,6,63},  {11,5,31},  { 0,5,31},  { 5,6,63},  {11,5,31}  },
116 /* WXR_FORMAT_R8G8B8   */ { {16,8,255}, { 8,8,255}, { 0,8,255}, {16,8,255}, { 8,8,255}, { 0,8,255} },
117 /* WXR_FORMAT_B8G8R8   */ { { 0,8,255}, { 8,8,255}, {16,8,255}, { 0,8,255}, { 8,8,255}, {16,8,255} },
118 /* WXR_FORMAT_A8R8G8B8 */ { {16,8,255}, { 8,8,255}, { 0,8,255}, {16,8,255}, { 8,8,255}, { 0,8,255} },
119 /* WXR_FORMAT_B8G8R8A8 */ { { 8,8,255}, {16,8,255}, {24,8,255}, { 8,8,255}, {16,8,255}, {24,8,255} },
120 /* WXR_FORMAT_X8R8G8B8 */ { {16,8,255}, { 8,8,255}, { 0,8,255}, {16,8,255}, { 8,8,255}, { 0,8,255} },
121 /* WXR_FORMAT_B8G8R8X8 */ { { 8,8,255}, {16,8,255}, {24,8,255}, { 8,8,255}, {16,8,255}, {24,8,255} },
122 };
123
124 static enum wxr_format default_format = WXR_INVALID_FORMAT;
125 static XRenderPictFormat *pict_formats[WXR_NB_FORMATS + 1 /* invalid format */];
126
127 typedef struct
128 {
129     LOGFONTW lf;
130     XFORM    xform;
131     SIZE     devsize;  /* size in device coords */
132     DWORD    hash;
133 } LFANDSIZE;
134
135 #define INITIAL_REALIZED_BUF_SIZE 128
136
137 typedef enum { AA_None = 0, AA_Grey, AA_RGB, AA_BGR, AA_VRGB, AA_VBGR, AA_MAXVALUE } AA_Type;
138
139 typedef struct
140 {
141     GlyphSet glyphset;
142     XRenderPictFormat *font_format;
143     int nrealized;
144     BOOL *realized;
145     void **bitmaps;
146     XGlyphInfo *gis;
147 } gsCacheEntryFormat;
148
149 typedef struct
150 {
151     LFANDSIZE lfsz;
152     AA_Type aa_default;
153     gsCacheEntryFormat * format[AA_MAXVALUE];
154     INT count;
155     INT next;
156 } gsCacheEntry;
157
158 struct xrender_physdev
159 {
160     struct gdi_physdev dev;
161     X11DRV_PDEVICE    *x11dev;
162     enum wxr_format    format;
163     int                cache_index;
164     BOOL               update_clip;
165     Picture            pict;
166     Picture            pict_src;
167     XRenderPictFormat *pict_format;
168 };
169
170 static inline struct xrender_physdev *get_xrender_dev( PHYSDEV dev )
171 {
172     return (struct xrender_physdev *)dev;
173 }
174
175 static const struct gdi_dc_funcs xrender_funcs;
176
177 static gsCacheEntry *glyphsetCache = NULL;
178 static DWORD glyphsetCacheSize = 0;
179 static INT lastfree = -1;
180 static INT mru = -1;
181
182 #define INIT_CACHE_SIZE 10
183
184 static int antialias = 1;
185
186 static void *xrender_handle;
187
188 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
189 MAKE_FUNCPTR(XRenderAddGlyphs)
190 MAKE_FUNCPTR(XRenderComposite)
191 MAKE_FUNCPTR(XRenderCompositeText16)
192 MAKE_FUNCPTR(XRenderCreateGlyphSet)
193 MAKE_FUNCPTR(XRenderCreatePicture)
194 MAKE_FUNCPTR(XRenderFillRectangle)
195 MAKE_FUNCPTR(XRenderFindFormat)
196 MAKE_FUNCPTR(XRenderFindVisualFormat)
197 MAKE_FUNCPTR(XRenderFreeGlyphSet)
198 MAKE_FUNCPTR(XRenderFreePicture)
199 MAKE_FUNCPTR(XRenderSetPictureClipRectangles)
200 #ifdef HAVE_XRENDERSETPICTURETRANSFORM
201 MAKE_FUNCPTR(XRenderSetPictureTransform)
202 #endif
203 MAKE_FUNCPTR(XRenderQueryExtension)
204
205 #ifdef SONAME_LIBFONTCONFIG
206 #include <fontconfig/fontconfig.h>
207 MAKE_FUNCPTR(FcConfigSubstitute)
208 MAKE_FUNCPTR(FcDefaultSubstitute)
209 MAKE_FUNCPTR(FcFontMatch)
210 MAKE_FUNCPTR(FcInit)
211 MAKE_FUNCPTR(FcPatternCreate)
212 MAKE_FUNCPTR(FcPatternDestroy)
213 MAKE_FUNCPTR(FcPatternAddInteger)
214 MAKE_FUNCPTR(FcPatternAddString)
215 MAKE_FUNCPTR(FcPatternGetBool)
216 MAKE_FUNCPTR(FcPatternGetInteger)
217 MAKE_FUNCPTR(FcPatternGetString)
218 static void *fontconfig_handle;
219 static BOOL fontconfig_installed;
220 #endif
221
222 #undef MAKE_FUNCPTR
223
224 static CRITICAL_SECTION xrender_cs;
225 static CRITICAL_SECTION_DEBUG critsect_debug =
226 {
227     0, 0, &xrender_cs,
228     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
229       0, 0, { (DWORD_PTR)(__FILE__ ": xrender_cs") }
230 };
231 static CRITICAL_SECTION xrender_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
232
233 #define MS_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
234           ( ( (ULONG)_x4 << 24 ) |     \
235             ( (ULONG)_x3 << 16 ) |     \
236             ( (ULONG)_x2 <<  8 ) |     \
237               (ULONG)_x1         )
238
239 #define MS_GASP_TAG MS_MAKE_TAG('g', 'a', 's', 'p')
240
241 #define GASP_GRIDFIT 0x01
242 #define GASP_DOGRAY  0x02
243
244 #ifdef WORDS_BIGENDIAN
245 #define get_be_word(x) (x)
246 #define NATIVE_BYTE_ORDER MSBFirst
247 #else
248 #define get_be_word(x) RtlUshortByteSwap(x)
249 #define NATIVE_BYTE_ORDER LSBFirst
250 #endif
251
252 static BOOL has_alpha( enum wxr_format format )
253 {
254     return (format == WXR_FORMAT_A8R8G8B8 || format == WXR_FORMAT_B8G8R8A8);
255 }
256
257 static enum wxr_format get_format_without_alpha( enum wxr_format format )
258 {
259     switch (format)
260     {
261     case WXR_FORMAT_A8R8G8B8: return WXR_FORMAT_X8R8G8B8;
262     case WXR_FORMAT_B8G8R8A8: return WXR_FORMAT_B8G8R8X8;
263     default: return format;
264     }
265 }
266
267 static BOOL get_xrender_template(const WineXRenderFormatTemplate *fmt, XRenderPictFormat *templ, unsigned long *mask)
268 {
269     templ->id = 0;
270     templ->type = PictTypeDirect;
271     templ->depth = fmt->depth;
272     templ->direct.alpha = fmt->alpha;
273     templ->direct.alphaMask = fmt->alphaMask;
274     templ->direct.red = fmt->red;
275     templ->direct.redMask = fmt->redMask;
276     templ->direct.green = fmt->green;
277     templ->direct.greenMask = fmt->greenMask;
278     templ->direct.blue = fmt->blue;
279     templ->direct.blueMask = fmt->blueMask;
280     templ->colormap = 0;
281
282     *mask = PictFormatType | PictFormatDepth | PictFormatAlpha | PictFormatAlphaMask | PictFormatRed | PictFormatRedMask | PictFormatGreen | PictFormatGreenMask | PictFormatBlue | PictFormatBlueMask;
283
284     return TRUE;
285 }
286
287 static BOOL is_wxrformat_compatible_with_default_visual(const WineXRenderFormatTemplate *fmt)
288 {
289     if(fmt->depth != screen_depth)
290         return FALSE;
291     if( (fmt->redMask << fmt->red) != visual->red_mask)
292         return FALSE;
293     if( (fmt->greenMask << fmt->green) != visual->green_mask)
294         return FALSE;
295     if( (fmt->blueMask << fmt->blue) != visual->blue_mask)
296         return FALSE;
297
298     /* We never select a default ARGB visual */
299     if(fmt->alphaMask)
300         return FALSE;
301
302     return TRUE;
303 }
304
305 static int load_xrender_formats(void)
306 {
307     int count = 0;
308     unsigned int i;
309
310     for (i = 0; i < WXR_NB_FORMATS; i++)
311     {
312         XRenderPictFormat templ;
313
314         if(is_wxrformat_compatible_with_default_visual(&wxr_formats_template[i]))
315         {
316             wine_tsx11_lock();
317             pict_formats[i] = pXRenderFindVisualFormat(gdi_display, visual);
318             if (!pict_formats[i])
319             {
320                 /* Xrender doesn't like DirectColor visuals, try to find a TrueColor one instead */
321                 if (visual->class == DirectColor)
322                 {
323                     XVisualInfo info;
324                     if (XMatchVisualInfo( gdi_display, DefaultScreen(gdi_display),
325                                           screen_depth, TrueColor, &info ))
326                     {
327                         pict_formats[i] = pXRenderFindVisualFormat(gdi_display, info.visual);
328                         if (pict_formats[i]) visual = info.visual;
329                     }
330                 }
331             }
332             wine_tsx11_unlock();
333             if (pict_formats[i]) default_format = i;
334         }
335         else
336         {
337             unsigned long mask = 0;
338             get_xrender_template(&wxr_formats_template[i], &templ, &mask);
339
340             wine_tsx11_lock();
341             pict_formats[i] = pXRenderFindFormat(gdi_display, mask, &templ, 0);
342             wine_tsx11_unlock();
343         }
344         if (pict_formats[i])
345         {
346             count++;
347             TRACE("Loaded pict_format with id=%#lx for wxr_format=%#x\n", pict_formats[i]->id, i);
348         }
349     }
350     return count;
351 }
352
353 /***********************************************************************
354  *   X11DRV_XRender_Init
355  *
356  * Let's see if our XServer has the extension available
357  *
358  */
359 const struct gdi_dc_funcs *X11DRV_XRender_Init(void)
360 {
361     int event_base, i;
362
363     if (client_side_with_render &&
364         (xrender_handle = wine_dlopen(SONAME_LIBXRENDER, RTLD_NOW, NULL, 0)))
365     {
366
367 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(xrender_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
368 LOAD_FUNCPTR(XRenderAddGlyphs)
369 LOAD_FUNCPTR(XRenderComposite)
370 LOAD_FUNCPTR(XRenderCompositeText16)
371 LOAD_FUNCPTR(XRenderCreateGlyphSet)
372 LOAD_FUNCPTR(XRenderCreatePicture)
373 LOAD_FUNCPTR(XRenderFillRectangle)
374 LOAD_FUNCPTR(XRenderFindFormat)
375 LOAD_FUNCPTR(XRenderFindVisualFormat)
376 LOAD_FUNCPTR(XRenderFreeGlyphSet)
377 LOAD_FUNCPTR(XRenderFreePicture)
378 LOAD_FUNCPTR(XRenderSetPictureClipRectangles)
379 LOAD_FUNCPTR(XRenderQueryExtension)
380 #undef LOAD_FUNCPTR
381 #ifdef HAVE_XRENDERSETPICTURETRANSFORM
382 #define LOAD_OPTIONAL_FUNCPTR(f) p##f = wine_dlsym(xrender_handle, #f, NULL, 0);
383 LOAD_OPTIONAL_FUNCPTR(XRenderSetPictureTransform)
384 #undef LOAD_OPTIONAL_FUNCPTR
385 #endif
386
387         wine_tsx11_lock();
388         X11DRV_XRender_Installed = pXRenderQueryExtension(gdi_display, &event_base, &xrender_error_base);
389         wine_tsx11_unlock();
390         if(X11DRV_XRender_Installed) {
391             TRACE("Xrender is up and running error_base = %d\n", xrender_error_base);
392             if(!load_xrender_formats()) /* This fails in buggy versions of libXrender.so */
393             {
394                 wine_tsx11_unlock();
395                 WINE_MESSAGE(
396                     "Wine has detected that you probably have a buggy version\n"
397                     "of libXrender.so .  Because of this client side font rendering\n"
398                     "will be disabled.  Please upgrade this library.\n");
399                 X11DRV_XRender_Installed = FALSE;
400                 return NULL;
401             }
402
403             if (!visual->red_mask || !visual->green_mask || !visual->blue_mask) {
404                 WARN("one or more of the colour masks are 0, disabling XRENDER. Try running in 16-bit mode or higher.\n");
405                 X11DRV_XRender_Installed = FALSE;
406             }
407         }
408     }
409
410 #ifdef SONAME_LIBFONTCONFIG
411     if ((fontconfig_handle = wine_dlopen(SONAME_LIBFONTCONFIG, RTLD_NOW, NULL, 0)))
412     {
413 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(fontconfig_handle, #f, NULL, 0)) == NULL){WARN("Can't find symbol %s\n", #f); goto sym_not_found;}
414         LOAD_FUNCPTR(FcConfigSubstitute);
415         LOAD_FUNCPTR(FcDefaultSubstitute);
416         LOAD_FUNCPTR(FcFontMatch);
417         LOAD_FUNCPTR(FcInit);
418         LOAD_FUNCPTR(FcPatternCreate);
419         LOAD_FUNCPTR(FcPatternDestroy);
420         LOAD_FUNCPTR(FcPatternAddInteger);
421         LOAD_FUNCPTR(FcPatternAddString);
422         LOAD_FUNCPTR(FcPatternGetBool);
423         LOAD_FUNCPTR(FcPatternGetInteger);
424         LOAD_FUNCPTR(FcPatternGetString);
425 #undef LOAD_FUNCPTR
426         fontconfig_installed = pFcInit();
427     }
428     else TRACE( "cannot find the fontconfig library " SONAME_LIBFONTCONFIG "\n" );
429 #endif
430
431 sym_not_found:
432     if(X11DRV_XRender_Installed || client_side_with_core)
433     {
434         glyphsetCache = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
435                                   sizeof(*glyphsetCache) * INIT_CACHE_SIZE);
436
437         glyphsetCacheSize = INIT_CACHE_SIZE;
438         lastfree = 0;
439         for(i = 0; i < INIT_CACHE_SIZE; i++) {
440           glyphsetCache[i].next = i + 1;
441           glyphsetCache[i].count = -1;
442         }
443         glyphsetCache[i-1].next = -1;
444         using_client_side_fonts = 1;
445
446         if(!X11DRV_XRender_Installed) {
447             TRACE("Xrender is not available on your XServer, client side rendering with the core protocol instead.\n");
448             if(screen_depth <= 8 || !client_side_antialias_with_core)
449                 antialias = 0;
450         } else {
451             if(screen_depth <= 8 || !client_side_antialias_with_render)
452                 antialias = 0;
453         }
454         return &xrender_funcs;
455     }
456     TRACE("Using X11 core fonts\n");
457     return NULL;
458 }
459
460 /* Helper function to convert from a color packed in a 32-bit integer to a XRenderColor */
461 static void get_xrender_color( XRenderPictFormat *pf, int src_color, XRenderColor *dst_color )
462 {
463     if(pf->direct.redMask)
464         dst_color->red = ((src_color >> pf->direct.red) & pf->direct.redMask) * 65535/pf->direct.redMask;
465     else
466        dst_color->red = 0;
467
468     if(pf->direct.greenMask)
469         dst_color->green = ((src_color >> pf->direct.green) & pf->direct.greenMask) * 65535/pf->direct.greenMask;
470     else
471         dst_color->green = 0;
472
473     if(pf->direct.blueMask)
474         dst_color->blue = ((src_color >> pf->direct.blue) & pf->direct.blueMask) * 65535/pf->direct.blueMask;
475     else
476         dst_color->blue = 0;
477
478     dst_color->alpha = 0xffff;
479 }
480
481 static enum wxr_format get_xrender_format_from_color_shifts(int depth, ColorShifts *shifts)
482 {
483     int redMask, greenMask, blueMask;
484     unsigned int i;
485
486     if (depth == 1) return WXR_FORMAT_MONO;
487
488     /* physDevs of a depth <=8, don't have color_shifts set and XRender can't handle those except for 1-bit */
489     if (!shifts) return default_format;
490
491     redMask   = shifts->physicalRed.max << shifts->physicalRed.shift;
492     greenMask = shifts->physicalGreen.max << shifts->physicalGreen.shift;
493     blueMask  = shifts->physicalBlue.max << shifts->physicalBlue.shift;
494
495     /* Try to locate a format which matches the specification of the dibsection. */
496     for(i = 0; i < WXR_NB_FORMATS; i++)
497     {
498         if( depth     == wxr_formats_template[i].depth &&
499             redMask   == (wxr_formats_template[i].redMask << wxr_formats_template[i].red) &&
500             greenMask == (wxr_formats_template[i].greenMask << wxr_formats_template[i].green) &&
501             blueMask  == (wxr_formats_template[i].blueMask << wxr_formats_template[i].blue) )
502             return i;
503     }
504
505     /* This should not happen because when we reach 'shifts' must have been set and we only allows shifts which are backed by X */
506     ERR("No XRender format found for %u %08x/%08x/%08x\n", depth, redMask, greenMask, blueMask);
507     return WXR_INVALID_FORMAT;
508 }
509
510 static enum wxr_format get_xrender_format_from_bitmapinfo( const BITMAPINFO *info, BOOL use_alpha )
511 {
512     if (info->bmiHeader.biPlanes != 1) return WXR_INVALID_FORMAT;
513
514     switch (info->bmiHeader.biBitCount)
515     {
516     case 1:
517         return WXR_FORMAT_MONO;
518     case 4:
519     case 8:
520         break;
521     case 24:
522         if (info->bmiHeader.biCompression != BI_RGB) break;
523         return WXR_FORMAT_R8G8B8;
524     case 16:
525     case 32:
526         if (info->bmiHeader.biCompression == BI_BITFIELDS)
527         {
528             DWORD *colors = (DWORD *)((char *)info + info->bmiHeader.biSize);
529             unsigned int i;
530
531             for (i = 0; i < WXR_NB_FORMATS; i++)
532             {
533                 if (info->bmiHeader.biBitCount == wxr_formats_template[i].depth &&
534                     colors[0] == (wxr_formats_template[i].redMask << wxr_formats_template[i].red) &&
535                     colors[1] == (wxr_formats_template[i].greenMask << wxr_formats_template[i].green) &&
536                     colors[2] == (wxr_formats_template[i].blueMask << wxr_formats_template[i].blue))
537                     return i;
538             }
539             break;
540         }
541         if (info->bmiHeader.biCompression != BI_RGB) break;
542         if (info->bmiHeader.biBitCount == 16) return WXR_FORMAT_X1R5G5B5;
543         return use_alpha ? WXR_FORMAT_A8R8G8B8 : WXR_FORMAT_X8R8G8B8;
544     }
545     return WXR_INVALID_FORMAT;
546 }
547
548 /* Set the x/y scaling and x/y offsets in the transformation matrix of the source picture */
549 static void set_xrender_transformation(Picture src_pict, double xscale, double yscale, int xoffset, int yoffset)
550 {
551 #ifdef HAVE_XRENDERSETPICTURETRANSFORM
552     XTransform xform = {{
553         { XDoubleToFixed(xscale), XDoubleToFixed(0), XDoubleToFixed(xoffset) },
554         { XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(yoffset) },
555         { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) }
556     }};
557
558     pXRenderSetPictureTransform(gdi_display, src_pict, &xform);
559 #endif
560 }
561
562 /* check if we can use repeating instead of scaling for the specified source DC */
563 static BOOL use_source_repeat( struct xrender_physdev *dev )
564 {
565     return (dev->x11dev->bitmap &&
566             dev->x11dev->drawable_rect.right - dev->x11dev->drawable_rect.left == 1 &&
567             dev->x11dev->drawable_rect.bottom - dev->x11dev->drawable_rect.top == 1);
568 }
569
570 static Picture get_xrender_picture( struct xrender_physdev *dev, HRGN clip_rgn, const RECT *clip_rect )
571 {
572     if (!dev->pict && dev->pict_format)
573     {
574         XRenderPictureAttributes pa;
575
576         wine_tsx11_lock();
577         pa.subwindow_mode = IncludeInferiors;
578         dev->pict = pXRenderCreatePicture( gdi_display, dev->x11dev->drawable,
579                                            dev->pict_format, CPSubwindowMode, &pa );
580         wine_tsx11_unlock();
581         TRACE( "Allocing pict=%lx dc=%p drawable=%08lx\n",
582                dev->pict, dev->dev.hdc, dev->x11dev->drawable );
583         dev->update_clip = TRUE;
584     }
585
586     if (dev->update_clip)
587     {
588         RGNDATA *clip_data;
589         HRGN rgn = 0;
590
591         if (clip_rect)
592         {
593             rgn = CreateRectRgnIndirect( clip_rect );
594             if (clip_rgn) CombineRgn( rgn, rgn, clip_rgn, RGN_AND );
595             CombineRgn( rgn, rgn, dev->x11dev->region, RGN_AND );
596         }
597         else if (clip_rgn)
598         {
599             rgn = CreateRectRgn( 0, 0, 0, 0 );
600             CombineRgn( rgn, clip_rgn, dev->x11dev->region, RGN_AND );
601         }
602
603         if ((clip_data = X11DRV_GetRegionData( rgn ? rgn : dev->x11dev->region, 0 )))
604         {
605             wine_tsx11_lock();
606             pXRenderSetPictureClipRectangles( gdi_display, dev->pict,
607                                               dev->x11dev->dc_rect.left, dev->x11dev->dc_rect.top,
608                                               (XRectangle *)clip_data->Buffer, clip_data->rdh.nCount );
609             wine_tsx11_unlock();
610             HeapFree( GetProcessHeap(), 0, clip_data );
611         }
612         dev->update_clip = (rgn != 0);  /* have to update again if we are using a custom region */
613         if (rgn) DeleteObject( rgn );
614     }
615     return dev->pict;
616 }
617
618 static Picture get_xrender_picture_source( struct xrender_physdev *dev, BOOL repeat )
619 {
620     if (!dev->pict_src && dev->pict_format)
621     {
622         XRenderPictureAttributes pa;
623
624         wine_tsx11_lock();
625         pa.subwindow_mode = IncludeInferiors;
626         pa.repeat = repeat ? RepeatNormal : RepeatNone;
627         dev->pict_src = pXRenderCreatePicture( gdi_display, dev->x11dev->drawable,
628                                                dev->pict_format, CPSubwindowMode|CPRepeat, &pa );
629         wine_tsx11_unlock();
630
631         TRACE("Allocing pict_src=%lx dc=%p drawable=%08lx repeat=%u\n",
632               dev->pict_src, dev->dev.hdc, dev->x11dev->drawable, pa.repeat);
633     }
634
635     return dev->pict_src;
636 }
637
638 static void free_xrender_picture( struct xrender_physdev *dev )
639 {
640     if (dev->pict || dev->pict_src)
641     {
642         wine_tsx11_lock();
643         XFlush( gdi_display );
644         if (dev->pict)
645         {
646             TRACE("freeing pict = %lx dc = %p\n", dev->pict, dev->dev.hdc);
647             pXRenderFreePicture(gdi_display, dev->pict);
648             dev->pict = 0;
649         }
650         if(dev->pict_src)
651         {
652             TRACE("freeing pict = %lx dc = %p\n", dev->pict_src, dev->dev.hdc);
653             pXRenderFreePicture(gdi_display, dev->pict_src);
654             dev->pict_src = 0;
655         }
656         wine_tsx11_unlock();
657     }
658 }
659
660 /* return a mask picture used to force alpha to 0 */
661 static Picture get_no_alpha_mask(void)
662 {
663     static Pixmap pixmap;
664     static Picture pict;
665
666     wine_tsx11_lock();
667     if (!pict)
668     {
669         XRenderPictureAttributes pa;
670         XRenderColor col;
671
672         pixmap = XCreatePixmap( gdi_display, root_window, 1, 1, 32 );
673         pa.repeat = RepeatNormal;
674         pa.component_alpha = True;
675         pict = pXRenderCreatePicture( gdi_display, pixmap, pict_formats[WXR_FORMAT_A8R8G8B8],
676                                       CPRepeat|CPComponentAlpha, &pa );
677         col.red = col.green = col.blue = 0xffff;
678         col.alpha = 0;
679         pXRenderFillRectangle( gdi_display, PictOpSrc, pict, &col, 0, 0, 1, 1 );
680     }
681     wine_tsx11_unlock();
682     return pict;
683 }
684
685 static BOOL fontcmp(LFANDSIZE *p1, LFANDSIZE *p2)
686 {
687   if(p1->hash != p2->hash) return TRUE;
688   if(memcmp(&p1->devsize, &p2->devsize, sizeof(p1->devsize))) return TRUE;
689   if(memcmp(&p1->xform, &p2->xform, sizeof(p1->xform))) return TRUE;
690   if(memcmp(&p1->lf, &p2->lf, offsetof(LOGFONTW, lfFaceName))) return TRUE;
691   return strcmpiW(p1->lf.lfFaceName, p2->lf.lfFaceName);
692 }
693
694 #if 0
695 static void walk_cache(void)
696 {
697   int i;
698
699   EnterCriticalSection(&xrender_cs);
700   for(i=mru; i >= 0; i = glyphsetCache[i].next)
701     TRACE("item %d\n", i);
702   LeaveCriticalSection(&xrender_cs);
703 }
704 #endif
705
706 static int LookupEntry(LFANDSIZE *plfsz)
707 {
708   int i, prev_i = -1;
709
710   for(i = mru; i >= 0; i = glyphsetCache[i].next) {
711     TRACE("%d\n", i);
712     if(glyphsetCache[i].count == -1) break; /* reached free list so stop */
713
714     if(!fontcmp(&glyphsetCache[i].lfsz, plfsz)) {
715       glyphsetCache[i].count++;
716       if(prev_i >= 0) {
717         glyphsetCache[prev_i].next = glyphsetCache[i].next;
718         glyphsetCache[i].next = mru;
719         mru = i;
720       }
721       TRACE("found font in cache %d\n", i);
722       return i;
723     }
724     prev_i = i;
725   }
726   TRACE("font not in cache\n");
727   return -1;
728 }
729
730 static void FreeEntry(int entry)
731 {
732     int i, format;
733   
734     for(format = 0; format < AA_MAXVALUE; format++) {
735         gsCacheEntryFormat * formatEntry;
736
737         if( !glyphsetCache[entry].format[format] )
738             continue;
739
740         formatEntry = glyphsetCache[entry].format[format];
741
742         if(formatEntry->glyphset) {
743             wine_tsx11_lock();
744             pXRenderFreeGlyphSet(gdi_display, formatEntry->glyphset);
745             wine_tsx11_unlock();
746             formatEntry->glyphset = 0;
747         }
748         if(formatEntry->nrealized) {
749             HeapFree(GetProcessHeap(), 0, formatEntry->realized);
750             formatEntry->realized = NULL;
751             if(formatEntry->bitmaps) {
752                 for(i = 0; i < formatEntry->nrealized; i++)
753                     HeapFree(GetProcessHeap(), 0, formatEntry->bitmaps[i]);
754                 HeapFree(GetProcessHeap(), 0, formatEntry->bitmaps);
755                 formatEntry->bitmaps = NULL;
756             }
757             HeapFree(GetProcessHeap(), 0, formatEntry->gis);
758             formatEntry->gis = NULL;
759             formatEntry->nrealized = 0;
760         }
761
762         HeapFree(GetProcessHeap(), 0, formatEntry);
763         glyphsetCache[entry].format[format] = NULL;
764     }
765 }
766
767 static int AllocEntry(void)
768 {
769   int best = -1, prev_best = -1, i, prev_i = -1;
770
771   if(lastfree >= 0) {
772     assert(glyphsetCache[lastfree].count == -1);
773     glyphsetCache[lastfree].count = 1;
774     best = lastfree;
775     lastfree = glyphsetCache[lastfree].next;
776     assert(best != mru);
777     glyphsetCache[best].next = mru;
778     mru = best;
779
780     TRACE("empty space at %d, next lastfree = %d\n", mru, lastfree);
781     return mru;
782   }
783
784   for(i = mru; i >= 0; i = glyphsetCache[i].next) {
785     if(glyphsetCache[i].count == 0) {
786       best = i;
787       prev_best = prev_i;
788     }
789     prev_i = i;
790   }
791
792   if(best >= 0) {
793     TRACE("freeing unused glyphset at cache %d\n", best);
794     FreeEntry(best);
795     glyphsetCache[best].count = 1;
796     if(prev_best >= 0) {
797       glyphsetCache[prev_best].next = glyphsetCache[best].next;
798       glyphsetCache[best].next = mru;
799       mru = best;
800     } else {
801       assert(mru == best);
802     }
803     return mru;
804   }
805
806   TRACE("Growing cache\n");
807   
808   if (glyphsetCache)
809     glyphsetCache = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
810                               glyphsetCache,
811                               (glyphsetCacheSize + INIT_CACHE_SIZE)
812                               * sizeof(*glyphsetCache));
813   else
814     glyphsetCache = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
815                               (glyphsetCacheSize + INIT_CACHE_SIZE)
816                               * sizeof(*glyphsetCache));
817
818   for(best = i = glyphsetCacheSize; i < glyphsetCacheSize + INIT_CACHE_SIZE;
819       i++) {
820     glyphsetCache[i].next = i + 1;
821     glyphsetCache[i].count = -1;
822   }
823   glyphsetCache[i-1].next = -1;
824   glyphsetCacheSize += INIT_CACHE_SIZE;
825
826   lastfree = glyphsetCache[best].next;
827   glyphsetCache[best].count = 1;
828   glyphsetCache[best].next = mru;
829   mru = best;
830   TRACE("new free cache slot at %d\n", mru);
831   return mru;
832 }
833
834 static BOOL get_gasp_flags(HDC hdc, WORD *flags)
835 {
836     DWORD size;
837     WORD *gasp, *buffer;
838     WORD num_recs;
839     DWORD ppem;
840     TEXTMETRICW tm;
841
842     *flags = 0;
843
844     size = GetFontData(hdc, MS_GASP_TAG,  0, NULL, 0);
845     if(size == GDI_ERROR)
846         return FALSE;
847
848     gasp = buffer = HeapAlloc(GetProcessHeap(), 0, size);
849     GetFontData(hdc, MS_GASP_TAG,  0, gasp, size);
850
851     GetTextMetricsW(hdc, &tm);
852     ppem = abs(X11DRV_YWStoDS(hdc, tm.tmAscent + tm.tmDescent - tm.tmInternalLeading));
853
854     gasp++;
855     num_recs = get_be_word(*gasp);
856     gasp++;
857     while(num_recs--)
858     {
859         *flags = get_be_word(*(gasp + 1));
860         if(ppem <= get_be_word(*gasp))
861             break;
862         gasp += 2;
863     }
864     TRACE("got flags %04x for ppem %d\n", *flags, ppem);
865
866     HeapFree(GetProcessHeap(), 0, buffer);
867     return TRUE;
868 }
869
870 static AA_Type get_antialias_type( HDC hdc, BOOL subpixel, BOOL hinter )
871 {
872     AA_Type ret;
873     WORD flags;
874     UINT font_smoothing_type, font_smoothing_orientation;
875
876     if (X11DRV_XRender_Installed && subpixel &&
877         SystemParametersInfoW( SPI_GETFONTSMOOTHINGTYPE, 0, &font_smoothing_type, 0) &&
878         font_smoothing_type == FE_FONTSMOOTHINGCLEARTYPE)
879     {
880         if ( SystemParametersInfoW( SPI_GETFONTSMOOTHINGORIENTATION, 0,
881                                     &font_smoothing_orientation, 0) &&
882              font_smoothing_orientation == FE_FONTSMOOTHINGORIENTATIONBGR)
883         {
884             ret = AA_BGR;
885         }
886         else
887             ret = AA_RGB;
888         /*FIXME
889           If the monitor is in portrait mode, ClearType is disabled in the MS Windows (MSDN).
890           But, Wine's subpixel rendering can support the portrait mode.
891          */
892     }
893     else if (!hinter || !get_gasp_flags(hdc, &flags) || flags & GASP_DOGRAY)
894         ret = AA_Grey;
895     else
896         ret = AA_None;
897
898     return ret;
899 }
900
901 static int GetCacheEntry( HDC hdc, LFANDSIZE *plfsz )
902 {
903     int ret;
904     int format;
905     gsCacheEntry *entry;
906     static int hinter = -1;
907     static int subpixel = -1;
908     BOOL font_smoothing;
909
910     if((ret = LookupEntry(plfsz)) != -1) return ret;
911
912     ret = AllocEntry();
913     entry = glyphsetCache + ret;
914     entry->lfsz = *plfsz;
915     for( format = 0; format < AA_MAXVALUE; format++ ) {
916         assert( !entry->format[format] );
917     }
918
919     if(antialias && plfsz->lf.lfQuality != NONANTIALIASED_QUALITY)
920     {
921         if(hinter == -1 || subpixel == -1)
922         {
923             RASTERIZER_STATUS status;
924             GetRasterizerCaps(&status, sizeof(status));
925             hinter = status.wFlags & WINE_TT_HINTER_ENABLED;
926             subpixel = status.wFlags & WINE_TT_SUBPIXEL_RENDERING_ENABLED;
927         }
928
929         switch (plfsz->lf.lfQuality)
930         {
931             case ANTIALIASED_QUALITY:
932                 entry->aa_default = get_antialias_type( hdc, FALSE, hinter );
933                 return ret;  /* ignore further configuration */
934             case CLEARTYPE_QUALITY:
935             case CLEARTYPE_NATURAL_QUALITY:
936                 entry->aa_default = get_antialias_type( hdc, subpixel, hinter );
937                 break;
938             case DEFAULT_QUALITY:
939             case DRAFT_QUALITY:
940             case PROOF_QUALITY:
941             default:
942                 if ( SystemParametersInfoW( SPI_GETFONTSMOOTHING, 0, &font_smoothing, 0) &&
943                      font_smoothing)
944                 {
945                     entry->aa_default = get_antialias_type( hdc, subpixel, hinter );
946                 }
947                 else
948                     entry->aa_default = AA_None;
949                 break;
950         }
951
952         font_smoothing = TRUE;  /* default to enabled */
953 #ifdef SONAME_LIBFONTCONFIG
954         if (fontconfig_installed)
955         {
956             FcPattern *match, *pattern = pFcPatternCreate();
957             FcResult result;
958             char family[LF_FACESIZE * 4];
959
960             WideCharToMultiByte( CP_UTF8, 0, plfsz->lf.lfFaceName, -1, family, sizeof(family), NULL, NULL );
961             pFcPatternAddString( pattern, FC_FAMILY, (FcChar8 *)family );
962             if (plfsz->lf.lfWeight != FW_DONTCARE)
963             {
964                 int weight;
965                 switch (plfsz->lf.lfWeight)
966                 {
967                 case FW_THIN:       weight = FC_WEIGHT_THIN; break;
968                 case FW_EXTRALIGHT: weight = FC_WEIGHT_EXTRALIGHT; break;
969                 case FW_LIGHT:      weight = FC_WEIGHT_LIGHT; break;
970                 case FW_NORMAL:     weight = FC_WEIGHT_NORMAL; break;
971                 case FW_MEDIUM:     weight = FC_WEIGHT_MEDIUM; break;
972                 case FW_SEMIBOLD:   weight = FC_WEIGHT_SEMIBOLD; break;
973                 case FW_BOLD:       weight = FC_WEIGHT_BOLD; break;
974                 case FW_EXTRABOLD:  weight = FC_WEIGHT_EXTRABOLD; break;
975                 case FW_HEAVY:      weight = FC_WEIGHT_HEAVY; break;
976                 default:            weight = (plfsz->lf.lfWeight - 80) / 4; break;
977                 }
978                 pFcPatternAddInteger( pattern, FC_WEIGHT, weight );
979             }
980             pFcPatternAddInteger( pattern, FC_SLANT, plfsz->lf.lfItalic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN );
981             pFcConfigSubstitute( NULL, pattern, FcMatchPattern );
982             pFcDefaultSubstitute( pattern );
983             if ((match = pFcFontMatch( NULL, pattern, &result )))
984             {
985                 int rgba;
986                 FcBool antialias;
987
988                 if (pFcPatternGetBool( match, FC_ANTIALIAS, 0, &antialias ) != FcResultMatch)
989                     antialias = TRUE;
990                 if (pFcPatternGetInteger( match, FC_RGBA, 0, &rgba ) == FcResultMatch)
991                 {
992                     FcChar8 *file;
993                     if (pFcPatternGetString( match, FC_FILE, 0, &file ) != FcResultMatch) file = NULL;
994
995                     TRACE( "fontconfig returned rgba %u antialias %u for font %s file %s\n",
996                            rgba, antialias, debugstr_w(plfsz->lf.lfFaceName), debugstr_a((char *)file) );
997
998                     switch (rgba)
999                     {
1000                     case FC_RGBA_RGB:  entry->aa_default = AA_RGB; break;
1001                     case FC_RGBA_BGR:  entry->aa_default = AA_BGR; break;
1002                     case FC_RGBA_VRGB: entry->aa_default = AA_VRGB; break;
1003                     case FC_RGBA_VBGR: entry->aa_default = AA_VBGR; break;
1004                     case FC_RGBA_NONE: entry->aa_default = AA_Grey; break;
1005                     }
1006                 }
1007                 if (!antialias) font_smoothing = FALSE;
1008                 pFcPatternDestroy( match );
1009             }
1010             pFcPatternDestroy( pattern );
1011         }
1012 #endif  /* SONAME_LIBFONTCONFIG */
1013
1014         /* now check Xft resources */
1015         {
1016             char *value;
1017             BOOL antialias = TRUE;
1018
1019             wine_tsx11_lock();
1020             if ((value = XGetDefault( gdi_display, "Xft", "antialias" )))
1021             {
1022                 if (tolower(value[0]) == 'f' || tolower(value[0]) == 'n' ||
1023                     value[0] == '0' || !strcasecmp( value, "off" ))
1024                     antialias = FALSE;
1025             }
1026             if ((value = XGetDefault( gdi_display, "Xft", "rgba" )))
1027             {
1028                 TRACE( "Xft resource returned rgba '%s' antialias %u\n", value, antialias );
1029                 if (!strcmp( value, "rgb" )) entry->aa_default = AA_RGB;
1030                 else if (!strcmp( value, "bgr" )) entry->aa_default = AA_BGR;
1031                 else if (!strcmp( value, "vrgb" )) entry->aa_default = AA_VRGB;
1032                 else if (!strcmp( value, "vbgr" )) entry->aa_default = AA_VBGR;
1033                 else if (!strcmp( value, "none" )) entry->aa_default = AA_Grey;
1034             }
1035             wine_tsx11_unlock();
1036             if (!antialias) font_smoothing = FALSE;
1037         }
1038
1039         if (!font_smoothing) entry->aa_default = AA_None;
1040
1041         /* we can't support subpixel without xrender */
1042         if (!X11DRV_XRender_Installed && entry->aa_default > AA_Grey) entry->aa_default = AA_Grey;
1043     }
1044     else
1045         entry->aa_default = AA_None;
1046
1047     return ret;
1048 }
1049
1050 static void dec_ref_cache(int index)
1051 {
1052     assert(index >= 0);
1053     TRACE("dec'ing entry %d to %d\n", index, glyphsetCache[index].count - 1);
1054     assert(glyphsetCache[index].count > 0);
1055     glyphsetCache[index].count--;
1056 }
1057
1058 static void lfsz_calc_hash(LFANDSIZE *plfsz)
1059 {
1060   DWORD hash = 0, *ptr, two_chars;
1061   WORD *pwc;
1062   int i;
1063
1064   hash ^= plfsz->devsize.cx;
1065   hash ^= plfsz->devsize.cy;
1066   for(i = 0, ptr = (DWORD*)&plfsz->xform; i < sizeof(XFORM)/sizeof(DWORD); i++, ptr++)
1067     hash ^= *ptr;
1068   for(i = 0, ptr = (DWORD*)&plfsz->lf; i < 7; i++, ptr++)
1069     hash ^= *ptr;
1070   for(i = 0, ptr = (DWORD*)plfsz->lf.lfFaceName; i < LF_FACESIZE/2; i++, ptr++) {
1071     two_chars = *ptr;
1072     pwc = (WCHAR *)&two_chars;
1073     if(!*pwc) break;
1074     *pwc = toupperW(*pwc);
1075     pwc++;
1076     *pwc = toupperW(*pwc);
1077     hash ^= two_chars;
1078     if(!*pwc) break;
1079   }
1080   plfsz->hash = hash;
1081   return;
1082 }
1083
1084 /***********************************************************************
1085  *   X11DRV_XRender_Finalize
1086  */
1087 void X11DRV_XRender_Finalize(void)
1088 {
1089     int i;
1090
1091     EnterCriticalSection(&xrender_cs);
1092     for(i = mru; i >= 0; i = glyphsetCache[i].next)
1093         FreeEntry(i);
1094     LeaveCriticalSection(&xrender_cs);
1095 }
1096
1097 /**********************************************************************
1098  *           xrenderdrv_SelectFont
1099  */
1100 static HFONT xrenderdrv_SelectFont( PHYSDEV dev, HFONT hfont, HANDLE gdiFont )
1101 {
1102     struct xrender_physdev *physdev = get_xrender_dev( dev );
1103     LFANDSIZE lfsz;
1104
1105     if (!GetObjectW( hfont, sizeof(lfsz.lf), &lfsz.lf )) return HGDI_ERROR;
1106
1107     if (!gdiFont)
1108     {
1109         dev = GET_NEXT_PHYSDEV( dev, pSelectFont );
1110         return dev->funcs->pSelectFont( dev, hfont, gdiFont );
1111     }
1112
1113     TRACE("h=%d w=%d weight=%d it=%d charset=%d name=%s\n",
1114           lfsz.lf.lfHeight, lfsz.lf.lfWidth, lfsz.lf.lfWeight,
1115           lfsz.lf.lfItalic, lfsz.lf.lfCharSet, debugstr_w(lfsz.lf.lfFaceName));
1116     lfsz.lf.lfWidth = abs( lfsz.lf.lfWidth );
1117     lfsz.devsize.cx = X11DRV_XWStoDS( dev->hdc, lfsz.lf.lfWidth );
1118     lfsz.devsize.cy = X11DRV_YWStoDS( dev->hdc, lfsz.lf.lfHeight );
1119
1120     GetTransform( dev->hdc, 0x204, &lfsz.xform );
1121     TRACE("font transform %f %f %f %f\n", lfsz.xform.eM11, lfsz.xform.eM12,
1122           lfsz.xform.eM21, lfsz.xform.eM22);
1123
1124     /* Not used fields, would break hashing */
1125     lfsz.xform.eDx = lfsz.xform.eDy = 0;
1126
1127     lfsz_calc_hash(&lfsz);
1128
1129     EnterCriticalSection(&xrender_cs);
1130     if (physdev->cache_index != -1)
1131         dec_ref_cache( physdev->cache_index );
1132     physdev->cache_index = GetCacheEntry( dev->hdc, &lfsz );
1133     LeaveCriticalSection(&xrender_cs);
1134     physdev->x11dev->has_gdi_font = TRUE;
1135     return 0;
1136 }
1137
1138 static BOOL create_xrender_dc( PHYSDEV *pdev, enum wxr_format format )
1139 {
1140     X11DRV_PDEVICE *x11dev = get_x11drv_dev( *pdev );
1141     struct xrender_physdev *physdev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*physdev) );
1142
1143     if (!physdev) return FALSE;
1144     physdev->x11dev = x11dev;
1145     physdev->cache_index = -1;
1146     physdev->format = format;
1147     physdev->pict_format = pict_formats[format];
1148     push_dc_driver( pdev, &physdev->dev, &xrender_funcs );
1149     return TRUE;
1150 }
1151
1152 /* store the color mask data in the bitmap info structure */
1153 static void set_color_info( XRenderPictFormat *format, BITMAPINFO *info )
1154 {
1155     DWORD *colors = (DWORD *)((char *)info + info->bmiHeader.biSize);
1156
1157     info->bmiHeader.biPlanes      = 1;
1158     info->bmiHeader.biBitCount    = pixmap_formats[format->depth]->bits_per_pixel;
1159     info->bmiHeader.biCompression = BI_RGB;
1160     info->bmiHeader.biClrUsed     = 0;
1161
1162     switch (info->bmiHeader.biBitCount)
1163     {
1164     case 16:
1165         colors[0] = format->direct.redMask   << format->direct.red;
1166         colors[1] = format->direct.greenMask << format->direct.green;
1167         colors[2] = format->direct.blueMask  << format->direct.blue;
1168         info->bmiHeader.biCompression = BI_BITFIELDS;
1169         break;
1170     case 32:
1171         colors[0] = format->direct.redMask   << format->direct.red;
1172         colors[1] = format->direct.greenMask << format->direct.green;
1173         colors[2] = format->direct.blueMask  << format->direct.blue;
1174         if (colors[0] != 0xff0000 || colors[1] != 0x00ff00 || colors[2] != 0x0000ff)
1175             info->bmiHeader.biCompression = BI_BITFIELDS;
1176         break;
1177     }
1178 }
1179
1180
1181 /**********************************************************************
1182  *           xrenderdrv_CreateDC
1183  */
1184 static BOOL xrenderdrv_CreateDC( PHYSDEV *pdev, LPCWSTR driver, LPCWSTR device,
1185                                  LPCWSTR output, const DEVMODEW* initData )
1186 {
1187     return create_xrender_dc( pdev, default_format );
1188 }
1189
1190 /**********************************************************************
1191  *           xrenderdrv_CreateCompatibleDC
1192  */
1193 static BOOL xrenderdrv_CreateCompatibleDC( PHYSDEV orig, PHYSDEV *pdev )
1194 {
1195     if (orig)  /* chain to x11drv first */
1196     {
1197         orig = GET_NEXT_PHYSDEV( orig, pCreateCompatibleDC );
1198         if (!orig->funcs->pCreateCompatibleDC( orig, pdev )) return FALSE;
1199     }
1200     /* otherwise we have been called by x11drv */
1201
1202     return create_xrender_dc( pdev, WXR_FORMAT_MONO );
1203 }
1204
1205 /**********************************************************************
1206  *           xrenderdrv_DeleteDC
1207  */
1208 static BOOL xrenderdrv_DeleteDC( PHYSDEV dev )
1209 {
1210     struct xrender_physdev *physdev = get_xrender_dev( dev );
1211
1212     free_xrender_picture( physdev );
1213
1214     EnterCriticalSection( &xrender_cs );
1215     if (physdev->cache_index != -1) dec_ref_cache( physdev->cache_index );
1216     LeaveCriticalSection( &xrender_cs );
1217
1218     HeapFree( GetProcessHeap(), 0, physdev );
1219     return TRUE;
1220 }
1221
1222 /**********************************************************************
1223  *           xrenderdrv_ExtEscape
1224  */
1225 static INT xrenderdrv_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_data,
1226                                  INT out_count, LPVOID out_data )
1227 {
1228     struct xrender_physdev *physdev = get_xrender_dev( dev );
1229
1230     dev = GET_NEXT_PHYSDEV( dev, pExtEscape );
1231
1232     if (escape == X11DRV_ESCAPE && in_data && in_count >= sizeof(enum x11drv_escape_codes))
1233     {
1234         if (*(const enum x11drv_escape_codes *)in_data == X11DRV_SET_DRAWABLE)
1235         {
1236             BOOL ret = dev->funcs->pExtEscape( dev, escape, in_count, in_data, out_count, out_data );
1237             if (ret) free_xrender_picture( physdev );  /* pict format doesn't change, only drawable */
1238             return ret;
1239         }
1240     }
1241     return dev->funcs->pExtEscape( dev, escape, in_count, in_data, out_count, out_data );
1242 }
1243
1244 /****************************************************************************
1245  *        xrenderdrv_CreateBitmap
1246  */
1247 static BOOL xrenderdrv_CreateBitmap( PHYSDEV dev, HBITMAP hbitmap )
1248 {
1249     enum wxr_format format = WXR_INVALID_FORMAT;
1250     BITMAP bitmap;
1251
1252     if (!GetObjectW( hbitmap, sizeof(bitmap), &bitmap )) return FALSE;
1253
1254     if (bitmap.bmPlanes == 1 && bitmap.bmBitsPixel == screen_bpp)
1255     {
1256         switch (bitmap.bmBitsPixel)
1257         {
1258         case 16: format = WXR_FORMAT_R5G6B5; break;
1259         case 24: format = WXR_FORMAT_R8G8B8; break;
1260         case 32: format = WXR_FORMAT_A8R8G8B8; break;
1261         }
1262     }
1263
1264     if (pict_formats[format])
1265         return X11DRV_create_phys_bitmap( hbitmap, &bitmap, pict_formats[format]->depth,
1266                                           TRUE, &wxr_color_shifts[format] );
1267
1268     dev = GET_NEXT_PHYSDEV( dev, pCreateBitmap );
1269     return dev->funcs->pCreateBitmap( dev, hbitmap );
1270 }
1271
1272 /****************************************************************************
1273  *        xrenderdrv_DeleteBitmap
1274  */
1275 static BOOL xrenderdrv_DeleteBitmap( HBITMAP hbitmap )
1276 {
1277     return X11DRV_DeleteBitmap( hbitmap );
1278 }
1279
1280 /***********************************************************************
1281  *           xrenderdrv_SelectBitmap
1282  */
1283 static HBITMAP xrenderdrv_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
1284 {
1285     HBITMAP ret;
1286     struct xrender_physdev *physdev = get_xrender_dev( dev );
1287
1288     dev = GET_NEXT_PHYSDEV( dev, pSelectBitmap );
1289     ret = dev->funcs->pSelectBitmap( dev, hbitmap );
1290     if (ret)
1291     {
1292         free_xrender_picture( physdev );
1293         physdev->format = get_xrender_format_from_color_shifts( physdev->x11dev->depth,
1294                                                                 physdev->x11dev->color_shifts );
1295         physdev->pict_format = pict_formats[physdev->format];
1296     }
1297     return ret;
1298 }
1299
1300 /***********************************************************************
1301  *           xrenderdrv_GetImage
1302  */
1303 static DWORD xrenderdrv_GetImage( PHYSDEV dev, HBITMAP hbitmap, BITMAPINFO *info,
1304                                   struct gdi_image_bits *bits, struct bitblt_coords *src )
1305 {
1306     if (hbitmap) return X11DRV_GetImage( dev, hbitmap, info, bits, src );
1307     dev = GET_NEXT_PHYSDEV( dev, pGetImage );
1308     return dev->funcs->pGetImage( dev, hbitmap, info, bits, src );
1309 }
1310
1311 /***********************************************************************
1312  *           xrenderdrv_SetDeviceClipping
1313  */
1314 static void xrenderdrv_SetDeviceClipping( PHYSDEV dev, HRGN vis_rgn, HRGN clip_rgn )
1315 {
1316     struct xrender_physdev *physdev = get_xrender_dev( dev );
1317
1318     physdev->update_clip = TRUE;
1319
1320     dev = GET_NEXT_PHYSDEV( dev, pSetDeviceClipping );
1321     dev->funcs->pSetDeviceClipping( dev, vis_rgn, clip_rgn );
1322 }
1323
1324
1325 BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits_pixel, const DIBSECTION *dib)
1326 {
1327     XRenderPictFormat *pict_format;
1328     ColorShifts shifts;
1329     const DWORD *bitfields;
1330     static const DWORD bitfields_32[3] = {0xff0000, 0x00ff00, 0x0000ff};
1331     static const DWORD bitfields_16[3] = {0x7c00, 0x03e0, 0x001f};
1332
1333
1334     /* When XRender is not around we can only use the screen_depth and when needed we perform depth conversion
1335      * in software. Further we also return the screen depth for paletted formats or TrueColor formats with a low
1336      * number of bits because XRender can't handle paletted formats and 8-bit TrueColor does not exist for XRender. */
1337     if (!X11DRV_XRender_Installed || bits_pixel <= 8)
1338         return FALSE;
1339
1340     if(dib->dsBmih.biCompression == BI_BITFIELDS)
1341         bitfields = dib->dsBitfields;
1342     else if(bits_pixel == 24 || bits_pixel == 32)
1343         bitfields = bitfields_32;
1344     else
1345         bitfields = bitfields_16;
1346
1347     X11DRV_PALETTE_ComputeColorShifts(&shifts, bitfields[0], bitfields[1], bitfields[2]);
1348     pict_format = pict_formats[get_xrender_format_from_color_shifts(dib->dsBm.bmBitsPixel, &shifts)];
1349
1350     /* Common formats should be in our picture format table. */
1351     if (!pict_format)
1352     {
1353         TRACE("Unhandled dibsection format bpp=%d, redMask=%x, greenMask=%x, blueMask=%x\n",
1354               dib->dsBm.bmBitsPixel, bitfields[0], bitfields[1], bitfields[2]);
1355         return FALSE;
1356     }
1357
1358     physBitmap->depth = pict_format->depth;
1359     physBitmap->trueColor = TRUE;
1360     physBitmap->color_shifts = shifts;
1361     return TRUE;
1362 }
1363
1364 /************************************************************************
1365  *   UploadGlyph
1366  *
1367  * Helper to ExtTextOut.  Must be called inside xrender_cs
1368  */
1369 static void UploadGlyph(struct xrender_physdev *physDev, int glyph, AA_Type format)
1370 {
1371     unsigned int buflen;
1372     char *buf;
1373     Glyph gid;
1374     GLYPHMETRICS gm;
1375     XGlyphInfo gi;
1376     gsCacheEntry *entry = glyphsetCache + physDev->cache_index;
1377     gsCacheEntryFormat *formatEntry;
1378     UINT ggo_format = GGO_GLYPH_INDEX;
1379     enum wxr_format wxr_format;
1380     static const char zero[4];
1381     static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} };
1382
1383     switch(format) {
1384     case AA_Grey:
1385         ggo_format |= WINE_GGO_GRAY16_BITMAP;
1386         break;
1387     case AA_RGB:
1388         ggo_format |= WINE_GGO_HRGB_BITMAP;
1389         break;
1390     case AA_BGR:
1391         ggo_format |= WINE_GGO_HBGR_BITMAP;
1392         break;
1393     case AA_VRGB:
1394         ggo_format |= WINE_GGO_VRGB_BITMAP;
1395         break;
1396     case AA_VBGR:
1397         ggo_format |= WINE_GGO_VBGR_BITMAP;
1398         break;
1399
1400     default:
1401         ERR("aa = %d - not implemented\n", format);
1402     case AA_None:
1403         ggo_format |= GGO_BITMAP;
1404         break;
1405     }
1406
1407     buflen = GetGlyphOutlineW(physDev->dev.hdc, glyph, ggo_format, &gm, 0, NULL, &identity);
1408     if(buflen == GDI_ERROR) {
1409         if(format != AA_None) {
1410             format = AA_None;
1411             entry->aa_default = AA_None;
1412             ggo_format = GGO_GLYPH_INDEX | GGO_BITMAP;
1413             buflen = GetGlyphOutlineW(physDev->dev.hdc, glyph, ggo_format, &gm, 0, NULL, &identity);
1414         }
1415         if(buflen == GDI_ERROR) {
1416             WARN("GetGlyphOutlineW failed using default glyph\n");
1417             buflen = GetGlyphOutlineW(physDev->dev.hdc, 0, ggo_format, &gm, 0, NULL, &identity);
1418             if(buflen == GDI_ERROR) {
1419                 WARN("GetGlyphOutlineW failed for default glyph trying for space\n");
1420                 buflen = GetGlyphOutlineW(physDev->dev.hdc, 0x20, ggo_format, &gm, 0, NULL, &identity);
1421                 if(buflen == GDI_ERROR) {
1422                     ERR("GetGlyphOutlineW for all attempts unable to upload a glyph\n");
1423                     return;
1424                 }
1425             }
1426         }
1427         TRACE("Turning off antialiasing for this monochrome font\n");
1428     }
1429
1430     /* If there is nothing for the current type, we create the entry. */
1431     if( !entry->format[format] ) {
1432         entry->format[format] = HeapAlloc(GetProcessHeap(),
1433                                           HEAP_ZERO_MEMORY,
1434                                           sizeof(gsCacheEntryFormat));
1435     }
1436     formatEntry = entry->format[format];
1437
1438     if(formatEntry->nrealized <= glyph) {
1439         formatEntry->nrealized = (glyph / 128 + 1) * 128;
1440
1441         if (formatEntry->realized)
1442             formatEntry->realized = HeapReAlloc(GetProcessHeap(),
1443                                       HEAP_ZERO_MEMORY,
1444                                       formatEntry->realized,
1445                                       formatEntry->nrealized * sizeof(BOOL));
1446         else
1447             formatEntry->realized = HeapAlloc(GetProcessHeap(),
1448                                       HEAP_ZERO_MEMORY,
1449                                       formatEntry->nrealized * sizeof(BOOL));
1450
1451         if(!X11DRV_XRender_Installed) {
1452           if (formatEntry->bitmaps)
1453             formatEntry->bitmaps = HeapReAlloc(GetProcessHeap(),
1454                                       HEAP_ZERO_MEMORY,
1455                                       formatEntry->bitmaps,
1456                                       formatEntry->nrealized * sizeof(formatEntry->bitmaps[0]));
1457           else
1458             formatEntry->bitmaps = HeapAlloc(GetProcessHeap(),
1459                                       HEAP_ZERO_MEMORY,
1460                                       formatEntry->nrealized * sizeof(formatEntry->bitmaps[0]));
1461         }
1462         if (formatEntry->gis)
1463             formatEntry->gis = HeapReAlloc(GetProcessHeap(),
1464                                    HEAP_ZERO_MEMORY,
1465                                    formatEntry->gis,
1466                                    formatEntry->nrealized * sizeof(formatEntry->gis[0]));
1467         else
1468             formatEntry->gis = HeapAlloc(GetProcessHeap(),
1469                                    HEAP_ZERO_MEMORY,
1470                                    formatEntry->nrealized * sizeof(formatEntry->gis[0]));
1471     }
1472
1473
1474     if(formatEntry->glyphset == 0 && X11DRV_XRender_Installed) {
1475         switch(format) {
1476             case AA_Grey:
1477                 wxr_format = WXR_FORMAT_GRAY;
1478                 break;
1479
1480             case AA_RGB:
1481             case AA_BGR:
1482             case AA_VRGB:
1483             case AA_VBGR:
1484                 wxr_format = WXR_FORMAT_A8R8G8B8;
1485                 break;
1486
1487             default:
1488                 ERR("aa = %d - not implemented\n", format);
1489             case AA_None:
1490                 wxr_format = WXR_FORMAT_MONO;
1491                 break;
1492         }
1493
1494         wine_tsx11_lock();
1495         formatEntry->font_format = pict_formats[wxr_format];
1496         formatEntry->glyphset = pXRenderCreateGlyphSet(gdi_display, formatEntry->font_format);
1497         wine_tsx11_unlock();
1498     }
1499
1500
1501     buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buflen);
1502     GetGlyphOutlineW(physDev->dev.hdc, glyph, ggo_format, &gm, buflen, buf, &identity);
1503     formatEntry->realized[glyph] = TRUE;
1504
1505     TRACE("buflen = %d. Got metrics: %dx%d adv=%d,%d origin=%d,%d\n",
1506           buflen,
1507           gm.gmBlackBoxX, gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY,
1508           gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y);
1509
1510     gi.width = gm.gmBlackBoxX;
1511     gi.height = gm.gmBlackBoxY;
1512     gi.x = -gm.gmptGlyphOrigin.x;
1513     gi.y = gm.gmptGlyphOrigin.y;
1514     gi.xOff = gm.gmCellIncX;
1515     gi.yOff = gm.gmCellIncY;
1516
1517     if(TRACE_ON(xrender)) {
1518         int pitch, i, j;
1519         char output[300];
1520         unsigned char *line;
1521
1522         if(format == AA_None) {
1523             pitch = ((gi.width + 31) / 32) * 4;
1524             for(i = 0; i < gi.height; i++) {
1525                 line = (unsigned char*) buf + i * pitch;
1526                 output[0] = '\0';
1527                 for(j = 0; j < pitch * 8; j++) {
1528                     strcat(output, (line[j / 8] & (1 << (7 - (j % 8)))) ? "#" : " ");
1529                 }
1530                 TRACE("%s\n", output);
1531             }
1532         } else {
1533             static const char blks[] = " .:;!o*#";
1534             char str[2];
1535
1536             str[1] = '\0';
1537             pitch = ((gi.width + 3) / 4) * 4;
1538             for(i = 0; i < gi.height; i++) {
1539                 line = (unsigned char*) buf + i * pitch;
1540                 output[0] = '\0';
1541                 for(j = 0; j < pitch; j++) {
1542                     str[0] = blks[line[j] >> 5];
1543                     strcat(output, str);
1544                 }
1545                 TRACE("%s\n", output);
1546             }
1547         }
1548     }
1549
1550
1551     if(formatEntry->glyphset) {
1552         if(format == AA_None && BitmapBitOrder(gdi_display) != MSBFirst) {
1553             unsigned char *byte = (unsigned char*) buf, c;
1554             int i = buflen;
1555
1556             while(i--) {
1557                 c = *byte;
1558
1559                 /* magic to flip bit order */
1560                 c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
1561                 c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
1562                 c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
1563
1564                 *byte++ = c;
1565             }
1566         }
1567         else if ( format != AA_Grey &&
1568                   ImageByteOrder (gdi_display) != NATIVE_BYTE_ORDER)
1569         {
1570             unsigned int i, *data = (unsigned int *)buf;
1571             for (i = buflen / sizeof(int); i; i--, data++) *data = RtlUlongByteSwap(*data);
1572         }
1573         gid = glyph;
1574
1575         /*
1576           XRenderCompositeText seems to ignore 0x0 glyphs when
1577           AA_None, which means we lose the advance width of glyphs
1578           like the space.  We'll pretend that such glyphs are 1x1
1579           bitmaps.
1580         */
1581
1582         if(buflen == 0)
1583             gi.width = gi.height = 1;
1584
1585         wine_tsx11_lock();
1586         pXRenderAddGlyphs(gdi_display, formatEntry->glyphset, &gid, &gi, 1,
1587                           buflen ? buf : zero, buflen ? buflen : sizeof(zero));
1588         wine_tsx11_unlock();
1589         HeapFree(GetProcessHeap(), 0, buf);
1590     } else {
1591         formatEntry->bitmaps[glyph] = buf;
1592     }
1593
1594     formatEntry->gis[glyph] = gi;
1595 }
1596
1597 static void SharpGlyphMono(struct xrender_physdev *physDev, INT x, INT y,
1598                             void *bitmap, XGlyphInfo *gi)
1599 {
1600     unsigned char   *srcLine = bitmap, *src;
1601     unsigned char   bits, bitsMask;
1602     int             width = gi->width;
1603     int             stride = ((width + 31) & ~31) >> 3;
1604     int             height = gi->height;
1605     int             w;
1606     int             xspan, lenspan;
1607
1608     TRACE("%d, %d\n", x, y);
1609     x -= gi->x;
1610     y -= gi->y;
1611     while (height--)
1612     {
1613         src = srcLine;
1614         srcLine += stride;
1615         w = width;
1616         
1617         bitsMask = 0x80;    /* FreeType is always MSB first */
1618         bits = *src++;
1619         
1620         xspan = x;
1621         while (w)
1622         {
1623             if (bits & bitsMask)
1624             {
1625                 lenspan = 0;
1626                 do
1627                 {
1628                     lenspan++;
1629                     if (lenspan == w)
1630                         break;
1631                     bitsMask = bitsMask >> 1;
1632                     if (!bitsMask)
1633                     {
1634                         bits = *src++;
1635                         bitsMask = 0x80;
1636                     }
1637                 } while (bits & bitsMask);
1638                 XFillRectangle (gdi_display, physDev->x11dev->drawable,
1639                                 physDev->x11dev->gc, xspan, y, lenspan, 1);
1640                 xspan += lenspan;
1641                 w -= lenspan;
1642             }
1643             else
1644             {
1645                 do
1646                 {
1647                     w--;
1648                     xspan++;
1649                     if (!w)
1650                         break;
1651                     bitsMask = bitsMask >> 1;
1652                     if (!bitsMask)
1653                     {
1654                         bits = *src++;
1655                         bitsMask = 0x80;
1656                     }
1657                 } while (!(bits & bitsMask));
1658             }
1659         }
1660         y++;
1661     }
1662 }
1663
1664 static void SharpGlyphGray(struct xrender_physdev *physDev, INT x, INT y,
1665                             void *bitmap, XGlyphInfo *gi)
1666 {
1667     unsigned char   *srcLine = bitmap, *src, bits;
1668     int             width = gi->width;
1669     int             stride = ((width + 3) & ~3);
1670     int             height = gi->height;
1671     int             w;
1672     int             xspan, lenspan;
1673
1674     x -= gi->x;
1675     y -= gi->y;
1676     while (height--)
1677     {
1678         src = srcLine;
1679         srcLine += stride;
1680         w = width;
1681         
1682         bits = *src++;
1683         xspan = x;
1684         while (w)
1685         {
1686             if (bits >= 0x80)
1687             {
1688                 lenspan = 0;
1689                 do
1690                 {
1691                     lenspan++;
1692                     if (lenspan == w)
1693                         break;
1694                     bits = *src++;
1695                 } while (bits >= 0x80);
1696                 XFillRectangle (gdi_display, physDev->x11dev->drawable,
1697                                 physDev->x11dev->gc, xspan, y, lenspan, 1);
1698                 xspan += lenspan;
1699                 w -= lenspan;
1700             }
1701             else
1702             {
1703                 do
1704                 {
1705                     w--;
1706                     xspan++;
1707                     if (!w)
1708                         break;
1709                     bits = *src++;
1710                 } while (bits < 0x80);
1711             }
1712         }
1713         y++;
1714     }
1715 }
1716
1717
1718 static void ExamineBitfield (DWORD mask, int *shift, int *len)
1719 {
1720     int s, l;
1721
1722     s = 0;
1723     while ((mask & 1) == 0)
1724     {
1725         mask >>= 1;
1726         s++;
1727     }
1728     l = 0;
1729     while ((mask & 1) == 1)
1730     {
1731         mask >>= 1;
1732         l++;
1733     }
1734     *shift = s;
1735     *len = l;
1736 }
1737
1738 static DWORD GetField (DWORD pixel, int shift, int len)
1739 {
1740     pixel = pixel & (((1 << (len)) - 1) << shift);
1741     pixel = pixel << (32 - (shift + len)) >> 24;
1742     while (len < 8)
1743     {
1744         pixel |= (pixel >> len);
1745         len <<= 1;
1746     }
1747     return pixel;
1748 }
1749
1750
1751 static DWORD PutField (DWORD pixel, int shift, int len)
1752 {
1753     shift = shift - (8 - len);
1754     if (len <= 8)
1755         pixel &= (((1 << len) - 1) << (8 - len));
1756     if (shift < 0)
1757         pixel >>= -shift;
1758     else
1759         pixel <<= shift;
1760     return pixel;
1761 }
1762
1763 static void SmoothGlyphGray(XImage *image, int x, int y, void *bitmap, XGlyphInfo *gi,
1764                             int color)
1765 {
1766     int             r_shift, r_len;
1767     int             g_shift, g_len;
1768     int             b_shift, b_len;
1769     BYTE            *maskLine, *mask, m;
1770     int             maskStride;
1771     DWORD           pixel;
1772     int             width, height;
1773     int             w, tx;
1774     BYTE            src_r, src_g, src_b;
1775
1776     x -= gi->x;
1777     y -= gi->y;
1778     width = gi->width;
1779     height = gi->height;
1780
1781     maskLine = bitmap;
1782     maskStride = (width + 3) & ~3;
1783
1784     ExamineBitfield (image->red_mask, &r_shift, &r_len);
1785     ExamineBitfield (image->green_mask, &g_shift, &g_len);
1786     ExamineBitfield (image->blue_mask, &b_shift, &b_len);
1787
1788     src_r = GetField(color, r_shift, r_len);
1789     src_g = GetField(color, g_shift, g_len);
1790     src_b = GetField(color, b_shift, b_len);
1791     
1792     for(; height--; y++)
1793     {
1794         mask = maskLine;
1795         maskLine += maskStride;
1796         w = width;
1797         tx = x;
1798
1799         if(y < 0) continue;
1800         if(y >= image->height) break;
1801
1802         for(; w--; tx++)
1803         {
1804             if(tx >= image->width) break;
1805
1806             m = *mask++;
1807             if(tx < 0) continue;
1808
1809             if (m == 0xff)
1810                 XPutPixel (image, tx, y, color);
1811             else if (m)
1812             {
1813                 BYTE r, g, b;
1814
1815                 pixel = XGetPixel (image, tx, y);
1816
1817                 r = GetField(pixel, r_shift, r_len);
1818                 r = ((BYTE)~m * (WORD)r + (BYTE)m * (WORD)src_r) >> 8;
1819                 g = GetField(pixel, g_shift, g_len);
1820                 g = ((BYTE)~m * (WORD)g + (BYTE)m * (WORD)src_g) >> 8;
1821                 b = GetField(pixel, b_shift, b_len);
1822                 b = ((BYTE)~m * (WORD)b + (BYTE)m * (WORD)src_b) >> 8;
1823
1824                 pixel = (PutField (r, r_shift, r_len) |
1825                          PutField (g, g_shift, g_len) |
1826                          PutField (b, b_shift, b_len));
1827                 XPutPixel (image, tx, y, pixel);
1828             }
1829         }
1830     }
1831 }
1832
1833 /*************************************************************
1834  *                 get_tile_pict
1835  *
1836  * Returns an appropriate Picture for tiling the text colour.
1837  * Call and use result within the xrender_cs
1838  */
1839 static Picture get_tile_pict( enum wxr_format wxr_format, const XRenderColor *color)
1840 {
1841     static struct
1842     {
1843         Pixmap xpm;
1844         Picture pict;
1845         XRenderColor current_color;
1846     } tiles[WXR_NB_FORMATS], *tile;
1847
1848     tile = &tiles[wxr_format];
1849
1850     if(!tile->xpm)
1851     {
1852         XRenderPictureAttributes pa;
1853         XRenderPictFormat *pict_format = pict_formats[wxr_format];
1854
1855         wine_tsx11_lock();
1856         tile->xpm = XCreatePixmap(gdi_display, root_window, 1, 1, pict_format->depth);
1857
1858         pa.repeat = RepeatNormal;
1859         tile->pict = pXRenderCreatePicture(gdi_display, tile->xpm, pict_format, CPRepeat, &pa);
1860         wine_tsx11_unlock();
1861
1862         /* init current_color to something different from text_pixel */
1863         tile->current_color = *color;
1864         tile->current_color.red ^= 0xffff;
1865
1866         if (wxr_format == WXR_FORMAT_MONO)
1867         {
1868             /* for a 1bpp bitmap we always need a 1 in the tile */
1869             XRenderColor col;
1870             col.red = col.green = col.blue = 0;
1871             col.alpha = 0xffff;
1872             wine_tsx11_lock();
1873             pXRenderFillRectangle(gdi_display, PictOpSrc, tile->pict, &col, 0, 0, 1, 1);
1874             wine_tsx11_unlock();
1875         }
1876     }
1877
1878     if (memcmp( color, &tile->current_color, sizeof(*color) ) && wxr_format != WXR_FORMAT_MONO)
1879     {
1880         wine_tsx11_lock();
1881         pXRenderFillRectangle(gdi_display, PictOpSrc, tile->pict, color, 0, 0, 1, 1);
1882         wine_tsx11_unlock();
1883         tile->current_color = *color;
1884     }
1885     return tile->pict;
1886 }
1887
1888 /*************************************************************
1889  *                 get_mask_pict
1890  *
1891  * Returns an appropriate Picture for masking with the specified alpha.
1892  * Call and use result within the xrender_cs
1893  */
1894 static Picture get_mask_pict( int alpha )
1895 {
1896     static Pixmap pixmap;
1897     static Picture pict;
1898     static int current_alpha;
1899
1900     if (alpha == 0xffff) return 0;  /* don't need a mask for alpha==1.0 */
1901
1902     if (!pixmap)
1903     {
1904         XRenderPictureAttributes pa;
1905
1906         wine_tsx11_lock();
1907         pixmap = XCreatePixmap( gdi_display, root_window, 1, 1, 32 );
1908         pa.repeat = RepeatNormal;
1909         pict = pXRenderCreatePicture( gdi_display, pixmap,
1910                                       pict_formats[WXR_FORMAT_A8R8G8B8], CPRepeat, &pa );
1911         wine_tsx11_unlock();
1912         current_alpha = -1;
1913     }
1914
1915     if (alpha != current_alpha)
1916     {
1917         XRenderColor col;
1918         col.red = col.green = col.blue = 0;
1919         col.alpha = current_alpha = alpha;
1920         wine_tsx11_lock();
1921         pXRenderFillRectangle( gdi_display, PictOpSrc, pict, &col, 0, 0, 1, 1 );
1922         wine_tsx11_unlock();
1923     }
1924     return pict;
1925 }
1926
1927 static int XRenderErrorHandler(Display *dpy, XErrorEvent *event, void *arg)
1928 {
1929     return 1;
1930 }
1931
1932 /********************************************************************
1933  *                   is_dib_with_colortable
1934  *
1935  * Return TRUE if physdev is backed by a dibsection with <= 8 bits per pixel
1936  */
1937 static inline BOOL is_dib_with_colortable( X11DRV_PDEVICE *physDev )
1938 {
1939     DIBSECTION dib;
1940
1941     if( physDev->bitmap && GetObjectW( physDev->bitmap->hbitmap, sizeof(dib), &dib ) == sizeof(dib) &&
1942         dib.dsBmih.biBitCount <= 8 )
1943         return TRUE;
1944
1945     return FALSE;
1946 }
1947
1948 /***********************************************************************
1949  *           xrenderdrv_ExtTextOut
1950  */
1951 static BOOL xrenderdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
1952                                    const RECT *lprect, LPCWSTR wstr, UINT count, const INT *lpDx )
1953 {
1954     struct xrender_physdev *physdev = get_xrender_dev( dev );
1955     XGCValues xgcval;
1956     gsCacheEntry *entry;
1957     gsCacheEntryFormat *formatEntry;
1958     BOOL retv = FALSE;
1959     int textPixel, backgroundPixel;
1960     RGNDATA *saved_region = NULL;
1961     BOOL disable_antialias = FALSE;
1962     AA_Type aa_type = AA_None;
1963     unsigned int idx;
1964     Picture tile_pict = 0;
1965
1966     if (!physdev->x11dev->has_gdi_font)
1967     {
1968         dev = GET_NEXT_PHYSDEV( dev, pExtTextOut );
1969         return dev->funcs->pExtTextOut( dev, x, y, flags, lprect, wstr, count, lpDx );
1970     }
1971
1972     if(is_dib_with_colortable( physdev->x11dev ))
1973     {
1974         TRACE("Disabling antialiasing\n");
1975         disable_antialias = TRUE;
1976     }
1977
1978     xgcval.function = GXcopy;
1979     xgcval.background = physdev->x11dev->backgroundPixel;
1980     xgcval.fill_style = FillSolid;
1981     wine_tsx11_lock();
1982     XChangeGC( gdi_display, physdev->x11dev->gc, GCFunction | GCBackground | GCFillStyle, &xgcval );
1983     wine_tsx11_unlock();
1984
1985     X11DRV_LockDIBSection( physdev->x11dev, DIB_Status_GdiMod );
1986
1987     if(physdev->x11dev->depth == 1) {
1988         if((physdev->x11dev->textPixel & 0xffffff) == 0) {
1989             textPixel = 0;
1990             backgroundPixel = 1;
1991         } else {
1992             textPixel = 1;
1993             backgroundPixel = 0;
1994         }
1995     } else {
1996         textPixel = physdev->x11dev->textPixel;
1997         backgroundPixel = physdev->x11dev->backgroundPixel;
1998     }
1999
2000     if(flags & ETO_OPAQUE)
2001     {
2002         wine_tsx11_lock();
2003         XSetForeground( gdi_display, physdev->x11dev->gc, backgroundPixel );
2004         XFillRectangle( gdi_display, physdev->x11dev->drawable, physdev->x11dev->gc,
2005                         physdev->x11dev->dc_rect.left + lprect->left, physdev->x11dev->dc_rect.top + lprect->top,
2006                         lprect->right - lprect->left, lprect->bottom - lprect->top );
2007         wine_tsx11_unlock();
2008     }
2009
2010     if(count == 0)
2011     {
2012         retv = TRUE;
2013         goto done_unlock;
2014     }
2015
2016     EnterCriticalSection(&xrender_cs);
2017
2018     entry = glyphsetCache + physdev->cache_index;
2019     if( disable_antialias == FALSE )
2020         aa_type = entry->aa_default;
2021     formatEntry = entry->format[aa_type];
2022
2023     for(idx = 0; idx < count; idx++) {
2024         if( !formatEntry ) {
2025             UploadGlyph(physdev, wstr[idx], aa_type);
2026             /* re-evaluate antialias since aa_default may have changed */
2027             if( disable_antialias == FALSE )
2028                 aa_type = entry->aa_default;
2029             formatEntry = entry->format[aa_type];
2030         } else if( wstr[idx] >= formatEntry->nrealized || formatEntry->realized[wstr[idx]] == FALSE) {
2031             UploadGlyph(physdev, wstr[idx], aa_type);
2032         }
2033     }
2034     if (!formatEntry)
2035     {
2036         WARN("could not upload requested glyphs\n");
2037         LeaveCriticalSection(&xrender_cs);
2038         goto done_unlock;
2039     }
2040
2041     TRACE("Writing %s at %d,%d\n", debugstr_wn(wstr,count),
2042           physdev->x11dev->dc_rect.left + x, physdev->x11dev->dc_rect.top + y);
2043
2044     if(X11DRV_XRender_Installed)
2045     {
2046         XGlyphElt16 *elts = HeapAlloc(GetProcessHeap(), 0, sizeof(XGlyphElt16) * count);
2047         POINT offset = {0, 0};
2048         POINT desired, current;
2049         int render_op = PictOpOver;
2050         Picture pict = get_xrender_picture( physdev, 0, (flags & ETO_CLIPPED) ? lprect : NULL );
2051         XRenderColor col;
2052
2053         /* There's a bug in XRenderCompositeText that ignores the xDst and yDst parameters.
2054            So we pass zeros to the function and move to our starting position using the first
2055            element of the elts array. */
2056
2057         desired.x = physdev->x11dev->dc_rect.left + x;
2058         desired.y = physdev->x11dev->dc_rect.top + y;
2059         current.x = current.y = 0;
2060
2061         get_xrender_color(physdev->pict_format, physdev->x11dev->textPixel, &col);
2062         tile_pict = get_tile_pict(physdev->format, &col);
2063
2064         /* FIXME the mapping of Text/BkColor onto 1 or 0 needs investigation.
2065          */
2066         if((physdev->format == WXR_FORMAT_MONO) && (textPixel == 0))
2067             render_op = PictOpOutReverse; /* This gives us 'black' text */
2068
2069         for(idx = 0; idx < count; idx++)
2070         {
2071             elts[idx].glyphset = formatEntry->glyphset;
2072             elts[idx].chars = wstr + idx;
2073             elts[idx].nchars = 1;
2074             elts[idx].xOff = desired.x - current.x;
2075             elts[idx].yOff = desired.y - current.y;
2076
2077             current.x += (elts[idx].xOff + formatEntry->gis[wstr[idx]].xOff);
2078             current.y += (elts[idx].yOff + formatEntry->gis[wstr[idx]].yOff);
2079
2080             if(!lpDx)
2081             {
2082                 desired.x += formatEntry->gis[wstr[idx]].xOff;
2083                 desired.y += formatEntry->gis[wstr[idx]].yOff;
2084             }
2085             else
2086             {
2087                 if(flags & ETO_PDY)
2088                 {
2089                     offset.x += lpDx[idx * 2];
2090                     offset.y += lpDx[idx * 2 + 1];
2091                 }
2092                 else
2093                     offset.x += lpDx[idx];
2094                 desired.x = physdev->x11dev->dc_rect.left + x + offset.x;
2095                 desired.y = physdev->x11dev->dc_rect.top  + y + offset.y;
2096             }
2097         }
2098
2099         wine_tsx11_lock();
2100         /* Make sure we don't have any transforms set from a previous call */
2101         set_xrender_transformation(pict, 1, 1, 0, 0);
2102         pXRenderCompositeText16(gdi_display, render_op,
2103                                 tile_pict,
2104                                 pict,
2105                                 formatEntry->font_format,
2106                                 0, 0, 0, 0, elts, count);
2107         wine_tsx11_unlock();
2108         HeapFree(GetProcessHeap(), 0, elts);
2109     } else {
2110         POINT offset = {0, 0};
2111
2112         if (flags & ETO_CLIPPED)
2113         {
2114             HRGN clip_region = CreateRectRgnIndirect( lprect );
2115             saved_region = add_extra_clipping_region( physdev->x11dev, clip_region );
2116             DeleteObject( clip_region );
2117         }
2118
2119         wine_tsx11_lock();
2120         XSetForeground( gdi_display, physdev->x11dev->gc, textPixel );
2121
2122         if(aa_type == AA_None || physdev->x11dev->depth == 1)
2123         {
2124             void (* sharp_glyph_fn)(struct xrender_physdev *, INT, INT, void *, XGlyphInfo *);
2125
2126             if(aa_type == AA_None)
2127                 sharp_glyph_fn = SharpGlyphMono;
2128             else
2129                 sharp_glyph_fn = SharpGlyphGray;
2130
2131             for(idx = 0; idx < count; idx++) {
2132                 sharp_glyph_fn(physdev,
2133                                physdev->x11dev->dc_rect.left + x + offset.x,
2134                                physdev->x11dev->dc_rect.top  + y + offset.y,
2135                                formatEntry->bitmaps[wstr[idx]],
2136                                &formatEntry->gis[wstr[idx]]);
2137                 if(lpDx)
2138                 {
2139                     if(flags & ETO_PDY)
2140                     {
2141                         offset.x += lpDx[idx * 2];
2142                         offset.y += lpDx[idx * 2 + 1];
2143                     }
2144                     else
2145                         offset.x += lpDx[idx];
2146                 }
2147                 else
2148                 {
2149                     offset.x += formatEntry->gis[wstr[idx]].xOff;
2150                     offset.y += formatEntry->gis[wstr[idx]].yOff;
2151                 }
2152             }
2153         } else {
2154             XImage *image;
2155             int image_x, image_y, image_off_x, image_off_y, image_w, image_h;
2156             RECT extents = {0, 0, 0, 0};
2157             POINT cur = {0, 0};
2158             int w = physdev->x11dev->drawable_rect.right - physdev->x11dev->drawable_rect.left;
2159             int h = physdev->x11dev->drawable_rect.bottom - physdev->x11dev->drawable_rect.top;
2160
2161             TRACE("drawable %dx%d\n", w, h);
2162
2163             for(idx = 0; idx < count; idx++) {
2164                 if(extents.left > cur.x - formatEntry->gis[wstr[idx]].x)
2165                     extents.left = cur.x - formatEntry->gis[wstr[idx]].x;
2166                 if(extents.top > cur.y - formatEntry->gis[wstr[idx]].y)
2167                     extents.top = cur.y - formatEntry->gis[wstr[idx]].y;
2168                 if(extents.right < cur.x - formatEntry->gis[wstr[idx]].x + formatEntry->gis[wstr[idx]].width)
2169                     extents.right = cur.x - formatEntry->gis[wstr[idx]].x + formatEntry->gis[wstr[idx]].width;
2170                 if(extents.bottom < cur.y - formatEntry->gis[wstr[idx]].y + formatEntry->gis[wstr[idx]].height)
2171                     extents.bottom = cur.y - formatEntry->gis[wstr[idx]].y + formatEntry->gis[wstr[idx]].height;
2172
2173                 if(lpDx)
2174                 {
2175                     if(flags & ETO_PDY)
2176                     {
2177                         cur.x += lpDx[idx * 2];
2178                         cur.y += lpDx[idx * 2 + 1];
2179                     }
2180                     else
2181                         cur.x += lpDx[idx];
2182                 }
2183                 else
2184                 {
2185                     cur.x += formatEntry->gis[wstr[idx]].xOff;
2186                     cur.y += formatEntry->gis[wstr[idx]].yOff;
2187                 }
2188             }
2189             TRACE("glyph extents %d,%d - %d,%d drawable x,y %d,%d\n", extents.left, extents.top,
2190                   extents.right, extents.bottom, physdev->x11dev->dc_rect.left + x, physdev->x11dev->dc_rect.top + y);
2191
2192             if(physdev->x11dev->dc_rect.left + x + extents.left >= 0) {
2193                 image_x = physdev->x11dev->dc_rect.left + x + extents.left;
2194                 image_off_x = 0;
2195             } else {
2196                 image_x = 0;
2197                 image_off_x = physdev->x11dev->dc_rect.left + x + extents.left;
2198             }
2199             if(physdev->x11dev->dc_rect.top + y + extents.top >= 0) {
2200                 image_y = physdev->x11dev->dc_rect.top + y + extents.top;
2201                 image_off_y = 0;
2202             } else {
2203                 image_y = 0;
2204                 image_off_y = physdev->x11dev->dc_rect.top + y + extents.top;
2205             }
2206             if(physdev->x11dev->dc_rect.left + x + extents.right < w)
2207                 image_w = physdev->x11dev->dc_rect.left + x + extents.right - image_x;
2208             else
2209                 image_w = w - image_x;
2210             if(physdev->x11dev->dc_rect.top + y + extents.bottom < h)
2211                 image_h = physdev->x11dev->dc_rect.top + y + extents.bottom - image_y;
2212             else
2213                 image_h = h - image_y;
2214
2215             if(image_w <= 0 || image_h <= 0) goto no_image;
2216
2217             X11DRV_expect_error(gdi_display, XRenderErrorHandler, NULL);
2218             image = XGetImage(gdi_display, physdev->x11dev->drawable,
2219                               image_x, image_y, image_w, image_h,
2220                               AllPlanes, ZPixmap);
2221             X11DRV_check_error();
2222
2223             TRACE("XGetImage(%p, %x, %d, %d, %d, %d, %lx, %x) depth = %d rets %p\n",
2224                   gdi_display, (int)physdev->x11dev->drawable, image_x, image_y,
2225                   image_w, image_h, AllPlanes, ZPixmap,
2226                   physdev->x11dev->depth, image);
2227             if(!image) {
2228                 Pixmap xpm = XCreatePixmap(gdi_display, root_window, image_w, image_h,
2229                                            physdev->x11dev->depth);
2230                 GC gc;
2231                 XGCValues gcv;
2232
2233                 gcv.graphics_exposures = False;
2234                 gc = XCreateGC(gdi_display, xpm, GCGraphicsExposures, &gcv);
2235                 XCopyArea(gdi_display, physdev->x11dev->drawable, xpm, gc, image_x, image_y,
2236                           image_w, image_h, 0, 0);
2237                 XFreeGC(gdi_display, gc);
2238                 X11DRV_expect_error(gdi_display, XRenderErrorHandler, NULL);
2239                 image = XGetImage(gdi_display, xpm, 0, 0, image_w, image_h, AllPlanes,
2240                                   ZPixmap);
2241                 X11DRV_check_error();
2242                 XFreePixmap(gdi_display, xpm);
2243             }
2244             if(!image) goto no_image;
2245
2246             image->red_mask = visual->red_mask;
2247             image->green_mask = visual->green_mask;
2248             image->blue_mask = visual->blue_mask;
2249
2250             for(idx = 0; idx < count; idx++) {
2251                 SmoothGlyphGray(image,
2252                                 offset.x + image_off_x - extents.left,
2253                                 offset.y + image_off_y - extents.top,
2254                                 formatEntry->bitmaps[wstr[idx]],
2255                                 &formatEntry->gis[wstr[idx]],
2256                                 physdev->x11dev->textPixel);
2257                 if(lpDx)
2258                 {
2259                     if(flags & ETO_PDY)
2260                     {
2261                         offset.x += lpDx[idx * 2];
2262                         offset.y += lpDx[idx * 2 + 1];
2263                     }
2264                     else
2265                         offset.x += lpDx[idx];
2266                 }
2267                 else
2268                 {
2269                     offset.x += formatEntry->gis[wstr[idx]].xOff;
2270                     offset.y += formatEntry->gis[wstr[idx]].yOff;
2271                 }
2272             }
2273             XPutImage(gdi_display, physdev->x11dev->drawable, physdev->x11dev->gc, image, 0, 0,
2274                       image_x, image_y, image_w, image_h);
2275             XDestroyImage(image);
2276         }
2277     no_image:
2278         wine_tsx11_unlock();
2279         restore_clipping_region( physdev->x11dev, saved_region );
2280     }
2281     LeaveCriticalSection(&xrender_cs);
2282     retv = TRUE;
2283
2284 done_unlock:
2285     X11DRV_UnlockDIBSection( physdev->x11dev, TRUE );
2286     return retv;
2287 }
2288
2289 /* multiply the alpha channel of a picture */
2290 static void multiply_alpha( Picture pict, XRenderPictFormat *format, int alpha,
2291                             int x, int y, int width, int height )
2292 {
2293     XRenderPictureAttributes pa;
2294     Pixmap src_pixmap, mask_pixmap;
2295     Picture src_pict, mask_pict;
2296     XRenderColor color;
2297
2298     wine_tsx11_lock();
2299     src_pixmap = XCreatePixmap( gdi_display, root_window, 1, 1, format->depth );
2300     mask_pixmap = XCreatePixmap( gdi_display, root_window, 1, 1, format->depth );
2301     pa.repeat = RepeatNormal;
2302     src_pict = pXRenderCreatePicture( gdi_display, src_pixmap, format, CPRepeat, &pa );
2303     pa.component_alpha = True;
2304     mask_pict = pXRenderCreatePicture( gdi_display, mask_pixmap, format, CPRepeat|CPComponentAlpha, &pa );
2305     color.red = color.green = color.blue = color.alpha = 0xffff;
2306     pXRenderFillRectangle( gdi_display, PictOpSrc, src_pict, &color, 0, 0, 1, 1 );
2307     color.alpha = alpha;
2308     pXRenderFillRectangle( gdi_display, PictOpSrc, mask_pict, &color, 0, 0, 1, 1 );
2309     pXRenderComposite( gdi_display, PictOpInReverse, src_pict, mask_pict, pict,
2310                        0, 0, 0, 0, x, y, width, height );
2311     pXRenderFreePicture( gdi_display, src_pict );
2312     pXRenderFreePicture( gdi_display, mask_pict );
2313     XFreePixmap( gdi_display, src_pixmap );
2314     XFreePixmap( gdi_display, mask_pixmap );
2315     wine_tsx11_unlock();
2316 }
2317
2318 /* Helper function for (stretched) blitting using xrender */
2319 static void xrender_blit( int op, Picture src_pict, Picture mask_pict, Picture dst_pict,
2320                           int x_src, int y_src, int x_dst, int y_dst,
2321                           double xscale, double yscale, int width, int height )
2322 {
2323     int x_offset, y_offset;
2324
2325     /* When we need to scale we perform scaling and source_x / source_y translation using a transformation matrix.
2326      * This is needed because XRender is inaccurate in combination with scaled source coordinates passed to XRenderComposite.
2327      * In all other cases we do use XRenderComposite for translation as it is faster than using a transformation matrix. */
2328     wine_tsx11_lock();
2329     if(xscale != 1.0 || yscale != 1.0)
2330     {
2331         /* In case of mirroring we need a source x- and y-offset because without the pixels will be
2332          * in the wrong quadrant of the x-y plane.
2333          */
2334         x_offset = (xscale < 0) ? -width : 0;
2335         y_offset = (yscale < 0) ? -height : 0;
2336         set_xrender_transformation(src_pict, xscale, yscale, x_src, y_src);
2337     }
2338     else
2339     {
2340         x_offset = x_src;
2341         y_offset = y_src;
2342         set_xrender_transformation(src_pict, 1, 1, 0, 0);
2343     }
2344     pXRenderComposite( gdi_display, op, src_pict, mask_pict, dst_pict,
2345                        x_offset, y_offset, 0, 0, x_dst, y_dst, width, height );
2346     wine_tsx11_unlock();
2347 }
2348
2349 /* Helper function for (stretched) mono->color blitting using xrender */
2350 static void xrender_mono_blit( Picture src_pict, Picture dst_pict,
2351                                enum wxr_format dst_format, XRenderColor *fg, XRenderColor *bg,
2352                                int x_src, int y_src, int x_dst, int y_dst,
2353                                double xscale, double yscale, int width, int height )
2354 {
2355     Picture tile_pict;
2356     int x_offset, y_offset;
2357     XRenderColor color;
2358
2359     /* When doing a mono->color blit, the source data is used as mask, and the source picture
2360      * contains a 1x1 picture for tiling. The source data effectively acts as an alpha channel to
2361      * the tile data.
2362      */
2363     EnterCriticalSection( &xrender_cs );
2364     color = *bg;
2365     color.alpha = 0xffff;  /* tile pict needs 100% alpha */
2366     tile_pict = get_tile_pict( dst_format, &color );
2367
2368     wine_tsx11_lock();
2369     pXRenderFillRectangle( gdi_display, PictOpSrc, dst_pict, fg, x_dst, y_dst, width, height );
2370
2371     if (xscale != 1.0 || yscale != 1.0)
2372     {
2373         /* In case of mirroring we need a source x- and y-offset because without the pixels will be
2374          * in the wrong quadrant of the x-y plane.
2375          */
2376         x_offset = (xscale < 0) ? -width : 0;
2377         y_offset = (yscale < 0) ? -height : 0;
2378         set_xrender_transformation(src_pict, xscale, yscale, x_src, y_src);
2379     }
2380     else
2381     {
2382         x_offset = x_src;
2383         y_offset = y_src;
2384         set_xrender_transformation(src_pict, 1, 1, 0, 0);
2385     }
2386     pXRenderComposite(gdi_display, PictOpOver, tile_pict, src_pict, dst_pict,
2387                       0, 0, x_offset, y_offset, x_dst, y_dst, width, height );
2388     wine_tsx11_unlock();
2389     LeaveCriticalSection( &xrender_cs );
2390
2391     /* force the alpha channel for background pixels, it has been set to 100% by the tile */
2392     if (bg->alpha != 0xffff && (dst_format == WXR_FORMAT_A8R8G8B8 || dst_format == WXR_FORMAT_B8G8R8A8))
2393         multiply_alpha( dst_pict, pict_formats[dst_format], bg->alpha, x_dst, y_dst, width, height );
2394 }
2395
2396 /* create a pixmap and render picture for an image */
2397 static DWORD create_image_pixmap( BITMAPINFO *info, const struct gdi_image_bits *bits,
2398                                   struct bitblt_coords *src, enum wxr_format format,
2399                                   Pixmap *pixmap, Picture *pict, BOOL *use_repeat )
2400 {
2401     DWORD ret;
2402     int width = src->visrect.right - src->visrect.left;
2403     int height = src->visrect.bottom - src->visrect.top;
2404     int depth = pict_formats[format]->depth;
2405     struct gdi_image_bits dst_bits;
2406     XRenderPictureAttributes pa;
2407     XImage *image;
2408
2409     wine_tsx11_lock();
2410     image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0, NULL,
2411                           info->bmiHeader.biWidth, height, 32, 0 );
2412     wine_tsx11_unlock();
2413     if (!image) return ERROR_OUTOFMEMORY;
2414
2415     ret = copy_image_bits( info, (format == WXR_FORMAT_R8G8B8), image, bits, &dst_bits, src, NULL, ~0u );
2416     if (ret) return ret;
2417
2418     image->data = dst_bits.ptr;
2419     /* hack: make sure the bits are readable if we are reading from a DIB section */
2420     /* to be removed once we get rid of DIB access protections */
2421     if (!dst_bits.is_copy) IsBadReadPtr( dst_bits.ptr, image->height * image->bytes_per_line );
2422
2423     *use_repeat = (width == 1 && height == 1);
2424     pa.repeat = *use_repeat ? RepeatNormal : RepeatNone;
2425
2426     wine_tsx11_lock();
2427     *pixmap = XCreatePixmap( gdi_display, root_window, width, height, depth );
2428     XPutImage( gdi_display, *pixmap, get_bitmap_gc( depth ), image,
2429                src->visrect.left, 0, 0, 0, width, height );
2430     *pict = pXRenderCreatePicture( gdi_display, *pixmap, pict_formats[format], CPRepeat, &pa );
2431     wine_tsx11_unlock();
2432
2433     /* make coordinates relative to the pixmap */
2434     src->x -= src->visrect.left;
2435     src->y -= src->visrect.top;
2436     OffsetRect( &src->visrect, -src->visrect.left, -src->visrect.top );
2437
2438     image->data = NULL;
2439     wine_tsx11_lock();
2440     XDestroyImage( image );
2441     wine_tsx11_unlock();
2442     if (dst_bits.free) dst_bits.free( &dst_bits );
2443     return ret;
2444 }
2445
2446 static void xrender_stretch_blit( struct xrender_physdev *physdev_src, struct xrender_physdev *physdev_dst,
2447                                   Drawable drawable, const struct bitblt_coords *src,
2448                                   const struct bitblt_coords *dst )
2449 {
2450     int width = abs( dst->width );
2451     int height = abs( dst->height );
2452     int x_src = physdev_src->x11dev->dc_rect.left + src->x;
2453     int y_src = physdev_src->x11dev->dc_rect.top + src->y;
2454     int x_dst, y_dst;
2455     Picture src_pict = 0, dst_pict, mask_pict = 0;
2456     BOOL use_repeat;
2457     double xscale, yscale;
2458
2459     use_repeat = use_source_repeat( physdev_src );
2460     if (!use_repeat)
2461     {
2462         xscale = src->width / (double)dst->width;
2463         yscale = src->height / (double)dst->height;
2464     }
2465     else xscale = yscale = 1;  /* no scaling needed with a repeating source */
2466
2467     if (drawable)  /* using an intermediate pixmap */
2468     {
2469         XRenderPictureAttributes pa;
2470
2471         x_dst = dst->x;
2472         y_dst = dst->y;
2473         pa.repeat = RepeatNone;
2474         wine_tsx11_lock();
2475         dst_pict = pXRenderCreatePicture( gdi_display, drawable, physdev_dst->pict_format, CPRepeat, &pa );
2476         wine_tsx11_unlock();
2477     }
2478     else
2479     {
2480         x_dst = physdev_dst->x11dev->dc_rect.left + dst->x;
2481         y_dst = physdev_dst->x11dev->dc_rect.top + dst->y;
2482         dst_pict = get_xrender_picture( physdev_dst, 0, &dst->visrect );
2483     }
2484
2485     if (src->width < 0) x_src += src->width + 1;
2486     if (src->height < 0) y_src += src->height + 1;
2487     if (dst->width < 0) x_dst += dst->width + 1;
2488     if (dst->height < 0) y_dst += dst->height + 1;
2489
2490     src_pict = get_xrender_picture_source( physdev_src, use_repeat );
2491
2492     /* mono -> color */
2493     if (physdev_src->format == WXR_FORMAT_MONO && physdev_dst->format != WXR_FORMAT_MONO)
2494     {
2495         XRenderColor fg, bg;
2496
2497         get_xrender_color( physdev_dst->pict_format, physdev_dst->x11dev->textPixel, &fg );
2498         get_xrender_color( physdev_dst->pict_format, physdev_dst->x11dev->backgroundPixel, &bg );
2499         fg.alpha = bg.alpha = 0;
2500
2501         xrender_mono_blit( src_pict, dst_pict, physdev_dst->format, &fg, &bg,
2502                            x_src, y_src, x_dst, y_dst, xscale, yscale, width, height );
2503     }
2504     else /* color -> color (can be at different depths) or mono -> mono */
2505     {
2506         if (physdev_dst->x11dev->depth == 32 && physdev_src->x11dev->depth < 32)
2507             mask_pict = get_no_alpha_mask();
2508
2509         xrender_blit( PictOpSrc, src_pict, mask_pict, dst_pict,
2510                       x_src, y_src, x_dst, y_dst, xscale, yscale, width, height );
2511     }
2512
2513     if (drawable)
2514     {
2515         wine_tsx11_lock();
2516         pXRenderFreePicture( gdi_display, dst_pict );
2517         wine_tsx11_unlock();
2518     }
2519 }
2520
2521
2522 static void xrender_put_image( Pixmap src_pixmap, Picture src_pict, Picture mask_pict, HRGN clip,
2523                                XRenderPictFormat *dst_format, struct xrender_physdev *physdev,
2524                                Drawable drawable, struct bitblt_coords *src,
2525                                struct bitblt_coords *dst, BOOL use_repeat )
2526 {
2527     int x_src, y_src, x_dst, y_dst;
2528     Picture dst_pict;
2529     XRenderPictureAttributes pa;
2530     double xscale, yscale;
2531
2532     if (drawable)  /* using an intermediate pixmap */
2533     {
2534         RGNDATA *clip_data = NULL;
2535
2536         if (clip) clip_data = X11DRV_GetRegionData( clip, 0 );
2537         x_dst = dst->x;
2538         y_dst = dst->y;
2539         pa.repeat = RepeatNone;
2540         wine_tsx11_lock();
2541         dst_pict = pXRenderCreatePicture( gdi_display, drawable, dst_format, CPRepeat, &pa );
2542         if (clip_data)
2543             pXRenderSetPictureClipRectangles( gdi_display, dst_pict, 0, 0,
2544                                               (XRectangle *)clip_data->Buffer, clip_data->rdh.nCount );
2545         wine_tsx11_unlock();
2546         HeapFree( GetProcessHeap(), 0, clip_data );
2547     }
2548     else
2549     {
2550         x_dst = physdev->x11dev->dc_rect.left + dst->x;
2551         y_dst = physdev->x11dev->dc_rect.top + dst->y;
2552         dst_pict = get_xrender_picture( physdev, clip, &dst->visrect );
2553     }
2554
2555     if (!use_repeat)
2556     {
2557         xscale = src->width / (double)dst->width;
2558         yscale = src->height / (double)dst->height;
2559     }
2560     else xscale = yscale = 1;  /* no scaling needed with a repeating source */
2561
2562     x_src = src->x;
2563     y_src = src->y;
2564     if (src->width < 0) x_src += src->width + 1;
2565     if (src->height < 0) y_src += src->height + 1;
2566     if (dst->width < 0) x_dst += dst->width + 1;
2567     if (dst->height < 0) y_dst += dst->height + 1;
2568
2569     xrender_blit( PictOpSrc, src_pict, mask_pict, dst_pict, x_src, y_src, x_dst, y_dst,
2570                   xscale, yscale, abs( dst->width ), abs( dst->height ));
2571
2572     if (drawable)
2573     {
2574         wine_tsx11_lock();
2575         pXRenderFreePicture( gdi_display, dst_pict );
2576         wine_tsx11_unlock();
2577     }
2578 }
2579
2580
2581 /***********************************************************************
2582  *           xrenderdrv_StretchBlt
2583  */
2584 static BOOL xrenderdrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
2585                                    PHYSDEV src_dev, struct bitblt_coords *src, DWORD rop )
2586 {
2587     struct xrender_physdev *physdev_dst = get_xrender_dev( dst_dev );
2588     struct xrender_physdev *physdev_src = get_xrender_dev( src_dev );
2589     BOOL stretch = (src->width != dst->width) || (src->height != dst->height);
2590
2591     if (src_dev->funcs != dst_dev->funcs)
2592     {
2593         dst_dev = GET_NEXT_PHYSDEV( dst_dev, pStretchBlt );
2594         return dst_dev->funcs->pStretchBlt( dst_dev, dst, src_dev, src, rop );
2595     }
2596
2597     if (!X11DRV_XRender_Installed) goto x11drv_fallback;
2598
2599     /* XRender is of no use for color -> mono */
2600     if (physdev_dst->format == WXR_FORMAT_MONO && physdev_src->format != WXR_FORMAT_MONO)
2601         goto x11drv_fallback;
2602
2603     /* if not stretching, we only need to handle format conversion */
2604     if (!stretch && physdev_dst->format == physdev_src->format) goto x11drv_fallback;
2605
2606     X11DRV_LockDIBSection( physdev_dst->x11dev, DIB_Status_GdiMod );
2607     if (physdev_dst != physdev_src) X11DRV_LockDIBSection( physdev_src->x11dev, DIB_Status_GdiMod );
2608
2609     if (rop != SRCCOPY)
2610     {
2611         GC tmpGC;
2612         Pixmap tmp_pixmap;
2613         struct bitblt_coords tmp;
2614
2615         /* make coordinates relative to tmp pixmap */
2616         tmp = *dst;
2617         tmp.x -= tmp.visrect.left;
2618         tmp.y -= tmp.visrect.top;
2619         OffsetRect( &tmp.visrect, -tmp.visrect.left, -tmp.visrect.top );
2620
2621         wine_tsx11_lock();
2622         tmpGC = XCreateGC( gdi_display, physdev_dst->x11dev->drawable, 0, NULL );
2623         XSetSubwindowMode( gdi_display, tmpGC, IncludeInferiors );
2624         XSetGraphicsExposures( gdi_display, tmpGC, False );
2625         tmp_pixmap = XCreatePixmap( gdi_display, root_window, tmp.visrect.right - tmp.visrect.left,
2626                                     tmp.visrect.bottom - tmp.visrect.top, physdev_dst->x11dev->depth );
2627         wine_tsx11_unlock();
2628
2629         xrender_stretch_blit( physdev_src, physdev_dst, tmp_pixmap, src, &tmp );
2630         execute_rop( physdev_dst->x11dev, tmp_pixmap, tmpGC, &dst->visrect, rop );
2631
2632         wine_tsx11_lock();
2633         XFreePixmap( gdi_display, tmp_pixmap );
2634         XFreeGC( gdi_display, tmpGC );
2635         wine_tsx11_unlock();
2636     }
2637     else xrender_stretch_blit( physdev_src, physdev_dst, 0, src, dst );
2638
2639     if (physdev_dst != physdev_src) X11DRV_UnlockDIBSection( physdev_src->x11dev, FALSE );
2640     X11DRV_UnlockDIBSection( physdev_dst->x11dev, TRUE );
2641     return TRUE;
2642
2643 x11drv_fallback:
2644     return X11DRV_StretchBlt( &physdev_dst->x11dev->dev, dst, &physdev_src->x11dev->dev, src, rop );
2645 }
2646
2647
2648 /***********************************************************************
2649  *           xrenderdrv_PutImage
2650  */
2651 static DWORD xrenderdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info,
2652                                   const struct gdi_image_bits *bits, struct bitblt_coords *src,
2653                                   struct bitblt_coords *dst, DWORD rop )
2654 {
2655     struct xrender_physdev *physdev;
2656     X_PHYSBITMAP *bitmap;
2657     DWORD ret;
2658     Pixmap tmp_pixmap;
2659     GC gc;
2660     enum wxr_format src_format, dst_format;
2661     XRenderPictFormat *pict_format;
2662     Pixmap src_pixmap;
2663     Picture src_pict, mask_pict = 0;
2664     BOOL use_repeat;
2665
2666     if (!X11DRV_XRender_Installed) goto x11drv_fallback;
2667
2668     if (hbitmap)
2669     {
2670         if (!(bitmap = X11DRV_get_phys_bitmap( hbitmap ))) return ERROR_INVALID_HANDLE;
2671         physdev = NULL;
2672         dst_format = get_xrender_format_from_color_shifts( bitmap->depth, &bitmap->color_shifts );
2673     }
2674     else
2675     {
2676         physdev = get_xrender_dev( dev );
2677         bitmap = NULL;
2678         dst_format = physdev->format;
2679     }
2680
2681     src_format = get_xrender_format_from_bitmapinfo( info, TRUE );
2682     if (!(pict_format = pict_formats[src_format])) goto update_format;
2683
2684     /* make sure we can create an image with the same bpp */
2685     if (info->bmiHeader.biBitCount != pixmap_formats[pict_format->depth]->bits_per_pixel)
2686         goto update_format;
2687
2688     /* mono <-> color conversions not supported */
2689     if ((src_format != dst_format) && (src_format == WXR_FORMAT_MONO || dst_format == WXR_FORMAT_MONO))
2690         goto x11drv_fallback;
2691
2692     if (!bits) return ERROR_SUCCESS;  /* just querying the format */
2693
2694     if (!has_alpha( src_format ) && has_alpha( dst_format )) mask_pict = get_no_alpha_mask();
2695
2696     ret = create_image_pixmap( info, bits, src, src_format, &src_pixmap, &src_pict, &use_repeat );
2697     if (!ret)
2698     {
2699         struct bitblt_coords tmp;
2700
2701         if (bitmap)
2702         {
2703             HRGN rgn = CreateRectRgnIndirect( &dst->visrect );
2704             if (clip) CombineRgn( rgn, rgn, clip, RGN_AND );
2705
2706             X11DRV_DIB_Lock( bitmap, DIB_Status_GdiMod );
2707
2708             xrender_put_image( src_pixmap, src_pict, mask_pict, rgn,
2709                                pict_formats[dst_format], NULL, bitmap->pixmap, src, dst, use_repeat );
2710
2711             X11DRV_DIB_Unlock( bitmap, TRUE );
2712             DeleteObject( rgn );
2713         }
2714         else
2715         {
2716             X11DRV_LockDIBSection( physdev->x11dev, DIB_Status_GdiMod );
2717
2718             if (rop != SRCCOPY)
2719             {
2720                 RGNDATA *clip_data = NULL;
2721
2722                 /* make coordinates relative to tmp pixmap */
2723                 tmp = *dst;
2724                 tmp.x -= tmp.visrect.left;
2725                 tmp.y -= tmp.visrect.top;
2726                 OffsetRect( &tmp.visrect, -tmp.visrect.left, -tmp.visrect.top );
2727
2728                 if (clip) clip_data = add_extra_clipping_region( physdev->x11dev, clip );
2729
2730                 wine_tsx11_lock();
2731                 gc = XCreateGC( gdi_display, physdev->x11dev->drawable, 0, NULL );
2732                 XSetSubwindowMode( gdi_display, gc, IncludeInferiors );
2733                 XSetGraphicsExposures( gdi_display, gc, False );
2734                 tmp_pixmap = XCreatePixmap( gdi_display, root_window, tmp.visrect.right - tmp.visrect.left,
2735                                             tmp.visrect.bottom - tmp.visrect.top, physdev->x11dev->depth );
2736                 wine_tsx11_unlock();
2737
2738                 xrender_put_image( src_pixmap, src_pict, mask_pict, NULL, physdev->pict_format,
2739                                    NULL, tmp_pixmap, src, &tmp, use_repeat );
2740                 execute_rop( physdev->x11dev, tmp_pixmap, gc, &dst->visrect, rop );
2741
2742                 wine_tsx11_lock();
2743                 XFreePixmap( gdi_display, tmp_pixmap );
2744                 XFreeGC( gdi_display, gc );
2745                 wine_tsx11_unlock();
2746
2747                 restore_clipping_region( physdev->x11dev, clip_data );
2748             }
2749             else xrender_put_image( src_pixmap, src_pict, mask_pict, clip,
2750                                     physdev->pict_format, physdev, 0, src, dst, use_repeat );
2751
2752             X11DRV_UnlockDIBSection( physdev->x11dev, TRUE );
2753         }
2754
2755         wine_tsx11_lock();
2756         pXRenderFreePicture( gdi_display, src_pict );
2757         XFreePixmap( gdi_display, src_pixmap );
2758         wine_tsx11_unlock();
2759     }
2760     return ret;
2761
2762 update_format:
2763     if (info->bmiHeader.biHeight > 0) info->bmiHeader.biHeight = -info->bmiHeader.biHeight;
2764     set_color_info( pict_formats[dst_format], info );
2765     return ERROR_BAD_FORMAT;
2766
2767 x11drv_fallback:
2768     if (hbitmap) return X11DRV_PutImage( dev, hbitmap, clip, info, bits, src, dst, rop );
2769     dev = GET_NEXT_PHYSDEV( dev, pPutImage );
2770     return dev->funcs->pPutImage( dev, hbitmap, clip, info, bits, src, dst, rop );
2771 }
2772
2773
2774 /***********************************************************************
2775  *           xrenderdrv_BlendImage
2776  */
2777 static DWORD xrenderdrv_BlendImage( PHYSDEV dev, BITMAPINFO *info, const struct gdi_image_bits *bits,
2778                                     struct bitblt_coords *src, struct bitblt_coords *dst,
2779                                     BLENDFUNCTION func )
2780 {
2781     struct xrender_physdev *physdev = get_xrender_dev( dev );
2782     DWORD ret;
2783     enum wxr_format format;
2784     XRenderPictFormat *pict_format;
2785     Picture dst_pict, src_pict, mask_pict;
2786     Pixmap src_pixmap;
2787     BOOL use_repeat;
2788
2789     if (!X11DRV_XRender_Installed)
2790     {
2791         dev = GET_NEXT_PHYSDEV( dev, pBlendImage );
2792         return dev->funcs->pBlendImage( dev, info, bits, src, dst, func );
2793     }
2794
2795     format = get_xrender_format_from_bitmapinfo( info, func.AlphaFormat & AC_SRC_ALPHA );
2796     if (!(pict_format = pict_formats[format])) goto update_format;
2797
2798     /* make sure we can create an image with the same bpp */
2799     if (info->bmiHeader.biBitCount != pixmap_formats[pict_format->depth]->bits_per_pixel)
2800         goto update_format;
2801
2802     if (format == WXR_FORMAT_MONO && physdev->format != WXR_FORMAT_MONO)
2803         goto update_format;
2804
2805     if (!bits) return ERROR_SUCCESS;  /* just querying the format */
2806
2807     ret = create_image_pixmap( info, bits, src, format, &src_pixmap, &src_pict, &use_repeat );
2808     if (!ret)
2809     {
2810         double xscale, yscale;
2811
2812         X11DRV_LockDIBSection( physdev->x11dev, DIB_Status_GdiMod );
2813
2814         if (!use_repeat)
2815         {
2816             xscale = src->width / (double)dst->width;
2817             yscale = src->height / (double)dst->height;
2818         }
2819         else xscale = yscale = 1;  /* no scaling needed with a repeating source */
2820
2821         dst_pict = get_xrender_picture( physdev, 0, &dst->visrect );
2822
2823         EnterCriticalSection( &xrender_cs );
2824         mask_pict = get_mask_pict( func.SourceConstantAlpha * 257 );
2825
2826         xrender_blit( PictOpOver, src_pict, mask_pict, dst_pict, src->x, src->y,
2827                       physdev->x11dev->dc_rect.left + dst->x,
2828                       physdev->x11dev->dc_rect.top + dst->y,
2829                       xscale, yscale, dst->width, dst->height );
2830
2831         wine_tsx11_lock();
2832         pXRenderFreePicture( gdi_display, src_pict );
2833         XFreePixmap( gdi_display, src_pixmap );
2834         wine_tsx11_unlock();
2835
2836         LeaveCriticalSection( &xrender_cs );
2837
2838         X11DRV_UnlockDIBSection( physdev->x11dev, TRUE );
2839     }
2840     return ret;
2841
2842 update_format:
2843     if (info->bmiHeader.biHeight > 0) info->bmiHeader.biHeight = -info->bmiHeader.biHeight;
2844     set_color_info( physdev->pict_format, info );
2845     return ERROR_BAD_FORMAT;
2846 }
2847
2848
2849 /***********************************************************************
2850  *           xrenderdrv_AlphaBlend
2851  */
2852 static BOOL xrenderdrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst,
2853                                    PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION blendfn )
2854 {
2855     struct xrender_physdev *physdev_dst = get_xrender_dev( dst_dev );
2856     struct xrender_physdev *physdev_src = get_xrender_dev( src_dev );
2857     Picture dst_pict, src_pict = 0, mask_pict = 0, tmp_pict = 0;
2858     XRenderPictureAttributes pa;
2859     Pixmap tmp_pixmap = 0;
2860     double xscale, yscale;
2861     BOOL use_repeat;
2862
2863     if (!X11DRV_XRender_Installed || src_dev->funcs != dst_dev->funcs)
2864     {
2865         dst_dev = GET_NEXT_PHYSDEV( dst_dev, pAlphaBlend );
2866         return dst_dev->funcs->pAlphaBlend( dst_dev, dst, src_dev, src, blendfn );
2867     }
2868
2869     if (physdev_dst != physdev_src)
2870     {
2871         int status = X11DRV_LockDIBSection( physdev_src->x11dev, DIB_Status_None );
2872         if (status == DIB_Status_AppMod || status == DIB_Status_InSync)
2873         {
2874             X11DRV_UnlockDIBSection( physdev_src->x11dev, FALSE );
2875             dst_dev = GET_NEXT_PHYSDEV( dst_dev, pAlphaBlend );
2876             return dst_dev->funcs->pAlphaBlend( dst_dev, dst, src_dev, src, blendfn );
2877         }
2878         X11DRV_CoerceDIBSection( physdev_src->x11dev, DIB_Status_GdiMod );
2879     }
2880     X11DRV_LockDIBSection( physdev_dst->x11dev, DIB_Status_GdiMod );
2881
2882     dst_pict = get_xrender_picture( physdev_dst, 0, &dst->visrect );
2883
2884     use_repeat = use_source_repeat( physdev_src );
2885     if (!use_repeat)
2886     {
2887         xscale = src->width / (double)dst->width;
2888         yscale = src->height / (double)dst->height;
2889     }
2890     else xscale = yscale = 1;  /* no scaling needed with a repeating source */
2891
2892     src_pict = get_xrender_picture_source( physdev_src, use_repeat );
2893
2894     if (physdev_src->format == WXR_FORMAT_MONO && physdev_dst->format != WXR_FORMAT_MONO)
2895     {
2896         /* mono -> color blending needs an intermediate color pixmap */
2897         XRenderColor fg, bg;
2898         int width = src->visrect.right - src->visrect.left;
2899         int height = src->visrect.bottom - src->visrect.top;
2900
2901         /* blending doesn't use the destination DC colors */
2902         fg.red = fg.green = fg.blue = 0;
2903         bg.red = bg.green = bg.blue = 0xffff;
2904         fg.alpha = bg.alpha = 0xffff;
2905
2906         wine_tsx11_lock();
2907         tmp_pixmap = XCreatePixmap( gdi_display, root_window, width, height,
2908                                     physdev_dst->pict_format->depth );
2909         pa.repeat = use_repeat ? RepeatNormal : RepeatNone;
2910         tmp_pict = pXRenderCreatePicture( gdi_display, tmp_pixmap, physdev_dst->pict_format,
2911                                           CPRepeat, &pa );
2912         wine_tsx11_unlock();
2913
2914         xrender_mono_blit( src_pict, tmp_pict, physdev_dst->format, &fg, &bg,
2915                            src->visrect.left, src->visrect.top, 0, 0, 1, 1, width, height );
2916     }
2917     else if (!(blendfn.AlphaFormat & AC_SRC_ALPHA) && physdev_src->pict_format)
2918     {
2919         /* we need a source picture with no alpha */
2920         enum wxr_format format = get_format_without_alpha( physdev_src->format );
2921         if (format != physdev_src->format)
2922         {
2923             wine_tsx11_lock();
2924             pa.subwindow_mode = IncludeInferiors;
2925             pa.repeat = use_repeat ? RepeatNormal : RepeatNone;
2926             tmp_pict = pXRenderCreatePicture( gdi_display, physdev_src->x11dev->drawable,
2927                                               pict_formats[format], CPSubwindowMode|CPRepeat, &pa );
2928             wine_tsx11_unlock();
2929         }
2930     }
2931
2932     if (tmp_pict) src_pict = tmp_pict;
2933
2934     EnterCriticalSection( &xrender_cs );
2935     mask_pict = get_mask_pict( blendfn.SourceConstantAlpha * 257 );
2936
2937     xrender_blit( PictOpOver, src_pict, mask_pict, dst_pict,
2938                   physdev_src->x11dev->dc_rect.left + src->x,
2939                   physdev_src->x11dev->dc_rect.top + src->y,
2940                   physdev_dst->x11dev->dc_rect.left + dst->x,
2941                   physdev_dst->x11dev->dc_rect.top + dst->y,
2942                   xscale, yscale, dst->width, dst->height );
2943
2944     wine_tsx11_lock();
2945     if (tmp_pict) pXRenderFreePicture( gdi_display, tmp_pict );
2946     if (tmp_pixmap) XFreePixmap( gdi_display, tmp_pixmap );
2947     wine_tsx11_unlock();
2948
2949     LeaveCriticalSection( &xrender_cs );
2950     if (physdev_src != physdev_dst) X11DRV_UnlockDIBSection( physdev_src->x11dev, FALSE );
2951     X11DRV_UnlockDIBSection( physdev_dst->x11dev, TRUE );
2952     return TRUE;
2953 }
2954
2955
2956 void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *physBitmap, int width, int height)
2957 {
2958     /* At depths >1, the depth of physBitmap and physDev might not be the same e.g. the physbitmap might be a 16-bit DIB while the physdev uses 24-bit */
2959     int depth = physBitmap->depth == 1 ? 1 : physDev->depth;
2960     enum wxr_format src_format = get_xrender_format_from_color_shifts(physBitmap->depth, &physBitmap->color_shifts);
2961     enum wxr_format dst_format = get_xrender_format_from_color_shifts(physDev->depth, physDev->color_shifts);
2962
2963     wine_tsx11_lock();
2964     physDev->brush.pixmap = XCreatePixmap(gdi_display, root_window, width, height, depth);
2965
2966     /* Use XCopyArea when the physBitmap and brush.pixmap have the same format. */
2967     if( (physBitmap->depth == 1) || (!X11DRV_XRender_Installed && physDev->depth == physBitmap->depth) ||
2968         (src_format == dst_format) )
2969     {
2970         XCopyArea( gdi_display, physBitmap->pixmap, physDev->brush.pixmap,
2971                    get_bitmap_gc(physBitmap->depth), 0, 0, width, height, 0, 0 );
2972     }
2973     else /* We need depth conversion */
2974     {
2975         Picture src_pict, dst_pict;
2976         XRenderPictureAttributes pa;
2977         pa.subwindow_mode = IncludeInferiors;
2978         pa.repeat = RepeatNone;
2979
2980         src_pict = pXRenderCreatePicture(gdi_display, physBitmap->pixmap,
2981                                          pict_formats[src_format], CPSubwindowMode|CPRepeat, &pa);
2982         dst_pict = pXRenderCreatePicture(gdi_display, physDev->brush.pixmap,
2983                                          pict_formats[dst_format], CPSubwindowMode|CPRepeat, &pa);
2984
2985         xrender_blit(PictOpSrc, src_pict, 0, dst_pict, 0, 0, 0, 0, 1.0, 1.0, width, height);
2986         pXRenderFreePicture(gdi_display, src_pict);
2987         pXRenderFreePicture(gdi_display, dst_pict);
2988     }
2989     wine_tsx11_unlock();
2990 }
2991
2992 static const struct gdi_dc_funcs xrender_funcs =
2993 {
2994     NULL,                               /* pAbortDoc */
2995     NULL,                               /* pAbortPath */
2996     xrenderdrv_AlphaBlend,              /* pAlphaBlend */
2997     NULL,                               /* pAngleArc */
2998     NULL,                               /* pArc */
2999     NULL,                               /* pArcTo */
3000     NULL,                               /* pBeginPath */
3001     xrenderdrv_BlendImage,              /* pBlendImage */
3002     NULL,                               /* pChoosePixelFormat */
3003     NULL,                               /* pChord */
3004     NULL,                               /* pCloseFigure */
3005     xrenderdrv_CreateBitmap,            /* pCreateBitmap */
3006     xrenderdrv_CreateCompatibleDC,      /* pCreateCompatibleDC */
3007     xrenderdrv_CreateDC,                /* pCreateDC */
3008     NULL,                               /* pCreateDIBSection */
3009     xrenderdrv_DeleteBitmap,            /* pDeleteBitmap */
3010     xrenderdrv_DeleteDC,                /* pDeleteDC */
3011     NULL,                               /* pDeleteObject */
3012     NULL,                               /* pDescribePixelFormat */
3013     NULL,                               /* pDeviceCapabilities */
3014     NULL,                               /* pEllipse */
3015     NULL,                               /* pEndDoc */
3016     NULL,                               /* pEndPage */
3017     NULL,                               /* pEndPath */
3018     NULL,                               /* pEnumDeviceFonts */
3019     NULL,                               /* pEnumICMProfiles */
3020     NULL,                               /* pExcludeClipRect */
3021     NULL,                               /* pExtDeviceMode */
3022     xrenderdrv_ExtEscape,               /* pExtEscape */
3023     NULL,                               /* pExtFloodFill */
3024     NULL,                               /* pExtSelectClipRgn */
3025     xrenderdrv_ExtTextOut,              /* pExtTextOut */
3026     NULL,                               /* pFillPath */
3027     NULL,                               /* pFillRgn */
3028     NULL,                               /* pFlattenPath */
3029     NULL,                               /* pFrameRgn */
3030     NULL,                               /* pGdiComment */
3031     NULL,                               /* pGetCharWidth */
3032     NULL,                               /* pGetDeviceCaps */
3033     NULL,                               /* pGetDeviceGammaRamp */
3034     NULL,                               /* pGetICMProfile */
3035     xrenderdrv_GetImage,                /* pGetImage */
3036     NULL,                               /* pGetNearestColor */
3037     NULL,                               /* pGetPixel */
3038     NULL,                               /* pGetPixelFormat */
3039     NULL,                               /* pGetSystemPaletteEntries */
3040     NULL,                               /* pGetTextExtentExPoint */
3041     NULL,                               /* pGetTextMetrics */
3042     NULL,                               /* pIntersectClipRect */
3043     NULL,                               /* pInvertRgn */
3044     NULL,                               /* pLineTo */
3045     NULL,                               /* pModifyWorldTransform */
3046     NULL,                               /* pMoveTo */
3047     NULL,                               /* pOffsetClipRgn */
3048     NULL,                               /* pOffsetViewportOrg */
3049     NULL,                               /* pOffsetWindowOrg */
3050     NULL,                               /* pPaintRgn */
3051     NULL,                               /* pPatBlt */
3052     NULL,                               /* pPie */
3053     NULL,                               /* pPolyBezier */
3054     NULL,                               /* pPolyBezierTo */
3055     NULL,                               /* pPolyDraw */
3056     NULL,                               /* pPolyPolygon */
3057     NULL,                               /* pPolyPolyline */
3058     NULL,                               /* pPolygon */
3059     NULL,                               /* pPolyline */
3060     NULL,                               /* pPolylineTo */
3061     xrenderdrv_PutImage,                /* pPutImage */
3062     NULL,                               /* pRealizeDefaultPalette */
3063     NULL,                               /* pRealizePalette */
3064     NULL,                               /* pRectangle */
3065     NULL,                               /* pResetDC */
3066     NULL,                               /* pRestoreDC */
3067     NULL,                               /* pRoundRect */
3068     NULL,                               /* pSaveDC */
3069     NULL,                               /* pScaleViewportExt */
3070     NULL,                               /* pScaleWindowExt */
3071     xrenderdrv_SelectBitmap,            /* pSelectBitmap */
3072     NULL,                               /* pSelectBrush */
3073     NULL,                               /* pSelectClipPath */
3074     xrenderdrv_SelectFont,              /* pSelectFont */
3075     NULL,                               /* pSelectPalette */
3076     NULL,                               /* pSelectPen */
3077     NULL,                               /* pSetArcDirection */
3078     NULL,                               /* pSetBkColor */
3079     NULL,                               /* pSetBkMode */
3080     NULL,                               /* pSetDCBrushColor */
3081     NULL,                               /* pSetDCPenColor */
3082     NULL,                               /* pSetDIBColorTable */
3083     NULL,                               /* pSetDIBitsToDevice */
3084     xrenderdrv_SetDeviceClipping,       /* pSetDeviceClipping */
3085     NULL,                               /* pSetDeviceGammaRamp */
3086     NULL,                               /* pSetLayout */
3087     NULL,                               /* pSetMapMode */
3088     NULL,                               /* pSetMapperFlags */
3089     NULL,                               /* pSetPixel */
3090     NULL,                               /* pSetPixelFormat */
3091     NULL,                               /* pSetPolyFillMode */
3092     NULL,                               /* pSetROP2 */
3093     NULL,                               /* pSetRelAbs */
3094     NULL,                               /* pSetStretchBltMode */
3095     NULL,                               /* pSetTextAlign */
3096     NULL,                               /* pSetTextCharacterExtra */
3097     NULL,                               /* pSetTextColor */
3098     NULL,                               /* pSetTextJustification */
3099     NULL,                               /* pSetViewportExt */
3100     NULL,                               /* pSetViewportOrg */
3101     NULL,                               /* pSetWindowExt */
3102     NULL,                               /* pSetWindowOrg */
3103     NULL,                               /* pSetWorldTransform */
3104     NULL,                               /* pStartDoc */
3105     NULL,                               /* pStartPage */
3106     xrenderdrv_StretchBlt,              /* pStretchBlt */
3107     NULL,                               /* pStretchDIBits */
3108     NULL,                               /* pStrokeAndFillPath */
3109     NULL,                               /* pStrokePath */
3110     NULL,                               /* pSwapBuffers */
3111     NULL,                               /* pUnrealizePalette */
3112     NULL,                               /* pWidenPath */
3113     /* OpenGL not supported */
3114 };
3115
3116 #else /* SONAME_LIBXRENDER */
3117
3118 const struct gdi_dc_funcs *X11DRV_XRender_Init(void)
3119 {
3120     TRACE("XRender support not compiled in.\n");
3121     return NULL;
3122 }
3123
3124 void X11DRV_XRender_Finalize(void)
3125 {
3126 }
3127
3128 void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *physBitmap, int width, int height)
3129 {
3130     wine_tsx11_lock();
3131     physDev->brush.pixmap = XCreatePixmap(gdi_display, root_window, width, height, physBitmap->pixmap_depth);
3132
3133     XCopyArea( gdi_display, physBitmap->pixmap, physDev->brush.pixmap,
3134                get_bitmap_gc(physBitmap->pixmap_depth), 0, 0, width, height, 0, 0 );
3135     wine_tsx11_unlock();
3136 }
3137
3138 BOOL X11DRV_XRender_SetPhysBitmapDepth(X_PHYSBITMAP *physBitmap, int bits_pixel, const DIBSECTION *dib)
3139 {
3140     return FALSE;
3141 }
3142
3143 #endif /* SONAME_LIBXRENDER */