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 | |
59 | static int |
60 | parse_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 | |
85 | static gboolean |
86 | get_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 | |
111 | static gboolean |
112 | get_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 | |
138 | static gboolean |
139 | get_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 | |
163 | static void |
164 | init_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 | |
194 | gboolean |
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 | |