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;
422 cairo_list_foreach_entry (visual,
423 cairo_xlib_visual_info_t,
427 if (visual->visualid == v->visualid) {
429 return CAIRO_STATUS_SUCCESS;
433 screen_number = XScreenNumberOfScreen (info->screen);
434 if (screen_number < 0)
435 return CAIRO_STATUS_NEGATIVE_COUNT;
437 status = _cairo_xlib_visual_info_create (display->display,
441 if (unlikely (status))
444 cairo_list_add (&visual->link, &info->visuals);
446 return CAIRO_STATUS_SUCCESS;
449 cairo_font_options_t *
450 _cairo_xlib_screen_get_font_options (cairo_xlib_screen_t *info)
452 if (! info->has_font_options) {
453 _cairo_font_options_init_default (&info->font_options);
454 _cairo_font_options_set_round_glyph_positions (&info->font_options, CAIRO_ROUND_GLYPH_POS_ON);
456 if (info->screen != NULL) {
457 cairo_xlib_display_t *display;
459 if (! _cairo_xlib_display_acquire (info->device, &display)) {
460 _cairo_xlib_init_screen_font_options (display->display,
462 cairo_device_release (&display->base);
466 info->has_font_options = TRUE;
469 return &info->font_options;
472 #endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */