changeset 106085:cd4cbab8bb21

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.
author Jan Djärv <jan.h.d@swipnet.se>
date Tue, 17 Nov 2009 08:21:23 +0000
parents f03048d6d95a
children be7e2495f4ac
files ChangeLog configure configure.in etc/ChangeLog etc/NEWS lisp/ChangeLog lisp/Makefile.in lisp/font-setting.el lisp/loadup.el lisp/menu-bar.el src/ChangeLog src/Makefile.in src/config.in src/emacs.c src/font.c src/font.h src/frame.c src/ftfont.c src/keyboard.c src/lisp.h src/termhooks.h src/w32font.c src/xfns.c src/xfont.c src/xftfont.c src/xsettings.c src/xsettings.h src/xterm.c src/xterm.h
diffstat 29 files changed, 1289 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Nov 17 04:44:58 2009 +0000
+++ b/ChangeLog	Tue Nov 17 08:21:23 2009 +0000
@@ -1,3 +1,8 @@
+2009-11-17  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* configure.in: New option: --with(out)-gconf.
+	Set HAVE_GCONF if we find gconf.
+
 2009-11-17  Glenn Morris  <rgm@gnu.org>
 
 	* Makefile.in (INFO_FILES): Add semantic.
--- a/configure	Tue Nov 17 04:44:58 2009 +0000
+++ b/configure	Tue Nov 17 08:21:23 2009 +0000
@@ -716,6 +716,8 @@
 GTK_LIBS
 DBUS_CFLAGS
 DBUS_LIBS
+GCONF_CFLAGS
+GCONF_LIBS
 FONTCONFIG_CFLAGS
 FONTCONFIG_LIBS
 XFT_CFLAGS
@@ -791,6 +793,7 @@
 with_ns
 with_gpm
 with_dbus
+with_gconf
 with_makeinfo
 with_gtk
 with_gcc
@@ -1499,6 +1502,7 @@
   --without-gpm           don't use -lgpm for mouse support on a GNU/Linux
                           console
   --without-dbus          don't compile with D-Bus support
+  --without-gconf         don't compile with GConf support
   --without-makeinfo      don't require makeinfo for building manuals
 
   --with-pkg-config-prog=PATH
@@ -2240,6 +2244,14 @@
 fi
 
 
+# Check whether --with-gconf was given.
+if test "${with_gconf+set}" = set; then
+  withval=$with_gconf;
+else
+     with_gconf=yes
+fi
+
+
 ## For the times when you want to build Emacs but don't have
 ## a suitable makeinfo, and can live without the manuals.
 
@@ -12519,6 +12531,111 @@
    fi
 fi
 
