emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r99850: Lucid menus can now use Xft f


From: Jan D.
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r99850: Lucid menus can now use Xft for fonts.
Date: Thu, 08 Apr 2010 18:21:25 +0200
User-agent: Bazaar (2.0.3)

------------------------------------------------------------
revno: 99850 [merge]
committer: Jan D. <address@hidden>
branch nick: trunk
timestamp: Thu 2010-04-08 18:21:25 +0200
message:
  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.
modified:
  doc/emacs/ChangeLog
  doc/emacs/xresources.texi
  etc/NEWS
  lwlib/ChangeLog
  lwlib/xlwmenu.c
  lwlib/xlwmenu.h
  lwlib/xlwmenuP.h
  src/ChangeLog
  src/menu.c
  src/xfns.c
  src/xmenu.c
  src/xsettings.c
  src/xsettings.h
=== modified file 'doc/emacs/ChangeLog'
--- a/doc/emacs/ChangeLog       2010-03-31 02:37:57 +0000
+++ b/doc/emacs/ChangeLog       2010-04-08 16:20:32 +0000
@@ -1,3 +1,7 @@
+2010-04-08  Jan Djärv  <address@hidden>
+
+       * xresources.texi (Lucid Resources): Mention faceName to set Xft fonts.
+
 2010-03-30  Eli Zaretskii  <address@hidden>
 
        * mule.texi (Input Methods): Mention "C-x 8 RET" and add a

=== modified file 'doc/emacs/xresources.texi'
--- a/doc/emacs/xresources.texi 2010-03-22 07:26:56 +0000
+++ b/doc/emacs/xresources.texi 2010-04-08 16:20:32 +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,32 +423,35 @@
 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
address@hidden for the menu-bar items, write this:
address@hidden for the menu-bar items, write this:
 @end iftex
 
 @example
-Emacs.pane.menubar.font:  8x16
address@hidden example
-
address@hidden
-Resources for @emph{non-menubar} toolkit pop-up menus have
address@hidden instead of @samp{pane.menubar}.  For example, to specify
-the font @samp{8x16} for the pop-up menu items, write this:
-
address@hidden
-Emacs.menu*.font:      8x16
address@hidden example
-
address@hidden
-For dialog boxes, use @samp{dialog*}:
-
address@hidden
-Emacs.dialog*.font:    8x16
address@hidden example
-
address@hidden
-The Lucid menus can display multilingual text in your locale.  For
-more information about fontsets see the man page for
+Emacs.pane.menubar.faceName:  Courier-12
address@hidden example
+
address@hidden
+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}:
+
address@hidden
+Emacs.pane.menubar.faceName:   none
address@hidden example
+
address@hidden
+To specify a non-Xft font, use @code{font}.  For example:
+
address@hidden
+Emacs.pane.menubar.font: lucidasanstypewriter-10
address@hidden example
+
address@hidden
+The Lucid menus can display multilingual text in your locale with old style
+fonts.  For more information about fontsets see the man page for
 @code{XCreateFontSet}.  To enable multilingual menu text you specify a
 @code{fontSet} resource instead of the font resource.  If both
 @code{font} and @code{fontSet} resources are specified, the
@@ -462,6 +465,22 @@
 @end example
 
 @noindent
+Resources for @emph{non-menubar} toolkit pop-up menus have
address@hidden instead of @samp{pane.menubar}.  For example, to specify
+the font @samp{8x16} for the pop-up menu items, write this:
+
address@hidden
+Emacs.menu*.font:      8x16
address@hidden example
+
address@hidden
+For dialog boxes, use @samp{dialog*}:
+
address@hidden
+Emacs.dialog*.font:    8x16
address@hidden example
+
address@hidden
 The @samp{*menu*} as a wildcard matches @samp{pane.menubar} and
 @address@hidden
 
@@ -473,6 +492,8 @@
   Here is a list of the specific resources for menu bars and pop-up menus:
 
 @table @code
address@hidden faceName
+Xft font for menu item text.
 @item font
 Font for menu item text.
 @item fontSet

=== modified file 'etc/NEWS'
--- a/etc/NEWS  2010-04-07 05:56:35 +0000
+++ b/etc/NEWS  2010-04-08 16:20:32 +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).

=== modified file 'lwlib/ChangeLog'
--- a/lwlib/ChangeLog   2010-03-10 15:17:13 +0000
+++ b/lwlib/ChangeLog   2010-04-08 16:20:32 +0000
@@ -1,3 +1,34 @@
+2010-04-08  Jan Djärv  <address@hidden>
+
+       * 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  <address@hidden>
 
        * Branch for 23.2.

=== modified file 'lwlib/xlwmenu.c'
--- a/lwlib/xlwmenu.c   2010-01-13 08:35:10 +0000
+++ b/lwlib/xlwmenu.c   2010-04-08 16:20:32 +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)
     {

=== modified file 'lwlib/xlwmenu.h'
--- a/lwlib/xlwmenu.h   2010-01-13 08:35:10 +0000
+++ b/lwlib/xlwmenu.h   2010-04-08 16:20:32 +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"

=== modified file 'lwlib/xlwmenuP.h'
--- a/lwlib/xlwmenuP.h  2010-01-13 08:35:10 +0000
+++ b/lwlib/xlwmenuP.h  2010-04-08 16:20:32 +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;

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2010-04-07 11:39:26 +0000
+++ b/src/ChangeLog     2010-04-08 16:20:32 +0000
@@ -1,3 +1,29 @@
+2010-04-08  Jan Djärv  <address@hidden>
+
+       * 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  <address@hidden>
 
        * frame.h (FRAME_TEXT_LINES_TO_PIXEL_HEIGHT): Don't use

=== modified file 'src/menu.c'
--- a/src/menu.c        2010-03-30 23:26:38 +0000
+++ b/src/menu.c        2010-04-08 16:20:32 +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))
            {

=== modified file 'src/xfns.c'
--- a/src/xfns.c        2010-04-05 07:35:53 +0000
+++ b/src/xfns.c        2010-04-08 16:20:32 +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),

=== modified file 'src/xmenu.c'
--- a/src/xmenu.c       2010-01-13 08:35:10 +0000
+++ b/src/xmenu.c       2010-04-08 16:20:32 +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;

=== modified file 'src/xsettings.c'
--- a/src/xsettings.c   2010-01-19 14:54:13 +0000
+++ b/src/xsettings.c   2010-04-08 16:20:32 +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;
@@ -65,7 +66,9 @@
 
 #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 @@
 
   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 @@
       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 @@
       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 @@
           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 @@
           return BadValue;
         }
 
-      if (is_xft) 
+      if (want_this) 
         {
           ++settings_seen;
           if (strcmp (name, "Xft/Antialias") == 0)
@@ -361,6 +365,11 @@
               else
                 settings->seen &= ~SEEN_LCDFILTER;
             }
+          else if (strcmp (name, XSETTINGS_FONT_NAME) == 0)
+            {
+              free (current_font);
+              current_font = xstrdup (sval);
+            }
         }
     }
 
@@ -571,6 +580,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 +650,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 +681,7 @@
 syms_of_xsettings ()
 {
   current_mono_font = NULL;
+  current_font = NULL;
   first_dpyinfo = NULL;
 #ifdef HAVE_GCONF
   gconf_client = NULL;
@@ -659,6 +692,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.  */);

=== modified file 'src/xsettings.h'
--- a/src/xsettings.h   2010-01-13 08:35:10 +0000
+++ b/src/xsettings.h   2010-04-08 16:20:32 +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 */


reply via email to

[Prev in Thread] Current Thread [Next in Thread]