Mercurial > emacs
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 |