summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Djärv <jan.h.d@swipnet.se>2010-04-08 18:20:32 +0200
committerJan Djärv <jan.h.d@swipnet.se>2010-04-08 18:20:32 +0200
commit99852628a828979c55c96d7def6c5a21f2b32af5 (patch)
tree31090fefe3468ad6d12495d2e65596dc939b41d2
parent9a15cc5a6837f39eaefd28ab607fc39dffcc11b3 (diff)
downloademacs-99852628a828979c55c96d7def6c5a21f2b32af5.tar.gz
Lucid menus can now use Xft for fonts.
* xsettings.c (current_font, SYSTEM_FONT, XSETTINGS_FONT_NAME): New. (parse_xft_settings): Also check for XSETTINGS_FONT_NAME and save that in current_font. (init_gconf): Read value of SYSTEM_FONT and save it in current_font. (Ffont_get_system_normal_font, xsettings_get_system_normal_font): New functions. (syms_of_xsettings): Initialize current_font. defsubr Sfont_get_system_normal_font. * xsettings.h (Ffont_get_system_normal_font, xsettings_get_system_normal_font): Declare. * xfns.c (extern xlwmenu_default_font): Remove. (Fx_create_frame): Remove setting of xlwmenu_default_font, moved to xlwmenu.c. * menu.c (digest_single_submenu): If USE_LUCID and HAVE_XFT, encode menu items in UTF-8. * xmenu.c: include xsettings.h and xlwmenu.h if USE_LUCID. (apply_systemfont_to_menu): New function. (set_frame_menubar, create_and_show_popup_menu): Call apply_systemfont_to_menu. * xlwmenu.c (xlwmenu_default_font): Make static. (xlwMenuResources): Add XtNfaceName and XtNdefaultFace. (string_width): Use XftTextExtentsUtf8 if HAVE_XFT. (MENU_FONT_HEIGHT, MENU_FONT_ASCENT): Add versions for HAVE_XFT. (size_menu): Set max_rest_width in window_state structure. (display_menu_item): If HAVE_XFT and xft_draw is set, use XftDrawRect and XftDrawStringUtf8 to draw text. (make_windows_if_needed): Set max_rest_width and xft_draw in windows[i]. (openXftFont): New. (XlwMenuInitialize): Call openXftFont if HAVE_XFT. If mw->menu.font is not set, load font fixed and save it in xlwmenu_default_font. (XlwMenuInitialize): Set max_rest_width and xft_draw in windows[0]. (XlwMenuClassInitialize): Initialize xlwmenu_default_font. (XlwMenuRealize): Set xft_fg, xft_bg, xft_disabled_fg and windows[0].xft_draw if xft_font is set. (XlwMenuDestroy): Destroy all xft_draw and close xft_font. (facename_changed): New. (XlwMenuSetValues): Call facename_changed. If face name did change, close old fonts and destroy xft_draw:s. Then create new ones. * xlwmenu.h (XtNfaceName, XtCFaceName, XtNdefaultFace, XtCDefaultFace): New. * xlwmenuP.h (_window_state): Add max_rest_width and xft_draw. (_XlwMenu_part): Add faceName,xft_fg, xft_bg, xft_disabled_fg and xft_font. * xresources.texi (Lucid Resources): Mention faceName to set Xft fonts.
-rw-r--r--doc/emacs/ChangeLog4
-rw-r--r--doc/emacs/xresources.texi43
-rw-r--r--etc/NEWS2
-rw-r--r--lwlib/ChangeLog31
-rw-r--r--lwlib/xlwmenu.c242
-rw-r--r--lwlib/xlwmenu.h4
-rw-r--r--lwlib/xlwmenuP.h13
-rw-r--r--src/ChangeLog26
-rw-r--r--src/menu.c18
-rw-r--r--src/xfns.c13
-rw-r--r--src/xmenu.c35
-rw-r--r--src/xsettings.c48
-rw-r--r--src/xsettings.h3
13 files changed, 441 insertions, 41 deletions
diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog
index c0a0539a018..8cb082d64e2 100644
--- a/doc/emacs/ChangeLog
+++ b/doc/emacs/ChangeLog
@@ -1,3 +1,7 @@
+2010-04-08 Jan Djärv <jan.h.d@swipnet.se>
+
+ * xresources.texi (Lucid Resources): Mention faceName to set Xft fonts.
+
2010-03-30 Eli Zaretskii <eliz@gnu.org>
* mule.texi (Input Methods): Mention "C-x 8 RET" and add a
diff --git a/doc/emacs/xresources.texi b/doc/emacs/xresources.texi
index 75b6e3bbe4c..4e4f3ad87a2 100644
--- a/doc/emacs/xresources.texi
+++ b/doc/emacs/xresources.texi
@@ -415,7 +415,7 @@ Emacs.pane.menubar.@var{resource}: @var{value}
@end example
@noindent
-For example, to specify the font @samp{8x16} for the menu-bar items,
+For example, to specify the font @samp{Courier-12} for the menu-bar items,
write this:
@end ifnottex
@iftex
@@ -423,32 +423,35 @@ write this:
with the Lucid menu widgets, then the menu bar is a separate widget
and has its own resources. The resource specifications start with
@samp{Emacs.pane.menubar}---for instance, to specify the font
-@samp{8x16} for the menu-bar items, write this:
+@samp{Courier-12} for the menu-bar items, write this:
@end iftex
@example
-Emacs.pane.menubar.font: 8x16
+Emacs.pane.menubar.faceName: Courier-12
@end example
@noindent
-Resources for @emph{non-menubar} toolkit pop-up menus have
-@samp{menu*} instead of @samp{pane.menubar}. For example, to specify
-the font @samp{8x16} for the pop-up menu items, write this:
+To specify a font, use fontconfig font names as values to the @code{faceName}
+resource.
+
+If Emacs is not built with the Xft library, Lucid menus can only display
+old style fonts. If Emacs is built with Xft and you prefer the old fonts,
+you have to specify @samp{none} to @code{faceName}:
@example
-Emacs.menu*.font: 8x16
+Emacs.pane.menubar.faceName: none
@end example
@noindent
-For dialog boxes, use @samp{dialog*}:
+To specify a non-Xft font, use @code{font}. For example:
@example
-Emacs.dialog*.font: 8x16
+Emacs.pane.menubar.font: lucidasanstypewriter-10
@end example
@noindent
-The Lucid menus can display multilingual text in your locale. For
-more information about fontsets see the man page for
+The Lucid menus can display multilingual text in your locale with old style
+fonts. For more information about fontsets see the man page for
@code{XCreateFontSet}. To enable multilingual menu text you specify a
@code{fontSet} resource instead of the font resource. If both
@code{font} and @code{fontSet} resources are specified, the
@@ -462,6 +465,22 @@ Emacs*menu*fontSet: -*-helvetica-medium-r-*--*-120-*-*-*-*-*-*,*
@end example
@noindent
+Resources for @emph{non-menubar} toolkit pop-up menus have
+@samp{menu*} instead of @samp{pane.menubar}. For example, to specify
+the font @samp{8x16} for the pop-up menu items, write this:
+
+@example
+Emacs.menu*.font: 8x16
+@end example
+
+@noindent
+For dialog boxes, use @samp{dialog*}:
+
+@example
+Emacs.dialog*.font: 8x16
+@end example
+
+@noindent
The @samp{*menu*} as a wildcard matches @samp{pane.menubar} and
@samp{menu@dots{}}.
@@ -473,6 +492,8 @@ approach should work on both kinds of systems.
Here is a list of the specific resources for menu bars and pop-up menus:
@table @code
+@item faceName
+Xft font for menu item text.
@item font
Font for menu item text.
@item fontSet
diff --git a/etc/NEWS b/etc/NEWS
index f555c8689a3..a21f7967c2f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -65,6 +65,8 @@ Algorithm.
** GTK scroll-bars are now placed on the right by default.
Use `set-scroll-bar-mode' to change this.
+** Lucid menus can display antialiased fonts if Emacs is build with Xft.
+
** New scrolling commands `scroll-up-command' and `scroll-down-command'
(bound to [next] and [prior]) does not signal errors at top/bottom
of buffer at first key-press (instead moves to top/bottom of buffer).
diff --git a/lwlib/ChangeLog b/lwlib/ChangeLog
index 9bea2c13dbd..189e2c65e10 100644
--- a/lwlib/ChangeLog
+++ b/lwlib/ChangeLog
@@ -1,3 +1,34 @@
+2010-04-08 Jan Djärv <jan.h.d@swipnet.se>
+
+ * xlwmenu.c (xlwmenu_default_font): Make static.
+ (xlwMenuResources): Add XtNfaceName and XtNdefaultFace.
+ (string_width): Use XftTextExtentsUtf8 if HAVE_XFT.
+ (MENU_FONT_HEIGHT, MENU_FONT_ASCENT): Add versions for
+ HAVE_XFT.
+ (size_menu): Set max_rest_width in window_state structure.
+ (display_menu_item): If HAVE_XFT and xft_draw is set, use
+ XftDrawRect and XftDrawStringUtf8 to draw text.
+ (make_windows_if_needed): Set max_rest_width and xft_draw
+ in windows[i].
+ (openXftFont): New.
+ (XlwMenuInitialize): Call openXftFont if HAVE_XFT. If mw->menu.font
+ is not set, load font fixed and save it in xlwmenu_default_font.
+ (XlwMenuInitialize): Set max_rest_width and xft_draw in windows[0].
+ (XlwMenuClassInitialize): Initialize xlwmenu_default_font.
+ (XlwMenuRealize): Set xft_fg, xft_bg, xft_disabled_fg and
+ windows[0].xft_draw if xft_font is set.
+ (XlwMenuDestroy): Destroy all xft_draw and close xft_font.
+ (facename_changed): New.
+ (XlwMenuSetValues): Call facename_changed. If face name did change,
+ close old fonts and destroy xft_draw:s. Then create new ones.
+
+ * xlwmenu.h (XtNfaceName, XtCFaceName, XtNdefaultFace,
+ XtCDefaultFace): New.
+
+ * xlwmenuP.h (_window_state): Add max_rest_width and xft_draw.
+ (_XlwMenu_part): Add faceName,xft_fg, xft_bg, xft_disabled_fg and
+ xft_font.
+
2010-03-10 Chong Yidong <cyd@stupidchicken.com>
* Branch for 23.2.
diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c
index 2ae7ae57e79..3e8259f9a19 100644
--- a/lwlib/xlwmenu.c
+++ b/lwlib/xlwmenu.c
@@ -30,6 +30,7 @@ Boston, MA 02110-1301, USA. */
#include "lisp.h"
#include <stdio.h>
+#include <ctype.h>
#include <sys/types.h>
#if (defined __sun) && !(defined SUNOS41)
@@ -69,7 +70,7 @@ extern char *gray_bitmap_bits;
static int pointer_grabbed;
static XEvent menu_post_event;
-XFontStruct *xlwmenu_default_font;
+static XFontStruct *xlwmenu_default_font;
static char
xlwMenuTranslations [] =
@@ -128,6 +129,13 @@ xlwMenuResources[] =
{XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet),
offset(menu.fontSet), XtRFontSet, NULL},
#endif
+#ifdef HAVE_XFT
+#define DEFAULT_FACENAME "Sans-10"
+ {XtNfaceName, XtCFaceName, XtRString, sizeof(String),
+ offset(menu.faceName), XtRString, DEFAULT_FACENAME},
+ {XtNdefaultFace, XtCDefaultFace, XtRInt, sizeof(int),
+ offset(menu.default_face), XtRImmediate, (XtPointer)1},
+#endif
{XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
offset(menu.font), XtRString, "XtDefaultFont"},
{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
@@ -352,10 +360,20 @@ string_width (mw, s)
{
XCharStruct xcs;
int drop;
+#ifdef HAVE_XFT
+ if (mw->menu.xft_font)
+ {
+ XGlyphInfo gi;
+ XftTextExtentsUtf8 (XtDisplay (mw), mw->menu.xft_font,
+ (FcChar8 *) s,
+ strlen (s), &gi);
+ return gi.width;
+ }
+#endif
#ifdef HAVE_X_I18N
- XRectangle ink, logical;
if (mw->menu.fontSet)
{
+ XRectangle ink, logical;
XmbTextExtents (mw->menu.fontSet, s, strlen (s), &ink, &logical);
return logical.width;
}
@@ -366,6 +384,20 @@ string_width (mw, s)
}
+#ifdef HAVE_XFT
+#define MENU_FONT_HEIGHT(mw) \
+ ((mw)->menu.xft_font != NULL \
+ ? (mw)->menu.xft_font->height \
+ : ((mw)->menu.fontSet != NULL \
+ ? (mw)->menu.font_extents->max_logical_extent.height \
+ : (mw)->menu.font->ascent + (mw)->menu.font->descent))
+#define MENU_FONT_ASCENT(mw) \
+ ((mw)->menu.xft_font != NULL \
+ ? (mw)->menu.xft_font->ascent \
+ : ((mw)->menu.fontSet != NULL \
+ ? - (mw)->menu.font_extents->max_logical_extent.y \
+ : (mw)->menu.font->ascent))
+#else
#ifdef HAVE_X_I18N
#define MENU_FONT_HEIGHT(mw) \
((mw)->menu.fontSet != NULL \
@@ -380,6 +412,7 @@ string_width (mw, s)
((mw)->menu.font->ascent + (mw)->menu.font->descent)
#define MENU_FONT_ASCENT(mw) ((mw)->menu.font->ascent)
#endif
+#endif
static int
arrow_width (mw)
@@ -559,6 +592,7 @@ size_menu (mw, level)
ws->width += 2 * mw->menu.shadow_thickness;
ws->height += 2 * mw->menu.shadow_thickness;
+ ws->max_rest_width = max_rest_width;
if (horizontal_p)
{
@@ -987,6 +1021,9 @@ display_menu_item (mw, val, ws, where, highlighted_p, horizontal_p,
int width;
enum menu_separator separator;
int separator_p = lw_separator_p (val->name, &separator, 0);
+#ifdef HAVE_XFT
+ XftColor *xftfg;
+#endif
/* compute the sizes of the item */
size_menu_item (mw, val, horizontal_p, &label_width, &rest_width,
@@ -1024,6 +1061,9 @@ display_menu_item (mw, val, ws, where, highlighted_p, horizontal_p,
else
text_gc = mw->menu.disabled_gc;
deco_gc = mw->menu.foreground_gc;
+#ifdef HAVE_XFT
+ xftfg = val->enabled ? &mw->menu.xft_fg : &mw->menu.xft_disabled_fg;
+#endif
if (separator_p)
{
@@ -1048,6 +1088,21 @@ display_menu_item (mw, val, ws, where, highlighted_p, horizontal_p,
x_offset += ws->button_width;
+#ifdef HAVE_XFT
+ if (ws->xft_draw)
+ {
+ int draw_y = y + v_spacing + shadow;
+ XftDrawRect (ws->xft_draw, &mw->menu.xft_bg,
+ x_offset, draw_y,
+ ws->width, font_height);
+ XftDrawStringUtf8 (ws->xft_draw, xftfg,
+ mw->menu.xft_font,
+ x_offset, draw_y + font_ascent,
+ (unsigned char *) display_string,
+ strlen (display_string));
+ }
+ else
+#endif
#ifdef HAVE_X_I18N
if (mw->menu.fontSet)
XmbDrawString (XtDisplay (mw), ws->window, mw->menu.fontSet,
@@ -1082,6 +1137,21 @@ display_menu_item (mw, val, ws, where, highlighted_p, horizontal_p,
}
else if (val->key)
{
+#ifdef HAVE_XFT
+ if (ws->xft_draw)
+ {
+ XGlyphInfo gi;
+ int draw_x = ws->width - ws->max_rest_width
+ + mw->menu.arrow_spacing;
+ int draw_y = y + v_spacing + shadow + font_ascent;
+ XftDrawStringUtf8 (ws->xft_draw, xftfg,
+ mw->menu.xft_font,
+ draw_x, draw_y,
+ (unsigned char *) val->key,
+ strlen (val->key));
+ }
+ else
+#endif
#ifdef HAVE_X_I18N
if (mw->menu.fontSet)
XmbDrawString (XtDisplay (mw), ws->window,
@@ -1242,6 +1312,9 @@ make_windows_if_needed (mw, n)
int mask;
Window root = RootWindowOfScreen (DefaultScreenOfDisplay (XtDisplay (mw)));
window_state* windows;
+#ifdef HAVE_XFT
+ int screen = XScreenNumberOfScreen (mw->core.screen);
+#endif
if (mw->menu.windows_length >= n)
return;
@@ -1280,10 +1353,21 @@ make_windows_if_needed (mw, n)
windows [i].y = 0;
windows [i].width = 1;
windows [i].height = 1;
+ windows [i].max_rest_width = 0;
windows [i].window =
XCreateWindow (XtDisplay (mw), root, 0, 0, 1, 1,
0, 0, CopyFromParent, CopyFromParent, mask, &xswa);
- }
+#ifdef HAVE_XFT
+ if (mw->menu.xft_font)
+ mw->menu.windows [i].xft_draw
+ = XftDrawCreate (XtDisplay (mw),
+ windows [i].window,
+ DefaultVisual (XtDisplay (mw), screen),
+ mw->core.colormap);
+ else
+ mw->menu.windows [i].xft_draw = 0;
+#endif
+ }
}
/* Value is non-zero if WINDOW is part of menu bar widget W. */
@@ -1758,6 +1842,44 @@ release_shadow_gcs (mw)
XtReleaseGC ((Widget) mw, mw->menu.shadow_bottom_gc);
}
+#ifdef HAVE_XFT
+static int
+openXftFont (mw)
+ XlwMenuWidget mw;
+{
+ char *fname = mw->menu.faceName;
+
+ mw->menu.xft_font = 0;
+ mw->menu.default_face = fname && strcmp (fname, DEFAULT_FACENAME) == 0;
+
+ if (fname && strcmp (fname, "none") != 0)
+ {
+ int screen = XScreenNumberOfScreen (mw->core.screen);
+ int len = strlen (fname), i = len-1;
+ /* Try to convert Gtk-syntax (Sans 9) to Xft syntax Sans-9. */
+ while (i > 0 && isdigit (fname[i]))
+ --i;
+ if (fname[i] == ' ')
+ {
+ fname = xstrdup (mw->menu.faceName);
+ fname[i] = '-';
+ }
+
+ mw->menu.xft_font = XftFontOpenName (XtDisplay (mw), screen, fname);
+ if (!mw->menu.xft_font)
+ {
+ fprintf (stderr, "Can't find font '%s'\n", fname);
+ mw->menu.xft_font = XftFontOpenName (XtDisplay (mw), screen,
+ DEFAULT_FACENAME);
+ }
+ }
+
+ if (fname != mw->menu.faceName) free (fname);
+
+ return mw->menu.xft_font != 0;
+}
+#endif
+
static void
XlwMenuInitialize (request, mw, args, num_args)
Widget request;
@@ -1779,7 +1901,7 @@ XlwMenuInitialize (request, mw, args, num_args)
mw->menu.contents = tem;
#endif
-/* mw->menu.cursor = XCreateFontCursor (display, mw->menu.cursor_shape); */
+ /* mw->menu.cursor = XCreateFontCursor (display, mw->menu.cursor_shape); */
mw->menu.cursor = mw->menu.cursor_shape;
mw->menu.gray_pixmap
@@ -1787,11 +1909,24 @@ XlwMenuInitialize (request, mw, args, num_args)
gray_bitmap_width, gray_bitmap_height,
(unsigned long)1, (unsigned long)0, 1);
- /* I don't understand why this ends up 0 sometimes,
- but it does. This kludge works around it.
- Can anyone find a real fix? -- rms. */
- if (mw->menu.font == 0)
- mw->menu.font = xlwmenu_default_font;
+#ifdef HAVE_XFT
+ if (openXftFont (mw))
+ ;
+ else
+#endif
+
+ if (!mw->menu.font)
+ {
+ if (!xlwmenu_default_font)
+ xlwmenu_default_font = XLoadQueryFont (display, "fixed");
+ mw->menu.font = xlwmenu_default_font;
+ if (!mw->menu.font)
+ {
+ fprintf (stderr, "Menu font fixed not found, can't continue.\n");
+ abort ();
+ }
+ }
+
#ifdef HAVE_X_I18N
if (mw->menu.fontSet)
mw->menu.font_extents = XExtentsOfFontSet (mw->menu.fontSet);
@@ -1818,6 +1953,10 @@ XlwMenuInitialize (request, mw, args, num_args)
mw->menu.windows [0].y = 0;
mw->menu.windows [0].width = 0;
mw->menu.windows [0].height = 0;
+ mw->menu.windows [0].max_rest_width = 0;
+#ifdef HAVE_XFT
+ mw->menu.windows [0].xft_draw = 0;
+#endif
size_menu (mw, 0);
mw->core.width = mw->menu.windows [0].width;
@@ -1827,6 +1966,7 @@ XlwMenuInitialize (request, mw, args, num_args)
static void
XlwMenuClassInitialize ()
{
+ xlwmenu_default_font = 0;
}
static void
@@ -1861,6 +2001,38 @@ XlwMenuRealize (w, valueMask, attributes)
mw->menu.windows [0].y = w->core.y;
mw->menu.windows [0].width = w->core.width;
mw->menu.windows [0].height = w->core.height;
+
+#ifdef HAVE_XFT
+ if (mw->menu.xft_font)
+ {
+ XColor colors[3];
+ int screen = XScreenNumberOfScreen (mw->core.screen);
+ mw->menu.windows [0].xft_draw
+ = XftDrawCreate (XtDisplay (w),
+ mw->menu.windows [0].window,
+ DefaultVisual (XtDisplay (w), screen),
+ mw->core.colormap);
+ colors[0].pixel = mw->menu.xft_fg.pixel = mw->menu.foreground;
+ colors[1].pixel = mw->menu.xft_bg.pixel = mw->core.background_pixel;
+ colors[2].pixel = mw->menu.xft_disabled_fg.pixel
+ = mw->menu.disabled_foreground;
+ XQueryColors (XtDisplay (mw), mw->core.colormap, colors, 3);
+ mw->menu.xft_fg.color.alpha = 0xFFFF;
+ mw->menu.xft_fg.color.red = colors[0].red;
+ mw->menu.xft_fg.color.green = colors[0].green;
+ mw->menu.xft_fg.color.blue = colors[0].blue;
+ mw->menu.xft_bg.color.alpha = 0xFFFF;
+ mw->menu.xft_bg.color.red = colors[1].red;
+ mw->menu.xft_bg.color.green = colors[1].green;
+ mw->menu.xft_bg.color.blue = colors[1].blue;
+ mw->menu.xft_disabled_fg.color.alpha = 0xFFFF;
+ mw->menu.xft_disabled_fg.color.red = colors[2].red;
+ mw->menu.xft_disabled_fg.color.green = colors[2].green;
+ mw->menu.xft_disabled_fg.color.blue = colors[2].blue;
+ }
+ else
+ mw->menu.windows [0].xft_draw = 0;
+#endif
}
/* Only the toplevel menubar/popup is a widget so it's the only one that
@@ -1942,13 +2114,37 @@ XlwMenuDestroy (w)
client exits. Nice, eh?
*/
+#ifdef HAVE_XFT
+ if (mw->menu.windows [0].xft_draw)
+ XftDrawDestroy (mw->menu.windows [0].xft_draw);
+ if (mw->menu.xft_font)
+ XftFontClose (XtDisplay (mw), mw->menu.xft_font);
+#endif
+
/* start from 1 because the one in slot 0 is w->core.window */
for (i = 1; i < mw->menu.windows_length; i++)
- XDestroyWindow (XtDisplay (mw), mw->menu.windows [i].window);
+ {
+ XDestroyWindow (XtDisplay (mw), mw->menu.windows [i].window);
+#ifdef HAVE_XFT
+ if (mw->menu.windows [i].xft_draw)
+ XftDrawDestroy (mw->menu.windows [i].xft_draw);
+#endif
+ }
+
if (mw->menu.windows)
XtFree ((char *) mw->menu.windows);
}
+static int
+facename_changed (XlwMenuWidget newmw,
+ XlwMenuWidget oldmw)
+{
+ /* This will fore a new XftFont even if the same sting is set.
+ This is good, as rendering parameters may have changed and
+ we just want to do a redisplay. */
+ return newmw->menu.faceName != oldmw->menu.faceName;
+}
+
static Boolean
XlwMenuSetValues (current, request, new)
Widget current;
@@ -1972,6 +2168,9 @@ XlwMenuSetValues (current, request, new)
if (newmw->core.background_pixel != oldmw->core.background_pixel
|| newmw->menu.foreground != oldmw->menu.foreground
+#ifdef HAVE_XFT
+ || facename_changed (newmw, oldmw)
+#endif
#ifdef HAVE_X_I18N
|| newmw->menu.fontSet != oldmw->menu.fontSet
|| (newmw->menu.fontSet == NULL && newmw->menu.font != oldmw->menu.font)
@@ -2004,6 +2203,29 @@ XlwMenuSetValues (current, request, new)
}
}
+#ifdef HAVE_XFT
+ if (facename_changed (newmw, oldmw))
+ {
+ int i;
+ int screen = XScreenNumberOfScreen (newmw->core.screen);
+ if (newmw->menu.xft_font)
+ XftFontClose (XtDisplay (newmw), newmw->menu.xft_font);
+ openXftFont (newmw);
+ for (i = 0; i < newmw->menu.windows_length; i++)
+ {
+ if (newmw->menu.windows [i].xft_draw)
+ XftDrawDestroy (newmw->menu.windows [i].xft_draw);
+ newmw->menu.windows [i].xft_draw = 0;
+ }
+ if (newmw->menu.xft_font)
+ for (i = 0; i < newmw->menu.windows_length; i++)
+ newmw->menu.windows [i].xft_draw
+ = XftDrawCreate (XtDisplay (newmw),
+ newmw->menu.windows [i].window,
+ DefaultVisual (XtDisplay (newmw), screen),
+ newmw->core.colormap);
+ }
+#endif
#ifdef HAVE_X_I18N
if (newmw->menu.fontSet != oldmw->menu.fontSet && newmw->menu.fontSet != NULL)
{
diff --git a/lwlib/xlwmenu.h b/lwlib/xlwmenu.h
index 4f2c6cc4452..a58fd00c1e3 100644
--- a/lwlib/xlwmenu.h
+++ b/lwlib/xlwmenu.h
@@ -58,6 +58,10 @@ Boston, MA 02110-1301, USA. */
#define XtCResizeToPreferred "ResizeToPreferred"
#define XtNallowResize "allowResize"
#define XtCAllowResize "AllowResize"
+#define XtNfaceName "faceName"
+#define XtCFaceName "FaceName"
+#define XtNdefaultFace "defaultFace"
+#define XtCDefaultFace "DefaultFace"
/* Motif-compatible resource names */
#define XmNshadowThickness "shadowThickness"
diff --git a/lwlib/xlwmenuP.h b/lwlib/xlwmenuP.h
index e98d657bfa0..39afcc6ca7f 100644
--- a/lwlib/xlwmenuP.h
+++ b/lwlib/xlwmenuP.h
@@ -25,6 +25,9 @@ Boston, MA 02110-1301, USA. */
#include "xlwmenu.h"
#include <X11/CoreP.h>
+#ifdef HAVE_XFT
+#include <X11/Xft/Xft.h>
+#endif
/* Elements in the stack arrays. */
typedef struct _window_state
@@ -35,9 +38,13 @@ typedef struct _window_state
Dimension width;
Dimension height;
Dimension label_width;
+ int max_rest_width;
/* Width of toggle buttons or radio buttons. */
Dimension button_width;
+#ifdef HAVE_XFT
+ XftDraw* xft_draw;
+#endif
} window_state;
@@ -49,6 +56,12 @@ typedef struct _XlwMenu_part
XFontSet fontSet;
XFontSetExtents *font_extents;
#endif
+#ifdef HAVE_XFT
+ String faceName;
+ int default_face;
+ XftFont* xft_font;
+ XftColor xft_fg, xft_bg, xft_disabled_fg;
+#endif
XFontStruct* font;
Pixel foreground;
Pixel disabled_foreground;
diff --git a/src/ChangeLog b/src/ChangeLog
index 455deff0aae..51ed028b9d5 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,29 @@
+2010-04-08 Jan Djärv <jan.h.d@swipnet.se>
+
+ * xsettings.c (current_font, SYSTEM_FONT, XSETTINGS_FONT_NAME): New.
+ (parse_xft_settings): Also check for XSETTINGS_FONT_NAME and save that
+ in current_font.
+ (init_gconf): Read value of SYSTEM_FONT and save it in current_font.
+ (Ffont_get_system_normal_font, xsettings_get_system_normal_font): New
+ functions.
+ (syms_of_xsettings): Initialize current_font. defsubr
+ Sfont_get_system_normal_font.
+
+ * xsettings.h (Ffont_get_system_normal_font,
+ xsettings_get_system_normal_font): Declare.
+
+ * xfns.c (extern xlwmenu_default_font): Remove.
+ (Fx_create_frame): Remove setting of xlwmenu_default_font, moved
+ to xlwmenu.c.
+
+ * menu.c (digest_single_submenu): If USE_LUCID and HAVE_XFT, encode
+ menu items in UTF-8.
+
+ * xmenu.c: include xsettings.h and xlwmenu.h if USE_LUCID.
+ (apply_systemfont_to_menu): New function.
+ (set_frame_menubar, create_and_show_popup_menu): Call
+ apply_systemfont_to_menu.
+
2010-04-07 Jan Djärv <jan.h.d@swipnet.se>
* frame.h (FRAME_TEXT_LINES_TO_PIXEL_HEIGHT): Don't use
diff --git a/src/menu.c b/src/menu.c
index bfe54a53328..ca00c06a98b 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -697,6 +697,12 @@ digest_single_submenu (start, end, top_level_items)
ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
}
+#elif defined (USE_LUCID) && defined (HAVE_XFT)
+ if (STRINGP (pane_name))
+ {
+ pane_name = ENCODE_UTF_8 (pane_name);
+ ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
+ }
#elif !defined (HAVE_MULTILINGUAL_MENU)
if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
{
@@ -770,6 +776,18 @@ digest_single_submenu (start, end, top_level_items)
descrip = ENCODE_SYSTEM (descrip);
ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
}
+#elif USE_LUCID
+ if (STRINGP (item_name))
+ {
+ item_name = ENCODE_UTF_8 (item_name);
+ ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
+ }
+
+ if (STRINGP (descrip))
+ {
+ descrip = ENCODE_UTF_8 (descrip);
+ ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
+ }
#elif !defined (HAVE_MULTILINGUAL_MENU)
if (STRING_MULTIBYTE (item_name))
{
diff --git a/src/xfns.c b/src/xfns.c
index 4ec13b7e50d..647526cc22b 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -110,11 +110,6 @@ extern void _XEditResCheckMessages ();
extern LWLIB_ID widget_id_tick;
-#ifdef USE_LUCID
-/* This is part of a kludge--see lwlib/xlwmenu.c. */
-extern XFontStruct *xlwmenu_default_font;
-#endif
-
extern void free_frame_menubar ();
extern double atof ();
@@ -3379,14 +3374,6 @@ This function is an internal primitive--use `make-frame' instead. */)
error ("Invalid frame font");
}
-#ifdef USE_LUCID
- /* Prevent lwlib/xlwmenu.c from crashing because of a bug
- whereby it fails to get any font. */
- BLOCK_INPUT;
- xlwmenu_default_font = XLoadQueryFont (FRAME_X_DISPLAY (f), "fixed");
- UNBLOCK_INPUT;
-#endif
-
/* Frame contents get displaced if an embedded X window has a border. */
if (! FRAME_X_EMBEDDED_P (f))
x_default_parameter (f, parms, Qborder_width, make_number (2),
diff --git a/src/xmenu.c b/src/xmenu.c
index 64e55b7413c..de2f4eb6815 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -81,6 +81,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#ifdef USE_LUCID
+#include "xsettings.h"
+#include "../lwlib/xlwmenu.h"
#ifdef HAVE_XAW3D
#include <X11/Xaw3d/Paned.h>
#else /* !HAVE_XAW3D */
@@ -950,6 +952,36 @@ update_frame_menubar (f)
return 1;
}
+#ifdef USE_LUCID
+static void
+apply_systemfont_to_menu (w)
+ Widget w;
+{
+ const char *fn = xsettings_get_system_normal_font ();
+ int defflt;
+
+ if (!fn) return;
+
+ if (XtIsShell (w)) /* popup menu */
+ {
+ Widget *childs[1];
+ int num = 0;
+
+ XtVaGetValues (w, XtNnumChildren, &num, NULL);
+ if (num != 1) return; /* Should only be one. */
+
+ childs[0] = 0;
+ XtVaGetValues (w, XtNchildren, childs, NULL);
+ if (childs[0] && *childs[0]) w = *childs[0];
+ }
+
+ /* Only use system font if the default is used for the menu. */
+ XtVaGetValues (w, XtNdefaultFace, &defflt, NULL);
+ if (defflt)
+ XtVaSetValues (w, XtNfaceName, fn, NULL);
+}
+#endif
+
/* Set the contents of the menubar widgets of frame F.
The argument FIRST_TIME is currently ignored;
it is set the first time this is called, from initialize_frame_menubar. */
@@ -1262,6 +1294,7 @@ set_frame_menubar (f, first_time, deep_p)
/* Make menu pop down on C-g. */
XtOverrideTranslations (menubar_widget, override);
+ apply_systemfont_to_menu (menubar_widget);
}
{
@@ -1608,6 +1641,8 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp)
popup_deactivate_callback,
menu_highlight_callback);
+ apply_systemfont_to_menu (menu);
+
dummy.type = ButtonPress;
dummy.serial = 0;
dummy.send_event = 0;
diff --git a/src/xsettings.c b/src/xsettings.c
index 945007db2f0..b71871df573 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -39,6 +39,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#endif
static char *current_mono_font;
+static char *current_font;
static struct x_display_info *first_dpyinfo;
static Lisp_Object Qfont_name, Qfont_render;
static int use_system_font;
@@ -65,7 +66,9 @@ store_font_changed_event (arg, display_name)
#ifdef HAVE_GCONF
-#define SYSTEM_MONO_FONT "/desktop/gnome/interface/monospace_font_name"
+#define SYSTEM_MONO_FONT "/desktop/gnome/interface/monospace_font_name"
+#define SYSTEM_FONT "/desktop/gnome/interface/font_name"
+#define XSETTINGS_FONT_NAME "Gtk/FontName"
/* Callback called when something changed in GConf that we care about,
that is SYSTEM_MONO_FONT. */
@@ -235,7 +238,7 @@ parse_xft_settings (prop, bytes, settings)
memset (settings, 0, sizeof (*settings));
- while (bytes_parsed+4 < bytes && settings_seen < 6
+ while (bytes_parsed+4 < bytes && settings_seen < 7
&& i < n_settings)
{
int type = prop[bytes_parsed++];
@@ -243,7 +246,7 @@ parse_xft_settings (prop, bytes, settings)
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 want_this;
int to_cpy;
sval[0] = '\0';
@@ -264,13 +267,14 @@ parse_xft_settings (prop, bytes, settings)
bytes_parsed += 4; /* Skip serial for this value */
if (bytes_parsed > bytes) return BadLength;
- is_xft = nlen > 6 && strncmp (name, "Xft/", 4) == 0;
+ want_this = (nlen > 6 && strncmp (name, "Xft/", 4) == 0)
+ || (strcmp (XSETTINGS_FONT_NAME, name) == 0);
switch (type)
{
case 0: /* Integer */
if (bytes_parsed+4 > bytes) return BadLength;
- if (is_xft)
+ if (want_this)
{
memcpy (&ival, prop+bytes_parsed, 4);
if (my_bo != that_bo) ival = SWAP32 (ival);
@@ -283,7 +287,7 @@ parse_xft_settings (prop, bytes, settings)
memcpy (&vlen, prop+bytes_parsed, 4);
bytes_parsed += 4;
if (my_bo != that_bo) vlen = SWAP32 (vlen);
- if (is_xft)
+ if (want_this)
{
to_cpy = vlen > 127 ? 127 : vlen;
memcpy (sval, prop+bytes_parsed, to_cpy);
@@ -303,7 +307,7 @@ parse_xft_settings (prop, bytes, settings)
return BadValue;
}
- if (is_xft)
+ if (want_this)
{
++settings_seen;
if (strcmp (name, "Xft/Antialias") == 0)
@@ -361,6 +365,11 @@ parse_xft_settings (prop, bytes, settings)
else
settings->seen &= ~SEEN_LCDFILTER;
}
+ else if (strcmp (name, XSETTINGS_FONT_NAME) == 0)
+ {
+ free (current_font);
+ current_font = xstrdup (sval);
+ }
}
}
@@ -571,6 +580,12 @@ init_gconf ()
current_mono_font = xstrdup (s);
g_free (s);
}
+ s = gconf_client_get_string (gconf_client, SYSTEM_FONT, NULL);
+ if (s)
+ {
+ current_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,
@@ -635,6 +650,23 @@ xsettings_get_system_font ()
return current_mono_font;
}
+const char *
+xsettings_get_system_normal_font ()
+{
+ return current_font;
+}
+
+DEFUN ("font-get-system-normal-font", Ffont_get_system_normal_font,
+ Sfont_get_system_normal_font,
+ 0, 0, 0,
+ doc: /* Get the system default font. */)
+ ()
+{
+ return current_font && use_system_font
+ ? make_string (current_font, strlen (current_font))
+ : Qnil;
+}
+
DEFUN ("font-get-system-font", Ffont_get_system_font, Sfont_get_system_font,
0, 0, 0,
doc: /* Get the system default monospaced font. */)
@@ -649,6 +681,7 @@ void
syms_of_xsettings ()
{
current_mono_font = NULL;
+ current_font = NULL;
first_dpyinfo = NULL;
#ifdef HAVE_GCONF
gconf_client = NULL;
@@ -659,6 +692,7 @@ syms_of_xsettings ()
Qfont_render = intern_c_string ("font-render");
staticpro (&Qfont_render);
defsubr (&Sfont_get_system_font);
+ defsubr (&Sfont_get_system_normal_font);
DEFVAR_BOOL ("font-use-system-font", &use_system_font,
doc: /* *Non-nil means to use the system defined font. */);
diff --git a/src/xsettings.h b/src/xsettings.h
index 6c603e5bbd9..f6399ea1bcc 100644
--- a/src/xsettings.h
+++ b/src/xsettings.h
@@ -21,10 +21,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define XSETTINGS_H
EXFUN (Ffont_get_system_font, 0);
+EXFUN (Ffont_get_system_normal_font, 0);
+
extern void xsettings_initialize P_ ((struct x_display_info *dpyinfo));
extern void xft_settings_event P_ ((struct x_display_info *dpyinfo,
XEvent *));
extern const char *xsettings_get_system_font P_ ((void));
+extern const char *xsettings_get_system_normal_font P_ ((void));
#endif /* XSETTINGS_H */