aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Djärv2009-11-17 08:21:23 +0000
committerJan Djärv2009-11-17 08:21:23 +0000
commit637fa9880877f485842b7aca18146a1f12c05b96 (patch)
treef4994cdadaad980b7b28827eba6cd50421a7f892 /src
parent77fd3e0c13b345cd4ff5c9ef5c89bd6b29054bc3 (diff)
downloademacs-637fa9880877f485842b7aca18146a1f12c05b96.tar.gz
emacs-637fa9880877f485842b7aca18146a1f12c05b96.zip
Handle system default font and changing font parameters.
* xterm.h (struct x_display_info): Add atoms and Window for xsettings. * xterm.c (handle_one_xevent): Call xft_settings_event for ClientMessage, PropertyNotify and DestroyNotify. (x_term_init): If we have XFT, get DPI from Xft.dpi. Call xsettings_initialize. * xftfont.c (xftfont_fix_match): New function. (xftfont_open): Call XftDefaultSubstitute before XftFontMatch. Call xftfont_fix_match after XftFontMatch. * xfont.c (xfont_driver): Initialize all members. * xfns.c (x_default_font_parameter): Try font from Ffont_get_system_font. Do not get font from x_default_parameter if we got one from Ffont_get_system_font. (Fx_select_font): Get the defaut font name from :name of FRAME_FONT (f). * w32font.c (w32font_driver): Initialize all members. * termhooks.h (enum event_kind): CONFIG_CHANGED_EVENT is new. * lisp.h: Declare syms_of_xsettings. * keyboard.c (kbd_buffer_get_event, make_lispy_event): Handle CONFIG_CHANGED_EVENT. * ftfont.c (ftfont_filter_properties): New function. * frame.c (x_set_font): Remove unused variable lval. * font.h (struct font_driver): filter_properties is new. * font.c (font_put_extra): Don't return if val is nil, it means boolean option is off. (font_parse_fcname): Collect all extra properties in extra_props and call filter_properties for all drivers with extra_props and font as parameter. (font_open_entity): Do not use cache, it does not pick up new fontconfig settings like hinting. (font_load_for_lface): If spec had a name in it, store it in entity. * emacs.c (main): Call syms_of_xsettings * config.in: HAVE_GCONF is new. * Makefile.in (GCONF_CFLAGS, GCONF_LIBS): New variables for HAVE_GCONF. xsettings.o is new. * menu-bar.el: Put "Use system font" in Option-menu. * loadup.el: If feature system-font-setting or font-render-setting is there, load font-setting. * Makefile.in (ELCFILES): font-settings.el is new. * font-setting.el: New file. * NEWS: Mention dynamic font changes (font-use-system-font). * configure.in: New option: --with(out)-gconf. Set HAVE_GCONF if we find gconf.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog51
-rw-r--r--src/Makefile.in18
-rw-r--r--src/config.in3
-rw-r--r--src/emacs.c3
-rw-r--r--src/font.c40
-rw-r--r--src/font.h2
-rw-r--r--src/frame.c3
-rw-r--r--src/ftfont.c97
-rw-r--r--src/keyboard.c17
-rw-r--r--src/lisp.h3
-rw-r--r--src/termhooks.h2
-rw-r--r--src/w32font.c5
-rw-r--r--src/xfns.c45
-rw-r--r--src/xfont.c4
-rw-r--r--src/xftfont.c54
-rw-r--r--src/xsettings.c627
-rw-r--r--src/xsettings.h29
-rw-r--r--src/xterm.c44
-rw-r--r--src/xterm.h4
19 files changed, 1003 insertions, 48 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 0bc2ad403e7..c09d11d5ecf 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,54 @@
12009-11-17 Jan Djärv <jan.h.d@swipnet.se>
2
3 * xterm.h (struct x_display_info): Add atoms and Window for xsettings.
4
5 * xterm.c (handle_one_xevent): Call xft_settings_event for
6 ClientMessage, PropertyNotify and DestroyNotify.
7 (x_term_init): If we have XFT, get DPI from Xft.dpi.
8 Call xsettings_initialize.
9
10 * xftfont.c (xftfont_fix_match): New function.
11 (xftfont_open): Call XftDefaultSubstitute before XftFontMatch.
12 Call xftfont_fix_match after XftFontMatch.
13
14 * xfont.c (xfont_driver): Initialize all members.
15
16 * xfns.c (x_default_font_parameter): Try font from Ffont_get_system_font.
17 Do not get font from x_default_parameter if we got one from
18 Ffont_get_system_font.
19 (Fx_select_font): Get the defaut font name from :name of FRAME_FONT (f).
20
21 * w32font.c (w32font_driver): Initialize all members.
22
23 * termhooks.h (enum event_kind): CONFIG_CHANGED_EVENT is new.
24
25 * lisp.h: Declare syms_of_xsettings.
26
27 * keyboard.c (kbd_buffer_get_event, make_lispy_event): Handle
28 CONFIG_CHANGED_EVENT.
29
30 * ftfont.c (ftfont_filter_properties): New function.
31
32 * frame.c (x_set_font): Remove unused variable lval.
33
34 * font.h (struct font_driver): filter_properties is new.
35
36 * font.c (font_put_extra): Don't return if val is nil, it means
37 boolean option is off.
38 (font_parse_fcname): Collect all extra properties in extra_props
39 and call filter_properties for all drivers with extra_props and
40 font as parameter.
41 (font_open_entity): Do not use cache, it does not pick up new fontconfig
42 settings like hinting.
43 (font_load_for_lface): If spec had a name in it, store it in entity.
44
45 * emacs.c (main): Call syms_of_xsettings
46
47 * config.in: HAVE_GCONF is new.
48
49 * Makefile.in (GCONF_CFLAGS, GCONF_LIBS): New variables for HAVE_GCONF.
50 xsettings.o is new.
51
12009-11-17 Kenichi Handa <handa@m17n.org> 522009-11-17 Kenichi Handa <handa@m17n.org>
2 53
3 * xdisp.c (x_produce_glyphs): Consider face-remapping when falling 54 * xdisp.c (x_produce_glyphs): Consider face-remapping when falling
diff --git a/src/Makefile.in b/src/Makefile.in
index 038689c6359..824381c812f 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -248,6 +248,11 @@ DBUS_LIBS = @DBUS_LIBS@
248DBUS_OBJ = dbusbind.o 248DBUS_OBJ = dbusbind.o
249#endif 249#endif
250 250
251#ifdef HAVE_GCONF
252GCONF_CFLAGS = @GCONF_CFLAGS@
253GCONF_LIBS = @GCONF_LIBS@
254#endif
255
251/* DO NOT use -R. There is a special hack described in lastfile.c 256/* DO NOT use -R. There is a special hack described in lastfile.c
252 which is used instead. Some initialized data areas are modified 257 which is used instead. Some initialized data areas are modified
253 at initial startup, then labeled as part of the text area when 258 at initial startup, then labeled as part of the text area when
@@ -261,7 +266,7 @@ DBUS_OBJ = dbusbind.o
261 266
262/* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM 267/* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM
263 since it may have -I options that should override those two. */ 268 since it may have -I options that should override those two. */
264ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ ${DEPFLAGS} 269ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${GCONF_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ ${DEPFLAGS}
265ALL_OBJC_CFLAGS=$(ALL_CFLAGS) @GNU_OBJC_CFLAGS@ 270ALL_OBJC_CFLAGS=$(ALL_CFLAGS) @GNU_OBJC_CFLAGS@
266 271
267.SUFFIXES: .m 272.SUFFIXES: .m
@@ -286,7 +291,8 @@ ALL_OBJC_CFLAGS=$(ALL_CFLAGS) @GNU_OBJC_CFLAGS@
286 291
287#ifdef HAVE_X_WINDOWS 292#ifdef HAVE_X_WINDOWS
288XMENU_OBJ = xmenu.o 293XMENU_OBJ = xmenu.o
289XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o fringe.o image.o 294XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o fringe.o image.o \
295 xsettings.o
290 296
291#ifdef HAVE_MENUS 297#ifdef HAVE_MENUS
292 298
@@ -904,7 +910,7 @@ SOME_MACHINE_LISP = ../lisp/mouse.elc \
904 910
905LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) $(DBUS_LIBS) \ 911LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) $(DBUS_LIBS) \
906 LIBGPM LIBRESOLV LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \ 912 LIBGPM LIBRESOLV LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \
907 LIBS_DEBUG $(GETLOADAVG_LIBS) \ 913 LIBS_DEBUG $(GETLOADAVG_LIBS) ${GCONF_LIBS} \
908 @FREETYPE_LIBS@ @FONTCONFIG_LIBS@ @LIBOTF_LIBS@ @M17N_FLT_LIBS@ \ 914 @FREETYPE_LIBS@ @FONTCONFIG_LIBS@ @LIBOTF_LIBS@ @M17N_FLT_LIBS@ \
909 $(GNULIB_VAR) LIB_MATH LIB_STANDARD $(GNULIB_VAR) 915 $(GNULIB_VAR) LIB_MATH LIB_STANDARD $(GNULIB_VAR)
910 916
@@ -1212,7 +1218,7 @@ xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
1212xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \ 1218xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
1213 $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \ 1219 $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
1214 character.h charset.h coding.h gtkutil.h lisp.h $(config_h) termhooks.h \ 1220 character.h charset.h coding.h gtkutil.h lisp.h $(config_h) termhooks.h \
1215 fontset.h termchar.h font.h 1221 fontset.h termchar.h font.h xsettings.h
1216xfont.o: dispextern.h xterm.h frame.h blockinput.h character.h charset.h \ 1222xfont.o: dispextern.h xterm.h frame.h blockinput.h character.h charset.h \
1217 font.h lisp.h $(config_h) 1223 font.h lisp.h $(config_h)
1218xftfont.o: dispextern.h xterm.h frame.h blockinput.h character.h charset.h \ 1224xftfont.o: dispextern.h xterm.h frame.h blockinput.h character.h charset.h \
@@ -1228,13 +1234,13 @@ xmenu.o: xmenu.c xterm.h termhooks.h window.h dispextern.h frame.h buffer.h \
1228xterm.o: xterm.c xterm.h termhooks.h termopts.h termchar.h window.h buffer.h \ 1234xterm.o: xterm.c xterm.h termhooks.h termopts.h termchar.h window.h buffer.h \
1229 dispextern.h frame.h disptab.h blockinput.h atimer.h systime.h syssignal.h \ 1235 dispextern.h frame.h disptab.h blockinput.h atimer.h systime.h syssignal.h \
1230 keyboard.h emacs-icon.h character.h charset.h ccl.h fontset.h composite.h \ 1236 keyboard.h emacs-icon.h character.h charset.h ccl.h fontset.h composite.h \
1231 coding.h process.h gtkutil.h font.h fontset.h lisp.h $(config_h) 1237 coding.h process.h gtkutil.h font.h fontset.h lisp.h $(config_h) xsettings.h
1232xselect.o: xselect.c process.h dispextern.h frame.h xterm.h blockinput.h \ 1238xselect.o: xselect.c process.h dispextern.h frame.h xterm.h blockinput.h \
1233 buffer.h atimer.h systime.h termhooks.h lisp.h $(config_h) 1239 buffer.h atimer.h systime.h termhooks.h lisp.h $(config_h)
1234xrdb.o: xrdb.c lisp.h $(config_h) epaths.h 1240xrdb.o: xrdb.c lisp.h $(config_h) epaths.h
1235xsmfns.o: xsmfns.c lisp.h $(config_h) systime.h sysselect.h termhooks.h xterm.h \ 1241xsmfns.o: xsmfns.c lisp.h $(config_h) systime.h sysselect.h termhooks.h xterm.h \
1236 lisp.h termopts.h 1242 lisp.h termopts.h
1237 1243xsettings.o: xterm.h xsettings.h lisp.h frame.h termhooks.h $(config_h)
1238/* The files of Lisp proper */ 1244/* The files of Lisp proper */
1239 1245
1240alloc.o: alloc.c process.h frame.h window.h buffer.h puresize.h syssignal.h keyboard.h \ 1246alloc.o: alloc.c process.h frame.h window.h buffer.h puresize.h syssignal.h keyboard.h \
diff --git a/src/config.in b/src/config.in
index 04b6de5714d..e7e1c9d0868 100644
--- a/src/config.in
+++ b/src/config.in
@@ -201,6 +201,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
201/* Define to 1 if you have the `gai_strerror' function. */ 201/* Define to 1 if you have the `gai_strerror' function. */
202#undef HAVE_GAI_STRERROR 202#undef HAVE_GAI_STRERROR
203 203
204/* Define to 1 if using GConf. */
205#undef HAVE_GCONF
206
204/* Define to 1 if you have the `gdk_display_open' function. */ 207/* Define to 1 if you have the `gdk_display_open' function. */
205#undef HAVE_GDK_DISPLAY_OPEN 208#undef HAVE_GDK_DISPLAY_OPEN
206 209
diff --git a/src/emacs.c b/src/emacs.c
index 4099a4f4795..d96b3a1daf1 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1669,6 +1669,7 @@ main (int argc, char **argv)
1669 syms_of_xfns (); 1669 syms_of_xfns ();
1670 syms_of_xmenu (); 1670 syms_of_xmenu ();
1671 syms_of_fontset (); 1671 syms_of_fontset ();
1672 syms_of_xsettings ();
1672#ifdef HAVE_X_SM 1673#ifdef HAVE_X_SM
1673 syms_of_xsmfns (); 1674 syms_of_xsmfns ();
1674#endif 1675#endif
@@ -1749,7 +1750,7 @@ main (int argc, char **argv)
1749#endif 1750#endif
1750 init_window (); 1751 init_window ();
1751 init_font (); 1752 init_font ();
1752 1753
1753 if (!initialized) 1754 if (!initialized)
1754 { 1755 {
1755 char *file; 1756 char *file;
diff --git a/src/font.c b/src/font.c
index bab3d9f821c..1c0a9dfb236 100644
--- a/src/font.c
+++ b/src/font.c
@@ -718,8 +718,6 @@ font_put_extra (font, prop, val)
718 { 718 {
719 Lisp_Object prev = Qnil; 719 Lisp_Object prev = Qnil;
720 720
721 if (NILP (val))
722 return val;
723 while (CONSP (extra) 721 while (CONSP (extra)
724 && NILP (Fstring_lessp (prop, XCAR (XCAR (extra))))) 722 && NILP (Fstring_lessp (prop, XCAR (XCAR (extra)))))
725 prev = extra, extra = XCDR (extra); 723 prev = extra, extra = XCDR (extra);
@@ -1431,6 +1429,8 @@ font_parse_fcname (name, font)
1431 1429
1432 if (family_end) 1430 if (family_end)
1433 { 1431 {
1432 Lisp_Object extra_props = Qnil;
1433
1434 /* A fontconfig name with size and/or property data. */ 1434 /* A fontconfig name with size and/or property data. */
1435 if (family_end > name) 1435 if (family_end > name)
1436 { 1436 {
@@ -1504,13 +1504,25 @@ font_parse_fcname (name, font)
1504 1504
1505 if (prop >= FONT_FOUNDRY_INDEX 1505 if (prop >= FONT_FOUNDRY_INDEX
1506 && prop < FONT_EXTRA_INDEX) 1506 && prop < FONT_EXTRA_INDEX)
1507 ASET (font, prop, font_prop_validate (prop, Qnil, val)); 1507 ASET (font, prop, font_prop_validate (prop, Qnil, val));
1508 else 1508 else
1509 Ffont_put (font, key, val); 1509 {
1510 extra_props = nconc2 (extra_props,
1511 Fcons (Fcons (key, val), Qnil));
1512 }
1510 } 1513 }
1511 p = q; 1514 p = q;
1512 } 1515 }
1513 } 1516 }
1517
1518 if (! NILP (extra_props))
1519 {
1520 struct font_driver_list *driver_list = font_driver_list;
1521 for ( ; driver_list; driver_list = driver_list->next)
1522 if (driver_list->driver->filter_properties)
1523 (*driver_list->driver->filter_properties) (font, extra_props);
1524 }
1525
1514 } 1526 }
1515 else 1527 else
1516 { 1528 {
@@ -2975,11 +2987,15 @@ font_open_entity (f, entity, pixel_size)
2975 else if (CONSP (Vface_font_rescale_alist)) 2987 else if (CONSP (Vface_font_rescale_alist))
2976 scaled_pixel_size = pixel_size * font_rescale_ratio (entity); 2988 scaled_pixel_size = pixel_size * font_rescale_ratio (entity);
2977 2989
2990#if 0
2991 /* This doesn't work if you have changed hinting or any other parameter.
2992 We need to make a new object in every case to be sure. */
2978 for (objlist = AREF (entity, FONT_OBJLIST_INDEX); CONSP (objlist); 2993 for (objlist = AREF (entity, FONT_OBJLIST_INDEX); CONSP (objlist);
2979 objlist = XCDR (objlist)) 2994 objlist = XCDR (objlist))
2980 if (! NILP (AREF (XCAR (objlist), FONT_TYPE_INDEX)) 2995 if (! NILP (AREF (XCAR (objlist), FONT_TYPE_INDEX))
2981 && XFONT_OBJECT (XCAR (objlist))->pixel_size == pixel_size) 2996 && XFONT_OBJECT (XCAR (objlist))->pixel_size == pixel_size)
2982 return XCAR (objlist); 2997 return XCAR (objlist);
2998#endif
2983 2999
2984 val = AREF (entity, FONT_TYPE_INDEX); 3000 val = AREF (entity, FONT_TYPE_INDEX);
2985 for (driver_list = f->font_driver_list; 3001 for (driver_list = f->font_driver_list;
@@ -3155,12 +3171,14 @@ font_clear_prop (attrs, prop)
3155 3171
3156 if (! FONTP (font)) 3172 if (! FONTP (font))
3157 return; 3173 return;
3174#if 0
3158 if (! NILP (Ffont_get (font, QCname))) 3175 if (! NILP (Ffont_get (font, QCname)))
3159 { 3176 {
3160 font = Fcopy_font_spec (font); 3177 font = Fcopy_font_spec (font);
3161 font_put_extra (font, QCname, Qnil); 3178 font_put_extra (font, QCname, Qnil);
3162 } 3179 }
3163 3180
3181#endif
3164 if (NILP (AREF (font, prop)) 3182 if (NILP (AREF (font, prop))
3165 && prop != FONT_FAMILY_INDEX 3183 && prop != FONT_FAMILY_INDEX
3166 && prop != FONT_FOUNDRY_INDEX 3184 && prop != FONT_FOUNDRY_INDEX
@@ -3438,7 +3456,7 @@ font_find_for_lface (f, attrs, spec, c)
3438 val = font_select_entity (frame, entities, 3456 val = font_select_entity (frame, entities,
3439 attrs, pixel_size, c); 3457 attrs, pixel_size, c);
3440 if (! NILP (val)) 3458 if (! NILP (val))
3441 return val; 3459 return val;
3442 } 3460 }
3443 } 3461 }
3444 } 3462 }
@@ -3500,7 +3518,7 @@ font_load_for_lface (f, attrs, spec)
3500 FRAME_PTR f; 3518 FRAME_PTR f;
3501 Lisp_Object *attrs, spec; 3519 Lisp_Object *attrs, spec;
3502{ 3520{
3503 Lisp_Object entity; 3521 Lisp_Object entity, name;
3504 3522
3505 entity = font_find_for_lface (f, attrs, spec, -1); 3523 entity = font_find_for_lface (f, attrs, spec, -1);
3506 if (NILP (entity)) 3524 if (NILP (entity))
@@ -3512,7 +3530,13 @@ font_load_for_lface (f, attrs, spec)
3512 if (NILP (entity)) 3530 if (NILP (entity))
3513 return Qnil; 3531 return Qnil;
3514 } 3532 }
3515 return font_open_for_lface (f, entity, attrs, spec); 3533 /* Don't loose the original name that was put in initially. We need
3534 it to re-apply the font when font parameters (like hinting or dpi) have
3535 changed. */
3536 entity = font_open_for_lface (f, entity, attrs, spec);
3537 name = Ffont_get (spec, QCname);
3538 if (STRINGP (name)) font_put_extra (entity, QCname, name);
3539 return entity;
3516} 3540}
3517 3541
3518 3542
diff --git a/src/font.h b/src/font.h
index 5726ffd319c..1a09df2558c 100644
--- a/src/font.h
+++ b/src/font.h
@@ -687,6 +687,8 @@ struct font_driver
687 the (N-1)th element of VARIATIONS. */ 687 the (N-1)th element of VARIATIONS. */
688 int (*get_variation_glyphs) P_ ((struct font *font, 688 int (*get_variation_glyphs) P_ ((struct font *font,
689 int c, unsigned variations[256])); 689 int c, unsigned variations[256]));
690
691 void (*filter_properties) P_ ((Lisp_Object font, Lisp_Object properties));
690}; 692};
691 693
692 694
diff --git a/src/frame.c b/src/frame.c
index 467f6bd1482..323bfc1c37d 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -3359,7 +3359,7 @@ x_set_font (f, arg, oldval)
3359 struct frame *f; 3359 struct frame *f;
3360 Lisp_Object arg, oldval; 3360 Lisp_Object arg, oldval;
3361{ 3361{
3362 Lisp_Object frame, font_object, lval; 3362 Lisp_Object frame, font_object;
3363 int fontset = -1; 3363 int fontset = -1;
3364 3364
3365 /* Set the frame parameter back to the old value because we may 3365 /* Set the frame parameter back to the old value because we may
@@ -3427,7 +3427,6 @@ x_set_font (f, arg, oldval)
3427 if (! NILP (Fequal (font_object, oldval))) 3427 if (! NILP (Fequal (font_object, oldval)))
3428 return; 3428 return;
3429 3429
3430
3431 x_new_font (f, font_object, fontset); 3430 x_new_font (f, font_object, fontset);
3432 store_frame_param (f, Qfont, arg); 3431 store_frame_param (f, Qfont, arg);
3433 /* Recalculate toolbar height. */ 3432 /* Recalculate toolbar height. */
diff --git a/src/ftfont.c b/src/ftfont.c
index ed9cb6f19d2..4ba4712965f 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -86,6 +86,8 @@ static Lisp_Object ftfont_resolve_generic_family P_ ((Lisp_Object,
86static Lisp_Object ftfont_lookup_cache P_ ((Lisp_Object, 86static Lisp_Object ftfont_lookup_cache P_ ((Lisp_Object,
87 enum ftfont_cache_for)); 87 enum ftfont_cache_for));
88 88
89static void ftfont_filter_properties P_ ((Lisp_Object font, Lisp_Object alist));
90
89Lisp_Object ftfont_font_format P_ ((FcPattern *, Lisp_Object)); 91Lisp_Object ftfont_font_format P_ ((FcPattern *, Lisp_Object));
90 92
91#define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM)) 93#define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM))
@@ -545,10 +547,12 @@ struct font_driver ftfont_driver =
545 NULL, /* check */ 547 NULL, /* check */
546 548
547#ifdef HAVE_OTF_GET_VARIATION_GLYPHS 549#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
548 ftfont_variation_glyphs 550 ftfont_variation_glyphs,
549#else 551#else
550 NULL 552 NULL,
551#endif 553#endif
554
555 ftfont_filter_properties, /* filter_properties */
552 }; 556 };
553 557
554extern Lisp_Object QCname; 558extern Lisp_Object QCname;
@@ -2226,7 +2230,94 @@ ftfont_font_format (FcPattern *pattern, Lisp_Object filename)
2226 return intern ("unknown"); 2230 return intern ("unknown");
2227} 2231}
2228 2232
2229 2233static const char *ftfont_booleans [] = {
2234 ":antialias",
2235 ":hinting",
2236 ":verticallayout",
2237 ":autohint",
2238 ":globaladvance",
2239 ":outline",
2240 ":scalable",
2241 ":minspace",
2242 ":embolden",
2243 NULL,
2244};
2245
2246static const char *ftfont_non_booleans [] = {
2247 ":family",
2248 ":familylang",
2249 ":style",
2250 ":stylelang",
2251 ":fullname",
2252 ":fullnamelang",
2253 ":slant",
2254 ":weight",
2255 ":size",
2256 ":width",
2257 ":aspect",
2258 ":pixelsize",
2259 ":spacing",
2260 ":foundry",
2261 ":hintstyle",
2262 ":file",
2263 ":index",
2264 ":ftface",
2265 ":rasterizer",
2266 ":scale",
2267 ":dpi",
2268 ":rgba",
2269 ":lcdfilter",
2270 ":charset",
2271 ":lang",
2272 ":fontversion",
2273 ":capability",
2274 NULL,
2275};
2276
2277static void
2278ftfont_filter_properties (font, alist)
2279 Lisp_Object font;
2280 Lisp_Object alist;
2281{
2282 Lisp_Object it;
2283 int i;
2284
2285 /* Set boolean values to Qt or Qnil */
2286 for (i = 0; ftfont_booleans[i] != NULL; ++i)
2287 for (it = alist; ! NILP (it); it = XCDR (it))
2288 {
2289 Lisp_Object key = XCAR (XCAR (it));
2290 Lisp_Object val = XCDR (XCAR (it));
2291 char *keystr = SDATA (SYMBOL_NAME (key));
2292
2293 if (strcmp (ftfont_booleans[i], keystr) == 0)
2294 {
2295 char *str = SYMBOLP (val) ? SDATA (SYMBOL_NAME (val)) : NULL;
2296 if (INTEGERP (val)) str = XINT (val) != 0 ? "true" : "false";
2297 if (str == NULL) str = "true";
2298
2299 val = Qt;
2300 if (strcmp ("false", str) == 0 || strcmp ("False", str) == 0
2301 || strcmp ("FALSE", str) == 0 || strcmp ("FcFalse", str) == 0
2302 || strcmp ("off", str) == 0 || strcmp ("OFF", str) == 0
2303 || strcmp ("Off", str) == 0)
2304 val = Qnil;
2305 Ffont_put (font, key, val);
2306 }
2307 }
2308
2309 for (i = 0; ftfont_non_booleans[i] != NULL; ++i)
2310 for (it = alist; ! NILP (it); it = XCDR (it))
2311 {
2312 Lisp_Object key = XCAR (XCAR (it));
2313 Lisp_Object val = XCDR (XCAR (it));
2314 char *keystr = SDATA (SYMBOL_NAME (key));
2315 if (strcmp (ftfont_non_booleans[i], keystr) == 0)
2316 Ffont_put (font, key, val);
2317 }
2318}
2319
2320
2230void 2321void
2231syms_of_ftfont () 2322syms_of_ftfont ()
2232{ 2323{
diff --git a/src/keyboard.c b/src/keyboard.c
index 5ea4f350809..f15b7971c45 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -489,6 +489,8 @@ Lisp_Object Qsave_session;
489#ifdef HAVE_DBUS 489#ifdef HAVE_DBUS
490Lisp_Object Qdbus_event; 490Lisp_Object Qdbus_event;
491#endif 491#endif
492Lisp_Object Qconfig_changed_event;
493
492/* Lisp_Object Qmouse_movement; - also an event header */ 494/* Lisp_Object Qmouse_movement; - also an event header */
493 495
494/* Properties of event headers. */ 496/* Properties of event headers. */
@@ -4283,6 +4285,11 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
4283 kbd_fetch_ptr = event + 1; 4285 kbd_fetch_ptr = event + 1;
4284 } 4286 }
4285#endif 4287#endif
4288 else if (event->kind == CONFIG_CHANGED_EVENT)
4289 {
4290 obj = make_lispy_event (event);
4291 kbd_fetch_ptr = event + 1;
4292 }
4286 else 4293 else
4287 { 4294 {
4288 /* If this event is on a different frame, return a switch-frame this 4295 /* If this event is on a different frame, return a switch-frame this
@@ -6196,6 +6203,10 @@ make_lispy_event (event)
6196 } 6203 }
6197#endif /* HAVE_DBUS */ 6204#endif /* HAVE_DBUS */
6198 6205
6206 case CONFIG_CHANGED_EVENT:
6207 return Fcons (Qconfig_changed_event,
6208 Fcons (event->arg,
6209 Fcons (event->frame_or_window, Qnil)));
6199#ifdef HAVE_GPM 6210#ifdef HAVE_GPM
6200 case GPM_CLICK_EVENT: 6211 case GPM_CLICK_EVENT:
6201 { 6212 {
@@ -11805,6 +11816,9 @@ syms_of_keyboard ()
11805 staticpro (&Qdbus_event); 11816 staticpro (&Qdbus_event);
11806#endif 11817#endif
11807 11818
11819 Qconfig_changed_event = intern_c_string ("config-changed-event");
11820 staticpro (&Qconfig_changed_event);
11821
11808 Qmenu_enable = intern_c_string ("menu-enable"); 11822 Qmenu_enable = intern_c_string ("menu-enable");
11809 staticpro (&Qmenu_enable); 11823 staticpro (&Qmenu_enable);
11810 QCenable = intern_c_string (":enable"); 11824 QCenable = intern_c_string (":enable");
@@ -12547,6 +12561,9 @@ keys_of_keyboard ()
12547 initial_define_lispy_key (Vspecial_event_map, "dbus-event", 12561 initial_define_lispy_key (Vspecial_event_map, "dbus-event",
12548 "dbus-handle-event"); 12562 "dbus-handle-event");
12549#endif 12563#endif
12564
12565 initial_define_lispy_key (Vspecial_event_map, "config-changed-event",
12566 "ignore");
12550} 12567}
12551 12568
12552/* Mark the pointers in the kboard objects. 12569/* Mark the pointers in the kboard objects.
diff --git a/src/lisp.h b/src/lisp.h
index 65c88dcfab7..01b2d61247e 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2643,6 +2643,9 @@ extern Lisp_Object safe_eval P_ ((Lisp_Object));
2643extern int pos_visible_p P_ ((struct window *, int, int *, 2643extern int pos_visible_p P_ ((struct window *, int, int *,
2644 int *, int *, int *, int *, int *)); 2644 int *, int *, int *, int *, int *));
2645 2645
2646/* Defined in xsettings.c */
2647extern void syms_of_xsettings P_ ((void));
2648
2646/* Defined in vm-limit.c. */ 2649/* Defined in vm-limit.c. */
2647extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ())); 2650extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ()));
2648 2651
diff --git a/src/termhooks.h b/src/termhooks.h
index bd9b4ec4575..33585e832a6 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -184,6 +184,8 @@ enum event_kind
184 , DBUS_EVENT 184 , DBUS_EVENT
185#endif 185#endif
186 186
187 , CONFIG_CHANGED_EVENT
188
187#ifdef WINDOWSNT 189#ifdef WINDOWSNT
188 /* Generated when an APPCOMMAND event is received, in response to 190 /* Generated when an APPCOMMAND event is received, in response to
189 Multimedia or Internet buttons on some keyboards. 191 Multimedia or Internet buttons on some keyboards.
diff --git a/src/w32font.c b/src/w32font.c
index 69462512ca3..b9ffea7cd30 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -2472,7 +2472,10 @@ struct font_driver w32font_driver =
2472 NULL, /* otf_drive */ 2472 NULL, /* otf_drive */
2473 NULL, /* start_for_frame */ 2473 NULL, /* start_for_frame */
2474 NULL, /* end_for_frame */ 2474 NULL, /* end_for_frame */
2475 NULL /* shape */ 2475 NULL, /* shape */
2476 NULL, /* check */
2477 NULL, /* get_variation_glyphs */
2478 NULL, /* filter_properties */
2476 }; 2479 };
2477 2480
2478 2481
diff --git a/src/xfns.c b/src/xfns.c
index 0a041a7dc9d..3d5a2a127d6 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -98,6 +98,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
98#include <Xm/FileSB.h> 98#include <Xm/FileSB.h>
99#endif 99#endif
100 100
101#include "xsettings.h"
102
101#if !defined(NO_EDITRES) 103#if !defined(NO_EDITRES)
102#define HACK_EDITRES 104#define HACK_EDITRES
103extern void _XEditResCheckMessages (); 105extern void _XEditResCheckMessages ();
@@ -3025,13 +3027,19 @@ x_default_font_parameter (f, parms)
3025{ 3027{
3026 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 3028 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3027 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL, 3029 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
3028 RES_TYPE_STRING); 3030 RES_TYPE_STRING);
3029 Lisp_Object font; 3031 Lisp_Object font;
3032 int got_from_gconf = 0;
3030 if (EQ (font_param, Qunbound)) 3033 if (EQ (font_param, Qunbound))
3031 font_param = Qnil; 3034 {
3035 font_param = Qnil;
3036 font_param = Ffont_get_system_font();
3037 got_from_gconf = !NILP (font_param);
3038 }
3039
3032 font = !NILP (font_param) ? font_param 3040 font = !NILP (font_param) ? font_param
3033 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING); 3041 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
3034 3042
3035 if (! STRINGP (font)) 3043 if (! STRINGP (font))
3036 { 3044 {
3037 char *names[] 3045 char *names[]
@@ -3068,7 +3076,11 @@ x_default_font_parameter (f, parms)
3068 we've applied the `default' face settings. */ 3076 we've applied the `default' face settings. */
3069 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil)); 3077 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
3070 } 3078 }
3071 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING); 3079
3080 x_default_parameter (f, parms, Qfont, font,
3081 got_from_gconf ? NULL : "font",
3082 got_from_gconf ? NULL : "Font",
3083 RES_TYPE_STRING);
3072} 3084}
3073 3085
3074 3086
@@ -5569,10 +5581,10 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
5569{ 5581{
5570 FRAME_PTR f = check_x_frame (frame); 5582 FRAME_PTR f = check_x_frame (frame);
5571 char *name; 5583 char *name;
5572 Lisp_Object default_font, font = Qnil; 5584 Lisp_Object font;
5573 Lisp_Object font_param; 5585 Lisp_Object font_param;
5574 char *default_name = NULL; 5586 char *default_name = NULL;
5575 struct gcpro gcpro1; 5587 struct gcpro gcpro1, gcpro2;
5576 int count = SPECPDL_INDEX (); 5588 int count = SPECPDL_INDEX ();
5577 5589
5578 check_x (); 5590 check_x ();
@@ -5586,21 +5598,22 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
5586 5598
5587 BLOCK_INPUT; 5599 BLOCK_INPUT;
5588 5600
5589 GCPRO1(font_param); 5601 GCPRO2(font_param, font);
5590 font_param = Fframe_parameter (frame, Qfont_param);
5591 5602
5592 if (x_last_font_name != NULL) 5603 XSETFONT (font, FRAME_FONT (f));
5593 default_name = x_last_font_name; 5604 font_param = Ffont_get (font, intern_c_string (":name"));
5594 else if (STRINGP (font_param)) 5605 if (STRINGP (font_param))
5595 default_name = SDATA (font_param); 5606 default_name = SDATA (font_param);
5596 else if (FONTP (default_font)) 5607 else
5597 { 5608 {
5598 XSETFONT (default_font, FRAME_FONT (f)); 5609 font_param = Fframe_parameter (frame, Qfont_param);
5599 default_name = alloca (256); 5610 if (STRINGP (font_param))
5600 if (font_unparse_gtkname (default_font, f, default_name, 256) < 0) 5611 default_name = SDATA (font_param);
5601 default_name = NULL;
5602 } 5612 }
5603 5613
5614 if (default_name == NULL && x_last_font_name != NULL)
5615 default_name = x_last_font_name;
5616
5604 name = xg_get_font_name (f, default_name); 5617 name = xg_get_font_name (f, default_name);
5605 5618
5606 if (name) 5619 if (name)
diff --git a/src/xfont.c b/src/xfont.c
index 36ac09fcb18..ab37350ddf6 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -151,7 +151,9 @@ struct font_driver xfont_driver =
151 xfont_text_extents, 151 xfont_text_extents,
152 xfont_draw, 152 xfont_draw,
153 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 153 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
154 xfont_check 154 xfont_check,
155 NULL, /* get_variation_glyphs */
156 NULL, /* filter_properties */
155 }; 157 };
156 158
157extern Lisp_Object QCname; 159extern Lisp_Object QCname;
diff --git a/src/xftfont.c b/src/xftfont.c
index e66b538fa15..6455c5f2c52 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -184,6 +184,53 @@ extern Lisp_Object QCantialias;
184 184
185static FcChar8 ascii_printable[95]; 185static FcChar8 ascii_printable[95];
186 186
187static void
188xftfont_fix_match (pat, match)
189 FcPattern *pat, *match;
190{
191 /* These values are not used for matching (except antialias), but for
192 rendering, so make sure they are carried over to the match.
193 We also put antialias here because most fonts are antialiased, so
194 the match will have antialias true. */
195
196 FcBool b = FcTrue;
197 int i;
198 double dpi;
199
200 FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b);
201 if (! b)
202 {
203 FcPatternDel (match, FC_ANTIALIAS);
204 FcPatternAddBool (match, FC_ANTIALIAS, FcFalse);
205 }
206 FcPatternGetBool (pat, FC_HINTING, 0, &b);
207 if (! b)
208 {
209 FcPatternDel (match, FC_HINTING);
210 FcPatternAddBool (match, FC_HINTING, FcFalse);
211 }
212 if (FcResultMatch == FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &i))
213 {
214 FcPatternDel (match, FC_HINT_STYLE);
215 FcPatternAddInteger (match, FC_HINT_STYLE, i);
216 }
217 if (FcResultMatch == FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &i))
218 {
219 FcPatternDel (match, FC_LCD_FILTER);
220 FcPatternAddInteger (match, FC_LCD_FILTER, i);
221 }
222 if (FcResultMatch == FcPatternGetInteger (pat, FC_RGBA, 0, &i))
223 {
224 FcPatternDel (match, FC_RGBA);
225 FcPatternAddInteger (match, FC_RGBA, i);
226 }
227 if (FcResultMatch == FcPatternGetDouble (pat, FC_DPI, 0, &dpi))
228 {
229 FcPatternDel (match, FC_DPI);
230 FcPatternAddDouble (match, FC_DPI, dpi);
231 }
232}
233
187static Lisp_Object 234static Lisp_Object
188xftfont_open (f, entity, pixel_size) 235xftfont_open (f, entity, pixel_size)
189 FRAME_PTR f; 236 FRAME_PTR f;
@@ -249,7 +296,7 @@ xftfont_open (f, entity, pixel_size)
249 296
250 key = XCAR (XCAR (tail)), val = XCDR (XCAR (tail)); 297 key = XCAR (XCAR (tail)), val = XCDR (XCAR (tail));
251 if (EQ (key, QCantialias)) 298 if (EQ (key, QCantialias))
252 FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue); 299 FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue);
253 else if (EQ (key, QChinting)) 300 else if (EQ (key, QChinting))
254 FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue); 301 FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue);
255 else if (EQ (key, QCautohint)) 302 else if (EQ (key, QCautohint))
@@ -285,7 +332,12 @@ xftfont_open (f, entity, pixel_size)
285 int event_base, error_base; 332 int event_base, error_base;
286 XRenderQueryExtension (display, &event_base, &error_base); 333 XRenderQueryExtension (display, &event_base, &error_base);
287 } 334 }
335
336 /* Substitute in values from X resources and XftDefaultSet. */
337 XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat);
288 match = XftFontMatch (display, FRAME_X_SCREEN_NUMBER (f), pat, &result); 338 match = XftFontMatch (display, FRAME_X_SCREEN_NUMBER (f), pat, &result);
339 xftfont_fix_match (pat, match);
340
289 FcPatternDestroy (pat); 341 FcPatternDestroy (pat);
290 xftfont = XftFontOpenPattern (display, match); 342 xftfont = XftFontOpenPattern (display, match);
291 if (!xftfont) 343 if (!xftfont)
diff --git a/src/xsettings.c b/src/xsettings.c
new file mode 100644
index 00000000000..84e05a1898a
--- /dev/null
+++ b/src/xsettings.c
@@ -0,0 +1,627 @@
1/* Functions for handle font changes dynamically.
2 Copyright (C) 2009
3 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19
20#include "config.h"
21#include <setjmp.h>
22#include <fcntl.h>
23#include "lisp.h"
24#include "xterm.h"
25#include "xsettings.h"
26#include "frame.h"
27#include "blockinput.h"
28#include "termhooks.h"
29#include "termopts.h"
30
31#include <X11/Xproto.h>
32
33#ifdef HAVE_GCONF
34#include <gconf/gconf-client.h>
35#endif
36#ifdef HAVE_XFT
37#include <X11/Xft/Xft.h>
38#endif
39
40static char *current_mono_font;
41static struct x_display_info *first_dpyinfo;
42static Lisp_Object Qfont_name, Qfont_render;
43
44#ifdef HAVE_GCONF
45static GConfClient *gconf_client;
46#endif
47
48
49static void
50store_font_changed_event (arg, display_name)
51 Lisp_Object arg;
52 Lisp_Object display_name;
53{
54 struct input_event event;
55 EVENT_INIT (event);
56 event.kind = CONFIG_CHANGED_EVENT;
57 event.frame_or_window = display_name;
58 event.arg = arg;
59 kbd_buffer_store_event (&event);
60}
61
62#ifdef HAVE_GCONF
63
64#define SYSTEM_MONO_FONT "/desktop/gnome/interface/monospace_font_name"
65
66/* Callback called when something changed in GConf that we care about,
67 that is SYSTEM_MONO_FONT. */
68
69static void
70something_changedCB (client, cnxn_id, entry, user_data)
71 GConfClient *client;
72 guint cnxn_id;
73 GConfEntry *entry;
74 gpointer user_data;
75{
76 GConfValue *v = gconf_entry_get_value (entry);
77
78 if (!v) return;
79 if (v->type == GCONF_VALUE_STRING)
80 {
81 const char *value = gconf_value_get_string (v);
82 int i;
83 if (current_mono_font != NULL && strcmp (value, current_mono_font) == 0)
84 return; // No change.
85
86 xfree (current_mono_font);
87 current_mono_font = xstrdup (value);
88 }
89
90
91 if (first_dpyinfo != NULL)
92 {
93 /* Check if display still open */
94 struct x_display_info *dpyinfo;
95 int found = 0;
96 for (dpyinfo = x_display_list; !found && dpyinfo; dpyinfo = dpyinfo->next)
97 found = dpyinfo == first_dpyinfo;
98
99 if (found)
100 store_font_changed_event (Qfont_name,
101 XCAR (first_dpyinfo->name_list_element));
102 }
103}
104#endif /* HAVE_GCONF */
105
106#ifdef HAVE_XFT
107
108/* Find the window that contains the XSETTINGS property values. */
109
110static void
111get_prop_window (dpyinfo)
112 struct x_display_info *dpyinfo;
113{
114 Display *dpy = dpyinfo->display;
115
116 XGrabServer (dpy);
117 dpyinfo->xsettings_window = XGetSelectionOwner (dpy,
118 dpyinfo->Xatom_xsettings_sel);
119 if (dpyinfo->xsettings_window != None)
120 /* Select events so we can detect if window is deleted or if settings
121 are changed. */
122 XSelectInput (dpy, dpyinfo->xsettings_window,
123 PropertyChangeMask|StructureNotifyMask);
124
125 XUngrabServer (dpy);
126}
127
128struct xsettings
129{
130 FcBool aa, hinting;
131 int rgba, lcdfilter, hintstyle;
132 double dpi;
133};
134
135#define SWAP32(nr) (((nr) << 24) | (((nr) << 8) & 0xff0000) \
136 | (((nr) >> 8) & 0xff00) | ((nr) >> 24))
137#define SWAP16(nr) (((nr) << 8) | ((nr) >> 8))
138#define PAD(nr) (((nr) + 3) & ~3)
139
140/* Parse xsettings and extract those that deal with Xft.
141 See http://freedesktop.org/wiki/Specifications/XSettingsRegistry
142 and http://standards.freedesktop.org/xsettings-spec/xsettings-spec-0.5.html.
143
144 Layout of prop. First is a header:
145
146 bytes type what
147 ------------------------------------
148 1 CARD8 byte-order
149 3 unused
150 4 CARD32 SERIAL
151 4 CARD32 N_SETTINGS
152
153 Then N_SETTINGS records, with header:
154
155 bytes type what
156 ------------------------------------
157 1 SETTING_TYPE type (0 = integer, 1 = string, 2 RGB color).
158 1 unused
159 2 CARD16 n == name-length
160 n STRING8 name
161 p unused, p=pad_to_even_4(n)
162 4 CARD32 last-change-serial
163
164 and then the value, For string:
165
166 bytes type what
167 ------------------------------------
168 4 CARD32 n = value-length
169 n STRING8 value
170 p unused, p=pad_to_even_4(n)
171
172 For integer:
173
174 bytes type what
175 ------------------------------------
176 4 INT32 value
177
178 For RGB color:
179
180 bytes type what
181 ------------------------------------
182 2 CARD16 red
183 2 CARD16 blue
184 2 CARD16 green
185 2 CARD16 alpha
186
187*/
188
189static int
190parse_xft_settings (prop, bytes, settings)
191 unsigned char *prop;
192 unsigned long bytes;
193 struct xsettings *settings;
194{
195 Lisp_Object byteorder = Fbyteorder ();
196 int my_bo = XFASTINT (byteorder) == 'B' ? MSBFirst : LSBFirst;
197 int that_bo = prop[0];
198 CARD32 n_settings;
199 int bytes_parsed = 0;
200 int settings_seen = 0;
201 int i = 0;
202
203 /* First 4 bytes is a serial number, skip that. */
204
205 if (bytes < 12) return BadLength;
206 memcpy (&n_settings, prop+8, 4);
207 if (my_bo != that_bo) n_settings = SWAP32 (n_settings);
208 bytes_parsed = 12;
209
210 memset (settings, 0, sizeof (*settings));
211
212 while (bytes_parsed+4 < bytes && settings_seen < 6
213 && i < n_settings)
214 {
215 int type = prop[bytes_parsed++];
216 CARD16 nlen;
217 CARD32 vlen, ival = 0;
218 char name[128]; /* The names we are looking for are not this long. */
219 char sval[128]; /* The values we are looking for are not this long. */
220 int is_xft;
221 int to_cpy;
222
223 sval[0] = '\0';
224 ++i;
225 ++bytes_parsed; /* Padding */
226
227 memcpy (&nlen, prop+bytes_parsed, 2);
228 bytes_parsed += 2;
229 if (my_bo != that_bo) nlen = SWAP16 (nlen);
230 if (bytes_parsed+nlen > bytes) return BadLength;
231 to_cpy = nlen > 127 ? 127 : nlen;
232 memcpy (name, prop+bytes_parsed, to_cpy);
233 name[to_cpy] = '\0';
234
235 bytes_parsed += nlen;
236 bytes_parsed = PAD (bytes_parsed);
237
238 bytes_parsed += 4; /* Skip serial for this value */
239 if (bytes_parsed > bytes) return BadLength;
240
241 is_xft = nlen > 6 && strncmp (name, "Xft/", 4) == 0;
242
243 switch (type)
244 {
245 case 0: /* Integer */
246 if (bytes_parsed+4 > bytes) return BadLength;
247 if (is_xft)
248 {
249 memcpy (&ival, prop+bytes_parsed, 4);
250 if (my_bo != that_bo) ival = SWAP32 (ival);
251 }
252 bytes_parsed += 4;
253 break;
254
255 case 1: /* String */
256 if (bytes_parsed+4 > bytes) return BadLength;
257 memcpy (&vlen, prop+bytes_parsed, 4);
258 bytes_parsed += 4;
259 if (my_bo != that_bo) vlen = SWAP32 (vlen);
260 if (is_xft)
261 {
262 to_cpy = vlen > 127 ? 127 : vlen;
263 memcpy (sval, prop+bytes_parsed, to_cpy);
264 sval[to_cpy] = '\0';
265 }
266 bytes_parsed += vlen;
267 bytes_parsed = PAD (bytes_parsed);
268 break;
269
270 case 2: /* RGB value */
271 /* No need to parse this */
272 if (bytes_parsed+8 > bytes) return BadLength;
273 bytes_parsed += 8; /* 4 values (r, b, g, alpha), 2 bytes each. */
274 break;
275
276 default: /* Parse Error */
277 return BadValue;
278 }
279
280 if (is_xft)
281 {
282 ++settings_seen;
283 if (strcmp (name, "Xft/Antialias") == 0)
284 settings->aa = ival != 0;
285 else if (strcmp (name, "Xft/Hinting") == 0)
286 settings->hinting = ival != 0;
287 else if (strcmp (name, "Xft/HintStyle") == 0)
288 {
289 if (strcmp (sval, "hintnone") == 0)
290 settings->hintstyle = FC_HINT_NONE;
291 else if (strcmp (sval, "hintslight") == 0)
292 settings->hintstyle = FC_HINT_SLIGHT;
293 else if (strcmp (sval, "hintmedium") == 0)
294 settings->hintstyle = FC_HINT_MEDIUM;
295 else if (strcmp (sval, "hintfull") == 0)
296 settings->hintstyle = FC_HINT_FULL;
297 }
298 else if (strcmp (name, "Xft/RGBA") == 0)
299 {
300 if (strcmp (sval, "none") == 0)
301 settings->rgba = FC_RGBA_NONE;
302 else if (strcmp (sval, "rgb") == 0)
303 settings->rgba = FC_RGBA_RGB;
304 else if (strcmp (sval, "bgr") == 0)
305 settings->rgba = FC_RGBA_BGR;
306 else if (strcmp (sval, "vrgb") == 0)
307 settings->rgba = FC_RGBA_VRGB;
308 else if (strcmp (sval, "vbgr") == 0)
309 settings->rgba = FC_RGBA_VBGR;
310 }
311 else if (strcmp (name, "Xft/DPI") == 0)
312 settings->dpi = (double)ival/1024.0;
313 else if (strcmp (name, "Xft/lcdfilter") == 0)
314 {
315 if (strcmp (sval, "none") == 0)
316 settings->lcdfilter = FC_LCD_NONE;
317 else if (strcmp (sval, "lcddefault") == 0)
318 settings->lcdfilter = FC_LCD_DEFAULT;
319 }
320 }
321 }
322
323 return Success;
324}
325
326static int
327read_xft_settings (dpyinfo, settings)
328 struct x_display_info *dpyinfo;
329 struct xsettings *settings;
330{
331 long long_len;
332 Atom act_type;
333 int act_form;
334 unsigned long nitems, bytes_after;
335 unsigned char *prop = NULL;
336 Display *dpy = dpyinfo->display;
337 int rc;
338
339 x_catch_errors (dpy);
340 rc = XGetWindowProperty (dpy,
341 dpyinfo->xsettings_window,
342 dpyinfo->Xatom_xsettings_prop,
343 0, LONG_MAX, False, AnyPropertyType,
344 &act_type, &act_form, &nitems, &bytes_after,
345 &prop);
346
347 if (rc == Success && prop != NULL && act_form == 8 && nitems > 0
348 && act_type == dpyinfo->Xatom_xsettings_prop)
349 rc = parse_xft_settings (prop, nitems, settings);
350
351 XFree (prop);
352
353 x_uncatch_errors ();
354
355 return rc == Success;
356}
357
358static void
359apply_xft_settings (dpyinfo, send_event_p)
360 struct x_display_info *dpyinfo;
361 int send_event_p;
362{
363 FcPattern *pat;
364 struct xsettings settings, oldsettings;
365 int changed = 0;
366
367 if (!read_xft_settings (dpyinfo, &settings))
368 return;
369
370 memset (&oldsettings, 0, sizeof (oldsettings));
371
372 pat = FcPatternCreate ();
373 XftDefaultSubstitute (dpyinfo->display,
374 XScreenNumberOfScreen (dpyinfo->screen),
375 pat);
376 FcPatternGetBool (pat, FC_ANTIALIAS, 0, &oldsettings.aa);
377 FcPatternGetBool (pat, FC_HINTING, 0, &oldsettings.hinting);
378 FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &oldsettings.hintstyle);
379 FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &oldsettings.lcdfilter);
380 FcPatternGetInteger (pat, FC_RGBA, 0, &oldsettings.rgba);
381 FcPatternGetDouble (pat, FC_DPI, 0, &oldsettings.dpi);
382
383 if (oldsettings.aa != settings.aa)
384 {
385 FcPatternDel (pat, FC_ANTIALIAS);
386 FcPatternAddBool (pat, FC_ANTIALIAS, settings.aa);
387 ++changed;
388 }
389 if (oldsettings.hinting != settings.hinting)
390 {
391 FcPatternDel (pat, FC_HINTING);
392 FcPatternAddBool (pat, FC_HINTING, settings.hinting);
393 ++changed;
394 }
395 if (oldsettings.rgba != settings.rgba)
396 {
397 FcPatternDel (pat, FC_RGBA);
398 FcPatternAddInteger (pat, FC_RGBA, settings.rgba);
399 ++changed;
400 }
401 if (oldsettings.lcdfilter != settings.lcdfilter)
402 {
403 FcPatternDel (pat, FC_LCD_FILTER);
404 FcPatternAddInteger (pat, FC_LCD_FILTER, settings.lcdfilter);
405 ++changed;
406 }
407 if (oldsettings.hintstyle != settings.hintstyle)
408 {
409 FcPatternDel (pat, FC_HINT_STYLE);
410 FcPatternAddInteger (pat, FC_HINT_STYLE, settings.hintstyle);
411 ++changed;
412 }
413 if (oldsettings.dpi != settings.dpi)
414 {
415 Lisp_Object frame, tail;
416
417 FcPatternDel (pat, FC_DPI);
418 FcPatternAddDouble (pat, FC_DPI, settings.dpi);
419 ++changed;
420
421 /* Change the DPI on this display and all frames on the display. */
422 dpyinfo->resy = dpyinfo->resx = settings.dpi;
423 FOR_EACH_FRAME (tail, frame)
424 if (FRAME_X_P (XFRAME (frame))
425 && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
426 XFRAME (frame)->resy = XFRAME (frame)->resx = settings.dpi;
427 }
428
429 if (changed)
430 {
431 XftDefaultSet (dpyinfo->display, pat);
432 if (send_event_p)
433 store_font_changed_event (Qfont_render,
434 XCAR (dpyinfo->name_list_element));
435 }
436 else
437 FcPatternDestroy (pat);
438}
439
440#endif /* HAVE_XFT */
441
442void
443xft_settings_event (dpyinfo, event)
444 struct x_display_info *dpyinfo;
445 XEvent *event;
446{
447#ifdef HAVE_XFT
448 int check_window_p = 0;
449
450 switch (event->type)
451 {
452 case DestroyNotify:
453 if (dpyinfo->xsettings_window == event->xany.window)
454 check_window_p = 1;
455 break;
456
457 case ClientMessage:
458 if (event->xclient.message_type == dpyinfo->Xatom_xsettings_mgr
459 && event->xclient.data.l[1] == dpyinfo->Xatom_xsettings_sel
460 && event->xclient.window == dpyinfo->root_window)
461 check_window_p = 1;
462 break;
463
464 case PropertyNotify:
465 if (event->xproperty.window == dpyinfo->xsettings_window
466 && event->xproperty.state == PropertyNewValue
467 && event->xproperty.atom == dpyinfo->Xatom_xsettings_prop)
468 {
469 apply_xft_settings (dpyinfo, True);
470 }
471 break;
472 }
473
474 if (check_window_p)
475 {
476 dpyinfo->xsettings_window = None;
477 get_prop_window (dpyinfo);
478 if (dpyinfo->xsettings_window != None)
479 apply_xft_settings (dpyinfo, True);
480 }
481#endif /* HAVE_XFT */
482}
483
484
485static void
486init_gconf ()
487{
488#ifdef HAVE_GCONF
489 int i;
490 char *s;
491 /* Should be enough, this is called at startup */
492#define N_FDS 1024
493 int fd_before[N_FDS], fd_before1[N_FDS];
494 int dummy, n_fds;
495 GPollFD gfds[N_FDS];
496
497 /* To find out which filedecriptors GConf uses, check before and after.
498 If we do not do this, GConf changes will only happen when Emacs gets
499 an X event. */
500 memset (fd_before, 0, sizeof (fd_before));
501 n_fds = g_main_context_query (g_main_context_default (),
502 G_PRIORITY_LOW,
503 &dummy,
504 gfds,
505 N_FDS);
506 for (i = 0; i < n_fds; ++i)
507 if (gfds[i].fd < N_FDS && gfds[i].fd > 0 && gfds[i].events > 0)
508 fd_before[gfds[i].fd] = 1;
509
510 g_type_init ();
511 gconf_client = gconf_client_get_default ();
512 s = gconf_client_get_string (gconf_client, SYSTEM_MONO_FONT, NULL);
513 if (s)
514 {
515 current_mono_font = xstrdup (s);
516 g_free (s);
517 }
518 gconf_client_set_error_handling (gconf_client, GCONF_CLIENT_HANDLE_NONE);
519 gconf_client_add_dir (gconf_client,
520 SYSTEM_MONO_FONT,
521 GCONF_CLIENT_PRELOAD_ONELEVEL,
522 NULL);
523 gconf_client_notify_add (gconf_client,
524 SYSTEM_MONO_FONT,
525 something_changedCB,
526 NULL, NULL, NULL);
527 n_fds = g_main_context_query (g_main_context_default (),
528 G_PRIORITY_LOW,
529 &dummy,
530 gfds,
531 N_FDS);
532
533 for (i = 0; i < n_fds; ++i)
534 if (gfds[i].fd < N_FDS && gfds[i].fd > 0 && gfds[i].events > 0
535 && !fd_before[gfds[i].fd])
536 {
537#ifdef F_SETOWN
538 fcntl (i, F_SETOWN, getpid ());
539#endif /* ! defined (F_SETOWN) */
540
541#ifdef SIGIO
542 if (interrupt_input)
543 init_sigio (i);
544#endif /* ! defined (SIGIO) */
545 }
546#endif /* HAVE_GCONF */
547}
548
549static void
550init_xfd_settings (dpyinfo)
551 struct x_display_info *dpyinfo;
552{
553#ifdef HAVE_XFT
554 char sel[64];
555 Display *dpy = dpyinfo->display;
556
557 BLOCK_INPUT;
558
559 sprintf (sel, "_XSETTINGS_S%d", XScreenNumberOfScreen (dpyinfo->screen));
560 dpyinfo->Xatom_xsettings_sel = XInternAtom (dpy, sel, False);
561 dpyinfo->Xatom_xsettings_prop = XInternAtom (dpy,
562 "_XSETTINGS_SETTINGS",
563 False);
564 dpyinfo->Xatom_xsettings_mgr = XInternAtom (dpy, "MANAGER", False);
565
566 /* Select events so we can detect client messages sent when selection
567 owner changes. */
568 XSelectInput (dpy, dpyinfo->root_window, StructureNotifyMask);
569
570 get_prop_window (dpyinfo);
571 if (dpyinfo->xsettings_window != None)
572 apply_xft_settings (dpyinfo, False);
573
574 UNBLOCK_INPUT;
575
576#else /* ! HAVE_XFT */
577
578 dpyinfo->Xatom_xsettings_sel = None;
579 dpyinfo->Xatom_xsettings_prop = None;
580 dpyinfo->Xatom_xsettings_mgr = None;
581 dpyinfo->xsettings_window = None;
582
583#endif /* ! HAVE_XFT */
584}
585
586void
587xsettings_initialize (dpyinfo)
588 struct x_display_info *dpyinfo;
589{
590 if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo;
591 init_gconf ();
592 init_xfd_settings (dpyinfo);
593}
594
595
596DEFUN ("font-get-system-font", Ffont_get_system_font, Sfont_get_system_font,
597 0, 0, 0,
598 doc: /* Get the system default monospaced font. */)
599 ()
600{
601 return current_mono_font
602 ? make_string (current_mono_font, strlen (current_mono_font))
603 : Qnil;
604}
605
606void
607syms_of_xsettings ()
608{
609 current_mono_font = NULL;
610 first_dpyinfo = NULL;
611#ifdef HAVE_GCONF
612 gconf_client = NULL;
613#endif
614
615 Qfont_name = intern_c_string ("font-name");
616 staticpro (&Qfont_name);
617 Qfont_render = intern_c_string ("font-render");
618 staticpro (&Qfont_render);
619 defsubr (&Sfont_get_system_font);
620
621#ifdef HAVE_GCONF
622 Fprovide (intern_c_string ("system-font-setting"), Qnil);
623#endif
624#ifdef HAVE_XFT
625 Fprovide (intern_c_string ("font-render-setting"), Qnil);
626#endif
627}
diff --git a/src/xsettings.h b/src/xsettings.h
new file mode 100644
index 00000000000..f8d73db2ee0
--- /dev/null
+++ b/src/xsettings.h
@@ -0,0 +1,29 @@
1/* Functions for handle font changes dynamically.
2 Copyright (C) 2009
3 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19
20#ifndef XSETTINGS_H
21#define XSETTINGS_H
22
23extern Lisp_Object Ffont_get_system_font P_ ((void));
24extern void xsettings_initialize P_ ((struct x_display_info *dpyinfo));
25extern void xft_settings_event P_ ((struct x_display_info *dpyinfo,
26 XEvent *));
27
28
29#endif /* XSETTINGS_H */
diff --git a/src/xterm.c b/src/xterm.c
index 9936e98b1ed..3349dc05b95 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -86,6 +86,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
86#include "keymap.h" 86#include "keymap.h"
87#include "font.h" 87#include "font.h"
88#include "fontset.h" 88#include "fontset.h"
89#include "xsettings.h"
89#include "sysselect.h" 90#include "sysselect.h"
90 91
91#ifdef USE_X_TOOLKIT 92#ifdef USE_X_TOOLKIT
@@ -6026,6 +6027,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6026 goto done; 6027 goto done;
6027 } 6028 }
6028 6029
6030 xft_settings_event (dpyinfo, &event);
6031
6029 f = x_any_window_to_frame (dpyinfo, event.xclient.window); 6032 f = x_any_window_to_frame (dpyinfo, event.xclient.window);
6030 if (!f) 6033 if (!f)
6031 goto OTHER; 6034 goto OTHER;
@@ -6088,6 +6091,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6088 x_handle_net_wm_state (f, &event.xproperty); 6091 x_handle_net_wm_state (f, &event.xproperty);
6089 6092
6090 x_handle_property_notify (&event.xproperty); 6093 x_handle_property_notify (&event.xproperty);
6094 xft_settings_event (dpyinfo, &event);
6091 goto OTHER; 6095 goto OTHER;
6092 6096
6093 case ReparentNotify: 6097 case ReparentNotify:
@@ -6991,6 +6995,10 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6991 } 6995 }
6992 goto OTHER; 6996 goto OTHER;
6993 6997
6998 case DestroyNotify:
6999 xft_settings_event (dpyinfo, &event);
7000 break;
7001
6994 default: 7002 default:
6995 OTHER: 7003 OTHER:
6996#ifdef USE_X_TOOLKIT 7004#ifdef USE_X_TOOLKIT
@@ -10300,17 +10308,33 @@ x_term_init (display_name, xrm_option, resource_name)
10300 dpyinfo->cmap = XCreateColormap (dpyinfo->display, dpyinfo->root_window, 10308 dpyinfo->cmap = XCreateColormap (dpyinfo->display, dpyinfo->root_window,
10301 dpyinfo->visual, AllocNone); 10309 dpyinfo->visual, AllocNone);
10302 10310
10311#ifdef HAVE_XFT
10303 { 10312 {
10304 int screen_number = XScreenNumberOfScreen (dpyinfo->screen); 10313 /* If we are using Xft, check dpi value in X resources.
10305 double pixels = DisplayHeight (dpyinfo->display, screen_number); 10314 It is better we use it as well, since Xft will use it, as will all
10306 double mm = DisplayHeightMM (dpyinfo->display, screen_number); 10315 Gnome applications. If our real DPI is smaller or larger than the
10307 /* Mac OS X 10.3's Xserver sometimes reports 0.0mm. */ 10316 one Xft uses, our font will look smaller or larger than other
10308 dpyinfo->resy = (mm < 1) ? 100 : pixels * 25.4 / mm; 10317 for other applications, even if it is the same font name (monospace-10
10309 pixels = DisplayWidth (dpyinfo->display, screen_number); 10318 for example). */
10310 mm = DisplayWidthMM (dpyinfo->display, screen_number); 10319 char *v = XGetDefault (dpyinfo->display, "Xft", "dpi");
10311 /* Mac OS X 10.3's Xserver sometimes reports 0.0mm. */ 10320 double d;
10312 dpyinfo->resx = (mm < 1) ? 100 : pixels * 25.4 / mm; 10321 if (v != NULL && sscanf (v, "%lf", &d) == 1)
10322 dpyinfo->resy = dpyinfo->resx = d;
10313 } 10323 }
10324#endif
10325
10326 if (dpyinfo->resy < 1)
10327 {
10328 int screen_number = XScreenNumberOfScreen (dpyinfo->screen);
10329 double pixels = DisplayHeight (dpyinfo->display, screen_number);
10330 double mm = DisplayHeightMM (dpyinfo->display, screen_number);
10331 /* Mac OS X 10.3's Xserver sometimes reports 0.0mm. */
10332 dpyinfo->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
10333 pixels = DisplayWidth (dpyinfo->display, screen_number);
10334 mm = DisplayWidthMM (dpyinfo->display, screen_number);
10335 /* Mac OS X 10.3's Xserver sometimes reports 0.0mm. */
10336 dpyinfo->resx = (mm < 1) ? 100 : pixels * 25.4 / mm;
10337 }
10314 10338
10315 dpyinfo->Xatom_wm_protocols 10339 dpyinfo->Xatom_wm_protocols
10316 = XInternAtom (dpyinfo->display, "WM_PROTOCOLS", False); 10340 = XInternAtom (dpyinfo->display, "WM_PROTOCOLS", False);
@@ -10415,6 +10439,8 @@ x_term_init (display_name, xrm_option, resource_name)
10415 xim_initialize (dpyinfo, resource_name); 10439 xim_initialize (dpyinfo, resource_name);
10416#endif 10440#endif
10417 10441
10442 xsettings_initialize (dpyinfo);
10443
10418#ifdef subprocesses 10444#ifdef subprocesses
10419 /* This is only needed for distinguishing keyboard and process input. */ 10445 /* This is only needed for distinguishing keyboard and process input. */
10420 if (connection != 0) 10446 if (connection != 0)
diff --git a/src/xterm.h b/src/xterm.h
index e76634d7d43..1ad2a097016 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -364,6 +364,10 @@ struct x_display_info
364 Atom Xatom_net_wm_state, Xatom_net_wm_state_fullscreen_atom, 364 Atom Xatom_net_wm_state, Xatom_net_wm_state_fullscreen_atom,
365 Xatom_net_wm_state_maximized_horz, Xatom_net_wm_state_maximized_vert, 365 Xatom_net_wm_state_maximized_horz, Xatom_net_wm_state_maximized_vert,
366 Xatom_net_wm_state_sticky; 366 Xatom_net_wm_state_sticky;
367
368 /* XSettings atoms and windows. */
369 Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr;
370 Window xsettings_window;
367}; 371};
368 372
369#ifdef HAVE_X_I18N 373#ifdef HAVE_X_I18N