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