]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkxftdefaults.c
Change GdkFrameClock from an interface to a class
[~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, 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
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
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
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
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
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_FULL;
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 = (((double) DisplayHeight (xdisplay, x11_screen->screen_num) * 25.4) /
178                   (double) DisplayHeightMM (xdisplay, x11_screen->screen_num));
179
180   x11_screen->xft_dpi = (int)(0.5 + PANGO_SCALE * dpi_double);
181 }
182
183 gboolean
184 _gdk_x11_get_xft_setting (GdkScreen   *screen,
185                           const gchar *name,
186                           GValue      *value)
187 {
188   GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
189   
190   if (strncmp (name, "gtk-xft-", 8) != 0)
191     return FALSE;
192
193   name += 8;
194
195   init_xft_settings (screen);
196
197   if (strcmp (name, "antialias") == 0)
198     {
199       g_value_set_int (value, x11_screen->xft_antialias);
200       return TRUE;
201     }
202   else if (strcmp (name, "hinting") == 0)
203     {
204       g_value_set_int (value, x11_screen->xft_hinting);
205       return TRUE;
206     }
207   else if (strcmp (name, "hintstyle") == 0)
208     {
209       const char *str;
210       
211       switch (x11_screen->xft_hintstyle)
212         {
213         case FC_HINT_NONE:
214           str = "hintnone";
215           break;
216         case FC_HINT_SLIGHT:
217           str = "hintslight";
218           break;
219         case FC_HINT_MEDIUM:
220           str = "hintmedium";
221           break;
222         case FC_HINT_FULL:
223           str = "hintfull";
224           break;
225         default:
226           return FALSE;
227         }
228
229       g_value_set_string (value, str);
230       return TRUE;
231     }
232   else if (strcmp (name, "rgba") == 0)
233     {
234       const char *str;
235       
236       switch (x11_screen->xft_rgba)
237         {
238         case FC_RGBA_NONE:
239           str = "none";
240           break;
241         case FC_RGBA_RGB:
242           str = "rgb";
243           break;
244         case FC_RGBA_BGR:
245           str = "bgr";
246           break;
247         case FC_RGBA_VRGB:
248           str = "vrgb";
249           break;
250         case FC_RGBA_VBGR:
251           str = "vbgr";
252           break;
253         case FC_RGBA_UNKNOWN:
254         default:
255           return FALSE;
256         }
257         
258       g_value_set_string (value, str);
259       return TRUE; 
260    }
261   else if (strcmp (name, "dpi") == 0)
262     {
263       g_value_set_int (value, x11_screen->xft_dpi);
264       return TRUE;
265     }
266
267   return FALSE;
268 }