# HG changeset patch # User Katsumi Yamaoka # Date 1270816572 0 # Node ID 0346e41d1e53815c89f528f1f626d3dc87038e18 # Parent 962b581f9cc792e177f0c39cac8146cee2473b86# Parent b4880c984e2f11ccfd172fd14181078949fdd01a Merge from mainline. diff -r 962b581f9cc7 -r 0346e41d1e53 .bzrignore --- 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 diff -r 962b581f9cc7 -r 0346e41d1e53 doc/emacs/ChangeLog --- 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 + + * xresources.texi (Lucid Resources): Mention faceName to set Xft fonts. + 2010-03-30 Eli Zaretskii * mule.texi (Input Methods): Mention "C-x 8 RET" and add a diff -r 962b581f9cc7 -r 0346e41d1e53 doc/emacs/xresources.texi --- 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 diff -r 962b581f9cc7 -r 0346e41d1e53 etc/NEWS --- 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). diff -r 962b581f9cc7 -r 0346e41d1e53 lisp/ChangeLog --- 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 + + 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 - * 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 diff -r 962b581f9cc7 -r 0346e41d1e53 lisp/emacs-lisp/cl-macs.el --- 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)))) diff -r 962b581f9cc7 -r 0346e41d1e53 lwlib/ChangeLog --- 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 + + * 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 * Branch for 23.2. diff -r 962b581f9cc7 -r 0346e41d1e53 lwlib/xlwmenu.c --- 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 +#include #include #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) { diff -r 962b581f9cc7 -r 0346e41d1e53 lwlib/xlwmenu.h --- 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" diff -r 962b581f9cc7 -r 0346e41d1e53 lwlib/xlwmenuP.h --- 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 +#ifdef HAVE_XFT +#include +#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; diff -r 962b581f9cc7 -r 0346e41d1e53 src/ChangeLog --- 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 + + * xdisp.c (set_cursor_from_row): Don't dereference glyphs beyond + the end of TEXT_AREA. (Bug#5856) + +2010-04-08 Jan Djärv + + * xsettings.c (XSETTINGS_FONT_NAME): Move XSETTINGS_FONT_NAME out of + HAVE_GCONF. + +2010-04-08 Eli Zaretskii + + * 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 + + * 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 * frame.h (FRAME_TEXT_LINES_TO_PIXEL_HEIGHT): Don't use diff -r 962b581f9cc7 -r 0346e41d1e53 src/bidi.c --- 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) diff -r 962b581f9cc7 -r 0346e41d1e53 src/menu.c --- 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)) { diff -r 962b581f9cc7 -r 0346e41d1e53 src/xdisp.c --- 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) diff -r 962b581f9cc7 -r 0346e41d1e53 src/xfns.c --- 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), diff -r 962b581f9cc7 -r 0346e41d1e53 src/xmenu.c --- 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 #include #ifdef USE_LUCID +#include "xsettings.h" +#include "../lwlib/xlwmenu.h" #ifdef HAVE_XAW3D #include #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; diff -r 962b581f9cc7 -r 0346e41d1e53 src/xsettings.c --- 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. */); diff -r 962b581f9cc7 -r 0346e41d1e53 src/xsettings.h --- 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 */