Mercurial > hg > xemacs-beta
diff lwlib/xlwmenu.c @ 5118:e0db3c197671 ben-lisp-object
merge up to latest default branch, doesn't compile yet
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sat, 26 Dec 2009 21:18:49 -0600 |
parents | 726060ee587c |
children | a6c778975d7d |
line wrap: on
line diff
--- a/lwlib/xlwmenu.c Sat Dec 26 00:20:27 2009 -0600 +++ b/lwlib/xlwmenu.c Sat Dec 26 21:18:49 2009 -0600 @@ -45,6 +45,11 @@ #define XmFONTLIST_DEFAULT_TAG XmSTRING_DEFAULT_CHARSET #endif /* XmVersion < 1.2 */ #endif + +/* #### we may want to turn off USE_XFT here if !USE_XFT_MENUBARS + In fact, maybe that's the right interface overall? */ +#include "lwlib-fonts.h" +#include "lwlib-colors.h" #include "xlwmenuP.h" #ifdef USE_DEBUG_MALLOC @@ -65,91 +70,112 @@ extern Widget lw_menubar_widget; -#define offset(field) XtOffset(XlwMenuWidget, field) static XtResource xlwMenuResources[] = { -#ifdef NEED_MOTIF +/* The offset macro is a standard trick. The remaining macros are an + experiment to compress redundancies in resource descriptions, and shut + up GCC 4.3 (the String casts, which keep G++ from complaining about + implicit conversions from const char *). */ +#define offset(field) XtOffset(XlwMenuWidget, menu.field) +#define fontres(name,_class,repr,type,member,value) \ + Xt_RESOURCE (name, _class, repr, type, offset(member), XtRString, value) +#define mflres(name,cls,member,repr,value) \ + Xt_RESOURCE (name, cls, XmRFontList, XmFontList, offset(member), repr, value) +#define dimres(name,cls,repr,member,value) \ + Xt_RESOURCE (name, cls, repr, Dimension, offset(member), XtRImmediate, value) +#define boolres(nm,cls,member,val) \ + Xt_RESOURCE (nm, cls, XtRBoolean, Boolean, offset(member), XtRImmediate, val) +#define cbres(name,member,value) \ + Xt_RESOURCE (name, XtCCallback, XtRCallback, XtPointer, offset(member), \ + XtRCallback, value) +#define pixres(name,_class,member,repr,value) \ + Xt_RESOURCE (name, _class, XtRPixel, Pixel, offset(member), repr, value) +#define fgpixres(name,_class,member) \ + pixres (name, _class, member, XtRString, "XtDefaultForeground") +#define nullpixres(name,_class,member) \ + pixres (name, _class, member, XtRImmediate, -1) +#define pmres(name,cls,member) \ + Xt_RESOURCE (name, cls, XtRPixmap, Pixmap, offset(member), XtRImmediate, None) + +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) /* There are three font list resources, so that we can accept either of the resources *fontList: or *font:, and so that we can tell the difference between them being specified, and being defaulted to a font from the XtRString specified here. */ - {XmNfontList, XmCFontList, XmRFontList, sizeof(XmFontList), - offset(menu.font_list), XtRImmediate, (XtPointer)0}, - {XtNfont, XtCFont, XmRFontList, sizeof(XmFontList), - offset(menu.font_list_2),XtRImmediate, (XtPointer)0}, - {XmNfontList, XmCFontList, XmRFontList, sizeof(XmFontList), - offset(menu.fallback_font_list), + mflres (XmNfontList, XmCFontList, font_list, XtRImmediate, 0), + mflres (XtNfont, XtCFont, font_list_2, XtRImmediate, 0), + mflres (XmNfontList, XmCFontList, fallback_font_list, /* We must use an iso8859-1 font here, or people without $LANG set lose. It's fair to assume that those who do have $LANG set also have the *fontList resource set, or at least know how to deal with this. */ - XtRString, (XtPointer) "-*-helvetica-bold-r-*-*-*-120-*-*-*-*-iso8859-1"}, + XtRString, (XtPointer) "-*-helvetica-bold-r-*-*-*-120-*-*-*-*-iso8859-1"), #else - {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), - offset(menu.font), XtRString, (XtPointer) "XtDefaultFont"}, + fontres (XtNfont, XtCFont, XtRFontStruct, XFontStruct *, font, + "XtDefaultFont"), +#ifdef USE_XFT_MENUBARS + fontres (XtNfcFontName, XtCFcFontName, XtRString, String, fcFontName, + "sans-serif-12:bold"), + /* #### This needs to be fixed to give a proper type and converter for + XftFonts. See also xlwtabs.c. */ + fontres (XtNxftFont, XtCXftFont, XtRString, XtPointer, xftFontName, + "Helvetica-12:bold"), +#endif # ifdef USE_XFONTSET /* #### Consider using the same method as for Motif; see the comment in XlwMenuInitialize(). */ - {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet), - offset(menu.font_set), XtRString, (XtPointer) "XtDefaultFontSet"}, + fontres (XtNfontSet, XtCFontSet, XtRFontSet, XFontSet, font_set, + "XtDefaultFontSet"), # endif #endif - {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), - offset(menu.foreground), XtRString, (XtPointer) "XtDefaultForeground"}, - {XtNbuttonForeground, XtCButtonForeground, XtRPixel, sizeof(Pixel), - offset(menu.button_foreground), XtRString, (XtPointer) "XtDefaultForeground"}, - {XtNhighlightForeground, XtCHighlightForeground, XtRPixel, sizeof(Pixel), - offset(menu.highlight_foreground), XtRString, (XtPointer) "XtDefaultForeground"}, - {XtNtitleForeground, XtCTitleForeground, XtRPixel, sizeof(Pixel), - offset(menu.title_foreground), XtRString, (XtPointer) "XtDefaultForeground"}, - {XtNmargin, XtCMargin, XtRDimension, sizeof(Dimension), - offset(menu.margin), XtRImmediate, (XtPointer)2}, - {XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension, sizeof(Dimension), - offset(menu.horizontal_margin), XtRImmediate, (XtPointer)2}, - {XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension, sizeof(Dimension), - offset(menu.vertical_margin), XtRImmediate, (XtPointer)1}, - {XmNspacing, XmCSpacing, XmRHorizontalDimension, sizeof(Dimension), - offset(menu.column_spacing), XtRImmediate, (XtPointer)4}, - {XmNindicatorSize, XmCIndicatorSize, XtRDimension, sizeof(Dimension), - offset(menu.indicator_size), XtRImmediate, (XtPointer)0}, + fgpixres (XtNforeground, XtCForeground, foreground), + fgpixres (XtNbuttonForeground, XtCButtonForeground, button_foreground), + fgpixres (XtNhighlightForeground, XtCHighlightForeground, + highlight_foreground), + fgpixres (XtNtitleForeground, XtCTitleForeground, title_foreground), + dimres (XtNmargin, XtCMargin, XtRDimension, margin, 2), + dimres (XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension, + horizontal_margin, 2), + dimres (XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension, + vertical_margin, 1), + dimres (XmNspacing, XmCSpacing, XmRHorizontalDimension, column_spacing, 4), + dimres (XmNindicatorSize, XmCIndicatorSize, XtRDimension, indicator_size, 0), #if 0 - {XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension, - sizeof (Dimension), offset (menu.shadow_thickness), - XtRImmediate, (XtPointer) 2}, + dimres (XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension, + shadow_thickness, 2), #else - {XmNshadowThickness, XmCShadowThickness, XtRDimension, - sizeof (Dimension), offset (menu.shadow_thickness), - XtRImmediate, (XtPointer) 2}, + dimres (XmNshadowThickness, XmCShadowThickness, XtRDimension, + shadow_thickness, 2), #endif - {XmNselectColor, XmCSelectColor, XtRPixel, sizeof (Pixel), - offset (menu.select_color), XtRImmediate, (XtPointer)-1}, - {XmNtopShadowColor, XmCTopShadowColor, XtRPixel, sizeof (Pixel), - offset (menu.top_shadow_color), XtRImmediate, (XtPointer)-1}, - {XmNbottomShadowColor, XmCBottomShadowColor, XtRPixel, sizeof (Pixel), - offset (menu.bottom_shadow_color), XtRImmediate, (XtPointer)-1}, - {XmNtopShadowPixmap, XmCTopShadowPixmap, XtRPixmap, sizeof (Pixmap), - offset (menu.top_shadow_pixmap), XtRImmediate, (XtPointer)None}, - {XmNbottomShadowPixmap, XmCBottomShadowPixmap, XtRPixmap, sizeof (Pixmap), - offset (menu.bottom_shadow_pixmap), XtRImmediate, (XtPointer)None}, - - {XtNopen, XtCCallback, XtRCallback, sizeof(XtPointer), - offset(menu.open), XtRCallback, (XtPointer)NULL}, - {XtNselect, XtCCallback, XtRCallback, sizeof(XtPointer), - offset(menu.select), XtRCallback, (XtPointer)NULL}, - {XtNmenu, XtCMenu, XtRPointer, sizeof(XtPointer), - offset(menu.contents), XtRImmediate, (XtPointer)NULL}, - {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor), - offset(menu.cursor_shape), XtRString, (XtPointer) "right_ptr"}, - {XtNhorizontal, XtCHorizontal, XtRInt, sizeof(int), - offset(menu.horizontal), XtRImmediate, (XtPointer)True}, - {XtNuseBackingStore, XtCUseBackingStore, XtRBoolean, sizeof (Boolean), - offset (menu.use_backing_store), XtRImmediate, (XtPointer)False}, - {XtNbounceDown, XtCBounceDown, XtRBoolean, sizeof (Boolean), - offset (menu.bounce_down), XtRImmediate, (XtPointer)True}, - {XtNresourceLabels, XtCResourceLabels, XtRBoolean, sizeof (Boolean), - offset (menu.lookup_labels), XtRImmediate, (XtPointer)False}, + nullpixres (XmNselectColor, XmCSelectColor, select_color), + nullpixres (XmNtopShadowColor, XmCTopShadowColor, top_shadow_color), + nullpixres (XmNbottomShadowColor, XmCBottomShadowColor, bottom_shadow_color), + pmres (XmNtopShadowPixmap, XmCTopShadowPixmap, top_shadow_pixmap), + pmres (XmNbottomShadowPixmap, XmCBottomShadowPixmap, bottom_shadow_pixmap), + + cbres (XtNopen, open, NULL), + cbres (XtNselect, select, NULL), + Xt_RESOURCE (XtNmenu, XtCMenu, XtRPointer, XtPointer, offset(contents), + XtRImmediate, NULL), + Xt_RESOURCE (XtNcursor, XtCCursor, XtRCursor, Cursor, offset(cursor_shape), + XtRString, "right_ptr"), + Xt_RESOURCE (XtNhorizontal, XtCHorizontal, XtRInt, int, offset(horizontal), + XtRImmediate, True), + boolres (XtNuseBackingStore, XtCUseBackingStore, use_backing_store, False), + boolres (XtNbounceDown, XtCBounceDown, bounce_down, True), + boolres (XtNresourceLabels, XtCResourceLabels, lookup_labels, False), + +#undef offset +#undef mflres +#undef fontres +#undef dimres +#undef boolres +#undef cbres +#undef pixres +#undef fgpixres +#undef nullpixres +#undef pmres }; -#undef offset static Boolean XlwMenuSetValues (Widget current, Widget request, Widget new_, ArgList args, Cardinal *num_args); @@ -165,16 +191,16 @@ static void Drag (Widget w, XEvent *ev, String *params, Cardinal *num_params); static void Select(Widget w, XEvent *ev, String *params, Cardinal *num_params); -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) static XFontStruct *default_font_of_font_list (XmFontList); #endif static XtActionsRec xlwMenuActionsList [] = { - {"start", Start}, - {"drag", Drag}, - {"select", Select}, + { (String) "start", Start}, + { (String) "drag", Drag}, + { (String) "select", Select}, }; #define SuperClass ((CoreWidgetClass)&coreClassRec) @@ -183,7 +209,7 @@ { { /* CoreClass fields initialization */ (WidgetClass) SuperClass, /* superclass */ - "XlwMenu", /* class_name */ + (String) "XlwMenu", /* class_name */ sizeof(XlwMenuRec), /* size */ XlwMenuClassInitialize, /* class_initialize */ NULL, /* class_part_initialize */ @@ -241,57 +267,6 @@ #endif /* 0 */ -/* Replacement for XAllocColor() that tries to return the nearest - available color if the colormap is full. From FSF Emacs. */ - -static int -allocate_nearest_color (Display *display, Colormap screen_colormap, - XColor *color_def) -{ - int status = XAllocColor (display, screen_colormap, color_def); - if (status) - return status; - - { - /* If we got to this point, the colormap is full, so we're - going to try to get the next closest color. - The algorithm used is a least-squares matching, which is - what X uses for closest color matching with StaticColor visuals. */ - - int nearest, x; - unsigned long nearest_delta = ULONG_MAX; - - int no_cells = XDisplayCells (display, XDefaultScreen (display)); - /* Don't use alloca here because lwlib doesn't have the - necessary configuration information that src does. */ - XColor *cells = (XColor *) malloc (sizeof (XColor) * no_cells); - - for (x = 0; x < no_cells; x++) - cells[x].pixel = x; - - XQueryColors (display, screen_colormap, cells, no_cells); - - for (nearest = 0, x = 0; x < no_cells; x++) - { - long dred = (color_def->red >> 8) - (cells[x].red >> 8); - long dgreen = (color_def->green >> 8) - (cells[x].green >> 8); - long dblue = (color_def->blue >> 8) - (cells[x].blue >> 8); - unsigned long delta = dred * dred + dgreen * dgreen + dblue * dblue; - - if (delta < nearest_delta) - { - nearest = x; - nearest_delta = delta; - } - } - color_def->red = cells[nearest].red; - color_def->green = cells[nearest].green; - color_def->blue = cells[nearest].blue; - free (cells); - return XAllocColor (display, screen_colormap, color_def); - } -} - static void push_new_stack (XlwMenuWidget mw, widget_value *val) { @@ -355,14 +330,14 @@ /* Size code */ static int string_width (XlwMenuWidget mw, -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) XmString s #else char *s #endif ) { -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) Dimension width, height; XmStringExtent (mw->menu.font_list, s, &width, &height); return width; @@ -372,10 +347,17 @@ XmbTextExtents (mw->menu.font_set, s, strlen (s), &ri, &rl); return rl.width; # else +#ifdef USE_XFT_MENUBARS + XGlyphInfo glyphinfo; + XftTextExtents8 (XtDisplay (mw), mw->menu.renderFont, (FcChar8 *) s, + strlen (s), &glyphinfo); + return glyphinfo.xOff; +#else XCharStruct xcs; int drop; XTextExtents (mw->menu.font, s, strlen (s), &drop, &drop, &drop, &xcs); return xcs.width; +#endif # endif /* USE_XFONTSET */ #endif } @@ -402,22 +384,26 @@ static int string_width_u (XlwMenuWidget mw, -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) XmString string #else char *string #endif ) { -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) Dimension width, height; XmString newstring; #else # ifdef USE_XFONTSET XRectangle ri, rl; # else /* ! USE_XFONTSET */ +#ifdef USE_XFT_MENUBARS + XGlyphInfo glyphinfo; +#else XCharStruct xcs; int drop; +#endif # endif #endif char* newchars; @@ -425,7 +411,7 @@ char *chars; int i, j; -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) chars = ""; if (!XmStringGetLtoR (string, XmFONTLIST_DEFAULT_TAG, &chars)) chars = ""; @@ -442,7 +428,7 @@ newchars[j++] = chars[i]; newchars[j] = '\0'; -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) newstring = XmStringLtoRCreate (newchars, XmFONTLIST_DEFAULT_TAG); XmStringExtent (mw->menu.font_list, newstring, &width, &height); XmStringFree (newstring); @@ -453,8 +439,14 @@ XmbTextExtents (mw->menu.font_set, newchars, j, &ri, &rl); return rl.width; # else /* ! USE_XFONTSET */ +#ifdef USE_XFT_MENUBARS + XftTextExtents8 (XtDisplay (mw), mw->menu.renderFont, (FcChar8 *) newchars, + j, &glyphinfo); + return glyphinfo.xOff; +#else XTextExtents (mw->menu.font, newchars, j, &drop, &drop, &drop, &xcs); return xcs.width; +#endif # endif /* USE_XFONTSET */ #endif } @@ -515,7 +507,7 @@ static XtResource nameResource[] = { - { "labelString", "LabelString", XtRString, sizeof(String), + { (String) "labelString", (String) "LabelString", XtRString, sizeof(String), 0, XtRImmediate, 0 } }; @@ -621,7 +613,7 @@ return result; } -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) static XmString resource_widget_value (XlwMenuWidget mw, widget_value *val) @@ -769,20 +761,41 @@ #endif /* !Motif */ +#define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \ + ? ((unsigned long) (x)) : ((unsigned long) (y))) + +#ifdef USE_XFT_MENUBARS +static int +x_xft_text_width (Display *dpy, XftFont *xft_font, char *run, int len) +{ + static XGlyphInfo glyphinfo; + + XftTextExtents8 (dpy, + xft_font, + (FcChar8 *) run, len, &glyphinfo); + return glyphinfo.xOff; +} +#endif + /* Code for drawing strings. */ static void string_draw (XlwMenuWidget mw, Window window, int x, int y, +#ifdef USE_XFT_MENUBARS + XftColor *color, + XftColor *colorBg, +#else GC gc, -#ifdef NEED_MOTIF +#endif +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) XmString string #else char *string #endif ) { -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) XmStringDraw (XtDisplay (mw), window, mw->menu.font_list, string, gc, @@ -792,15 +805,31 @@ 0, /* ???? layout_direction */ 0); #else -# ifdef USE_XFONTSET +# ifdef USE_XFT_MENUBARS + Display *display = XtDisplay (mw); + Visual *visual = DefaultVisualOfScreen (XtScreen (mw)); + Colormap cmap = mw->core.colormap; + XftDraw *xftDraw = XftDrawCreate (display, window, visual, cmap); + XftFont *renderFont = mw->menu.renderFont; + /* draw background rect */ + XftDrawRect (xftDraw, colorBg, + x, y, + x_xft_text_width (display, renderFont, string, strlen (string)), + renderFont->ascent + renderFont->descent); /* XXX */ + /* draw text */ + XftDrawString8 (xftDraw, color, renderFont, x, y + mw->menu.font_ascent, + (FcChar8 *) string, strlen (string)); + XftDrawDestroy (xftDraw); +# else +# ifdef USE_XFONTSET XmbDrawString (XtDisplay (mw), window, mw->menu.font_set, gc, x, y + mw->menu.font_ascent, string, strlen (string)); -# else +# else XDrawString (XtDisplay (mw), window, gc, x, y + mw->menu.font_ascent, string, strlen (string)); -# endif /* USE_XFONTSET */ - -#endif +# endif /* USE_XFONTSET */ +# endif /* USE_XFT_MENUBARS */ +#endif /* NEED_MOTIF */ } static int @@ -808,13 +837,18 @@ XlwMenuWidget mw, Window window, int x, int y, +#ifdef USE_XFT_MENUBARS + XftColor *color, + XftColor *colorBg, +#else GC gc, +#endif char *string, int start, int end ) { -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) Dimension width, height; XmString newstring; int c; @@ -851,18 +885,50 @@ mw->menu.font_set, &string[start], end - start, &ri, &rl); return rl.width; # else +#ifdef USE_XFT_MENUBARS + if (end <= start) + return 0; + else + { + XGlyphInfo glyphinfo; + Display *display = XtDisplay (mw); + Visual *visual = DefaultVisualOfScreen (XtScreen (mw)); + Colormap cmap = mw->core.colormap; + XftFont *renderFont = mw->menu.renderFont; + /* #### should use parent frame's .xftDraw? */ + XftDraw *xftDraw = XftDrawCreate (display, window, visual, cmap); + /* draw background rect */ + XftDrawRect (xftDraw, colorBg, + x, y, + x_xft_text_width (display, + renderFont, &string[start], end - start), + renderFont->ascent + renderFont->descent); /* XXX */ + /* draw text */ + XftDrawString8 (xftDraw, color, renderFont, + x, y + mw->menu.font_ascent, + (FcChar8 *) &string[start], end - start); + + XftTextExtents8 (display, renderFont, (FcChar8 *) &string[start], + end - start, &glyphinfo); + + /* #### should use parent frame's .xftDraw */ + XftDrawDestroy (xftDraw); + return glyphinfo.xOff; + } +#else XCharStruct xcs; int drop; if (end <= start) return 0; - XDrawString ( + XDrawString ( /* XXX */ XtDisplay (mw), window, gc, x, y + mw->menu.font_ascent, &string[start], end - start); XTextExtents ( mw->menu.font, &string[start], end - start, &drop, &drop, &drop, &xcs); return xcs.width; +#endif # endif #endif } @@ -871,8 +937,12 @@ string_draw_u (XlwMenuWidget mw, Window window, int x, int y, +#ifdef USE_XFT_MENUBARS + XftColor *color, XftColor *colorBg, GC gc, +#else GC gc, -#ifdef NEED_MOTIF +#endif +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) XmString string #else char *string @@ -882,7 +952,7 @@ int i, s = 0; char *chars; -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) chars = ""; if (!XmStringGetLtoR (string, XmFONTLIST_DEFAULT_TAG, &chars)) chars = ""; @@ -893,8 +963,13 @@ if (chars[i] == '%' && chars[i+1] == '_') { int w; +#ifdef USE_XFT_MENUBARS + x += string_draw_range (mw, window, x, y, color, colorBg, chars, s, i); + w = string_draw_range (mw, window, x, y, color, colorBg, chars, i+2, i+3); +#else x += string_draw_range (mw, window, x, y, gc, chars, s, i); w = string_draw_range (mw, window, x, y, gc, chars, i+2, i+3); +#endif /* underline next character */ XDrawLine (XtDisplay (mw), window, gc, x - 1, @@ -905,22 +980,37 @@ i += 2; } } +#ifdef USE_XFT_MENUBARS + x += string_draw_range (mw, window, x, y, color, colorBg, chars, s, i); +#else x += string_draw_range (mw, window, x, y, gc, chars, s, i); -#ifdef NEED_MOTIF +#endif +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) XtFree (chars); #endif } -static void -binding_draw (XlwMenuWidget mw, Window w, int x, int y, GC gc, char *value) +static void /* XXX */ +binding_draw (XlwMenuWidget mw, Window w, int x, int y, +#ifdef USE_XFT_MENUBARS + XftColor *color, + XftColor *colorBg, +#else + GC gc, +#endif + char *value) { -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) XmString xm_value = XmStringCreateLtoR(value, XmSTRING_DEFAULT_CHARSET); string_draw (mw, w, x, y, gc, xm_value); XmStringFree (xm_value); #else +#ifdef USE_XFT_MENUBARS + string_draw (mw, w, x, y, color, colorBg, value); +#else string_draw (mw, w, x, y, gc, value); #endif +#endif } /* Low level code for drawing 3-D edges. */ @@ -1562,21 +1652,57 @@ int y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin; GC gc; +#ifdef USE_XFT_MENUBARS + XftColor color, colorBg; + Display *display = XtDisplay (mw); + Colormap cmap = mw->core.colormap; + Visual *visual; + int ignored, pixel, pixelBg; + + visual_info_from_widget ((Widget) mw, &visual, &ignored); +#endif + if (!label_offset) label_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin; - if (highlighted && (in_menubar || val->contents)) - gc = mw->menu.highlight_gc; + if (highlighted && (in_menubar || val->contents)) + { +#ifdef USE_XFT_MENUBARS + pixel = mw->menu.highlight_foreground; + pixelBg = mw->core.background_pixel; +#endif + gc = mw->menu.highlight_gc; + } else if (in_menubar || val->contents) - gc = mw->menu.foreground_gc; + { +#ifdef USE_XFT_MENUBARS + pixel = mw->menu.foreground; + pixelBg = mw->core.background_pixel; +#endif + gc = mw->menu.foreground_gc; + } else - gc = mw->menu.title_gc; + { +#ifdef USE_XFT_MENUBARS + pixel = mw->menu.title_foreground; + pixelBg = mw->core.background_pixel; +#endif + gc = mw->menu.title_gc; + } +#ifdef USE_XFT_MENUBARS + color = xft_convert_color (display, cmap, visual, pixel, 0); + colorBg = xft_convert_color (display, cmap, visual, pixelBg, 0); +#endif /* Draw the label string. */ - string_draw_u (mw, - window, - x + label_offset, y + y_offset, + string_draw_u (mw, /* XXX */ + window, + x + label_offset, y + y_offset, +#ifdef USE_XFT_MENUBARS + &color, &colorBg, gc, +#else gc, +#endif resource_widget_value (mw, val)); } @@ -1598,7 +1724,7 @@ if (!in_menubar && val->key) { int w; -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) XmString key = XmStringCreateLtoR (val->key, XmSTRING_DEFAULT_CHARSET); w = string_width (mw, key); XmStringFree (key); @@ -1627,6 +1753,16 @@ shadow_type type; Boolean menu_pb = in_menubar && (menu_item_type (val) == BUTTON_TYPE); +#ifdef USE_XFT_MENUBARS + XftColor color, colorBg; + Display *display = XtDisplay (mw); + Colormap cmap = mw->core.colormap; + Visual *visual; + int ignored, pixel, pixelBg, dim = 0; + + visual_info_from_widget ((Widget) mw, &visual, &ignored); +#endif + /* Draw the label string. */ if (!label_offset) label_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin; @@ -1634,29 +1770,77 @@ if (highlighted) { if (val->enabled) - gc = mw->menu.highlight_gc; + { +#ifdef USE_XFT_MENUBARS + pixel = mw->menu.highlight_foreground; + pixelBg = mw->core.background_pixel; +#endif + gc = mw->menu.highlight_gc; + } else - gc = mw->menu.inactive_gc; + { +#ifdef USE_XFT_MENUBARS + dim = 1; + pixel = mw->menu.foreground; + pixelBg = mw->core.background_pixel; +#endif + gc = mw->menu.inactive_gc; + } } else if (menu_pb) { if (val->enabled) - gc = mw->menu.button_gc; + { +#ifdef USE_XFT_MENUBARS + pixel = mw->menu.button_foreground; + pixelBg = mw->core.background_pixel; +#endif + gc = mw->menu.button_gc; + } else - gc = mw->menu.inactive_button_gc; + { +#ifdef USE_XFT_MENUBARS + dim = 1; + pixel = mw->menu.button_foreground; + pixelBg = mw->core.background_pixel; +#endif + gc = mw->menu.inactive_button_gc; + } } else { if (val->enabled) - gc = mw->menu.foreground_gc; + { +#ifdef USE_XFT_MENUBARS + pixel = mw->menu.foreground; + pixelBg = mw->core.background_pixel; +#endif + gc = mw->menu.foreground_gc; + } else - gc = mw->menu.inactive_gc; + { +#ifdef USE_XFT_MENUBARS + dim = 1; + pixel = mw->menu.foreground; + pixelBg = mw->core.background_pixel; +#endif + gc = mw->menu.inactive_gc; + } } +#ifdef USE_XFT_MENUBARS + color = xft_convert_color (display, cmap, visual, pixel, dim); + colorBg = xft_convert_color (display, cmap, visual, pixelBg, 0); +#endif + string_draw_u (mw, - window, - x + label_offset, y + y_offset, - gc, + window, + x + label_offset, y + y_offset, +#ifdef USE_XFT_MENUBARS + &color, &colorBg, gc, +#else + gc, +#endif resource_widget_value (mw, val)); /* Draw the keybindings */ @@ -1670,7 +1854,13 @@ } binding_draw (mw, window, x + binding_offset + mw->menu.column_spacing, - y + y_offset, gc, val->key); + y + y_offset, +#ifdef USE_XFT_MENUBARS + &color, &colorBg, +#else + gc, +#endif + val->key); } /* Draw the shadow */ @@ -2336,6 +2526,7 @@ return; root = RootWindowOfScreen (XtScreen(mw)); + /* use visual_info_from_widget() from lwlib-colors.c */ /* grab the visual and depth from the nearest shell ancestor */ visual = CopyFromParent; depth = CopyFromParent; @@ -2615,13 +2806,19 @@ make_drawing_gcs (XlwMenuWidget mw) { XGCValues xgcv; +#ifdef USE_XFT_MENUBARS + unsigned long flags = (GCForeground | GCBackground); +#else unsigned long flags = (GCFont | GCForeground | GCBackground); - -#ifdef NEED_MOTIF +#endif + +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) xgcv.font = default_font_of_font_list (mw->menu.font_list)->fid; #else +#ifndef USE_XFT_MENUBARS xgcv.font = mw->menu.font->fid; #endif +#endif xgcv.foreground = mw->core.background_pixel; xgcv.background = mw->menu.foreground; @@ -2645,18 +2842,22 @@ else { /* color */ XColor xcolor; - Colormap cmap = mw->core.colormap; + Visual *visual; + int ignore; + Colormap cmap; + visual_info_from_widget ((Widget) mw, &visual, &ignore); + cmap = mw->core.colormap; xcolor.pixel = mw->core.background_pixel; XQueryColor (dpy, cmap, &xcolor); xcolor.red = (xcolor.red * 17) / 20; xcolor.green = (xcolor.green * 17) / 20; xcolor.blue = (xcolor.blue * 17) / 20; - if (allocate_nearest_color (dpy, cmap, &xcolor)) + if (x_allocate_nearest_color (dpy, cmap, visual, &xcolor)) xgcv.foreground = xcolor.pixel; } } xgcv.background = mw->core.background_pixel; - mw->menu.select_gc = XtGetGC ((Widget)mw, flags, &xgcv); + mw->menu.select_gc = XtGetGC ((Widget) mw, flags, &xgcv); xgcv.foreground = mw->menu.foreground; xgcv.background = mw->core.background_pixel; @@ -2688,6 +2889,7 @@ static void release_drawing_gcs (XlwMenuWidget mw) { + XtReleaseGC ((Widget) mw, mw->menu.foreground_gc); XtReleaseGC ((Widget) mw, mw->menu.button_gc); XtReleaseGC ((Widget) mw, mw->menu.highlight_gc); @@ -2707,9 +2909,6 @@ mw->menu.select_gc = (GC) -1; } -#define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \ - ? ((unsigned long) (x)) : ((unsigned long) (y))) - static void make_shadow_gcs (XlwMenuWidget mw) { @@ -2717,9 +2916,20 @@ unsigned long pm = 0; Display *dpy = XtDisplay ((Widget) mw); Colormap cmap = mw->core.colormap; + Visual *visual; + int ignored; XColor topc, botc; int top_frobbed = 0, bottom_frobbed = 0; + visual_info_from_widget ((Widget) mw, &visual, &ignored); + /* #### Apparently this is called before any shell has a visual? + or maybe the widget doesn't have a parent yet? */ + if (visual == CopyFromParent) + { + Screen *screen = DefaultScreenOfDisplay (dpy); + visual = DefaultVisualOfScreen (screen); + } + if (mw->menu.top_shadow_color == (Pixel) (-1)) mw->menu.top_shadow_color = mw->core.background_pixel; if (mw->menu.bottom_shadow_color == (Pixel) (-1)) @@ -2734,7 +2944,7 @@ topc.red = MINL (65535, topc.red * 1.2); topc.green = MINL (65535, topc.green * 1.2); topc.blue = MINL (65535, topc.blue * 1.2); - if (allocate_nearest_color (dpy, cmap, &topc)) + if (x_allocate_nearest_color (dpy, cmap, visual, &topc)) { if (topc.pixel == mw->core.background_pixel) { @@ -2742,7 +2952,7 @@ topc.red = MINL (65535, topc.red + 0x8000); topc.green = MINL (65535, topc.green + 0x8000); topc.blue = MINL (65535, topc.blue + 0x8000); - if (allocate_nearest_color (dpy, cmap, &topc)) + if (x_allocate_nearest_color (dpy, cmap, visual, &topc)) { mw->menu.top_shadow_color = topc.pixel; } @@ -2763,7 +2973,7 @@ botc.red = (botc.red * 3) / 5; botc.green = (botc.green * 3) / 5; botc.blue = (botc.blue * 3) / 5; - if (allocate_nearest_color (dpy, cmap, &botc)) + if (x_allocate_nearest_color (dpy, cmap, visual, &botc)) { if (botc.pixel == mw->core.background_pixel) { @@ -2771,7 +2981,7 @@ botc.red = MINL (65535, botc.red + 0x4000); botc.green = MINL (65535, botc.green + 0x4000); botc.blue = MINL (65535, botc.blue + 0x4000); - if (allocate_nearest_color (dpy, cmap, &botc)) + if (x_allocate_nearest_color (dpy, cmap, visual, &botc)) { mw->menu.bottom_shadow_color = botc.pixel; } @@ -2854,7 +3064,7 @@ static void extract_font_extents (XlwMenuWidget mw) { -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) /* Find the maximal ascent/descent of the fonts in the font list so that all menu items can be the same height... */ mw->menu.font_ascent = 0; @@ -2939,13 +3149,18 @@ mw->menu.font_descent = font->descent; } # else /* ! USE_XFONTSET */ +#ifdef USE_XFT_MENUBARS + mw->menu.font_ascent = mw->menu.renderFont->ascent; + mw->menu.font_descent = mw->menu.renderFont->descent; +#else mw->menu.font_ascent = mw->menu.font->ascent; mw->menu.font_descent = mw->menu.font->descent; +#endif # endif #endif /* NEED_MOTIF */ } -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) static XFontStruct * default_font_of_font_list (XmFontList font_list) { @@ -3015,7 +3230,7 @@ XCreatePixmapFromBitmapData (display, window, (char *) gray_bits, gray_width, gray_height, 1, 0, 1); -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) /* #### Even if it's a kludge!!!, we should consider doing the same for X Font Sets. */ /* The menu.font_list slot came from the *fontList resource (Motif standard.) @@ -3037,6 +3252,17 @@ mw->menu.font_list = mw->menu.fallback_font_list; #endif +#ifdef USE_XFT_MENUBARS + /* #### kludge for name change */ + if (!mw->menu.fcFontName) + mw->menu.fcFontName = mw->menu.xftFontName; + /* to do this right, we should add a new Xt Resource type + + conversion function + */ + mw->menu.renderFont = + xft_open_font_by_name (XtDisplay (mw), mw->menu.fcFontName); +#endif + make_drawing_gcs (mw); make_shadow_gcs (mw); extract_font_extents (mw); @@ -3137,6 +3363,10 @@ XFreePixmap (XtDisplay (mw), mw->menu.gray_pixmap); mw->menu.gray_pixmap = (Pixmap) -1; +#ifdef USE_XFT_MENUBARS + XftFontClose (XtDisplay (mw), mw->menu.renderFont); +#endif + /* Don't free mw->menu.contents because that comes from our creator. The `*_stack' elements are just pointers into `contents' so leave that alone too. But free the stacks themselves. */ @@ -3179,13 +3409,17 @@ if (newmw->core.background_pixel != oldmw->core.background_pixel || newmw->menu.foreground != oldmw->menu.foreground /* For the XEditResource protocol, which may want to change the font. */ -#ifdef NEED_MOTIF +#if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS) || newmw->menu.font_list != oldmw->menu.font_list || newmw->menu.font_list_2 != oldmw->menu.font_list_2 || newmw->menu.fallback_font_list != oldmw->menu.fallback_font_list #else +#ifdef USE_XFT_MENUBARS + || newmw->menu.renderFont != oldmw->menu.renderFont +#else || newmw->menu.font != oldmw->menu.font #endif +#endif ) { release_drawing_gcs (newmw); @@ -3415,8 +3649,8 @@ if (!mw->menu.pointer_grabbed) { XWindowAttributes ret; - Window parent,root; - Window *waste; + Window parent,root = 0UL; + Window *waste = NULL; unsigned int num_waste; lw_menu_active = True;