comparison lwlib/xlwmenu.c @ 90127:30ad2795fdab

Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-28 Merge from emacs--cvs-trunk--0 Patches applied: * emacs--cvs-trunk--0 (patch 180-191) - Update from CVS - Merge from gnus--rel--5.10 * gnus--rel--5.10 (patch 39-44) - Merge from emacs--cvs-trunk--0 - Update from CVS
author Miles Bader <miles@gnu.org>
date Sat, 19 Mar 2005 02:42:17 +0000
parents 95879cc1ed20 2610d09357c8
children 13796b0653c7
comparison
equal deleted inserted replaced
90126:8ee106ee2dc8 90127:30ad2795fdab
1 /* Implements a lightweight menubar widget. 1 /* Implements a lightweight menubar widget.
2 Copyright (C) 1992 Lucid, Inc. 2 Copyright (C) 1992 Lucid, Inc.
3 Copyright (C) 2002 Free Software Foundation, Inc. 3 Copyright (C) 2002, 2005 Free Software Foundation, Inc.
4 4
5 This file is part of the Lucid Widget Library. 5 This file is part of the Lucid Widget Library.
6 6
7 The Lucid Widget Library is free software; you can redistribute it and/or 7 The Lucid Widget Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as published by 8 modify it under the terms of the GNU General Public License as published by
133 133
134 #define offset(field) XtOffset(XlwMenuWidget, field) 134 #define offset(field) XtOffset(XlwMenuWidget, field)
135 static XtResource 135 static XtResource
136 xlwMenuResources[] = 136 xlwMenuResources[] =
137 { 137 {
138 #ifdef HAVE_X_I18N
139 {XtNfont, XtCFont, XtRFontSet, sizeof(XFontSet),
140 offset(menu.font), XtRString, "XtDefaultFontSet"},
141 #else
138 {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), 142 {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
139 offset(menu.font),XtRString, "XtDefaultFont"}, 143 offset(menu.font), XtRString, "XtDefaultFont"},
144 #endif
140 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), 145 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
141 offset(menu.foreground), XtRString, "XtDefaultForeground"}, 146 offset(menu.foreground), XtRString, "XtDefaultForeground"},
142 {XtNdisabledForeground, XtCDisabledForeground, XtRPixel, sizeof(Pixel), 147 {XtNdisabledForeground, XtCDisabledForeground, XtRPixel, sizeof(Pixel),
143 offset(menu.disabled_foreground), XtRString, (XtPointer)NULL}, 148 offset(menu.disabled_foreground), XtRString, (XtPointer)NULL},
144 {XtNbuttonForeground, XtCButtonForeground, XtRPixel, sizeof(Pixel), 149 {XtNbuttonForeground, XtCButtonForeground, XtRPixel, sizeof(Pixel),
233 XtNumber(xlwMenuActionsList), /* num_actions */ 238 XtNumber(xlwMenuActionsList), /* num_actions */
234 xlwMenuResources, /* resources */ 239 xlwMenuResources, /* resources */
235 XtNumber(xlwMenuResources), /* resource_count */ 240 XtNumber(xlwMenuResources), /* resource_count */
236 NULLQUARK, /* xrm_class */ 241 NULLQUARK, /* xrm_class */
237 TRUE, /* compress_motion */ 242 TRUE, /* compress_motion */
238 TRUE, /* compress_exposure */ 243 XtExposeCompressMaximal, /* compress_exposure */
239 TRUE, /* compress_enterleave */ 244 TRUE, /* compress_enterleave */
240 FALSE, /* visible_interest */ 245 FALSE, /* visible_interest */
241 XlwMenuDestroy, /* destroy */ 246 XlwMenuDestroy, /* destroy */
242 XlwMenuResize, /* resize */ 247 XlwMenuResize, /* resize */
243 XlwMenuRedisplay, /* expose */ 248 XlwMenuRedisplay, /* expose */
351 int 356 int
352 string_width (mw, s) 357 string_width (mw, s)
353 XlwMenuWidget mw; 358 XlwMenuWidget mw;
354 char *s; 359 char *s;
355 { 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
356 XCharStruct xcs; 366 XCharStruct xcs;
357 int drop; 367 int drop;
358 368
359 XTextExtents (mw->menu.font, s, strlen (s), &drop, &drop, &drop, &xcs); 369 XTextExtents (mw->menu.font, s, strlen (s), &drop, &drop, &drop, &xcs);
360 return xcs.width; 370 return xcs.width;
361 } 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) \
378 (- (mw)->menu.font_extents->max_logical_extent.y)
379 #else
380 #define MENU_FONT_HEIGHT(mw) \
381 ((mw)->menu.font->ascent + (mw)->menu.font->descent)
382 #define MENU_FONT_ASCENT(mw) ((mw)->menu.font->ascent)
383 #endif
362 384
363 static int 385 static int
364 arrow_width (mw) 386 arrow_width (mw)
365 XlwMenuWidget mw; 387 XlwMenuWidget mw;
366 { 388 {
367 return (mw->menu.font->ascent * 3/4) | 1; 389 return (MENU_FONT_ASCENT (mw) * 3/4) | 1;
368 } 390 }
369 391
370 /* Return the width of toggle buttons of widget MW. */ 392 /* Return the width of toggle buttons of widget MW. */
371 393
372 static int 394 static int
373 toggle_button_width (mw) 395 toggle_button_width (mw)
374 XlwMenuWidget mw; 396 XlwMenuWidget mw;
375 { 397 {
376 return ((mw->menu.font->ascent + mw->menu.font->descent) * 2 / 3) | 1; 398 return (MENU_FONT_HEIGHT (mw) * 2 / 3) | 1;
377 } 399 }
378 400
379 401
380 /* Return the width of radio buttons of widget MW. */ 402 /* Return the width of radio buttons of widget MW. */
381 403
452 *rest_width = 0; 474 *rest_width = 0;
453 *button_width = 0; 475 *button_width = 0;
454 } 476 }
455 else 477 else
456 { 478 {
457 *height = 479 *height = MENU_FONT_HEIGHT (mw)
458 mw->menu.font->ascent + mw->menu.font->descent 480 + 2 * mw->menu.vertical_spacing + 2 * mw->menu.shadow_thickness;
459 + 2 * mw->menu.vertical_spacing + 2 * mw->menu.shadow_thickness;
460 481
461 *label_width = 482 *label_width =
462 string_width (mw, resource_widget_value (mw, val)) 483 string_width (mw, resource_widget_value (mw, val))
463 + mw->menu.horizontal_spacing + mw->menu.shadow_thickness; 484 + mw->menu.horizontal_spacing + mw->menu.shadow_thickness;
464 485
569 /* alpha = atan (0.5) 590 /* alpha = atan (0.5)
570 factor = (1 + sin (alpha)) / cos (alpha) */ 591 factor = (1 + sin (alpha)) / cos (alpha) */
571 double factor = 1.62; 592 double factor = 1.62;
572 int thickness2 = thickness * factor; 593 int thickness2 = thickness * factor;
573 594
574 y += (mw->menu.font->ascent + mw->menu.font->descent - height) / 2; 595 y += (MENU_FONT_HEIGHT (mw) - height) / 2;
575 596
576 if (down_p) 597 if (down_p)
577 { 598 {
578 GC temp; 599 GC temp;
579 temp = top_gc; 600 temp = top_gc;
755 int width, height; 776 int width, height;
756 777
757 width = toggle_button_width (mw); 778 width = toggle_button_width (mw);
758 height = width; 779 height = width;
759 x += mw->menu.horizontal_spacing; 780 x += mw->menu.horizontal_spacing;
760 y += (mw->menu.font->ascent - height) / 2; 781 y += (MENU_FONT_ASCENT (mw) - height) / 2;
761 draw_shadow_rectangle (mw, window, x, y, width, height, False, selected_p); 782 draw_shadow_rectangle (mw, window, x, y, width, height, False, selected_p);
762 } 783 }
763 784
764 785
765 /* Draw a radio button on widget MW, X window WINDOW. X/Y is the 786 /* Draw a radio button on widget MW, X window WINDOW. X/Y is the
775 int width, height; 796 int width, height;
776 797
777 width = radio_button_width (mw); 798 width = radio_button_width (mw);
778 height = width; 799 height = width;
779 x += mw->menu.horizontal_spacing; 800 x += mw->menu.horizontal_spacing;
780 y += (mw->menu.font->ascent - height) / 2; 801 y += (MENU_FONT_ASCENT (mw) - height) / 2;
781 draw_shadow_rhombus (mw, window, x, y, width, height, False, selected_p); 802 draw_shadow_rhombus (mw, window, x, y, width, height, False, selected_p);
782 } 803 }
783 804
784 805
785 /* Draw a menu separator on widget MW, X window WINDOW. X/Y is the 806 /* Draw a menu separator on widget MW, X window WINDOW. X/Y is the
952 Boolean horizontal_p; 973 Boolean horizontal_p;
953 Boolean just_compute_p; 974 Boolean just_compute_p;
954 { 975 {
955 GC deco_gc; 976 GC deco_gc;
956 GC text_gc; 977 GC text_gc;
957 int font_ascent = mw->menu.font->ascent; 978 int font_height = MENU_FONT_HEIGHT (mw);
958 int font_descent = mw->menu.font->descent; 979 int font_ascent = MENU_FONT_ASCENT (mw);
959 int shadow = mw->menu.shadow_thickness; 980 int shadow = mw->menu.shadow_thickness;
960 int margin = mw->menu.margin; 981 int margin = mw->menu.margin;
961 int h_spacing = mw->menu.horizontal_spacing; 982 int h_spacing = mw->menu.horizontal_spacing;
962 int v_spacing = mw->menu.vertical_spacing; 983 int v_spacing = mw->menu.vertical_spacing;
963 int label_width; 984 int label_width;
1026 } 1047 }
1027 else if (!horizontal_p && ws->button_width) 1048 else if (!horizontal_p && ws->button_width)
1028 x_offset += ws->button_width; 1049 x_offset += ws->button_width;
1029 1050
1030 1051
1031 XDrawString (XtDisplay (mw), ws->window, text_gc, x_offset, 1052 #ifdef HAVE_X_I18N
1053 XmbDrawString (XtDisplay (mw), ws->window, mw->menu.font,
1054 #else
1055 XDrawString (XtDisplay (mw), ws->window,
1056 #endif
1057 text_gc, x_offset,
1032 y + v_spacing + shadow + font_ascent, 1058 y + v_spacing + shadow + font_ascent,
1033 display_string, strlen (display_string)); 1059 display_string, strlen (display_string));
1034 1060
1035 if (!horizontal_p) 1061 if (!horizontal_p)
1036 { 1062 {
1051 y + v_spacing + shadow, a_w, 1077 y + v_spacing + shadow, a_w,
1052 highlighted_p); 1078 highlighted_p);
1053 } 1079 }
1054 else if (val->key) 1080 else if (val->key)
1055 { 1081 {
1056 XDrawString (XtDisplay (mw), ws->window, text_gc, 1082 #ifdef HAVE_X_I18N
1083 XmbDrawString (XtDisplay (mw), ws->window, mw->menu.font,
1084 #else
1085 XDrawString (XtDisplay (mw), ws->window,
1086 #endif
1087 text_gc,
1057 x + label_width + mw->menu.arrow_spacing, 1088 x + label_width + mw->menu.arrow_spacing,
1058 y + v_spacing + shadow + font_ascent, 1089 y + v_spacing + shadow + font_ascent,
1059 val->key, strlen (val->key)); 1090 val->key, strlen (val->key));
1060 } 1091 }
1061 } 1092 }
1063 { 1094 {
1064 XDrawRectangle (XtDisplay (mw), ws->window, 1095 XDrawRectangle (XtDisplay (mw), ws->window,
1065 mw->menu.background_gc, 1096 mw->menu.background_gc,
1066 x + shadow, y + shadow, 1097 x + shadow, y + shadow,
1067 label_width + h_spacing - 1, 1098 label_width + h_spacing - 1,
1068 font_ascent + font_descent + 2 * v_spacing - 1); 1099 font_height + 2 * v_spacing - 1);
1069 draw_shadow_rectangle (mw, ws->window, x, y, width, height, 1100 draw_shadow_rectangle (mw, ws->window, x, y, width, height,
1070 True, False); 1101 True, False);
1071 } 1102 }
1072 1103
1073 if (highlighted_p) 1104 if (highlighted_p)
1458 XlwMenuWidget mw; 1489 XlwMenuWidget mw;
1459 { 1490 {
1460 XGCValues xgcv; 1491 XGCValues xgcv;
1461 float scale; 1492 float scale;
1462 1493
1494 #ifndef HAVE_X_I18N
1463 xgcv.font = mw->menu.font->fid; 1495 xgcv.font = mw->menu.font->fid;
1496 #endif
1464 xgcv.foreground = mw->menu.foreground; 1497 xgcv.foreground = mw->menu.foreground;
1465 xgcv.background = mw->core.background_pixel; 1498 xgcv.background = mw->core.background_pixel;
1466 mw->menu.foreground_gc = XtGetGC ((Widget)mw, 1499 mw->menu.foreground_gc = XtGetGC ((Widget)mw,
1467 GCFont | GCForeground | GCBackground, 1500 #ifndef HAVE_X_I18N
1501 GCFont |
1502 #endif
1503 GCForeground | GCBackground,
1468 &xgcv); 1504 &xgcv);
1469 1505
1506 #ifndef HAVE_X_I18N
1470 xgcv.font = mw->menu.font->fid; 1507 xgcv.font = mw->menu.font->fid;
1508 #endif
1471 xgcv.foreground = mw->menu.button_foreground; 1509 xgcv.foreground = mw->menu.button_foreground;
1472 xgcv.background = mw->core.background_pixel; 1510 xgcv.background = mw->core.background_pixel;
1473 mw->menu.button_gc = XtGetGC ((Widget)mw, 1511 mw->menu.button_gc = XtGetGC ((Widget)mw,
1474 GCFont | GCForeground | GCBackground, 1512 #ifndef HAVE_X_I18N
1513 GCFont |
1514 #endif
1515 GCForeground | GCBackground,
1475 &xgcv); 1516 &xgcv);
1476 1517
1518 #ifndef HAVE_X_I18N
1477 xgcv.font = mw->menu.font->fid; 1519 xgcv.font = mw->menu.font->fid;
1520 #endif
1478 xgcv.background = mw->core.background_pixel; 1521 xgcv.background = mw->core.background_pixel;
1479 1522
1480 #define BRIGHTNESS(color) (((color) & 0xff) + (((color) >> 8) & 0xff) + (((color) >> 16) & 0xff)) 1523 #define BRIGHTNESS(color) (((color) & 0xff) + (((color) >> 8) & 0xff) + (((color) >> 16) & 0xff))
1481 1524
1482 /* Allocate color for disabled menu-items. */ 1525 /* Allocate color for disabled menu-items. */
1498 /* Too few colors, use stipple. */ 1541 /* Too few colors, use stipple. */
1499 xgcv.foreground = mw->menu.foreground; 1542 xgcv.foreground = mw->menu.foreground;
1500 xgcv.fill_style = FillStippled; 1543 xgcv.fill_style = FillStippled;
1501 xgcv.stipple = mw->menu.gray_pixmap; 1544 xgcv.stipple = mw->menu.gray_pixmap;
1502 mw->menu.disabled_gc = XtGetGC ((Widget)mw, 1545 mw->menu.disabled_gc = XtGetGC ((Widget)mw,
1503 (GCFont | GCForeground | GCBackground 1546 #ifndef HAVE_X_I18N
1504 | GCFillStyle | GCStipple), &xgcv); 1547 GCFont |
1548 #endif
1549 GCForeground | GCBackground
1550 | GCFillStyle | GCStipple, &xgcv);
1505 } 1551 }
1506 else 1552 else
1507 { 1553 {
1508 /* Many colors available, use disabled pixel. */ 1554 /* Many colors available, use disabled pixel. */
1509 xgcv.foreground = mw->menu.disabled_foreground; 1555 xgcv.foreground = mw->menu.disabled_foreground;
1510 mw->menu.disabled_gc = XtGetGC ((Widget)mw, 1556 mw->menu.disabled_gc = XtGetGC ((Widget)mw,
1511 (GCFont | GCForeground | GCBackground), &xgcv); 1557 #ifndef HAVE_X_I18N
1512 } 1558 GCFont |
1513 1559 #endif
1560 GCForeground | GCBackground, &xgcv);
1561 }
1562
1563 #ifndef HAVE_X_I18N
1514 xgcv.font = mw->menu.font->fid; 1564 xgcv.font = mw->menu.font->fid;
1565 #endif
1515 xgcv.foreground = mw->menu.button_foreground; 1566 xgcv.foreground = mw->menu.button_foreground;
1516 xgcv.background = mw->core.background_pixel; 1567 xgcv.background = mw->core.background_pixel;
1517 xgcv.fill_style = FillStippled; 1568 xgcv.fill_style = FillStippled;
1518 xgcv.stipple = mw->menu.gray_pixmap; 1569 xgcv.stipple = mw->menu.gray_pixmap;
1519 mw->menu.inactive_button_gc = XtGetGC ((Widget)mw, 1570 mw->menu.inactive_button_gc = XtGetGC ((Widget)mw,
1520 (GCFont | GCForeground | GCBackground 1571 #ifndef HAVE_X_I18N
1521 | GCFillStyle | GCStipple), &xgcv); 1572 GCFont |
1522 1573 #endif
1574 GCForeground | GCBackground
1575 | GCFillStyle | GCStipple, &xgcv);
1576
1577 #ifndef HAVE_X_I18N
1523 xgcv.font = mw->menu.font->fid; 1578 xgcv.font = mw->menu.font->fid;
1579 #endif
1524 xgcv.foreground = mw->core.background_pixel; 1580 xgcv.foreground = mw->core.background_pixel;
1525 xgcv.background = mw->menu.foreground; 1581 xgcv.background = mw->menu.foreground;
1526 mw->menu.background_gc = XtGetGC ((Widget)mw, 1582 mw->menu.background_gc = XtGetGC ((Widget)mw,
1527 GCFont | GCForeground | GCBackground, 1583 #ifndef HAVE_X_I18N
1584 GCFont |
1585 #endif
1586 GCForeground | GCBackground,
1528 &xgcv); 1587 &xgcv);
1529 } 1588 }
1530 1589
1531 static void 1590 static void
1532 release_drawing_gcs (mw) 1591 release_drawing_gcs (mw)
1729 mw->menu.gray_pixmap 1788 mw->menu.gray_pixmap
1730 = XCreatePixmapFromBitmapData (display, window, gray_bitmap_bits, 1789 = XCreatePixmapFromBitmapData (display, window, gray_bitmap_bits,
1731 gray_bitmap_width, gray_bitmap_height, 1790 gray_bitmap_width, gray_bitmap_height,
1732 (unsigned long)1, (unsigned long)0, 1); 1791 (unsigned long)1, (unsigned long)0, 1);
1733 1792
1793 #ifndef HAVE_X_I18N
1734 /* I don't understand why this ends up 0 sometimes, 1794 /* I don't understand why this ends up 0 sometimes,
1735 but it does. This kludge works around it. 1795 but it does. This kludge works around it.
1736 Can anyone find a real fix? -- rms. */ 1796 Can anyone find a real fix? -- rms. */
1737 if (mw->menu.font == 0) 1797 if (mw->menu.font == 0)
1738 mw->menu.font = xlwmenu_default_font; 1798 mw->menu.font = xlwmenu_default_font;
1739 1799 #else
1800 mw->menu.font_extents = XExtentsOfFontSet (mw->menu.font);
1801 #endif
1802
1740 make_drawing_gcs (mw); 1803 make_drawing_gcs (mw);
1741 make_shadow_gcs (mw); 1804 make_shadow_gcs (mw);
1742 1805
1743 mw->menu.popped_up = False; 1806 mw->menu.popped_up = False;
1744 1807
1901 && newmw->menu.contents->change >= VISIBLE_CHANGE) 1964 && newmw->menu.contents->change >= VISIBLE_CHANGE)
1902 redisplay = True; 1965 redisplay = True;
1903 1966
1904 if (newmw->core.background_pixel != oldmw->core.background_pixel 1967 if (newmw->core.background_pixel != oldmw->core.background_pixel
1905 || newmw->menu.foreground != oldmw->menu.foreground 1968 || newmw->menu.foreground != oldmw->menu.foreground
1906 || newmw->menu.font != oldmw->menu.font) 1969 #ifndef HAVE_X_I18N
1970 || newmw->menu.font != oldmw->menu.font
1971 #endif
1972 )
1907 { 1973 {
1908 release_drawing_gcs (newmw); 1974 release_drawing_gcs (newmw);
1909 make_drawing_gcs (newmw); 1975 make_drawing_gcs (newmw);
1910 1976
1911 release_shadow_gcs (newmw); 1977 release_shadow_gcs (newmw);
1926 /* clear windows and generate expose events */ 1992 /* clear windows and generate expose events */
1927 XClearArea (XtDisplay (oldmw), oldmw->menu.windows[i].window, 1993 XClearArea (XtDisplay (oldmw), oldmw->menu.windows[i].window,
1928 0, 0, 0, 0, True); 1994 0, 0, 0, 0, True);
1929 } 1995 }
1930 } 1996 }
1997
1998 #ifdef HAVE_X_I18N
1999 if (newmw->menu.font != oldmw->menu.font)
2000 {
2001 redisplay = True;
2002 newmw->menu.font_extents = XExtentsOfFontSet (newmw->menu.font);
2003 }
2004 #endif
1931 2005
1932 return redisplay; 2006 return redisplay;
1933 } 2007 }
1934 2008
1935 static void 2009 static void