+HAVE_GCONF=no
+if test "${with_gconf}" = "yes"; then
+
+  succeeded=no
+
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
+  ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+  if test "$PKG_CONFIG" = "no" ; then
+     HAVE_GCONF=no
+  else
+     PKG_CONFIG_MIN_VERSION=0.9.0
+     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
+        { $as_echo "$as_me:$LINENO: checking for gconf-2.0 >= 2.13" >&5
+$as_echo_n "checking for gconf-2.0 >= 2.13... " >&6; }
+
+        if $PKG_CONFIG --exists "gconf-2.0 >= 2.13" 2>&5; then
+            { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+            succeeded=yes
+
+            { $as_echo "$as_me:$LINENO: checking GCONF_CFLAGS" >&5
+$as_echo_n "checking GCONF_CFLAGS... " >&6; }
+            GCONF_CFLAGS=`$PKG_CONFIG --cflags "gconf-2.0 >= 2.13"|sed -e 's,///*,/,g'`
+            { $as_echo "$as_me:$LINENO: result: $GCONF_CFLAGS" >&5
+$as_echo "$GCONF_CFLAGS" >&6; }
+
+            { $as_echo "$as_me:$LINENO: checking GCONF_LIBS" >&5
+$as_echo_n "checking GCONF_LIBS... " >&6; }
+            GCONF_LIBS=`$PKG_CONFIG --libs "gconf-2.0 >= 2.13"|sed -e 's,///*,/,g'`
+            { $as_echo "$as_me:$LINENO: result: $GCONF_LIBS" >&5
+$as_echo "$GCONF_LIBS" >&6; }
+        else
+            { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+            GCONF_CFLAGS=""
+            GCONF_LIBS=""
+            ## If we have a custom action on failure, don't print errors, but
+            ## do set a variable so people can do so.
+            GCONF_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "gconf-2.0 >= 2.13"`
+
+        fi
+
+
+
+     else
+        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
+        echo "*** See http://www.freedesktop.org/software/pkgconfig"
+     fi
+  fi
+
+  if test $succeeded = yes; then
+     HAVE_GCONF=yes
+  else
+     HAVE_GCONF=no
+  fi
+
+   if test "$HAVE_GCONF" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GCONF 1
+_ACEOF
+
+   fi
+fi
+
 HAVE_XAW3D=no
 if test x"${USE_X_TOOLKIT}" = xmaybe || test x"${USE_X_TOOLKIT}" = xLUCID; then
   if test "$with_xaw3d" != no; then
@@ -25513,6 +25630,7 @@
 echo "  Does Emacs use -lrsvg-2?                                ${HAVE_RSVG}"
 echo "  Does Emacs use -lgpm?                                   ${HAVE_GPM}"
 echo "  Does Emacs use -ldbus?                                  ${HAVE_DBUS}"
+echo "  Does Emacs use -lgconf?                                 ${HAVE_GCONF}"
 
 echo "  Does Emacs use -lfreetype?                              ${HAVE_FREETYPE}"
 echo "  Does Emacs use -lm17n-flt?                              ${HAVE_M17N_FLT}"
--- a/configure.in	Tue Nov 17 04:44:58 2009 +0000
+++ b/configure.in	Tue Nov 17 08:21:23 2009 +0000
@@ -144,6 +144,7 @@
 
 OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux console])
 OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support])
+OPTION_DEFAULT_ON([gconf],[don't compile with GConf support])
 
 ## For the times when you want to build Emacs but don't have
 ## a suitable makeinfo, and can live without the manuals.
@@ -1739,6 +1740,16 @@
    fi
 fi
 
+dnl GConf has been tested under GNU/Linux only.
+dnl The version is really arbitrary, it is about the same age as Gtk+ 2.6.
+HAVE_GCONF=no
+if test "${with_gconf}" = "yes"; then
+   PKG_CHECK_MODULES(GCONF, gconf-2.0 >= 2.13, HAVE_GCONF=yes, HAVE_GCONF=no)
+   if test "$HAVE_GCONF" = yes; then
+      AC_DEFINE(HAVE_GCONF, 1, [Define to 1 if using GConf.])
+   fi
+fi
+
 dnl Do not put whitespace before the #include statements below.
 dnl Older compilers (eg sunos4 cc) choke on it.
 HAVE_XAW3D=no
@@ -2985,6 +2996,7 @@
 echo "  Does Emacs use -lrsvg-2?                                ${HAVE_RSVG}"
 echo "  Does Emacs use -lgpm?                                   ${HAVE_GPM}"
 echo "  Does Emacs use -ldbus?                                  ${HAVE_DBUS}"
+echo "  Does Emacs use -lgconf?                                 ${HAVE_GCONF}"
 
 echo "  Does Emacs use -lfreetype?                              ${HAVE_FREETYPE}"
 echo "  Does Emacs use -lm17n-flt?                              ${HAVE_M17N_FLT}"
--- a/etc/ChangeLog	Tue Nov 17 04:44:58 2009 +0000
+++ b/etc/ChangeLog	Tue Nov 17 08:21:23 2009 +0000
@@ -1,3 +1,7 @@
+2009-11-17  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* NEWS: Mention dynamic font changes (font-use-system-font).
+
 2009-11-15  Carsten Dominik  <dominik@u016822.science.uva.nl>
 
 	* refcards/orgcard.tex: Push version number to 6.33a.
--- a/etc/NEWS	Tue Nov 17 04:44:58 2009 +0000
+++ b/etc/NEWS	Tue Nov 17 08:21:23 2009 +0000
@@ -78,6 +78,18 @@
 ** The pointer now becomes invisible when typing.
 Customize make-pointer-invisible to turn it off.
 
+** Emacs can use the system default monospaced font in Gnome.
+The use of the system default font can be turned on or off by customizing
+the variable 'font-use-system-font'.  It is off by default.
+If the system default is changed, Emacs changes also.
+This requires that gconf-support is built in.  If configure finds the
+gconf-libraries, that support is included. Gconf-support can be
+turned off with the configure option --without-gconf.
+
+** Emacs now reacts to Xft-changes made by configuration tools on X11.
+Changes to antialias, hinting, hintstyle, RGBA, DPI and lcdfilter are
+handeled.  The XSETTINGS mechanism is used to implement this.
+
 ** Killing a buffer with a running process now asks for confirmation.
 You can remove this query in two ways: either remove
 `process-kill-buffer-query-function' from `kill-buffer-query-functions',
--- a/lisp/ChangeLog	Tue Nov 17 04:44:58 2009 +0000
+++ b/lisp/ChangeLog	Tue Nov 17 08:21:23 2009 +0000
@@ -1,3 +1,13 @@
+2009-11-17  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* 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.
+
 2009-11-17  Glenn Morris  <rgm@gnu.org>
 
 	* vc-svn.el (vc-svn-print-log): Fix typo in previous.
--- a/lisp/Makefile.in	Tue Nov 17 04:44:58 2009 +0000
+++ b/lisp/Makefile.in	Tue Nov 17 08:21:23 2009 +0000
@@ -680,6 +680,7 @@
 	$(lisp)/follow.elc \
 	$(lisp)/font-core.elc \
 	$(lisp)/font-lock.elc \
+	$(lisp)/font-setting.elc \
 	$(lisp)/format-spec.elc \
 	$(lisp)/format.elc \
 	$(lisp)/forms.elc \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/font-setting.el	Tue Nov 17 08:21:23 2009 +0000
@@ -0,0 +1,109 @@
+;;; xsettings.el --- Support dynamic font changes
+
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+
+;; Author: Jan Djärv <jan.h.d@swipnet.se>
+;; Maintainer: FSF
+;; Keywords: font, system-font
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file provides the lisp part of the GConf and XSetting code in
+;; xsetting.c.  But it is nothing that prevents it from being used by
+;; other configuration schemes.
+
+;;; Code:
+
+;;; Customizable variables
+
+(defun font-setting-set-system-font (symbol value)
+  (set-default symbol value)
+  (if (symbol-value symbol)
+      (let ((f (selected-frame)))
+	(if (display-graphic-p f)
+	    (font-setting-change-default-font f t)))))
+
+(defcustom font-use-system-font nil
+  "If non-nil, use the system monospaced font"
+  :version "23.2"
+  :type 'boolean
+  :group 'font-selection
+  :set 'font-setting-set-system-font)
+
+(declare-function font-get-system-font "xsettings.c" ())
+
+(defun font-setting-change-default-font (display-or-frame set-font)
+  "Change font and/or font settings for frames on display DISPLAY-OR-FRAME.
+If DISPLAY-OR-FRAME is a frame, the display is the one for that frame.
+
+If set-font is non-nil, change the font for frames.  Otherwise re-apply the
+current form for the frame (i.e. hinting or somesuch changed)."
+
+  (let ((new-font (and (fboundp 'font-get-system-font) 
+		       (font-get-system-font))))
+    (when new-font
+      ;; Be careful here: when set-face-attribute is called for the
+      ;; :font attribute, Emacs tries to guess the best matching font
+      ;; by examining the other face attributes (Bug#2476).
+
+      (clear-font-cache)
+      ;; Set for current frames. Only change font for those that have
+      ;; the old font now. If they don't have the old font, the user
+      ;; probably changed it.
+      (dolist (f (frames-on-display-list display-or-frame))
+	(if (display-graphic-p f)
+	    (let* ((frame-font 
+		    (or (font-get (face-attribute 'default :font f
+						  'default) :name)
+			(frame-parameter f 'font-parameter)))
+		   (font-to-set
+		    (if set-font new-font
+		      ;; else set font again, hinting etc. may have changed.
+		      frame-font)))
+	      (progn
+		(set-frame-parameter f 'font-parameter font-to-set)
+		(set-face-attribute 'default f 
+				    :width 'normal
+				    :weight 'normal
+				    :slant 'normal
+				    :font font-to-set)))))
+    
+      ;; Set for future frames.
+      (set-face-attribute 'default t :font new-font)
+      (let ((spec (list (list t (face-attr-construct 'default)))))
+	(progn
+	  (put 'default 'customized-face spec)
+	  (custom-push-theme 'theme-face 'default 'user 'set spec)
+	  (put 'default 'face-modified nil))))))
+
+(defun font-setting-handle-config-changed-event (event)
+  "Handle config-changed-event to change fonts on the display in EVENT.
+If `font-use-system-font' is nil, the font is not changed."
+  (interactive "e")
+  (let ((type (nth 1 event)) ;; font-name or font-render
+	(display-name (nth 2 event)))
+    (if (or (not (eq type 'font-name))
+	    font-use-system-font)
+	(font-setting-change-default-font display-name
+					  (eq type 'font-name)))))
+
+(if (or (featurep 'system-font-setting) (featurep 'font-render-setting))
+  (define-key special-event-map [config-changed-event] 
+    'font-setting-handle-config-changed-event))
+
+(provide 'font-setting)
--- a/lisp/loadup.el	Tue Nov 17 04:44:58 2009 +0000
+++ b/lisp/loadup.el	Tue Nov 17 08:21:23 2009 +0000
@@ -198,6 +198,10 @@
       (load "international/fontset")
       (load "dnd")
       (load "tool-bar")))
+
+(if (or (featurep 'system-font-setting) (featurep 'font-render-setting))
+    (load "font-setting"))
+
 (if (featurep 'x)
     (progn
       (load "x-dnd")
--- a/lisp/menu-bar.el	Tue Nov 17 04:44:58 2009 +0000
+++ b/lisp/menu-bar.el	Tue Nov 17 08:21:23 2009 +0000
@@ -660,6 +660,8 @@
       (custom-push-theme 'theme-face 'default 'user 'set spec)
       (put 'default 'face-modified nil))))
 
+
+
 ;;; Assemble all the top-level items of the "Options" menu
 (define-key menu-bar-options-menu [customize]
   `(menu-item ,(purecopy "Customize Emacs") ,menu-bar-custom-menu))
@@ -713,6 +715,14 @@
 	      :visible (display-multi-font-p)
 	      :help ,(purecopy "Select a default font")))
 
+(if (featurep 'system-font-setting)
+    (define-key menu-bar-options-menu [menu-system-font]
+      (menu-bar-make-toggle toggle-use-system-font font-use-system-font
+			    "Use system font"
+			    "Use system font: %s"
+			    "Use the monospaced font defined by the system")))
+
+
 ;; The "Show/Hide" submenu of menu "Options"
 
 (defvar menu-bar-showhide-menu (make-sparse-keymap "Show/Hide"))
--- a/src/ChangeLog	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/ChangeLog	Tue Nov 17 08:21:23 2009 +0000
@@ -1,3 +1,54 @@
+2009-11-17  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* 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.
+
 2009-11-17  Kenichi Handa  <handa@m17n.org>
 
 	* xdisp.c (x_produce_glyphs): Consider face-remapping when falling
--- a/src/Makefile.in	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/Makefile.in	Tue Nov 17 08:21:23 2009 +0000
@@ -248,6 +248,11 @@
 DBUS_OBJ = dbusbind.o
 #endif
 
+#ifdef HAVE_GCONF
+GCONF_CFLAGS = @GCONF_CFLAGS@
+GCONF_LIBS = @GCONF_LIBS@
+#endif
+
 /* DO NOT use -R.  There is a special hack described in lastfile.c
    which is used instead.  Some initialized data areas are modified
    at initial startup, then labeled as part of the text area when
@@ -261,7 +266,7 @@
 
 /* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM
    since it may have -I options that should override those two.  */
-ALL_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}
+ALL_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}
 ALL_OBJC_CFLAGS=$(ALL_CFLAGS) @GNU_OBJC_CFLAGS@
 
 .SUFFIXES: .m
@@ -286,7 +291,8 @@
 
 #ifdef HAVE_X_WINDOWS
 XMENU_OBJ = xmenu.o
-XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o fringe.o image.o
+XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o fringe.o image.o \
+      xsettings.o
 
 #ifdef HAVE_MENUS
 
@@ -904,7 +910,7 @@
 
 LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) $(DBUS_LIBS) \
    LIBGPM LIBRESOLV LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \
-   LIBS_DEBUG $(GETLOADAVG_LIBS) \
+   LIBS_DEBUG $(GETLOADAVG_LIBS) ${GCONF_LIBS} \
    @FREETYPE_LIBS@ @FONTCONFIG_LIBS@ @LIBOTF_LIBS@ @M17N_FLT_LIBS@ \
    $(GNULIB_VAR) LIB_MATH LIB_STANDARD $(GNULIB_VAR)
 
@@ -1212,7 +1218,7 @@
 xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
    $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
    character.h charset.h coding.h gtkutil.h lisp.h $(config_h) termhooks.h \
-   fontset.h termchar.h font.h
+   fontset.h termchar.h font.h xsettings.h
 xfont.o: dispextern.h xterm.h frame.h blockinput.h character.h charset.h \
    font.h lisp.h $(config_h)
 xftfont.o: dispextern.h xterm.h frame.h blockinput.h character.h charset.h \
@@ -1228,13 +1234,13 @@
 xterm.o: xterm.c xterm.h termhooks.h termopts.h termchar.h window.h buffer.h \
    dispextern.h frame.h disptab.h blockinput.h atimer.h systime.h syssignal.h \
    keyboard.h emacs-icon.h character.h charset.h ccl.h fontset.h composite.h \
-   coding.h process.h gtkutil.h font.h fontset.h lisp.h $(config_h)
+   coding.h process.h gtkutil.h font.h fontset.h lisp.h $(config_h) xsettings.h
 xselect.o: xselect.c process.h dispextern.h frame.h xterm.h blockinput.h \
   buffer.h atimer.h systime.h termhooks.h lisp.h $(config_h)
 xrdb.o: xrdb.c lisp.h $(config_h) epaths.h
 xsmfns.o: xsmfns.c lisp.h $(config_h) systime.h sysselect.h termhooks.h xterm.h \
   lisp.h termopts.h
-
+xsettings.o: xterm.h xsettings.h lisp.h frame.h termhooks.h $(config_h) 
 /* The files of Lisp proper */
 
 alloc.o: alloc.c process.h frame.h window.h buffer.h  puresize.h syssignal.h keyboard.h \
--- a/src/config.in	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/config.in	Tue Nov 17 08:21:23 2009 +0000
@@ -201,6 +201,9 @@
 /* Define to 1 if you have the `gai_strerror' function. */
 #undef HAVE_GAI_STRERROR
 
+/* Define to 1 if using GConf. */
+#undef HAVE_GCONF
+
 /* Define to 1 if you have the `gdk_display_open' function. */
 #undef HAVE_GDK_DISPLAY_OPEN
 
--- a/src/emacs.c	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/emacs.c	Tue Nov 17 08:21:23 2009 +0000
@@ -1669,6 +1669,7 @@
       syms_of_xfns ();
       syms_of_xmenu ();
       syms_of_fontset ();
+      syms_of_xsettings ();
 #ifdef HAVE_X_SM
       syms_of_xsmfns ();
 #endif
@@ -1749,7 +1750,7 @@
 #endif
   init_window ();
   init_font ();
-
+  
   if (!initialized)
     {
       char *file;
--- a/src/font.c	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/font.c	Tue Nov 17 08:21:23 2009 +0000
@@ -718,8 +718,6 @@
     {
       Lisp_Object prev = Qnil;
 
-      if (NILP (val))
-	return val;
       while (CONSP (extra)
 	     && NILP (Fstring_lessp (prop, XCAR (XCAR (extra)))))
 	prev = extra, extra = XCDR (extra);
@@ -1431,6 +1429,8 @@
 
   if (family_end)
     {
+      Lisp_Object extra_props = Qnil;
+
       /* A fontconfig name with size and/or property data.  */
       if (family_end > name)
 	{
@@ -1504,13 +1504,25 @@
 
 		  if (prop >= FONT_FOUNDRY_INDEX
 		      && prop < FONT_EXTRA_INDEX)
-		    ASET (font, prop, font_prop_validate (prop, Qnil, val));
-		  else
-		    Ffont_put (font, key, val);
+                    ASET (font, prop, font_prop_validate (prop, Qnil, val));
+		  else 
+                    {
+                      extra_props = nconc2 (extra_props,
+                                            Fcons (Fcons (key, val), Qnil));
+                    }
 		}
 	      p = q;
 	    }
 	}
+
+      if (! NILP (extra_props))
+        {
+          struct font_driver_list *driver_list = font_driver_list;
+          for ( ; driver_list; driver_list = driver_list->next)
+            if (driver_list->driver->filter_properties)
+              (*driver_list->driver->filter_properties) (font, extra_props);
+        }
+      
     }
   else
     {
@@ -2975,11 +2987,15 @@
   else if (CONSP (Vface_font_rescale_alist))
     scaled_pixel_size = pixel_size * font_rescale_ratio (entity);
 
+#if 0
+  /* This doesn't work if you have changed hinting or any other parameter.
+     We need to make a new object in every case to be sure. */
   for (objlist = AREF (entity, FONT_OBJLIST_INDEX); CONSP (objlist);
        objlist = XCDR (objlist))
     if (! NILP (AREF (XCAR (objlist), FONT_TYPE_INDEX))
 	&& XFONT_OBJECT (XCAR (objlist))->pixel_size == pixel_size)
       return  XCAR (objlist);
+#endif
 
   val = AREF (entity, FONT_TYPE_INDEX);
   for (driver_list = f->font_driver_list;
@@ -3155,12 +3171,14 @@
 
   if (! FONTP (font))
     return;
+#if 0
   if (! NILP (Ffont_get (font, QCname)))
     {
       font = Fcopy_font_spec (font);
       font_put_extra (font, QCname, Qnil);
     }
 
+#endif
   if (NILP (AREF (font, prop))
       && prop != FONT_FAMILY_INDEX
       && prop != FONT_FOUNDRY_INDEX
@@ -3438,7 +3456,7 @@
 		      val = font_select_entity (frame, entities,
 						attrs, pixel_size, c);
 		      if (! NILP (val))
-			return val;
+                        return val;
 		    }
 		}
 	    }
@@ -3500,7 +3518,7 @@
      FRAME_PTR f;
      Lisp_Object *attrs, spec;
 {
-  Lisp_Object entity;
+  Lisp_Object entity, name;
 
   entity = font_find_for_lface (f, attrs, spec, -1);
   if (NILP (entity))
@@ -3512,7 +3530,13 @@
       if (NILP (entity))
 	return Qnil;
     }
-  return font_open_for_lface (f, entity, attrs, spec);
+  /* Don't loose the original name that was put in initially.  We need
+     it to re-apply the font when font parameters (like hinting or dpi) have
+     changed.  */
+  entity = font_open_for_lface (f, entity, attrs, spec);
+  name = Ffont_get (spec, QCname);
+  if (STRINGP (name)) font_put_extra (entity, QCname, name);
+  return entity;
 }
 
 
--- a/src/font.h	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/font.h	Tue Nov 17 08:21:23 2009 +0000
@@ -687,6 +687,8 @@
      the (N-1)th element of VARIATIONS.  */
   int (*get_variation_glyphs) P_ ((struct font *font,
 				   int c, unsigned variations[256]));
+
+  void (*filter_properties) P_ ((Lisp_Object font, Lisp_Object properties));
 };
 
 
--- a/src/frame.c	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/frame.c	Tue Nov 17 08:21:23 2009 +0000
@@ -3359,7 +3359,7 @@
      struct frame *f;
      Lisp_Object arg, oldval;
 {
-  Lisp_Object frame, font_object, lval;
+  Lisp_Object frame, font_object;
   int fontset = -1;
 
   /* Set the frame parameter back to the old value because we may
@@ -3427,7 +3427,6 @@
   if (! NILP (Fequal (font_object, oldval)))
     return;
 
-
   x_new_font (f, font_object, fontset);
   store_frame_param (f, Qfont, arg);
   /* Recalculate toolbar height.  */
--- a/src/ftfont.c	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/ftfont.c	Tue Nov 17 08:21:23 2009 +0000
@@ -86,6 +86,8 @@
 static Lisp_Object ftfont_lookup_cache P_ ((Lisp_Object,
 					    enum ftfont_cache_for));
 
+static void ftfont_filter_properties P_ ((Lisp_Object font, Lisp_Object alist));
+                                                
 Lisp_Object ftfont_font_format P_ ((FcPattern *, Lisp_Object));
 
 #define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM))
@@ -545,10 +547,12 @@
     NULL,			/* check */
 
 #ifdef HAVE_OTF_GET_VARIATION_GLYPHS
-    ftfont_variation_glyphs
+    ftfont_variation_glyphs,
 #else
-    NULL
+    NULL,
 #endif
+
+    ftfont_filter_properties, /* filter_properties */
   };
 
 extern Lisp_Object QCname;
@@ -2226,7 +2230,94 @@
   return intern ("unknown");
 }
 
-
+static const char *ftfont_booleans [] = {
+  ":antialias",
+  ":hinting",
+  ":verticallayout",
+  ":autohint",
+  ":globaladvance",
+  ":outline",
+  ":scalable",
+  ":minspace",
+  ":embolden",
+  NULL,
+};
+
+static const char *ftfont_non_booleans [] = {
+  ":family",
+  ":familylang",
+  ":style",
+  ":stylelang",
+  ":fullname",
+  ":fullnamelang",
+  ":slant",
+  ":weight",
+  ":size",
+  ":width",
+  ":aspect",
+  ":pixelsize",
+  ":spacing",
+  ":foundry",
+  ":hintstyle",
+  ":file",
+  ":index",
+  ":ftface",
+  ":rasterizer",
+  ":scale",
+  ":dpi",
+  ":rgba",
+  ":lcdfilter",
+  ":charset",
+  ":lang",
+  ":fontversion",
+  ":capability",
+  NULL,
+};
+
+static void
+ftfont_filter_properties (font, alist)
+     Lisp_Object font;
+     Lisp_Object alist;
+{
+  Lisp_Object it;
+  int i;
+
+  /* Set boolean values to Qt or Qnil */
+  for (i = 0; ftfont_booleans[i] != NULL; ++i)
+    for (it = alist; ! NILP (it); it = XCDR (it))
+      {
+        Lisp_Object key = XCAR (XCAR (it));
+        Lisp_Object val = XCDR (XCAR (it));
+        char *keystr = SDATA (SYMBOL_NAME (key));
+
+        if (strcmp (ftfont_booleans[i], keystr) == 0)
+          {
+            char *str = SYMBOLP (val) ? SDATA (SYMBOL_NAME (val)) : NULL;
+            if (INTEGERP (val)) str = XINT (val) != 0 ? "true" : "false";
+            if (str == NULL) str = "true";
+
+            val = Qt;
+            if (strcmp ("false", str) == 0 || strcmp ("False", str) == 0
+                || strcmp ("FALSE", str) == 0 || strcmp ("FcFalse", str) == 0
+                || strcmp ("off", str) == 0 || strcmp ("OFF", str) == 0
+                || strcmp ("Off", str) == 0)
+              val = Qnil;
+            Ffont_put (font, key, val);
+          }
+      }
+
+  for (i = 0; ftfont_non_booleans[i] != NULL; ++i)
+    for (it = alist; ! NILP (it); it = XCDR (it))
+      {
+        Lisp_Object key = XCAR (XCAR (it));
+        Lisp_Object val = XCDR (XCAR (it));
+        char *keystr = SDATA (SYMBOL_NAME (key));
+        if (strcmp (ftfont_non_booleans[i], keystr) == 0)
+          Ffont_put (font, key, val);
+      }
+}
+
+
 void
 syms_of_ftfont ()
 {
--- a/src/keyboard.c	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/keyboard.c	Tue Nov 17 08:21:23 2009 +0000
@@ -489,6 +489,8 @@
 #ifdef HAVE_DBUS
 Lisp_Object Qdbus_event;
 #endif
+Lisp_Object Qconfig_changed_event;
+
 /* Lisp_Object Qmouse_movement; - also an event header */
 
 /* Properties of event headers.  */
@@ -4283,6 +4285,11 @@
 	  kbd_fetch_ptr = event + 1;
 	}
 #endif
+      else if (event->kind == CONFIG_CHANGED_EVENT)
+	{
+	  obj = make_lispy_event (event);
+	  kbd_fetch_ptr = event + 1;
+	}
       else
 	{
 	  /* If this event is on a different frame, return a switch-frame this
@@ -6196,6 +6203,10 @@
       }
 #endif /* HAVE_DBUS */
 
+    case CONFIG_CHANGED_EVENT:
+	return Fcons (Qconfig_changed_event,
+                      Fcons (event->arg,
+                             Fcons (event->frame_or_window, Qnil)));
 #ifdef HAVE_GPM
     case GPM_CLICK_EVENT:
       {
@@ -11805,6 +11816,9 @@
   staticpro (&Qdbus_event);
 #endif
 
+  Qconfig_changed_event = intern_c_string ("config-changed-event");
+  staticpro (&Qconfig_changed_event);
+
   Qmenu_enable = intern_c_string ("menu-enable");
   staticpro (&Qmenu_enable);
   QCenable = intern_c_string (":enable");
@@ -12547,6 +12561,9 @@
   initial_define_lispy_key (Vspecial_event_map, "dbus-event",
 			    "dbus-handle-event");
 #endif
+
+  initial_define_lispy_key (Vspecial_event_map, "config-changed-event",
+			    "ignore");
 }
 
 /* Mark the pointers in the kboard objects.
--- a/src/lisp.h	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/lisp.h	Tue Nov 17 08:21:23 2009 +0000
@@ -2643,6 +2643,9 @@
 extern int pos_visible_p P_ ((struct window *, int, int *,
 			      int *, int *, int *, int *, int *));
 
+/* Defined in xsettings.c */
+extern void syms_of_xsettings P_ ((void));
+
 /* Defined in vm-limit.c.  */
 extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ()));
 
--- a/src/termhooks.h	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/termhooks.h	Tue Nov 17 08:21:23 2009 +0000
@@ -184,6 +184,8 @@
   , DBUS_EVENT
 #endif
 
+  , CONFIG_CHANGED_EVENT
+
 #ifdef WINDOWSNT
   /* Generated when an APPCOMMAND event is received, in response to
      Multimedia or Internet buttons on some keyboards.
--- a/src/w32font.c	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/w32font.c	Tue Nov 17 08:21:23 2009 +0000
@@ -2472,7 +2472,10 @@
     NULL, /* otf_drive */
     NULL, /* start_for_frame */
     NULL, /* end_for_frame */
-    NULL  /* shape */
+    NULL, /* shape */
+    NULL, /* check */
+    NULL, /* get_variation_glyphs */
+    NULL, /* filter_properties */
   };
 
 
--- a/src/xfns.c	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/xfns.c	Tue Nov 17 08:21:23 2009 +0000
@@ -98,6 +98,8 @@
 #include <Xm/FileSB.h>
 #endif
 
+#include "xsettings.h"
+
 #if !defined(NO_EDITRES)
 #define HACK_EDITRES
 extern void _XEditResCheckMessages ();
@@ -3025,13 +3027,19 @@
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
-				RES_TYPE_STRING);
+                                      RES_TYPE_STRING);
   Lisp_Object font;
+  int got_from_gconf = 0;
   if (EQ (font_param, Qunbound))
-    font_param = Qnil;
+    {
+      font_param = Qnil;
+      font_param = Ffont_get_system_font();
+      got_from_gconf = !NILP (font_param);
+    }
+
   font = !NILP (font_param) ? font_param
     : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
-
+  
   if (! STRINGP (font))
     {
       char *names[]
@@ -3068,7 +3076,11 @@
 	 we've applied the `default' face settings.  */
       x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
     }
-  x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
+
+  x_default_parameter (f, parms, Qfont, font,
+                       got_from_gconf ? NULL : "font",
+                       got_from_gconf ? NULL : "Font",
+                       RES_TYPE_STRING);
 }
 
 
@@ -5569,10 +5581,10 @@
 {
   FRAME_PTR f = check_x_frame (frame);
   char *name;
-  Lisp_Object default_font, font = Qnil;
+  Lisp_Object font;
   Lisp_Object font_param;
   char *default_name = NULL;
-  struct gcpro gcpro1;
+  struct gcpro gcpro1, gcpro2;
   int count = SPECPDL_INDEX ();
 
   check_x ();
@@ -5586,21 +5598,22 @@
 
   BLOCK_INPUT;
 
-  GCPRO1(font_param);
-  font_param = Fframe_parameter (frame, Qfont_param);
-
-  if (x_last_font_name != NULL)
-    default_name = x_last_font_name;
-  else if (STRINGP (font_param))
+  GCPRO2(font_param, font);
+
+  XSETFONT (font, FRAME_FONT (f));
+  font_param = Ffont_get (font, intern_c_string (":name"));
+  if (STRINGP (font_param))
     default_name = SDATA (font_param);
-  else if (FONTP (default_font))
+  else 
     {
-      XSETFONT (default_font, FRAME_FONT (f));
-      default_name = alloca (256);
-      if (font_unparse_gtkname (default_font, f, default_name, 256) < 0)
-	default_name = NULL;
+      font_param = Fframe_parameter (frame, Qfont_param);
+      if (STRINGP (font_param))
+        default_name = SDATA (font_param);
     }
 
+  if (default_name == NULL && x_last_font_name != NULL)
+    default_name = x_last_font_name;
+
   name = xg_get_font_name (f, default_name);
 
   if (name)
--- a/src/xfont.c	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/xfont.c	Tue Nov 17 08:21:23 2009 +0000
@@ -151,7 +151,9 @@
     xfont_text_extents,
     xfont_draw,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    xfont_check
+    xfont_check,
+    NULL, /* get_variation_glyphs */
+    NULL, /* filter_properties */
   };
 
 extern Lisp_Object QCname;
--- a/src/xftfont.c	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/xftfont.c	Tue Nov 17 08:21:23 2009 +0000
@@ -184,6 +184,53 @@
 
 static FcChar8 ascii_printable[95];
 
+static void
+xftfont_fix_match (pat, match)
+     FcPattern *pat, *match;
+{
+  /*  These values are not used for matching (except antialias), but for
+      rendering, so make sure they are carried over to the match.
+      We also put antialias here because most fonts are antialiased, so
+      the match will have antialias true.  */
+
+  FcBool b = FcTrue;
+  int i;
+  double dpi;
+
+  FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b);
+  if (! b) 
+    {
+      FcPatternDel (match, FC_ANTIALIAS);
+      FcPatternAddBool (match, FC_ANTIALIAS, FcFalse);
+    }
+  FcPatternGetBool (pat, FC_HINTING, 0, &b);
+  if (! b) 
+    {
+      FcPatternDel (match, FC_HINTING);
+      FcPatternAddBool (match, FC_HINTING, FcFalse);
+    }
+  if (FcResultMatch == FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &i))
+    {
+      FcPatternDel (match, FC_HINT_STYLE);
+      FcPatternAddInteger (match, FC_HINT_STYLE, i);
+    }
+  if (FcResultMatch == FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &i))
+    {
+      FcPatternDel (match, FC_LCD_FILTER);
+      FcPatternAddInteger (match, FC_LCD_FILTER, i);
+    }
+  if (FcResultMatch == FcPatternGetInteger (pat, FC_RGBA, 0, &i))
+    {
+      FcPatternDel (match, FC_RGBA);
+      FcPatternAddInteger (match, FC_RGBA, i);
+    }
+  if (FcResultMatch == FcPatternGetDouble (pat, FC_DPI, 0, &dpi))
+    {
+      FcPatternDel (match, FC_DPI);
+      FcPatternAddDouble (match, FC_DPI, dpi);
+    }
+}
+
 static Lisp_Object
 xftfont_open (f, entity, pixel_size)
      FRAME_PTR f;
@@ -249,7 +296,7 @@
 
       key = XCAR (XCAR (tail)), val = XCDR (XCAR (tail));
       if (EQ (key, QCantialias))
-	FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue);
+          FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue);
       else if (EQ (key, QChinting))
 	FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue);
       else if (EQ (key, QCautohint))
