1/* GDK - The GIMP Drawing Kit
2 * Copyright © 2005 Red Hat, Inc
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Based on code from xftdpy.c
18 *
19 * Copyright © 2000 Keith Packard
20 *
21 * Permission to use, copy, modify, distribute, and sell this software and its
22 * documentation for any purpose is hereby granted without fee, provided that
23 * the above copyright notice appear in all copies and that both that
24 * copyright notice and this permission notice appear in supporting
25 * documentation, and that the name of Keith Packard not be used in
26 * advertising or publicity pertaining to distribution of the software without
27 * specific, written prior permission. Keith Packard makes no
28 * representations about the suitability of this software for any purpose. It
29 * is provided "as is" without express or implied warranty.
30 *
31 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
32 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
33 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
34 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
35 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
36 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
37 * PERFORMANCE OF THIS SOFTWARE.
38 */
39
40#include "config.h"
41
42#include <stdlib.h>
43#include <string.h>
44
45#include <fontconfig/fontconfig.h>
46
47#ifndef FC_HINT_STYLE
48#define FC_HINT_NONE 0
49#define FC_HINT_SLIGHT 1
50#define FC_HINT_MEDIUM 2
51#define FC_HINT_FULL 3
52#endif
53
54#include <gdkscreen-x11.h>
55#include <gdkprivate-x11.h>
56
57#include "gdkdebug.h"
58
59static int
60parse_boolean (char *v)
61{
62 char c0, c1;
63
64 c0 = *v;
65 if (g_ascii_isupper ((int)c0))
66 c0 = g_ascii_tolower (c: c0);
67 if (c0 == 't' || c0 == 'y' || c0 == '1')
68 return 1;
69 if (c0 == 'f' || c0 == 'n' || c0 == '0')
70 return 0;
71 if (c0 == 'o')
72 {
73 c1 = v[1];
74 if (g_ascii_isupper ((int)c1))
75 c1 = g_ascii_tolower (c: c1);
76 if (c1 == 'n')
77 return 1;
78 if (c1 == 'f')
79 return 0;
80 }
81
82 return -1;
83}
84
85static gboolean
86get_boolean_default (GdkX11Screen *x11_screen,
87 const char *option,
88 gboolean *value)
89{
90 Display *dpy = GDK_SCREEN_XDISPLAY (x11_screen);
91 char *v;
92 int i;
93
94 if (gdk_display_get_debug_flags (GDK_SCREEN_DISPLAY (x11_screen)) & GDK_DEBUG_DEFAULT_SETTINGS)
95 return FALSE;
96
97 v = XGetDefault (dpy, "Xft", option);
98 if (v)
99 {
100 i = parse_boolean (v);
101 if (i >= 0)
102 {
103 *value = i;
104 return TRUE;
105 }
106 }
107
108 return FALSE;
109}
110
111static gboolean
112get_double_default (GdkX11Screen *x11_screen,
113 const char *option,
114 double *value)
115{
116 Display *dpy = GDK_SCREEN_XDISPLAY (x11_screen);
117 char *v, *e;
118
119 if (gdk_display_get_debug_flags (GDK_SCREEN_DISPLAY (x11_screen)) & GDK_DEBUG_DEFAULT_SETTINGS)
120 return FALSE;
121
122 v = XGetDefault (dpy, "Xft", option);
123 if (v)
124 {
125 /* Xft uses strtod, though localization probably wasn't
126 * desired. For compatibility, we use the conservative
127 * g_strtod() that accepts either localized or non-localized
128 * decimal separator.
129 */
130 *value = g_strtod (nptr: v, endptr: &e);
131 if (e != v)
132 return TRUE;
133 }
134
135 return FALSE;
136}
137
138static gboolean
139get_integer_default (GdkX11Screen *x11_screen,
140 const char *option,
141 int *value)
142{
143 Display *dpy = GDK_SCREEN_XDISPLAY (x11_screen);
144 char *v, *e;
145
146 if (gdk_display_get_debug_flags (GDK_SCREEN_DISPLAY (x11_screen)) & GDK_DEBUG_DEFAULT_SETTINGS)
147 return FALSE;
148
149 v = XGetDefault (dpy, "Xft", option);
150 if (v)
151 {
152 if (FcNameConstant (string: (FcChar8 *) v, result: value))
153 return TRUE;
154
155 *value = strtol (nptr: v, endptr: &e, base: 0);
156 if (e != v)
157 return TRUE;
158 }
159
160 return FALSE;
161}
162
163static void
164init_xft_settings (GdkX11Screen *x11_screen)
165{
166 double dpi_double;
167 gboolean b;
168
169 if (x11_screen->xft_init)
170 return;
171
172 x11_screen->xft_init = TRUE;
173
174 if (!get_boolean_default (x11_screen, option: "antialias", value: &b))
175 b = TRUE;
176 x11_screen->xft_antialias = b;
177
178 if (!get_boolean_default (x11_screen, option: "hinting", value: &b))
179 b = TRUE;
180 x11_screen->xft_hinting = b;
181
182 if (!get_integer_default (x11_screen, option: "hintstyle", value: &x11_screen->xft_hintstyle))
183 x11_screen->xft_hintstyle = FC_HINT_MEDIUM;
184
185 if (!get_integer_default (x11_screen, option: "rgba", value: &x11_screen->xft_rgba))
186 x11_screen->xft_rgba = FC_RGBA_UNKNOWN;
187
188 if (!get_double_default (x11_screen, option: "dpi", value: &dpi_double))
189 dpi_double = 96.0;
190
191 x11_screen->xft_dpi = (int)(0.5 + PANGO_SCALE * dpi_double);
192}
193
194gboolean
195_gdk_x11_screen_get_xft_setting (GdkX11Screen *x11_screen,
196 const char *name,
197 GValue *value)
198{
199 if (strncmp (s1: name, s2: "gtk-xft-", n: 8) != 0)
200 return FALSE;
201
202 name += 8;
203
204 init_xft_settings (x11_screen);
205
206 if (strcmp (s1: name, s2: "antialias") == 0)
207 {
208 g_value_set_int (value, v_int: x11_screen->xft_antialias);
209 return TRUE;
210 }
211 else if (strcmp (s1: name, s2: "hinting") == 0)
212 {
213 g_value_set_int (value, v_int: x11_screen->xft_hinting);
214 return TRUE;
215 }
216 else if (strcmp (s1: name, s2: "hintstyle") == 0)
217 {
218 const char *str;
219
220 switch (x11_screen->xft_hintstyle)
221 {
222 case FC_HINT_NONE:
223 str = "hintnone";
224 break;
225 case FC_HINT_SLIGHT:
226 str = "hintslight";
227 break;
228 case FC_HINT_MEDIUM:
229 str = "hintmedium";
230 break;
231 case FC_HINT_FULL:
232 str = "hintfull";
233 break;
234 default:
235 return FALSE;
236 }
237
238 g_value_set_string (value, v_string: str);
239 return TRUE;
240 }
241 else if (strcmp (s1: name, s2: "rgba") == 0)
242 {
243 const char *str;
244
245 switch (x11_screen->xft_rgba)
246 {
247 case FC_RGBA_NONE:
248 str = "none";
249 break;
250 case FC_RGBA_RGB:
251 str = "rgb";
252 break;
253 case FC_RGBA_BGR:
254 str = "bgr";
255 break;
256 case FC_RGBA_VRGB:
257 str = "vrgb";
258 break;
259 case FC_RGBA_VBGR:
260 str = "vbgr";
261 break;
262 case FC_RGBA_UNKNOWN:
263 default:
264 return FALSE;
265 }
266
267 g_value_set_string (value, v_string: str);
268 return TRUE;
269 }
270 else if (strcmp (s1: name, s2: "dpi") == 0)
271 {
272 g_value_set_int (value, v_int: x11_screen->xft_dpi);
273 return TRUE;
274 }
275
276 return FALSE;
277}
278

source code of gtk/gdk/x11/gdkxftdefaults.c