comparison 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
comparison
equal deleted inserted replaced
5117:3742ea8250b5 5118:e0db3c197671
43 #if XmVersion < 1002 /* 1.1 or ancient */ 43 #if XmVersion < 1002 /* 1.1 or ancient */
44 #undef XmFONTLIST_DEFAULT_TAG 44 #undef XmFONTLIST_DEFAULT_TAG
45 #define XmFONTLIST_DEFAULT_TAG XmSTRING_DEFAULT_CHARSET 45 #define XmFONTLIST_DEFAULT_TAG XmSTRING_DEFAULT_CHARSET
46 #endif /* XmVersion < 1.2 */ 46 #endif /* XmVersion < 1.2 */
47 #endif 47 #endif
48
49 /* #### we may want to turn off USE_XFT here if !USE_XFT_MENUBARS
50 In fact, maybe that's the right interface overall? */
51 #include "lwlib-fonts.h"
52 #include "lwlib-colors.h"
48 #include "xlwmenuP.h" 53 #include "xlwmenuP.h"
49 54
50 #ifdef USE_DEBUG_MALLOC 55 #ifdef USE_DEBUG_MALLOC
51 #include <dmalloc.h> 56 #include <dmalloc.h>
52 #endif 57 #endif
63 <BtnUp>: select()\n\ 68 <BtnUp>: select()\n\
64 "; 69 ";
65 70
66 extern Widget lw_menubar_widget; 71 extern Widget lw_menubar_widget;
67 72
68 #define offset(field) XtOffset(XlwMenuWidget, field)
69 static XtResource 73 static XtResource
70 xlwMenuResources[] = 74 xlwMenuResources[] =
71 { 75 {
72 #ifdef NEED_MOTIF 76 /* The offset macro is a standard trick. The remaining macros are an
77 experiment to compress redundancies in resource descriptions, and shut
78 up GCC 4.3 (the String casts, which keep G++ from complaining about
79 implicit conversions from const char *). */
80 #define offset(field) XtOffset(XlwMenuWidget, menu.field)
81 #define fontres(name,_class,repr,type,member,value) \
82 Xt_RESOURCE (name, _class, repr, type, offset(member), XtRString, value)
83 #define mflres(name,cls,member,repr,value) \
84 Xt_RESOURCE (name, cls, XmRFontList, XmFontList, offset(member), repr, value)
85 #define dimres(name,cls,repr,member,value) \
86 Xt_RESOURCE (name, cls, repr, Dimension, offset(member), XtRImmediate, value)
87 #define boolres(nm,cls,member,val) \
88 Xt_RESOURCE (nm, cls, XtRBoolean, Boolean, offset(member), XtRImmediate, val)
89 #define cbres(name,member,value) \
90 Xt_RESOURCE (name, XtCCallback, XtRCallback, XtPointer, offset(member), \
91 XtRCallback, value)
92 #define pixres(name,_class,member,repr,value) \
93 Xt_RESOURCE (name, _class, XtRPixel, Pixel, offset(member), repr, value)
94 #define fgpixres(name,_class,member) \
95 pixres (name, _class, member, XtRString, "XtDefaultForeground")
96 #define nullpixres(name,_class,member) \
97 pixres (name, _class, member, XtRImmediate, -1)
98 #define pmres(name,cls,member) \
99 Xt_RESOURCE (name, cls, XtRPixmap, Pixmap, offset(member), XtRImmediate, None)
100
101 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
73 /* There are three font list resources, so that we can accept either of 102 /* There are three font list resources, so that we can accept either of
74 the resources *fontList: or *font:, and so that we can tell the 103 the resources *fontList: or *font:, and so that we can tell the
75 difference between them being specified, and being defaulted to a 104 difference between them being specified, and being defaulted to a
76 font from the XtRString specified here. */ 105 font from the XtRString specified here. */
77 {XmNfontList, XmCFontList, XmRFontList, sizeof(XmFontList), 106 mflres (XmNfontList, XmCFontList, font_list, XtRImmediate, 0),
78 offset(menu.font_list), XtRImmediate, (XtPointer)0}, 107 mflres (XtNfont, XtCFont, font_list_2, XtRImmediate, 0),
79 {XtNfont, XtCFont, XmRFontList, sizeof(XmFontList), 108 mflres (XmNfontList, XmCFontList, fallback_font_list,
80 offset(menu.font_list_2),XtRImmediate, (XtPointer)0},
81 {XmNfontList, XmCFontList, XmRFontList, sizeof(XmFontList),
82 offset(menu.fallback_font_list),
83 /* We must use an iso8859-1 font here, or people without $LANG set lose. 109 /* We must use an iso8859-1 font here, or people without $LANG set lose.
84 It's fair to assume that those who do have $LANG set also have the 110 It's fair to assume that those who do have $LANG set also have the
85 *fontList resource set, or at least know how to deal with this. */ 111 *fontList resource set, or at least know how to deal with this. */
86 XtRString, (XtPointer) "-*-helvetica-bold-r-*-*-*-120-*-*-*-*-iso8859-1"}, 112 XtRString, (XtPointer) "-*-helvetica-bold-r-*-*-*-120-*-*-*-*-iso8859-1"),
87 #else 113 #else
88 {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), 114 fontres (XtNfont, XtCFont, XtRFontStruct, XFontStruct *, font,
89 offset(menu.font), XtRString, (XtPointer) "XtDefaultFont"}, 115 "XtDefaultFont"),
116 #ifdef USE_XFT_MENUBARS
117 fontres (XtNfcFontName, XtCFcFontName, XtRString, String, fcFontName,
118 "sans-serif-12:bold"),
119 /* #### This needs to be fixed to give a proper type and converter for
120 XftFonts. See also xlwtabs.c. */
121 fontres (XtNxftFont, XtCXftFont, XtRString, XtPointer, xftFontName,
122 "Helvetica-12:bold"),
123 #endif
90 # ifdef USE_XFONTSET 124 # ifdef USE_XFONTSET
91 /* #### Consider using the same method as for Motif; see the comment in 125 /* #### Consider using the same method as for Motif; see the comment in
92 XlwMenuInitialize(). */ 126 XlwMenuInitialize(). */
93 {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet), 127 fontres (XtNfontSet, XtCFontSet, XtRFontSet, XFontSet, font_set,
94 offset(menu.font_set), XtRString, (XtPointer) "XtDefaultFontSet"}, 128 "XtDefaultFontSet"),
95 # endif 129 # endif
96 #endif 130 #endif
97 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), 131 fgpixres (XtNforeground, XtCForeground, foreground),
98 offset(menu.foreground), XtRString, (XtPointer) "XtDefaultForeground"}, 132 fgpixres (XtNbuttonForeground, XtCButtonForeground, button_foreground),
99 {XtNbuttonForeground, XtCButtonForeground, XtRPixel, sizeof(Pixel), 133 fgpixres (XtNhighlightForeground, XtCHighlightForeground,
100 offset(menu.button_foreground), XtRString, (XtPointer) "XtDefaultForeground"}, 134 highlight_foreground),
101 {XtNhighlightForeground, XtCHighlightForeground, XtRPixel, sizeof(Pixel), 135 fgpixres (XtNtitleForeground, XtCTitleForeground, title_foreground),
102 offset(menu.highlight_foreground), XtRString, (XtPointer) "XtDefaultForeground"}, 136 dimres (XtNmargin, XtCMargin, XtRDimension, margin, 2),
103 {XtNtitleForeground, XtCTitleForeground, XtRPixel, sizeof(Pixel), 137 dimres (XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension,
104 offset(menu.title_foreground), XtRString, (XtPointer) "XtDefaultForeground"}, 138 horizontal_margin, 2),
105 {XtNmargin, XtCMargin, XtRDimension, sizeof(Dimension), 139 dimres (XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension,
106 offset(menu.margin), XtRImmediate, (XtPointer)2}, 140 vertical_margin, 1),
107 {XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension, sizeof(Dimension), 141 dimres (XmNspacing, XmCSpacing, XmRHorizontalDimension, column_spacing, 4),
108 offset(menu.horizontal_margin), XtRImmediate, (XtPointer)2}, 142 dimres (XmNindicatorSize, XmCIndicatorSize, XtRDimension, indicator_size, 0),
109 {XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension, sizeof(Dimension),
110 offset(menu.vertical_margin), XtRImmediate, (XtPointer)1},
111 {XmNspacing, XmCSpacing, XmRHorizontalDimension, sizeof(Dimension),
112 offset(menu.column_spacing), XtRImmediate, (XtPointer)4},
113 {XmNindicatorSize, XmCIndicatorSize, XtRDimension, sizeof(Dimension),
114 offset(menu.indicator_size), XtRImmediate, (XtPointer)0},
115 #if 0 143 #if 0
116 {XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension, 144 dimres (XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension,
117 sizeof (Dimension), offset (menu.shadow_thickness), 145 shadow_thickness, 2),
118 XtRImmediate, (XtPointer) 2}, 146 #else
119 #else 147 dimres (XmNshadowThickness, XmCShadowThickness, XtRDimension,
120 {XmNshadowThickness, XmCShadowThickness, XtRDimension, 148 shadow_thickness, 2),
121 sizeof (Dimension), offset (menu.shadow_thickness), 149 #endif
122 XtRImmediate, (XtPointer) 2}, 150 nullpixres (XmNselectColor, XmCSelectColor, select_color),
123 #endif 151 nullpixres (XmNtopShadowColor, XmCTopShadowColor, top_shadow_color),
124 {XmNselectColor, XmCSelectColor, XtRPixel, sizeof (Pixel), 152 nullpixres (XmNbottomShadowColor, XmCBottomShadowColor, bottom_shadow_color),
125 offset (menu.select_color), XtRImmediate, (XtPointer)-1}, 153 pmres (XmNtopShadowPixmap, XmCTopShadowPixmap, top_shadow_pixmap),
126 {XmNtopShadowColor, XmCTopShadowColor, XtRPixel, sizeof (Pixel), 154 pmres (XmNbottomShadowPixmap, XmCBottomShadowPixmap, bottom_shadow_pixmap),
127 offset (menu.top_shadow_color), XtRImmediate, (XtPointer)-1}, 155
128 {XmNbottomShadowColor, XmCBottomShadowColor, XtRPixel, sizeof (Pixel), 156 cbres (XtNopen, open, NULL),
129 offset (menu.bottom_shadow_color), XtRImmediate, (XtPointer)-1}, 157 cbres (XtNselect, select, NULL),
130 {XmNtopShadowPixmap, XmCTopShadowPixmap, XtRPixmap, sizeof (Pixmap), 158 Xt_RESOURCE (XtNmenu, XtCMenu, XtRPointer, XtPointer, offset(contents),
131 offset (menu.top_shadow_pixmap), XtRImmediate, (XtPointer)None}, 159 XtRImmediate, NULL),
132 {XmNbottomShadowPixmap, XmCBottomShadowPixmap, XtRPixmap, sizeof (Pixmap), 160 Xt_RESOURCE (XtNcursor, XtCCursor, XtRCursor, Cursor, offset(cursor_shape),
133 offset (menu.bottom_shadow_pixmap), XtRImmediate, (XtPointer)None}, 161 XtRString, "right_ptr"),
134 162 Xt_RESOURCE (XtNhorizontal, XtCHorizontal, XtRInt, int, offset(horizontal),
135 {XtNopen, XtCCallback, XtRCallback, sizeof(XtPointer), 163 XtRImmediate, True),
136 offset(menu.open), XtRCallback, (XtPointer)NULL}, 164 boolres (XtNuseBackingStore, XtCUseBackingStore, use_backing_store, False),
137 {XtNselect, XtCCallback, XtRCallback, sizeof(XtPointer), 165 boolres (XtNbounceDown, XtCBounceDown, bounce_down, True),
138 offset(menu.select), XtRCallback, (XtPointer)NULL}, 166 boolres (XtNresourceLabels, XtCResourceLabels, lookup_labels, False),
139 {XtNmenu, XtCMenu, XtRPointer, sizeof(XtPointer), 167
140 offset(menu.contents), XtRImmediate, (XtPointer)NULL}, 168 #undef offset
141 {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor), 169 #undef mflres
142 offset(menu.cursor_shape), XtRString, (XtPointer) "right_ptr"}, 170 #undef fontres
143 {XtNhorizontal, XtCHorizontal, XtRInt, sizeof(int), 171 #undef dimres
144 offset(menu.horizontal), XtRImmediate, (XtPointer)True}, 172 #undef boolres
145 {XtNuseBackingStore, XtCUseBackingStore, XtRBoolean, sizeof (Boolean), 173 #undef cbres
146 offset (menu.use_backing_store), XtRImmediate, (XtPointer)False}, 174 #undef pixres
147 {XtNbounceDown, XtCBounceDown, XtRBoolean, sizeof (Boolean), 175 #undef fgpixres
148 offset (menu.bounce_down), XtRImmediate, (XtPointer)True}, 176 #undef nullpixres
149 {XtNresourceLabels, XtCResourceLabels, XtRBoolean, sizeof (Boolean), 177 #undef pmres
150 offset (menu.lookup_labels), XtRImmediate, (XtPointer)False},
151 }; 178 };
152 #undef offset
153 179
154 static Boolean XlwMenuSetValues (Widget current, Widget request, Widget new_, 180 static Boolean XlwMenuSetValues (Widget current, Widget request, Widget new_,
155 ArgList args, Cardinal *num_args); 181 ArgList args, Cardinal *num_args);
156 static void XlwMenuRealize (Widget w, Mask *valueMask, 182 static void XlwMenuRealize (Widget w, Mask *valueMask,
157 XSetWindowAttributes *attributes); 183 XSetWindowAttributes *attributes);
163 static void XlwMenuClassInitialize (void); 189 static void XlwMenuClassInitialize (void);
164 static void Start (Widget w, XEvent *ev, String *params, Cardinal *num_params); 190 static void Start (Widget w, XEvent *ev, String *params, Cardinal *num_params);
165 static void Drag (Widget w, XEvent *ev, String *params, Cardinal *num_params); 191 static void Drag (Widget w, XEvent *ev, String *params, Cardinal *num_params);
166 static void Select(Widget w, XEvent *ev, String *params, Cardinal *num_params); 192 static void Select(Widget w, XEvent *ev, String *params, Cardinal *num_params);
167 193
168 #ifdef NEED_MOTIF 194 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
169 static XFontStruct *default_font_of_font_list (XmFontList); 195 static XFontStruct *default_font_of_font_list (XmFontList);
170 #endif 196 #endif
171 197
172 static XtActionsRec 198 static XtActionsRec
173 xlwMenuActionsList [] = 199 xlwMenuActionsList [] =
174 { 200 {
175 {"start", Start}, 201 { (String) "start", Start},
176 {"drag", Drag}, 202 { (String) "drag", Drag},
177 {"select", Select}, 203 { (String) "select", Select},
178 }; 204 };
179 205
180 #define SuperClass ((CoreWidgetClass)&coreClassRec) 206 #define SuperClass ((CoreWidgetClass)&coreClassRec)
181 207
182 XlwMenuClassRec xlwMenuClassRec = 208 XlwMenuClassRec xlwMenuClassRec =
183 { 209 {
184 { /* CoreClass fields initialization */ 210 { /* CoreClass fields initialization */
185 (WidgetClass) SuperClass, /* superclass */ 211 (WidgetClass) SuperClass, /* superclass */
186 "XlwMenu", /* class_name */ 212 (String) "XlwMenu", /* class_name */
187 sizeof(XlwMenuRec), /* size */ 213 sizeof(XlwMenuRec), /* size */
188 XlwMenuClassInitialize, /* class_initialize */ 214 XlwMenuClassInitialize, /* class_initialize */
189 NULL, /* class_part_initialize */ 215 NULL, /* class_part_initialize */
190 FALSE, /* class_inited */ 216 FALSE, /* class_inited */
191 XlwMenuInitialize, /* initialize */ 217 XlwMenuInitialize, /* initialize */
239 return result; 265 return result;
240 } 266 }
241 267
242 #endif /* 0 */ 268 #endif /* 0 */
243 269
244 /* Replacement for XAllocColor() that tries to return the nearest
245 available color if the colormap is full. From FSF Emacs. */
246
247 static int
248 allocate_nearest_color (Display *display, Colormap screen_colormap,
249 XColor *color_def)
250 {
251 int status = XAllocColor (display, screen_colormap, color_def);
252 if (status)
253 return status;
254
255 {
256 /* If we got to this point, the colormap is full, so we're
257 going to try to get the next closest color.
258 The algorithm used is a least-squares matching, which is
259 what X uses for closest color matching with StaticColor visuals. */
260
261 int nearest, x;
262 unsigned long nearest_delta = ULONG_MAX;
263
264 int no_cells = XDisplayCells (display, XDefaultScreen (display));
265 /* Don't use alloca here because lwlib doesn't have the
266 necessary configuration information that src does. */
267 XColor *cells = (XColor *) malloc (sizeof (XColor) * no_cells);
268
269 for (x = 0; x < no_cells; x++)
270 cells[x].pixel = x;
271
272 XQueryColors (display, screen_colormap, cells, no_cells);
273
274 for (nearest = 0, x = 0; x < no_cells; x++)
275 {
276 long dred = (color_def->red >> 8) - (cells[x].red >> 8);
277 long dgreen = (color_def->green >> 8) - (cells[x].green >> 8);
278 long dblue = (color_def->blue >> 8) - (cells[x].blue >> 8);
279 unsigned long delta = dred * dred + dgreen * dgreen + dblue * dblue;
280
281 if (delta < nearest_delta)
282 {
283 nearest = x;
284 nearest_delta = delta;
285 }
286 }
287 color_def->red = cells[nearest].red;
288 color_def->green = cells[nearest].green;
289 color_def->blue = cells[nearest].blue;
290 free (cells);
291 return XAllocColor (display, screen_colormap, color_def);
292 }
293 }
294
295 static void 270 static void
296 push_new_stack (XlwMenuWidget mw, widget_value *val) 271 push_new_stack (XlwMenuWidget mw, widget_value *val)
297 { 272 {
298 if (!mw->menu.new_stack) 273 if (!mw->menu.new_stack)
299 { 274 {
353 } 328 }
354 329
355 /* Size code */ 330 /* Size code */
356 static int 331 static int
357 string_width (XlwMenuWidget mw, 332 string_width (XlwMenuWidget mw,
358 #ifdef NEED_MOTIF 333 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
359 XmString s 334 XmString s
360 #else 335 #else
361 char *s 336 char *s
362 #endif 337 #endif
363 ) 338 )
364 { 339 {
365 #ifdef NEED_MOTIF 340 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
366 Dimension width, height; 341 Dimension width, height;
367 XmStringExtent (mw->menu.font_list, s, &width, &height); 342 XmStringExtent (mw->menu.font_list, s, &width, &height);
368 return width; 343 return width;
369 #else 344 #else
370 # ifdef USE_XFONTSET 345 # ifdef USE_XFONTSET
371 XRectangle ri, rl; 346 XRectangle ri, rl;
372 XmbTextExtents (mw->menu.font_set, s, strlen (s), &ri, &rl); 347 XmbTextExtents (mw->menu.font_set, s, strlen (s), &ri, &rl);
373 return rl.width; 348 return rl.width;
374 # else 349 # else
350 #ifdef USE_XFT_MENUBARS
351 XGlyphInfo glyphinfo;
352 XftTextExtents8 (XtDisplay (mw), mw->menu.renderFont, (FcChar8 *) s,
353 strlen (s), &glyphinfo);
354 return glyphinfo.xOff;
355 #else
375 XCharStruct xcs; 356 XCharStruct xcs;
376 int drop; 357 int drop;
377 XTextExtents (mw->menu.font, s, strlen (s), &drop, &drop, &drop, &xcs); 358 XTextExtents (mw->menu.font, s, strlen (s), &drop, &drop, &drop, &xcs);
378 return xcs.width; 359 return xcs.width;
360 #endif
379 # endif /* USE_XFONTSET */ 361 # endif /* USE_XFONTSET */
380 #endif 362 #endif
381 } 363 }
382 364
383 static char massaged_resource_char[256]; 365 static char massaged_resource_char[256];
400 massaged_resource_char ['.'] = '_'; /* Convert Buffers... to buffers___ */ 382 massaged_resource_char ['.'] = '_'; /* Convert Buffers... to buffers___ */
401 } 383 }
402 384
403 static int 385 static int
404 string_width_u (XlwMenuWidget mw, 386 string_width_u (XlwMenuWidget mw,
405 #ifdef NEED_MOTIF 387 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
406 XmString string 388 XmString string
407 #else 389 #else
408 char *string 390 char *string
409 #endif 391 #endif
410 ) 392 )
411 { 393 {
412 #ifdef NEED_MOTIF 394 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
413 Dimension width, height; 395 Dimension width, height;
414 XmString newstring; 396 XmString newstring;
415 #else 397 #else
416 # ifdef USE_XFONTSET 398 # ifdef USE_XFONTSET
417 XRectangle ri, rl; 399 XRectangle ri, rl;
418 # else /* ! USE_XFONTSET */ 400 # else /* ! USE_XFONTSET */
401 #ifdef USE_XFT_MENUBARS
402 XGlyphInfo glyphinfo;
403 #else
419 XCharStruct xcs; 404 XCharStruct xcs;
420 int drop; 405 int drop;
406 #endif
421 # endif 407 # endif
422 #endif 408 #endif
423 char* newchars; 409 char* newchars;
424 int charslength; 410 int charslength;
425 char *chars; 411 char *chars;
426 int i, j; 412 int i, j;
427 413
428 #ifdef NEED_MOTIF 414 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
429 chars = ""; 415 chars = "";
430 if (!XmStringGetLtoR (string, XmFONTLIST_DEFAULT_TAG, &chars)) 416 if (!XmStringGetLtoR (string, XmFONTLIST_DEFAULT_TAG, &chars))
431 chars = ""; 417 chars = "";
432 #else 418 #else
433 chars = string; 419 chars = string;
440 i++; 426 i++;
441 else 427 else
442 newchars[j++] = chars[i]; 428 newchars[j++] = chars[i];
443 newchars[j] = '\0'; 429 newchars[j] = '\0';
444 430
445 #ifdef NEED_MOTIF 431 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
446 newstring = XmStringLtoRCreate (newchars, XmFONTLIST_DEFAULT_TAG); 432 newstring = XmStringLtoRCreate (newchars, XmFONTLIST_DEFAULT_TAG);
447 XmStringExtent (mw->menu.font_list, newstring, &width, &height); 433 XmStringExtent (mw->menu.font_list, newstring, &width, &height);
448 XmStringFree (newstring); 434 XmStringFree (newstring);
449 XtFree (chars); 435 XtFree (chars);
450 return width; 436 return width;
451 #else 437 #else
452 # ifdef USE_XFONTSET 438 # ifdef USE_XFONTSET
453 XmbTextExtents (mw->menu.font_set, newchars, j, &ri, &rl); 439 XmbTextExtents (mw->menu.font_set, newchars, j, &ri, &rl);
454 return rl.width; 440 return rl.width;
455 # else /* ! USE_XFONTSET */ 441 # else /* ! USE_XFONTSET */
442 #ifdef USE_XFT_MENUBARS
443 XftTextExtents8 (XtDisplay (mw), mw->menu.renderFont, (FcChar8 *) newchars,
444 j, &glyphinfo);
445 return glyphinfo.xOff;
446 #else
456 XTextExtents (mw->menu.font, newchars, j, &drop, &drop, &drop, &xcs); 447 XTextExtents (mw->menu.font, newchars, j, &drop, &drop, &drop, &xcs);
457 return xcs.width; 448 return xcs.width;
449 #endif
458 # endif /* USE_XFONTSET */ 450 # endif /* USE_XFONTSET */
459 #endif 451 #endif
460 } 452 }
461 453
462 static void 454 static void
513 } 505 }
514 506
515 static XtResource 507 static XtResource
516 nameResource[] = 508 nameResource[] =
517 { 509 {
518 { "labelString", "LabelString", XtRString, sizeof(String), 510 { (String) "labelString", (String) "LabelString", XtRString, sizeof(String),
519 0, XtRImmediate, 0 } 511 0, XtRImmediate, 0 }
520 }; 512 };
521 513
522 /* This function searches STRING for parameter inserts of the form: 514 /* This function searches STRING for parameter inserts of the form:
523 %[padding]1 515 %[padding]1
619 } 611 }
620 612
621 return result; 613 return result;
622 } 614 }
623 615
624 #ifdef NEED_MOTIF 616 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
625 617
626 static XmString 618 static XmString
627 resource_widget_value (XlwMenuWidget mw, widget_value *val) 619 resource_widget_value (XlwMenuWidget mw, widget_value *val)
628 { 620 {
629 if (!val->toolkit_data) 621 if (!val->toolkit_data)
767 return (char *) val->toolkit_data; 759 return (char *) val->toolkit_data;
768 } 760 }
769 761
770 #endif /* !Motif */ 762 #endif /* !Motif */
771 763
764 #define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \
765 ? ((unsigned long) (x)) : ((unsigned long) (y)))
766
767 #ifdef USE_XFT_MENUBARS
768 static int
769 x_xft_text_width (Display *dpy, XftFont *xft_font, char *run, int len)
770 {
771 static XGlyphInfo glyphinfo;
772
773 XftTextExtents8 (dpy,
774 xft_font,
775 (FcChar8 *) run, len, &glyphinfo);
776 return glyphinfo.xOff;
777 }
778 #endif
779
772 /* Code for drawing strings. */ 780 /* Code for drawing strings. */
773 static void 781 static void
774 string_draw (XlwMenuWidget mw, 782 string_draw (XlwMenuWidget mw,
775 Window window, 783 Window window,
776 int x, int y, 784 int x, int y,
785 #ifdef USE_XFT_MENUBARS
786 XftColor *color,
787 XftColor *colorBg,
788 #else
777 GC gc, 789 GC gc,
778 #ifdef NEED_MOTIF 790 #endif
791 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
779 XmString string 792 XmString string
780 #else 793 #else
781 char *string 794 char *string
782 #endif 795 #endif
783 ) 796 )
784 { 797 {
785 #ifdef NEED_MOTIF 798 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
786 XmStringDraw (XtDisplay (mw), window, 799 XmStringDraw (XtDisplay (mw), window,
787 mw->menu.font_list, 800 mw->menu.font_list,
788 string, gc, 801 string, gc,
789 x, y, 802 x, y,
790 1000, /* ???? width */ 803 1000, /* ???? width */
791 XmALIGNMENT_BEGINNING, 804 XmALIGNMENT_BEGINNING,
792 0, /* ???? layout_direction */ 805 0, /* ???? layout_direction */
793 0); 806 0);
794 #else 807 #else
795 # ifdef USE_XFONTSET 808 # ifdef USE_XFT_MENUBARS
809 Display *display = XtDisplay (mw);
810 Visual *visual = DefaultVisualOfScreen (XtScreen (mw));
811 Colormap cmap = mw->core.colormap;
812 XftDraw *xftDraw = XftDrawCreate (display, window, visual, cmap);
813 XftFont *renderFont = mw->menu.renderFont;
814 /* draw background rect */
815 XftDrawRect (xftDraw, colorBg,
816 x, y,
817 x_xft_text_width (display, renderFont, string, strlen (string)),
818 renderFont->ascent + renderFont->descent); /* XXX */
819 /* draw text */
820 XftDrawString8 (xftDraw, color, renderFont, x, y + mw->menu.font_ascent,
821 (FcChar8 *) string, strlen (string));
822 XftDrawDestroy (xftDraw);
823 # else
824 # ifdef USE_XFONTSET
796 XmbDrawString (XtDisplay (mw), window, mw->menu.font_set, gc, 825 XmbDrawString (XtDisplay (mw), window, mw->menu.font_set, gc,
797 x, y + mw->menu.font_ascent, string, strlen (string)); 826 x, y + mw->menu.font_ascent, string, strlen (string));
798 # else 827 # else
799 XDrawString (XtDisplay (mw), window, gc, 828 XDrawString (XtDisplay (mw), window, gc,
800 x, y + mw->menu.font_ascent, string, strlen (string)); 829 x, y + mw->menu.font_ascent, string, strlen (string));
801 # endif /* USE_XFONTSET */ 830 # endif /* USE_XFONTSET */
802 831 # endif /* USE_XFT_MENUBARS */
803 #endif 832 #endif /* NEED_MOTIF */
804 } 833 }
805 834
806 static int 835 static int
807 string_draw_range ( 836 string_draw_range (
808 XlwMenuWidget mw, 837 XlwMenuWidget mw,
809 Window window, 838 Window window,
810 int x, int y, 839 int x, int y,
840 #ifdef USE_XFT_MENUBARS
841 XftColor *color,
842 XftColor *colorBg,
843 #else
811 GC gc, 844 GC gc,
845 #endif
812 char *string, 846 char *string,
813 int start, 847 int start,
814 int end 848 int end
815 ) 849 )
816 { 850 {
817 #ifdef NEED_MOTIF 851 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
818 Dimension width, height; 852 Dimension width, height;
819 XmString newstring; 853 XmString newstring;
820 int c; 854 int c;
821 855
822 if (end <= start) 856 if (end <= start)
849 x, y + mw->menu.font_ascent, &string[start], end - start); 883 x, y + mw->menu.font_ascent, &string[start], end - start);
850 XmbTextExtents ( 884 XmbTextExtents (
851 mw->menu.font_set, &string[start], end - start, &ri, &rl); 885 mw->menu.font_set, &string[start], end - start, &ri, &rl);
852 return rl.width; 886 return rl.width;
853 # else 887 # else
888 #ifdef USE_XFT_MENUBARS
889 if (end <= start)
890 return 0;
891 else
892 {
893 XGlyphInfo glyphinfo;
894 Display *display = XtDisplay (mw);
895 Visual *visual = DefaultVisualOfScreen (XtScreen (mw));
896 Colormap cmap = mw->core.colormap;
897 XftFont *renderFont = mw->menu.renderFont;
898 /* #### should use parent frame's .xftDraw? */
899 XftDraw *xftDraw = XftDrawCreate (display, window, visual, cmap);
900 /* draw background rect */
901 XftDrawRect (xftDraw, colorBg,
902 x, y,
903 x_xft_text_width (display,
904 renderFont, &string[start], end - start),
905 renderFont->ascent + renderFont->descent); /* XXX */
906 /* draw text */
907 XftDrawString8 (xftDraw, color, renderFont,
908 x, y + mw->menu.font_ascent,
909 (FcChar8 *) &string[start], end - start);
910
911 XftTextExtents8 (display, renderFont, (FcChar8 *) &string[start],
912 end - start, &glyphinfo);
913
914 /* #### should use parent frame's .xftDraw */
915 XftDrawDestroy (xftDraw);
916 return glyphinfo.xOff;
917 }
918 #else
854 XCharStruct xcs; 919 XCharStruct xcs;
855 int drop; 920 int drop;
856 921
857 if (end <= start) 922 if (end <= start)
858 return 0; 923 return 0;
859 XDrawString ( 924 XDrawString ( /* XXX */
860 XtDisplay (mw), window, gc, 925 XtDisplay (mw), window, gc,
861 x, y + mw->menu.font_ascent, &string[start], end - start); 926 x, y + mw->menu.font_ascent, &string[start], end - start);
862 XTextExtents ( 927 XTextExtents (
863 mw->menu.font, &string[start], end - start, 928 mw->menu.font, &string[start], end - start,
864 &drop, &drop, &drop, &xcs); 929 &drop, &drop, &drop, &xcs);
865 return xcs.width; 930 return xcs.width;
931 #endif
866 # endif 932 # endif
867 #endif 933 #endif
868 } 934 }
869 935
870 static void 936 static void
871 string_draw_u (XlwMenuWidget mw, 937 string_draw_u (XlwMenuWidget mw,
872 Window window, 938 Window window,
873 int x, int y, 939 int x, int y,
940 #ifdef USE_XFT_MENUBARS
941 XftColor *color, XftColor *colorBg, GC gc,
942 #else
874 GC gc, 943 GC gc,
875 #ifdef NEED_MOTIF 944 #endif
945 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
876 XmString string 946 XmString string
877 #else 947 #else
878 char *string 948 char *string
879 #endif 949 #endif
880 ) 950 )
881 { 951 {
882 int i, s = 0; 952 int i, s = 0;
883 char *chars; 953 char *chars;
884 954
885 #ifdef NEED_MOTIF 955 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
886 chars = ""; 956 chars = "";
887 if (!XmStringGetLtoR (string, XmFONTLIST_DEFAULT_TAG, &chars)) 957 if (!XmStringGetLtoR (string, XmFONTLIST_DEFAULT_TAG, &chars))
888 chars = ""; 958 chars = "";
889 #else 959 #else
890 chars = string; 960 chars = string;
891 #endif 961 #endif
892 for (i=0; chars[i]; ++i) { 962 for (i=0; chars[i]; ++i) {
893 if (chars[i] == '%' && chars[i+1] == '_') { 963 if (chars[i] == '%' && chars[i+1] == '_') {
894 int w; 964 int w;
895 965
966 #ifdef USE_XFT_MENUBARS
967 x += string_draw_range (mw, window, x, y, color, colorBg, chars, s, i);
968 w = string_draw_range (mw, window, x, y, color, colorBg, chars, i+2, i+3);
969 #else
896 x += string_draw_range (mw, window, x, y, gc, chars, s, i); 970 x += string_draw_range (mw, window, x, y, gc, chars, s, i);
897 w = string_draw_range (mw, window, x, y, gc, chars, i+2, i+3); 971 w = string_draw_range (mw, window, x, y, gc, chars, i+2, i+3);
972 #endif
898 973
899 /* underline next character */ 974 /* underline next character */
900 XDrawLine (XtDisplay (mw), window, gc, x - 1, 975 XDrawLine (XtDisplay (mw), window, gc, x - 1,
901 y + mw->menu.font_ascent + 1, 976 y + mw->menu.font_ascent + 1,
902 x + w - 1, y + mw->menu.font_ascent + 1 ); 977 x + w - 1, y + mw->menu.font_ascent + 1 );
903 x += w; 978 x += w;
904 s = i + 3; 979 s = i + 3;
905 i += 2; 980 i += 2;
906 } 981 }
907 } 982 }
983 #ifdef USE_XFT_MENUBARS
984 x += string_draw_range (mw, window, x, y, color, colorBg, chars, s, i);
985 #else
908 x += string_draw_range (mw, window, x, y, gc, chars, s, i); 986 x += string_draw_range (mw, window, x, y, gc, chars, s, i);
909 #ifdef NEED_MOTIF 987 #endif
988 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
910 XtFree (chars); 989 XtFree (chars);
911 #endif 990 #endif
912 } 991 }
913 992
914 static void 993 static void /* XXX */
915 binding_draw (XlwMenuWidget mw, Window w, int x, int y, GC gc, char *value) 994 binding_draw (XlwMenuWidget mw, Window w, int x, int y,
916 { 995 #ifdef USE_XFT_MENUBARS
917 #ifdef NEED_MOTIF 996 XftColor *color,
997 XftColor *colorBg,
998 #else
999 GC gc,
1000 #endif
1001 char *value)
1002 {
1003 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
918 XmString xm_value = XmStringCreateLtoR(value, XmSTRING_DEFAULT_CHARSET); 1004 XmString xm_value = XmStringCreateLtoR(value, XmSTRING_DEFAULT_CHARSET);
919 string_draw (mw, w, x, y, gc, xm_value); 1005 string_draw (mw, w, x, y, gc, xm_value);
920 XmStringFree (xm_value); 1006 XmStringFree (xm_value);
921 #else 1007 #else
1008 #ifdef USE_XFT_MENUBARS
1009 string_draw (mw, w, x, y, color, colorBg, value);
1010 #else
922 string_draw (mw, w, x, y, gc, value); 1011 string_draw (mw, w, x, y, gc, value);
1012 #endif
923 #endif 1013 #endif
924 } 1014 }
925 1015
926 /* Low level code for drawing 3-D edges. */ 1016 /* Low level code for drawing 3-D edges. */
927 static void 1017 static void
1560 unsigned int UNUSED (binding_tab)) 1650 unsigned int UNUSED (binding_tab))
1561 { 1651 {
1562 int y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin; 1652 int y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin;
1563 GC gc; 1653 GC gc;
1564 1654
1655 #ifdef USE_XFT_MENUBARS
1656 XftColor color, colorBg;
1657 Display *display = XtDisplay (mw);
1658 Colormap cmap = mw->core.colormap;
1659 Visual *visual;
1660 int ignored, pixel, pixelBg;
1661
1662 visual_info_from_widget ((Widget) mw, &visual, &ignored);
1663 #endif
1664
1565 if (!label_offset) 1665 if (!label_offset)
1566 label_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin; 1666 label_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin;
1567 1667
1568 if (highlighted && (in_menubar || val->contents)) 1668 if (highlighted && (in_menubar || val->contents))
1569 gc = mw->menu.highlight_gc; 1669 {
1670 #ifdef USE_XFT_MENUBARS
1671 pixel = mw->menu.highlight_foreground;
1672 pixelBg = mw->core.background_pixel;
1673 #endif
1674 gc = mw->menu.highlight_gc;
1675 }
1570 else if (in_menubar || val->contents) 1676 else if (in_menubar || val->contents)
1571 gc = mw->menu.foreground_gc; 1677 {
1678 #ifdef USE_XFT_MENUBARS
1679 pixel = mw->menu.foreground;
1680 pixelBg = mw->core.background_pixel;
1681 #endif
1682 gc = mw->menu.foreground_gc;
1683 }
1572 else 1684 else
1573 gc = mw->menu.title_gc; 1685 {
1686 #ifdef USE_XFT_MENUBARS
1687 pixel = mw->menu.title_foreground;
1688 pixelBg = mw->core.background_pixel;
1689 #endif
1690 gc = mw->menu.title_gc;
1691 }
1692 #ifdef USE_XFT_MENUBARS
1693 color = xft_convert_color (display, cmap, visual, pixel, 0);
1694 colorBg = xft_convert_color (display, cmap, visual, pixelBg, 0);
1695 #endif
1574 1696
1575 /* Draw the label string. */ 1697 /* Draw the label string. */
1576 string_draw_u (mw, 1698 string_draw_u (mw, /* XXX */
1577 window, 1699 window,
1578 x + label_offset, y + y_offset, 1700 x + label_offset, y + y_offset,
1701 #ifdef USE_XFT_MENUBARS
1702 &color, &colorBg, gc,
1703 #else
1579 gc, 1704 gc,
1705 #endif
1580 resource_widget_value (mw, val)); 1706 resource_widget_value (mw, val));
1581 } 1707 }
1582 1708
1583 static void 1709 static void
1584 push_button_size (XlwMenuWidget mw, 1710 push_button_size (XlwMenuWidget mw,
1596 1722
1597 /* key bindings to display? */ 1723 /* key bindings to display? */
1598 if (!in_menubar && val->key) 1724 if (!in_menubar && val->key)
1599 { 1725 {
1600 int w; 1726 int w;
1601 #ifdef NEED_MOTIF 1727 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
1602 XmString key = XmStringCreateLtoR (val->key, XmSTRING_DEFAULT_CHARSET); 1728 XmString key = XmStringCreateLtoR (val->key, XmSTRING_DEFAULT_CHARSET);
1603 w = string_width (mw, key); 1729 w = string_width (mw, key);
1604 XmStringFree (key); 1730 XmStringFree (key);
1605 #else 1731 #else
1606 char *key = val->key; 1732 char *key = val->key;
1625 int y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin; 1751 int y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin;
1626 GC gc; 1752 GC gc;
1627 shadow_type type; 1753 shadow_type type;
1628 Boolean menu_pb = in_menubar && (menu_item_type (val) == BUTTON_TYPE); 1754 Boolean menu_pb = in_menubar && (menu_item_type (val) == BUTTON_TYPE);
1629 1755
1756 #ifdef USE_XFT_MENUBARS
1757 XftColor color, colorBg;
1758 Display *display = XtDisplay (mw);
1759 Colormap cmap = mw->core.colormap;
1760 Visual *visual;
1761 int ignored, pixel, pixelBg, dim = 0;
1762
1763 visual_info_from_widget ((Widget) mw, &visual, &ignored);
1764 #endif
1765
1630 /* Draw the label string. */ 1766 /* Draw the label string. */
1631 if (!label_offset) 1767 if (!label_offset)
1632 label_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin; 1768 label_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin;
1633 1769
1634 if (highlighted) 1770 if (highlighted)
1635 { 1771 {
1636 if (val->enabled) 1772 if (val->enabled)
1637 gc = mw->menu.highlight_gc; 1773 {
1774 #ifdef USE_XFT_MENUBARS
1775 pixel = mw->menu.highlight_foreground;
1776 pixelBg = mw->core.background_pixel;
1777 #endif
1778 gc = mw->menu.highlight_gc;
1779 }
1638 else 1780 else
1639 gc = mw->menu.inactive_gc; 1781 {
1782 #ifdef USE_XFT_MENUBARS
1783 dim = 1;
1784 pixel = mw->menu.foreground;
1785 pixelBg = mw->core.background_pixel;
1786 #endif
1787 gc = mw->menu.inactive_gc;
1788 }
1640 } 1789 }
1641 else if (menu_pb) 1790 else if (menu_pb)
1642 { 1791 {
1643 if (val->enabled) 1792 if (val->enabled)
1644 gc = mw->menu.button_gc; 1793 {
1794 #ifdef USE_XFT_MENUBARS
1795 pixel = mw->menu.button_foreground;
1796 pixelBg = mw->core.background_pixel;
1797 #endif
1798 gc = mw->menu.button_gc;
1799 }
1645 else 1800 else
1646 gc = mw->menu.inactive_button_gc; 1801 {
1802 #ifdef USE_XFT_MENUBARS
1803 dim = 1;
1804 pixel = mw->menu.button_foreground;
1805 pixelBg = mw->core.background_pixel;
1806 #endif
1807 gc = mw->menu.inactive_button_gc;
1808 }
1647 } 1809 }
1648 else 1810 else
1649 { 1811 {
1650 if (val->enabled) 1812 if (val->enabled)
1651 gc = mw->menu.foreground_gc; 1813 {
1814 #ifdef USE_XFT_MENUBARS
1815 pixel = mw->menu.foreground;
1816 pixelBg = mw->core.background_pixel;
1817 #endif
1818 gc = mw->menu.foreground_gc;
1819 }
1652 else 1820 else
1653 gc = mw->menu.inactive_gc; 1821 {
1654 } 1822 #ifdef USE_XFT_MENUBARS
1823 dim = 1;
1824 pixel = mw->menu.foreground;
1825 pixelBg = mw->core.background_pixel;
1826 #endif
1827 gc = mw->menu.inactive_gc;
1828 }
1829 }
1830
1831 #ifdef USE_XFT_MENUBARS
1832 color = xft_convert_color (display, cmap, visual, pixel, dim);
1833 colorBg = xft_convert_color (display, cmap, visual, pixelBg, 0);
1834 #endif
1655 1835
1656 string_draw_u (mw, 1836 string_draw_u (mw,
1657 window, 1837 window,
1658 x + label_offset, y + y_offset, 1838 x + label_offset, y + y_offset,
1659 gc, 1839 #ifdef USE_XFT_MENUBARS
1840 &color, &colorBg, gc,
1841 #else
1842 gc,
1843 #endif
1660 resource_widget_value (mw, val)); 1844 resource_widget_value (mw, val));
1661 1845
1662 /* Draw the keybindings */ 1846 /* Draw the keybindings */
1663 if (val->key) 1847 if (val->key)
1664 { 1848 {
1668 string_width (mw, resource_widget_value (mw, val)); 1852 string_width (mw, resource_widget_value (mw, val));
1669 binding_offset = label_offset + s_width + mw->menu.shadow_thickness; 1853 binding_offset = label_offset + s_width + mw->menu.shadow_thickness;
1670 } 1854 }
1671 binding_draw (mw, window, 1855 binding_draw (mw, window,
1672 x + binding_offset + mw->menu.column_spacing, 1856 x + binding_offset + mw->menu.column_spacing,
1673 y + y_offset, gc, val->key); 1857 y + y_offset,
1858 #ifdef USE_XFT_MENUBARS
1859 &color, &colorBg,
1860 #else
1861 gc,
1862 #endif
1863 val->key);
1674 } 1864 }
1675 1865
1676 /* Draw the shadow */ 1866 /* Draw the shadow */
1677 if (menu_pb) 1867 if (menu_pb)
1678 { 1868 {
2334 2524
2335 if (mw->menu.windows_length >= n) 2525 if (mw->menu.windows_length >= n)
2336 return; 2526 return;
2337 2527
2338 root = RootWindowOfScreen (XtScreen(mw)); 2528 root = RootWindowOfScreen (XtScreen(mw));
2529 /* use visual_info_from_widget() from lwlib-colors.c */
2339 /* grab the visual and depth from the nearest shell ancestor */ 2530 /* grab the visual and depth from the nearest shell ancestor */
2340 visual = CopyFromParent; 2531 visual = CopyFromParent;
2341 depth = CopyFromParent; 2532 depth = CopyFromParent;
2342 p = XtParent(mw); 2533 p = XtParent(mw);
2343 while (visual == CopyFromParent && p) 2534 while (visual == CopyFromParent && p)
2613 /* Procedures */ 2804 /* Procedures */
2614 static void 2805 static void
2615 make_drawing_gcs (XlwMenuWidget mw) 2806 make_drawing_gcs (XlwMenuWidget mw)
2616 { 2807 {
2617 XGCValues xgcv; 2808 XGCValues xgcv;
2809 #ifdef USE_XFT_MENUBARS
2810 unsigned long flags = (GCForeground | GCBackground);
2811 #else
2618 unsigned long flags = (GCFont | GCForeground | GCBackground); 2812 unsigned long flags = (GCFont | GCForeground | GCBackground);
2619 2813 #endif
2620 #ifdef NEED_MOTIF 2814
2815 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
2621 xgcv.font = default_font_of_font_list (mw->menu.font_list)->fid; 2816 xgcv.font = default_font_of_font_list (mw->menu.font_list)->fid;
2622 #else 2817 #else
2818 #ifndef USE_XFT_MENUBARS
2623 xgcv.font = mw->menu.font->fid; 2819 xgcv.font = mw->menu.font->fid;
2820 #endif
2624 #endif 2821 #endif
2625 2822
2626 xgcv.foreground = mw->core.background_pixel; 2823 xgcv.foreground = mw->core.background_pixel;
2627 xgcv.background = mw->menu.foreground; 2824 xgcv.background = mw->menu.foreground;
2628 mw->menu.background_gc = XtGetGC ((Widget) mw, flags, &xgcv); 2825 mw->menu.background_gc = XtGetGC ((Widget) mw, flags, &xgcv);
2643 xgcv.foreground = mw->menu.foreground; 2840 xgcv.foreground = mw->menu.foreground;
2644 } 2841 }
2645 else 2842 else
2646 { /* color */ 2843 { /* color */
2647 XColor xcolor; 2844 XColor xcolor;
2648 Colormap cmap = mw->core.colormap; 2845 Visual *visual;
2846 int ignore;
2847 Colormap cmap;
2848 visual_info_from_widget ((Widget) mw, &visual, &ignore);
2849 cmap = mw->core.colormap;
2649 xcolor.pixel = mw->core.background_pixel; 2850 xcolor.pixel = mw->core.background_pixel;
2650 XQueryColor (dpy, cmap, &xcolor); 2851 XQueryColor (dpy, cmap, &xcolor);
2651 xcolor.red = (xcolor.red * 17) / 20; 2852 xcolor.red = (xcolor.red * 17) / 20;
2652 xcolor.green = (xcolor.green * 17) / 20; 2853 xcolor.green = (xcolor.green * 17) / 20;
2653 xcolor.blue = (xcolor.blue * 17) / 20; 2854 xcolor.blue = (xcolor.blue * 17) / 20;
2654 if (allocate_nearest_color (dpy, cmap, &xcolor)) 2855 if (x_allocate_nearest_color (dpy, cmap, visual, &xcolor))
2655 xgcv.foreground = xcolor.pixel; 2856 xgcv.foreground = xcolor.pixel;
2656 } 2857 }
2657 } 2858 }
2658 xgcv.background = mw->core.background_pixel; 2859 xgcv.background = mw->core.background_pixel;
2659 mw->menu.select_gc = XtGetGC ((Widget)mw, flags, &xgcv); 2860 mw->menu.select_gc = XtGetGC ((Widget) mw, flags, &xgcv);
2660 2861
2661 xgcv.foreground = mw->menu.foreground; 2862 xgcv.foreground = mw->menu.foreground;
2662 xgcv.background = mw->core.background_pixel; 2863 xgcv.background = mw->core.background_pixel;
2663 xgcv.fill_style = FillStippled; 2864 xgcv.fill_style = FillStippled;
2664 xgcv.stipple = mw->menu.gray_pixmap; 2865 xgcv.stipple = mw->menu.gray_pixmap;
2686 } 2887 }
2687 2888
2688 static void 2889 static void
2689 release_drawing_gcs (XlwMenuWidget mw) 2890 release_drawing_gcs (XlwMenuWidget mw)
2690 { 2891 {
2892
2691 XtReleaseGC ((Widget) mw, mw->menu.foreground_gc); 2893 XtReleaseGC ((Widget) mw, mw->menu.foreground_gc);
2692 XtReleaseGC ((Widget) mw, mw->menu.button_gc); 2894 XtReleaseGC ((Widget) mw, mw->menu.button_gc);
2693 XtReleaseGC ((Widget) mw, mw->menu.highlight_gc); 2895 XtReleaseGC ((Widget) mw, mw->menu.highlight_gc);
2694 XtReleaseGC ((Widget) mw, mw->menu.title_gc); 2896 XtReleaseGC ((Widget) mw, mw->menu.title_gc);
2695 XtReleaseGC ((Widget) mw, mw->menu.inactive_gc); 2897 XtReleaseGC ((Widget) mw, mw->menu.inactive_gc);
2705 mw->menu.inactive_button_gc = (GC) -1; 2907 mw->menu.inactive_button_gc = (GC) -1;
2706 mw->menu.background_gc = (GC) -1; 2908 mw->menu.background_gc = (GC) -1;
2707 mw->menu.select_gc = (GC) -1; 2909 mw->menu.select_gc = (GC) -1;
2708 } 2910 }
2709 2911
2710 #define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \
2711 ? ((unsigned long) (x)) : ((unsigned long) (y)))
2712
2713 static void 2912 static void
2714 make_shadow_gcs (XlwMenuWidget mw) 2913 make_shadow_gcs (XlwMenuWidget mw)
2715 { 2914 {
2716 XGCValues xgcv; 2915 XGCValues xgcv;
2717 unsigned long pm = 0; 2916 unsigned long pm = 0;
2718 Display *dpy = XtDisplay ((Widget) mw); 2917 Display *dpy = XtDisplay ((Widget) mw);
2719 Colormap cmap = mw->core.colormap; 2918 Colormap cmap = mw->core.colormap;
2919 Visual *visual;
2920 int ignored;
2720 XColor topc, botc; 2921 XColor topc, botc;
2721 int top_frobbed = 0, bottom_frobbed = 0; 2922 int top_frobbed = 0, bottom_frobbed = 0;
2923
2924 visual_info_from_widget ((Widget) mw, &visual, &ignored);
2925 /* #### Apparently this is called before any shell has a visual?
2926 or maybe the widget doesn't have a parent yet? */
2927 if (visual == CopyFromParent)
2928 {
2929 Screen *screen = DefaultScreenOfDisplay (dpy);
2930 visual = DefaultVisualOfScreen (screen);
2931 }
2722 2932
2723 if (mw->menu.top_shadow_color == (Pixel) (-1)) 2933 if (mw->menu.top_shadow_color == (Pixel) (-1))
2724 mw->menu.top_shadow_color = mw->core.background_pixel; 2934 mw->menu.top_shadow_color = mw->core.background_pixel;
2725 if (mw->menu.bottom_shadow_color == (Pixel) (-1)) 2935 if (mw->menu.bottom_shadow_color == (Pixel) (-1))
2726 mw->menu.bottom_shadow_color = mw->menu.foreground; 2936 mw->menu.bottom_shadow_color = mw->menu.foreground;
2732 XQueryColor (dpy, cmap, &topc); 2942 XQueryColor (dpy, cmap, &topc);
2733 /* don't overflow/wrap! */ 2943 /* don't overflow/wrap! */
2734 topc.red = MINL (65535, topc.red * 1.2); 2944 topc.red = MINL (65535, topc.red * 1.2);
2735 topc.green = MINL (65535, topc.green * 1.2); 2945 topc.green = MINL (65535, topc.green * 1.2);
2736 topc.blue = MINL (65535, topc.blue * 1.2); 2946 topc.blue = MINL (65535, topc.blue * 1.2);
2737 if (allocate_nearest_color (dpy, cmap, &topc)) 2947 if (x_allocate_nearest_color (dpy, cmap, visual, &topc))
2738 { 2948 {
2739 if (topc.pixel == mw->core.background_pixel) 2949 if (topc.pixel == mw->core.background_pixel)
2740 { 2950 {
2741 XFreeColors( dpy, cmap, &topc.pixel, 1, 0); 2951 XFreeColors( dpy, cmap, &topc.pixel, 1, 0);
2742 topc.red = MINL (65535, topc.red + 0x8000); 2952 topc.red = MINL (65535, topc.red + 0x8000);
2743 topc.green = MINL (65535, topc.green + 0x8000); 2953 topc.green = MINL (65535, topc.green + 0x8000);
2744 topc.blue = MINL (65535, topc.blue + 0x8000); 2954 topc.blue = MINL (65535, topc.blue + 0x8000);
2745 if (allocate_nearest_color (dpy, cmap, &topc)) 2955 if (x_allocate_nearest_color (dpy, cmap, visual, &topc))
2746 { 2956 {
2747 mw->menu.top_shadow_color = topc.pixel; 2957 mw->menu.top_shadow_color = topc.pixel;
2748 } 2958 }
2749 } 2959 }
2750 else 2960 else
2761 botc.pixel = mw->core.background_pixel; 2971 botc.pixel = mw->core.background_pixel;
2762 XQueryColor (dpy, cmap, &botc); 2972 XQueryColor (dpy, cmap, &botc);
2763 botc.red = (botc.red * 3) / 5; 2973 botc.red = (botc.red * 3) / 5;
2764 botc.green = (botc.green * 3) / 5; 2974 botc.green = (botc.green * 3) / 5;
2765 botc.blue = (botc.blue * 3) / 5; 2975 botc.blue = (botc.blue * 3) / 5;
2766 if (allocate_nearest_color (dpy, cmap, &botc)) 2976 if (x_allocate_nearest_color (dpy, cmap, visual, &botc))
2767 { 2977 {
2768 if (botc.pixel == mw->core.background_pixel) 2978 if (botc.pixel == mw->core.background_pixel)
2769 { 2979 {
2770 XFreeColors (dpy, cmap, &botc.pixel, 1, 0); 2980 XFreeColors (dpy, cmap, &botc.pixel, 1, 0);
2771 botc.red = MINL (65535, botc.red + 0x4000); 2981 botc.red = MINL (65535, botc.red + 0x4000);
2772 botc.green = MINL (65535, botc.green + 0x4000); 2982 botc.green = MINL (65535, botc.green + 0x4000);
2773 botc.blue = MINL (65535, botc.blue + 0x4000); 2983 botc.blue = MINL (65535, botc.blue + 0x4000);
2774 if (allocate_nearest_color (dpy, cmap, &botc)) 2984 if (x_allocate_nearest_color (dpy, cmap, visual, &botc))
2775 { 2985 {
2776 mw->menu.bottom_shadow_color = botc.pixel; 2986 mw->menu.bottom_shadow_color = botc.pixel;
2777 } 2987 }
2778 } 2988 }
2779 else 2989 else
2852 3062
2853 3063
2854 static void 3064 static void
2855 extract_font_extents (XlwMenuWidget mw) 3065 extract_font_extents (XlwMenuWidget mw)
2856 { 3066 {
2857 #ifdef NEED_MOTIF 3067 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
2858 /* Find the maximal ascent/descent of the fonts in the font list 3068 /* Find the maximal ascent/descent of the fonts in the font list
2859 so that all menu items can be the same height... */ 3069 so that all menu items can be the same height... */
2860 mw->menu.font_ascent = 0; 3070 mw->menu.font_ascent = 0;
2861 mw->menu.font_descent = 0; 3071 mw->menu.font_descent = 0;
2862 3072
2937 mw->menu.font_ascent = font->ascent; 3147 mw->menu.font_ascent = font->ascent;
2938 if (font->descent > (int) mw->menu.font_descent) 3148 if (font->descent > (int) mw->menu.font_descent)
2939 mw->menu.font_descent = font->descent; 3149 mw->menu.font_descent = font->descent;
2940 } 3150 }
2941 # else /* ! USE_XFONTSET */ 3151 # else /* ! USE_XFONTSET */
3152 #ifdef USE_XFT_MENUBARS
3153 mw->menu.font_ascent = mw->menu.renderFont->ascent;
3154 mw->menu.font_descent = mw->menu.renderFont->descent;
3155 #else
2942 mw->menu.font_ascent = mw->menu.font->ascent; 3156 mw->menu.font_ascent = mw->menu.font->ascent;
2943 mw->menu.font_descent = mw->menu.font->descent; 3157 mw->menu.font_descent = mw->menu.font->descent;
3158 #endif
2944 # endif 3159 # endif
2945 #endif /* NEED_MOTIF */ 3160 #endif /* NEED_MOTIF */
2946 } 3161 }
2947 3162
2948 #ifdef NEED_MOTIF 3163 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
2949 static XFontStruct * 3164 static XFontStruct *
2950 default_font_of_font_list (XmFontList font_list) 3165 default_font_of_font_list (XmFontList font_list)
2951 { 3166 {
2952 XFontStruct *font = 0; 3167 XFontStruct *font = 0;
2953 # if 0 3168 # if 0
3013 3228
3014 mw->menu.gray_pixmap = 3229 mw->menu.gray_pixmap =
3015 XCreatePixmapFromBitmapData (display, window, (char *) gray_bits, 3230 XCreatePixmapFromBitmapData (display, window, (char *) gray_bits,
3016 gray_width, gray_height, 1, 0, 1); 3231 gray_width, gray_height, 1, 0, 1);
3017 3232
3018 #ifdef NEED_MOTIF 3233 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
3019 /* #### Even if it's a kludge!!!, we should consider doing the same for 3234 /* #### Even if it's a kludge!!!, we should consider doing the same for
3020 X Font Sets. */ 3235 X Font Sets. */
3021 /* The menu.font_list slot came from the *fontList resource (Motif standard.) 3236 /* The menu.font_list slot came from the *fontList resource (Motif standard.)
3022 The menu.font_list_2 slot came from the *font resource, for backward 3237 The menu.font_list_2 slot came from the *font resource, for backward
3023 compatibility with older versions of this code, and consistency with the 3238 compatibility with older versions of this code, and consistency with the
3035 mw->menu.font_list = mw->menu.font_list_2; 3250 mw->menu.font_list = mw->menu.font_list_2;
3036 else /* otherwise use default */ 3251 else /* otherwise use default */
3037 mw->menu.font_list = mw->menu.fallback_font_list; 3252 mw->menu.font_list = mw->menu.fallback_font_list;
3038 #endif 3253 #endif
3039 3254
3255 #ifdef USE_XFT_MENUBARS
3256 /* #### kludge for name change */
3257 if (!mw->menu.fcFontName)
3258 mw->menu.fcFontName = mw->menu.xftFontName;
3259 /* to do this right, we should add a new Xt Resource type +
3260 conversion function
3261 */
3262 mw->menu.renderFont =
3263 xft_open_font_by_name (XtDisplay (mw), mw->menu.fcFontName);
3264 #endif
3265
3040 make_drawing_gcs (mw); 3266 make_drawing_gcs (mw);
3041 make_shadow_gcs (mw); 3267 make_shadow_gcs (mw);
3042 extract_font_extents (mw); 3268 extract_font_extents (mw);
3043 3269
3044 mw->menu.popped_up = False; 3270 mw->menu.popped_up = False;
3134 3360
3135 /* this doesn't come from the resource db but is created explicitly 3361 /* this doesn't come from the resource db but is created explicitly
3136 so we must free it ourselves. */ 3362 so we must free it ourselves. */
3137 XFreePixmap (XtDisplay (mw), mw->menu.gray_pixmap); 3363 XFreePixmap (XtDisplay (mw), mw->menu.gray_pixmap);
3138 mw->menu.gray_pixmap = (Pixmap) -1; 3364 mw->menu.gray_pixmap = (Pixmap) -1;
3365
3366 #ifdef USE_XFT_MENUBARS
3367 XftFontClose (XtDisplay (mw), mw->menu.renderFont);
3368 #endif
3139 3369
3140 /* Don't free mw->menu.contents because that comes from our creator. 3370 /* Don't free mw->menu.contents because that comes from our creator.
3141 The `*_stack' elements are just pointers into `contents' so leave 3371 The `*_stack' elements are just pointers into `contents' so leave
3142 that alone too. But free the stacks themselves. */ 3372 that alone too. But free the stacks themselves. */
3143 if (mw->menu.old_stack) XtFree ((char *) mw->menu.old_stack); 3373 if (mw->menu.old_stack) XtFree ((char *) mw->menu.old_stack);
3177 redisplay = True; 3407 redisplay = True;
3178 3408
3179 if (newmw->core.background_pixel != oldmw->core.background_pixel 3409 if (newmw->core.background_pixel != oldmw->core.background_pixel
3180 || newmw->menu.foreground != oldmw->menu.foreground 3410 || newmw->menu.foreground != oldmw->menu.foreground
3181 /* For the XEditResource protocol, which may want to change the font. */ 3411 /* For the XEditResource protocol, which may want to change the font. */
3182 #ifdef NEED_MOTIF 3412 #if defined(NEED_MOTIF) && !defined(USE_XFT_MENUBARS)
3183 || newmw->menu.font_list != oldmw->menu.font_list 3413 || newmw->menu.font_list != oldmw->menu.font_list
3184 || newmw->menu.font_list_2 != oldmw->menu.font_list_2 3414 || newmw->menu.font_list_2 != oldmw->menu.font_list_2
3185 || newmw->menu.fallback_font_list != oldmw->menu.fallback_font_list 3415 || newmw->menu.fallback_font_list != oldmw->menu.fallback_font_list
3186 #else 3416 #else
3417 #ifdef USE_XFT_MENUBARS
3418 || newmw->menu.renderFont != oldmw->menu.renderFont
3419 #else
3187 || newmw->menu.font != oldmw->menu.font 3420 || newmw->menu.font != oldmw->menu.font
3421 #endif
3188 #endif 3422 #endif
3189 ) 3423 )
3190 { 3424 {
3191 release_drawing_gcs (newmw); 3425 release_drawing_gcs (newmw);
3192 make_drawing_gcs (newmw); 3426 make_drawing_gcs (newmw);
3413 lw_menu_accelerate = True; 3647 lw_menu_accelerate = True;
3414 3648
3415 if (!mw->menu.pointer_grabbed) 3649 if (!mw->menu.pointer_grabbed)
3416 { 3650 {
3417 XWindowAttributes ret; 3651 XWindowAttributes ret;
3418 Window parent,root; 3652 Window parent,root = 0UL;
3419 Window *waste; 3653 Window *waste = NULL;
3420 unsigned int num_waste; 3654 unsigned int num_waste;
3421 3655
3422 lw_menu_active = True; 3656 lw_menu_active = True;
3423 3657
3424 mw->menu.menu_post_time = t; 3658 mw->menu.menu_post_time = t;