# HG changeset patch # User Stefan Monnier # Date 1111119581 0 # Node ID 3e557e11645e7fdf24ba8682cd37e090eeea3b0d # Parent d9c9ad74e719d0201f0d040f18a74222ebb59482 Add support for I18N to Lucid menus. * xlwmenuP.h (struct _XlwMenu_part) [HAVE_X_I18N]: Change `font' to be a fontset. Add a `font_extents' element. * xlwmenu.c (xlwMenuResources) [HAVE_X_I18N]: Use a fontset for the `font' resource. (string_width) [HAVE_X_I18N]: Use XmbTextExtents; (MENU_FONT_HEIGHT, MENU_FONT_ASCENT): New macros. (arrow_width, toggle_button_width, size_menu_item, draw_arrow) (draw_toggle, draw_radio, display_menu_item): Use them. (display_menu_item) [HAVE_X_I18N]: Use XmbDrawString. (make_drawing_gcs) [HAVE_X_I18N]: Don't mess with fonts. (XlwMenuInitialize) [HAVE_X_I18N]: Initialize font_extents. (XlwMenuSetValues) [HAVE_X_I18N]: Refresh font_extents if font changes. diff -r d9c9ad74e719 -r 3e557e11645e lwlib/ChangeLog --- a/lwlib/ChangeLog Fri Mar 18 02:53:44 2005 +0000 +++ b/lwlib/ChangeLog Fri Mar 18 04:19:41 2005 +0000 @@ -1,5 +1,21 @@ 2005-03-17 Stefan Monnier + Add support for I18N to Lucid menus. + + * xlwmenuP.h (struct _XlwMenu_part) [HAVE_X_I18N]: Change `font' to be + a fontset. Add a `font_extents' element. + + * xlwmenu.c (xlwMenuResources) [HAVE_X_I18N]: Use a fontset for the + `font' resource. + (string_width) [HAVE_X_I18N]: Use XmbTextExtents; + (MENU_FONT_HEIGHT, MENU_FONT_ASCENT): New macros. + (arrow_width, toggle_button_width, size_menu_item, draw_arrow) + (draw_toggle, draw_radio, display_menu_item): Use them. + (display_menu_item) [HAVE_X_I18N]: Use XmbDrawString. + (make_drawing_gcs) [HAVE_X_I18N]: Don't mess with fonts. + (XlwMenuInitialize) [HAVE_X_I18N]: Initialize font_extents. + (XlwMenuSetValues) [HAVE_X_I18N]: Refresh font_extents if font changes. + * lwlib-Xm.c (xm_update_label, xm_update_list): Use the recommended XmStringCreateLocalized function. Add missing copyright. diff -r d9c9ad74e719 -r 3e557e11645e lwlib/xlwmenu.c --- a/lwlib/xlwmenu.c Fri Mar 18 02:53:44 2005 +0000 +++ b/lwlib/xlwmenu.c Fri Mar 18 04:19:41 2005 +0000 @@ -1,6 +1,6 @@ /* Implements a lightweight menubar widget. Copyright (C) 1992 Lucid, Inc. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 Free Software Foundation, Inc. This file is part of the Lucid Widget Library. @@ -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,34 @@ 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 } +#ifdef HAVE_X_I18N +#define MENU_FONT_HEIGHT(mw) \ + ((mw)->menu.font_extents->max_logical_extent.height) +#define MENU_FONT_ASCENT(mw) (MENU_FONT_HEIGHT(mw) * 9 / 10) +#else +#define MENU_FONT_HEIGHT(mw) \ + ((mw)->menu.font->ascent + (mw)->menu.font->descent) +#define MENU_FONT_ASCENT(mw) ((mw)->menu.font->ascent) +#endif + static int arrow_width (mw) XlwMenuWidget mw; { - return (mw->menu.font->ascent * 3/4) | 1; + return (MENU_FONT_ASCENT (mw) * 3/4) | 1; } /* Return the width of toggle buttons of widget MW. */ @@ -373,7 +394,7 @@ toggle_button_width (mw) XlwMenuWidget mw; { - return ((mw->menu.font->ascent + mw->menu.font->descent) * 2 / 3) | 1; + return (MENU_FONT_HEIGHT (mw) * 2 / 3) | 1; } @@ -454,9 +475,8 @@ } else { - *height = - mw->menu.font->ascent + mw->menu.font->descent - + 2 * mw->menu.vertical_spacing + 2 * mw->menu.shadow_thickness; + *height = MENU_FONT_HEIGHT (mw) + + 2 * mw->menu.vertical_spacing + 2 * mw->menu.shadow_thickness; *label_width = string_width (mw, resource_widget_value (mw, val)) @@ -571,7 +591,7 @@ double factor = 1.62; int thickness2 = thickness * factor; - y += (mw->menu.font->ascent + mw->menu.font->descent - height) / 2; + y += (MENU_FONT_HEIGHT (mw) - height) / 2; if (down_p) { @@ -757,7 +777,7 @@ width = toggle_button_width (mw); height = width; x += mw->menu.horizontal_spacing; - y += (mw->menu.font->ascent - height) / 2; + y += (MENU_FONT_ASCENT (mw) - height) / 2; draw_shadow_rectangle (mw, window, x, y, width, height, False, selected_p); } @@ -777,7 +797,7 @@ width = radio_button_width (mw); height = width; x += mw->menu.horizontal_spacing; - y += (mw->menu.font->ascent - height) / 2; + y += (MENU_FONT_ASCENT (mw) - height) / 2; draw_shadow_rhombus (mw, window, x, y, width, height, False, selected_p); } @@ -954,8 +974,8 @@ { GC deco_gc; GC text_gc; - int font_ascent = mw->menu.font->ascent; - int font_descent = mw->menu.font->descent; + int font_height = MENU_FONT_HEIGHT (mw); + int font_ascent = MENU_FONT_ASCENT (mw); int shadow = mw->menu.shadow_thickness; int margin = mw->menu.margin; int h_spacing = mw->menu.horizontal_spacing; @@ -1028,7 +1048,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 +1078,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 +1095,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 +1490,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 +1542,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 +1789,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 +1965,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 +1994,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; } diff -r d9c9ad74e719 -r 3e557e11645e lwlib/xlwmenuP.h --- a/lwlib/xlwmenuP.h Fri Mar 18 02:53:44 2005 +0000 +++ b/lwlib/xlwmenuP.h Fri Mar 18 04:19:41 2005 +0000 @@ -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;