>>> It is incompatible in the sense that settings in .Xresources that >>> previously >>> used >>> ...*menu*font: ... >> >>> now must use >>> ...*menu*fontSet: >> >>> for the lucid menus. This should be mentioned in NEWS. >> >> Hmm... good point. Do you happen to know how I could get the expected >> behavior that "if `font' is set but `fontSet' isn't, use `font'"?
> Basically you have to set the default to something else than the > XtDdefaultFont(Set), and then check if either has been changed. OK, I now understand how I could do that. > But better would be to just have one, as Motif has FontList. But I prefer this option as well. In the patch below I simply changed the semantics of the "font" Xresource so that it is now a fontset rather than a font: you can still specify a font, but you can now also specify a list of fonts. So it should be 100% backward compatible with users's Xresource customizations. > It is just that the default for font and fontset in Xt differs. It should > perhaps be noted in NEWS, or we should perhaps just be prepared for "why > have you changed the menu font" questions :-). I don't think that this is > a problem, it is just different. Just to make sure I understand your judgment: you think it's not important because the difference is minor, or because the "new" default (if different") is also different for other apps and so it's still considered as a legitimate default, or ... In any case, here is the new improved patch. This new patch should also enable non-ASCII in Motif menus, although I haven't actually checked it. I'll be happy to keep this patch for post-21.4, but if people feel like this is important, I can install it as well. W.r.t the fact that the menus only support chars in the user's locale rather than always support unicode, that can be changed later with an additional patch, but AFAICT the current patch would be a prerequisite anyway. Stefan --- orig/lwlib/xlwmenu.c +++ mod/lwlib/xlwmenu.c @@ -135,8 +135,13 @@ static XtResource xlwMenuResources[] = { +#ifdef HAVE_X_I18N + {XtNfont, XtCFont, XtRFontSet, sizeof(XFontSet), + offset(menu.font), XtRString, "XtDefaultFontSet"}, +#else {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), - offset(menu.font),XtRString, "XtDefaultFont"}, + offset(menu.font), XtRString, "XtDefaultFont"}, +#endif {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), offset(menu.foreground), XtRString, "XtDefaultForeground"}, {XtNdisabledForeground, XtCDisabledForeground, XtRPixel, sizeof(Pixel), @@ -235,7 +240,7 @@ XtNumber(xlwMenuResources), /* resource_count */ NULLQUARK, /* xrm_class */ TRUE, /* compress_motion */ - TRUE, /* compress_exposure */ + XtExposeCompressMaximal, /* compress_exposure */ TRUE, /* compress_enterleave */ FALSE, /* visible_interest */ XlwMenuDestroy, /* destroy */ @@ -353,18 +358,30 @@ XlwMenuWidget mw; char *s; { +#ifdef HAVE_X_I18N + XRectangle ink, logical; + XmbTextExtents (mw->menu.font, s, strlen (s), &ink, &logical); + return logical.width; +#else XCharStruct xcs; int drop; XTextExtents (mw->menu.font, s, strlen (s), &drop, &drop, &drop, &xcs); return xcs.width; +#endif } static int arrow_width (mw) XlwMenuWidget mw; { - return (mw->menu.font->ascent * 3/4) | 1; + return ( +#ifdef HAVE_X_I18N + mw->menu.font_extents->max_logical_extent.height * 9 / 10 +#else + mw->menu.font->ascent +#endif + * 3/4) | 1; } /* Return the width of toggle buttons of widget MW. */ @@ -373,7 +390,13 @@ toggle_button_width (mw) XlwMenuWidget mw; { - return ((mw->menu.font->ascent + mw->menu.font->descent) * 2 / 3) | 1; + return (( +#ifdef HAVE_X_I18N + mw->menu.font_extents->max_logical_extent.height +#else + mw->menu.font->ascent + mw->menu.font->descent +#endif + ) * 2 / 3) | 1; } @@ -455,7 +478,11 @@ else { *height = - mw->menu.font->ascent + mw->menu.font->descent +#ifdef HAVE_X_I18N + mw->menu.font_extents->max_logical_extent.height +#else + mw->menu.font->ascent + mw->menu.font->descent +#endif + 2 * mw->menu.vertical_spacing + 2 * mw->menu.shadow_thickness; *label_width = @@ -571,7 +598,13 @@ double factor = 1.62; int thickness2 = thickness * factor; - y += (mw->menu.font->ascent + mw->menu.font->descent - height) / 2; + y += ( +#ifdef HAVE_X_I18N + mw->menu.font_extents->max_logical_extent.height +#else + mw->menu.font->ascent + mw->menu.font->descent +#endif + - height) / 2; if (down_p) { @@ -757,7 +790,13 @@ width = toggle_button_width (mw); height = width; x += mw->menu.horizontal_spacing; - y += (mw->menu.font->ascent - height) / 2; + y += ( +#ifdef HAVE_X_I18N + mw->menu.font_extents->max_logical_extent.height * 9 / 10 +#else + mw->menu.font->ascent +#endif + - height) / 2; draw_shadow_rectangle (mw, window, x, y, width, height, False, selected_p); } @@ -777,7 +816,13 @@ width = radio_button_width (mw); height = width; x += mw->menu.horizontal_spacing; - y += (mw->menu.font->ascent - height) / 2; + y += ( +#ifdef HAVE_X_I18N + mw->menu.font_extents->max_logical_extent.height * 9 / 10 +#else + mw->menu.font->ascent +#endif + - height) / 2; draw_shadow_rhombus (mw, window, x, y, width, height, False, selected_p); } @@ -954,8 +999,18 @@ { GC deco_gc; GC text_gc; - int font_ascent = mw->menu.font->ascent; - int font_descent = mw->menu.font->descent; + int font_height = +#ifdef HAVE_X_I18N + mw->menu.font_extents->max_logical_extent.height; +#else + mw->menu.font->ascent + mw->menu.font->descent; +#endif + int font_ascent = +#ifdef HAVE_X_I18N + mw->menu.font_extents->max_logical_extent.height * 9 / 10; +#else + mw->menu.font->ascent; +#endif int shadow = mw->menu.shadow_thickness; int margin = mw->menu.margin; int h_spacing = mw->menu.horizontal_spacing; @@ -1028,7 +1083,12 @@ x_offset += ws->button_width; - XDrawString (XtDisplay (mw), ws->window, text_gc, x_offset, +#ifdef HAVE_X_I18N + XmbDrawString (XtDisplay (mw), ws->window, mw->menu.font, +#else + XDrawString (XtDisplay (mw), ws->window, +#endif + text_gc, x_offset, y + v_spacing + shadow + font_ascent, display_string, strlen (display_string)); @@ -1053,7 +1113,12 @@ } else if (val->key) { - XDrawString (XtDisplay (mw), ws->window, text_gc, +#ifdef HAVE_X_I18N + XmbDrawString (XtDisplay (mw), ws->window, mw->menu.font, +#else + XDrawString (XtDisplay (mw), ws->window, +#endif + text_gc, x + label_width + mw->menu.arrow_spacing, y + v_spacing + shadow + font_ascent, val->key, strlen (val->key)); @@ -1065,7 +1130,7 @@ mw->menu.background_gc, x + shadow, y + shadow, label_width + h_spacing - 1, - font_ascent + font_descent + 2 * v_spacing - 1); + font_height + 2 * v_spacing - 1); draw_shadow_rectangle (mw, ws->window, x, y, width, height, True, False); } @@ -1460,21 +1525,33 @@ XGCValues xgcv; float scale; +#ifndef HAVE_X_I18N xgcv.font = mw->menu.font->fid; +#endif xgcv.foreground = mw->menu.foreground; xgcv.background = mw->core.background_pixel; mw->menu.foreground_gc = XtGetGC ((Widget)mw, - GCFont | GCForeground | GCBackground, +#ifndef HAVE_X_I18N + GCFont | +#endif + GCForeground | GCBackground, &xgcv); +#ifndef HAVE_X_I18N xgcv.font = mw->menu.font->fid; +#endif xgcv.foreground = mw->menu.button_foreground; xgcv.background = mw->core.background_pixel; mw->menu.button_gc = XtGetGC ((Widget)mw, - GCFont | GCForeground | GCBackground, +#ifndef HAVE_X_I18N + GCFont | +#endif + GCForeground | GCBackground, &xgcv); +#ifndef HAVE_X_I18N xgcv.font = mw->menu.font->fid; +#endif xgcv.background = mw->core.background_pixel; #define BRIGHTNESS(color) (((color) & 0xff) + (((color) >> 8) & 0xff) + (((color) >> 16) & 0xff)) @@ -1500,31 +1577,47 @@ xgcv.fill_style = FillStippled; xgcv.stipple = mw->menu.gray_pixmap; mw->menu.disabled_gc = XtGetGC ((Widget)mw, - (GCFont | GCForeground | GCBackground - | GCFillStyle | GCStipple), &xgcv); +#ifndef HAVE_X_I18N + GCFont | +#endif + GCForeground | GCBackground + | GCFillStyle | GCStipple, &xgcv); } else { /* Many colors available, use disabled pixel. */ xgcv.foreground = mw->menu.disabled_foreground; mw->menu.disabled_gc = XtGetGC ((Widget)mw, - (GCFont | GCForeground | GCBackground), &xgcv); +#ifndef HAVE_X_I18N + GCFont | +#endif + GCForeground | GCBackground, &xgcv); } +#ifndef HAVE_X_I18N xgcv.font = mw->menu.font->fid; +#endif xgcv.foreground = mw->menu.button_foreground; xgcv.background = mw->core.background_pixel; xgcv.fill_style = FillStippled; xgcv.stipple = mw->menu.gray_pixmap; mw->menu.inactive_button_gc = XtGetGC ((Widget)mw, - (GCFont | GCForeground | GCBackground - | GCFillStyle | GCStipple), &xgcv); +#ifndef HAVE_X_I18N + GCFont | +#endif + GCForeground | GCBackground + | GCFillStyle | GCStipple, &xgcv); +#ifndef HAVE_X_I18N xgcv.font = mw->menu.font->fid; +#endif xgcv.foreground = mw->core.background_pixel; xgcv.background = mw->menu.foreground; mw->menu.background_gc = XtGetGC ((Widget)mw, - GCFont | GCForeground | GCBackground, +#ifndef HAVE_X_I18N + GCFont | +#endif + GCForeground | GCBackground, &xgcv); } @@ -1731,12 +1824,16 @@ gray_bitmap_width, gray_bitmap_height, (unsigned long)1, (unsigned long)0, 1); +#ifndef HAVE_X_I18N /* 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; - +#else + mw->menu.font_extents = XExtentsOfFontSet (mw->menu.font); +#endif + make_drawing_gcs (mw); make_shadow_gcs (mw); @@ -1903,7 +2000,10 @@ if (newmw->core.background_pixel != oldmw->core.background_pixel || newmw->menu.foreground != oldmw->menu.foreground - || newmw->menu.font != oldmw->menu.font) +#ifndef HAVE_X_I18N + || newmw->menu.font != oldmw->menu.font +#endif + ) { release_drawing_gcs (newmw); make_drawing_gcs (newmw); @@ -1929,6 +2029,14 @@ } } +#ifdef HAVE_X_I18N + if (newmw->menu.font != oldmw->menu.font) + { + redisplay = True; + newmw->menu.font_extents = XExtentsOfFontSet (newmw->menu.font); + } +#endif + return redisplay; } --- orig/lwlib/xlwmenuP.h +++ mod/lwlib/xlwmenuP.h @@ -43,7 +43,12 @@ typedef struct _XlwMenu_part { /* slots set by the resources */ +#ifdef HAVE_X_I18N + XFontSet font; + XFontSetExtents *font_extents; +#else XFontStruct* font; +#endif Pixel foreground; Pixel disabled_foreground; Pixel button_foreground; --- orig/src/xmenu.c +++ mod/src/xmenu.c @@ -137,6 +137,8 @@ #ifdef USE_GTK /* gtk just uses utf-8. */ # define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str) +#elif defined HAVE_X_I18N +# define ENCODE_MENU_STRING(str) ENCODE_SYSTEM (str) #else # define ENCODE_MENU_STRING(str) string_make_unibyte (str) #endif --- orig/src/xfaces.c +++ mod/src/xfaces.c @@ -4695,13 +4695,25 @@ #else const char *suffix = ""; #endif +#ifdef HAVE_X_I18N + /* Let's build an Xt fontset corresponding to a face. + Maybe we should try and use Mule fontsets more directly, but + for now, we'll stick to this simple solution. --Stef */ + extern char * xic_create_fontsetname P_ ((char *base_fontname)); + char *fontname = xic_create_fontsetname (face->font_name); +#else + char *fontname = face->font_name; +#endif + fprintf (stderr, "Setting menu's font : %s\n", fontname); sprintf (line, "%s.pane.menubar*font%s: %s", - myname, suffix, face->font_name); + myname, suffix, fontname); XrmPutLineResource (&rdb, line); sprintf (line, "%s.%s*font%s: %s", - myname, popup_path, suffix, face->font_name); + myname, popup_path, suffix, fontname); XrmPutLineResource (&rdb, line); changed_p = 1; + if (fontname != face->font_name) + xfree (fontname); } if (changed_p && f->output_data.x->menubar_widget) _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel