comparison lwlib/xlwmenu.c @ 183:e121b013d1f0 r20-3b18

Import from CVS: tag r20-3b18
author cvs
date Mon, 13 Aug 2007 09:54:23 +0200
parents bfd6434d15b3
children 3d6bfa290dbd
comparison
equal deleted inserted replaced
182:f07455f06202 183:e121b013d1f0
1 /* Implements a lightweight menubar widget. 1 /* Implements a lightweight menubar widget.
2 Copyright (C) 1992, 1993, 1994 Lucid, Inc. 2 Copyright (C) 1992, 1993, 1994 Lucid, Inc.
3 Copyright (C) 1995 Tinker Systems and INS Engineering Corp. 3 Copyright (C) 1995 Tinker Systems and INS Engineering Corp.
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
9 the Free Software Foundation; either version 2, or (at your option) 9 the Free Software Foundation; either version 2, or (at your option)
10 any later version. 10 any later version.
11 11
12 The Lucid Widget Library is distributed in the hope that it will be useful, 12 The Lucid Widget Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to 18 along with XEmacs; see the file COPYING. If not, write to
54 /* simple, naieve integer maximum */ 54 /* simple, naieve integer maximum */
55 #ifndef max 55 #ifndef max
56 #define max(a,b) ((a)>(b)?(a):(b)) 56 #define max(a,b) ((a)>(b)?(a):(b))
57 #endif 57 #endif
58 58
59 static char 59 static char
60 xlwMenuTranslations [] = 60 xlwMenuTranslations [] =
61 "<BtnDown>: start()\n\ 61 "<BtnDown>: start()\n\
62 <BtnMotion>: drag()\n\ 62 <BtnMotion>: drag()\n\
63 <BtnUp>: select()\n\ 63 <BtnUp>: select()\n\
64 "; 64 ";
65 65
66 extern Widget lw_menubar_widget; 66 extern Widget lw_menubar_widget;
67 67
68 #define offset(field) XtOffset(XlwMenuWidget, field) 68 #define offset(field) XtOffset(XlwMenuWidget, field)
69 static XtResource 69 static XtResource
70 xlwMenuResources[] = 70 xlwMenuResources[] =
71 { 71 {
72 #ifdef NEED_MOTIF 72 #ifdef NEED_MOTIF
73 /* There are three font list resources, so that we can accept either of 73 /* 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 74 the resources *fontList: or *font:, and so that we can tell the
75 difference between them being specified, and being defaulted to a 75 difference between them being specified, and being defaulted to a
76 font from the XtRString specified here. */ 76 font from the XtRString specified here. */
118 {XmNtopShadowPixmap, XmCTopShadowPixmap, XtRPixmap, sizeof (Pixmap), 118 {XmNtopShadowPixmap, XmCTopShadowPixmap, XtRPixmap, sizeof (Pixmap),
119 offset (menu.top_shadow_pixmap), XtRImmediate, (XtPointer)None}, 119 offset (menu.top_shadow_pixmap), XtRImmediate, (XtPointer)None},
120 {XmNbottomShadowPixmap, XmCBottomShadowPixmap, XtRPixmap, sizeof (Pixmap), 120 {XmNbottomShadowPixmap, XmCBottomShadowPixmap, XtRPixmap, sizeof (Pixmap),
121 offset (menu.bottom_shadow_pixmap), XtRImmediate, (XtPointer)None}, 121 offset (menu.bottom_shadow_pixmap), XtRImmediate, (XtPointer)None},
122 122
123 {XtNopen, XtCCallback, XtRCallback, sizeof(XtPointer), 123 {XtNopen, XtCCallback, XtRCallback, sizeof(XtPointer),
124 offset(menu.open), XtRCallback, (XtPointer)NULL}, 124 offset(menu.open), XtRCallback, (XtPointer)NULL},
125 {XtNselect, XtCCallback, XtRCallback, sizeof(XtPointer), 125 {XtNselect, XtCCallback, XtRCallback, sizeof(XtPointer),
126 offset(menu.select), XtRCallback, (XtPointer)NULL}, 126 offset(menu.select), XtRCallback, (XtPointer)NULL},
127 {XtNmenu, XtCMenu, XtRPointer, sizeof(XtPointer), 127 {XtNmenu, XtCMenu, XtRPointer, sizeof(XtPointer),
128 offset(menu.contents), XtRImmediate, (XtPointer)NULL}, 128 offset(menu.contents), XtRImmediate, (XtPointer)NULL},
129 {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor), 129 {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
130 offset(menu.cursor_shape), XtRString, (XtPointer) "right_ptr"}, 130 offset(menu.cursor_shape), XtRString, (XtPointer) "right_ptr"},
155 155
156 #ifdef NEED_MOTIF 156 #ifdef NEED_MOTIF
157 static XFontStruct *default_font_of_font_list (XmFontList); 157 static XFontStruct *default_font_of_font_list (XmFontList);
158 #endif 158 #endif
159 159
160 static XtActionsRec 160 static XtActionsRec
161 xlwMenuActionsList [] = 161 xlwMenuActionsList [] =
162 { 162 {
163 {"start", Start}, 163 {"start", Start},
164 {"drag", Drag}, 164 {"drag", Drag},
165 {"select", Select}, 165 {"select", Select},
168 #define SuperClass ((CoreWidgetClass)&coreClassRec) 168 #define SuperClass ((CoreWidgetClass)&coreClassRec)
169 169
170 XlwMenuClassRec xlwMenuClassRec = 170 XlwMenuClassRec xlwMenuClassRec =
171 { 171 {
172 { /* CoreClass fields initialization */ 172 { /* CoreClass fields initialization */
173 (WidgetClass) SuperClass, /* superclass */ 173 (WidgetClass) SuperClass, /* superclass */
174 "XlwMenu", /* class_name */ 174 "XlwMenu", /* class_name */
175 sizeof(XlwMenuRec), /* size */ 175 sizeof(XlwMenuRec), /* size */
176 XlwMenuClassInitialize, /* class_initialize */ 176 XlwMenuClassInitialize, /* class_initialize */
177 NULL, /* class_part_initialize */ 177 NULL, /* class_part_initialize */
178 FALSE, /* class_inited */ 178 FALSE, /* class_inited */
321 } 321 }
322 else if (mw->menu.old_stack_length < n) 322 else if (mw->menu.old_stack_length < n)
323 { 323 {
324 while (mw->menu.old_stack_length < n) 324 while (mw->menu.old_stack_length < n)
325 mw->menu.old_stack_length *= 2; 325 mw->menu.old_stack_length *= 2;
326 326
327 mw->menu.old_stack = 327 mw->menu.old_stack =
328 (widget_value**)XtRealloc ((char *)mw->menu.old_stack, 328 (widget_value**)XtRealloc ((char *)mw->menu.old_stack,
329 mw->menu.old_stack_length * 329 mw->menu.old_stack_length *
330 sizeof (widget_value*)); 330 sizeof (widget_value*));
331 } 331 }
459 if (!*(in-1)) /* Overshot the NULL byte? */ 459 if (!*(in-1)) /* Overshot the NULL byte? */
460 break; 460 break;
461 } 461 }
462 } 462 }
463 *out = 0; 463 *out = 0;
464 464
465 #ifdef PRINT_XLWMENU_RESOURCE_CONVERSIONS 465 #ifdef PRINT_XLWMENU_RESOURCE_CONVERSIONS
466 printf("! Emacs*XlwMenu.%s.labelString:\t%s\n", save_out, save_in); 466 printf("! Emacs*XlwMenu.%s.labelString:\t%s\n", save_out, save_in);
467 printf( "Emacs*XlwMenu.%s.labelString:\n", save_out); 467 printf( "Emacs*XlwMenu.%s.labelString:\n", save_out);
468 #endif 468 #endif
469 } 469 }
470 470
471 static XtResource 471 static XtResource
472 nameResource[] = 472 nameResource[] =
473 { 473 {
474 { "labelString", "LabelString", XtRString, sizeof(String), 474 { "labelString", "LabelString", XtRString, sizeof(String),
475 0, XtRImmediate, 0 } 475 0, XtRImmediate, 0 }
476 }; 476 };
477 477
478 /* 478 /*
507 value = ""; 507 value = "";
508 508
509 for (ntimes = 1, result = (char *) string; (percent = strchr(result, '%')); 509 for (ntimes = 1, result = (char *) string; (percent = strchr(result, '%'));
510 ntimes++) 510 ntimes++)
511 result = &percent[1]; 511 result = &percent[1];
512 512
513 result = XtMalloc ((ntimes * strlen(value)) + strlen(string) + 4); 513 result = XtMalloc ((ntimes * strlen(value)) + strlen(string) + 4);
514 result[0] = '\0'; 514 result[0] = '\0';
515 515
516 while ((percent = strchr(string, '%'))) 516 while ((percent = strchr(string, '%')))
517 { 517 {
518 unsigned left_pad; 518 unsigned left_pad;
519 unsigned right_pad; 519 unsigned right_pad;
520 char *p; 520 char *p;
521 521
522 if (percent[1] == '%') 522 if (percent[1] == '%')
523 { /* it's a real % */ 523 { /* it's a real % */
524 strncat(result, string, 1 + percent - string); /* incl % */ 524 strncat(result, string, 1 + percent - string); /* incl % */
525 string = &percent[2]; /* after the second '%' */ 525 string = &percent[2]; /* after the second '%' */
526 continue; /* with the while() loop */ 526 continue; /* with the while() loop */
527 } 527 }
528 528
529 left_pad = 0; 529 left_pad = 0;
530 right_pad = 0; 530 right_pad = 0;
531 531
532 for (p = &percent[1]; /* test *p inside the loop */ ; p++) 532 for (p = &percent[1]; /* test *p inside the loop */ ; p++)
533 { 533 {
558 else 558 else
559 { /* bogus, copy the format as is */ 559 { /* bogus, copy the format as is */
560 /* out of for() loop */ 560 /* out of for() loop */
561 strncat(result, string, 1 + p - string); 561 strncat(result, string, 1 + p - string);
562 string= (*p ? &p[1] : p); 562 string= (*p ? &p[1] : p);
563 break; 563 break;
564 } 564 }
565 } 565 }
566 } 566 }
567 567
568 /* 568 /*
597 if (mw->menu.lookup_labels) 597 if (mw->menu.lookup_labels)
598 { 598 {
599 /* Convert value style name into resource style name. 599 /* Convert value style name into resource style name.
600 eg: "Free Willy" becomes "freeWilly" */ 600 eg: "Free Willy" becomes "freeWilly" */
601 massage_resource_name (val->name, massaged_name); 601 massage_resource_name (val->name, massaged_name);
602 602
603 /* If we have a value (parameter) see if we can find a "Named" 603 /* If we have a value (parameter) see if we can find a "Named"
604 resource. */ 604 resource. */
605 if (val->value) 605 if (val->value)
606 { 606 {
607 char named_name[1024]; 607 char named_name[1024];
705 char massaged_name [1024]; 705 char massaged_name [1024];
706 706
707 if (mw->menu.lookup_labels) 707 if (mw->menu.lookup_labels)
708 { 708 {
709 massage_resource_name (val->name, massaged_name); 709 massage_resource_name (val->name, massaged_name);
710 710
711 XtGetSubresources ((Widget) mw, 711 XtGetSubresources ((Widget) mw,
712 (XtPointer) &resourced_name, 712 (XtPointer) &resourced_name,
713 massaged_name, massaged_name, 713 massaged_name, massaged_name,
714 nameResource, 1, NULL, 0); 714 nameResource, 1, NULL, 0);
715 } 715 }
802 x, y + mw->menu.font_ascent, &string[s], i-s); 802 x, y + mw->menu.font_ascent, &string[s], i-s);
803 # else 803 # else
804 XDrawString (XtDisplay (mw), window, gc, 804 XDrawString (XtDisplay (mw), window, gc,
805 x, y + mw->menu.font_ascent, &string[s], i-s); 805 x, y + mw->menu.font_ascent, &string[s], i-s);
806 # endif /* USE_XFONTSET */ 806 # endif /* USE_XFONTSET */
807 807
808 XTextExtents (mw->menu.font, &string[s], i-s, &drop, &drop, &drop, 808 XTextExtents (mw->menu.font, &string[s], i-s, &drop, &drop, &drop,
809 &xcs); 809 &xcs);
810 x += xcs.width; 810 x += xcs.width;
811 811
812 s=i+3; 812 s=i+3;
813 i+=2; 813 i+=2;
814 814
815 # ifdef USE_XFONTSET 815 # ifdef USE_XFONTSET
816 XmbDrawString (XtDisplay (mw), window, mw->menu.font_set, gc, 816 XmbDrawString (XtDisplay (mw), window, mw->menu.font_set, gc,
817 x, y + mw->menu.font_ascent, &string[i], 1); 817 x, y + mw->menu.font_ascent, &string[i], 1);
818 # else 818 # else
819 XDrawString (XtDisplay (mw), window, gc, 819 XDrawString (XtDisplay (mw), window, gc,
820 x, y + mw->menu.font_ascent, &string[i], 1); 820 x, y + mw->menu.font_ascent, &string[i], 1);
821 # endif /* USE_XFONTSET */ 821 # endif /* USE_XFONTSET */
822 822
823 XTextExtents (mw->menu.font, &string[i], 1, &drop, &drop, &drop, 823 XTextExtents (mw->menu.font, &string[i], 1, &drop, &drop, &drop,
824 &xcs); 824 &xcs);
825 825
826 XDrawLine (XtDisplay (mw), window, gc, x - 1, 826 XDrawLine (XtDisplay (mw), window, gc, x - 1,
827 y + mw->menu.font_ascent + 1, 827 y + mw->menu.font_ascent + 1,
828 x + xcs.width - 1, y + mw->menu.font_ascent + 1 ); 828 x + xcs.width - 1, y + mw->menu.font_ascent + 1 );
829 829
830 x += xcs.width; 830 x += xcs.width;
831 } 831 }
832 } 832 }
833 if (string[s]) 833 if (string[s])
834 # ifdef USE_XFONTSET 834 # ifdef USE_XFONTSET
835 XmbDrawString (XtDisplay (mw), window, mw->menu.font_set, gc, 835 XmbDrawString (XtDisplay (mw), window, mw->menu.font_set, gc,
836 x, y + mw->menu.font_ascent, &string[s], 836 x, y + mw->menu.font_ascent, &string[s],
837 strlen (&string[s])); 837 strlen (&string[s]));
838 # else 838 # else
841 strlen (&string[s])); 841 strlen (&string[s]));
842 # endif /* USE_XFONTSET */ 842 # endif /* USE_XFONTSET */
843 #endif /* NEED_MOTIF */ 843 #endif /* NEED_MOTIF */
844 } 844 }
845 845
846 static void 846 static void
847 binding_draw (XlwMenuWidget mw, Window w, int x, int y, GC gc, char *value) 847 binding_draw (XlwMenuWidget mw, Window w, int x, int y, GC gc, char *value)
848 { 848 {
849 #ifdef NEED_MOTIF 849 #ifdef NEED_MOTIF
850 XmString xm_value = XmStringCreateLtoR(value, XmSTRING_DEFAULT_CHARSET); 850 XmString xm_value = XmStringCreateLtoR(value, XmSTRING_DEFAULT_CHARSET);
851 string_draw (mw, w, x, y, gc, xm_value); 851 string_draw (mw, w, x, y, gc, xm_value);
1000 width, height, 1000 width, height,
1001 thickness); 1001 thickness);
1002 } 1002 }
1003 } 1003 }
1004 1004
1005 static void 1005 static void
1006 arrow_decoration_draw (XlwMenuWidget mw, 1006 arrow_decoration_draw (XlwMenuWidget mw,
1007 Window window, 1007 Window window,
1008 int x, int y, 1008 int x, int y,
1009 unsigned width, 1009 unsigned width,
1010 Boolean raised) 1010 Boolean raised)
1021 1021
1022 if (width & 0x1) 1022 if (width & 0x1)
1023 half_width = width/2 + 1; 1023 half_width = width/2 + 1;
1024 else 1024 else
1025 half_width = width/2; 1025 half_width = width/2;
1026 1026
1027 select_gc = mw->menu.background_gc; 1027 select_gc = mw->menu.background_gc;
1028 1028
1029 if (raised) 1029 if (raised)
1030 { 1030 {
1031 top_gc = mw->menu.shadow_bottom_gc; 1031 top_gc = mw->menu.shadow_bottom_gc;
1032 bottom_gc = mw->menu.shadow_top_gc; 1032 bottom_gc = mw->menu.shadow_top_gc;
1033 } 1033 }
1047 points [1].y = y + half_width; 1047 points [1].y = y + half_width;
1048 points [2].x = x + length - thickness; 1048 points [2].x = x + length - thickness;
1049 points [2].y = y + half_width + thickness; 1049 points [2].y = y + half_width + thickness;
1050 points [3].x = x + thickness; 1050 points [3].x = x + thickness;
1051 points [3].y = y + width - thickness; 1051 points [3].y = y + width - thickness;
1052 1052
1053 XFillPolygon (dpy, 1053 XFillPolygon (dpy,
1054 window, 1054 window,
1055 select_gc, 1055 select_gc,
1056 points, 1056 points,
1057 4, 1057 4,
1058 Convex, 1058 Convex,
1059 CoordModeOrigin); 1059 CoordModeOrigin);
1060 1060
1061 /* left border */ 1061 /* left border */
1062 points [0].x = x; 1062 points [0].x = x;
1065 points [1].y = y + thick_med; 1065 points [1].y = y + thick_med;
1066 points [2].x = x + thickness; 1066 points [2].x = x + thickness;
1067 points [2].y = y + width - thick_med; 1067 points [2].y = y + width - thick_med;
1068 points [3].x = x; 1068 points [3].x = x;
1069 points [3].y = y + width; 1069 points [3].y = y + width;
1070 1070
1071 XFillPolygon (dpy, window, top_gc, points, 4, Convex, CoordModeOrigin); 1071 XFillPolygon (dpy, window, top_gc, points, 4, Convex, CoordModeOrigin);
1072 1072
1073 /* top border */ 1073 /* top border */
1074 points [0].x = x; 1074 points [0].x = x;
1075 points [0].y = y + width; 1075 points [0].y = y + width;
1077 points [1].y = y + half_width; 1077 points [1].y = y + half_width;
1078 points [2].x = x + length - (thickness + thickness); 1078 points [2].x = x + length - (thickness + thickness);
1079 points [2].y = y + half_width; 1079 points [2].y = y + half_width;
1080 points [3].x = x + thickness; 1080 points [3].x = x + thickness;
1081 points [3].y = y + width - thick_med; 1081 points [3].y = y + width - thick_med;
1082 1082
1083 XFillPolygon (dpy, window, bottom_gc, points, 4, Convex, CoordModeOrigin); 1083 XFillPolygon (dpy, window, bottom_gc, points, 4, Convex, CoordModeOrigin);
1084 1084
1085 /* bottom shadow */ 1085 /* bottom shadow */
1086 points [0].x = x; 1086 points [0].x = x;
1087 points [0].y = y; 1087 points [0].y = y;
1089 points [1].y = y + half_width; 1089 points [1].y = y + half_width;
1090 points [2].x = x + length - (thickness + thickness); 1090 points [2].x = x + length - (thickness + thickness);
1091 points [2].y = y + half_width; 1091 points [2].y = y + half_width;
1092 points [3].x = x + thickness; 1092 points [3].x = x + thickness;
1093 points [3].y = y + thick_med; 1093 points [3].y = y + thick_med;
1094 1094
1095 XFillPolygon (dpy, window, top_gc, points, 4, Convex, CoordModeOrigin); 1095 XFillPolygon (dpy, window, top_gc, points, 4, Convex, CoordModeOrigin);
1096 } 1096 }
1097 1097
1098 static void 1098 static void
1099 toggle_decoration_draw (XlwMenuWidget mw, 1099 toggle_decoration_draw (XlwMenuWidget mw,
1113 type = SHADOW_OUT; 1113 type = SHADOW_OUT;
1114 1114
1115 /* 1115 /*
1116 * Fill internal area. 1116 * Fill internal area.
1117 */ 1117 */
1118 if (set) 1118 if (set)
1119 XFillRectangle (dpy, 1119 XFillRectangle (dpy,
1120 window, 1120 window,
1121 select_gc, 1121 select_gc,
1122 x + thickness, 1122 x + thickness,
1123 y + thickness, 1123 y + thickness,
1124 width - (2*thickness), 1124 width - (2*thickness),
1125 width - (2*thickness)); 1125 width - (2*thickness));
1126 1126
1127 shadow_draw(mw, window, x, y, width, width, type); 1127 shadow_draw(mw, window, x, y, width, width, type);
1128 } 1128 }
1129 1129
1130 static void 1130 static void
1131 radio_decoration_draw (XlwMenuWidget mw, 1131 radio_decoration_draw (XlwMenuWidget mw,
1226 points [npoints].x = x + half_width; /* bottom inside corner */ 1226 points [npoints].x = x + half_width; /* bottom inside corner */
1227 points [npoints++].y = y + width - thickness; 1227 points [npoints++].y = y + width - thickness;
1228 points [npoints].x = x + thickness; /* left inside corner */ 1228 points [npoints].x = x + thickness; /* left inside corner */
1229 points [npoints++].y = y + half_width; 1229 points [npoints++].y = y + half_width;
1230 1230
1231 XFillPolygon (dpy, window, bottom_gc, 1231 XFillPolygon (dpy, window, bottom_gc,
1232 points, npoints, Nonconvex, CoordModeOrigin); 1232 points, npoints, Nonconvex, CoordModeOrigin);
1233 1233
1234 npoints = 0; 1234 npoints = 0;
1235 1235
1236 points [npoints].x = x; /* left corner */ 1236 points [npoints].x = x; /* left corner */
1266 points [3].y = y + width - thickness; 1266 points [3].y = y + width - thickness;
1267 XFillPolygon (dpy, 1267 XFillPolygon (dpy,
1268 window, 1268 window,
1269 select_gc, 1269 select_gc,
1270 points, 1270 points,
1271 4, 1271 4,
1272 Convex, 1272 Convex,
1273 CoordModeOrigin); 1273 CoordModeOrigin);
1274 } 1274 }
1275 } 1275 }
1276 1276
1293 int i; 1293 int i;
1294 1294
1295 switch (type) 1295 switch (type)
1296 { 1296 {
1297 case SHADOW_NO_LINE: /* nothing to do */ 1297 case SHADOW_NO_LINE: /* nothing to do */
1298 return; 1298 return;
1299 case SHADOW_DOUBLE_LINE: 1299 case SHADOW_DOUBLE_LINE:
1300 num_separators = 2; 1300 num_separators = 2;
1301 case SHADOW_SINGLE_LINE: 1301 case SHADOW_SINGLE_LINE:
1302 top_gc = bottom_gc = mw->menu.foreground_gc; 1302 top_gc = bottom_gc = mw->menu.foreground_gc;
1303 top_line_thickness = 1; 1303 top_line_thickness = 1;
1343 bottom_gc = mw->menu.shadow_top_gc; 1343 bottom_gc = mw->menu.shadow_top_gc;
1344 top_line_thickness = mw->menu.shadow_thickness/2; 1344 top_line_thickness = mw->menu.shadow_thickness/2;
1345 bottom_line_thickness = mw->menu.shadow_thickness - top_line_thickness; 1345 bottom_line_thickness = mw->menu.shadow_thickness - top_line_thickness;
1346 break; 1346 break;
1347 } 1347 }
1348 1348
1349 if (dashed) 1349 if (dashed)
1350 { 1350 {
1351 XGCValues values; 1351 XGCValues values;
1352 values.line_style = LineOnOffDash; 1352 values.line_style = LineOnOffDash;
1353 if (top_line_thickness > 0) 1353 if (top_line_thickness > 0)
1354 XChangeGC (dpy, top_gc, GCLineStyle, &values); 1354 XChangeGC (dpy, top_gc, GCLineStyle, &values);
1355 if (bottom_line_thickness > 0 && bottom_gc != top_gc) 1355 if (bottom_line_thickness > 0 && bottom_gc != top_gc)
1356 XChangeGC (dpy, bottom_gc, GCLineStyle, &values); 1356 XChangeGC (dpy, bottom_gc, GCLineStyle, &values);
1357 } 1357 }
1358 1358
1359 while (num_separators--) 1359 while (num_separators--)
1360 { 1360 {
1361 for (i = 0; i < top_line_thickness; i++) 1361 for (i = 0; i < top_line_thickness; i++)
1362 XDrawLine (dpy, window, top_gc, x, y + i, x + width, y + i); 1362 XDrawLine (dpy, window, top_gc, x, y + i, x + width, y + i);
1363 1363
1364 for (i = 0; i < bottom_line_thickness; i++) 1364 for (i = 0; i < bottom_line_thickness; i++)
1365 XDrawLine (dpy, window, bottom_gc, 1365 XDrawLine (dpy, window, bottom_gc,
1366 x, y + top_line_thickness + offset + i, 1366 x, y + top_line_thickness + offset + i,
1367 x + width, y + top_line_thickness + offset + i); 1367 x + width, y + top_line_thickness + offset + i);
1368 y += (top_line_thickness + offset + bottom_line_thickness + 1); 1368 y += (top_line_thickness + offset + bottom_line_thickness + 1);
1369 } 1369 }
1370 1370
1460 return CASCADE_TYPE; 1460 return CASCADE_TYPE;
1461 else if (val->call_data) /* push button */ 1461 else if (val->call_data) /* push button */
1462 return BUTTON_TYPE; 1462 return BUTTON_TYPE;
1463 else 1463 else
1464 return TEXT_TYPE; 1464 return TEXT_TYPE;
1465 #else 1465 #else
1466 abort(); 1466 abort();
1467 #endif 1467 #endif
1468 } 1468 }
1469 } 1469 }
1470 1470
1471 static void 1471 static void
1472 label_button_size (XlwMenuWidget mw, 1472 label_button_size (XlwMenuWidget mw,
1480 *height = (mw->menu.font_ascent + mw->menu.font_descent + 1480 *height = (mw->menu.font_ascent + mw->menu.font_descent +
1481 2 * mw->menu.vertical_margin + 1481 2 * mw->menu.vertical_margin +
1482 2 * mw->menu.shadow_thickness); 1482 2 * mw->menu.shadow_thickness);
1483 /* no left column decoration */ 1483 /* no left column decoration */
1484 *toggle_width = mw->menu.horizontal_margin + mw->menu.shadow_thickness;; 1484 *toggle_width = mw->menu.horizontal_margin + mw->menu.shadow_thickness;;
1485 1485
1486 *label_width = string_width_u (mw, resource_widget_value (mw, val)); 1486 *label_width = string_width_u (mw, resource_widget_value (mw, val));
1487 *bindings_width = mw->menu.horizontal_margin + mw->menu.shadow_thickness; 1487 *bindings_width = mw->menu.horizontal_margin + mw->menu.shadow_thickness;
1488 } 1488 }
1489 1489
1490 static void 1490 static void
1498 unsigned height, 1498 unsigned height,
1499 unsigned label_offset, 1499 unsigned label_offset,
1500 unsigned binding_tab) 1500 unsigned binding_tab)
1501 { 1501 {
1502 int y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin; 1502 int y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin;
1503 1503
1504 if (!label_offset) 1504 if (!label_offset)
1505 label_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin; 1505 label_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin;
1506 1506
1507 /* 1507 /*
1508 * Draw the label string. 1508 * Draw the label string.
1509 */ 1509 */
1510 string_draw_u (mw, 1510 string_draw_u (mw,
1511 window, 1511 window,
1512 x + label_offset, y + y_offset, 1512 x + label_offset, y + y_offset,
1513 mw->menu.foreground_gc, 1513 mw->menu.foreground_gc,
1514 resource_widget_value (mw, val)); 1514 resource_widget_value (mw, val));
1515 } 1515 }
1516 1516
1517 static void 1517 static void
1525 { 1525 {
1526 /* inherit */ 1526 /* inherit */
1527 label_button_size (mw, val, in_menubar, 1527 label_button_size (mw, val, in_menubar,
1528 toggle_width, label_width, bindings_width, 1528 toggle_width, label_width, bindings_width,
1529 height); 1529 height);
1530 1530
1531 /* key bindings to display? */ 1531 /* key bindings to display? */
1532 if (!in_menubar && val->key) 1532 if (!in_menubar && val->key)
1533 { 1533 {
1534 int w; 1534 int w;
1535 #ifdef NEED_MOTIF 1535 #ifdef NEED_MOTIF
1547 static void 1547 static void
1548 push_button_draw (XlwMenuWidget mw, 1548 push_button_draw (XlwMenuWidget mw,
1549 widget_value *val, 1549 widget_value *val,
1550 Boolean in_menubar, 1550 Boolean in_menubar,
1551 Boolean highlighted, 1551 Boolean highlighted,
1552 Window window, 1552 Window window,
1553 int x, int y, 1553 int x, int y,
1554 unsigned width, unsigned height, 1554 unsigned width, unsigned height,
1555 unsigned label_offset, 1555 unsigned label_offset,
1556 unsigned binding_offset) 1556 unsigned binding_offset)
1557 { 1557 {
1558 int y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin; 1558 int y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin;
1559 GC gc; 1559 GC gc;
1560 shadow_type type; 1560 shadow_type type;
1561 Boolean menu_pb = in_menubar && (menu_item_type (val) == BUTTON_TYPE); 1561 Boolean menu_pb = in_menubar && (menu_item_type (val) == BUTTON_TYPE);
1562 1562
1563 /* 1563 /*
1564 * Draw the label string. 1564 * Draw the label string.
1565 */ 1565 */
1566 if (!label_offset) 1566 if (!label_offset)
1567 label_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin; 1567 label_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin;
1568 1568
1569 if (menu_pb) 1569 if (menu_pb)
1570 { 1570 {
1571 if (val->enabled) 1571 if (val->enabled)
1572 gc = mw->menu.button_gc; 1572 gc = mw->menu.button_gc;
1573 else 1573 else
1581 gc = mw->menu.inactive_gc; 1581 gc = mw->menu.inactive_gc;
1582 } 1582 }
1583 1583
1584 string_draw_u (mw, 1584 string_draw_u (mw,
1585 window, 1585 window,
1586 x + label_offset, y + y_offset, 1586 x + label_offset, y + y_offset,
1587 gc, 1587 gc,
1588 resource_widget_value(mw, val)); 1588 resource_widget_value(mw, val));
1589 1589
1590 /* 1590 /*
1591 * Draw the keybindings 1591 * Draw the keybindings
1592 */ 1592 */
1593 if (val->key) 1593 if (val->key)
1594 { 1594 {
1599 } 1599 }
1600 binding_draw (mw, window, 1600 binding_draw (mw, window,
1601 x + binding_offset + mw->menu.column_spacing, 1601 x + binding_offset + mw->menu.column_spacing,
1602 y + y_offset, gc, val->key); 1602 y + y_offset, gc, val->key);
1603 } 1603 }
1604 1604
1605 /* 1605 /*
1606 * Draw the shadow 1606 * Draw the shadow
1607 */ 1607 */
1608 if (menu_pb) 1608 if (menu_pb)
1609 { 1609 {
1610 if (highlighted) 1610 if (highlighted)
1611 type = SHADOW_OUT; 1611 type = SHADOW_OUT;
1612 else 1612 else
1613 type = (val->selected ? SHADOW_ETCHED_OUT : SHADOW_ETCHED_IN); 1613 type = (val->selected ? SHADOW_ETCHED_OUT : SHADOW_ETCHED_IN);
1614 } 1614 }
1615 else 1615 else
1616 { 1616 {
1617 if (highlighted) 1617 if (highlighted)
1618 type = SHADOW_OUT; 1618 type = SHADOW_OUT;
1619 else 1619 else
1620 type = SHADOW_BACKGROUND; 1620 type = SHADOW_BACKGROUND;
1621 } 1621 }
1622 1622
1623 shadow_draw (mw, window, x, y, width, height, type); 1623 shadow_draw (mw, window, x, y, width, height, type);
1624 } 1624 }
1626 static unsigned int 1626 static unsigned int
1627 arrow_decoration_height (XlwMenuWidget mw) 1627 arrow_decoration_height (XlwMenuWidget mw)
1628 { 1628 {
1629 unsigned int result = 1629 unsigned int result =
1630 (mw->menu.font_ascent + mw->menu.font_descent) / (unsigned int)2; 1630 (mw->menu.font_ascent + mw->menu.font_descent) / (unsigned int)2;
1631 1631
1632 result += 2 * mw->menu.shadow_thickness; 1632 result += 2 * mw->menu.shadow_thickness;
1633 1633
1634 if (result > (mw->menu.font_ascent + mw->menu.font_descent)) 1634 if (result > (mw->menu.font_ascent + mw->menu.font_descent))
1635 result = mw->menu.font_ascent + mw->menu.font_descent; 1635 result = mw->menu.font_ascent + mw->menu.font_descent;
1636 1636
1656 *arrow_width += arrow_decoration_height(mw) + mw->menu.column_spacing; 1656 *arrow_width += arrow_decoration_height(mw) + mw->menu.column_spacing;
1657 } 1657 }
1658 } 1658 }
1659 1659
1660 static void 1660 static void
1661 cascade_button_draw (XlwMenuWidget mw, 1661 cascade_button_draw (XlwMenuWidget mw,
1662 widget_value *val, 1662 widget_value *val,
1663 Boolean in_menubar, 1663 Boolean in_menubar,
1664 Boolean highlighted, 1664 Boolean highlighted,
1665 Window window, 1665 Window window,
1666 int x, int y, 1666 int x, int y,
1667 unsigned width, unsigned height, 1667 unsigned width, unsigned height,
1668 unsigned label_offset, 1668 unsigned label_offset,
1669 unsigned binding_offset) 1669 unsigned binding_offset)
1670 { 1670 {
1671 shadow_type type; 1671 shadow_type type;
1682 */ 1682 */
1683 if (!in_menubar && val->contents) 1683 if (!in_menubar && val->contents)
1684 { 1684 {
1685 int y_offset; 1685 int y_offset;
1686 unsigned arrow_height = arrow_decoration_height (mw); 1686 unsigned arrow_height = arrow_decoration_height (mw);
1687 1687
1688 y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin + 1688 y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin +
1689 (mw->menu.font_ascent+mw->menu.font_descent - arrow_height)/2; 1689 (mw->menu.font_ascent+mw->menu.font_descent - arrow_height)/2;
1690 1690
1691 if (!binding_offset) 1691 if (!binding_offset)
1692 { 1692 {
1693 unsigned s_width = string_width(mw, resource_widget_value (mw, val)); 1693 unsigned s_width = string_width(mw, resource_widget_value (mw, val));
1694 1694
1695 if (!label_offset) 1695 if (!label_offset)
1696 label_offset = mw->menu.shadow_thickness + 1696 label_offset = mw->menu.shadow_thickness +
1697 mw->menu.horizontal_margin; 1697 mw->menu.horizontal_margin;
1698 1698
1699 binding_offset = label_offset + s_width + mw->menu.shadow_thickness; 1699 binding_offset = label_offset + s_width + mw->menu.shadow_thickness;
1700 } 1700 }
1701 1701
1702 arrow_decoration_draw (mw, 1702 arrow_decoration_draw (mw,
1703 window, 1703 window,
1704 x + binding_offset + mw->menu.column_spacing, 1704 x + binding_offset + mw->menu.column_spacing,
1705 y + y_offset, 1705 y + y_offset,
1706 arrow_height, 1706 arrow_height,
1707 highlighted); 1707 highlighted);
1708 } 1708 }
1709 1709
1710 /* 1710 /*
1711 * Draw the shadow 1711 * Draw the shadow
1712 */ 1712 */
1713 if (highlighted) 1713 if (highlighted)
1714 type = SHADOW_OUT; 1714 type = SHADOW_OUT;
1715 else 1715 else
1716 type = SHADOW_BACKGROUND; 1716 type = SHADOW_BACKGROUND;
1717 1717
1718 shadow_draw(mw, window, x, y, width, height, type); 1718 shadow_draw(mw, window, x, y, width, height, type);
1719 } 1719 }
1720 1720
1721 static unsigned 1721 static unsigned
1722 toggle_decoration_height(XlwMenuWidget mw) 1722 toggle_decoration_height(XlwMenuWidget mw)
1724 unsigned rv; 1724 unsigned rv;
1725 if (mw->menu.indicator_size > 0) 1725 if (mw->menu.indicator_size > 0)
1726 rv = mw->menu.indicator_size; 1726 rv = mw->menu.indicator_size;
1727 else 1727 else
1728 rv = mw->menu.font_ascent; 1728 rv = mw->menu.font_ascent;
1729 1729
1730 if (rv > (mw->menu.font_ascent+mw->menu.font_descent)) 1730 if (rv > (mw->menu.font_ascent+mw->menu.font_descent))
1731 rv = mw->menu.font_ascent+mw->menu.font_descent; 1731 rv = mw->menu.font_ascent+mw->menu.font_descent;
1732 1732
1733 return rv; 1733 return rv;
1734 } 1734 }
1735 1735
1736 static void 1736 static void
1737 toggle_button_size (XlwMenuWidget mw, 1737 toggle_button_size (XlwMenuWidget mw,
1753 static void 1753 static void
1754 toggle_button_draw (XlwMenuWidget mw, 1754 toggle_button_draw (XlwMenuWidget mw,
1755 widget_value *val, 1755 widget_value *val,
1756 Boolean in_menubar, 1756 Boolean in_menubar,
1757 Boolean highlighted, 1757 Boolean highlighted,
1758 Window window, 1758 Window window,
1759 int x, int y, 1759 int x, int y,
1760 unsigned width, unsigned height, 1760 unsigned width, unsigned height,
1761 unsigned label_tab, 1761 unsigned label_tab,
1762 unsigned binding_tab) 1762 unsigned binding_tab)
1763 { 1763 {
1764 int x_offset; 1764 int x_offset;
1765 int y_offset; 1765 int y_offset;
1766 unsigned t_height = toggle_decoration_height(mw); 1766 unsigned t_height = toggle_decoration_height(mw);
1767 1767
1768 /* 1768 /*
1769 * Draw a toggle. 1769 * Draw a toggle.
1770 */ 1770 */
1771 x_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin; 1771 x_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin;
1772 y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin; 1772 y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin;
1773 y_offset += (mw->menu.font_ascent + mw->menu.font_descent - t_height)/2; 1773 y_offset += (mw->menu.font_ascent + mw->menu.font_descent - t_height)/2;
1774 1774
1775 toggle_decoration_draw (mw, window, x + x_offset, y + y_offset, 1775 toggle_decoration_draw (mw, window, x + x_offset, y + y_offset,
1776 t_height, val->selected); 1776 t_height, val->selected);
1777 1777
1778 /* 1778 /*
1779 * Draw the pushbutton parts. 1779 * Draw the pushbutton parts.
1787 { 1787 {
1788 return toggle_decoration_height(mw); 1788 return toggle_decoration_height(mw);
1789 } 1789 }
1790 1790
1791 static void 1791 static void
1792 radio_button_draw (XlwMenuWidget mw, 1792 radio_button_draw (XlwMenuWidget mw,
1793 widget_value *val, 1793 widget_value *val,
1794 Boolean in_menubar, 1794 Boolean in_menubar,
1795 Boolean highlighted, 1795 Boolean highlighted,
1796 Window window, 1796 Window window,
1797 int x, int y, 1797 int x, int y,
1798 unsigned width, unsigned height, 1798 unsigned width, unsigned height,
1799 unsigned label_tab, 1799 unsigned label_tab,
1800 unsigned binding_tab) 1800 unsigned binding_tab)
1801 { 1801 {
1802 int x_offset; 1802 int x_offset;
1803 int y_offset; 1803 int y_offset;
1804 unsigned r_height = radio_decoration_height(mw); 1804 unsigned r_height = radio_decoration_height(mw);
1805 1805
1806 /* 1806 /*
1807 * Draw a toggle. 1807 * Draw a toggle.
1808 */ 1808 */
1809 x_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin; 1809 x_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin;
1810 y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin; 1810 y_offset = mw->menu.shadow_thickness + mw->menu.vertical_margin;
1897 *label_width = 1; 1897 *label_width = 1;
1898 *toggle_width = *rest_width = 0; 1898 *toggle_width = *rest_width = 0;
1899 } 1899 }
1900 1900
1901 static void 1901 static void
1902 separator_draw (XlwMenuWidget mw, 1902 separator_draw (XlwMenuWidget mw,
1903 widget_value *val, 1903 widget_value *val,
1904 Boolean in_menubar, 1904 Boolean in_menubar,
1905 Boolean highlighted, 1905 Boolean highlighted,
1906 Window window, 1906 Window window,
1907 int x, int y, 1907 int x, int y,
1908 unsigned width, unsigned height, 1908 unsigned width, unsigned height,
1909 unsigned label_tab, 1909 unsigned label_tab,
1910 unsigned binding_tab) 1910 unsigned binding_tab)
1911 { 1911 {
1912 unsigned sep_width; 1912 unsigned sep_width;
1997 XPoint *where, 1997 XPoint *where,
1998 Boolean highlighted, 1998 Boolean highlighted,
1999 Boolean horizontal, 1999 Boolean horizontal,
2000 Boolean just_compute) 2000 Boolean just_compute)
2001 { 2001 {
2002 2002
2003 int x = where->x /* + mw->menu.shadow_thickness */ ; 2003 int x = where->x /* + mw->menu.shadow_thickness */ ;
2004 int y = where->y /* + mw->menu.shadow_thickness */ ; 2004 int y = where->y /* + mw->menu.shadow_thickness */ ;
2005 unsigned toggle_width; 2005 unsigned toggle_width;
2006 unsigned label_width; 2006 unsigned label_width;
2007 unsigned binding_width; 2007 unsigned binding_width;
2011 unsigned binding_tab; 2011 unsigned binding_tab;
2012 void (*function_ptr) (XlwMenuWidget _mw, 2012 void (*function_ptr) (XlwMenuWidget _mw,
2013 widget_value *_val, 2013 widget_value *_val,
2014 Boolean _in_menubar, 2014 Boolean _in_menubar,
2015 Boolean _highlighted, 2015 Boolean _highlighted,
2016 Window _window, 2016 Window _window,
2017 int _x, int _y, 2017 int _x, int _y,
2018 unsigned _width, unsigned _height, 2018 unsigned _width, unsigned _height,
2019 unsigned _label_tab, 2019 unsigned _label_tab,
2020 unsigned _binding_tab); 2020 unsigned _binding_tab);
2021 2021
2022 size_menu_item (mw, val, horizontal, 2022 size_menu_item (mw, val, horizontal,
2031 { 2031 {
2032 width = ws->width - 2 * mw->menu.shadow_thickness; 2032 width = ws->width - 2 * mw->menu.shadow_thickness;
2033 toggle_width = ws->toggle_width; 2033 toggle_width = ws->toggle_width;
2034 label_width = ws->label_width; 2034 label_width = ws->label_width;
2035 } 2035 }
2036 2036
2037 where->x += width; 2037 where->x += width;
2038 where->y += height; 2038 where->y += height;
2039 2039
2040 if (just_compute) 2040 if (just_compute)
2041 return; 2041 return;
2042 2042
2043 label_tab = toggle_width; 2043 label_tab = toggle_width;
2044 binding_tab = toggle_width + label_width; 2044 binding_tab = toggle_width + label_width;
2045 2045
2046 switch (menu_item_type (val)) 2046 switch (menu_item_type (val))
2047 { 2047 {
2070 2070
2071 (*function_ptr) (mw, 2071 (*function_ptr) (mw,
2072 val, 2072 val,
2073 horizontal, 2073 horizontal,
2074 highlighted, 2074 highlighted,
2075 ws->window, 2075 ws->window,
2076 x, y, 2076 x, y,
2077 width, height, 2077 width, height,
2078 label_tab, 2078 label_tab,
2079 binding_tab); 2079 binding_tab);
2080 } 2080 }
2081 2081
2095 window_state* ws; 2095 window_state* ws;
2096 2096
2097 if (level >= mw->menu.old_depth) 2097 if (level >= mw->menu.old_depth)
2098 abort (); 2098 abort ();
2099 2099
2100 ws = &mw->menu.windows [level]; 2100 ws = &mw->menu.windows [level];
2101 2101
2102 for (val = mw->menu.old_stack [level]->contents; val; val = val->next) 2102 for (val = mw->menu.old_stack [level]->contents; val; val = val->next)
2103 { 2103 {
2104 size_menu_item (mw, 2104 size_menu_item (mw,
2105 val, 2105 val,
2123 if (max_rest_width < rest_width) 2123 if (max_rest_width < rest_width)
2124 max_rest_width = rest_width; 2124 max_rest_width = rest_width;
2125 max_height += height; 2125 max_height += height;
2126 } 2126 }
2127 } 2127 }
2128 2128
2129 ws->height = max_height; 2129 ws->height = max_height;
2130 ws->width = max_label_width + max_rest_width + max_toggle_width; 2130 ws->width = max_label_width + max_rest_width + max_toggle_width;
2131 ws->toggle_width = max_toggle_width; 2131 ws->toggle_width = max_toggle_width;
2132 ws->label_width = max_label_width; 2132 ws->label_width = max_label_width;
2133 2133
2151 if (level >= mw->menu.old_depth) 2151 if (level >= mw->menu.old_depth)
2152 abort (); 2152 abort ();
2153 2153
2154 if (level < mw->menu.old_depth - 1) 2154 if (level < mw->menu.old_depth - 1)
2155 following_item = mw->menu.old_stack [level + 1]; 2155 following_item = mw->menu.old_stack [level + 1];
2156 else 2156 else
2157 { 2157 {
2158 if (lw_menu_accelerate 2158 if (lw_menu_accelerate
2159 && level == mw->menu.old_depth - 1 2159 && level == mw->menu.old_depth - 1
2160 && mw->menu.old_stack [level]->type == CASCADE_TYPE) 2160 && mw->menu.old_stack [level]->type == CASCADE_TYPE)
2161 just_compute_p = True; 2161 just_compute_p = True;
2163 } 2163 }
2164 2164
2165 #if SLOPPY_TYPES == 1 2165 #if SLOPPY_TYPES == 1
2166 puts("==================================================================="); 2166 puts("===================================================================");
2167 print_widget_value (following_item, 1, 0); 2167 print_widget_value (following_item, 1, 0);
2168 #endif 2168 #endif
2169 if (following_item 2169 if (following_item
2170 && following_item->type == CASCADE_TYPE 2170 && following_item->type == CASCADE_TYPE
2171 && following_item->contents 2171 && following_item->contents
2172 && following_item->contents->type == INCREMENTAL_TYPE) 2172 && following_item->contents->type == INCREMENTAL_TYPE)
2173 { 2173 {
2177 mw->menu.open, 2177 mw->menu.open,
2178 (XtPointer)following_item->contents); 2178 (XtPointer)following_item->contents);
2179 #if SLOPPY_TYPES == 1 2179 #if SLOPPY_TYPES == 1
2180 puts("==== NEW ==== NEW ==== NEW ==== NEW ==== NEW ==== NEW ==== NEW ===="); 2180 puts("==== NEW ==== NEW ==== NEW ==== NEW ==== NEW ==== NEW ==== NEW ====");
2181 print_widget_value(following_item, 1, 0); 2181 print_widget_value(following_item, 1, 0);
2182 #endif 2182 #endif
2183 } 2183 }
2184 2184
2185 if (hit) 2185 if (hit)
2186 *hit_return = NULL; 2186 *hit_return = NULL;
2187 2187
2221 if (horizontal_p) 2221 if (horizontal_p)
2222 highlighted_pos->x = where.x; 2222 highlighted_pos->x = where.x;
2223 else 2223 else
2224 highlighted_pos->y = where.y; 2224 highlighted_pos->y = where.y;
2225 } 2225 }
2226 2226
2227 just_compute_this_one_p = 2227 just_compute_this_one_p =
2228 just_compute_p || ((this || that) && val != this && val != that); 2228 just_compute_p || ((this || that) && val != this && val != that);
2229 2229
2230 start.x = where.x; 2230 start.x = where.x;
2231 start.y = where.y; 2231 start.y = where.y;
2262 /* Motion code */ 2262 /* Motion code */
2263 static void 2263 static void
2264 set_new_state (XlwMenuWidget mw, widget_value *val, int level) 2264 set_new_state (XlwMenuWidget mw, widget_value *val, int level)
2265 { 2265 {
2266 int i; 2266 int i;
2267 2267
2268 mw->menu.new_depth = 0; 2268 mw->menu.new_depth = 0;
2269 for (i = 0; i < level; i++) 2269 for (i = 0; i < level; i++)
2270 push_new_stack (mw, mw->menu.old_stack [i]); 2270 push_new_stack (mw, mw->menu.old_stack [i]);
2271 if (val) 2271 if (val)
2272 push_new_stack (mw, val); 2272 push_new_stack (mw, val);
2280 XSetWindowAttributes xswa; 2280 XSetWindowAttributes xswa;
2281 int mask; 2281 int mask;
2282 #define ROOT_PARENT 2282 #define ROOT_PARENT
2283 #ifdef ROOT_PARENT 2283 #ifdef ROOT_PARENT
2284 Window root = RootWindowOfScreen (DefaultScreenOfDisplay (XtDisplay (mw))); 2284 Window root = RootWindowOfScreen (DefaultScreenOfDisplay (XtDisplay (mw)));
2285 #endif 2285 #endif
2286 window_state *windows; 2286 window_state *windows;
2287 2287
2288 if (mw->menu.windows_length >= n) 2288 if (mw->menu.windows_length >= n)
2289 return; 2289 return;
2290 2290
2291 xswa.save_under = True; 2291 xswa.save_under = True;
2292 xswa.override_redirect = True; 2292 xswa.override_redirect = True;
2301 if (mw->menu.use_backing_store) 2301 if (mw->menu.use_backing_store)
2302 { 2302 {
2303 xswa.backing_store = Always; 2303 xswa.backing_store = Always;
2304 mask |= CWBackingStore; 2304 mask |= CWBackingStore;
2305 } 2305 }
2306 2306
2307 if (!mw->menu.windows) 2307 if (!mw->menu.windows)
2308 { 2308 {
2309 mw->menu.windows = 2309 mw->menu.windows =
2310 (window_state *) XtMalloc (n * sizeof (window_state)); 2310 (window_state *) XtMalloc (n * sizeof (window_state));
2311 start_at = 0; 2311 start_at = 0;
2329 windows [i].height = 1; 2329 windows [i].height = 1;
2330 windows [i].window = 2330 windows [i].window =
2331 XCreateWindow (XtDisplay (mw), 2331 XCreateWindow (XtDisplay (mw),
2332 #ifdef ROOT_PARENT 2332 #ifdef ROOT_PARENT
2333 root, 2333 root,
2334 #else 2334 #else
2335 ((i > 0) 2335 ((i > 0)
2336 ? windows[0].window 2336 ? windows[0].window
2337 : XtWindow (XtParent (mw))), 2337 : XtWindow (XtParent (mw))),
2338 #endif 2338 #endif
2339 0, 0, 1, 1, 2339 0, 0, 1, 1,
2340 0, 0, CopyFromParent, CopyFromParent, mask, &xswa); 2340 0, 0, CopyFromParent, CopyFromParent, mask, &xswa);
2341 } 2341 }
2342 } 2342 }
2343 2343
2423 if (lw_menu_accelerate 2423 if (lw_menu_accelerate
2424 && last_same 2424 && last_same
2425 && last_same == old_depth - 1 2425 && last_same == old_depth - 1
2426 && old_stack [last_same]->contents) 2426 && old_stack [last_same]->contents)
2427 last_same--; 2427 last_same--;
2428 2428
2429 /* Memorize the previously selected item to be able to refresh it */ 2429 /* Memorize the previously selected item to be able to refresh it */
2430 old_selection = last_same + 1 < old_depth ? old_stack [last_same + 1] : NULL; 2430 old_selection = last_same + 1 < old_depth ? old_stack [last_same + 1] : NULL;
2431 if (old_selection && !old_selection->enabled) 2431 if (old_selection && !old_selection->enabled)
2432 old_selection = NULL; 2432 old_selection = NULL;
2433 new_selection = last_same + 1 < new_depth ? new_stack [last_same + 1] : NULL; 2433 new_selection = last_same + 1 < new_depth ? new_stack [last_same + 1] : NULL;
2436 2436
2437 /* updates old_state from new_state. It has to be done now because 2437 /* updates old_state from new_state. It has to be done now because
2438 display_menu (called below) uses the old_stack to know what to display. */ 2438 display_menu (called below) uses the old_stack to know what to display. */
2439 for (i = last_same + 1; i < new_depth; i++) 2439 for (i = last_same + 1; i < new_depth; i++)
2440 old_stack [i] = new_stack [i]; 2440 old_stack [i] = new_stack [i];
2441 2441
2442 mw->menu.old_depth = new_depth; 2442 mw->menu.old_depth = new_depth;
2443 2443
2444 /* refresh the last seletion */ 2444 /* refresh the last seletion */
2445 selection_position.x = 0; 2445 selection_position.x = 0;
2446 selection_position.y = 0; 2446 selection_position.y = 0;
2453 window_state *previous_ws = &windows [i - 1]; 2453 window_state *previous_ws = &windows [i - 1];
2454 window_state *ws = &windows [i]; 2454 window_state *ws = &windows [i];
2455 2455
2456 if (lw_menu_accelerate && i == new_depth - 1) 2456 if (lw_menu_accelerate && i == new_depth - 1)
2457 break; 2457 break;
2458 2458
2459 ws->x = previous_ws->x + selection_position.x; 2459 ws->x = previous_ws->x + selection_position.x;
2460 ws->y = previous_ws->y + selection_position.y; 2460 ws->y = previous_ws->y + selection_position.y;
2461 2461
2462 /* take into account the slab around the new menu */ 2462 /* take into account the slab around the new menu */
2463 ws->y -= mw->menu.shadow_thickness; 2463 ws->y -= mw->menu.shadow_thickness;
2472 XMapRaised (XtDisplay (mw), ws->window); 2472 XMapRaised (XtDisplay (mw), ws->window);
2473 display_menu (mw, i, False, &selection_position, NULL, NULL, NULL, NULL); 2473 display_menu (mw, i, False, &selection_position, NULL, NULL, NULL, NULL);
2474 } 2474 }
2475 2475
2476 /* unmap the menus that popped down */ 2476 /* unmap the menus that popped down */
2477 2477
2478 last_same = new_depth; 2478 last_same = new_depth;
2479 if (lw_menu_accelerate 2479 if (lw_menu_accelerate
2480 && last_same > 1 2480 && last_same > 1
2481 && new_stack [last_same - 1]->contents) 2481 && new_stack [last_same - 1]->contents)
2482 last_same--; 2482 last_same--;
2483 2483
2484 for (i = last_same - 1; i < old_depth; i++) 2484 for (i = last_same - 1; i < old_depth; i++)
2485 if (i >= last_same || !new_stack [i]->contents) 2485 if (i >= last_same || !new_stack [i]->contents)
2486 XUnmapWindow (XtDisplay (mw), windows [i].window); 2486 XUnmapWindow (XtDisplay (mw), windows [i].window);
2487 } 2487 }
2488 2488
2508 XPoint relative_pos; 2508 XPoint relative_pos;
2509 window_state* ws; 2509 window_state* ws;
2510 2510
2511 *val_ptr = NULL; 2511 *val_ptr = NULL;
2512 *inside_menu = False; 2512 *inside_menu = False;
2513 2513
2514 /* Find the window */ 2514 /* Find the window */
2515 #if 1 2515 #if 1
2516 for (i = mw->menu.old_depth - 1; i >= 0; i--) 2516 for (i = mw->menu.old_depth - 1; i >= 0; i--)
2517 #else 2517 #else
2518 for (i = 0; i <= mw->menu.old_depth - 1; i++) 2518 for (i = 0; i <= mw->menu.old_depth - 1; i++)
2590 xgcv.foreground = xcolor.pixel; 2590 xgcv.foreground = xcolor.pixel;
2591 } 2591 }
2592 } 2592 }
2593 xgcv.background = mw->core.background_pixel; 2593 xgcv.background = mw->core.background_pixel;
2594 mw->menu.select_gc = XtGetGC ((Widget)mw, flags, &xgcv); 2594 mw->menu.select_gc = XtGetGC ((Widget)mw, flags, &xgcv);
2595 2595
2596 xgcv.foreground = mw->menu.foreground; 2596 xgcv.foreground = mw->menu.foreground;
2597 xgcv.background = mw->core.background_pixel; 2597 xgcv.background = mw->core.background_pixel;
2598 xgcv.fill_style = FillStippled; 2598 xgcv.fill_style = FillStippled;
2599 xgcv.stipple = mw->menu.gray_pixmap; 2599 xgcv.stipple = mw->menu.gray_pixmap;
2600 mw->menu.inactive_gc = XtGetGC ((Widget)mw, 2600 mw->menu.inactive_gc = XtGetGC ((Widget)mw,
2602 &xgcv); 2602 &xgcv);
2603 2603
2604 xgcv.foreground = mw->menu.button_foreground; 2604 xgcv.foreground = mw->menu.button_foreground;
2605 xgcv.background = mw->core.background_pixel; 2605 xgcv.background = mw->core.background_pixel;
2606 mw->menu.button_gc = XtGetGC ((Widget)mw, flags, &xgcv); 2606 mw->menu.button_gc = XtGetGC ((Widget)mw, flags, &xgcv);
2607 2607
2608 xgcv.fill_style = FillStippled; 2608 xgcv.fill_style = FillStippled;
2609 xgcv.stipple = mw->menu.gray_pixmap; 2609 xgcv.stipple = mw->menu.gray_pixmap;
2610 mw->menu.inactive_button_gc = XtGetGC ((Widget)mw, 2610 mw->menu.inactive_button_gc = XtGetGC ((Widget)mw,
2611 (flags | GCFillStyle | GCStipple), 2611 (flags | GCFillStyle | GCStipple),
2612 &xgcv); 2612 &xgcv);
2666 topc.green = MINL (65535, topc.green + 0x8000); 2666 topc.green = MINL (65535, topc.green + 0x8000);
2667 topc.blue = MINL (65535, topc.blue + 0x8000); 2667 topc.blue = MINL (65535, topc.blue + 0x8000);
2668 if (allocate_nearest_color (dpy, cmap, &topc)) 2668 if (allocate_nearest_color (dpy, cmap, &topc))
2669 { 2669 {
2670 mw->menu.top_shadow_color = topc.pixel; 2670 mw->menu.top_shadow_color = topc.pixel;
2671 } 2671 }
2672 } 2672 }
2673 else 2673 else
2674 { 2674 {
2675 mw->menu.top_shadow_color = topc.pixel; 2675 mw->menu.top_shadow_color = topc.pixel;
2676 } 2676 }
2695 botc.green = MINL (65535, botc.green + 0x4000); 2695 botc.green = MINL (65535, botc.green + 0x4000);
2696 botc.blue = MINL (65535, botc.blue + 0x4000); 2696 botc.blue = MINL (65535, botc.blue + 0x4000);
2697 if (allocate_nearest_color (dpy, cmap, &botc)) 2697 if (allocate_nearest_color (dpy, cmap, &botc))
2698 { 2698 {
2699 mw->menu.bottom_shadow_color = botc.pixel; 2699 mw->menu.bottom_shadow_color = botc.pixel;
2700 } 2700 }
2701 } 2701 }
2702 else 2702 else
2703 { 2703 {
2704 mw->menu.bottom_shadow_color = botc.pixel; 2704 mw->menu.bottom_shadow_color = botc.pixel;
2705 } 2705 }
2770 #ifdef NEED_MOTIF 2770 #ifdef NEED_MOTIF
2771 /* Find the maximal ascent/descent of the fonts in the font list 2771 /* Find the maximal ascent/descent of the fonts in the font list
2772 so that all menu items can be the same height... */ 2772 so that all menu items can be the same height... */
2773 mw->menu.font_ascent = 0; 2773 mw->menu.font_ascent = 0;
2774 mw->menu.font_descent = 0; 2774 mw->menu.font_descent = 0;
2775 2775
2776 { 2776 {
2777 XmFontContext context; 2777 XmFontContext context;
2778 #if (XmVersion >= 1002) 2778 #if (XmVersion >= 1002)
2779 XmFontListEntry fontentry; 2779 XmFontListEntry fontentry;
2780 #else 2780 #else
2781 XmStringCharSet charset; 2781 XmStringCharSet charset;
2782 #endif 2782 #endif
2783 XFontStruct *font; 2783 XFontStruct *font;
2784 2784
2785 if (! XmFontListInitFontContext (&context, mw->menu.font_list)) 2785 if (! XmFontListInitFontContext (&context, mw->menu.font_list))
2791 newer equivalent, instead. Also, it supports font sets, and the 2791 newer equivalent, instead. Also, it supports font sets, and the
2792 older function doesn't. */ 2792 older function doesn't. */
2793 while ((fontentry = XmFontListNextEntry (context))) 2793 while ((fontentry = XmFontListNextEntry (context)))
2794 { 2794 {
2795 char *one_of_them; 2795 char *one_of_them;
2796 XmFontType rettype; 2796 XmFontType rettype;
2797 2797
2798 one_of_them = XmFontListEntryGetFont (fontentry, &rettype); 2798 one_of_them = XmFontListEntryGetFont (fontentry, &rettype);
2799 if (rettype == XmFONT_IS_FONTSET) 2799 if (rettype == XmFONT_IS_FONTSET)
2800 { 2800 {
2801 XFontSet fontset = (XFontSet) one_of_them; 2801 XFontSet fontset = (XFontSet) one_of_them;
2802 XFontStruct **fontstruct_list; 2802 XFontStruct **fontstruct_list;
2872 XmFontContext context; 2872 XmFontContext context;
2873 #if (XmVersion >= 1002) 2873 #if (XmVersion >= 1002)
2874 XmFontListEntry fontentry; 2874 XmFontListEntry fontentry;
2875 XmFontType rettype; 2875 XmFontType rettype;
2876 char *one_of_them; 2876 char *one_of_them;
2877 #else 2877 #else
2878 XmStringCharSet charset; 2878 XmStringCharSet charset;
2879 #endif 2879 #endif
2880 2880
2881 if (! XmFontListInitFontContext (&context, font_list)) 2881 if (! XmFontListInitFontContext (&context, font_list))
2882 abort (); 2882 abort ();
2883 #if (XmVersion >= 1002) 2883 #if (XmVersion >= 1002)
2884 /* There is a BUG in the 1.2 version of XmFontListGetNextFont() (or more 2884 /* There is a BUG in the 1.2 version of XmFontListGetNextFont() (or more
2885 specifically, in _XmGetFirstFont()) that can cause a null pointer to be 2885 specifically, in _XmGetFirstFont()) that can cause a null pointer to be
2897 } 2897 }
2898 else /* XmFONT_IS_FONT */ 2898 else /* XmFONT_IS_FONT */
2899 { 2899 {
2900 font = (XFontStruct *) one_of_them; 2900 font = (XFontStruct *) one_of_them;
2901 } 2901 }
2902 #else 2902 #else
2903 if (! XmFontListGetNextFont (context, &charset, &font)) 2903 if (! XmFontListGetNextFont (context, &charset, &font))
2904 abort (); 2904 abort ();
2905 XtFree (charset); 2905 XtFree (charset);
2906 #endif 2906 #endif
2907 XmFontListFreeFontContext (context); 2907 XmFontListFreeFontContext (context);
2908 } 2908 }
2909 # endif /* !0 */ 2909 # endif /* !0 */
2910 2910
2911 if (! font) abort (); 2911 if (! font) abort ();
2917 XlwMenuInitialize (Widget request, Widget new, ArgList args, 2917 XlwMenuInitialize (Widget request, Widget new, ArgList args,
2918 Cardinal *num_args) 2918 Cardinal *num_args)
2919 { 2919 {
2920 /* Get the GCs and the widget size */ 2920 /* Get the GCs and the widget size */
2921 XlwMenuWidget mw = (XlwMenuWidget)new; 2921 XlwMenuWidget mw = (XlwMenuWidget)new;
2922 2922
2923 XSetWindowAttributes xswa; 2923 XSetWindowAttributes xswa;
2924 int mask; 2924 int mask;
2925 2925
2926 Window window = RootWindowOfScreen (DefaultScreenOfDisplay (XtDisplay (mw))); 2926 Window window = RootWindowOfScreen (DefaultScreenOfDisplay (XtDisplay (mw)));
2927 Display *display = XtDisplay (mw); 2927 Display *display = XtDisplay (mw);
2928 2928
2929 /* mw->menu.cursor = XCreateFontCursor (display, mw->menu.cursor_shape); */ 2929 /* mw->menu.cursor = XCreateFontCursor (display, mw->menu.cursor_shape); */
2930 mw->menu.cursor = mw->menu.cursor_shape; 2930 mw->menu.cursor = mw->menu.cursor_shape;
2931 2931
2932 mw->menu.gray_pixmap = 2932 mw->menu.gray_pixmap =
2933 XCreatePixmapFromBitmapData (display, window, (char *) gray_bits, 2933 XCreatePixmapFromBitmapData (display, window, (char *) gray_bits,
2934 gray_width, gray_height, 1, 0, 1); 2934 gray_width, gray_height, 1, 0, 1);
2935 2935
2936 #ifdef NEED_MOTIF 2936 #ifdef NEED_MOTIF
2937 /* The menu.font_list slot came from the *fontList resource (Motif standard.) 2937 /* The menu.font_list slot came from the *fontList resource (Motif standard.)
2938 The menu.font_list_2 slot came from the *font resource, for backward 2938 The menu.font_list_2 slot came from the *font resource, for backward
2939 compatibility with older versions of this code, and consistency with the 2939 compatibility with older versions of this code, and consistency with the
2940 rest of emacs. If both font and fontList are specified, we use font. 2940 rest of emacs. If both font and fontList are specified, we use font.
2958 extract_font_extents (mw); 2958 extract_font_extents (mw);
2959 2959
2960 xswa.background_pixel = mw->core.background_pixel; 2960 xswa.background_pixel = mw->core.background_pixel;
2961 xswa.border_pixel = mw->core.border_pixel; 2961 xswa.border_pixel = mw->core.border_pixel;
2962 mask = CWBackPixel | CWBorderPixel; 2962 mask = CWBackPixel | CWBorderPixel;
2963 2963
2964 mw->menu.popped_up = False; 2964 mw->menu.popped_up = False;
2965 mw->menu.pointer_grabbed = False; 2965 mw->menu.pointer_grabbed = False;
2966 mw->menu.next_release_must_exit = False; 2966 mw->menu.next_release_must_exit = False;
2967 2967
2968 mw->menu.old_depth = 1; 2968 mw->menu.old_depth = 1;
2969 mw->menu.old_stack = (widget_value**)XtMalloc (sizeof (widget_value*)); 2969 mw->menu.old_stack = XtNew (widget_value*);
2970 mw->menu.old_stack_length = 1; 2970 mw->menu.old_stack_length = 1;
2971 mw->menu.old_stack [0] = mw->menu.contents; 2971 mw->menu.old_stack [0] = mw->menu.contents;
2972 2972
2973 mw->menu.new_depth = 0; 2973 mw->menu.new_depth = 0;
2974 mw->menu.new_stack = 0; 2974 mw->menu.new_stack = 0;
2975 mw->menu.new_stack_length = 0; 2975 mw->menu.new_stack_length = 0;
2976 push_new_stack (mw, mw->menu.contents); 2976 push_new_stack (mw, mw->menu.contents);
2977 2977
2978 mw->menu.windows = (window_state*)XtMalloc (sizeof (window_state)); 2978 mw->menu.windows = XtNew (window_state);
2979 mw->menu.windows_length = 1; 2979 mw->menu.windows_length = 1;
2980 mw->menu.windows [0].x = 0; 2980 mw->menu.windows [0].x = 0;
2981 mw->menu.windows [0].y = 0; 2981 mw->menu.windows [0].y = 0;
2982 mw->menu.windows [0].width = 0; 2982 mw->menu.windows [0].width = 0;
2983 mw->menu.windows [0].height = 0; 2983 mw->menu.windows [0].height = 0;
2984 size_menu (mw, 0); 2984 size_menu (mw, 0);
2985 2985
2986 mw->core.width = mw->menu.windows [0].width; 2986 mw->core.width = mw->menu.windows [0].width;
2987 mw->core.height = mw->menu.windows [0].height; 2987 mw->core.height = mw->menu.windows [0].height;
2988 } 2988 }
2989 2989
2990 static void 2990 static void
3021 } 3021 }
3022 3022
3023 /* Only the toplevel menubar/popup is a widget so it's the only one that 3023 /* Only the toplevel menubar/popup is a widget so it's the only one that
3024 receives expose events through Xt. So we repaint all the other panes 3024 receives expose events through Xt. So we repaint all the other panes
3025 when receiving an Expose event. */ 3025 when receiving an Expose event. */
3026 static void 3026 static void
3027 XlwMenuRedisplay (Widget w, XEvent *ev, Region region) 3027 XlwMenuRedisplay (Widget w, XEvent *ev, Region region)
3028 { 3028 {
3029 XlwMenuWidget mw = (XlwMenuWidget)w; 3029 XlwMenuWidget mw = (XlwMenuWidget)w;
3030 int i; 3030 int i;
3031 3031
3035 display_menu (mw, i, False, NULL, NULL, NULL, NULL, NULL); 3035 display_menu (mw, i, False, NULL, NULL, NULL, NULL, NULL);
3036 set_new_state (mw, NULL, mw->menu.old_depth); /* #### - ??? */ 3036 set_new_state (mw, NULL, mw->menu.old_depth); /* #### - ??? */
3037 remap_menubar (mw); /* #### - do these two lines do anything? */ 3037 remap_menubar (mw); /* #### - do these two lines do anything? */
3038 } 3038 }
3039 3039
3040 static void 3040 static void
3041 XlwMenuDestroy (Widget w) 3041 XlwMenuDestroy (Widget w)
3042 { 3042 {
3043 int i; 3043 int i;
3044 XlwMenuWidget mw = (XlwMenuWidget) w; 3044 XlwMenuWidget mw = (XlwMenuWidget) w;
3045 3045
3046 if (mw->menu.pointer_grabbed) 3046 if (mw->menu.pointer_grabbed)
3047 { 3047 {
3048 XtUngrabPointer (w, CurrentTime); 3048 XtUngrabPointer (w, CurrentTime);
3049 mw->menu.pointer_grabbed = False; 3049 mw->menu.pointer_grabbed = False;
3050 } 3050 }
3051 3051
3052 release_drawing_gcs (mw); 3052 release_drawing_gcs (mw);
3053 release_shadow_gcs (mw); 3053 release_shadow_gcs (mw);
3054 3054
3055 /* this doesn't come from the resource db but is created explicitly 3055 /* this doesn't come from the resource db but is created explicitly
3056 so we must free it ourselves. */ 3056 so we must free it ourselves. */
3080 XDestroyWindow (XtDisplay (mw), mw->menu.windows [i].window); 3080 XDestroyWindow (XtDisplay (mw), mw->menu.windows [i].window);
3081 if (mw->menu.windows) 3081 if (mw->menu.windows)
3082 XtFree ((char *) mw->menu.windows); 3082 XtFree ((char *) mw->menu.windows);
3083 } 3083 }
3084 3084
3085 static Boolean 3085 static Boolean
3086 XlwMenuSetValues (Widget current, Widget request, Widget new, ArgList args, 3086 XlwMenuSetValues (Widget current, Widget request, Widget new, ArgList args,
3087 Cardinal *num_args) 3087 Cardinal *num_args)
3088 { 3088 {
3089 XlwMenuWidget oldmw = (XlwMenuWidget)current; 3089 XlwMenuWidget oldmw = (XlwMenuWidget)current;
3090 XlwMenuWidget newmw = (XlwMenuWidget)new; 3090 XlwMenuWidget newmw = (XlwMenuWidget)new;
3109 ) 3109 )
3110 { 3110 {
3111 release_drawing_gcs (newmw); 3111 release_drawing_gcs (newmw);
3112 make_drawing_gcs (newmw); 3112 make_drawing_gcs (newmw);
3113 redisplay = True; 3113 redisplay = True;
3114 3114
3115 for (i = 0; i < oldmw->menu.windows_length; i++) 3115 for (i = 0; i < oldmw->menu.windows_length; i++)
3116 { 3116 {
3117 XSetWindowBackground (XtDisplay (oldmw), 3117 XSetWindowBackground (XtDisplay (oldmw),
3118 oldmw->menu.windows [i].window, 3118 oldmw->menu.windows [i].window,
3119 newmw->core.background_pixel); 3119 newmw->core.background_pixel);
3124 } 3124 }
3125 3125
3126 return redisplay; 3126 return redisplay;
3127 } 3127 }
3128 3128
3129 static void 3129 static void
3130 XlwMenuResize (Widget w) 3130 XlwMenuResize (Widget w)
3131 { 3131 {
3132 XlwMenuWidget mw = (XlwMenuWidget)w; 3132 XlwMenuWidget mw = (XlwMenuWidget)w;
3133 3133
3134 mw->menu.windows [0].width = mw->core.width; 3134 mw->menu.windows [0].width = mw->core.width;
3151 a disabled menu item */ 3151 a disabled menu item */
3152 pop_new_stack_if_no_contents (mw); 3152 pop_new_stack_if_no_contents (mw);
3153 if (select_p && !stay_up) { 3153 if (select_p && !stay_up) {
3154 /* pop down all menus and exit */ 3154 /* pop down all menus and exit */
3155 mw->menu.next_release_must_exit = True; 3155 mw->menu.next_release_must_exit = True;
3156 set_new_state(mw, (val = NULL), 1); 3156 set_new_state(mw, (val = NULL), 1);
3157 } 3157 }
3158 } 3158 }
3159 else 3159 else
3160 { 3160 {
3161 /* we wind up here when: (a) the event pops up a pull_right menu, 3161 /* we wind up here when: (a) the event pops up a pull_right menu,
3178 /* popdown last menu if we're selecting the same menu item as we did 3178 /* popdown last menu if we're selecting the same menu item as we did
3179 last time and the XlwMenu.bounceDown resource is set, if the 3179 last time and the XlwMenu.bounceDown resource is set, if the
3180 item is on the menubar itself, then exit. */ 3180 item is on the menubar itself, then exit. */
3181 if (level == (mw->menu.popped_up ? 0 : 1)) 3181 if (level == (mw->menu.popped_up ? 0 : 1))
3182 mw->menu.next_release_must_exit = True; 3182 mw->menu.next_release_must_exit = True;
3183 } 3183 }
3184 else 3184 else
3185 mw->menu.menu_bounce_time = 0; 3185 mw->menu.menu_bounce_time = 0;
3186 set_new_state (mw, val, level); 3186 set_new_state (mw, val, level);
3187 } 3187 }
3188 mw->menu.last_selected_val = val; 3188 mw->menu.last_selected_val = val;
3189 remap_menubar (mw); 3189 remap_menubar (mw);
3190 3190
3191 /* Sync with the display. Makes it feel better on X terms. */ 3191 /* Sync with the display. Makes it feel better on X terms. */
3192 XFlush (XtDisplay (mw)); 3192 XFlush (XtDisplay (mw));
3193 } 3193 }
3194 3194
3195 static void 3195 static void
3221 handle_single_motion_event (mw, event, select_p); 3221 handle_single_motion_event (mw, event, select_p);
3222 } 3222 }
3223 3223
3224 Time x_focus_timestamp_really_sucks_fix_me_better; 3224 Time x_focus_timestamp_really_sucks_fix_me_better;
3225 3225
3226 static void 3226 static void
3227 Start (Widget w, XEvent *ev, String *params, Cardinal *num_params) 3227 Start (Widget w, XEvent *ev, String *params, Cardinal *num_params)
3228 { 3228 {
3229 XlwMenuWidget mw = (XlwMenuWidget)w; 3229 XlwMenuWidget mw = (XlwMenuWidget)w;
3230 3230
3231 lw_menubar_widget = w; 3231 lw_menubar_widget = w;
3232 3232
3233 lw_menu_active = True; 3233 lw_menu_active = True;
3234 3234
3235 if (!mw->menu.pointer_grabbed) 3235 if (!mw->menu.pointer_grabbed)
3236 { 3236 {
3237 mw->menu.menu_post_time = ev->xbutton.time; 3237 mw->menu.menu_post_time = ev->xbutton.time;
3238 mw->menu.menu_bounce_time = 0; 3238 mw->menu.menu_bounce_time = 0;
3239 mw->menu.next_release_must_exit = True; 3239 mw->menu.next_release_must_exit = True;
3240 mw->menu.last_selected_val = NULL; 3240 mw->menu.last_selected_val = NULL;
3241 x_focus_timestamp_really_sucks_fix_me_better = 3241 x_focus_timestamp_really_sucks_fix_me_better =
3242 ((XButtonPressedEvent*)ev)->time; 3242 ((XButtonPressedEvent*)ev)->time;
3243 XtCallCallbackList ((Widget)mw, mw->menu.open, NULL); 3243 XtCallCallbackList ((Widget)mw, mw->menu.open, NULL);
3244 3244
3245 /* notes the absolute position of the menubar window */ 3245 /* notes the absolute position of the menubar window */
3246 mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x; 3246 mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x;
3247 mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y; 3247 mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y;
3248 3248
3249 XtGrabPointer ((Widget)mw, False, 3249 XtGrabPointer ((Widget)mw, False,
3250 (ButtonMotionMask | ButtonReleaseMask | ButtonPressMask), 3250 (ButtonMotionMask | ButtonReleaseMask | ButtonPressMask),
3251 GrabModeAsync, GrabModeAsync, 3251 GrabModeAsync, GrabModeAsync,
3252 None, mw->menu.cursor_shape, 3252 None, mw->menu.cursor_shape,
3253 ((XButtonPressedEvent*)ev)->time); 3253 ((XButtonPressedEvent*)ev)->time);
3256 3256
3257 /* handles the down like a move, slots are mostly compatible */ 3257 /* handles the down like a move, slots are mostly compatible */
3258 handle_motion_event (mw, &ev->xmotion, True); 3258 handle_motion_event (mw, &ev->xmotion, True);
3259 } 3259 }
3260 3260
3261 static void 3261 static void
3262 Drag (Widget w, XEvent *ev, String *params, Cardinal *num_params) 3262 Drag (Widget w, XEvent *ev, String *params, Cardinal *num_params)
3263 { 3263 {
3264 XlwMenuWidget mw = (XlwMenuWidget)w; 3264 XlwMenuWidget mw = (XlwMenuWidget)w;
3265 handle_motion_event (mw, &ev->xmotion, False); 3265 handle_motion_event (mw, &ev->xmotion, False);
3266 } 3266 }
3267 3267
3268 static void 3268 static void
3269 Select (Widget w, XEvent *ev, String *params, Cardinal *num_params) 3269 Select (Widget w, XEvent *ev, String *params, Cardinal *num_params)
3270 { 3270 {
3271 XlwMenuWidget mw = (XlwMenuWidget)w; 3271 XlwMenuWidget mw = (XlwMenuWidget)w;
3272 widget_value *selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; 3272 widget_value *selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
3273 3273
3274 lw_menu_accelerate = False; 3274 lw_menu_accelerate = False;
3275 3275
3276 /* If user releases the button quickly, without selecting anything, 3276 /* If user releases the button quickly, without selecting anything,
3277 after the initial down-click that brought the menu up, 3277 after the initial down-click that brought the menu up,
3278 do nothing. */ 3278 do nothing. */
3279 if ((selected_item == 0 || selected_item->call_data == 0) 3279 if ((selected_item == 0 || selected_item->call_data == 0)
3280 && (!mw->menu.next_release_must_exit 3280 && (!mw->menu.next_release_must_exit
3285 } 3285 }
3286 3286
3287 /* pop down everything */ 3287 /* pop down everything */
3288 mw->menu.new_depth = 1; 3288 mw->menu.new_depth = 1;
3289 remap_menubar (mw); 3289 remap_menubar (mw);
3290 3290
3291 /* Destroy() only gets called for popup menus. Menubar widgets aren't 3291 /* Destroy() only gets called for popup menus. Menubar widgets aren't
3292 destroyed when their menu panes get nuked. */ 3292 destroyed when their menu panes get nuked. */
3293 if (mw->menu.pointer_grabbed) 3293 if (mw->menu.pointer_grabbed)
3294 { 3294 {
3295 XtUngrabPointer ((Widget)w, ev->xmotion.time); 3295 XtUngrabPointer ((Widget)w, ev->xmotion.time);
3296 mw->menu.pointer_grabbed = False; 3296 mw->menu.pointer_grabbed = False;
3297 } 3297 }
3298 3298
3299 if (mw->menu.popped_up) 3299 if (mw->menu.popped_up)
3300 { 3300 {
3301 mw->menu.popped_up = False; 3301 mw->menu.popped_up = False;
3302 XtPopdown (XtParent (mw)); 3302 XtPopdown (XtParent (mw));
3303 } 3303 }
3304 3304
3305 lw_menu_active = False; 3305 lw_menu_active = False;
3306 3306
3307 x_focus_timestamp_really_sucks_fix_me_better = 3307 x_focus_timestamp_really_sucks_fix_me_better =
3308 ((XButtonPressedEvent*)ev)->time; 3308 ((XButtonPressedEvent*)ev)->time;
3309 3309
3310 /* callback */ 3310 /* callback */
3311 XtCallCallbackList ((Widget) mw, mw->menu.select, (XtPointer) selected_item); 3311 XtCallCallbackList ((Widget) mw, mw->menu.select, (XtPointer) selected_item);
3312 } 3312 }
3313 3313
3314 /* Action procedures for keyboard accelerators */ 3314 /* Action procedures for keyboard accelerators */
3326 xlw_map_menu (Time t) 3326 xlw_map_menu (Time t)
3327 { 3327 {
3328 XlwMenuWidget mw = (XlwMenuWidget)lw_menubar_widget; 3328 XlwMenuWidget mw = (XlwMenuWidget)lw_menubar_widget;
3329 3329
3330 lw_menu_accelerate = True; 3330 lw_menu_accelerate = True;
3331 3331
3332 if (!mw->menu.pointer_grabbed) 3332 if (!mw->menu.pointer_grabbed)
3333 { 3333 {
3334 XWindowAttributes ret; 3334 XWindowAttributes ret;
3335 Window parent,root; 3335 Window parent,root;
3336 Window *waste; 3336 Window *waste;
3337 unsigned int num_waste; 3337 unsigned int num_waste;
3338 3338
3339 lw_menu_active = True; 3339 lw_menu_active = True;
3340 3340
3341 mw->menu.menu_post_time = t; 3341 mw->menu.menu_post_time = t;
3342 mw->menu.menu_bounce_time = 0; 3342 mw->menu.menu_bounce_time = 0;
3343 3343
3344 mw->menu.next_release_must_exit = True; 3344 mw->menu.next_release_must_exit = True;
3345 mw->menu.last_selected_val = NULL; 3345 mw->menu.last_selected_val = NULL;
3346 3346
3347 XtCallCallbackList ((Widget)mw, mw->menu.open, NULL); 3347 XtCallCallbackList ((Widget)mw, mw->menu.open, NULL);
3348 3348
3349 /* do this for keyboards too! */ 3349 /* do this for keyboards too! */
3350 /* notes the absolute position of the menubar window */ 3350 /* notes the absolute position of the menubar window */
3351 /* 3351 /*
3352 mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x; 3352 mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x;
3353 mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y; 3353 mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y;
3354 */ 3354 */
3355 3355
3356 /* get the geometry of the menubar */ 3356 /* get the geometry of the menubar */
3357 3357
3358 /* there has to be a better way than this. */ 3358 /* there has to be a better way than this. */
3359 3359
3360 mw->menu.windows [0].x = 0; 3360 mw->menu.windows [0].x = 0;
3361 mw->menu.windows [0].y = 0; 3361 mw->menu.windows [0].y = 0;
3362 3362
3363 parent = XtWindow (lw_menubar_widget); 3363 parent = XtWindow (lw_menubar_widget);
3364 do 3364 do
3365 { 3365 {
3366 XGetWindowAttributes (XtDisplay (lw_menubar_widget), parent, &ret); 3366 XGetWindowAttributes (XtDisplay (lw_menubar_widget), parent, &ret);
3367 mw->menu.windows [0].x += ret.x; 3367 mw->menu.windows [0].x += ret.x;
3368 mw->menu.windows [0].y += ret.y; 3368 mw->menu.windows [0].y += ret.y;
3369 3369
3370 if (parent) 3370 if (parent)
3371 XQueryTree (XtDisplay (lw_menubar_widget), parent, &root, &parent, &waste, 3371 XQueryTree (XtDisplay (lw_menubar_widget), parent, &root, &parent, &waste,
3372 &num_waste); 3372 &num_waste);
3373 if (waste) 3373 if (waste)
3374 { 3374 {
3375 XFree (waste); 3375 XFree (waste);
3376 } 3376 }
3377 } 3377 }
3378 while (parent != root); 3378 while (parent != root);
3379 3379
3380 XtGrabPointer ((Widget)mw, False, 3380 XtGrabPointer ((Widget)mw, False,
3381 (ButtonMotionMask | ButtonReleaseMask | ButtonPressMask), 3381 (ButtonMotionMask | ButtonReleaseMask | ButtonPressMask),
3382 GrabModeAsync, GrabModeAsync, 3382 GrabModeAsync, GrabModeAsync,
3383 None, mw->menu.cursor_shape, t); 3383 None, mw->menu.cursor_shape, t);
3384 mw->menu.pointer_grabbed = True; 3384 mw->menu.pointer_grabbed = True;
3390 xlw_display_menu (Time t) 3390 xlw_display_menu (Time t)
3391 { 3391 {
3392 XlwMenuWidget mw = (XlwMenuWidget)lw_menubar_widget; 3392 XlwMenuWidget mw = (XlwMenuWidget)lw_menubar_widget;
3393 3393
3394 lw_menu_accelerate = True; 3394 lw_menu_accelerate = True;
3395 3395
3396 remap_menubar (mw); 3396 remap_menubar (mw);
3397 3397
3398 /* Sync with the display. Makes it feel better on X terms. */ 3398 /* Sync with the display. Makes it feel better on X terms. */
3399 XFlush (XtDisplay (mw)); 3399 XFlush (XtDisplay (mw));
3400 } 3400 }
3401 3401
3402 /* push a sub menu */ 3402 /* push a sub menu */
3419 3419
3420 void 3420 void
3421 xlw_kill_menus (widget_value *val) 3421 xlw_kill_menus (widget_value *val)
3422 { 3422 {
3423 XlwMenuWidget mw = (XlwMenuWidget)lw_menubar_widget; 3423 XlwMenuWidget mw = (XlwMenuWidget)lw_menubar_widget;
3424 3424
3425 lw_menu_accelerate = False; 3425 lw_menu_accelerate = False;
3426 3426
3427 mw->menu.new_depth = 1; 3427 mw->menu.new_depth = 1;
3428 remap_menubar (mw); 3428 remap_menubar (mw);
3429 3429
3430 if (mw->menu.pointer_grabbed) 3430 if (mw->menu.pointer_grabbed)
3431 { 3431 {
3432 XtUngrabPointer (lw_menubar_widget, CurrentTime); 3432 XtUngrabPointer (lw_menubar_widget, CurrentTime);
3433 mw->menu.pointer_grabbed = False; 3433 mw->menu.pointer_grabbed = False;
3434 } 3434 }
3459 return mw->menu.new_stack[0]; 3459 return mw->menu.new_stack[0];
3460 } 3460 }
3461 else 3461 else
3462 if (mw->menu.new_depth >= 1) 3462 if (mw->menu.new_depth >= 1)
3463 return mw->menu.new_stack [mw->menu.new_depth - 1]; 3463 return mw->menu.new_stack [mw->menu.new_depth - 1];
3464 3464
3465 return NULL; 3465 return NULL;
3466 } 3466 }
3467 3467
3468 int 3468 int
3469 xlw_menu_level (void) 3469 xlw_menu_level (void)
3495 w = mw->menu.windows [0].width; 3495 w = mw->menu.windows [0].width;
3496 h = mw->menu.windows [0].height; 3496 h = mw->menu.windows [0].height;
3497 3497
3498 x -= borderwidth; 3498 x -= borderwidth;
3499 y -= borderwidth; 3499 y -= borderwidth;
3500 3500
3501 if (x < borderwidth) 3501 if (x < borderwidth)
3502 x = borderwidth; 3502 x = borderwidth;
3503 3503
3504 if (x > WidthOfScreen (screen) - w - 2 * borderwidth) 3504 if (x > WidthOfScreen (screen) - w - 2 * borderwidth)
3505 x = WidthOfScreen (screen) - w - 2 * borderwidth; 3505 x = WidthOfScreen (screen) - w - 2 * borderwidth;
3506 3506
3507 if (y < borderwidth) 3507 if (y < borderwidth)
3508 y = borderwidth; 3508 y = borderwidth;
3509 3509
3510 if (y > HeightOfScreen (screen) - h - 2 * borderwidth) 3510 if (y > HeightOfScreen (screen) - h - 2 * borderwidth)
3511 y = HeightOfScreen (screen) - h - 2 * borderwidth; 3511 y = HeightOfScreen (screen) - h - 2 * borderwidth;
3512 3512
3513 mw->menu.popped_up = True; 3513 mw->menu.popped_up = True;
3514 XtConfigureWidget (XtParent (mw), x, y, w, h, 3514 XtConfigureWidget (XtParent (mw), x, y, w, h,