@@ -285,7 +332,12 @@
     int event_base, error_base;
     XRenderQueryExtension (display, &event_base, &error_base);
   }
+
+  /* Substitute in values from X resources and XftDefaultSet.  */
+  XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat);
   match = XftFontMatch (display, FRAME_X_SCREEN_NUMBER (f), pat, &result);
+  xftfont_fix_match (pat, match);
+  
   FcPatternDestroy (pat);
   xftfont = XftFontOpenPattern (display, match);
   if (!xftfont)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/xsettings.c	Tue Nov 17 08:21:23 2009 +0000
@@ -0,0 +1,627 @@
+/* Functions for handle font changes dynamically.
+   Copyright (C) 2009
+                 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include <setjmp.h>
+#include <fcntl.h>
+#include "lisp.h"
+#include "xterm.h"
+#include "xsettings.h"
+#include "frame.h"
+#include "blockinput.h"
+#include "termhooks.h"
+#include "termopts.h"
+
+#include <X11/Xproto.h>
+
+#ifdef HAVE_GCONF
+#include <gconf/gconf-client.h>
+#endif
+#ifdef HAVE_XFT
+#include <X11/Xft/Xft.h>
+#endif
+
+static char *current_mono_font;
+static struct x_display_info *first_dpyinfo;
+static Lisp_Object Qfont_name, Qfont_render;
+
+#ifdef HAVE_GCONF
+static GConfClient *gconf_client;
+#endif
+
+
+static void
+store_font_changed_event (arg, display_name)
+     Lisp_Object arg;
+     Lisp_Object display_name;
+{
+  struct input_event event;
+  EVENT_INIT (event);
+  event.kind = CONFIG_CHANGED_EVENT;
+  event.frame_or_window = display_name;
+  event.arg = arg;
+  kbd_buffer_store_event (&event);
+}
+
+#ifdef HAVE_GCONF
+
+#define SYSTEM_MONO_FONT       "/desktop/gnome/interface/monospace_font_name"
+
+/* Callback called when something changed in GConf that we care about,
+   that is SYSTEM_MONO_FONT.  */
+
+static void
+something_changedCB (client, cnxn_id, entry, user_data)
+     GConfClient *client;
+     guint cnxn_id;
+     GConfEntry *entry;
+     gpointer user_data;
+{
+  GConfValue *v = gconf_entry_get_value (entry);
+  
+  if (!v) return;
+  if (v->type == GCONF_VALUE_STRING)
+    {
+      const char *value = gconf_value_get_string (v);
+      int i;
+      if (current_mono_font != NULL && strcmp (value, current_mono_font) == 0)
+        return; // No change.
+
+      xfree (current_mono_font);
+      current_mono_font = xstrdup (value);
+    }
+
+
+  if (first_dpyinfo != NULL)
+    {
+      /* Check if display still open */
+      struct x_display_info *dpyinfo;
+      int found = 0;
+      for (dpyinfo = x_display_list; !found && dpyinfo; dpyinfo = dpyinfo->next)
+        found = dpyinfo == first_dpyinfo;
+
+      if (found)
+        store_font_changed_event (Qfont_name,
+                                  XCAR (first_dpyinfo->name_list_element));
+    }
+}
+#endif /* HAVE_GCONF */
+
+#ifdef HAVE_XFT
+
+/* Find the window that contains the XSETTINGS property values.  */
+
+static void
+get_prop_window (dpyinfo)
+     struct x_display_info *dpyinfo;
+{
+  Display *dpy = dpyinfo->display;
+
+  XGrabServer (dpy);
+  dpyinfo->xsettings_window = XGetSelectionOwner (dpy,
+                                                  dpyinfo->Xatom_xsettings_sel);
+  if (dpyinfo->xsettings_window != None)
+    /* Select events so we can detect if window is deleted or if settings
+       are changed.  */
+    XSelectInput (dpy, dpyinfo->xsettings_window,
+                  PropertyChangeMask|StructureNotifyMask);
+
+  XUngrabServer (dpy);
+}
+
+struct xsettings 
+{
+  FcBool aa, hinting;
+  int rgba, lcdfilter, hintstyle;
+  double dpi;
+};
+
+#define SWAP32(nr) (((nr) << 24) | (((nr) << 8) & 0xff0000)     \
+                    | (((nr) >> 8) & 0xff00) | ((nr) >> 24))
+#define SWAP16(nr) (((nr) << 8) | ((nr) >> 8))
+#define PAD(nr)    (((nr) + 3) & ~3)
+
+/* Parse xsettings and extract those that deal with Xft.
+   See http://freedesktop.org/wiki/Specifications/XSettingsRegistry
+   and http://standards.freedesktop.org/xsettings-spec/xsettings-spec-0.5.html.
+
+   Layout of prop.  First is a header:
+
+   bytes   type     what
+   ------------------------------------
+   1      CARD8    byte-order
+   3               unused
+   4      CARD32   SERIAL
+   4      CARD32   N_SETTINGS
+
+   Then N_SETTINGS records, with header:
+
+   bytes   type          what
+   ------------------------------------
+   1      SETTING_TYPE  type (0 = integer, 1 = string, 2 RGB color).
+   1                    unused
+   2      CARD16        n == name-length
+   n      STRING8       name
+   p                    unused, p=pad_to_even_4(n)
+   4      CARD32        last-change-serial
+
+   and then the value, For string:
+   
+   bytes   type          what
+   ------------------------------------
+   4      CARD32        n = value-length
+   n      STRING8       value
+   p                    unused, p=pad_to_even_4(n)
+
+   For integer:
+
+   bytes   type          what
+   ------------------------------------
+   4      INT32         value
+
+   For RGB color:
+
+   bytes   type          what
+   ------------------------------------
+   2      CARD16        red
+   2      CARD16        blue
+   2      CARD16        green
+   2      CARD16        alpha
+
+*/
+
+static int
+parse_xft_settings (prop, bytes, settings)
+     unsigned char *prop;
+     unsigned long bytes;
+     struct xsettings *settings;
+{
+  Lisp_Object byteorder = Fbyteorder ();
+  int my_bo = XFASTINT (byteorder) == 'B' ? MSBFirst : LSBFirst;
+  int that_bo = prop[0];
+  CARD32 n_settings;
+  int bytes_parsed = 0;
+  int settings_seen = 0;
+  int i = 0;
+
+  /* First 4 bytes is a serial number, skip that.  */
+
+  if (bytes < 12) return BadLength;
+  memcpy (&n_settings, prop+8, 4);
+  if (my_bo != that_bo) n_settings = SWAP32 (n_settings);
+  bytes_parsed = 12;
+
+  memset (settings, 0, sizeof (*settings));
+
+  while (bytes_parsed+4 < bytes && settings_seen < 6
+         && i < n_settings)
+    {
+      int type = prop[bytes_parsed++];
+      CARD16 nlen;
+      CARD32 vlen, ival = 0;
+      char name[128]; /* The names we are looking for are not this long.  */
+      char sval[128]; /* The values we are looking for are not this long.  */
+      int is_xft;
+      int to_cpy;
+
+      sval[0] = '\0';
+      ++i;
+      ++bytes_parsed; /* Padding */
+
+      memcpy (&nlen, prop+bytes_parsed, 2);
+      bytes_parsed += 2;
+      if (my_bo != that_bo) nlen = SWAP16 (nlen);
+      if (bytes_parsed+nlen > bytes) return BadLength;
+      to_cpy = nlen > 127 ? 127 : nlen;
+      memcpy (name, prop+bytes_parsed, to_cpy);
+      name[to_cpy] = '\0';
+
+      bytes_parsed += nlen;
+      bytes_parsed = PAD (bytes_parsed);
+
+      bytes_parsed += 4; /* Skip serial for this value */
+      if (bytes_parsed > bytes) return BadLength;
+
+      is_xft = nlen > 6 && strncmp (name, "Xft/", 4) == 0;
+
+      switch (type) 
+        {
+        case 0: /* Integer */
+          if (bytes_parsed+4 > bytes) return BadLength;
+          if (is_xft)
+            {
+              memcpy (&ival, prop+bytes_parsed, 4);
+              if (my_bo != that_bo) ival = SWAP32 (ival);
+            }
+          bytes_parsed += 4;
+          break;
+
+        case 1: /* String */
+          if (bytes_parsed+4 > bytes) return BadLength;
+          memcpy (&vlen, prop+bytes_parsed, 4);
+          bytes_parsed += 4;
+          if (my_bo != that_bo) vlen = SWAP32 (vlen);
+          if (is_xft)
+            {
+              to_cpy = vlen > 127 ? 127 : vlen;
+              memcpy (sval, prop+bytes_parsed, to_cpy);
+              sval[to_cpy] = '\0';
+            }
+          bytes_parsed += vlen;
+          bytes_parsed = PAD (bytes_parsed);
+          break;
+
+        case 2: /* RGB value */
+          /* No need to parse this */
+          if (bytes_parsed+8 > bytes) return BadLength;
+          bytes_parsed += 8; /* 4 values (r, b, g, alpha), 2 bytes each.  */ 
+          break;
+
+        default: /* Parse Error */
+          return BadValue;
+        }
+
+      if (is_xft) 
+        {
+          ++settings_seen;
+          if (strcmp (name, "Xft/Antialias") == 0)
+            settings->aa = ival != 0;
+          else if (strcmp (name, "Xft/Hinting") == 0)
+            settings->hinting = ival != 0;
+          else if (strcmp (name, "Xft/HintStyle") == 0)
+            {
+              if (strcmp (sval, "hintnone") == 0)
+                settings->hintstyle = FC_HINT_NONE;
+              else if (strcmp (sval, "hintslight") == 0)
+                settings->hintstyle = FC_HINT_SLIGHT;
+              else if (strcmp (sval, "hintmedium") == 0)
+                settings->hintstyle = FC_HINT_MEDIUM;
+              else if (strcmp (sval, "hintfull") == 0)
+                settings->hintstyle = FC_HINT_FULL;
+            }
+          else if (strcmp (name, "Xft/RGBA") == 0)
+            {
+              if (strcmp (sval, "none") == 0)
+                settings->rgba = FC_RGBA_NONE;
+              else if (strcmp (sval, "rgb") == 0)
+                settings->rgba = FC_RGBA_RGB;
+              else if (strcmp (sval, "bgr") == 0)
+                settings->rgba = FC_RGBA_BGR;
+              else if (strcmp (sval, "vrgb") == 0)
+                settings->rgba = FC_RGBA_VRGB;
+              else if (strcmp (sval, "vbgr") == 0)
+                settings->rgba = FC_RGBA_VBGR;
+            }
+          else if (strcmp (name, "Xft/DPI") == 0)
+            settings->dpi = (double)ival/1024.0;
+          else if (strcmp (name, "Xft/lcdfilter") == 0)
+            {
+              if (strcmp (sval, "none") == 0)
+                settings->lcdfilter = FC_LCD_NONE;
+              else if (strcmp (sval, "lcddefault") == 0)
+                settings->lcdfilter = FC_LCD_DEFAULT;
+            }
+        }
+    }
+
+  return Success;
+}
+
+static int
+read_xft_settings (dpyinfo, settings)
+     struct x_display_info *dpyinfo;
+     struct xsettings *settings;
+{
+  long long_len;
+  Atom act_type;
+  int act_form;
+  unsigned long nitems, bytes_after;
+  unsigned char *prop = NULL;
+  Display *dpy = dpyinfo->display;
+  int rc;
+
+  x_catch_errors (dpy);
+  rc = XGetWindowProperty (dpy,
+                           dpyinfo->xsettings_window,
+                           dpyinfo->Xatom_xsettings_prop,
+                           0, LONG_MAX, False, AnyPropertyType,
+                           &act_type, &act_form, &nitems, &bytes_after,
+                           &prop);
+
+  if (rc == Success && prop != NULL && act_form == 8 && nitems > 0
+      && act_type == dpyinfo->Xatom_xsettings_prop)
+    rc = parse_xft_settings (prop, nitems, settings);
+
+  XFree (prop);
+
+  x_uncatch_errors ();
+
+  return rc == Success;
+}
+
+static void
+apply_xft_settings (dpyinfo, send_event_p)
+     struct x_display_info *dpyinfo;
+     int send_event_p;
+{
+  FcPattern *pat;
+  struct xsettings settings, oldsettings;
+  int changed = 0;
+
+  if (!read_xft_settings (dpyinfo, &settings))
+    return;
+
+  memset (&oldsettings, 0, sizeof (oldsettings));
+
+  pat = FcPatternCreate ();
+  XftDefaultSubstitute (dpyinfo->display,
+                        XScreenNumberOfScreen (dpyinfo->screen),
+                        pat);
+  FcPatternGetBool (pat, FC_ANTIALIAS, 0, &oldsettings.aa);
+  FcPatternGetBool (pat, FC_HINTING, 0, &oldsettings.hinting);
+  FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &oldsettings.hintstyle);
+  FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &oldsettings.lcdfilter);
+  FcPatternGetInteger (pat, FC_RGBA, 0, &oldsettings.rgba);
+  FcPatternGetDouble (pat, FC_DPI, 0, &oldsettings.dpi);
+
+  if (oldsettings.aa != settings.aa)
+    {
+      FcPatternDel (pat, FC_ANTIALIAS);
+      FcPatternAddBool (pat, FC_ANTIALIAS, settings.aa);
+      ++changed;
+    }
+  if (oldsettings.hinting != settings.hinting)
+    {
+      FcPatternDel (pat, FC_HINTING);
+      FcPatternAddBool (pat, FC_HINTING, settings.hinting);
+      ++changed;
+    }
+  if (oldsettings.rgba != settings.rgba)
+    {
+      FcPatternDel (pat, FC_RGBA);
+      FcPatternAddInteger (pat, FC_RGBA, settings.rgba);
+      ++changed;
+    }
+  if (oldsettings.lcdfilter != settings.lcdfilter)
+    {
+      FcPatternDel (pat, FC_LCD_FILTER);
+      FcPatternAddInteger (pat, FC_LCD_FILTER, settings.lcdfilter);
+      ++changed;
+    }
+  if (oldsettings.hintstyle != settings.hintstyle)
+    {
+      FcPatternDel (pat, FC_HINT_STYLE);
+      FcPatternAddInteger (pat, FC_HINT_STYLE, settings.hintstyle);
+      ++changed;
+    }
+  if (oldsettings.dpi != settings.dpi)
+    {
+      Lisp_Object frame, tail;
+
+      FcPatternDel (pat, FC_DPI);
+      FcPatternAddDouble (pat, FC_DPI, settings.dpi);
+      ++changed;
+
+      /* Change the DPI on this display and all frames on the display.  */
+      dpyinfo->resy = dpyinfo->resx = settings.dpi;
+      FOR_EACH_FRAME (tail, frame)
+        if (FRAME_X_P (XFRAME (frame))
+            && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
+          XFRAME (frame)->resy = XFRAME (frame)->resx = settings.dpi;
+    }
+
+  if (changed)
+    {
+      XftDefaultSet (dpyinfo->display, pat);
+      if (send_event_p)
+        store_font_changed_event (Qfont_render,
+                                  XCAR (dpyinfo->name_list_element));
+    }
+  else
+    FcPatternDestroy (pat);
+}
+
+#endif /* HAVE_XFT */
+
+void
+xft_settings_event (dpyinfo, event)
+     struct x_display_info *dpyinfo;
+     XEvent *event;
+{
+#ifdef HAVE_XFT
+  int check_window_p = 0;
+
+  switch (event->type)
+    {
+    case DestroyNotify:
+      if (dpyinfo->xsettings_window == event->xany.window)
+        check_window_p = 1;
+      break;
+
+    case ClientMessage:
+      if (event->xclient.message_type == dpyinfo->Xatom_xsettings_mgr
+          && event->xclient.data.l[1] == dpyinfo->Xatom_xsettings_sel
+          && event->xclient.window == dpyinfo->root_window)
+        check_window_p = 1;
+      break;
+
+    case PropertyNotify:
+      if (event->xproperty.window == dpyinfo->xsettings_window
+          && event->xproperty.state == PropertyNewValue
+          && event->xproperty.atom == dpyinfo->Xatom_xsettings_prop)
+        {
+          apply_xft_settings (dpyinfo, True);
+        }
+      break;
+    }
+
+  if (check_window_p)
+    {
+      dpyinfo->xsettings_window = None;
+      get_prop_window (dpyinfo);
+      if (dpyinfo->xsettings_window != None)
+        apply_xft_settings (dpyinfo, True);
+    }
+#endif /* HAVE_XFT */
+}
+
+
+static void
+init_gconf ()
+{
+#ifdef HAVE_GCONF
+  int i;
+  char *s;
+  /* Should be enough, this is called at startup */
+#define N_FDS 1024
+  int fd_before[N_FDS], fd_before1[N_FDS];
+  int dummy, n_fds;
+  GPollFD gfds[N_FDS];
+
+  /* To find out which filedecriptors GConf uses, check before and after.
+     If we do not do this, GConf changes will only happen when Emacs gets
+     an X event.  */
+  memset (fd_before, 0, sizeof (fd_before));
+  n_fds = g_main_context_query (g_main_context_default (),
+                                G_PRIORITY_LOW,
+                                &dummy,
+                                gfds,
+                                N_FDS);
+  for (i = 0; i < n_fds; ++i)
+    if (gfds[i].fd < N_FDS && gfds[i].fd > 0 && gfds[i].events > 0)
+      fd_before[gfds[i].fd] = 1;
+
+  g_type_init ();
+  gconf_client = gconf_client_get_default ();
+  s = gconf_client_get_string (gconf_client, SYSTEM_MONO_FONT, NULL);
+  if (s)
+    {
+      current_mono_font = xstrdup (s);
+      g_free (s);
+    }
+  gconf_client_set_error_handling (gconf_client, GCONF_CLIENT_HANDLE_NONE);
+  gconf_client_add_dir (gconf_client,
+                        SYSTEM_MONO_FONT,
+                        GCONF_CLIENT_PRELOAD_ONELEVEL,
+                        NULL);
+  gconf_client_notify_add (gconf_client,
+                           SYSTEM_MONO_FONT,
+                           something_changedCB,
+                           NULL, NULL, NULL);
+  n_fds = g_main_context_query (g_main_context_default (),
+                                G_PRIORITY_LOW,
+                                &dummy,
+                                gfds,
+                                N_FDS);
+
+  for (i = 0; i < n_fds; ++i)
+    if (gfds[i].fd < N_FDS && gfds[i].fd > 0 && gfds[i].events > 0
+        && !fd_before[gfds[i].fd])
+      {
+#ifdef F_SETOWN
+        fcntl (i, F_SETOWN, getpid ());
+#endif /* ! defined (F_SETOWN) */
+
+#ifdef SIGIO
+        if (interrupt_input)
+          init_sigio (i);
+#endif /* ! defined (SIGIO) */
+      }
+#endif /* HAVE_GCONF */
+}
+
+static void
+init_xfd_settings (dpyinfo)
+     struct x_display_info *dpyinfo;
+{
+#ifdef HAVE_XFT
+  char sel[64];
+  Display *dpy = dpyinfo->display;
+
+  BLOCK_INPUT;
+
+  sprintf (sel, "_XSETTINGS_S%d", XScreenNumberOfScreen (dpyinfo->screen));
+  dpyinfo->Xatom_xsettings_sel = XInternAtom (dpy, sel, False);
+  dpyinfo->Xatom_xsettings_prop = XInternAtom (dpy,
+                                               "_XSETTINGS_SETTINGS",
+                                               False);
+  dpyinfo->Xatom_xsettings_mgr = XInternAtom (dpy, "MANAGER", False);
+
+  /* Select events so we can detect client messages sent when selection
+     owner changes.  */
+  XSelectInput (dpy, dpyinfo->root_window, StructureNotifyMask);
+
+  get_prop_window (dpyinfo);
+  if (dpyinfo->xsettings_window != None)
+    apply_xft_settings (dpyinfo, False);
+
+  UNBLOCK_INPUT;
+
+#else /* ! HAVE_XFT */
+
+  dpyinfo->Xatom_xsettings_sel = None;
+  dpyinfo->Xatom_xsettings_prop = None;
+  dpyinfo->Xatom_xsettings_mgr = None;
+  dpyinfo->xsettings_window = None;
+
+#endif /* ! HAVE_XFT */
+}
+
+void
+xsettings_initialize (dpyinfo)
+     struct x_display_info *dpyinfo;
+{
+  if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo;
+  init_gconf ();
+  init_xfd_settings (dpyinfo);
+}
+
+
+DEFUN ("font-get-system-font", Ffont_get_system_font, Sfont_get_system_font,
+       0, 0, 0,
+       doc: /* Get the system default monospaced font. */)
+  ()
+{
+  return current_mono_font
+    ? make_string (current_mono_font, strlen (current_mono_font))
+    : Qnil;
+}
+
+void
+syms_of_xsettings ()
+{
+  current_mono_font = NULL;
+  first_dpyinfo = NULL;
+#ifdef HAVE_GCONF
+  gconf_client = NULL;
+#endif
+
+  Qfont_name = intern_c_string ("font-name");
+  staticpro (&Qfont_name);
+  Qfont_render = intern_c_string ("font-render");
+  staticpro (&Qfont_render);
+  defsubr (&Sfont_get_system_font);
+
+#ifdef HAVE_GCONF
+  Fprovide (intern_c_string ("system-font-setting"), Qnil);
+#endif
+#ifdef HAVE_XFT
+  Fprovide (intern_c_string ("font-render-setting"), Qnil);
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/xsettings.h	Tue Nov 17 08:21:23 2009 +0000
@@ -0,0 +1,29 @@
+/* Functions for handle font changes dynamically.
+   Copyright (C) 2009
+                 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef XSETTINGS_H
+#define XSETTINGS_H
+
+extern Lisp_Object Ffont_get_system_font P_ ((void));
+extern void xsettings_initialize P_ ((struct x_display_info *dpyinfo));
+extern void xft_settings_event P_ ((struct x_display_info *dpyinfo,
+                                    XEvent *));
+
+
+#endif /* XSETTINGS_H */
--- a/src/xterm.c	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/xterm.c	Tue Nov 17 08:21:23 2009 +0000
@@ -86,6 +86,7 @@
 #include "keymap.h"
 #include "font.h"
 #include "fontset.h"
+#include "xsettings.h"
 #include "sysselect.h"
 
 #ifdef USE_X_TOOLKIT
@@ -6026,6 +6027,8 @@
             goto done;
           }
 
