1 /* Cairo - a vector graphics library with display and print output
3 * Copyright © 2005 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it either under the terms of the GNU Lesser General Public
7 * License version 2.1 as published by the Free Software Foundation
8 * (the "LGPL") or, at your option, under the terms of the Mozilla
9 * Public License Version 1.1 (the "MPL"). If you do not alter this
10 * notice, a recipient may use your version of this file under either
11 * the MPL or the LGPL.
13 * You should have received a copy of the LGPL along with this library
14 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16 * You should have received a copy of the MPL along with this library
17 * in the file COPYING-MPL-1.1
19 * The contents of this file are subject to the Mozilla Public License
20 * Version 1.1 (the "License"); you may not use this file except in
21 * compliance with the License. You may obtain a copy of the License at
22 * http://www.mozilla.org/MPL/
24 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26 * the specific language governing rights and limitations.
28 * The Original Code is the cairo graphics library.
30 * The Initial Developer of the Original Code is Red Hat, Inc.
32 * Partially on code from xftdpy.c
34 * Copyright © 2000 Keith Packard
36 * Permission to use, copy, modify, distribute, and sell this software and its
37 * documentation for any purpose is hereby granted without fee, provided that
38 * the above copyright notice appear in all copies and that both that
39 * copyright notice and this permission notice appear in supporting
40 * documentation, and that the name of Keith Packard not be used in
41 * advertising or publicity pertaining to distribution of the software without
42 * specific, written prior permission. Keith Packard makes no
43 * representations about the suitability of this software for any purpose. It
44 * is provided "as is" without express or implied warranty.
46 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
47 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
48 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
49 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
50 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
51 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
52 * PERFORMANCE OF THIS SOFTWARE.
57 #if !CAIRO_HAS_XLIB_XCB_FUNCTIONS
59 #include "cairo-xlib-private.h"
60 #include "cairo-xlib-xrender-private.h"
62 #include "cairo-xlib-surface-private.h"
63 #include "cairo-error-private.h"
64 #include "cairo-list-inline.h"
66 #include "cairo-fontconfig-private.h"
69 parse_boolean (const char *v
)
74 if (c0
== 't' || c0
== 'T' || c0
== 'y' || c0
== 'Y' || c0
== '1')
76 if (c0
== 'f' || c0
== 'F' || c0
== 'n' || c0
== 'N' || c0
== '0')
81 if (c1
== 'n' || c1
== 'N')
83 if (c1
== 'f' || c1
== 'F')
91 get_boolean_default (Display
*dpy
,
98 v
= XGetDefault (dpy
, "Xft", option
);
100 i
= parse_boolean (v
);
111 get_integer_default (Display
*dpy
,
117 v
= XGetDefault (dpy
, "Xft", option
);
119 #if CAIRO_HAS_FC_FONT
120 if (FcNameConstant ((FcChar8
*) v
, value
))
124 *value
= strtol (v
, &e
, 0);
133 _cairo_xlib_init_screen_font_options (Display
*dpy
,
134 cairo_xlib_screen_t
*info
)
136 cairo_bool_t xft_hinting
;
137 cairo_bool_t xft_antialias
;
141 cairo_antialias_t antialias
;
142 cairo_subpixel_order_t subpixel_order
;
143 cairo_lcd_filter_t lcd_filter
;
144 cairo_hint_style_t hint_style
;
146 if (!get_boolean_default (dpy
, "antialias", &xft_antialias
))
147 xft_antialias
= TRUE
;
149 if (!get_integer_default (dpy
, "lcdfilter", &xft_lcdfilter
)) {
150 /* -1 is an non-existant Fontconfig constant used to differentiate
151 * the case when no lcdfilter property is available.
156 if (!get_boolean_default (dpy
, "hinting", &xft_hinting
))
159 if (!get_integer_default (dpy
, "hintstyle", &xft_hintstyle
))
160 xft_hintstyle
= FC_HINT_FULL
;
162 if (!get_integer_default (dpy
, "rgba", &xft_rgba
))
164 cairo_xlib_display_t
*display
= (cairo_xlib_display_t
*) info
->device
;
166 xft_rgba
= FC_RGBA_UNKNOWN
;
168 #if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
169 if (display
->render_major
> 0 || display
->render_minor
>= 6) {
170 int render_order
= XRenderQuerySubpixelOrder (dpy
,
171 XScreenNumberOfScreen (info
->screen
));
173 switch (render_order
) {
175 case SubPixelUnknown
:
176 xft_rgba
= FC_RGBA_UNKNOWN
;
178 case SubPixelHorizontalRGB
:
179 xft_rgba
= FC_RGBA_RGB
;
181 case SubPixelHorizontalBGR
:
182 xft_rgba
= FC_RGBA_BGR
;
184 case SubPixelVerticalRGB
:
185 xft_rgba
= FC_RGBA_VRGB
;
187 case SubPixelVerticalBGR
:
188 xft_rgba
= FC_RGBA_VBGR
;
191 xft_rgba
= FC_RGBA_NONE
;
199 switch (xft_hintstyle
) {
201 hint_style
= CAIRO_HINT_STYLE_NONE
;
204 hint_style
= CAIRO_HINT_STYLE_SLIGHT
;
207 hint_style
= CAIRO_HINT_STYLE_MEDIUM
;
210 hint_style
= CAIRO_HINT_STYLE_FULL
;
213 hint_style
= CAIRO_HINT_STYLE_DEFAULT
;
216 hint_style
= CAIRO_HINT_STYLE_NONE
;
221 subpixel_order
= CAIRO_SUBPIXEL_ORDER_RGB
;
224 subpixel_order
= CAIRO_SUBPIXEL_ORDER_BGR
;
227 subpixel_order
= CAIRO_SUBPIXEL_ORDER_VRGB
;
230 subpixel_order
= CAIRO_SUBPIXEL_ORDER_VBGR
;
232 case FC_RGBA_UNKNOWN
:
235 subpixel_order
= CAIRO_SUBPIXEL_ORDER_DEFAULT
;
238 switch (xft_lcdfilter
) {
240 lcd_filter
= CAIRO_LCD_FILTER_NONE
;
243 lcd_filter
= CAIRO_LCD_FILTER_FIR5
;
246 lcd_filter
= CAIRO_LCD_FILTER_FIR3
;
249 lcd_filter
= CAIRO_LCD_FILTER_INTRA_PIXEL
;
252 lcd_filter
= CAIRO_LCD_FILTER_DEFAULT
;
257 if (subpixel_order
== CAIRO_SUBPIXEL_ORDER_DEFAULT
)
258 antialias
= CAIRO_ANTIALIAS_GRAY
;
260 antialias
= CAIRO_ANTIALIAS_SUBPIXEL
;
262 antialias
= CAIRO_ANTIALIAS_NONE
;
265 cairo_font_options_set_hint_style (&info
->font_options
, hint_style
);
266 cairo_font_options_set_antialias (&info
->font_options
, antialias
);
267 cairo_font_options_set_subpixel_order (&info
->font_options
, subpixel_order
);
268 _cairo_font_options_set_lcd_filter (&info
->font_options
, lcd_filter
);
269 cairo_font_options_set_hint_metrics (&info
->font_options
, CAIRO_HINT_METRICS_ON
);
273 _cairo_xlib_screen_destroy (cairo_xlib_display_t
*display
,
274 cairo_xlib_screen_t
*info
)
279 dpy
= display
->display
;
281 while (! cairo_list_is_empty (&info
->surfaces
)) {
282 cairo_xlib_surface_t
*surface
;
284 surface
= cairo_list_first_entry (&info
->surfaces
,
285 cairo_xlib_surface_t
,
287 cairo_surface_finish (&surface
->base
);
290 for (i
= 0; i
< ARRAY_LENGTH (info
->gc
); i
++) {
291 if (info
->gc_depths
[i
] != 0) {
292 XFreeGC (dpy
, info
->gc
[i
]);
293 info
->gc_depths
[i
] = 0;
297 while (! cairo_list_is_empty (&info
->visuals
)) {
298 _cairo_xlib_visual_info_destroy (cairo_list_first_entry (&info
->visuals
,
299 cairo_xlib_visual_info_t
,
303 cairo_list_del (&info
->link
);
309 _cairo_xlib_screen_get (Display
*dpy
,
311 cairo_xlib_screen_t
**out
)
313 cairo_xlib_display_t
*display
;
314 cairo_device_t
*device
;
315 cairo_xlib_screen_t
*info
;
316 cairo_status_t status
;
318 device
= _cairo_xlib_device_create (dpy
);
319 status
= device
->status
;
320 if (unlikely (status
))
323 status
= _cairo_xlib_display_acquire (device
, &display
);
324 if (unlikely (status
))
327 info
= _cairo_xlib_display_get_screen (display
, screen
);
330 goto CLEANUP_DISPLAY
;
333 info
= malloc (sizeof (cairo_xlib_screen_t
));
334 if (unlikely (info
== NULL
)) {
335 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
336 goto CLEANUP_DISPLAY
;
339 info
->device
= device
;
340 info
->screen
= screen
;
341 info
->has_font_options
= FALSE
;
342 memset (info
->gc_depths
, 0, sizeof (info
->gc_depths
));
343 memset (info
->gc
, 0, sizeof (info
->gc
));
345 cairo_list_init (&info
->surfaces
);
346 cairo_list_init (&info
->visuals
);
347 cairo_list_add (&info
->link
, &display
->screens
);
352 cairo_device_release (&display
->base
);
355 cairo_device_destroy (device
);
360 _cairo_xlib_screen_get_gc (cairo_xlib_display_t
*display
,
361 cairo_xlib_screen_t
*info
,
368 for (i
= 0; i
< ARRAY_LENGTH (info
->gc
); i
++) {
369 if (info
->gc_depths
[i
] == depth
) {
370 info
->gc_depths
[i
] = 0;
379 gcv
.graphics_exposures
= False
;
380 gcv
.fill_style
= FillTiled
;
381 gc
= XCreateGC (display
->display
,
383 GCGraphicsExposures
| GCFillStyle
, &gcv
);
390 _cairo_xlib_screen_put_gc (cairo_xlib_display_t
*display
,
391 cairo_xlib_screen_t
*info
,
397 for (i
= 0; i
< ARRAY_LENGTH (info
->gc
); i
++) {
398 if (info
->gc_depths
[i
] == 0)
402 if (i
== ARRAY_LENGTH (info
->gc
)) {
403 /* perform random substitution to ensure fair caching over depths */
404 i
= rand () % ARRAY_LENGTH (info
->gc
);
405 XFreeGC(display
->display
, info
->gc
[i
]);
409 info
->gc_depths
[i
] = depth
;
413 _cairo_xlib_screen_get_visual_info (cairo_xlib_display_t
*display
,
414 cairo_xlib_screen_t
*info
,
416 cairo_xlib_visual_info_t
**out
)
418 cairo_xlib_visual_info_t
*visual
;
419 cairo_status_t status
;
421 cairo_list_foreach_entry (visual
,
422 cairo_xlib_visual_info_t
,
426 if (visual
->visualid
== v
->visualid
) {
428 return CAIRO_STATUS_SUCCESS
;
432 status
= _cairo_xlib_visual_info_create (display
->display
,
433 XScreenNumberOfScreen (info
->screen
),
436 if (unlikely (status
))
439 cairo_list_add (&visual
->link
, &info
->visuals
);
441 return CAIRO_STATUS_SUCCESS
;
444 cairo_font_options_t
*
445 _cairo_xlib_screen_get_font_options (cairo_xlib_screen_t
*info
)
447 if (! info
->has_font_options
) {
448 _cairo_font_options_init_default (&info
->font_options
);
449 _cairo_font_options_set_round_glyph_positions (&info
->font_options
, CAIRO_ROUND_GLYPH_POS_ON
);
451 if (info
->screen
!= NULL
) {
452 cairo_xlib_display_t
*display
;
454 if (! _cairo_xlib_display_acquire (info
->device
, &display
)) {
455 _cairo_xlib_init_screen_font_options (display
->display
,
457 cairo_device_release (&display
->base
);
461 info
->has_font_options
= TRUE
;
464 return &info
->font_options
;
467 #endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */