Commit | Line | Data |
---|---|---|
4ff155dd GM |
1 | /* Functions for handling font and other changes dynamically. |
2 | ||
acaf905b | 3 | Copyright (C) 2009-2012 Free Software Foundation, Inc. |
637fa988 JD |
4 | |
5 | This file is part of GNU Emacs. | |
6 | ||
7 | GNU Emacs is free software: you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation, either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | GNU Emacs is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
08a494a3 | 20 | #include <config.h> |
aaafe47a PE |
21 | |
22 | #include <float.h> | |
210af043 | 23 | #include <limits.h> |
637fa988 JD |
24 | #include <fcntl.h> |
25 | #include "lisp.h" | |
26 | #include "xterm.h" | |
27 | #include "xsettings.h" | |
28 | #include "frame.h" | |
b87dd913 | 29 | #include "keyboard.h" |
637fa988 JD |
30 | #include "blockinput.h" |
31 | #include "termhooks.h" | |
32 | #include "termopts.h" | |
33 | ||
34 | #include <X11/Xproto.h> | |
35 | ||
9851bfc5 | 36 | #ifdef HAVE_GSETTINGS |
51bb811f JD |
37 | #include <glib-object.h> |
38 | #include <gio/gio.h> | |
869795d6 JD |
39 | #endif |
40 | ||
637fa988 JD |
41 | #ifdef HAVE_GCONF |
42 | #include <gconf/gconf-client.h> | |
43 | #endif | |
9851bfc5 | 44 | |
637fa988 JD |
45 | #ifdef HAVE_XFT |
46 | #include <X11/Xft/Xft.h> | |
47 | #endif | |
48 | ||
49 | static char *current_mono_font; | |
99852628 | 50 | static char *current_font; |
637fa988 | 51 | static struct x_display_info *first_dpyinfo; |
f904c0f9 JD |
52 | static Lisp_Object Qmonospace_font_name, Qfont_name, Qfont_render, |
53 | Qtool_bar_style; | |
f904c0f9 | 54 | static Lisp_Object current_tool_bar_style; |
637fa988 | 55 | |
869795d6 JD |
56 | /* Store an config changed event in to the event queue. */ |
57 | ||
637fa988 | 58 | static void |
971de7fb | 59 | store_config_changed_event (Lisp_Object arg, Lisp_Object display_name) |
637fa988 JD |
60 | { |
61 | struct input_event event; | |
62 | EVENT_INIT (event); | |
63 | event.kind = CONFIG_CHANGED_EVENT; | |
64 | event.frame_or_window = display_name; | |
65 | event.arg = arg; | |
66 | kbd_buffer_store_event (&event); | |
67 | } | |
68 | ||
869795d6 JD |
69 | /* Return non-zero if DPYINFO is still valid. */ |
70 | static int | |
71 | dpyinfo_valid (struct x_display_info *dpyinfo) | |
72 | { | |
73 | int found = 0; | |
74 | if (dpyinfo != NULL) | |
75 | { | |
76 | struct x_display_info *d; | |
77 | for (d = x_display_list; !found && d; d = d->next) | |
78 | found = d == dpyinfo && d->display == dpyinfo->display; | |
79 | } | |
80 | return found; | |
81 | } | |
82 | ||
83 | /* Store a monospace font change event if the monospaced font changed. */ | |
84 | ||
490011a6 | 85 | #if defined HAVE_XFT && (defined HAVE_GSETTINGS || defined HAVE_GCONF) |
9851bfc5 | 86 | static void |
0949d2b6 | 87 | store_monospaced_changed (const char *newfont) |
9851bfc5 | 88 | { |
0949d2b6 JD |
89 | if (current_mono_font != NULL && strcmp (newfont, current_mono_font) == 0) |
90 | return; /* No change. */ | |
91 | ||
92 | xfree (current_mono_font); | |
93 | current_mono_font = xstrdup (newfont); | |
94 | ||
869795d6 | 95 | if (dpyinfo_valid (first_dpyinfo) && use_system_font) |
9851bfc5 | 96 | { |
869795d6 JD |
97 | store_config_changed_event (Qmonospace_font_name, |
98 | XCAR (first_dpyinfo->name_list_element)); | |
9851bfc5 JD |
99 | } |
100 | } | |
490011a6 | 101 | #endif |
9851bfc5 | 102 | |
869795d6 | 103 | /* Store a font name change event if the font name changed. */ |
9851bfc5 | 104 | |
490011a6 | 105 | #ifdef HAVE_XFT |
869795d6 JD |
106 | static void |
107 | store_font_name_changed (const char *newfont) | |
108 | { | |
109 | if (current_font != NULL && strcmp (newfont, current_font) == 0) | |
110 | return; /* No change. */ | |
111 | ||
112 | xfree (current_font); | |
113 | current_font = xstrdup (newfont); | |
114 | ||
115 | if (dpyinfo_valid (first_dpyinfo)) | |
116 | { | |
117 | store_config_changed_event (Qfont_name, | |
118 | XCAR (first_dpyinfo->name_list_element)); | |
119 | } | |
120 | } | |
121 | #endif /* HAVE_XFT */ | |
122 | ||
da6062e6 | 123 | /* Map TOOL_BAR_STYLE from a string to its corresponding Lisp value. |
869795d6 JD |
124 | Return Qnil if TOOL_BAR_STYLE is not known. */ |
125 | ||
126 | static Lisp_Object | |
127 | map_tool_bar_style (const char *tool_bar_style) | |
128 | { | |
129 | Lisp_Object style = Qnil; | |
130 | if (tool_bar_style) | |
131 | { | |
132 | if (strcmp (tool_bar_style, "both") == 0) | |
133 | style = Qboth; | |
134 | else if (strcmp (tool_bar_style, "both-horiz") == 0) | |
135 | style = Qboth_horiz; | |
136 | else if (strcmp (tool_bar_style, "icons") == 0) | |
137 | style = Qimage; | |
138 | else if (strcmp (tool_bar_style, "text") == 0) | |
139 | style = Qtext; | |
140 | } | |
141 | ||
142 | return style; | |
143 | } | |
144 | ||
145 | /* Store a tool bar style change event if the tool bar style changed. */ | |
146 | ||
147 | static void | |
148 | store_tool_bar_style_changed (const char *newstyle, | |
149 | struct x_display_info *dpyinfo) | |
150 | { | |
151 | Lisp_Object style = map_tool_bar_style (newstyle); | |
152 | if (EQ (current_tool_bar_style, style)) | |
153 | return; /* No change. */ | |
154 | ||
155 | current_tool_bar_style = style; | |
156 | if (dpyinfo_valid (dpyinfo)) | |
157 | store_config_changed_event (Qtool_bar_style, | |
158 | XCAR (dpyinfo->name_list_element)); | |
159 | } | |
9851bfc5 | 160 | |
2014308a | 161 | #ifdef HAVE_XFT |
f904c0f9 | 162 | #define XSETTINGS_FONT_NAME "Gtk/FontName" |
2014308a | 163 | #endif |
f904c0f9 | 164 | #define XSETTINGS_TOOL_BAR_STYLE "Gtk/ToolbarStyle" |
0269ef77 | 165 | |
f904c0f9 JD |
166 | enum { |
167 | SEEN_AA = 0x01, | |
168 | SEEN_HINTING = 0x02, | |
169 | SEEN_RGBA = 0x04, | |
170 | SEEN_LCDFILTER = 0x08, | |
171 | SEEN_HINTSTYLE = 0x10, | |
172 | SEEN_DPI = 0x20, | |
173 | SEEN_FONT = 0x40, | |
174 | SEEN_TB_STYLE = 0x80, | |
175 | }; | |
af59aa6e | 176 | struct xsettings |
f904c0f9 JD |
177 | { |
178 | #ifdef HAVE_XFT | |
179 | FcBool aa, hinting; | |
180 | int rgba, lcdfilter, hintstyle; | |
181 | double dpi; | |
f904c0f9 JD |
182 | |
183 | char *font; | |
869795d6 JD |
184 | #endif |
185 | ||
f904c0f9 JD |
186 | char *tb_style; |
187 | ||
188 | unsigned seen; | |
189 | }; | |
190 | ||
9851bfc5 | 191 | #ifdef HAVE_GSETTINGS |
869795d6 JD |
192 | #define GSETTINGS_SCHEMA "org.gnome.desktop.interface" |
193 | #define GSETTINGS_TOOL_BAR_STYLE "toolbar-style" | |
194 | ||
195 | #ifdef HAVE_XFT | |
196 | #define GSETTINGS_MONO_FONT "monospace-font-name" | |
197 | #define GSETTINGS_FONT_NAME "font-name" | |
198 | #endif | |
199 | ||
200 | ||
201 | /* The single GSettings instance, or NULL if not connected to GSettings. */ | |
202 | ||
203 | static GSettings *gsettings_client; | |
204 | ||
205 | /* Callback called when something changed in GSettings. */ | |
31a01b90 | 206 | |
0949d2b6 | 207 | static void |
869795d6 JD |
208 | something_changed_gsettingsCB (GSettings *settings, |
209 | gchar *key, | |
210 | gpointer user_data) | |
0949d2b6 JD |
211 | { |
212 | GVariant *val; | |
869795d6 JD |
213 | |
214 | if (strcmp (key, GSETTINGS_TOOL_BAR_STYLE) == 0) | |
0949d2b6 | 215 | { |
869795d6 JD |
216 | val = g_settings_get_value (settings, GSETTINGS_TOOL_BAR_STYLE); |
217 | if (val) | |
0949d2b6 | 218 | { |
869795d6 JD |
219 | g_variant_ref_sink (val); |
220 | if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) | |
221 | { | |
222 | const gchar *newstyle = g_variant_get_string (val, NULL); | |
223 | store_tool_bar_style_changed (newstyle, first_dpyinfo); | |
224 | } | |
225 | g_variant_unref (val); | |
226 | } | |
227 | } | |
228 | #ifdef HAVE_XFT | |
229 | else if (strcmp (key, GSETTINGS_MONO_FONT) == 0) | |
230 | { | |
231 | val = g_settings_get_value (settings, GSETTINGS_MONO_FONT); | |
232 | if (val) | |
233 | { | |
234 | g_variant_ref_sink (val); | |
235 | if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) | |
236 | { | |
237 | const gchar *newfont = g_variant_get_string (val, NULL); | |
238 | store_monospaced_changed (newfont); | |
239 | } | |
240 | g_variant_unref (val); | |
0949d2b6 | 241 | } |
0949d2b6 | 242 | } |
869795d6 JD |
243 | else if (strcmp (key, GSETTINGS_FONT_NAME) == 0) |
244 | { | |
245 | val = g_settings_get_value (settings, GSETTINGS_FONT_NAME); | |
246 | if (val) | |
247 | { | |
248 | g_variant_ref_sink (val); | |
249 | if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) | |
250 | { | |
251 | const gchar *newfont = g_variant_get_string (val, NULL); | |
252 | store_font_name_changed (newfont); | |
253 | } | |
254 | g_variant_unref (val); | |
255 | } | |
256 | } | |
490011a6 | 257 | #endif /* HAVE_XFT */ |
0949d2b6 JD |
258 | } |
259 | ||
869795d6 | 260 | #endif /* HAVE_GSETTINGS */ |
2e13213d | 261 | |
869795d6 JD |
262 | #ifdef HAVE_GCONF |
263 | #define GCONF_TOOL_BAR_STYLE "/desktop/gnome/interface/toolbar_style" | |
2e13213d | 264 | #ifdef HAVE_XFT |
869795d6 JD |
265 | #define GCONF_MONO_FONT "/desktop/gnome/interface/monospace_font_name" |
266 | #define GCONF_FONT_NAME "/desktop/gnome/interface/font_name" | |
2e13213d | 267 | #endif |
31a01b90 | 268 | |
869795d6 JD |
269 | /* The single GConf instance, or NULL if not connected to GConf. */ |
270 | ||
271 | static GConfClient *gconf_client; | |
272 | ||
273 | /* Callback called when something changed in GConf that we care about. */ | |
637fa988 JD |
274 | |
275 | static void | |
869795d6 JD |
276 | something_changed_gconfCB (GConfClient *client, |
277 | guint cnxn_id, | |
278 | GConfEntry *entry, | |
279 | gpointer user_data) | |
637fa988 JD |
280 | { |
281 | GConfValue *v = gconf_entry_get_value (entry); | |
869795d6 | 282 | const char *key = gconf_entry_get_key (entry); |
af59aa6e | 283 | |
869795d6 JD |
284 | if (!v || v->type != GCONF_VALUE_STRING || ! key) return; |
285 | if (strcmp (key, GCONF_TOOL_BAR_STYLE) == 0) | |
286 | { | |
287 | const char *value = gconf_value_get_string (v); | |
288 | store_tool_bar_style_changed (value, first_dpyinfo); | |
289 | } | |
290 | #ifdef HAVE_XFT | |
291 | else if (strcmp (key, GCONF_MONO_FONT) == 0) | |
637fa988 JD |
292 | { |
293 | const char *value = gconf_value_get_string (v); | |
0949d2b6 | 294 | store_monospaced_changed (value); |
637fa988 | 295 | } |
869795d6 JD |
296 | else if (strcmp (key, GCONF_FONT_NAME) == 0) |
297 | { | |
298 | const char *value = gconf_value_get_string (v); | |
299 | store_font_name_changed (value); | |
300 | } | |
301 | #endif /* HAVE_XFT */ | |
637fa988 | 302 | } |
9851bfc5 | 303 | |
637fa988 JD |
304 | #endif /* HAVE_GCONF */ |
305 | ||
306 | #ifdef HAVE_XFT | |
307 | ||
21050de1 JD |
308 | /* Older fontconfig versions don't have FC_LCD_*. */ |
309 | #ifndef FC_LCD_NONE | |
310 | #define FC_LCD_NONE 0 | |
311 | #endif | |
312 | #ifndef FC_LCD_DEFAULT | |
313 | #define FC_LCD_DEFAULT 1 | |
314 | #endif | |
315 | #ifndef FC_LCD_FILTER | |
316 | #define FC_LCD_FILTER "lcdfilter" | |
317 | #endif | |
318 | ||
f904c0f9 JD |
319 | #endif /* HAVE_XFT */ |
320 | ||
637fa988 JD |
321 | /* Find the window that contains the XSETTINGS property values. */ |
322 | ||
323 | static void | |
971de7fb | 324 | get_prop_window (struct x_display_info *dpyinfo) |
637fa988 JD |
325 | { |
326 | Display *dpy = dpyinfo->display; | |
327 | ||
328 | XGrabServer (dpy); | |
329 | dpyinfo->xsettings_window = XGetSelectionOwner (dpy, | |
330 | dpyinfo->Xatom_xsettings_sel); | |
331 | if (dpyinfo->xsettings_window != None) | |
332 | /* Select events so we can detect if window is deleted or if settings | |
333 | are changed. */ | |
334 | XSelectInput (dpy, dpyinfo->xsettings_window, | |
335 | PropertyChangeMask|StructureNotifyMask); | |
336 | ||
337 | XUngrabServer (dpy); | |
338 | } | |
339 | ||
637fa988 JD |
340 | #define SWAP32(nr) (((nr) << 24) | (((nr) << 8) & 0xff0000) \ |
341 | | (((nr) >> 8) & 0xff00) | ((nr) >> 24)) | |
342 | #define SWAP16(nr) (((nr) << 8) | ((nr) >> 8)) | |
343 | #define PAD(nr) (((nr) + 3) & ~3) | |
344 | ||
345 | /* Parse xsettings and extract those that deal with Xft. | |
346 | See http://freedesktop.org/wiki/Specifications/XSettingsRegistry | |
347 | and http://standards.freedesktop.org/xsettings-spec/xsettings-spec-0.5.html. | |
348 | ||
349 | Layout of prop. First is a header: | |
350 | ||
351 | bytes type what | |
352 | ------------------------------------ | |
353 | 1 CARD8 byte-order | |
354 | 3 unused | |
355 | 4 CARD32 SERIAL | |
356 | 4 CARD32 N_SETTINGS | |
357 | ||
358 | Then N_SETTINGS records, with header: | |
359 | ||
360 | bytes type what | |
361 | ------------------------------------ | |
362 | 1 SETTING_TYPE type (0 = integer, 1 = string, 2 RGB color). | |
363 | 1 unused | |
364 | 2 CARD16 n == name-length | |
365 | n STRING8 name | |
366 | p unused, p=pad_to_even_4(n) | |
367 | 4 CARD32 last-change-serial | |
368 | ||
369 | and then the value, For string: | |
af59aa6e | 370 | |
637fa988 JD |
371 | bytes type what |
372 | ------------------------------------ | |
373 | 4 CARD32 n = value-length | |
374 | n STRING8 value | |
375 | p unused, p=pad_to_even_4(n) | |
376 | ||
377 | For integer: | |
378 | ||
379 | bytes type what | |
380 | ------------------------------------ | |
381 | 4 INT32 value | |
382 | ||
383 | For RGB color: | |
384 | ||
385 | bytes type what | |
386 | ------------------------------------ | |
387 | 2 CARD16 red | |
388 | 2 CARD16 blue | |
389 | 2 CARD16 green | |
390 | 2 CARD16 alpha | |
391 | ||
3c055b77 | 392 | Returns non-zero if some Xft settings was seen, zero otherwise. |
637fa988 JD |
393 | */ |
394 | ||
395 | static int | |
e4c8d29a J |
396 | parse_settings (unsigned char *prop, |
397 | long unsigned int bytes, | |
398 | struct xsettings *settings) | |
637fa988 JD |
399 | { |
400 | Lisp_Object byteorder = Fbyteorder (); | |
401 | int my_bo = XFASTINT (byteorder) == 'B' ? MSBFirst : LSBFirst; | |
402 | int that_bo = prop[0]; | |
403 | CARD32 n_settings; | |
404 | int bytes_parsed = 0; | |
405 | int settings_seen = 0; | |
406 | int i = 0; | |
407 | ||
408 | /* First 4 bytes is a serial number, skip that. */ | |
409 | ||
410 | if (bytes < 12) return BadLength; | |
411 | memcpy (&n_settings, prop+8, 4); | |
412 | if (my_bo != that_bo) n_settings = SWAP32 (n_settings); | |
413 | bytes_parsed = 12; | |
414 | ||
415 | memset (settings, 0, sizeof (*settings)); | |
416 | ||
99852628 | 417 | while (bytes_parsed+4 < bytes && settings_seen < 7 |
637fa988 JD |
418 | && i < n_settings) |
419 | { | |
420 | int type = prop[bytes_parsed++]; | |
421 | CARD16 nlen; | |
422 | CARD32 vlen, ival = 0; | |
423 | char name[128]; /* The names we are looking for are not this long. */ | |
424 | char sval[128]; /* The values we are looking for are not this long. */ | |
99852628 | 425 | int want_this; |
637fa988 JD |
426 | int to_cpy; |
427 | ||
428 | sval[0] = '\0'; | |
429 | ++i; | |
430 | ++bytes_parsed; /* Padding */ | |
431 | ||
432 | memcpy (&nlen, prop+bytes_parsed, 2); | |
433 | bytes_parsed += 2; | |
434 | if (my_bo != that_bo) nlen = SWAP16 (nlen); | |
435 | if (bytes_parsed+nlen > bytes) return BadLength; | |
436 | to_cpy = nlen > 127 ? 127 : nlen; | |
437 | memcpy (name, prop+bytes_parsed, to_cpy); | |
438 | name[to_cpy] = '\0'; | |
439 | ||
440 | bytes_parsed += nlen; | |
441 | bytes_parsed = PAD (bytes_parsed); | |
442 | ||
443 | bytes_parsed += 4; /* Skip serial for this value */ | |
444 | if (bytes_parsed > bytes) return BadLength; | |
445 | ||
490011a6 | 446 | want_this = |
f904c0f9 JD |
447 | #ifdef HAVE_XFT |
448 | (nlen > 6 && strncmp (name, "Xft/", 4) == 0) | |
869795d6 | 449 | || strcmp (XSETTINGS_FONT_NAME, name) == 0 |
f904c0f9 JD |
450 | || |
451 | #endif | |
869795d6 | 452 | strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0; |
490011a6 | 453 | |
af59aa6e | 454 | switch (type) |
637fa988 JD |
455 | { |
456 | case 0: /* Integer */ | |
457 | if (bytes_parsed+4 > bytes) return BadLength; | |
99852628 | 458 | if (want_this) |
637fa988 JD |
459 | { |
460 | memcpy (&ival, prop+bytes_parsed, 4); | |
461 | if (my_bo != that_bo) ival = SWAP32 (ival); | |
462 | } | |
463 | bytes_parsed += 4; | |
464 | break; | |
465 | ||
466 | case 1: /* String */ | |
467 | if (bytes_parsed+4 > bytes) return BadLength; | |
468 | memcpy (&vlen, prop+bytes_parsed, 4); | |
469 | bytes_parsed += 4; | |
470 | if (my_bo != that_bo) vlen = SWAP32 (vlen); | |
99852628 | 471 | if (want_this) |
637fa988 JD |
472 | { |
473 | to_cpy = vlen > 127 ? 127 : vlen; | |
474 | memcpy (sval, prop+bytes_parsed, to_cpy); | |
475 | sval[to_cpy] = '\0'; | |
476 | } | |
477 | bytes_parsed += vlen; | |
478 | bytes_parsed = PAD (bytes_parsed); | |
479 | break; | |
480 | ||
481 | case 2: /* RGB value */ | |
482 | /* No need to parse this */ | |
483 | if (bytes_parsed+8 > bytes) return BadLength; | |
af59aa6e | 484 | bytes_parsed += 8; /* 4 values (r, b, g, alpha), 2 bytes each. */ |
637fa988 JD |
485 | break; |
486 | ||
487 | default: /* Parse Error */ | |
488 | return BadValue; | |
489 | } | |
490 | ||
af59aa6e | 491 | if (want_this) |
637fa988 JD |
492 | { |
493 | ++settings_seen; | |
869795d6 | 494 | if (strcmp (name, XSETTINGS_TOOL_BAR_STYLE) == 0) |
f904c0f9 JD |
495 | { |
496 | settings->tb_style = xstrdup (sval); | |
497 | settings->seen |= SEEN_TB_STYLE; | |
498 | } | |
499 | #ifdef HAVE_XFT | |
869795d6 JD |
500 | else if (strcmp (name, XSETTINGS_FONT_NAME) == 0) |
501 | { | |
502 | settings->font = xstrdup (sval); | |
503 | settings->seen |= SEEN_FONT; | |
504 | } | |
f904c0f9 | 505 | else if (strcmp (name, "Xft/Antialias") == 0) |
3c055b77 JD |
506 | { |
507 | settings->seen |= SEEN_AA; | |
508 | settings->aa = ival != 0; | |
509 | } | |
637fa988 | 510 | else if (strcmp (name, "Xft/Hinting") == 0) |
3c055b77 JD |
511 | { |
512 | settings->seen |= SEEN_HINTING; | |
513 | settings->hinting = ival != 0; | |
514 | } | |
af59aa6e | 515 | # ifdef FC_HINT_STYLE |
637fa988 JD |
516 | else if (strcmp (name, "Xft/HintStyle") == 0) |
517 | { | |
3c055b77 | 518 | settings->seen |= SEEN_HINTSTYLE; |
637fa988 JD |
519 | if (strcmp (sval, "hintnone") == 0) |
520 | settings->hintstyle = FC_HINT_NONE; | |
521 | else if (strcmp (sval, "hintslight") == 0) | |
522 | settings->hintstyle = FC_HINT_SLIGHT; | |
523 | else if (strcmp (sval, "hintmedium") == 0) | |
524 | settings->hintstyle = FC_HINT_MEDIUM; | |
525 | else if (strcmp (sval, "hintfull") == 0) | |
526 | settings->hintstyle = FC_HINT_FULL; | |
3c055b77 JD |
527 | else |
528 | settings->seen &= ~SEEN_HINTSTYLE; | |
637fa988 | 529 | } |
af59aa6e | 530 | # endif |
637fa988 JD |
531 | else if (strcmp (name, "Xft/RGBA") == 0) |
532 | { | |
3c055b77 | 533 | settings->seen |= SEEN_RGBA; |
637fa988 JD |
534 | if (strcmp (sval, "none") == 0) |
535 | settings->rgba = FC_RGBA_NONE; | |
536 | else if (strcmp (sval, "rgb") == 0) | |
537 | settings->rgba = FC_RGBA_RGB; | |
538 | else if (strcmp (sval, "bgr") == 0) | |
539 | settings->rgba = FC_RGBA_BGR; | |
540 | else if (strcmp (sval, "vrgb") == 0) | |
541 | settings->rgba = FC_RGBA_VRGB; | |
542 | else if (strcmp (sval, "vbgr") == 0) | |
543 | settings->rgba = FC_RGBA_VBGR; | |
3c055b77 JD |
544 | else |
545 | settings->seen &= ~SEEN_RGBA; | |
637fa988 JD |
546 | } |
547 | else if (strcmp (name, "Xft/DPI") == 0) | |
3c055b77 JD |
548 | { |
549 | settings->seen |= SEEN_DPI; | |
550 | settings->dpi = (double)ival/1024.0; | |
551 | } | |
637fa988 JD |
552 | else if (strcmp (name, "Xft/lcdfilter") == 0) |
553 | { | |
3c055b77 | 554 | settings->seen |= SEEN_LCDFILTER; |
637fa988 JD |
555 | if (strcmp (sval, "none") == 0) |
556 | settings->lcdfilter = FC_LCD_NONE; | |
557 | else if (strcmp (sval, "lcddefault") == 0) | |
558 | settings->lcdfilter = FC_LCD_DEFAULT; | |
3c055b77 JD |
559 | else |
560 | settings->seen &= ~SEEN_LCDFILTER; | |
637fa988 | 561 | } |
f904c0f9 | 562 | #endif /* HAVE_XFT */ |
637fa988 JD |
563 | } |
564 | } | |
565 | ||
3c055b77 | 566 | return settings_seen; |
637fa988 JD |
567 | } |
568 | ||
869795d6 JD |
569 | /* Read settings from the XSettings property window on display for DPYINFO. |
570 | Store settings read in SETTINGS. | |
571 | Return non-zero if successful, zero if not. */ | |
572 | ||
637fa988 | 573 | static int |
971de7fb | 574 | read_settings (struct x_display_info *dpyinfo, struct xsettings *settings) |
637fa988 | 575 | { |
637fa988 JD |
576 | Atom act_type; |
577 | int act_form; | |
578 | unsigned long nitems, bytes_after; | |
579 | unsigned char *prop = NULL; | |
580 | Display *dpy = dpyinfo->display; | |
581 | int rc; | |
582 | ||
583 | x_catch_errors (dpy); | |
584 | rc = XGetWindowProperty (dpy, | |
585 | dpyinfo->xsettings_window, | |
586 | dpyinfo->Xatom_xsettings_prop, | |
587 | 0, LONG_MAX, False, AnyPropertyType, | |
588 | &act_type, &act_form, &nitems, &bytes_after, | |
589 | &prop); | |
590 | ||
591 | if (rc == Success && prop != NULL && act_form == 8 && nitems > 0 | |
592 | && act_type == dpyinfo->Xatom_xsettings_prop) | |
f904c0f9 | 593 | rc = parse_settings (prop, nitems, settings); |
637fa988 JD |
594 | |
595 | XFree (prop); | |
596 | ||
597 | x_uncatch_errors (); | |
598 | ||
3c055b77 | 599 | return rc != 0; |
637fa988 JD |
600 | } |
601 | ||
869795d6 JD |
602 | /* Apply Xft settings in SETTINGS to the Xft library. |
603 | If SEND_EVENT_P is non-zero store a Lisp event that Xft settings changed. */ | |
581e51e8 | 604 | |
637fa988 | 605 | static void |
e4c8d29a J |
606 | apply_xft_settings (struct x_display_info *dpyinfo, |
607 | int send_event_p, | |
608 | struct xsettings *settings) | |
637fa988 | 609 | { |
f904c0f9 | 610 | #ifdef HAVE_XFT |
637fa988 | 611 | FcPattern *pat; |
f904c0f9 | 612 | struct xsettings oldsettings; |
637fa988 JD |
613 | int changed = 0; |
614 | ||
637fa988 | 615 | memset (&oldsettings, 0, sizeof (oldsettings)); |
637fa988 JD |
616 | pat = FcPatternCreate (); |
617 | XftDefaultSubstitute (dpyinfo->display, | |
618 | XScreenNumberOfScreen (dpyinfo->screen), | |
619 | pat); | |
620 | FcPatternGetBool (pat, FC_ANTIALIAS, 0, &oldsettings.aa); | |
621 | FcPatternGetBool (pat, FC_HINTING, 0, &oldsettings.hinting); | |
869795d6 | 622 | #ifdef FC_HINT_STYLE |
637fa988 | 623 | FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &oldsettings.hintstyle); |
869795d6 | 624 | #endif |
637fa988 JD |
625 | FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &oldsettings.lcdfilter); |
626 | FcPatternGetInteger (pat, FC_RGBA, 0, &oldsettings.rgba); | |
627 | FcPatternGetDouble (pat, FC_DPI, 0, &oldsettings.dpi); | |
628 | ||
f904c0f9 | 629 | if ((settings->seen & SEEN_AA) != 0 && oldsettings.aa != settings->aa) |
637fa988 JD |
630 | { |
631 | FcPatternDel (pat, FC_ANTIALIAS); | |
f904c0f9 | 632 | FcPatternAddBool (pat, FC_ANTIALIAS, settings->aa); |
637fa988 | 633 | ++changed; |
f904c0f9 | 634 | oldsettings.aa = settings->aa; |
637fa988 | 635 | } |
67477f30 | 636 | |
f904c0f9 JD |
637 | if ((settings->seen & SEEN_HINTING) != 0 |
638 | && oldsettings.hinting != settings->hinting) | |
637fa988 JD |
639 | { |
640 | FcPatternDel (pat, FC_HINTING); | |
f904c0f9 | 641 | FcPatternAddBool (pat, FC_HINTING, settings->hinting); |
637fa988 | 642 | ++changed; |
f904c0f9 | 643 | oldsettings.hinting = settings->hinting; |
637fa988 | 644 | } |
f904c0f9 | 645 | if ((settings->seen & SEEN_RGBA) != 0 && oldsettings.rgba != settings->rgba) |
637fa988 JD |
646 | { |
647 | FcPatternDel (pat, FC_RGBA); | |
f904c0f9 JD |
648 | FcPatternAddInteger (pat, FC_RGBA, settings->rgba); |
649 | oldsettings.rgba = settings->rgba; | |
637fa988 JD |
650 | ++changed; |
651 | } | |
67477f30 | 652 | |
a6eb20d8 | 653 | /* Older fontconfig versions don't have FC_LCD_FILTER. */ |
f904c0f9 JD |
654 | if ((settings->seen & SEEN_LCDFILTER) != 0 |
655 | && oldsettings.lcdfilter != settings->lcdfilter) | |
637fa988 JD |
656 | { |
657 | FcPatternDel (pat, FC_LCD_FILTER); | |
f904c0f9 | 658 | FcPatternAddInteger (pat, FC_LCD_FILTER, settings->lcdfilter); |
637fa988 | 659 | ++changed; |
f904c0f9 | 660 | oldsettings.lcdfilter = settings->lcdfilter; |
637fa988 | 661 | } |
67477f30 | 662 | |
869795d6 | 663 | #ifdef FC_HINT_STYLE |
f904c0f9 JD |
664 | if ((settings->seen & SEEN_HINTSTYLE) != 0 |
665 | && oldsettings.hintstyle != settings->hintstyle) | |
637fa988 JD |
666 | { |
667 | FcPatternDel (pat, FC_HINT_STYLE); | |
f904c0f9 | 668 | FcPatternAddInteger (pat, FC_HINT_STYLE, settings->hintstyle); |
637fa988 | 669 | ++changed; |
f904c0f9 | 670 | oldsettings.hintstyle = settings->hintstyle; |
637fa988 | 671 | } |
869795d6 | 672 | #endif |
67477f30 | 673 | |
f904c0f9 JD |
674 | if ((settings->seen & SEEN_DPI) != 0 && oldsettings.dpi != settings->dpi |
675 | && settings->dpi > 0) | |
637fa988 JD |
676 | { |
677 | Lisp_Object frame, tail; | |
678 | ||
679 | FcPatternDel (pat, FC_DPI); | |
f904c0f9 | 680 | FcPatternAddDouble (pat, FC_DPI, settings->dpi); |
637fa988 | 681 | ++changed; |
f904c0f9 | 682 | oldsettings.dpi = settings->dpi; |
af59aa6e | 683 | |
637fa988 | 684 | /* Change the DPI on this display and all frames on the display. */ |
f904c0f9 | 685 | dpyinfo->resy = dpyinfo->resx = settings->dpi; |
637fa988 JD |
686 | FOR_EACH_FRAME (tail, frame) |
687 | if (FRAME_X_P (XFRAME (frame)) | |
688 | && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo) | |
f904c0f9 | 689 | XFRAME (frame)->resy = XFRAME (frame)->resx = settings->dpi; |
637fa988 JD |
690 | } |
691 | ||
692 | if (changed) | |
693 | { | |
aaafe47a PE |
694 | static char const format[] = |
695 | "Antialias: %d, Hinting: %d, RGBA: %d, LCDFilter: %d, " | |
696 | "Hintstyle: %d, DPI: %lf"; | |
697 | enum | |
698 | { | |
699 | d_formats = 5, | |
700 | d_growth = INT_BUFSIZE_BOUND (int) - sizeof "%d", | |
701 | lf_formats = 1, | |
702 | max_f_integer_digits = DBL_MAX_10_EXP + 1, | |
703 | f_precision = 6, | |
704 | lf_growth = (sizeof "-." + max_f_integer_digits + f_precision | |
705 | - sizeof "%lf") | |
706 | }; | |
707 | char buf[sizeof format + d_formats * d_growth + lf_formats * lf_growth]; | |
708 | ||
637fa988 JD |
709 | XftDefaultSet (dpyinfo->display, pat); |
710 | if (send_event_p) | |
f904c0f9 JD |
711 | store_config_changed_event (Qfont_render, |
712 | XCAR (dpyinfo->name_list_element)); | |
0328b6de | 713 | Vxft_settings |
a8290ec3 DA |
714 | = make_formatted_string (buf, format, |
715 | oldsettings.aa, oldsettings.hinting, | |
716 | oldsettings.rgba, oldsettings.lcdfilter, | |
717 | oldsettings.hintstyle, oldsettings.dpi); | |
0328b6de | 718 | |
637fa988 JD |
719 | } |
720 | else | |
721 | FcPatternDestroy (pat); | |
f904c0f9 | 722 | #endif /* HAVE_XFT */ |
637fa988 JD |
723 | } |
724 | ||
869795d6 JD |
725 | /* Read XSettings from the display for DPYINFO. |
726 | If SEND_EVENT_P is non-zero store a Lisp event settings that changed. */ | |
727 | ||
f904c0f9 | 728 | static void |
971de7fb | 729 | read_and_apply_settings (struct x_display_info *dpyinfo, int send_event_p) |
f904c0f9 JD |
730 | { |
731 | struct xsettings settings; | |
f904c0f9 JD |
732 | |
733 | if (!read_settings (dpyinfo, &settings)) | |
734 | return; | |
735 | ||
736 | apply_xft_settings (dpyinfo, True, &settings); | |
737 | if (settings.seen & SEEN_TB_STYLE) | |
738 | { | |
869795d6 JD |
739 | if (send_event_p) |
740 | store_tool_bar_style_changed (settings.tb_style, dpyinfo); | |
741 | else | |
742 | current_tool_bar_style = map_tool_bar_style (settings.tb_style); | |
baad03f0 | 743 | xfree (settings.tb_style); |
f904c0f9 | 744 | } |
869795d6 | 745 | #ifdef HAVE_XFT |
f904c0f9 JD |
746 | if (settings.seen & SEEN_FONT) |
747 | { | |
869795d6 JD |
748 | if (send_event_p) |
749 | store_font_name_changed (settings.font); | |
750 | else | |
f904c0f9 | 751 | { |
baad03f0 | 752 | xfree (current_font); |
869795d6 | 753 | current_font = xstrdup (settings.font); |
f904c0f9 | 754 | } |
869795d6 | 755 | xfree (settings.font); |
f904c0f9 | 756 | } |
869795d6 | 757 | #endif |
f904c0f9 | 758 | } |
637fa988 | 759 | |
869795d6 JD |
760 | /* Check if EVENT for the display in DPYINFO is XSettings related. */ |
761 | ||
637fa988 | 762 | void |
971de7fb | 763 | xft_settings_event (struct x_display_info *dpyinfo, XEvent *event) |
637fa988 | 764 | { |
637fa988 | 765 | int check_window_p = 0; |
f904c0f9 | 766 | int apply_settings = 0; |
637fa988 JD |
767 | |
768 | switch (event->type) | |
769 | { | |
770 | case DestroyNotify: | |
771 | if (dpyinfo->xsettings_window == event->xany.window) | |
772 | check_window_p = 1; | |
773 | break; | |
774 | ||
775 | case ClientMessage: | |
776 | if (event->xclient.message_type == dpyinfo->Xatom_xsettings_mgr | |
777 | && event->xclient.data.l[1] == dpyinfo->Xatom_xsettings_sel | |
778 | && event->xclient.window == dpyinfo->root_window) | |
779 | check_window_p = 1; | |
780 | break; | |
781 | ||
782 | case PropertyNotify: | |
783 | if (event->xproperty.window == dpyinfo->xsettings_window | |
784 | && event->xproperty.state == PropertyNewValue | |
785 | && event->xproperty.atom == dpyinfo->Xatom_xsettings_prop) | |
f904c0f9 | 786 | apply_settings = 1; |
637fa988 JD |
787 | break; |
788 | } | |
789 | ||
f904c0f9 | 790 | |
637fa988 JD |
791 | if (check_window_p) |
792 | { | |
793 | dpyinfo->xsettings_window = None; | |
794 | get_prop_window (dpyinfo); | |
795 | if (dpyinfo->xsettings_window != None) | |
f904c0f9 | 796 | apply_settings = 1; |
637fa988 | 797 | } |
f904c0f9 JD |
798 | |
799 | if (apply_settings) | |
800 | read_and_apply_settings (dpyinfo, True); | |
637fa988 JD |
801 | } |
802 | ||
869795d6 | 803 | /* Initialize GSettings and read startup values. */ |
637fa988 | 804 | |
9851bfc5 JD |
805 | static void |
806 | init_gsettings (void) | |
807 | { | |
808 | #ifdef HAVE_GSETTINGS | |
809 | GVariant *val; | |
0949d2b6 JD |
810 | const gchar *const *schemas; |
811 | int schema_found = 0; | |
812 | ||
9851bfc5 JD |
813 | #ifdef HAVE_G_TYPE_INIT |
814 | g_type_init (); | |
815 | #endif | |
816 | ||
5e617bc2 | 817 | schemas = g_settings_list_schemas (); |
0949d2b6 JD |
818 | if (schemas == NULL) return; |
819 | while (! schema_found && *schemas != NULL) | |
820 | schema_found = strcmp (*schemas++, GSETTINGS_SCHEMA) == 0; | |
821 | if (!schema_found) return; | |
822 | ||
9851bfc5 JD |
823 | gsettings_client = g_settings_new (GSETTINGS_SCHEMA); |
824 | if (!gsettings_client) return; | |
825 | g_object_ref_sink (G_OBJECT (gsettings_client)); | |
869795d6 JD |
826 | g_signal_connect (G_OBJECT (gsettings_client), "changed", |
827 | G_CALLBACK (something_changed_gsettingsCB), NULL); | |
828 | ||
829 | val = g_settings_get_value (gsettings_client, GSETTINGS_TOOL_BAR_STYLE); | |
830 | if (val) | |
831 | { | |
832 | g_variant_ref_sink (val); | |
833 | if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) | |
834 | current_tool_bar_style | |
835 | = map_tool_bar_style (g_variant_get_string (val, NULL)); | |
836 | g_variant_unref (val); | |
837 | } | |
9851bfc5 | 838 | |
869795d6 JD |
839 | #ifdef HAVE_XFT |
840 | val = g_settings_get_value (gsettings_client, GSETTINGS_MONO_FONT); | |
2e13213d | 841 | if (val) |
9851bfc5 JD |
842 | { |
843 | g_variant_ref_sink (val); | |
844 | if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) | |
845 | current_mono_font = xstrdup (g_variant_get_string (val, NULL)); | |
846 | g_variant_unref (val); | |
847 | } | |
848 | ||
869795d6 JD |
849 | val = g_settings_get_value (gsettings_client, GSETTINGS_FONT_NAME); |
850 | if (val) | |
851 | { | |
852 | g_variant_ref_sink (val); | |
853 | if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) | |
854 | current_font = xstrdup (g_variant_get_string (val, NULL)); | |
855 | g_variant_unref (val); | |
856 | } | |
857 | #endif /* HAVE_XFT */ | |
858 | ||
9851bfc5 JD |
859 | #endif /* HAVE_GSETTINGS */ |
860 | } | |
861 | ||
869795d6 | 862 | /* Init GConf and read startup values. */ |
9851bfc5 | 863 | |
637fa988 | 864 | static void |
971de7fb | 865 | init_gconf (void) |
637fa988 | 866 | { |
869795d6 | 867 | #if defined (HAVE_GCONF) |
637fa988 | 868 | char *s; |
637fa988 | 869 | |
1e600395 | 870 | #ifdef HAVE_G_TYPE_INIT |
637fa988 | 871 | g_type_init (); |
1e600395 | 872 | #endif |
869795d6 | 873 | |
637fa988 | 874 | gconf_client = gconf_client_get_default (); |
869795d6 JD |
875 | gconf_client_set_error_handling (gconf_client, GCONF_CLIENT_HANDLE_NONE); |
876 | gconf_client_add_dir (gconf_client, | |
877 | GCONF_TOOL_BAR_STYLE, | |
878 | GCONF_CLIENT_PRELOAD_ONELEVEL, | |
879 | NULL); | |
880 | gconf_client_notify_add (gconf_client, | |
881 | GCONF_TOOL_BAR_STYLE, | |
882 | something_changed_gconfCB, | |
883 | NULL, NULL, NULL); | |
884 | ||
885 | s = gconf_client_get_string (gconf_client, GCONF_TOOL_BAR_STYLE, NULL); | |
886 | if (s) | |
887 | { | |
888 | current_tool_bar_style = map_tool_bar_style (s); | |
889 | g_free (s); | |
890 | } | |
891 | ||
892 | #ifdef HAVE_XFT | |
893 | s = gconf_client_get_string (gconf_client, GCONF_MONO_FONT, NULL); | |
637fa988 JD |
894 | if (s) |
895 | { | |
896 | current_mono_font = xstrdup (s); | |
897 | g_free (s); | |
898 | } | |
869795d6 | 899 | s = gconf_client_get_string (gconf_client, GCONF_FONT_NAME, NULL); |
99852628 JD |
900 | if (s) |
901 | { | |
902 | current_font = xstrdup (s); | |
903 | g_free (s); | |
904 | } | |
637fa988 | 905 | gconf_client_add_dir (gconf_client, |
869795d6 | 906 | GCONF_MONO_FONT, |
637fa988 JD |
907 | GCONF_CLIENT_PRELOAD_ONELEVEL, |
908 | NULL); | |
909 | gconf_client_notify_add (gconf_client, | |
869795d6 JD |
910 | GCONF_MONO_FONT, |
911 | something_changed_gconfCB, | |
637fa988 | 912 | NULL, NULL, NULL); |
869795d6 JD |
913 | gconf_client_add_dir (gconf_client, |
914 | GCONF_FONT_NAME, | |
915 | GCONF_CLIENT_PRELOAD_ONELEVEL, | |
916 | NULL); | |
917 | gconf_client_notify_add (gconf_client, | |
918 | GCONF_FONT_NAME, | |
919 | something_changed_gconfCB, | |
920 | NULL, NULL, NULL); | |
921 | #endif /* HAVE_XFT */ | |
922 | #endif /* HAVE_GCONF */ | |
637fa988 JD |
923 | } |
924 | ||
869795d6 JD |
925 | /* Init Xsettings and read startup values. */ |
926 | ||
637fa988 | 927 | static void |
971de7fb | 928 | init_xsettings (struct x_display_info *dpyinfo) |
637fa988 | 929 | { |
637fa988 JD |
930 | Display *dpy = dpyinfo->display; |
931 | ||
4d7e6e51 | 932 | block_input (); |
637fa988 | 933 | |
637fa988 JD |
934 | /* Select events so we can detect client messages sent when selection |
935 | owner changes. */ | |
936 | XSelectInput (dpy, dpyinfo->root_window, StructureNotifyMask); | |
937 | ||
938 | get_prop_window (dpyinfo); | |
939 | if (dpyinfo->xsettings_window != None) | |
f904c0f9 | 940 | read_and_apply_settings (dpyinfo, False); |
637fa988 | 941 | |
4d7e6e51 | 942 | unblock_input (); |
637fa988 JD |
943 | } |
944 | ||
945 | void | |
971de7fb | 946 | xsettings_initialize (struct x_display_info *dpyinfo) |
637fa988 JD |
947 | { |
948 | if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo; | |
949 | init_gconf (); | |
f904c0f9 | 950 | init_xsettings (dpyinfo); |
869795d6 | 951 | init_gsettings (); |
637fa988 JD |
952 | } |
953 | ||
869795d6 JD |
954 | /* Return the system monospaced font. |
955 | May be NULL if not known. */ | |
956 | ||
0d1d0d26 | 957 | const char * |
971de7fb | 958 | xsettings_get_system_font (void) |
0d1d0d26 JD |
959 | { |
960 | return current_mono_font; | |
961 | } | |
637fa988 | 962 | |
e87b6180 | 963 | #ifdef USE_LUCID |
869795d6 JD |
964 | /* Return the system font. |
965 | May be NULL if not known. */ | |
966 | ||
99852628 | 967 | const char * |
971de7fb | 968 | xsettings_get_system_normal_font (void) |
99852628 JD |
969 | { |
970 | return current_font; | |
971 | } | |
e87b6180 | 972 | #endif |
99852628 JD |
973 | |
974 | DEFUN ("font-get-system-normal-font", Ffont_get_system_normal_font, | |
975 | Sfont_get_system_normal_font, | |
976 | 0, 0, 0, | |
bf935339 | 977 | doc: /* Get the system default application font. */) |
5842a27b | 978 | (void) |
99852628 | 979 | { |
2674ddc8 | 980 | return current_font ? build_string (current_font) : Qnil; |
99852628 JD |
981 | } |
982 | ||
637fa988 JD |
983 | DEFUN ("font-get-system-font", Ffont_get_system_font, Sfont_get_system_font, |
984 | 0, 0, 0, | |
bf935339 | 985 | doc: /* Get the system default fixed width font. */) |
5842a27b | 986 | (void) |
637fa988 | 987 | { |
2674ddc8 | 988 | return current_mono_font ? build_string (current_mono_font) : Qnil; |
637fa988 JD |
989 | } |
990 | ||
a7ca3326 | 991 | DEFUN ("tool-bar-get-system-style", Ftool_bar_get_system_style, |
16a97296 | 992 | Stool_bar_get_system_style, 0, 0, 0, |
f904c0f9 | 993 | doc: /* Get the system tool bar style. |
4721152c | 994 | If no system tool bar style is known, return `tool-bar-style' if set to a |
f904c0f9 | 995 | known style. Otherwise return image. */) |
5842a27b | 996 | (void) |
f904c0f9 JD |
997 | { |
998 | if (EQ (Vtool_bar_style, Qimage) | |
999 | || EQ (Vtool_bar_style, Qtext) | |
1000 | || EQ (Vtool_bar_style, Qboth) | |
8a52f00a JD |
1001 | || EQ (Vtool_bar_style, Qboth_horiz) |
1002 | || EQ (Vtool_bar_style, Qtext_image_horiz)) | |
f904c0f9 JD |
1003 | return Vtool_bar_style; |
1004 | if (!NILP (current_tool_bar_style)) | |
1005 | return current_tool_bar_style; | |
1006 | return Qimage; | |
1007 | } | |
1008 | ||
637fa988 | 1009 | void |
971de7fb | 1010 | syms_of_xsettings (void) |
637fa988 JD |
1011 | { |
1012 | current_mono_font = NULL; | |
99852628 | 1013 | current_font = NULL; |
637fa988 | 1014 | first_dpyinfo = NULL; |
9851bfc5 JD |
1015 | #ifdef HAVE_GSETTINGS |
1016 | gsettings_client = NULL; | |
869795d6 | 1017 | #endif |
637fa988 JD |
1018 | #ifdef HAVE_GCONF |
1019 | gconf_client = NULL; | |
1020 | #endif | |
1021 | ||
cd3520a4 JB |
1022 | DEFSYM (Qmonospace_font_name, "monospace-font-name"); |
1023 | DEFSYM (Qfont_name, "font-name"); | |
1024 | DEFSYM (Qfont_render, "font-render"); | |
637fa988 | 1025 | defsubr (&Sfont_get_system_font); |
99852628 | 1026 | defsubr (&Sfont_get_system_normal_font); |
637fa988 | 1027 | |
29208e82 | 1028 | DEFVAR_BOOL ("font-use-system-font", use_system_font, |
fb7ada5f | 1029 | doc: /* Non-nil means to apply the system defined font dynamically. |
bf935339 J |
1030 | When this is non-nil and the system defined fixed width font changes, we |
1031 | update frames dynamically. | |
1032 | If this variable is nil, Emacs ignores system font changes. */); | |
dfb3c4c6 JD |
1033 | use_system_font = 0; |
1034 | ||
29208e82 | 1035 | DEFVAR_LISP ("xft-settings", Vxft_settings, |
67477f30 | 1036 | doc: /* Font settings applied to Xft. */); |
4a7edc24 | 1037 | Vxft_settings = empty_unibyte_string; |
67477f30 | 1038 | |
0d1d0d26 JD |
1039 | #ifdef HAVE_XFT |
1040 | Fprovide (intern_c_string ("font-render-setting"), Qnil); | |
9851bfc5 | 1041 | #if defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) |
637fa988 JD |
1042 | Fprovide (intern_c_string ("system-font-setting"), Qnil); |
1043 | #endif | |
637fa988 | 1044 | #endif |
f904c0f9 JD |
1045 | |
1046 | current_tool_bar_style = Qnil; | |
cd3520a4 | 1047 | DEFSYM (Qtool_bar_style, "tool-bar-style"); |
f904c0f9 JD |
1048 | defsubr (&Stool_bar_get_system_style); |
1049 | ||
1050 | Fprovide (intern_c_string ("dynamic-setting"), Qnil); | |
637fa988 | 1051 | } |