changeset 108449:0346e41d1e53

Merge from mainline.
author Katsumi Yamaoka <yamaoka@jpl.org>
date Fri, 09 Apr 2010 12:36:12 +0000
parents 962b581f9cc7 (current diff) b4880c984e2f (diff)
children de8a1b891175
files
diffstat 18 files changed, 523 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/.bzrignore	Thu Apr 08 14:13:22 2010 +0000
+++ b/.bzrignore	Fri Apr 09 12:36:12 2010 +0000
@@ -65,3 +65,4 @@
 configure.lineno
 conftest*
 confdefs.h
+core
--- a/doc/emacs/ChangeLog	Thu Apr 08 14:13:22 2010 +0000
+++ b/doc/emacs/ChangeLog	Fri Apr 09 12:36:12 2010 +0000
@@ -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
--- a/doc/emacs/xresources.texi	Thu Apr 08 14:13:22 2010 +0000
+++ b/doc/emacs/xresources.texi	Fri Apr 09 12:36:12 2010 +0000
@@ -415,7 +415,7 @@
 @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,11 +423,45 @@
 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
+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.pane.menubar.faceName:	none
+@end example
+
+@noindent
+To specify a non-Xft font, use @code{font}.  For example:
+
+@example
+Emacs.pane.menubar.font: lucidasanstypewriter-10
+@end example
+
+@noindent
+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
+@code{fontSet} resource is used.
+
+  Thus, to specify @samp{-*-helvetica-medium-r-*--*-120-*-*-*-*-*-*,*}
+for both the popup and menu bar menus, write this:
+
+@example
+Emacs*menu*fontSet:  -*-helvetica-medium-r-*--*-120-*-*-*-*-*-*,*
 @end example
 
 @noindent
@@ -447,21 +481,6 @@
 @end example
 
 @noindent
-The Lucid menus can display multilingual text in your locale.  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
-@code{fontSet} resource is used.
-
-  Thus, to specify @samp{-*-helvetica-medium-r-*--*-120-*-*-*-*-*-*,*}
-for both the popup and menu bar menus, write this:
-
-@example
-Emacs*menu*fontSet:  -*-helvetica-medium-r-*--*-120-*-*-*-*-*-*,*
-@end example
-
-@noindent
 The @samp{*menu*} as a wildcard matches @samp{pane.menubar} and
 @samp{menu@dots{}}.
 
@@ -473,6 +492,8 @@
   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
--- a/etc/NEWS	Thu Apr 08 14:13:22 2010 +0000
+++ b/etc/NEWS	Fri Apr 09 12:36:12 2010 +0000
@@ -65,6 +65,8 @@
 ** 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).