+        xft_settings_event (dpyinfo, &event);
+
 	f = x_any_window_to_frame (dpyinfo, event.xclient.window);
 	if (!f)
 	  goto OTHER;
@@ -6088,6 +6091,7 @@
         x_handle_net_wm_state (f, &event.xproperty);
 
       x_handle_property_notify (&event.xproperty);
+      xft_settings_event (dpyinfo, &event);
       goto OTHER;
 
     case ReparentNotify:
@@ -6991,6 +6995,10 @@
         }
       goto OTHER;
 
+    case DestroyNotify:
+      xft_settings_event (dpyinfo, &event);
+      break;
+
     default:
     OTHER:
 #ifdef USE_X_TOOLKIT
@@ -10300,17 +10308,33 @@
     dpyinfo->cmap = XCreateColormap (dpyinfo->display, dpyinfo->root_window,
 				     dpyinfo->visual, AllocNone);
 
+#ifdef HAVE_XFT
   {
-    int screen_number = XScreenNumberOfScreen (dpyinfo->screen);
-    double pixels = DisplayHeight (dpyinfo->display, screen_number);
-    double mm = DisplayHeightMM (dpyinfo->display, screen_number);
-    /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
-    dpyinfo->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
-    pixels = DisplayWidth (dpyinfo->display, screen_number);
-    mm = DisplayWidthMM (dpyinfo->display, screen_number);
-    /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
-    dpyinfo->resx = (mm < 1) ? 100 : pixels * 25.4 / mm;
+    /* If we are using Xft, check dpi value in X resources.
+       It is better we use it as well, since Xft will use it, as will all
+       Gnome applications.  If our real DPI is smaller or larger than the
+       one Xft uses, our font will look smaller or larger than other
+       for other applications, even if it is the same font name (monospace-10
+       for example).  */
+    char *v = XGetDefault (dpyinfo->display, "Xft", "dpi");
+    double d;
+    if (v != NULL && sscanf (v, "%lf", &d) == 1)
+      dpyinfo->resy = dpyinfo->resx = d;
   }
