Mercurial > hg > xemacs-beta
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; |