From 99852628a828979c55c96d7def6c5a21f2b32af5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Dj=C3=A4rv?= Date: Thu, 8 Apr 2010 18:20:32 +0200 Subject: [PATCH] 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. --- doc/emacs/ChangeLog | 4 + doc/emacs/xresources.texi | 43 +++++-- etc/NEWS | 2 + lwlib/ChangeLog | 31 +++++ lwlib/xlwmenu.c | 242 ++++++++++++++++++++++++++++++++++++-- lwlib/xlwmenu.h | 4 + lwlib/xlwmenuP.h | 13 ++ src/ChangeLog | 26 ++++ src/menu.c | 18 +++ src/xfns.c | 13 -- src/xmenu.c | 35 ++++++ src/xsettings.c | 48 ++++++-- src/xsettings.h | 3 + 13 files changed, 441 insertions(+), 41 deletions(-) diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog index c0a0539a01..8cb082d64e 100644 --- a/doc/emacs/ChangeLog +++ b/doc/emacs/ChangeLog @@ -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 --git a/doc/emacs/xresources.texi b/doc/emacs/xresources.texi index 75b6e3bbe4..4e4f3ad87a 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 @@ -461,6 +464,22 @@ for both the popup and menu bar menus, write this: 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 f555c8689a..a21f7967c2 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 9bea2c13db..189e2c65e1 100644 --- a/lwlib/ChangeLog +++ b/lwlib/ChangeLog @@ -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 --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c index 2ae7ae57e7..3e8259f9a1 100644 --- a/lwlib/xlwmenu.c +++ b/lwlib/xlwmenu.c @@ -30,6 +30,7 @@ Boston, MA 02110-1301, USA. */ #include "lisp.h" #include +#include #include #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 [] = @@ -127,6 +128,13 @@ xlwMenuResources[] = #ifdef HAVE_X_I18N {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"}, @@ -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 4f2c6cc445..a58fd00c1e 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 e98d657bfa..39afcc6ca7 100644 --- a/lwlib/xlwmenuP.h +++ b/lwlib/xlwmenuP.h @@ -25,6 +25,9 @@ Boston, MA 02110-1301, USA. */ #include "xlwmenu.h" #include +#ifdef HAVE_XFT +#include +#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; @@ -48,6 +55,12 @@ typedef struct _XlwMenu_part #ifdef HAVE_X_I18N 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; diff --git a/src/ChangeLog b/src/ChangeLog index 455deff0aa..51ed028b9d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,29 @@ +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 --git a/src/menu.c b/src/menu.c index bfe54a5332..ca00c06a98 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 4ec13b7e50..647526cc22 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 64e55b7413..de2f4eb681 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -81,6 +81,8 @@ along with GNU Emacs. If not, see . */ #include #include #ifdef USE_LUCID +#include "xsettings.h" +#include "../lwlib/xlwmenu.h" #ifdef HAVE_XAW3D #include #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 945007db2f..b71871df57 100644 --- a/src/xsettings.c +++ b/src/xsettings.c @@ -39,6 +39,7 @@ along with GNU Emacs. If not, see . */ #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 6c603e5bbd..f6399ea1bc 100644 --- a/src/xsettings.h +++ b/src/xsettings.h @@ -21,10 +21,13 @@ along with GNU Emacs. If not, see . */ #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 */ -- 2.20.1