1 /* Cairo - a vector graphics library with display and print output
3 * Copyright © 2014 Lukas Lalinsky
4 * Copyright © 2005 Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it either under the terms of the GNU Lesser General Public
8 * License version 2.1 as published by the Free Software Foundation
9 * (the "LGPL") or, at your option, under the terms of the Mozilla
10 * Public License Version 1.1 (the "MPL"). If you do not alter this
11 * notice, a recipient may use your version of this file under either
12 * the MPL or the LGPL.
14 * You should have received a copy of the LGPL along with this library
15 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17 * You should have received a copy of the MPL along with this library
18 * in the file COPYING-MPL-1.1
20 * The contents of this file are subject to the Mozilla Public License
21 * Version 1.1 (the "License"); you may not use this file except in
22 * compliance with the License. You may obtain a copy of the License at
23 * http://www.mozilla.org/MPL/
25 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27 * the specific language governing rights and limitations.
30 * Lukas Lalinsky <lukas@oxygene.sk>
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 #include "cairo-xcb-private.h"
59 #include "cairo-fontconfig-private.h"
62 parse_boolean (const char *v, cairo_bool_t *out)
67 if (c0 == 't' || c0 == 'T' || c0 == 'y' || c0 == 'Y' || c0 == '1')
69 if (c0 == 'f' || c0 == 'F' || c0 == 'n' || c0 == 'N' || c0 == '0')
73 if (c1 == 'n' || c1 == 'N')
75 if (c1 == 'f' || c1 == 'F')
81 parse_integer (const char *v, int *out)
87 if (FcNameConstant ((FcChar8 *) v, out))
91 value = strtol (v, &e, 0);
97 skip_spaces(char *str)
99 while (*str == ' ' || *str == '\t' || *str == '\n')
104 struct resource_parser {
108 cairo_xcb_resources_t *resources;
112 resource_parse_line (char *name, cairo_xcb_resources_t *resources)
116 value = strchr (name, ':');
122 name = skip_spaces (name);
123 value = skip_spaces (value);
125 if (strcmp (name, "Xft.antialias") == 0)
126 parse_boolean (value, &(resources->xft_antialias));
127 else if (strcmp (name, "Xft.lcdfilter") == 0)
128 parse_integer (value, &(resources->xft_lcdfilter));
129 else if (strcmp (name, "Xft.rgba") == 0)
130 parse_integer (value, &(resources->xft_rgba));
131 else if (strcmp (name, "Xft.hinting") == 0)
132 parse_boolean (value, &(resources->xft_hinting));
133 else if (strcmp (name, "Xft.hintstyle") == 0)
134 parse_integer (value, &(resources->xft_hintstyle));
140 resource_parse_lines (struct resource_parser *parser)
142 char *line, *newline;
144 line = parser->buffer;
146 newline = strchr (line, '\n');
152 if (! resource_parse_line (line, parser->resources))
158 return line - parser->buffer;
162 resource_parser_init (struct resource_parser *parser, cairo_xcb_resources_t *resources)
164 parser->buffer_size = 0;
165 parser->bytes_in_buffer = 0;
166 parser->buffer = NULL;
167 parser->resources = resources;
171 resource_parser_update (struct resource_parser *parser, const char *data, int length)
175 if (parser->bytes_in_buffer + length + 1 > parser->buffer_size) {
176 parser->buffer_size = parser->bytes_in_buffer + length + 1;
177 parser->buffer = realloc(parser->buffer, parser->buffer_size);
178 if (! parser->buffer) {
179 parser->buffer_size = 0;
180 parser->bytes_in_buffer = 0;
185 memmove (parser->buffer + parser->bytes_in_buffer, data, length);
186 parser->bytes_in_buffer += length;
187 parser->buffer[parser->bytes_in_buffer] = 0;
189 bytes_parsed = resource_parse_lines (parser);
191 if (parser->bytes_in_buffer > bytes_parsed) {
192 memmove (parser->buffer, parser->buffer + bytes_parsed, parser->bytes_in_buffer - bytes_parsed);
193 parser->bytes_in_buffer -= bytes_parsed;
195 parser->bytes_in_buffer = 0;
202 resource_parser_done (struct resource_parser *parser)
204 if (parser->bytes_in_buffer > 0) {
205 parser->buffer[parser->bytes_in_buffer] = 0;
206 resource_parse_line (parser->buffer, parser->resources);
209 free (parser->buffer);
213 get_resources(xcb_connection_t *connection, xcb_screen_t *screen, cairo_xcb_resources_t *resources)
215 xcb_get_property_cookie_t cookie;
216 xcb_get_property_reply_t *reply;
217 struct resource_parser parser;
219 cairo_bool_t has_more_data;
221 resources->xft_antialias = TRUE;
222 resources->xft_lcdfilter = -1;
223 resources->xft_hinting = TRUE;
224 resources->xft_hintstyle = FC_HINT_FULL;
225 resources->xft_rgba = FC_RGBA_UNKNOWN;
227 resource_parser_init (&parser, resources);
230 has_more_data = FALSE;
232 cookie = xcb_get_property (connection, 0, screen->root, XCB_ATOM_RESOURCE_MANAGER, XCB_ATOM_STRING, offset, 1024);
233 reply = xcb_get_property_reply (connection, cookie, NULL);
236 if (reply->format == 8 && reply->type == XCB_ATOM_STRING) {
237 char *value = (char *) xcb_get_property_value (reply);
238 int length = xcb_get_property_value_length (reply);
240 offset += length / 4; /* X needs the offset in 'long' units */
241 has_more_data = reply->bytes_after > 0;
243 if (! resource_parser_update (&parser, value, length))
244 has_more_data = FALSE; /* early exit on error */
249 } while (has_more_data);
251 resource_parser_done (&parser);
255 _cairo_xcb_resources_get (cairo_xcb_screen_t *screen, cairo_xcb_resources_t *resources)
257 get_resources (screen->connection->xcb_connection, screen->xcb_screen, resources);
259 if (resources->xft_rgba == FC_RGBA_UNKNOWN) {
260 switch (screen->subpixel_order) {
261 case XCB_RENDER_SUB_PIXEL_UNKNOWN:
262 resources->xft_rgba = FC_RGBA_UNKNOWN;
264 case XCB_RENDER_SUB_PIXEL_HORIZONTAL_RGB:
265 resources->xft_rgba = FC_RGBA_RGB;
267 case XCB_RENDER_SUB_PIXEL_HORIZONTAL_BGR:
268 resources->xft_rgba = FC_RGBA_BGR;
270 case XCB_RENDER_SUB_PIXEL_VERTICAL_RGB:
271 resources->xft_rgba = FC_RGBA_VRGB;
273 case XCB_RENDER_SUB_PIXEL_VERTICAL_BGR:
274 resources->xft_rgba = FC_RGBA_VBGR;
276 case XCB_RENDER_SUB_PIXEL_NONE:
277 resources->xft_rgba = FC_RGBA_NONE;