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 static gint
parse_boolean(char * v)58 parse_boolean (char *v)
59 {
60 gchar c0, c1;
61
62 c0 = *v;
63 if (g_ascii_isupper ((int)c0))
64 c0 = g_ascii_tolower (c0);
65 if (c0 == 't' || c0 == 'y' || c0 == '1')
66 return 1;
67 if (c0 == 'f' || c0 == 'n' || c0 == '0')
68 return 0;
69 if (c0 == 'o')
70 {
71 c1 = v[1];
72 if (g_ascii_isupper ((int)c1))
73 c1 = g_ascii_tolower (c1);
74 if (c1 == 'n')
75 return 1;
76 if (c1 == 'f')
77 return 0;
78 }
79
80 return -1;
81 }
82
83 static gboolean
get_boolean_default(Display * dpy,gchar * option,gboolean * value)84 get_boolean_default (Display *dpy,
85 gchar *option,
86 gboolean *value)
87 {
88 gchar *v;
89 gint i;
90
91 v = XGetDefault (dpy, "Xft", option);
92 if (v)
93 {
94 i = parse_boolean (v);
95 if (i >= 0)
96 {
97 *value = i;
98 return TRUE;
99 }
100 }
101
102 return FALSE;
103 }
104
105 static gboolean
get_double_default(Display * dpy,gchar * option,gdouble * value)106 get_double_default (Display *dpy,
107 gchar *option,
108 gdouble *value)
109 {
110 gchar *v, *e;
111
112 v = XGetDefault (dpy, "Xft", option);
113 if (v)
114 {
115 /* Xft uses strtod, though localization probably wasn't
116 * desired. For compatibility, we use the conservative
117 * g_strtod() that accepts either localized or non-localized
118 * decimal separator.
119 */
120 *value = g_strtod (v, &e);
121 if (e != v)
122 return TRUE;
123 }
124
125 return FALSE;
126 }
127
128 static gboolean
get_integer_default(Display * dpy,gchar * option,gint * value)129 get_integer_default (Display *dpy,
130 gchar *option,
131 gint *value)
132 {
133 gchar *v, *e;
134
135 v = XGetDefault (dpy, "Xft", option);
136 if (v)
137 {
138 if (FcNameConstant ((FcChar8 *) v, value))
139 return TRUE;
140
141 *value = strtol (v, &e, 0);
142 if (e != v)
143 return TRUE;
144 }
145
146 return FALSE;
147 }
148
149 static void
init_xft_settings(GdkScreen * screen)150 init_xft_settings (GdkScreen *screen)
151 {
152 GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
153 Display *xdisplay = GDK_SCREEN_XDISPLAY (screen);
154 double dpi_double;
155 gboolean b;
156
157 if (x11_screen->xft_init)
158 return;
159
160 x11_screen->xft_init = TRUE;
161
162 if (!get_boolean_default (xdisplay, "antialias", &b))
163 b = TRUE;
164 x11_screen->xft_antialias = b;
165
166 if (!get_boolean_default (xdisplay, "hinting", &b))
167 b = TRUE;
168 x11_screen->xft_hinting = b;
169
170 if (!get_integer_default (xdisplay, "hintstyle", &x11_screen->xft_hintstyle))
171 x11_screen->xft_hintstyle = FC_HINT_MEDIUM;
172
173 if (!get_integer_default (xdisplay, "rgba", &x11_screen->xft_rgba))
174 x11_screen->xft_rgba = FC_RGBA_UNKNOWN;
175
176 if (!get_double_default (xdisplay, "dpi", &dpi_double))
177 dpi_double = 96.0;
178
179 x11_screen->xft_dpi = (int)(0.5 + PANGO_SCALE * dpi_double);
180 }
181
182 gboolean
_gdk_x11_get_xft_setting(GdkScreen * screen,const gchar * name,GValue * value)183 _gdk_x11_get_xft_setting (GdkScreen *screen,
184 const gchar *name,
185 GValue *value)
186 {
187 GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
188
189 if (strncmp (name, "gtk-xft-", 8) != 0)
190 return FALSE;
191
192 name += 8;
193
194 init_xft_settings (screen);
195
196 if (strcmp (name, "antialias") == 0)
197 {
198 g_value_set_int (value, x11_screen->xft_antialias);
199 return TRUE;
200 }
201 else if (strcmp (name, "hinting") == 0)
202 {
203 g_value_set_int (value, x11_screen->xft_hinting);
204 return TRUE;
205 }
206 else if (strcmp (name, "hintstyle") == 0)
207 {
208 const char *str;
209
210 switch (x11_screen->xft_hintstyle)
211 {
212 case FC_HINT_NONE:
213 str = "hintnone";
214 break;
215 case FC_HINT_SLIGHT:
216 str = "hintslight";
217 break;
218 case FC_HINT_MEDIUM:
219 str = "hintmedium";
220 break;
221 case FC_HINT_FULL:
222 str = "hintfull";
223 break;
224 default:
225 return FALSE;
226 }
227
228 g_value_set_string (value, str);
229 return TRUE;
230 }
231 else if (strcmp (name, "rgba") == 0)
232 {
233 const char *str;
234
235 switch (x11_screen->xft_rgba)
236 {
237 case FC_RGBA_NONE:
238 str = "none";
239 break;
240 case FC_RGBA_RGB:
241 str = "rgb";
242 break;
243 case FC_RGBA_BGR:
244 str = "bgr";
245 break;
246 case FC_RGBA_VRGB:
247 str = "vrgb";
248 break;
249 case FC_RGBA_VBGR:
250 str = "vbgr";
251 break;
252 case FC_RGBA_UNKNOWN:
253 default:
254 return FALSE;
255 }
256
257 g_value_set_string (value, str);
258 return TRUE;
259 }
260 else if (strcmp (name, "dpi") == 0)
261 {
262 g_value_set_int (value, x11_screen->xft_dpi);
263 return TRUE;
264 }
265
266 return FALSE;
267 }
268