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