]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkxftdefaults.c
x11: Rename GdkScreenX11 to GdkX11Screen
[~andy/gtk] / gdk / x11 / gdkxftdefaults.c
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, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Based on code from xftdpy.c
20  *
21  * Copyright © 2000 Keith Packard
22  *
23  * Permission to use, copy, modify, distribute, and sell this software and its
24  * documentation for any purpose is hereby granted without fee, provided that
25  * the above copyright notice appear in all copies and that both that
26  * copyright notice and this permission notice appear in supporting
27  * documentation, and that the name of Keith Packard not be used in
28  * advertising or publicity pertaining to distribution of the software without
29  * specific, written prior permission.  Keith Packard makes no
30  * representations about the suitability of this software for any purpose.  It
31  * is provided "as is" without express or implied warranty.
32  *
33  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
34  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
35  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
36  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
37  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39  * PERFORMANCE OF THIS SOFTWARE.
40  */
41
42 #include "config.h"
43
44 #include <stdlib.h>
45 #include <string.h>
46
47 #include <fontconfig/fontconfig.h>
48
49 #ifndef FC_HINT_STYLE
50 #define FC_HINT_NONE        0
51 #define FC_HINT_SLIGHT      1
52 #define FC_HINT_MEDIUM      2
53 #define FC_HINT_FULL        3
54 #endif
55
56 #include <gdkscreen-x11.h>
57 #include <gdkprivate-x11.h>
58
59 static gint
60 parse_boolean (char *v)
61 {
62   gchar c0, c1;
63   
64   c0 = *v;
65   if (g_ascii_isupper ((int)c0))
66     c0 = g_ascii_tolower (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 (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 (Display *dpy,
87                      gchar   *option,
88                      gboolean *value)
89 {
90   gchar *v;
91   gint i;
92   
93   v = XGetDefault (dpy, "Xft", option);
94   if (v)
95     {
96       i = parse_boolean (v);
97       if (i >= 0)
98         {
99           *value = i;
100           return TRUE;
101         }
102     }
103   
104   return FALSE;
105 }
106
107 static gboolean
108 get_double_default (Display *dpy,
109                     gchar   *option,
110                     gdouble *value)
111 {
112   gchar    *v, *e;
113   
114   v = XGetDefault (dpy, "Xft", option);
115   if (v)
116     {
117       /* Xft uses strtod, though localization probably wasn't
118        * desired. For compatibility, we use the conservative
119        * g_strtod() that accepts either localized or non-localized
120        * decimal separator.
121        */
122       *value = g_strtod (v, &e);
123       if (e != v)
124         return TRUE;
125     }
126   
127   return FALSE;
128 }
129
130 static gboolean
131 get_integer_default (Display *dpy,
132                      gchar   *option,
133                      gint    *value)
134 {
135   gchar *v, *e;
136   
137   v = XGetDefault (dpy, "Xft", option);
138   if (v)
139     {
140       if (FcNameConstant ((FcChar8 *) v, value))
141         return TRUE;
142       
143       *value = strtol (v, &e, 0);
144       if (e != v)
145         return TRUE;
146     }
147   
148   return FALSE;
149 }
150
151 static void
152 init_xft_settings (GdkScreen *screen)
153 {
154   GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
155   Display *xdisplay = GDK_SCREEN_XDISPLAY (screen);
156   double dpi_double;
157
158   if (x11_screen->xft_init)
159     return;
160
161   x11_screen->xft_init = TRUE;
162
163   if (!get_boolean_default (xdisplay, "antialias", &x11_screen->xft_antialias))
164     x11_screen->xft_antialias = TRUE;
165
166   if (!get_boolean_default (xdisplay, "hinting", &x11_screen->xft_hinting))
167     x11_screen->xft_hinting = TRUE;
168
169   if (!get_integer_default (xdisplay, "hintstyle", &x11_screen->xft_hintstyle))
170     x11_screen->xft_hintstyle = FC_HINT_FULL;
171
172   if (!get_integer_default (xdisplay, "rgba", &x11_screen->xft_rgba))
173     x11_screen->xft_rgba = FC_RGBA_UNKNOWN;
174
175   if (!get_double_default (xdisplay, "dpi", &dpi_double))
176     dpi_double = (((double) DisplayHeight (xdisplay, x11_screen->screen_num) * 25.4) /
177                   (double) DisplayHeightMM (xdisplay, x11_screen->screen_num));
178
179   x11_screen->xft_dpi = (int)(0.5 + PANGO_SCALE * dpi_double);
180 }
181
182 gboolean
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 }