]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkxftdefaults.c
79dd26cd32b5b9c4826f5b368776a65198930a61
[~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 #include <stdlib.h>
42 #include <string.h>
43
44 #include <fontconfig/fontconfig.h>
45
46 #ifndef FC_HINT_STYLE
47 #define FC_HINT_NONE        0
48 #define FC_HINT_SLIGHT      1
49 #define FC_HINT_MEDIUM      2
50 #define FC_HINT_FULL        3
51 #endif
52
53 #include <gdkscreen-x11.h>
54 #include <gdkx.h>
55
56 static gint
57 parse_boolean (char *v)
58 {
59   gchar c0, c1;
60   
61   c0 = *v;
62   if (g_ascii_isupper ((int)c0))
63     c0 = g_ascii_tolower (c0);
64   if (c0 == 't' || c0 == 'y' || c0 == '1')
65     return 1;
66   if (c0 == 'f' || c0 == 'n' || c0 == '0')
67     return 0;
68   if (c0 == 'o')
69     {
70       c1 = v[1];
71       if (g_ascii_isupper ((int)c1))
72         c1 = g_ascii_tolower (c1);
73       if (c1 == 'n')
74         return 1;
75       if (c1 == 'f')
76         return 0;
77     }
78   
79   return -1;
80 }
81
82 static gboolean
83 get_boolean_default (Display *dpy,
84                      gchar   *option,
85                      gboolean *value)
86 {
87   gchar *v;
88   gint i;
89   
90   v = XGetDefault (dpy, "Xft", option);
91   if (v)
92     {
93       i = parse_boolean (v);
94       if (i >= 0)
95         {
96           *value = i;
97           return TRUE;
98         }
99     }
100   
101   return FALSE;
102 }
103
104 static gboolean
105 get_double_default (Display *dpy,
106                     gchar   *option,
107                     gdouble *value)
108 {
109   gchar    *v, *e;
110   
111   v = XGetDefault (dpy, "Xft", option);
112   if (v)
113     {
114       /* Xft uses strtod, though localization probably wasn't
115        * desired. For compatibility, we use the conservative
116        * g_strtod() that accepts either localized or non-localized
117        * decimal separator.
118        */
119       *value = g_strtod (v, &e);
120       if (e != v)
121         return TRUE;
122     }
123   
124   return FALSE;
125 }
126
127 static gboolean
128 get_integer_default (Display *dpy,
129                      gchar   *option,
130                      gint    *value)
131 {
132   gchar *v, *e;
133   
134   v = XGetDefault (dpy, "Xft", option);
135   if (v)
136     {
137       if (FcNameConstant ((FcChar8 *) v, value))
138         return TRUE;
139       
140       *value = strtol (v, &e, 0);
141       if (e != v)
142         return TRUE;
143     }
144   
145   return FALSE;
146 }
147
148 static void
149 init_xft_settings (GdkScreen *screen)
150 {
151   GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
152   Display *xdisplay = GDK_SCREEN_XDISPLAY (screen);
153   int xscreen = GDK_SCREEN_XNUMBER (screen);
154   double dpi_double;
155
156   if (screen_x11->xft_init)
157     return;
158
159   screen_x11->xft_init = TRUE;
160
161   if (!get_boolean_default (xdisplay, "antialias", &screen_x11->xft_antialias))
162     screen_x11->xft_antialias = TRUE;
163
164   if (!get_boolean_default (xdisplay, "hinting", &screen_x11->xft_hinting))
165     screen_x11->xft_hinting = TRUE;
166
167   if (!get_integer_default (xdisplay, "hintstyle", &screen_x11->xft_hintstyle))
168     screen_x11->xft_hintstyle = FC_HINT_FULL;
169
170   if (!get_integer_default (xdisplay, "rgba", &screen_x11->xft_rgba))
171                             
172     {
173       int subpixel = FC_RGBA_UNKNOWN;
174       
175 #if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
176       if (_gdk_x11_have_render (screen_x11->display))
177         {
178           int render_order = XRenderQuerySubpixelOrder (xdisplay, xscreen);
179           
180           switch (render_order)
181             {
182             default:
183             case SubPixelUnknown:
184               subpixel = FC_RGBA_UNKNOWN;
185               break;
186             case SubPixelHorizontalRGB:
187               subpixel = FC_RGBA_RGB;
188               break;
189             case SubPixelHorizontalBGR:
190               subpixel = FC_RGBA_BGR;
191               break;
192             case SubPixelVerticalRGB:
193               subpixel = FC_RGBA_VRGB;
194               break;
195             case SubPixelVerticalBGR:
196               subpixel = FC_RGBA_VBGR;
197               break;
198             case SubPixelNone:
199               subpixel = FC_RGBA_NONE;
200               break;
201             }
202         }
203 #endif
204
205       screen_x11->xft_rgba = subpixel;
206     }
207
208   if (!get_double_default (xdisplay, "dpi", &dpi_double))
209     dpi_double = (((double) DisplayHeight (xdisplay, xscreen) * 25.4) / 
210                   (double) DisplayHeightMM (xdisplay, xscreen));
211
212   screen_x11->xft_dpi = (int)(0.5 + PANGO_SCALE * dpi_double);
213 }
214
215 gboolean
216 _gdk_x11_get_xft_setting (GdkScreen   *screen,
217                           const gchar *name,
218                           GValue      *value)
219 {
220   GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
221   
222   if (strncmp (name, "gtk-xft-", 8) != 0)
223     return FALSE;
224
225   name += 8;
226
227   init_xft_settings (screen);
228
229   if (strcmp (name, "antialias") == 0)
230     {
231       g_value_set_int (value, screen_x11->xft_antialias);
232       return TRUE;
233     }
234   else if (strcmp (name, "hinting") == 0)
235     {
236       g_value_set_int (value, screen_x11->xft_hinting);
237       return TRUE;
238     }
239   else if (strcmp (name, "hintstyle") == 0)
240     {
241       const char *str;
242       
243       switch (screen_x11->xft_hintstyle)
244         {
245         case FC_HINT_NONE:
246           str = "hintnone";
247           break;
248         case FC_HINT_SLIGHT:
249           str = "hintslight";
250           break;
251         case FC_HINT_MEDIUM:
252           str = "hintmedium";
253           break;
254         case FC_HINT_FULL:
255           str = "hintfull";
256           break;
257         default:
258           return FALSE;
259         }
260
261       g_value_set_string (value, str);
262       return TRUE;
263     }
264   else if (strcmp (name, "rgba") == 0)
265     {
266       const char *str;
267       
268       switch (screen_x11->xft_rgba)
269         {
270         case FC_RGBA_NONE:
271           str = "none";
272           break;
273         case FC_RGBA_RGB:
274           str = "rgb";
275           break;
276         case FC_RGBA_BGR:
277           str = "bgr";
278           break;
279         case FC_RGBA_VRGB:
280           str = "vrgb";
281           break;
282         case FC_RGBA_VBGR:
283           str = "vbgr";
284           break;
285         case FC_RGBA_UNKNOWN:
286         default:
287           return FALSE;
288         }
289         
290       g_value_set_string (value, str);
291       return TRUE; 
292    }
293   else if (strcmp (name, "dpi") == 0)
294     {
295       g_value_set_int (value, screen_x11->xft_dpi);
296       return TRUE;
297     }
298
299   return FALSE;
300 }