+#endif
+
+  if (dpyinfo->resy < 1)
+    {
+      int screen_number = XScreenNumberOfScreen (dpyinfo->screen);
+      double pixels = DisplayHeight (dpyinfo->display, screen_number);
+      double mm = DisplayHeightMM (dpyinfo->display, screen_number);
+      /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
+      dpyinfo->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
+      pixels = DisplayWidth (dpyinfo->display, screen_number);
+      mm = DisplayWidthMM (dpyinfo->display, screen_number);
+      /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
+      dpyinfo->resx = (mm < 1) ? 100 : pixels * 25.4 / mm;
+    }
 
   dpyinfo->Xatom_wm_protocols
     = XInternAtom (dpyinfo->display, "WM_PROTOCOLS", False);
@@ -10415,6 +10439,8 @@
   xim_initialize (dpyinfo, resource_name);
 #endif
 
+  xsettings_initialize (dpyinfo);
+
 #ifdef subprocesses
   /* This is only needed for distinguishing keyboard and process input.  */
   if (connection != 0)
--- a/src/xterm.h	Tue Nov 17 04:44:58 2009 +0000
+++ b/src/xterm.h	Tue Nov 17 08:21:23 2009 +0000
@@ -364,6 +364,10 @@
   Atom Xatom_net_wm_state, Xatom_net_wm_state_fullscreen_atom,
     Xatom_net_wm_state_maximized_horz, Xatom_net_wm_state_maximized_vert,
     Xatom_net_wm_state_sticky;
+
+  /* XSettings atoms and windows.  */
+  Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr;
+  Window xsettings_window;
 };
 
 #ifdef HAVE_X_I18N