--- a/lisp/ChangeLog	Thu Apr 08 14:13:22 2010 +0000
+++ b/lisp/ChangeLog	Fri Apr 09 12:36:12 2010 +0000
@@ -1,7 +1,13 @@
+2010-04-08  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	Fix some of the problems in defsubst* (bug#5728).
+	* emacs-lisp/cl-macs.el (defsubst*): Don't substitute non-trivial args.
+	(cl-defsubst-expand): Do the substitutions simultaneously (bug#5728).
+
 2010-04-07  Sam Steingold  <sds@gnu.org>
 
-	* progmodes/compile.el (compilation-save-buffers-predicate): New
-	custom variable.
+	* progmodes/compile.el (compilation-save-buffers-predicate):
+	New custom variable.
 	(compile, recompile): Pass it to `save-some-buffers'.
 
 2010-04-07  Jan Djärv  <jan.h.d@swipnet.se>
--- a/lisp/emacs-lisp/cl-macs.el	Thu Apr 08 14:13:22 2010 +0000
+++ b/lisp/emacs-lisp/cl-macs.el	Fri Apr 09 12:36:12 2010 +0000
@@ -128,6 +128,12 @@
   (and (eq (cl-const-expr-p x) t) (if (consp x) (nth 1 x) x)))
 
 (defun cl-expr-access-order (x v)
+  ;; This apparently tries to return nil iff the expression X evaluates
+  ;; the variables V in the same order as they appear in V (so as to
+  ;; be able to replace those vars with the expressions they're bound
+  ;; to).
+  ;; FIXME: This is very naive, it doesn't even check to see if those
+  ;; variables appear more than once.
   (if (cl-const-expr-p x) v
     (if (consp x)
 	(progn
@@ -2616,21 +2622,36 @@
 		    (cons '&cl-quote args))
 		  (list* 'cl-defsubst-expand (list 'quote argns)
 			 (list 'quote (list* 'block name body))
-			 (not (or unsafe (cl-expr-access-order pbody argns)))
+                         ;; We used to pass `simple' as
+                         ;; (not (or unsafe (cl-expr-access-order pbody argns)))
+                         ;; But this is much too simplistic since it
+                         ;; does not pay attention to the argvs (and
+                         ;; cl-expr-access-order itself is also too naive).
+			 nil
 			 (and (memq '&key args) 'cl-whole) unsafe argns)))
 	  (list* 'defun* name args body))))
 
 (defun cl-defsubst-expand (argns body simple whole unsafe &rest argvs)
   (if (and whole (not (cl-safe-expr-p (cons 'progn argvs)))) whole
     (if (cl-simple-exprs-p argvs) (setq simple t))
-    (let ((lets (delq nil
-		      (mapcar* (function
-				(lambda (argn argv)
-				  (if (or simple (cl-const-expr-p argv))
-				      (progn (setq body (subst argv argn body))
-					     (and unsafe (list argn argv)))
-				    (list argn argv))))
-			       argns argvs))))
+    (let* ((substs ())
+           (lets (delq nil
+                       (mapcar* (function
+                                 (lambda (argn argv)
+                                   (if (or simple (cl-const-expr-p argv))
+                                       (progn (push (cons argn argv) substs)
+                                              (and unsafe (list argn argv)))
+                                     (list argn argv))))
+                                argns argvs))))
+      ;; FIXME: `sublis/subst' will happily substitute the symbol
+      ;; `argn' in places where it's not used as a reference
+      ;; to a variable.
+      ;; FIXME: `sublis/subst' will happily copy `argv' to a different
+      ;; scope, leading to name capture.
+      (setq body (cond ((null substs) body)
+                       ((null (cdr substs))
+                        (subst (cdar substs) (caar substs) body))
+                       (t (sublis substs body))))
       (if lets (list 'let lets body) body))))
 
 
--- a/lwlib/ChangeLog	Thu Apr 08 14:13:22 2010 +0000
+++ b/lwlib/ChangeLog	Fri Apr 09 12:36:12 2010 +0000
@@ -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.
--- a/lwlib/xlwmenu.c	Thu Apr 08 14:13:22 2010 +0000
+++ b/lwlib/xlwmenu.c	Fri Apr 09 12:36:12 2010 +0000
@@ -30,6 +30,7 @@
 #include "lisp.h"
 
 #include <stdio.h>
+#include <ctype.h>
 
 #include <sys/types.h>
 #if (defined __sun) && !(defined SUNOS41)
@@ -69,7 +70,7 @@
 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 @@
   {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 @@
 {
   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 @@
 
 }
 
+#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 @@
   ((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 @@
 
   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 @@
   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 @@
       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 @@
 	    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 @@
 		}
 	      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 @@
   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 @@
      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 @@
   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 @@
   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 @@
 				   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 @@
   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 @@
 static void
 XlwMenuClassInitialize ()
 {
+  xlwmenu_default_font = 0;
 }
 
 static void
@@ -1861,6 +2001,38 @@
   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 @@
      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 @@
 
   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 @@
 	  }
     }
 
+#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)
     {
--- a/lwlib/xlwmenu.h	Thu Apr 08 14:13:22 2010 +0000
+++ b/lwlib/xlwmenu.h	Fri Apr 09 12:36:12 2010 +0000
@@ -58,6 +58,10 @@
 #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"
--- a/lwlib/xlwmenuP.h	Thu Apr 08 14:13:22 2010 +0000
+++ b/lwlib/xlwmenuP.h	Fri Apr 09 12:36:12 2010 +0000
@@ -25,6 +25,9 @@
 
 #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 @@
   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 @@
   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;
--- a/src/ChangeLog	Thu Apr 08 14:13:22 2010 +0000
+++ b/src/ChangeLog	Fri Apr 09 12:36:12 2010 +0000
@@ -1,3 +1,44 @@
+2010-04-08  Eli Zaretskii  <eliz@gnu.org>
+
+	* xdisp.c (set_cursor_from_row): Don't dereference glyphs beyond
+	the end of TEXT_AREA.  (Bug#5856)
+
+2010-04-08  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* xsettings.c (XSETTINGS_FONT_NAME): Move XSETTINGS_FONT_NAME out of
+	HAVE_GCONF.
+
+2010-04-08  Eli Zaretskii  <eliz@gnu.org>
+
+	* bidi.c (bidi_resolve_weak): Use prev.type_after_w1, instead of
+	prev.orig_type, for resolving type of NSM.  (Bug#5858)
+
+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
--- a/src/bidi.c	Thu Apr 08 14:13:22 2010 +0000
+++ b/src/bidi.c	Fri Apr 09 12:36:12 2010 +0000
@@ -1347,12 +1347,14 @@
       if (type == WEAK_NSM)	/* W1 */
 	{
 	  /* Note that we don't need to consider the case where the
-	     prev character has its type overridden by an RLO or LRO:
-	     such characters are outside the current level run, and
-	     thus not relevant to this NSM.  Thus, NSM gets the
-	     orig_type of the previous character.  */
+	     prev character has its type overridden by an RLO or LRO,
+	     because then either the type of this NSM would have been
+	     also overridden, or the previous character is outside the
+	     current level run, and thus not relevant to this NSM.
+	     This is why NSM gets the type_after_w1 of the previous
+	     character.  */
 	  if (bidi_it->prev.type != UNKNOWN_BT)
-	    type = bidi_it->prev.orig_type;
+	    type = bidi_it->prev.type_after_w1;
 	  else if (bidi_it->sor == R2L)
 	    type = STRONG_R;
 	  else if (bidi_it->sor == L2R)
--- a/src/menu.c	Thu Apr 08 14:13:22 2010 +0000
+++ b/src/menu.c	Fri Apr 09 12:36:12 2010 +0000
@@ -697,6 +697,12 @@
 
 	      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 @@
 	      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))
 	    {
--- a/src/xdisp.c	Thu Apr 08 14:13:22 2010 +0000
+++ b/src/xdisp.c	Fri Apr 09 12:36:12 2010 +0000
@@ -12553,6 +12553,9 @@
   EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
   EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
   struct glyph *glyph_before = glyph - 1, *glyph_after = end;
+  /* A glyph beyond the edge of TEXT_AREA which we should never
+     touch.  */
+  struct glyph *glyphs_end = end;
   /* Non-zero means we've found a match for cursor position, but that
      glyph has the avoid_cursor_p flag set.  */
   int match_with_avoid_cursor = 0;
@@ -12594,7 +12597,7 @@
 
 	  /* If the glyph row is reversed, we need to process it from back
 	     to front, so swap the edge pointers.  */
-	  end = glyph - 1;
+	  glyphs_end = end = glyph - 1;
 	  glyph += row->used[TEXT_AREA] - 1;
 	  /* Reverse the known positions in the row.  */
 	  last_pos = pos_after = MATRIX_ROW_START_CHARPOS (row) + delta;
@@ -12772,7 +12775,8 @@
   /* Step 2: If we didn't find an exact match for point, we need to
      look for a proper place to put the cursor among glyphs between
      GLYPH_BEFORE and GLYPH_AFTER.  */
-  if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
+  if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
+	&& BUFFERP (glyph->object) && glyph->charpos == pt_old)
       && bpos_covered < pt_old)
     {
       if (row->ends_in_ellipsis_p && pos_after == last_pos)
@@ -12938,9 +12942,15 @@
       struct glyph *g1 =
 	MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
 
+      /* Don't consider glyphs that are outside TEXT_AREA.  */
+      if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
+	return 0;
       /* Keep the candidate whose buffer position is the closest to
 	 point.  */
-      if (BUFFERP (g1->object)
+      if (/* previous candidate is a glyph in TEXT_AREA of that row */
+	  w->cursor.hpos >= 0
+	  && w->cursor.hpos < MATRIX_ROW_USED(matrix, w->cursor.vpos)
+	  && BUFFERP (g1->object)
 	  && (g1->charpos == pt_old /* an exact match always wins */
 	      || (BUFFERP (glyph->object)
 		  && eabs (g1->charpos - pt_old)
--- a/src/xfns.c	Thu Apr 08 14:13:22 2010 +0000
+++ b/src/xfns.c	Fri Apr 09 12:36:12 2010 +0000
@@ -110,11 +110,6 @@
 
 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 @@
       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),
--- a/src/xmenu.c	Thu Apr 08 14:13:22 2010 +0000
+++ b/src/xmenu.c	Fri Apr 09 12:36:12 2010 +0000
@@ -81,6 +81,8 @@
 #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 @@
   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 @@
 
       /* Make menu pop down on C-g.  */
       XtOverrideTranslations (menubar_widget, override);
+      apply_systemfont_to_menu (menubar_widget);
     }
 
   {
@@ -1608,6 +1641,8 @@
                            popup_deactivate_callback,
                            menu_highlight_callback);
 
+  apply_systemfont_to_menu (menu);
+
   dummy.type = ButtonPress;
   dummy.serial = 0;
   dummy.send_event = 0;
--- a/src/xsettings.c	Thu Apr 08 14:13:22 2010 +0000
+++ b/src/xsettings.c	Fri Apr 09 12:36:12 2010 +0000
@@ -39,6 +39,7 @@
 #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;
@@ -63,9 +64,12 @@
   kbd_buffer_store_event (&event);
 }
 
+#define XSETTINGS_FONT_NAME  "Gtk/FontName"
+
 #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"
 
 /* Callback called when something changed in GConf that we care about,
    that is SYSTEM_MONO_FONT.  */
@@ -235,7 +239,7 @@
 
   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 +247,7 @@
       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 +268,14 @@
       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 +288,7 @@
           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 +308,7 @@
           return BadValue;
         }
 
-      if (is_xft) 
+      if (want_this) 
         {
           ++settings_seen;
           if (strcmp (name, "Xft/Antialias") == 0)
@@ -361,6 +366,11 @@
               else
                 settings->seen &= ~SEEN_LCDFILTER;
             }
+          else if (strcmp (name, XSETTINGS_FONT_NAME) == 0)
+            {
+              free (current_font);
+              current_font = xstrdup (sval);
+            }
         }
     }
 
@@ -571,6 +581,12 @@
       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 +651,23 @@
   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 +682,7 @@
 syms_of_xsettings ()
 {
   current_mono_font = NULL;
+  current_font = NULL;
   first_dpyinfo = NULL;
 #ifdef HAVE_GCONF
   gconf_client = NULL;
@@ -659,6 +693,7 @@
   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.  */);
--- a/src/xsettings.h	Thu Apr 08 14:13:22 2010 +0000
+++ b/src/xsettings.h	Fri Apr 09 12:36:12 2010 +0000
@@ -21,10 +21,13 @@
 #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 */