ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/menubar.C
(Generate patch)

Comparing rxvt-unicode/src/menubar.C (file contents):
Revision 1.2 by pcg, Mon Nov 24 17:31:27 2003 UTC vs.
Revision 1.3 by pcg, Tue Nov 25 11:52:42 2003 UTC

1/*--------------------------------*-C-*---------------------------------* 1/*--------------------------------*-C-*---------------------------------*
2 * File: menubar.c 2 * File: menubar.c
3 *----------------------------------------------------------------------* 3 *----------------------------------------------------------------------*
4 * $Id: menubar.C,v 1.2 2003/11/24 17:31:27 pcg Exp $ 4 * $Id: menubar.C,v 1.3 2003/11/25 11:52:42 pcg Exp $
5 * 5 *
6 * Copyright (c) 1997,1998 mj olesen <olesen@me.QueensU.CA> 6 * Copyright (c) 1997,1998 mj olesen <olesen@me.QueensU.CA>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
196 int i; 196 int i;
197 197
198 if (name) { 198 if (name) {
199 i = rxvt_menuarrow_find(name); 199 i = rxvt_menuarrow_find(name);
200 if (i >= 0) { 200 if (i >= 0) {
201 action_t *act = &(R->h->CurrentBar->arrows[i]); 201 action_t *act = &(R->CurrentBar->arrows[i]);
202 202
203 switch (act->type) { 203 switch (act->type) {
204 case MenuAction: 204 case MenuAction:
205 case MenuTerminalAction: 205 case MenuTerminalAction:
206 free(act->str); 206 free(act->str);
329 str[len] = '\0'; 329 str[len] = '\0';
330 330
331#ifdef DEBUG_MENUARROWS 331#ifdef DEBUG_MENUARROWS
332 fprintf(stderr, "<%c>(len %d) = %s\n", Arrows[i].name, len, str); 332 fprintf(stderr, "<%c>(len %d) = %s\n", Arrows[i].name, len, str);
333#endif 333#endif
334 if (rxvt_action_type(&(R->h->CurrentBar->arrows[i]), str) < 0) 334 if (rxvt_action_type(&(R->CurrentBar->arrows[i]), str) < 0)
335 free(str); 335 free(str);
336 } 336 }
337} 337}
338 338
339/* INTPROTO */ 339/* INTPROTO */
447 menu_t *m = NULL; 447 menu_t *m = NULL;
448 menuitem_t *item; 448 menuitem_t *item;
449 449
450#ifdef DEBUG_STRICT 450#ifdef DEBUG_STRICT
451 assert(menu != NULL); 451 assert(menu != NULL);
452 assert(R->h->CurrentBar != NULL); 452 assert(R->CurrentBar != NULL);
453#endif 453#endif
454 454
455 if (path[0] == '\0') 455 if (path[0] == '\0')
456 return path; 456 return path;
457 457
493 *menu = (*menu)->parent; 493 *menu = (*menu)->parent;
494 return path; 494 return path;
495 } 495 }
496/* find this menu */ 496/* find this menu */
497 if (*menu == NULL) { 497 if (*menu == NULL) {
498 for (m = R->h->CurrentBar->tail; m != NULL; m = m->prev) { 498 for (m = R->CurrentBar->tail; m != NULL; m = m->prev) {
499 if (!STRCMP(path, m->name)) 499 if (!STRCMP(path, m->name))
500 break; 500 break;
501 } 501 }
502 } else { 502 } else {
503 /* find this menu */ 503 /* find this menu */
523menu_t * 523menu_t *
524rxvt_menu_delete(pR_ menu_t *menu) 524rxvt_menu_delete(pR_ menu_t *menu)
525{ 525{
526 menu_t *parent = NULL, *prev, *next; 526 menu_t *parent = NULL, *prev, *next;
527 menuitem_t *item; 527 menuitem_t *item;
528 bar_t *CurrentBar = R->h->CurrentBar; 528 bar_t *CurrentBar = R->CurrentBar;
529 529
530#ifdef DEBUG_STRICT 530#ifdef DEBUG_STRICT
531 assert(CurrentBar != NULL); 531 assert(CurrentBar != NULL);
532#endif 532#endif
533 533
585/* INTPROTO */ 585/* INTPROTO */
586menu_t * 586menu_t *
587rxvt_menu_add(pR_ menu_t *parent, char *path) 587rxvt_menu_add(pR_ menu_t *parent, char *path)
588{ 588{
589 menu_t *menu; 589 menu_t *menu;
590 bar_t *CurrentBar = R->h->CurrentBar; 590 bar_t *CurrentBar = R->CurrentBar;
591 591
592#ifdef DEBUG_STRICT 592#ifdef DEBUG_STRICT
593 assert(CurrentBar != NULL); 593 assert(CurrentBar != NULL);
594#endif 594#endif
595 595
677#ifdef MENUBAR_SHADOW_IN 677#ifdef MENUBAR_SHADOW_IN
678 state = -state; 678 state = -state;
679#endif 679#endif
680 switch (state) { 680 switch (state) {
681 case +1: 681 case +1:
682 top = R->h->topShadowGC; 682 top = R->topShadowGC;
683 bot = R->h->botShadowGC; 683 bot = R->botShadowGC;
684 break; /* SHADOW_OUT */ 684 break; /* SHADOW_OUT */
685 case -1: 685 case -1:
686 top = R->h->botShadowGC; 686 top = R->botShadowGC;
687 bot = R->h->topShadowGC; 687 bot = R->topShadowGC;
688 break; /* SHADOW_IN */ 688 break; /* SHADOW_IN */
689 default: 689 default:
690 top = bot = R->h->scrollbarGC; 690 top = bot = R->scrollbarGC;
691 break; /* neutral */ 691 break; /* neutral */
692 } 692 }
693 693
694 rxvt_Draw_Shadow(R->Xdisplay, R->menuBar.win, top, bot, 694 rxvt_Draw_Shadow(R->Xdisplay, R->menuBar.win, top, bot,
695 x, 0, len, menuBar_TotalHeight()); 695 x, 0, len, menuBar_TotalHeight());
705#ifdef MENU_SHADOW_IN 705#ifdef MENU_SHADOW_IN
706 state = -state; 706 state = -state;
707#endif 707#endif
708 switch (state) { 708 switch (state) {
709 case +1: 709 case +1:
710 top = R->h->topShadowGC; 710 top = R->topShadowGC;
711 bot = R->h->botShadowGC; 711 bot = R->botShadowGC;
712 break; /* SHADOW_OUT */ 712 break; /* SHADOW_OUT */
713 case -1: 713 case -1:
714 top = R->h->botShadowGC; 714 top = R->botShadowGC;
715 bot = R->h->topShadowGC; 715 bot = R->topShadowGC;
716 break; /* SHADOW_IN */ 716 break; /* SHADOW_IN */
717 default: 717 default:
718 top = bot = R->h->scrollbarGC; 718 top = bot = R->scrollbarGC;
719 break; /* neutral */ 719 break; /* neutral */
720 } 720 }
721 721
722 w = Height2Pixel(1) - 2 * SHADOW; 722 w = Height2Pixel(1) - 2 * SHADOW;
723 723
724 x -= SHADOW + (3 * w / 2); 724 x -= SHADOW + (3 * w / 2);
725 y += SHADOW * 3; 725 y += SHADOW * 3;
726 726
727 rxvt_Draw_Triangle(R->Xdisplay, R->h->ActiveMenu->win, top, bot, x, y, w, 727 rxvt_Draw_Triangle(R->Xdisplay, R->ActiveMenu->win, top, bot, x, y, w,
728 'r'); 728 'r');
729} 729}
730 730
731/* INTPROTO */ 731/* INTPROTO */
732void 732void
737#ifdef MENU_SHADOW_IN 737#ifdef MENU_SHADOW_IN
738 state = -state; 738 state = -state;
739#endif 739#endif
740 switch (state) { 740 switch (state) {
741 case +1: 741 case +1:
742 top = R->h->topShadowGC; 742 top = R->topShadowGC;
743 bot = R->h->botShadowGC; 743 bot = R->botShadowGC;
744 break; /* SHADOW_OUT */ 744 break; /* SHADOW_OUT */
745 case -1: 745 case -1:
746 top = R->h->botShadowGC; 746 top = R->botShadowGC;
747 bot = R->h->topShadowGC; 747 bot = R->topShadowGC;
748 break; /* SHADOW_IN */ 748 break; /* SHADOW_IN */
749 default: 749 default:
750 top = bot = R->h->scrollbarGC; 750 top = bot = R->scrollbarGC;
751 break; /* neutral */ 751 break; /* neutral */
752 } 752 }
753 753
754 rxvt_Draw_Shadow(R->Xdisplay, R->h->ActiveMenu->win, top, bot, 754 rxvt_Draw_Shadow(R->Xdisplay, R->ActiveMenu->win, top, bot,
755 SHADOW + 0, SHADOW + y, 755 SHADOW + 0, SHADOW + y,
756 R->h->ActiveMenu->w - 2 * (SHADOW), 756 R->ActiveMenu->w - 2 * (SHADOW),
757 HEIGHT_TEXT + 2 * SHADOW); 757 HEIGHT_TEXT + 2 * SHADOW);
758 XFlush(R->Xdisplay); 758 XFlush(R->Xdisplay);
759} 759}
760 760
761#ifdef DEBUG_MENU_LAYOUT 761#ifdef DEBUG_MENU_LAYOUT
830/* INTPROTO */ 830/* INTPROTO */
831void 831void
832rxvt_menu_show(pR) 832rxvt_menu_show(pR)
833{ 833{
834 int x, y, xright; 834 int x, y, xright;
835 menu_t *ActiveMenu = R->h->ActiveMenu; 835 menu_t *ActiveMenu = R->ActiveMenu;
836 menuitem_t *item; 836 menuitem_t *item;
837 837
838 if (ActiveMenu == NULL) 838 if (ActiveMenu == NULL)
839 return; 839 return;
840 840
865 R->PixColors[Color_fg], 865 R->PixColors[Color_fg],
866 R->PixColors[Color_scroll]); 866 R->PixColors[Color_scroll]);
867 XMapWindow(R->Xdisplay, ActiveMenu->win); 867 XMapWindow(R->Xdisplay, ActiveMenu->win);
868 } 868 }
869 rxvt_Draw_Shadow(R->Xdisplay, ActiveMenu->win, 869 rxvt_Draw_Shadow(R->Xdisplay, ActiveMenu->win,
870 R->h->topShadowGC, R->h->botShadowGC, 870 R->topShadowGC, R->botShadowGC,
871 0, 0, ActiveMenu->w, ActiveMenu->h); 871 0, 0, ActiveMenu->w, ActiveMenu->h);
872 872
873/* determine the correct right-alignment */ 873/* determine the correct right-alignment */
874 for (xright = 0, item = ActiveMenu->head; item != NULL; item = item->next) 874 for (xright = 0, item = ActiveMenu->head; item != NULL; item = item->next)
875 if (item->len2 > xright) 875 if (item->len2 > xright)
876 xright = item->len2; 876 xright = item->len2;
877 877
878 for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next) { 878 for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next) {
879 const int xoff = (SHADOW + Width2Pixel(HSPACE) / 2); 879 const int xoff = (SHADOW + Width2Pixel(HSPACE) / 2);
880 register int h; 880 register int h;
881 GC gc = R->h->menubarGC; 881 GC gc = R->menubarGC;
882 882
883 if (isSeparator(item->name)) { 883 if (isSeparator(item->name)) {
884 rxvt_Draw_Shadow(R->Xdisplay, ActiveMenu->win, 884 rxvt_Draw_Shadow(R->Xdisplay, ActiveMenu->win,
885 R->h->topShadowGC, R->h->botShadowGC, 885 R->topShadowGC, R->botShadowGC,
886 SHADOW, y + SHADOW + 1, 886 SHADOW, y + SHADOW + 1,
887 ActiveMenu->w - 2 * SHADOW, 0); 887 ActiveMenu->w - 2 * SHADOW, 0);
888 h = HEIGHT_SEPARATOR; 888 h = HEIGHT_SEPARATOR;
889 } else { 889 } else {
890 char *name = item->name; 890 char *name = item->name;
891 int len = item->len; 891 int len = item->len;
892 892
893 if (item->entry.type == MenuLabel) { 893 if (item->entry.type == MenuLabel) {
894 gc = R->h->botShadowGC; 894 gc = R->botShadowGC;
895 } else if (item->entry.type == MenuSubMenu) { 895 } else if (item->entry.type == MenuSubMenu) {
896 int x1, y1; 896 int x1, y1;
897 menuitem_t *it; 897 menuitem_t *it;
898 menu_t *menu = item->entry.submenu.menu; 898 menu_t *menu = item->entry.submenu.menu;
899 899
971 971
972/* INTPROTO */ 972/* INTPROTO */
973void 973void
974rxvt_menu_display(pR_ void (*update)(rxvt_t *)) 974rxvt_menu_display(pR_ void (*update)(rxvt_t *))
975{ 975{
976 menu_t *ActiveMenu = R->h->ActiveMenu; 976 menu_t *ActiveMenu = R->ActiveMenu;
977 977
978 if (ActiveMenu == NULL) 978 if (ActiveMenu == NULL)
979 return; 979 return;
980 if (ActiveMenu->win != None) 980 if (ActiveMenu->win != None)
981 XDestroyWindow(R->Xdisplay, ActiveMenu->win); 981 XDestroyWindow(R->Xdisplay, ActiveMenu->win);
982 ActiveMenu->win = None; 982 ActiveMenu->win = None;
983 ActiveMenu->item = NULL; 983 ActiveMenu->item = NULL;
984 984
985 if (ActiveMenu->parent == NULL) 985 if (ActiveMenu->parent == NULL)
986 rxvt_drawbox_menubar(aR_ ActiveMenu->x, ActiveMenu->len, +1); 986 rxvt_drawbox_menubar(aR_ ActiveMenu->x, ActiveMenu->len, +1);
987 R->h->ActiveMenu = ActiveMenu->parent; 987 R->ActiveMenu = ActiveMenu->parent;
988 update(r); 988 update(r);
989} 989}
990 990
991/* INTPROTO */ 991/* INTPROTO */
992void 992void
1022 1022
1023/* INTPROTO */ 1023/* INTPROTO */
1024void 1024void
1025rxvt_menubar_clear(pR) 1025rxvt_menubar_clear(pR)
1026{ 1026{
1027 bar_t *CurrentBar = R->h->CurrentBar; 1027 bar_t *CurrentBar = R->CurrentBar;
1028 1028
1029 if (CurrentBar != NULL) { 1029 if (CurrentBar != NULL) {
1030 menu_t *menu = CurrentBar->tail; 1030 menu_t *menu = CurrentBar->tail;
1031 1031
1032 while (menu != NULL) { 1032 while (menu != NULL) {
1041 free(CurrentBar->title); 1041 free(CurrentBar->title);
1042 CurrentBar->title = NULL; 1042 CurrentBar->title = NULL;
1043 } 1043 }
1044 rxvt_menuarrow_free(aR_ 0); /* remove all arrow functions */ 1044 rxvt_menuarrow_free(aR_ 0); /* remove all arrow functions */
1045 } 1045 }
1046 R->h->ActiveMenu = NULL; 1046 R->ActiveMenu = NULL;
1047} 1047}
1048 1048
1049#if (MENUBAR_MAX > 1) 1049#if (MENUBAR_MAX > 1)
1050/* find if menu already exists */ 1050/* find if menu already exists */
1051/* INTPROTO */ 1051/* INTPROTO */
1052bar_t * 1052bar_t *
1053rxvt_menubar_find(pR_ const char *name) 1053rxvt_menubar_find(pR_ const char *name)
1054{ 1054{
1055 bar_t *bar = R->h->CurrentBar; 1055 bar_t *bar = R->CurrentBar;
1056 1056
1057#ifdef DEBUG_MENUBAR_STACKING 1057#ifdef DEBUG_MENUBAR_STACKING
1058 fprintf(stderr, "looking for [menu:%s] ...", name ? name : "(nil)"); 1058 fprintf(stderr, "looking for [menu:%s] ...", name ? name : "(nil)");
1059#endif 1059#endif
1060 if (bar == NULL || name == NULL) 1060 if (bar == NULL || name == NULL)
1068#endif 1068#endif
1069 return bar; 1069 return bar;
1070 } 1070 }
1071 bar = bar->next; 1071 bar = bar->next;
1072 } 1072 }
1073 while (bar != R->h->CurrentBar); 1073 while (bar != R->CurrentBar);
1074 bar = NULL; 1074 bar = NULL;
1075 } 1075 }
1076#ifdef DEBUG_MENUBAR_STACKING 1076#ifdef DEBUG_MENUBAR_STACKING
1077 fprintf(stderr, "%s found!\n", (bar ? "" : " NOT")); 1077 fprintf(stderr, "%s found!\n", (bar ? "" : " NOT"));
1078#endif 1078#endif
1085rxvt_menubar_push(pR_ const char *name) 1085rxvt_menubar_push(pR_ const char *name)
1086{ 1086{
1087 int ret = 1; 1087 int ret = 1;
1088 bar_t *bar; 1088 bar_t *bar;
1089 1089
1090 if (R->h->CurrentBar == NULL) { 1090 if (R->CurrentBar == NULL) {
1091 /* allocate first one */ 1091 /* allocate first one */
1092 bar = (bar_t *) rxvt_malloc(sizeof(bar_t)); 1092 bar = (bar_t *) rxvt_malloc(sizeof(bar_t));
1093 1093
1094 MEMSET(bar, 0, sizeof(bar_t)); 1094 MEMSET(bar, 0, sizeof(bar_t));
1095 /* circular linked-list */ 1095 /* circular linked-list */
1096 bar->next = bar->prev = bar; 1096 bar->next = bar->prev = bar;
1097 bar->head = bar->tail = NULL; 1097 bar->head = bar->tail = NULL;
1098 bar->title = NULL; 1098 bar->title = NULL;
1099 R->h->CurrentBar = bar; 1099 R->CurrentBar = bar;
1100 R->h->Nbars++; 1100 R->Nbars++;
1101 1101
1102 rxvt_menubar_clear(aR); 1102 rxvt_menubar_clear(aR);
1103 } else { 1103 } else {
1104 /* find if menu already exists */ 1104 /* find if menu already exists */
1105 bar = rxvt_menubar_find(aR_ name); 1105 bar = rxvt_menubar_find(aR_ name);
1106 if (bar != NULL) { 1106 if (bar != NULL) {
1107 /* found it, use it */ 1107 /* found it, use it */
1108 R->h->CurrentBar = bar; 1108 R->CurrentBar = bar;
1109 } else { 1109 } else {
1110 /* create if needed, or reuse the existing empty menubar */ 1110 /* create if needed, or reuse the existing empty menubar */
1111 if (R->h->CurrentBar->head != NULL) { 1111 if (R->CurrentBar->head != NULL) {
1112 /* need to malloc another one */ 1112 /* need to malloc another one */
1113 if (R->h->Nbars < MENUBAR_MAX) 1113 if (R->Nbars < MENUBAR_MAX)
1114 bar = (bar_t *) rxvt_malloc(sizeof(bar_t)); 1114 bar = (bar_t *) rxvt_malloc(sizeof(bar_t));
1115 else 1115 else
1116 bar = NULL; 1116 bar = NULL;
1117 1117
1118 /* malloc failed or too many menubars, reuse another */ 1118 /* malloc failed or too many menubars, reuse another */
1119 if (bar == NULL) { 1119 if (bar == NULL) {
1120 bar = R->h->CurrentBar->next; 1120 bar = R->CurrentBar->next;
1121 ret = -1; 1121 ret = -1;
1122 } else { 1122 } else {
1123 bar->head = bar->tail = NULL; 1123 bar->head = bar->tail = NULL;
1124 bar->title = NULL; 1124 bar->title = NULL;
1125 1125
1126 bar->next = R->h->CurrentBar->next; 1126 bar->next = R->CurrentBar->next;
1127 R->h->CurrentBar->next = bar; 1127 R->CurrentBar->next = bar;
1128 bar->prev = R->h->CurrentBar; 1128 bar->prev = R->CurrentBar;
1129 bar->next->prev = bar; 1129 bar->next->prev = bar;
1130 1130
1131 R->h->Nbars++; 1131 R->Nbars++;
1132 } 1132 }
1133 R->h->CurrentBar = bar; 1133 R->CurrentBar = bar;
1134 1134
1135 } 1135 }
1136 rxvt_menubar_clear(aR); 1136 rxvt_menubar_clear(aR);
1137 } 1137 }
1138 } 1138 }
1139 1139
1140/* give menubar this name */ 1140/* give menubar this name */
1141 STRNCPY(R->h->CurrentBar->name, name, MAXNAME); 1141 STRNCPY(R->CurrentBar->name, name, MAXNAME);
1142 R->h->CurrentBar->name[MAXNAME - 1] = '\0'; 1142 R->CurrentBar->name[MAXNAME - 1] = '\0';
1143 1143
1144 return ret; 1144 return ret;
1145} 1145}
1146 1146
1147/* switch to a menu called NAME and remove it */ 1147/* switch to a menu called NAME and remove it */
1151{ 1151{
1152 bar_t *bar; 1152 bar_t *bar;
1153 1153
1154 if ((bar = rxvt_menubar_find(aR_ name)) == NULL) 1154 if ((bar = rxvt_menubar_find(aR_ name)) == NULL)
1155 return; 1155 return;
1156 R->h->CurrentBar = bar; 1156 R->CurrentBar = bar;
1157 1157
1158 do { 1158 do {
1159 rxvt_menubar_clear(aR); 1159 rxvt_menubar_clear(aR);
1160 /* 1160 /*
1161 * pop a menubar, clean it up first 1161 * pop a menubar, clean it up first
1162 */ 1162 */
1163 if (R->h->CurrentBar != NULL) { 1163 if (R->CurrentBar != NULL) {
1164 bar_t *prev = R->h->CurrentBar->prev; 1164 bar_t *prev = R->CurrentBar->prev;
1165 bar_t *next = R->h->CurrentBar->next; 1165 bar_t *next = R->CurrentBar->next;
1166 1166
1167 if (prev == next && prev == R->h->CurrentBar) { /* only 1 left */ 1167 if (prev == next && prev == R->CurrentBar) { /* only 1 left */
1168 prev = NULL; 1168 prev = NULL;
1169 R->h->Nbars = 0; /* safety */ 1169 R->Nbars = 0; /* safety */
1170 } else { 1170 } else {
1171 next->prev = prev; 1171 next->prev = prev;
1172 prev->next = next; 1172 prev->next = next;
1173 R->h->Nbars--; 1173 R->Nbars--;
1174 } 1174 }
1175 1175
1176 free(R->h->CurrentBar); 1176 free(R->CurrentBar);
1177 R->h->CurrentBar = prev; 1177 R->CurrentBar = prev;
1178 } 1178 }
1179 } 1179 }
1180 while (R->h->CurrentBar && !STRCMP(name, "*")); 1180 while (R->CurrentBar && !STRCMP(name, "*"));
1181} 1181}
1182 1182
1183/* INTPROTO */ 1183/* INTPROTO */
1184void 1184void
1185rxvt_action_decode(FILE *fp, action_t *act) 1185rxvt_action_decode(FILE *fp, action_t *act)
1290 1290
1291/* INTPROTO */ 1291/* INTPROTO */
1292void 1292void
1293rxvt_menubar_dump(pR_ FILE *fp) 1293rxvt_menubar_dump(pR_ FILE *fp)
1294{ 1294{
1295 bar_t *bar = R->h->CurrentBar; 1295 bar_t *bar = R->CurrentBar;
1296 time_t t; 1296 time_t t;
1297 1297
1298 if (bar == NULL || fp == NULL) 1298 if (bar == NULL || fp == NULL)
1299 return; 1299 return;
1300 time(&t); 1300 time(&t);
1301 1301
1302 fprintf(fp, 1302 fprintf(fp,
1303 "# " APL_SUBCLASS " (%s) Pid: %u\n# Date: %s\n\n", 1303 "# " APL_SUBCLASS " (%s) Pid: %u\n# Date: %s\n\n",
1304 R->h->rs[Rs_name], (unsigned int)getpid(), ctime(&t)); 1304 R->rs[Rs_name], (unsigned int)getpid(), ctime(&t));
1305 1305
1306/* dump in reverse order */ 1306/* dump in reverse order */
1307 bar = R->h->CurrentBar->prev; 1307 bar = R->CurrentBar->prev;
1308 do { 1308 do {
1309 menu_t *menu; 1309 menu_t *menu;
1310 int i; 1310 int i;
1311 1311
1312 fprintf(fp, "[menu:%s]\n", bar->name); 1312 fprintf(fp, "[menu:%s]\n", bar->name);
1329 rxvt_menu_dump(fp, menu); 1329 rxvt_menu_dump(fp, menu);
1330 1330
1331 fprintf(fp, "\n[done:%s]\n\n", bar->name); 1331 fprintf(fp, "\n[done:%s]\n\n", bar->name);
1332 bar = bar->prev; 1332 bar = bar->prev;
1333 } 1333 }
1334 while (bar != R->h->CurrentBar->prev); 1334 while (bar != R->CurrentBar->prev);
1335} 1335}
1336#endif /* (MENUBAR_MAX > 1) */ 1336#endif /* (MENUBAR_MAX > 1) */
1337 1337
1338/* 1338/*
1339 * read in menubar commands from FILENAME 1339 * read in menubar commands from FILENAME
1357/* read in a menu from a file */ 1357/* read in a menu from a file */
1358 FILE *fp; 1358 FILE *fp;
1359 char buffer[256]; 1359 char buffer[256];
1360 char *p, *file, *tag = NULL; 1360 char *p, *file, *tag = NULL;
1361 1361
1362 file = (char *)rxvt_File_find(filename, ".menu", R->h->rs[Rs_path]); 1362 file = (char *)rxvt_File_find(filename, ".menu", R->rs[Rs_path]);
1363 if (file == NULL) 1363 if (file == NULL)
1364 return; 1364 return;
1365 fp = fopen(file, "rb"); 1365 fp = fopen(file, "rb");
1366 free(file); 1366 free(file);
1367 if (fp == NULL) 1367 if (fp == NULL)
1411#endif 1411#endif
1412 1412
1413 /* looking for [done:tag] or [done:] */ 1413 /* looking for [done:tag] or [done:] */
1414 if ((n = rxvt_Str_match(p, "[done")) != 0) { 1414 if ((n = rxvt_Str_match(p, "[done")) != 0) {
1415 if (p[n] == ']') { 1415 if (p[n] == ']') {
1416 R->h->menu_readonly = 1; 1416 R->menu_readonly = 1;
1417 break; 1417 break;
1418 } else if (p[n] == ':') { 1418 } else if (p[n] == ':') {
1419 n++; 1419 n++;
1420 if (p[n] == ']') { 1420 if (p[n] == ']') {
1421 R->h->menu_readonly = 1; 1421 R->menu_readonly = 1;
1422 break; 1422 break;
1423 } else if (tag) { 1423 } else if (tag) {
1424 n += rxvt_Str_match(p + n, tag); 1424 n += rxvt_Str_match(p + n, tag);
1425 if (p[n] == ']') { 1425 if (p[n] == ']') {
1426#ifdef DEBUG_MENU 1426#ifdef DEBUG_MENU
1427 fprintf(stderr, "[done:%s]\n", tag); 1427 fprintf(stderr, "[done:%s]\n", tag);
1428#endif 1428#endif
1429 R->h->menu_readonly = 1; 1429 R->menu_readonly = 1;
1430 break; 1430 break;
1431 } 1431 }
1432 } else { 1432 } else {
1433 /* what? ... skip this line */ 1433 /* what? ... skip this line */
1434 p[0] = COMMENT_CHAR; 1434 p[0] = COMMENT_CHAR;
1440 * and strip-off leading/trailing quotes 1440 * and strip-off leading/trailing quotes
1441 * skip blank or comment lines 1441 * skip blank or comment lines
1442 */ 1442 */
1443 rxvt_Str_trim(p); 1443 rxvt_Str_trim(p);
1444 if (*p && *p != '#') { 1444 if (*p && *p != '#') {
1445 R->h->menu_readonly = 0; /* if case we read another file */ 1445 R->menu_readonly = 0; /* if case we read another file */
1446 rxvt_menubar_dispatch(aR_ p); 1446 rxvt_menubar_dispatch(aR_ p);
1447 } 1447 }
1448 /* get another line */ 1448 /* get another line */
1449 p = fgets(buffer, sizeof(buffer), fp); 1449 p = fgets(buffer, sizeof(buffer), fp);
1450 } 1450 }
1460rxvt_menubar_dispatch(pR_ char *str) 1460rxvt_menubar_dispatch(pR_ char *str)
1461{ 1461{
1462 int n, cmd; 1462 int n, cmd;
1463 char *path, *name, *name2; 1463 char *path, *name, *name2;
1464 1464
1465 if (menubar_visible(r) && R->h->ActiveMenu != NULL) 1465 if (menubar_visible(r) && R->ActiveMenu != NULL)
1466 rxvt_menubar_expose(aR); 1466 rxvt_menubar_expose(aR);
1467 else 1467 else
1468 R->h->ActiveMenu = NULL; 1468 R->ActiveMenu = NULL;
1469 1469
1470 cmd = *str; 1470 cmd = *str;
1471 switch (cmd) { 1471 switch (cmd) {
1472 case '.': 1472 case '.':
1473 case '/': /* absolute & relative path */ 1473 case '/': /* absolute & relative path */
1481 str++; /* skip cmd character */ 1481 str++; /* skip cmd character */
1482 break; 1482 break;
1483 1483
1484 case '<': 1484 case '<':
1485#if (MENUBAR_MAX > 1) 1485#if (MENUBAR_MAX > 1)
1486 if (R->h->CurrentBar == NULL) 1486 if (R->CurrentBar == NULL)
1487 break; 1487 break;
1488#endif /* (MENUBAR_MAX > 1) */ 1488#endif /* (MENUBAR_MAX > 1) */
1489 if (str[1] && str[2] == '>') /* arrow commands */ 1489 if (str[1] && str[2] == '>') /* arrow commands */
1490 rxvt_menuarrow_add(aR_ str); 1490 rxvt_menuarrow_add(aR_ str);
1491 break; 1491 break;
1514 1514
1515 if (str[0] == ':') { 1515 if (str[0] == ':') {
1516 int saved; 1516 int saved;
1517 1517
1518 /* try and dispatch it, regardless of read/write status */ 1518 /* try and dispatch it, regardless of read/write status */
1519 saved = R->h->menu_readonly; 1519 saved = R->menu_readonly;
1520 R->h->menu_readonly = 0; 1520 R->menu_readonly = 0;
1521 rxvt_menubar_dispatch(aR_ str + 1); 1521 rxvt_menubar_dispatch(aR_ str + 1);
1522 R->h->menu_readonly = saved; 1522 R->menu_readonly = saved;
1523 } 1523 }
1524 /* these ones don't require menu stacking */ 1524 /* these ones don't require menu stacking */
1525 else if (!STRCMP(str, "clear")) { 1525 else if (!STRCMP(str, "clear")) {
1526 rxvt_menubar_clear(aR); 1526 rxvt_menubar_clear(aR);
1527 } else if (!STRCMP(str, "done") || rxvt_Str_match(str, "done:")) { 1527 } else if (!STRCMP(str, "done") || rxvt_Str_match(str, "done:")) {
1528 R->h->menu_readonly = 1; 1528 R->menu_readonly = 1;
1529 } else if (!STRCMP(str, "show")) { 1529 } else if (!STRCMP(str, "show")) {
1530 rxvt_map_menuBar(aR_ 1); 1530 rxvt_map_menuBar(aR_ 1);
1531 R->h->menu_readonly = 1; 1531 R->menu_readonly = 1;
1532 } else if (!STRCMP(str, "hide")) { 1532 } else if (!STRCMP(str, "hide")) {
1533 rxvt_map_menuBar(aR_ 0); 1533 rxvt_map_menuBar(aR_ 0);
1534 R->h->menu_readonly = 1; 1534 R->menu_readonly = 1;
1535 } else if ((n = rxvt_Str_match(str, "read:")) != 0) { 1535 } else if ((n = rxvt_Str_match(str, "read:")) != 0) {
1536 /* read in a menu from a file */ 1536 /* read in a menu from a file */
1537 str += n; 1537 str += n;
1538 rxvt_menubar_read(aR_ str); 1538 rxvt_menubar_read(aR_ str);
1539 } else if ((n = rxvt_Str_match(str, "title:")) != 0) { 1539 } else if ((n = rxvt_Str_match(str, "title:")) != 0) {
1540 str += n; 1540 str += n;
1541 if (R->h->CurrentBar != NULL && !R->h->menu_readonly) { 1541 if (R->CurrentBar != NULL && !R->menu_readonly) {
1542 if (*str) { 1542 if (*str) {
1543 name = rxvt_realloc(R->h->CurrentBar->title, 1543 name = rxvt_realloc(R->CurrentBar->title,
1544 STRLEN(str) + 1); 1544 STRLEN(str) + 1);
1545 if (name != NULL) { 1545 if (name != NULL) {
1546 STRCPY(name, str); 1546 STRCPY(name, str);
1547 R->h->CurrentBar->title = name; 1547 R->CurrentBar->title = name;
1548 } 1548 }
1549 rxvt_menubar_expose(aR); 1549 rxvt_menubar_expose(aR);
1550 } else { 1550 } else {
1551 free(R->h->CurrentBar->title); 1551 free(R->CurrentBar->title);
1552 R->h->CurrentBar->title = NULL; 1552 R->CurrentBar->title = NULL;
1553 } 1553 }
1554 } 1554 }
1555 } else if ((n = rxvt_Str_match(str, "pixmap:")) != 0) { 1555 } else if ((n = rxvt_Str_match(str, "pixmap:")) != 0) {
1556 str += n; 1556 str += n;
1557 rxvt_xterm_seq(aR_ XTerm_Pixmap, str, CHAR_ST); 1557 rxvt_xterm_seq(aR_ XTerm_Pixmap, str, CHAR_ST);
1567 /* FALLTHROUGH */ 1567 /* FALLTHROUGH */
1568 case '*': 1568 case '*':
1569 rxvt_menubar_remove(aR_ str); 1569 rxvt_menubar_remove(aR_ str);
1570 break; 1570 break;
1571 } 1571 }
1572 R->h->menu_readonly = 1; 1572 R->menu_readonly = 1;
1573 } else if ((n = rxvt_Str_match(str, "menu")) != 0) { 1573 } else if ((n = rxvt_Str_match(str, "menu")) != 0) {
1574 str += n; 1574 str += n;
1575 switch (str[0]) { 1575 switch (str[0]) {
1576 case ':': 1576 case ':':
1577 str++; 1577 str++;
1578 /* add/access menuBar */ 1578 /* add/access menuBar */
1579 if (*str != '\0' && *str != '*') 1579 if (*str != '\0' && *str != '*')
1580 rxvt_menubar_push(aR_ str); 1580 rxvt_menubar_push(aR_ str);
1581 break; 1581 break;
1582 default: 1582 default:
1583 if (R->h->CurrentBar == NULL) { 1583 if (R->CurrentBar == NULL) {
1584 rxvt_menubar_push(aR_ "default"); 1584 rxvt_menubar_push(aR_ "default");
1585 } 1585 }
1586 } 1586 }
1587 1587
1588 if (R->h->CurrentBar != NULL) 1588 if (R->CurrentBar != NULL)
1589 R->h->menu_readonly = 0; /* allow menu build commands */ 1589 R->menu_readonly = 0; /* allow menu build commands */
1590 } else if (!STRCMP(str, "dump")) { 1590 } else if (!STRCMP(str, "dump")) {
1591 /* dump current menubars to a file */ 1591 /* dump current menubars to a file */
1592 FILE *fp; 1592 FILE *fp;
1593 1593
1594 /* enough space to hold the results */ 1594 /* enough space to hold the results */
1601 rxvt_xterm_seq(aR_ XTerm_title, buffer, CHAR_ST); 1601 rxvt_xterm_seq(aR_ XTerm_title, buffer, CHAR_ST);
1602 rxvt_menubar_dump(aR_ fp); 1602 rxvt_menubar_dump(aR_ fp);
1603 fclose(fp); 1603 fclose(fp);
1604 } 1604 }
1605 } else if (!STRCMP(str, "next")) { 1605 } else if (!STRCMP(str, "next")) {
1606 if (R->h->CurrentBar) { 1606 if (R->CurrentBar) {
1607 R->h->CurrentBar = R->h->CurrentBar->next; 1607 R->CurrentBar = R->CurrentBar->next;
1608 R->h->menu_readonly = 1; 1608 R->menu_readonly = 1;
1609 } 1609 }
1610 } else if (!STRCMP(str, "prev")) { 1610 } else if (!STRCMP(str, "prev")) {
1611 if (R->h->CurrentBar) { 1611 if (R->CurrentBar) {
1612 R->h->CurrentBar = R->h->CurrentBar->prev; 1612 R->CurrentBar = R->CurrentBar->prev;
1613 R->h->menu_readonly = 1; 1613 R->menu_readonly = 1;
1614 } 1614 }
1615 } else if (!STRCMP(str, "swap")) { 1615 } else if (!STRCMP(str, "swap")) {
1616 /* swap the top 2 menus */ 1616 /* swap the top 2 menus */
1617 if (R->h->CurrentBar) { 1617 if (R->CurrentBar) {
1618 bar_t *cbprev = R->h->CurrentBar->prev; 1618 bar_t *cbprev = R->CurrentBar->prev;
1619 bar_t *cbnext = R->h->CurrentBar->next; 1619 bar_t *cbnext = R->CurrentBar->next;
1620 1620
1621 cbprev->next = cbnext; 1621 cbprev->next = cbnext;
1622 cbnext->prev = cbprev; 1622 cbnext->prev = cbprev;
1623 1623
1624 R->h->CurrentBar->next = cbprev; 1624 R->CurrentBar->next = cbprev;
1625 R->h->CurrentBar->prev = cbprev->prev; 1625 R->CurrentBar->prev = cbprev->prev;
1626 1626
1627 cbprev->prev->next = R->h->CurrentBar; 1627 cbprev->prev->next = R->CurrentBar;
1628 cbprev->prev = R->h->CurrentBar; 1628 cbprev->prev = R->CurrentBar;
1629 1629
1630 R->h->CurrentBar = cbprev; 1630 R->CurrentBar = cbprev;
1631 R->h->menu_readonly = 1; 1631 R->menu_readonly = 1;
1632 } 1632 }
1633 } 1633 }
1634#endif /* (MENUBAR_MAX > 1) */ 1634#endif /* (MENUBAR_MAX > 1) */
1635 str = next; 1635 str = next;
1636 1636
1637 R->h->BuildMenu = R->h->ActiveMenu = NULL; 1637 R->BuildMenu = R->ActiveMenu = NULL;
1638 rxvt_menubar_expose(aR); 1638 rxvt_menubar_expose(aR);
1639#ifdef DEBUG_MENUBAR_STACKING 1639#ifdef DEBUG_MENUBAR_STACKING
1640 fprintf(stderr, "menus are read%s\n", 1640 fprintf(stderr, "menus are read%s\n",
1641 R->h->menu_readonly ? "only" : "/write"); 1641 R->menu_readonly ? "only" : "/write");
1642#endif 1642#endif
1643 } 1643 }
1644 return; 1644 return;
1645 break; 1645 break;
1646 } 1646 }
1647 1647
1648#if (MENUBAR_MAX > 1) 1648#if (MENUBAR_MAX > 1)
1649 if (R->h->CurrentBar == NULL) 1649 if (R->CurrentBar == NULL)
1650 return; 1650 return;
1651 if (R->h->menu_readonly) { 1651 if (R->menu_readonly) {
1652#ifdef DEBUG_MENUBAR_STACKING 1652#ifdef DEBUG_MENUBAR_STACKING
1653 fprintf(stderr, "menus are read%s\n", 1653 fprintf(stderr, "menus are read%s\n",
1654 R->h->menu_readonly ? "only" : "/write"); 1654 R->menu_readonly ? "only" : "/write");
1655#endif 1655#endif
1656 return; 1656 return;
1657 } 1657 }
1658#endif /* (MENUBAR_MAX > 1) */ 1658#endif /* (MENUBAR_MAX > 1) */
1659 1659
1704 switch (cmd) { 1704 switch (cmd) {
1705 case '+': /* add/replace existing menu or menuitem */ 1705 case '+': /* add/replace existing menu or menuitem */
1706 if (path[0] != '\0') { 1706 if (path[0] != '\0') {
1707 int len; 1707 int len;
1708 1708
1709 path = rxvt_menu_find_base(aR_ &(R->h->BuildMenu), path); 1709 path = rxvt_menu_find_base(aR_ &(R->BuildMenu), path);
1710 len = STRLEN(path); 1710 len = STRLEN(path);
1711 1711
1712 /* don't allow menus called `*' */ 1712 /* don't allow menus called `*' */
1713 if (path[0] == '*') { 1713 if (path[0] == '*') {
1714 rxvt_menu_clear(aR_ R->h->BuildMenu); 1714 rxvt_menu_clear(aR_ R->BuildMenu);
1715 break; 1715 break;
1716 } else if (len >= 2 && !STRCMP((path + len - 2), "/*")) { 1716 } else if (len >= 2 && !STRCMP((path + len - 2), "/*")) {
1717 path[len - 2] = '\0'; 1717 path[len - 2] = '\0';
1718 } 1718 }
1719 if (path[0] != '\0') 1719 if (path[0] != '\0')
1720 R->h->BuildMenu = rxvt_menu_add(aR_ R->h->BuildMenu, path); 1720 R->BuildMenu = rxvt_menu_add(aR_ R->BuildMenu, path);
1721 } 1721 }
1722 if (name != NULL && name[0] != '\0') 1722 if (name != NULL && name[0] != '\0')
1723 rxvt_menuitem_add(R->h->BuildMenu, 1723 rxvt_menuitem_add(R->BuildMenu,
1724 (STRCMP(name, SEPARATOR_NAME) ? name : ""), 1724 (STRCMP(name, SEPARATOR_NAME) ? name : ""),
1725 name2, str); 1725 name2, str);
1726 break; 1726 break;
1727 1727
1728 case '-': /* delete menu entry */ 1728 case '-': /* delete menu entry */
1729 if (!STRCMP(path, "/*") && (name == NULL || name[0] == '\0')) { 1729 if (!STRCMP(path, "/*") && (name == NULL || name[0] == '\0')) {
1730 rxvt_menubar_clear(aR); 1730 rxvt_menubar_clear(aR);
1731 R->h->BuildMenu = NULL; 1731 R->BuildMenu = NULL;
1732 rxvt_menubar_expose(aR); 1732 rxvt_menubar_expose(aR);
1733 break; 1733 break;
1734 } else if (path[0] != '\0') { 1734 } else if (path[0] != '\0') {
1735 int len; 1735 int len;
1736 menu_t *menu = R->h->BuildMenu; 1736 menu_t *menu = R->BuildMenu;
1737 1737
1738 path = rxvt_menu_find_base(aR_ &menu, path); 1738 path = rxvt_menu_find_base(aR_ &menu, path);
1739 len = STRLEN(path); 1739 len = STRLEN(path);
1740 1740
1741 /* submenu called `*' clears all menu items */ 1741 /* submenu called `*' clears all menu items */
1744 break; /* done */ 1744 break; /* done */
1745 } else if (len >= 2 && !STRCMP(&path[len - 2], "/*")) { 1745 } else if (len >= 2 && !STRCMP(&path[len - 2], "/*")) {
1746 /* done */ 1746 /* done */
1747 break; 1747 break;
1748 } else if (path[0] != '\0') { 1748 } else if (path[0] != '\0') {
1749 R->h->BuildMenu = NULL; 1749 R->BuildMenu = NULL;
1750 break; 1750 break;
1751 } else 1751 } else
1752 R->h->BuildMenu = menu; 1752 R->BuildMenu = menu;
1753 } 1753 }
1754 if (R->h->BuildMenu != NULL) { 1754 if (R->BuildMenu != NULL) {
1755 if (name == NULL || name[0] == '\0') 1755 if (name == NULL || name[0] == '\0')
1756 R->h->BuildMenu = rxvt_menu_delete(aR_ R->h->BuildMenu); 1756 R->BuildMenu = rxvt_menu_delete(aR_ R->BuildMenu);
1757 else { 1757 else {
1758 const char *n1; 1758 const char *n1;
1759 menuitem_t *item; 1759 menuitem_t *item;
1760 menu_t *BuildMenu = R->h->BuildMenu; 1760 menu_t *BuildMenu = R->BuildMenu;
1761 1761
1762 n1 = STRCMP(name, SEPARATOR_NAME) ? name : ""; 1762 n1 = STRCMP(name, SEPARATOR_NAME) ? name : "";
1763 item = rxvt_menuitem_find(BuildMenu, n1); 1763 item = rxvt_menuitem_find(BuildMenu, n1);
1764 if (item != NULL && item->entry.type != MenuSubMenu) { 1764 if (item != NULL && item->entry.type != MenuSubMenu) {
1765 rxvt_menuitem_free(aR_ BuildMenu, item); 1765 rxvt_menuitem_free(aR_ BuildMenu, item);
1793#ifdef MENU_SHADOW_IN 1793#ifdef MENU_SHADOW_IN
1794 state = -state; 1794 state = -state;
1795#endif 1795#endif
1796 switch (state) { 1796 switch (state) {
1797 case +1: 1797 case +1:
1798 top = R->h->topShadowGC; 1798 top = R->topShadowGC;
1799 bot = R->h->botShadowGC; 1799 bot = R->botShadowGC;
1800 break; /* SHADOW_OUT */ 1800 break; /* SHADOW_OUT */
1801 case -1: 1801 case -1:
1802 top = R->h->botShadowGC; 1802 top = R->botShadowGC;
1803 bot = R->h->topShadowGC; 1803 bot = R->topShadowGC;
1804 break; /* SHADOW_IN */ 1804 break; /* SHADOW_IN */
1805 default: 1805 default:
1806 top = bot = R->h->scrollbarGC; 1806 top = bot = R->scrollbarGC;
1807 break; /* neutral */ 1807 break; /* neutral */
1808 } 1808 }
1809 1809
1810 if (!R->h->Arrows_x) 1810 if (!R->Arrows_x)
1811 return; 1811 return;
1812 1812
1813 for (i = 0; i < NARROWS; i++) { 1813 for (i = 0; i < NARROWS; i++) {
1814 const int w = Width2Pixel(1); 1814 const int w = Width2Pixel(1);
1815 const int y = (menuBar_TotalHeight() - w) / 2; 1815 const int y = (menuBar_TotalHeight() - w) / 2;
1816 int x = R->h->Arrows_x + (5 * Width2Pixel(i)) / 4; 1816 int x = R->Arrows_x + (5 * Width2Pixel(i)) / 4;
1817 1817
1818 if (!name || name == Arrows[i].name) 1818 if (!name || name == Arrows[i].name)
1819 rxvt_Draw_Triangle(R->Xdisplay, R->menuBar.win, top, bot, x, y, w, 1819 rxvt_Draw_Triangle(R->Xdisplay, R->menuBar.win, top, bot, x, y, w,
1820 Arrows[i].name); 1820 Arrows[i].name);
1821 } 1821 }
1830 int x; 1830 int x;
1831 1831
1832 if (!menubar_visible(r) || R->menuBar.win == 0) 1832 if (!menubar_visible(r) || R->menuBar.win == 0)
1833 return; 1833 return;
1834 1834
1835 if (R->h->menubarGC == None) { 1835 if (R->menubarGC == None) {
1836 /* Create the graphics context */ 1836 /* Create the graphics context */
1837 XGCValues gcvalue; 1837 XGCValues gcvalue;
1838 1838
1839 gcvalue.font = R->TermWin.font->fid; 1839 gcvalue.font = R->TermWin.font->fid;
1840 1840
1841 gcvalue.foreground = (XDEPTH <= 2 ? R->PixColors[Color_fg] 1841 gcvalue.foreground = (XDEPTH <= 2 ? R->PixColors[Color_fg]
1842 : R->PixColors[Color_Black]); 1842 : R->PixColors[Color_Black]);
1843 R->h->menubarGC = XCreateGC(R->Xdisplay, R->menuBar.win, 1843 R->menubarGC = XCreateGC(R->Xdisplay, R->menuBar.win,
1844 GCForeground | GCFont, &gcvalue); 1844 GCForeground | GCFont, &gcvalue);
1845 1845
1846 } 1846 }
1847/* make sure the font is correct */ 1847/* make sure the font is correct */
1848 XSetFont(R->Xdisplay, R->h->menubarGC, R->TermWin.font->fid); 1848 XSetFont(R->Xdisplay, R->menubarGC, R->TermWin.font->fid);
1849 XSetFont(R->Xdisplay, R->h->botShadowGC, R->TermWin.font->fid); 1849 XSetFont(R->Xdisplay, R->botShadowGC, R->TermWin.font->fid);
1850 XClearWindow(R->Xdisplay, R->menuBar.win); 1850 XClearWindow(R->Xdisplay, R->menuBar.win);
1851 1851
1852 rxvt_menu_hide_all(aR); 1852 rxvt_menu_hide_all(aR);
1853 1853
1854 x = 0; 1854 x = 0;
1855 if (R->h->CurrentBar != NULL) { 1855 if (R->CurrentBar != NULL) {
1856 for (menu = R->h->CurrentBar->head; menu != NULL; menu = menu->next) { 1856 for (menu = R->CurrentBar->head; menu != NULL; menu = menu->next) {
1857 int len = menu->len; 1857 int len = menu->len;
1858 1858
1859 x = (menu->x + menu->len + HSPACE); 1859 x = (menu->x + menu->len + HSPACE);
1860 1860
1861#ifdef DEBUG_MENU_LAYOUT 1861#ifdef DEBUG_MENU_LAYOUT
1868 rxvt_drawbox_menubar(aR_ menu->x, len, +1); 1868 rxvt_drawbox_menubar(aR_ menu->x, len, +1);
1869#ifdef USE_XIM 1869#ifdef USE_XIM
1870 if (R->TermWin.fontset) 1870 if (R->TermWin.fontset)
1871 XmbDrawString(R->Xdisplay, 1871 XmbDrawString(R->Xdisplay,
1872 R->menuBar.win, R->TermWin.fontset, 1872 R->menuBar.win, R->TermWin.fontset,
1873 R->h->menubarGC, 1873 R->menubarGC,
1874 (Width2Pixel(menu->x) + Width2Pixel(HSPACE) / 2), 1874 (Width2Pixel(menu->x) + Width2Pixel(HSPACE) / 2),
1875 menuBar_height() - SHADOW, menu->name, len); 1875 menuBar_height() - SHADOW, menu->name, len);
1876 else 1876 else
1877#endif 1877#endif
1878 XDrawString(R->Xdisplay, R->menuBar.win, R->h->menubarGC, 1878 XDrawString(R->Xdisplay, R->menuBar.win, R->menubarGC,
1879 (Width2Pixel(menu->x) + Width2Pixel(HSPACE) / 2), 1879 (Width2Pixel(menu->x) + Width2Pixel(HSPACE) / 2),
1880 menuBar_height() - SHADOW, menu->name, len); 1880 menuBar_height() - SHADOW, menu->name, len);
1881 1881
1882 if (x >= R->TermWin.ncol) 1882 if (x >= R->TermWin.ncol)
1883 break; 1883 break;
1884 } 1884 }
1885 } 1885 }
1886 rxvt_drawbox_menubar(aR_ x, R->TermWin.ncol, (R->h->CurrentBar ? +1 : -1)); 1886 rxvt_drawbox_menubar(aR_ x, R->TermWin.ncol, (R->CurrentBar ? +1 : -1));
1887 1887
1888/* add the menuBar title, if it exists and there's plenty of room */ 1888/* add the menuBar title, if it exists and there's plenty of room */
1889 R->h->Arrows_x = 0; 1889 R->Arrows_x = 0;
1890 if (x < R->TermWin.ncol) { 1890 if (x < R->TermWin.ncol) {
1891 const char *str; 1891 const char *str;
1892 int ncol; 1892 int ncol;
1893 unsigned int len; 1893 unsigned int len;
1894 char title[256]; 1894 char title[256];
1895 1895
1896 ncol = (int)R->TermWin.ncol; 1896 ncol = (int)R->TermWin.ncol;
1897 if (x < (ncol - (NARROWS + 1))) { 1897 if (x < (ncol - (NARROWS + 1))) {
1898 ncol -= (NARROWS + 1); 1898 ncol -= (NARROWS + 1);
1899 R->h->Arrows_x = Width2Pixel(ncol); 1899 R->Arrows_x = Width2Pixel(ncol);
1900 } 1900 }
1901 rxvt_draw_Arrows(aR_ 0, +1); 1901 rxvt_draw_Arrows(aR_ 0, +1);
1902 1902
1903 str = (R->h->CurrentBar 1903 str = (R->CurrentBar
1904 && R->h->CurrentBar->title) ? R->h->CurrentBar->title : "%n-%v"; 1904 && R->CurrentBar->title) ? R->CurrentBar->title : "%n-%v";
1905 for (len = 0; str[0] && len < sizeof(title) - 1; str++) { 1905 for (len = 0; str[0] && len < sizeof(title) - 1; str++) {
1906 const char *s = NULL; 1906 const char *s = NULL;
1907 1907
1908 switch (str[0]) { 1908 switch (str[0]) {
1909 case '%': 1909 case '%':
1910 str++; 1910 str++;
1911 switch (str[0]) { 1911 switch (str[0]) {
1912 case 'n': 1912 case 'n':
1913 s = R->h->rs[Rs_name]; 1913 s = R->rs[Rs_name];
1914 break; /* resource name */ 1914 break; /* resource name */
1915 case 'v': 1915 case 'v':
1916 s = VERSION; 1916 s = VERSION;
1917 break; /* version number */ 1917 break; /* version number */
1918 case '%': 1918 case '%':
1935 if (len > 0 && ncol >= 0) { 1935 if (len > 0 && ncol >= 0) {
1936#ifdef USE_XIM 1936#ifdef USE_XIM
1937 if (R->TermWin.fontset) 1937 if (R->TermWin.fontset)
1938 XmbDrawString(R->Xdisplay, 1938 XmbDrawString(R->Xdisplay,
1939 R->menuBar.win, R->TermWin.fontset, 1939 R->menuBar.win, R->TermWin.fontset,
1940 R->h->menubarGC, 1940 R->menubarGC,
1941 Width2Pixel(x) + Width2Pixel(ncol + HSPACE) / 2, 1941 Width2Pixel(x) + Width2Pixel(ncol + HSPACE) / 2,
1942 menuBar_height() - SHADOW, title, len); 1942 menuBar_height() - SHADOW, title, len);
1943 else 1943 else
1944#endif 1944#endif
1945 XDrawString(R->Xdisplay, R->menuBar.win, R->h->menubarGC, 1945 XDrawString(R->Xdisplay, R->menuBar.win, R->menubarGC,
1946 Width2Pixel(x) + Width2Pixel(ncol + HSPACE) / 2, 1946 Width2Pixel(x) + Width2Pixel(ncol + HSPACE) / 2,
1947 menuBar_height() - SHADOW, title, len); 1947 menuBar_height() - SHADOW, title, len);
1948 } 1948 }
1949 } 1949 }
1950} 1950}
1976int 1976int
1977rxvt_menu_select(pR_ XButtonEvent *ev) 1977rxvt_menu_select(pR_ XButtonEvent *ev)
1978{ 1978{
1979 menuitem_t *thisitem, *item = NULL; 1979 menuitem_t *thisitem, *item = NULL;
1980 int this_y, y; 1980 int this_y, y;
1981 menu_t *ActiveMenu = R->h->ActiveMenu; 1981 menu_t *ActiveMenu = R->ActiveMenu;
1982 1982
1983 Window unused_root, unused_child; 1983 Window unused_root, unused_child;
1984 int unused_root_x, unused_root_y; 1984 int unused_root_x, unused_root_y;
1985 unsigned int unused_mask; 1985 unsigned int unused_mask;
1986 1986
2098 x = ev->x + (ActiveMenu->parent 2098 x = ev->x + (ActiveMenu->parent
2099 ? ActiveMenu->x 2099 ? ActiveMenu->x
2100 : Width2Pixel(ActiveMenu->x)); 2100 : Width2Pixel(ActiveMenu->x));
2101 2101
2102 if (x >= item->entry.submenu.menu->x) { 2102 if (x >= item->entry.submenu.menu->x) {
2103 R->h->ActiveMenu = item->entry.submenu.menu; 2103 R->ActiveMenu = item->entry.submenu.menu;
2104 rxvt_menu_show(aR); 2104 rxvt_menu_show(aR);
2105 return 1; 2105 return 1;
2106 } 2106 }
2107 } 2107 }
2108 } 2108 }
2114rxvt_menubar_select(pR_ XButtonEvent *ev) 2114rxvt_menubar_select(pR_ XButtonEvent *ev)
2115{ 2115{
2116 menu_t *menu = NULL; 2116 menu_t *menu = NULL;
2117 2117
2118/* determine the pulldown menu corresponding to the X index */ 2118/* determine the pulldown menu corresponding to the X index */
2119 if (ev->y >= 0 && ev->y <= menuBar_height() && R->h->CurrentBar != NULL) { 2119 if (ev->y >= 0 && ev->y <= menuBar_height() && R->CurrentBar != NULL) {
2120 for (menu = R->h->CurrentBar->head; menu != NULL; menu = menu->next) { 2120 for (menu = R->CurrentBar->head; menu != NULL; menu = menu->next) {
2121 int x = Width2Pixel(menu->x); 2121 int x = Width2Pixel(menu->x);
2122 int w = Width2Pixel(menu->len + HSPACE); 2122 int w = Width2Pixel(menu->len + HSPACE);
2123 2123
2124 if ((ev->x >= x && ev->x < x + w)) 2124 if ((ev->x >= x && ev->x < x + w))
2125 break; 2125 break;
2129 case ButtonRelease: 2129 case ButtonRelease:
2130 rxvt_menu_hide_all(aR); 2130 rxvt_menu_hide_all(aR);
2131 break; 2131 break;
2132 2132
2133 case ButtonPress: 2133 case ButtonPress:
2134 if (menu == NULL && R->h->Arrows_x && ev->x >= R->h->Arrows_x) { 2134 if (menu == NULL && R->Arrows_x && ev->x >= R->Arrows_x) {
2135 int i; 2135 int i;
2136 2136
2137 for (i = 0; i < NARROWS; i++) { 2137 for (i = 0; i < NARROWS; i++) {
2138 if (ev->x >= (R->h->Arrows_x + (Width2Pixel(4 * i + i)) / 4) 2138 if (ev->x >= (R->Arrows_x + (Width2Pixel(4 * i + i)) / 4)
2139 && ev->x < (R->h->Arrows_x 2139 && ev->x < (R->Arrows_x
2140 + (Width2Pixel(4 * i + i + 4)) / 4)) { 2140 + (Width2Pixel(4 * i + i + 4)) / 4)) {
2141 rxvt_draw_Arrows(aR_ Arrows[i].name, -1); 2141 rxvt_draw_Arrows(aR_ Arrows[i].name, -1);
2142 { 2142 {
2143#ifdef HAVE_NANOSLEEP 2143#ifdef HAVE_NANOSLEEP
2144 struct timespec rqt; 2144 struct timespec rqt;
2157 } 2157 }
2158 rxvt_draw_Arrows(aR_ Arrows[i].name, +1); 2158 rxvt_draw_Arrows(aR_ Arrows[i].name, +1);
2159#ifdef DEBUG_MENUARROWS 2159#ifdef DEBUG_MENUARROWS
2160 fprintf(stderr, "'%c': ", Arrows[i].name); 2160 fprintf(stderr, "'%c': ", Arrows[i].name);
2161 2161
2162 if (R->h->CurrentBar == NULL 2162 if (R->CurrentBar == NULL
2163 || (R->h->CurrentBar->arrows[i].type != MenuAction 2163 || (R->CurrentBar->arrows[i].type != MenuAction
2164 && R->h->CurrentBar->arrows[i].type != 2164 && R->CurrentBar->arrows[i].type !=
2165 MenuTerminalAction)) { 2165 MenuTerminalAction)) {
2166 if (Arrows[i].str != NULL && Arrows[i].str[0]) 2166 if (Arrows[i].str != NULL && Arrows[i].str[0])
2167 fprintf(stderr, "(default) \\033%s\n", 2167 fprintf(stderr, "(default) \\033%s\n",
2168 &(Arrows[i].str[2])); 2168 &(Arrows[i].str[2]));
2169 } else { 2169 } else {
2170 fprintf(stderr, "%s\n", 2170 fprintf(stderr, "%s\n",
2171 R->h->CurrentBar->arrows[i].str); 2171 R->CurrentBar->arrows[i].str);
2172 } 2172 }
2173#else /* DEBUG_MENUARROWS */ 2173#else /* DEBUG_MENUARROWS */
2174 if (R->h->CurrentBar == NULL 2174 if (R->CurrentBar == NULL
2175 || rxvt_action_dispatch(r, 2175 || rxvt_action_dispatch(r,
2176 &(R->h->CurrentBar->arrows[i])) 2176 &(R->CurrentBar->arrows[i]))
2177 ) { 2177 ) {
2178 if (Arrows[i].str != NULL && Arrows[i].str[0] != 0) 2178 if (Arrows[i].str != NULL && Arrows[i].str[0] != 0)
2179 rxvt_tt_write(aR_ (Arrows[i].str + 1), 2179 rxvt_tt_write(aR_ (Arrows[i].str + 1),
2180 Arrows[i].str[0]); 2180 Arrows[i].str[0]);
2181 } 2181 }
2188 2188
2189 default: 2189 default:
2190 /* 2190 /*
2191 * press menubar or move to a new entry 2191 * press menubar or move to a new entry
2192 */ 2192 */
2193 if (menu != NULL && menu != R->h->ActiveMenu) { 2193 if (menu != NULL && menu != R->ActiveMenu) {
2194 rxvt_menu_hide_all(aR); /* pop down old menu */ 2194 rxvt_menu_hide_all(aR); /* pop down old menu */
2195 R->h->ActiveMenu = menu; 2195 R->ActiveMenu = menu;
2196 rxvt_menu_show(aR); /* pop up new menu */ 2196 rxvt_menu_show(aR); /* pop up new menu */
2197 } 2197 }
2198 break; 2198 break;
2199 } 2199 }
2200} 2200}
2220 2220
2221 case MotionNotify: 2221 case MotionNotify:
2222 while (XCheckTypedWindowEvent(R->Xdisplay, R->TermWin.parent[0], 2222 while (XCheckTypedWindowEvent(R->Xdisplay, R->TermWin.parent[0],
2223 MotionNotify, (XEvent *) ev)) ; 2223 MotionNotify, (XEvent *) ev)) ;
2224 2224
2225 if (R->h->ActiveMenu) 2225 if (R->ActiveMenu)
2226 while (rxvt_menu_select(aR_ ev)) ; 2226 while (rxvt_menu_select(aR_ ev)) ;
2227 else 2227 else
2228 ev->y = -1; 2228 ev->y = -1;
2229 if (ev->y < 0) { 2229 if (ev->y < 0) {
2230 Window unused_root, unused_child; 2230 Window unused_root, unused_child;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines