1 |
/* Implements a lightweight menubar widget. |
/* Implements a lightweight menubar widget. |
2 |
Copyright (C) 1992 Lucid, Inc. |
Copyright (C) 1992 Lucid, Inc. |
3 |
Copyright (C) 2002 Free Software Foundation, Inc. |
Copyright (C) 2002, 2005 Free Software Foundation, Inc. |
4 |
|
|
5 |
This file is part of the Lucid Widget Library. |
This file is part of the Lucid Widget Library. |
6 |
|
|
135 |
static XtResource |
static XtResource |
136 |
xlwMenuResources[] = |
xlwMenuResources[] = |
137 |
{ |
{ |
138 |
|
#ifdef HAVE_X_I18N |
139 |
|
{XtNfont, XtCFont, XtRFontSet, sizeof(XFontSet), |
140 |
|
offset(menu.font), XtRString, "XtDefaultFontSet"}, |
141 |
|
#else |
142 |
{XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), |
{XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), |
143 |
offset(menu.font),XtRString, "XtDefaultFont"}, |
offset(menu.font), XtRString, "XtDefaultFont"}, |
144 |
|
#endif |
145 |
{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), |
{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), |
146 |
offset(menu.foreground), XtRString, "XtDefaultForeground"}, |
offset(menu.foreground), XtRString, "XtDefaultForeground"}, |
147 |
{XtNdisabledForeground, XtCDisabledForeground, XtRPixel, sizeof(Pixel), |
{XtNdisabledForeground, XtCDisabledForeground, XtRPixel, sizeof(Pixel), |
240 |
XtNumber(xlwMenuResources), /* resource_count */ |
XtNumber(xlwMenuResources), /* resource_count */ |
241 |
NULLQUARK, /* xrm_class */ |
NULLQUARK, /* xrm_class */ |
242 |
TRUE, /* compress_motion */ |
TRUE, /* compress_motion */ |
243 |
TRUE, /* compress_exposure */ |
XtExposeCompressMaximal, /* compress_exposure */ |
244 |
TRUE, /* compress_enterleave */ |
TRUE, /* compress_enterleave */ |
245 |
FALSE, /* visible_interest */ |
FALSE, /* visible_interest */ |
246 |
XlwMenuDestroy, /* destroy */ |
XlwMenuDestroy, /* destroy */ |
358 |
XlwMenuWidget mw; |
XlwMenuWidget mw; |
359 |
char *s; |
char *s; |
360 |
{ |
{ |
361 |
|
#ifdef HAVE_X_I18N |
362 |
|
XRectangle ink, logical; |
363 |
|
XmbTextExtents (mw->menu.font, s, strlen (s), &ink, &logical); |
364 |
|
return logical.width; |
365 |
|
#else |
366 |
XCharStruct xcs; |
XCharStruct xcs; |
367 |
int drop; |
int drop; |
368 |
|
|
369 |
XTextExtents (mw->menu.font, s, strlen (s), &drop, &drop, &drop, &xcs); |
XTextExtents (mw->menu.font, s, strlen (s), &drop, &drop, &drop, &xcs); |
370 |
return xcs.width; |
return xcs.width; |
371 |
|
#endif |
372 |
} |
} |
373 |
|
|
374 |
|
#ifdef HAVE_X_I18N |
375 |
|
#define MENU_FONT_HEIGHT(mw) \ |
376 |
|
((mw)->menu.font_extents->max_logical_extent.height) |
377 |
|
#define MENU_FONT_ASCENT(mw) (MENU_FONT_HEIGHT(mw) * 9 / 10) |
378 |
|
#else |
379 |
|
#define MENU_FONT_HEIGHT(mw) \ |
380 |
|
((mw)->menu.font->ascent + (mw)->menu.font->descent) |
381 |
|
#define MENU_FONT_ASCENT(mw) ((mw)->menu.font->ascent) |
382 |
|
#endif |
383 |
|
|
384 |
static int |
static int |
385 |
arrow_width (mw) |
arrow_width (mw) |
386 |
XlwMenuWidget mw; |
XlwMenuWidget mw; |
387 |
{ |
{ |
388 |
return (mw->menu.font->ascent * 3/4) | 1; |
return (MENU_FONT_ASCENT (mw) * 3/4) | 1; |
389 |
} |
} |
390 |
|
|
391 |
/* Return the width of toggle buttons of widget MW. */ |
/* Return the width of toggle buttons of widget MW. */ |
394 |
toggle_button_width (mw) |
toggle_button_width (mw) |
395 |
XlwMenuWidget mw; |
XlwMenuWidget mw; |
396 |
{ |
{ |
397 |
return ((mw->menu.font->ascent + mw->menu.font->descent) * 2 / 3) | 1; |
return (MENU_FONT_HEIGHT (mw) * 2 / 3) | 1; |
398 |
} |
} |
399 |
|
|
400 |
|
|
475 |
} |
} |
476 |
else |
else |
477 |
{ |
{ |
478 |
*height = |
*height = MENU_FONT_HEIGHT (mw) |
479 |
mw->menu.font->ascent + mw->menu.font->descent |
+ 2 * mw->menu.vertical_spacing + 2 * mw->menu.shadow_thickness; |
|
+ 2 * mw->menu.vertical_spacing + 2 * mw->menu.shadow_thickness; |
|
480 |
|
|
481 |
*label_width = |
*label_width = |
482 |
string_width (mw, resource_widget_value (mw, val)) |
string_width (mw, resource_widget_value (mw, val)) |
591 |
double factor = 1.62; |
double factor = 1.62; |
592 |
int thickness2 = thickness * factor; |
int thickness2 = thickness * factor; |
593 |
|
|
594 |
y += (mw->menu.font->ascent + mw->menu.font->descent - height) / 2; |
y += (MENU_FONT_HEIGHT (mw) - height) / 2; |
595 |
|
|
596 |
if (down_p) |
if (down_p) |
597 |
{ |
{ |
777 |
width = toggle_button_width (mw); |
width = toggle_button_width (mw); |
778 |
height = width; |
height = width; |
779 |
x += mw->menu.horizontal_spacing; |
x += mw->menu.horizontal_spacing; |
780 |
y += (mw->menu.font->ascent - height) / 2; |
y += (MENU_FONT_ASCENT (mw) - height) / 2; |
781 |
draw_shadow_rectangle (mw, window, x, y, width, height, False, selected_p); |
draw_shadow_rectangle (mw, window, x, y, width, height, False, selected_p); |
782 |
} |
} |
783 |
|
|
797 |
width = radio_button_width (mw); |
width = radio_button_width (mw); |
798 |
height = width; |
height = width; |
799 |
x += mw->menu.horizontal_spacing; |
x += mw->menu.horizontal_spacing; |
800 |
y += (mw->menu.font->ascent - height) / 2; |
y += (MENU_FONT_ASCENT (mw) - height) / 2; |
801 |
draw_shadow_rhombus (mw, window, x, y, width, height, False, selected_p); |
draw_shadow_rhombus (mw, window, x, y, width, height, False, selected_p); |
802 |
} |
} |
803 |
|
|
974 |
{ |
{ |
975 |
GC deco_gc; |
GC deco_gc; |
976 |
GC text_gc; |
GC text_gc; |
977 |
int font_ascent = mw->menu.font->ascent; |
int font_height = MENU_FONT_HEIGHT (mw); |
978 |
int font_descent = mw->menu.font->descent; |
int font_ascent = MENU_FONT_ASCENT (mw); |
979 |
int shadow = mw->menu.shadow_thickness; |
int shadow = mw->menu.shadow_thickness; |
980 |
int margin = mw->menu.margin; |
int margin = mw->menu.margin; |
981 |
int h_spacing = mw->menu.horizontal_spacing; |
int h_spacing = mw->menu.horizontal_spacing; |
1048 |
x_offset += ws->button_width; |
x_offset += ws->button_width; |
1049 |
|
|
1050 |
|
|
1051 |
XDrawString (XtDisplay (mw), ws->window, text_gc, x_offset, |
#ifdef HAVE_X_I18N |
1052 |
|
XmbDrawString (XtDisplay (mw), ws->window, mw->menu.font, |
1053 |
|
#else |
1054 |
|
XDrawString (XtDisplay (mw), ws->window, |
1055 |
|
#endif |
1056 |
|
text_gc, x_offset, |
1057 |
y + v_spacing + shadow + font_ascent, |
y + v_spacing + shadow + font_ascent, |
1058 |
display_string, strlen (display_string)); |
display_string, strlen (display_string)); |
1059 |
|
|
1078 |
} |
} |
1079 |
else if (val->key) |
else if (val->key) |
1080 |
{ |
{ |
1081 |
XDrawString (XtDisplay (mw), ws->window, text_gc, |
#ifdef HAVE_X_I18N |
1082 |
|
XmbDrawString (XtDisplay (mw), ws->window, mw->menu.font, |
1083 |
|
#else |
1084 |
|
XDrawString (XtDisplay (mw), ws->window, |
1085 |
|
#endif |
1086 |
|
text_gc, |
1087 |
x + label_width + mw->menu.arrow_spacing, |
x + label_width + mw->menu.arrow_spacing, |
1088 |
y + v_spacing + shadow + font_ascent, |
y + v_spacing + shadow + font_ascent, |
1089 |
val->key, strlen (val->key)); |
val->key, strlen (val->key)); |
1095 |
mw->menu.background_gc, |
mw->menu.background_gc, |
1096 |
x + shadow, y + shadow, |
x + shadow, y + shadow, |
1097 |
label_width + h_spacing - 1, |
label_width + h_spacing - 1, |
1098 |
font_ascent + font_descent + 2 * v_spacing - 1); |
font_height + 2 * v_spacing - 1); |
1099 |
draw_shadow_rectangle (mw, ws->window, x, y, width, height, |
draw_shadow_rectangle (mw, ws->window, x, y, width, height, |
1100 |
True, False); |
True, False); |
1101 |
} |
} |
1490 |
XGCValues xgcv; |
XGCValues xgcv; |
1491 |
float scale; |
float scale; |
1492 |
|
|
1493 |
|
#ifndef HAVE_X_I18N |
1494 |
xgcv.font = mw->menu.font->fid; |
xgcv.font = mw->menu.font->fid; |
1495 |
|
#endif |
1496 |
xgcv.foreground = mw->menu.foreground; |
xgcv.foreground = mw->menu.foreground; |
1497 |
xgcv.background = mw->core.background_pixel; |
xgcv.background = mw->core.background_pixel; |
1498 |
mw->menu.foreground_gc = XtGetGC ((Widget)mw, |
mw->menu.foreground_gc = XtGetGC ((Widget)mw, |
1499 |
GCFont | GCForeground | GCBackground, |
#ifndef HAVE_X_I18N |
1500 |
|
GCFont | |
1501 |
|
#endif |
1502 |
|
GCForeground | GCBackground, |
1503 |
&xgcv); |
&xgcv); |
1504 |
|
|
1505 |
|
#ifndef HAVE_X_I18N |
1506 |
xgcv.font = mw->menu.font->fid; |
xgcv.font = mw->menu.font->fid; |
1507 |
|
#endif |
1508 |
xgcv.foreground = mw->menu.button_foreground; |
xgcv.foreground = mw->menu.button_foreground; |
1509 |
xgcv.background = mw->core.background_pixel; |
xgcv.background = mw->core.background_pixel; |
1510 |
mw->menu.button_gc = XtGetGC ((Widget)mw, |
mw->menu.button_gc = XtGetGC ((Widget)mw, |
1511 |
GCFont | GCForeground | GCBackground, |
#ifndef HAVE_X_I18N |
1512 |
|
GCFont | |
1513 |
|
#endif |
1514 |
|
GCForeground | GCBackground, |
1515 |
&xgcv); |
&xgcv); |
1516 |
|
|
1517 |
|
#ifndef HAVE_X_I18N |
1518 |
xgcv.font = mw->menu.font->fid; |
xgcv.font = mw->menu.font->fid; |
1519 |
|
#endif |
1520 |
xgcv.background = mw->core.background_pixel; |
xgcv.background = mw->core.background_pixel; |
1521 |
|
|
1522 |
#define BRIGHTNESS(color) (((color) & 0xff) + (((color) >> 8) & 0xff) + (((color) >> 16) & 0xff)) |
#define BRIGHTNESS(color) (((color) & 0xff) + (((color) >> 8) & 0xff) + (((color) >> 16) & 0xff)) |
1542 |
xgcv.fill_style = FillStippled; |
xgcv.fill_style = FillStippled; |
1543 |
xgcv.stipple = mw->menu.gray_pixmap; |
xgcv.stipple = mw->menu.gray_pixmap; |
1544 |
mw->menu.disabled_gc = XtGetGC ((Widget)mw, |
mw->menu.disabled_gc = XtGetGC ((Widget)mw, |
1545 |
(GCFont | GCForeground | GCBackground |
#ifndef HAVE_X_I18N |
1546 |
| GCFillStyle | GCStipple), &xgcv); |
GCFont | |
1547 |
|
#endif |
1548 |
|
GCForeground | GCBackground |
1549 |
|
| GCFillStyle | GCStipple, &xgcv); |
1550 |
} |
} |
1551 |
else |
else |
1552 |
{ |
{ |
1553 |
/* Many colors available, use disabled pixel. */ |
/* Many colors available, use disabled pixel. */ |
1554 |
xgcv.foreground = mw->menu.disabled_foreground; |
xgcv.foreground = mw->menu.disabled_foreground; |
1555 |
mw->menu.disabled_gc = XtGetGC ((Widget)mw, |
mw->menu.disabled_gc = XtGetGC ((Widget)mw, |
1556 |
(GCFont | GCForeground | GCBackground), &xgcv); |
#ifndef HAVE_X_I18N |
1557 |
|
GCFont | |
1558 |
|
#endif |
1559 |
|
GCForeground | GCBackground, &xgcv); |
1560 |
} |
} |
1561 |
|
|
1562 |
|
#ifndef HAVE_X_I18N |
1563 |
xgcv.font = mw->menu.font->fid; |
xgcv.font = mw->menu.font->fid; |
1564 |
|
#endif |
1565 |
xgcv.foreground = mw->menu.button_foreground; |
xgcv.foreground = mw->menu.button_foreground; |
1566 |
xgcv.background = mw->core.background_pixel; |
xgcv.background = mw->core.background_pixel; |
1567 |
xgcv.fill_style = FillStippled; |
xgcv.fill_style = FillStippled; |
1568 |
xgcv.stipple = mw->menu.gray_pixmap; |
xgcv.stipple = mw->menu.gray_pixmap; |
1569 |
mw->menu.inactive_button_gc = XtGetGC ((Widget)mw, |
mw->menu.inactive_button_gc = XtGetGC ((Widget)mw, |
1570 |
(GCFont | GCForeground | GCBackground |
#ifndef HAVE_X_I18N |
1571 |
| GCFillStyle | GCStipple), &xgcv); |
GCFont | |
1572 |
|
#endif |
1573 |
|
GCForeground | GCBackground |
1574 |
|
| GCFillStyle | GCStipple, &xgcv); |
1575 |
|
|
1576 |
|
#ifndef HAVE_X_I18N |
1577 |
xgcv.font = mw->menu.font->fid; |
xgcv.font = mw->menu.font->fid; |
1578 |
|
#endif |
1579 |
xgcv.foreground = mw->core.background_pixel; |
xgcv.foreground = mw->core.background_pixel; |
1580 |
xgcv.background = mw->menu.foreground; |
xgcv.background = mw->menu.foreground; |
1581 |
mw->menu.background_gc = XtGetGC ((Widget)mw, |
mw->menu.background_gc = XtGetGC ((Widget)mw, |
1582 |
GCFont | GCForeground | GCBackground, |
#ifndef HAVE_X_I18N |
1583 |
|
GCFont | |
1584 |
|
#endif |
1585 |
|
GCForeground | GCBackground, |
1586 |
&xgcv); |
&xgcv); |
1587 |
} |
} |
1588 |
|
|
1789 |
gray_bitmap_width, gray_bitmap_height, |
gray_bitmap_width, gray_bitmap_height, |
1790 |
(unsigned long)1, (unsigned long)0, 1); |
(unsigned long)1, (unsigned long)0, 1); |
1791 |
|
|
1792 |
|
#ifndef HAVE_X_I18N |
1793 |
/* I don't understand why this ends up 0 sometimes, |
/* I don't understand why this ends up 0 sometimes, |
1794 |
but it does. This kludge works around it. |
but it does. This kludge works around it. |
1795 |
Can anyone find a real fix? -- rms. */ |
Can anyone find a real fix? -- rms. */ |
1796 |
if (mw->menu.font == 0) |
if (mw->menu.font == 0) |
1797 |
mw->menu.font = xlwmenu_default_font; |
mw->menu.font = xlwmenu_default_font; |
1798 |
|
#else |
1799 |
|
mw->menu.font_extents = XExtentsOfFontSet (mw->menu.font); |
1800 |
|
#endif |
1801 |
|
|
1802 |
make_drawing_gcs (mw); |
make_drawing_gcs (mw); |
1803 |
make_shadow_gcs (mw); |
make_shadow_gcs (mw); |
1804 |
|
|
1965 |
|
|
1966 |
if (newmw->core.background_pixel != oldmw->core.background_pixel |
if (newmw->core.background_pixel != oldmw->core.background_pixel |
1967 |
|| newmw->menu.foreground != oldmw->menu.foreground |
|| newmw->menu.foreground != oldmw->menu.foreground |
1968 |
|| newmw->menu.font != oldmw->menu.font) |
#ifndef HAVE_X_I18N |
1969 |
|
|| newmw->menu.font != oldmw->menu.font |
1970 |
|
#endif |
1971 |
|
) |
1972 |
{ |
{ |
1973 |
release_drawing_gcs (newmw); |
release_drawing_gcs (newmw); |
1974 |
make_drawing_gcs (newmw); |
make_drawing_gcs (newmw); |
1994 |
} |
} |
1995 |
} |
} |
1996 |
|
|
1997 |
|
#ifdef HAVE_X_I18N |
1998 |
|
if (newmw->menu.font != oldmw->menu.font) |
1999 |
|
{ |
2000 |
|
redisplay = True; |
2001 |
|
newmw->menu.font_extents = XExtentsOfFontSet (newmw->menu.font); |
2002 |
|
} |
2003 |
|
#endif |
2004 |
|
|
2005 |
return redisplay; |
return redisplay; |
2006 |
} |
} |
2007 |
|
|