mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-02-01 20:06:00 +00:00
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.
This commit is contained in:
parent
77fd3e0c13
commit
637fa98808
@ -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.
|
||||
|
118
configure
vendored
118
configure
vendored
@ -716,6 +716,8 @@ GTK_CFLAGS
|
||||
GTK_LIBS
|
||||
DBUS_CFLAGS
|
||||
DBUS_LIBS
|
||||
GCONF_CFLAGS
|
||||
GCONF_LIBS
|
||||
FONTCONFIG_CFLAGS
|
||||
FONTCONFIG_LIBS
|
||||
XFT_CFLAGS
|
||||
@ -791,6 +793,7 @@ with_xim
|
||||
with_ns
|
||||
with_gpm
|
||||
with_dbus
|
||||
with_gconf
|
||||
with_makeinfo
|
||||
with_gtk
|
||||
with_gcc
|
||||
@ -1499,6 +1502,7 @@ Optional Packages:
|
||||
--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 @@ else
|
||||
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 @@ done
|
||||
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 -lpng? ${HAVE_PNG}"
|
||||
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}"
|
||||
|
12
configure.in
12
configure.in
@ -144,6 +144,7 @@ OPTION_DEFAULT_OFF([ns],[use nextstep (Cocoa or GNUstep) windowing system])
|
||||
|
||||
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 @@ if test "${with_dbus}" = "yes"; then
|
||||
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 -lpng? ${HAVE_PNG}"
|
||||
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}"
|
||||
|
@ -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.
|
||||
|
12
etc/NEWS
12
etc/NEWS
@ -78,6 +78,18 @@ frame parameter fullscreen makes the Emacs frame maximized.
|
||||
** 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',
|
||||
|
@ -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.
|
||||
|
@ -680,6 +680,7 @@ ELCFILES = \
|
||||
$(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 \
|
||||
|
109
lisp/font-setting.el
Normal file
109
lisp/font-setting.el
Normal file
@ -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)
|
@ -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")
|
||||
|
@ -660,6 +660,8 @@ by \"Save Options\" in Custom buffers.")
|
||||
(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 @@ by \"Save Options\" in Custom buffers.")
|
||||
: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"))
|
||||
|
@ -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
|
||||
|
@ -248,6 +248,11 @@ DBUS_LIBS = @DBUS_LIBS@
|
||||
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 @@ DBUS_OBJ = dbusbind.o
|
||||
|
||||
/* 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 @@ ALL_OBJC_CFLAGS=$(ALL_CFLAGS) @GNU_OBJC_CFLAGS@
|
||||
|
||||
#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 @@ SOME_MACHINE_LISP = ../lisp/mouse.elc \
|
||||
|
||||
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 @@ xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
|
||||
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 @@ xmenu.o: xmenu.c xterm.h termhooks.h window.h dispextern.h frame.h buffer.h \
|
||||
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 \
|
||||
|
@ -201,6 +201,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* 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
|
||||
|
||||
|
@ -1669,6 +1669,7 @@ main (int argc, char **argv)
|
||||
syms_of_xfns ();
|
||||
syms_of_xmenu ();
|
||||
syms_of_fontset ();
|
||||
syms_of_xsettings ();
|
||||
#ifdef HAVE_X_SM
|
||||
syms_of_xsmfns ();
|
||||
#endif
|
||||
@ -1749,7 +1750,7 @@ main (int argc, char **argv)
|
||||
#endif
|
||||
init_window ();
|
||||
init_font ();
|
||||
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
char *file;
|
||||
|
40
src/font.c
40
src/font.c
@ -718,8 +718,6 @@ font_put_extra (font, prop, val)
|
||||
{
|
||||
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 @@ font_parse_fcname (name, font)
|
||||
|
||||
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 @@ font_parse_fcname (name, font)
|
||||
|
||||
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 @@ font_open_entity (f, entity, pixel_size)
|
||||
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 @@ font_clear_prop (attrs, prop)
|
||||
|
||||
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 @@ font_find_for_lface (f, attrs, spec, c)
|
||||
val = font_select_entity (frame, entities,
|
||||
attrs, pixel_size, c);
|
||||
if (! NILP (val))
|
||||
return val;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3500,7 +3518,7 @@ font_load_for_lface (f, attrs, spec)
|
||||
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 @@ font_load_for_lface (f, attrs, spec)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -687,6 +687,8 @@ struct font_driver
|
||||
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));
|
||||
};
|
||||
|
||||
|
||||
|
@ -3359,7 +3359,7 @@ x_set_font (f, arg, oldval)
|
||||
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 @@ x_set_font (f, arg, oldval)
|
||||
if (! NILP (Fequal (font_object, oldval)))
|
||||
return;
|
||||
|
||||
|
||||
x_new_font (f, font_object, fontset);
|
||||
store_frame_param (f, Qfont, arg);
|
||||
/* Recalculate toolbar height. */
|
||||
|
97
src/ftfont.c
97
src/ftfont.c
@ -86,6 +86,8 @@ static Lisp_Object ftfont_resolve_generic_family P_ ((Lisp_Object,
|
||||
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 @@ struct font_driver ftfont_driver =
|
||||
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 @@ ftfont_font_format (FcPattern *pattern, Lisp_Object filename)
|
||||
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 ()
|
||||
{
|
||||
|
@ -489,6 +489,8 @@ Lisp_Object Qsave_session;
|
||||
#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_buffer_get_event (kbp, used_mouse_menu, end_time)
|
||||
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 @@ make_lispy_event (event)
|
||||
}
|
||||
#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 @@ syms_of_keyboard ()
|
||||
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 @@ keys_of_keyboard ()
|
||||
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.
|
||||
|
@ -2643,6 +2643,9 @@ extern Lisp_Object safe_eval P_ ((Lisp_Object));
|
||||
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) ()));
|
||||
|
||||
|
@ -184,6 +184,8 @@ enum event_kind
|
||||
, 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.
|
||||
|
@ -2472,7 +2472,10 @@ struct font_driver w32font_driver =
|
||||
NULL, /* otf_drive */
|
||||
NULL, /* start_for_frame */
|
||||
NULL, /* end_for_frame */
|
||||
NULL /* shape */
|
||||
NULL, /* shape */
|
||||
NULL, /* check */
|
||||
NULL, /* get_variation_glyphs */
|
||||
NULL, /* filter_properties */
|
||||
};
|
||||
|
||||
|
||||
|
45
src/xfns.c
45
src/xfns.c
@ -98,6 +98,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include <Xm/FileSB.h>
|
||||
#endif
|
||||
|
||||
#include "xsettings.h"
|
||||
|
||||
#if !defined(NO_EDITRES)
|
||||
#define HACK_EDITRES
|
||||
extern void _XEditResCheckMessages ();
|
||||
@ -3025,13 +3027,19 @@ x_default_font_parameter (f, parms)
|
||||
{
|
||||
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 @@ x_default_font_parameter (f, parms)
|
||||
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 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
|
||||
{
|
||||
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 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
|
||||
|
||||
BLOCK_INPUT;
|
||||
|
||||
GCPRO1(font_param);
|
||||
font_param = Fframe_parameter (frame, Qfont_param);
|
||||
GCPRO2(font_param, font);
|
||||
|
||||
if (x_last_font_name != NULL)
|
||||
default_name = x_last_font_name;
|
||||
else if (STRINGP (font_param))
|
||||
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)
|
||||
|
@ -151,7 +151,9 @@ struct font_driver xfont_driver =
|
||||
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;
|
||||
|
@ -184,6 +184,53 @@ extern Lisp_Object QCantialias;
|
||||
|
||||
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 @@ xftfont_open (f, entity, pixel_size)
|
||||
|
||||
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 @@ xftfont_open (f, entity, pixel_size)
|
||||
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)
|
||||
|
627
src/xsettings.c
Normal file
627
src/xsettings.c
Normal file
@ -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
|
||||
}
|
29
src/xsettings.h
Normal file
29
src/xsettings.h
Normal file
@ -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 */
|
44
src/xterm.c
44
src/xterm.c
@ -86,6 +86,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "keymap.h"
|
||||
#include "font.h"
|
||||
#include "fontset.h"
|
||||
#include "xsettings.h"
|
||||
#include "sysselect.h"
|
||||
|
||||
#ifdef USE_X_TOOLKIT
|
||||
@ -6026,6 +6027,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
|
||||
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 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
|
||||
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 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
|
||||
}
|
||||
goto OTHER;
|
||||
|
||||
case DestroyNotify:
|
||||
xft_settings_event (dpyinfo, &event);
|
||||
break;
|
||||
|
||||
default:
|
||||
OTHER:
|
||||
#ifdef USE_X_TOOLKIT
|
||||
@ -10300,17 +10308,33 @@ x_term_init (display_name, xrm_option, resource_name)
|
||||
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 @@ x_term_init (display_name, xrm_option, resource_name)
|
||||
xim_initialize (dpyinfo, resource_name);
|
||||
#endif
|
||||
|
||||
xsettings_initialize (dpyinfo);
|
||||
|
||||
#ifdef subprocesses
|
||||
/* This is only needed for distinguishing keyboard and process input. */
|
||||
if (connection != 0)
|
||||
|
@ -364,6 +364,10 @@ struct x_display_info
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user