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.9 by pcg, Tue Feb 24 00:02:44 2004 UTC vs.
Revision 1.10 by pcg, Tue Feb 24 16:25:44 2004 UTC

21 * refer.html (or refer.txt) contains up-to-date documentation. The 21 * refer.html (or refer.txt) contains up-to-date documentation. The
22 * summary that appears at the end of this file was taken from there. 22 * summary that appears at the end of this file was taken from there.
23 *----------------------------------------------------------------------*/ 23 *----------------------------------------------------------------------*/
24 24
25#include "../config.h" /* NECESSARY */ 25#include "../config.h" /* NECESSARY */
26
27#include <stdlib.h>
28
26#include "rxvt.h" /* NECESSARY */ 29#include "rxvt.h" /* NECESSARY */
27#ifdef MENUBAR 30#ifdef MENUBAR
28#include "version.h" 31#include "version.h"
29#include "menubar.h" 32#include "menubar.h"
30#include "menubar.intpro" /* PROTOS for internal routines */ 33#include "menubar.intpro" /* PROTOS for internal routines */
43 { 'd', "\003\033[B" }, 46 { 'd', "\003\033[B" },
44 { 'r', "\003\033[C" } 47 { 'r', "\003\033[C" }
45 }; 48 };
46 49
47/*}}} */ 50/*}}} */
51
52static void
53draw_string (rxvt_drawable &d, GC gc, rxvt_fontset *fs, int x, int y, char *str, int len)
54{
55 mbstate mbs;
56
57 while (len)
58 {
59 wchar_t w;
60 int l = mbrtowc (&w, str, len, mbs);
61
62 if (l <= 0)
63 break;
64
65 len -= l;
66 str += l;
67
68 rxvt_font *font = (*fs)[fs->find_font (w)];
69 text_t ch = w;
70 font->draw (d, x, y, &ch, 1, Color_bg, Color_scroll);
71
72 x += font->width * wcwidth (w);
73 }
74}
48 75
49/* 76/*
50 * find an item called NAME in MENU 77 * find an item called NAME in MENU
51 */ 78 */
52menuitem_t * 79menuitem_t *
491 { 518 {
492 p++; 519 p++;
493 if (*p == '/') 520 if (*p == '/')
494 path = p; 521 path = p;
495 } 522 }
523
496 if (path[0] == '/') 524 if (path[0] == '/')
497 { 525 {
498 path++; 526 path++;
499 *menu = NULL; 527 *menu = NULL;
500 } 528 }
529
501 while ((p = STRCHR (path, '/')) != NULL) 530 while ((p = STRCHR (path, '/')) != NULL)
502 { 531 {
503 p[0] = '\0'; 532 p[0] = '\0';
504 if (path[0] == '\0') 533 if (path[0] == '\0')
505 return NULL; 534 return NULL;
535
506 if (!STRCMP (path, DOT)) 536 if (!STRCMP (path, DOT))
507 { 537 {
508 /* nothing to do */ 538 /* nothing to do */
509 } 539 }
510 else if (!STRCMP (path, DOTS)) 540 else if (!STRCMP (path, DOTS))
523 } 553 }
524 554
525 path = (p + 1); 555 path = (p + 1);
526 } 556 }
527 } 557 }
558
528 if (!STRCMP (path, DOTS)) 559 if (!STRCMP (path, DOTS))
529 { 560 {
530 path += STRLEN (DOTS); 561 path += STRLEN (DOTS);
531 if (*menu != NULL) 562 if (*menu != NULL)
532 *menu = (*menu)->parent; 563 *menu = (*menu)->parent;
533 return path; 564 return path;
534 } 565 }
566
535 /* find this menu */ 567 /* find this menu */
536 if (*menu == NULL) 568 if (*menu == NULL)
537 { 569 {
538 for (m = CurrentBar->tail; m != NULL; m = m->prev) 570 for (m = CurrentBar->tail; m != NULL; m = m->prev)
539 {
540 if (!STRCMP (path, m->name)) 571 if (!STRCMP (path, m->name))
541 break; 572 break;
542 }
543 } 573 }
544 else 574 else
545 { 575 {
546 /* find this menu */ 576 /* find this menu */
547 for (item = (*menu)->tail; item != NULL; item = item->prev) 577 for (item = (*menu)->tail; item != NULL; item = item->prev)
552 m = (item->entry.submenu.menu); 582 m = (item->entry.submenu.menu);
553 break; 583 break;
554 } 584 }
555 } 585 }
556 } 586 }
587
557 if (m != NULL) 588 if (m != NULL)
558 { 589 {
559 *menu = m; 590 *menu = m;
560 path += STRLEN (path); 591 path += STRLEN (path);
561 } 592 }
593
562 return path; 594 return path;
563} 595}
564 596
565/* 597/*
566 * delete this entire menu 598 * delete this entire menu
568menu_t * 600menu_t *
569rxvt_term::menu_delete (menu_t *menu) 601rxvt_term::menu_delete (menu_t *menu)
570{ 602{
571 menu_t *parent = NULL, *prev, *next; 603 menu_t *parent = NULL, *prev, *next;
572 menuitem_t *item; 604 menuitem_t *item;
573 bar_t *CurrentBar = CurrentBar;
574 605
575#ifdef DEBUG_STRICT 606#ifdef DEBUG_STRICT
576 assert (CurrentBar != NULL); 607 assert (CurrentBar != NULL);
577#endif 608#endif
578 609
618 } 649 }
619 650
620 item = menu->tail; 651 item = menu->tail;
621 while (item != NULL) 652 while (item != NULL)
622 { 653 {
623 menuitem_t *p = item->prev; 654 menuitem_t *p = item->prev;
624 655
625 menuitem_free (menu, item); 656 menuitem_free (menu, item);
626 item = p; 657 item = p;
627 } 658 }
628 659
629 if (menu->name != NULL)
630 free (menu->name); 660 free (menu->name);
631 free (menu); 661 free (menu);
632 662
633 return parent; 663 return parent;
634} 664}
635 665
636menu_t * 666menu_t *
637rxvt_term::menu_add (menu_t *parent, char *path) 667rxvt_term::menu_add (menu_t *parent, char *path)
638{ 668{
639 menu_t *menu; 669 menu_t *menu;
640 bar_t *CurrentBar = CurrentBar;
641 670
642#ifdef DEBUG_STRICT 671#ifdef DEBUG_STRICT
643 assert (CurrentBar != NULL); 672 assert (CurrentBar != NULL);
644#endif 673#endif
645 674
646 if (STRCHR (path, '/') != NULL) 675 if (STRCHR (path, '/') != NULL)
647 { 676 {
648 char *p; 677 char *p;
649 678
650 if (path[0] == '/') 679 if (path[0] == '/')
651 { 680 {
652 /* shouldn't happen */ 681 /* shouldn't happen */
653 path++; 682 path++;
681 /* initialize head/tail */ 710 /* initialize head/tail */
682 menu->head = menu->tail = NULL; 711 menu->head = menu->tail = NULL;
683 menu->prev = menu->next = NULL; 712 menu->prev = menu->next = NULL;
684 713
685 menu->win = None; 714 menu->win = None;
715 menu->drawable = 0;
686 menu->x = menu->y = menu->w = menu->h = 0; 716 menu->x = menu->y = menu->w = menu->h = 0;
687 menu->item = NULL; 717 menu->item = NULL;
688 718
689 /* add to tail of list */ 719 /* add to tail of list */
690 if (parent == NULL) 720 if (parent == NULL)
779 w = Height2Pixel (1) - 2 * SHADOW; 809 w = Height2Pixel (1) - 2 * SHADOW;
780 810
781 x -= SHADOW + (3 * w / 2); 811 x -= SHADOW + (3 * w / 2);
782 y += SHADOW * 3; 812 y += SHADOW * 3;
783 813
784 rxvt_Draw_Triangle (display->display, ActiveMenu->win, top, bot, x, y, w, 814 rxvt_Draw_Triangle (display->display, ActiveMenu->win, top, bot, x, y, w, 'r');
785 'r');
786} 815}
787 816
788void 817void
789rxvt_term::drawbox_menuitem (int y, int state) 818rxvt_term::drawbox_menuitem (int y, int state)
790{ 819{
822 if (menu == NULL) 851 if (menu == NULL)
823 { 852 {
824 fprintf (stderr, "Top Level menu\n"); 853 fprintf (stderr, "Top Level menu\n");
825 return; 854 return;
826 } 855 }
856
827 fprintf (stderr, "menu %s ", menu->name); 857 fprintf (stderr, "menu %s ", menu->name);
828 if (menu->parent != NULL) 858 if (menu->parent != NULL)
829 { 859 {
830 menuitem_t *item; 860 menuitem_t *item;
831 861
835 && item->entry.submenu.menu == menu) 865 && item->entry.submenu.menu == menu)
836 { 866 {
837 break; 867 break;
838 } 868 }
839 } 869 }
870
840 if (item == NULL) 871 if (item == NULL)
841 { 872 {
842 fprintf (stderr, "is an orphan!\n"); 873 fprintf (stderr, "is an orphan!\n");
843 return; 874 return;
844 } 875 }
845 } 876 }
877
846 fprintf (stderr, "\n"); 878 fprintf (stderr, "\n");
847 rxvt_print_menu_ancestors (menu->parent); 879 rxvt_print_menu_ancestors (menu->parent);
848} 880}
849 881
850void 882void
893 925
894/* pop up/down the current menu and redraw the menuBar button */ 926/* pop up/down the current menu and redraw the menuBar button */
895void 927void
896rxvt_term::menu_show () 928rxvt_term::menu_show ()
897{ 929{
898 int x, y, xright; 930 int x, y, xright;
899 menu_t *ActiveMenu = ActiveMenu;
900 menuitem_t *item; 931 menuitem_t *item;
901 932
902 if (ActiveMenu == NULL) 933 if (ActiveMenu == NULL)
903 return; 934 return;
904 935
905 x = ActiveMenu->x; 936 x = ActiveMenu->x;
920 for (h = 0, item = ActiveMenu->head; item != NULL; item = item->next) 951 for (h = 0, item = ActiveMenu->head; item != NULL; item = item->next)
921 h += isSeparator (item->name) ? HEIGHT_SEPARATOR 952 h += isSeparator (item->name) ? HEIGHT_SEPARATOR
922 : HEIGHT_TEXT + 2 * SHADOW; 953 : HEIGHT_TEXT + 2 * SHADOW;
923 ActiveMenu->h = h + 2 * SHADOW; 954 ActiveMenu->h = h + 2 * SHADOW;
924 } 955 }
956
925 if (ActiveMenu->win == None) 957 if (ActiveMenu->win == None)
926 { 958 {
927 ActiveMenu->win = XCreateSimpleWindow (display->display, TermWin.vt, 959 ActiveMenu->win = XCreateSimpleWindow (display->display, TermWin.vt,
928 x, ActiveMenu->y, 960 x, ActiveMenu->y,
929 ActiveMenu->w, ActiveMenu->h, 961 ActiveMenu->w, ActiveMenu->h,
930 0, 962 0,
931 PixColors[Color_fg], 963 PixColors[Color_fg],
932 PixColors[Color_scroll]); 964 PixColors[Color_scroll]);
965 ActiveMenu->drawable = new rxvt_drawable (display, ActiveMenu->win);
933 XMapWindow (display->display, ActiveMenu->win); 966 XMapWindow (display->display, ActiveMenu->win);
934 } 967 }
968
935 rxvt_Draw_Shadow (display->display, ActiveMenu->win, 969 rxvt_Draw_Shadow (display->display, ActiveMenu->win,
936 topShadowGC, botShadowGC, 970 topShadowGC, botShadowGC,
937 0, 0, ActiveMenu->w, ActiveMenu->h); 971 0, 0, ActiveMenu->w, ActiveMenu->h);
938 972
939 /* determine the correct right-alignment */ 973 /* determine the correct right-alignment */
941 if (item->len2 > xright) 975 if (item->len2 > xright)
942 xright = item->len2; 976 xright = item->len2;
943 977
944 for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next) 978 for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next)
945 { 979 {
946 const int xoff = (SHADOW + Width2Pixel (HSPACE) / 2); 980 const int xoff = (SHADOW + Width2Pixel (HSPACE) / 2);
947 register int h; 981 register int h;
948 GC gc = menubarGC; 982 GC gc = menubarGC;
949 983
950 if (isSeparator (item->name)) 984 if (isSeparator (item->name))
951 { 985 {
952 rxvt_Draw_Shadow (display->display, ActiveMenu->win, 986 rxvt_Draw_Shadow (display->display, ActiveMenu->win,
953 topShadowGC, botShadowGC, 987 topShadowGC, botShadowGC,
959 { 993 {
960 char *name = item->name; 994 char *name = item->name;
961 int len = item->len; 995 int len = item->len;
962 996
963 if (item->entry.type == MenuLabel) 997 if (item->entry.type == MenuLabel)
964 {
965 gc = botShadowGC; 998 gc = botShadowGC;
966 }
967 else if (item->entry.type == MenuSubMenu) 999 else if (item->entry.type == MenuSubMenu)
968 { 1000 {
969 int x1, y1; 1001 int x1, y1;
970 menuitem_t *it; 1002 menuitem_t *it;
971 menu_t *menu = item->entry.submenu.menu; 1003 menu_t *menu = item->entry.submenu.menu;
1003 } 1035 }
1004 else if (item->name2 && !STRCMP (name, item->name2)) 1036 else if (item->name2 && !STRCMP (name, item->name2))
1005 name = NULL; 1037 name = NULL;
1006 1038
1007 if (len && name) 1039 if (len && name)
1008 draw_string (display->display, ActiveMenu->win, gc, xoff, 1040 draw_string (*ActiveMenu->drawable, gc, TermWin.fontset,
1009 2 * SHADOW + y + TermWin.font->ascent + 1,
1010 name, len); 1041 xoff, 2 * SHADOW + y, name, len);
1011 1042
1012 len = item->len2; 1043 len = item->len2;
1013 name = item->name2; 1044 name = item->name2;
1014 1045
1015 if (len && name) 1046 if (len && name)
1016 draw_string (display->display, ActiveMenu->win, gc, 1047 draw_string (*ActiveMenu->drawable, gc, TermWin.fontset,
1017 ActiveMenu->w - (xoff + Width2Pixel (xright)), 1048 ActiveMenu->w - (xoff + Width2Pixel (xright)), 2 * SHADOW + y, name, len);
1018 2 * SHADOW + y + TermWin.font->ascent + 1,
1019 name, len);
1020 1049
1021 h = HEIGHT_TEXT + 2 * SHADOW; 1050 h = HEIGHT_TEXT + 2 * SHADOW;
1022 } 1051 }
1023 y += h; 1052 y += h;
1024 } 1053 }
1025} 1054}
1026 1055
1027void 1056void
1028rxvt_term::menu_display (void (rxvt_term::*update) ()) 1057rxvt_term::menu_display (void (rxvt_term::*update) ())
1029{ 1058{
1030 menu_t *ActiveMenu = ActiveMenu;
1031
1032 if (ActiveMenu == NULL) 1059 if (ActiveMenu == NULL)
1033 return; 1060 return;
1061
1062 delete ActiveMenu->drawable;
1034 if (ActiveMenu->win != None) 1063 if (ActiveMenu->win != None)
1035 XDestroyWindow (display->display, ActiveMenu->win); 1064 XDestroyWindow (display->display, ActiveMenu->win);
1036 ActiveMenu->win = None; 1065 ActiveMenu->win = None;
1037 ActiveMenu->item = NULL; 1066 ActiveMenu->item = NULL;
1038 1067
1039 if (ActiveMenu->parent == NULL) 1068 if (ActiveMenu->parent == NULL)
1040 drawbox_menubar (ActiveMenu->x, ActiveMenu->len, +1); 1069 drawbox_menubar (ActiveMenu->x, ActiveMenu->len, +1);
1070
1041 ActiveMenu = ActiveMenu->parent; 1071 ActiveMenu = ActiveMenu->parent;
1042 (this->*update) (); 1072 (this->*update) ();
1043} 1073}
1044 1074
1045void 1075void
1057void 1087void
1058rxvt_term::menu_clear (menu_t *menu) 1088rxvt_term::menu_clear (menu_t *menu)
1059{ 1089{
1060 if (menu != NULL) 1090 if (menu != NULL)
1061 { 1091 {
1062 menuitem_t *item = menu->tail; 1092 menuitem_t *item = menu->tail;
1063 1093
1064 while (item != NULL) 1094 while (item != NULL)
1065 { 1095 {
1066 menuitem_free (menu, item); 1096 menuitem_free (menu, item);
1067 /* it didn't get freed ... why? */ 1097 /* it didn't get freed ... why? */
1074} 1104}
1075 1105
1076void 1106void
1077rxvt_term::menubar_clear () 1107rxvt_term::menubar_clear ()
1078{ 1108{
1079 bar_t *CurrentBar = CurrentBar;
1080
1081 if (CurrentBar != NULL) 1109 if (CurrentBar != NULL)
1082 { 1110 {
1083 menu_t *menu = CurrentBar->tail; 1111 menu_t *menu = CurrentBar->tail;
1084 1112
1085 while (menu != NULL) 1113 while (menu != NULL)
1086 { 1114 {
1087 menu_t *prev = menu->prev; 1115 menu_t *prev = menu->prev;
1088 1116
1089 menu_delete (menu); 1117 menu_delete (menu);
1090 menu = prev; 1118 menu = prev;
1091 } 1119 }
1092 CurrentBar->head = CurrentBar->tail = NULL; 1120 CurrentBar->head = CurrentBar->tail = NULL;
1094 if (CurrentBar->title) 1122 if (CurrentBar->title)
1095 { 1123 {
1096 free (CurrentBar->title); 1124 free (CurrentBar->title);
1097 CurrentBar->title = NULL; 1125 CurrentBar->title = NULL;
1098 } 1126 }
1127
1099 menuarrow_free (0); /* remove all arrow functions */ 1128 menuarrow_free (0); /* remove all arrow functions */
1100 } 1129 }
1130
1101 ActiveMenu = NULL; 1131 ActiveMenu = NULL;
1102} 1132}
1103 1133
1104#if (MENUBAR_MAX > 1) 1134#if (MENUBAR_MAX > 1)
1105/* find if menu already exists */ 1135/* find if menu already exists */
1106bar_t * 1136bar_t *
1107rxvt_term::menubar_find (const char *name) 1137rxvt_term::menubar_find (const char *name)
1108{ 1138{
1109 bar_t *bar = CurrentBar; 1139 bar_t *bar = CurrentBar;
1110 1140
1111#ifdef DEBUG_MENUBAR_STACKING 1141#ifdef DEBUG_MENUBAR_STACKING
1112 fprintf (stderr, "looking for [menu:%s] ...", name ? name : " (nil)"); 1142 fprintf (stderr, "looking for [menu:%s] ...", name ? name : " (nil)");
1113#endif 1143#endif
1114 if (bar == NULL || name == NULL) 1144 if (bar == NULL || name == NULL)
1138} 1168}
1139 1169
1140int 1170int
1141rxvt_term::menubar_push (const char *name) 1171rxvt_term::menubar_push (const char *name)
1142{ 1172{
1143 int ret = 1; 1173 int ret = 1;
1144 bar_t *bar; 1174 bar_t *bar;
1145 1175
1146 if (CurrentBar == NULL) 1176 if (CurrentBar == NULL)
1147 { 1177 {
1148 /* allocate first one */ 1178 /* allocate first one */
1149 bar = (bar_t *) rxvt_malloc (sizeof (bar_t)); 1179 bar = (bar_t *) rxvt_malloc (sizeof (bar_t));
1197 Nbars++; 1227 Nbars++;
1198 } 1228 }
1199 CurrentBar = bar; 1229 CurrentBar = bar;
1200 1230
1201 } 1231 }
1232
1202 menubar_clear (); 1233 menubar_clear ();
1203 } 1234 }
1204 } 1235 }
1205 1236
1206 /* give menubar this name */ 1237 /* give menubar this name */
1251} 1282}
1252 1283
1253void 1284void
1254rxvt_action_decode (FILE *fp, action_t *act) 1285rxvt_action_decode (FILE *fp, action_t *act)
1255{ 1286{
1256 unsigned char *str; 1287 unsigned char *str;
1257 short len; 1288 short len;
1258 1289
1259 if (act == NULL || (len = act->len) == 0 || (str = act->str) == NULL) 1290 if (act == NULL || (len = act->len) == 0 || (str = act->str) == NULL)
1260 return; 1291 return;
1261 1292
1262 if (act->type == MenuTerminalAction) 1293 if (act->type == MenuTerminalAction)
1285 str++; 1316 str++;
1286 len--; 1317 len--;
1287 break; 1318 break;
1288 } 1319 }
1289 } 1320 }
1321
1290 /* 1322 /*
1291 * control character form is preferred, since backslash-escaping 1323 * control character form is preferred, since backslash-escaping
1292 * can be really ugly looking when the backslashes themselves also 1324 * can be really ugly looking when the backslashes themselves also
1293 * have to be escaped to avoid Shell (or whatever scripting 1325 * have to be escaped to avoid Shell (or whatever scripting
1294 * language) interpretation 1326 * language) interpretation
1320 fprintf (fp, "\\%o", ch); 1352 fprintf (fp, "\\%o", ch);
1321 else 1353 else
1322 fprintf (fp, "%c", ch); 1354 fprintf (fp, "%c", ch);
1323 break; 1355 break;
1324 } 1356 }
1357
1325 len--; 1358 len--;
1326 } 1359 }
1360
1327 fprintf (fp, "\n"); 1361 fprintf (fp, "\n");
1328} 1362}
1329 1363
1330void 1364void
1331rxvt_menu_dump (FILE *fp, menu_t *menu) 1365rxvt_menu_dump (FILE *fp, menu_t *menu)
1437 char *p, *file, *tag = NULL; 1471 char *p, *file, *tag = NULL;
1438 1472
1439 file = (char *)rxvt_File_find (filename, ".menu", rs[Rs_path]); 1473 file = (char *)rxvt_File_find (filename, ".menu", rs[Rs_path]);
1440 if (file == NULL) 1474 if (file == NULL)
1441 return; 1475 return;
1476
1442 fp = fopen (file, "rb"); 1477 fp = fopen (file, "rb");
1443 free (file); 1478 free (file);
1444 if (fp == NULL) 1479 if (fp == NULL)
1445 return; 1480 return;
1446 1481
1552 * user interface for building/deleting and otherwise managing menus 1587 * user interface for building/deleting and otherwise managing menus
1553 */ 1588 */
1554void 1589void
1555rxvt_term::menubar_dispatch (char *str) 1590rxvt_term::menubar_dispatch (char *str)
1556{ 1591{
1557 int n, cmd; 1592 int n, cmd;
1558 char *path, *name, *name2; 1593 char *path, *name, *name2;
1559 1594
1560 if (menubar_visible () && ActiveMenu != NULL) 1595 if (menubar_visible () && ActiveMenu != NULL)
1561 menubar_expose (); 1596 menubar_expose ();
1562 else 1597 else
1563 ActiveMenu = NULL; 1598 ActiveMenu = NULL;
1974 if (!Arrows_x) 2009 if (!Arrows_x)
1975 return; 2010 return;
1976 2011
1977 for (i = 0; i < NARROWS; i++) 2012 for (i = 0; i < NARROWS; i++)
1978 { 2013 {
1979 const int w = Width2Pixel (1); 2014 const int w = Width2Pixel (1);
1980 const int y = (menuBar_TotalHeight () - w) / 2; 2015 const int y = (menuBar_TotalHeight () - w) / 2;
1981 int x = Arrows_x + (5 * Width2Pixel (i)) / 4; 2016 int x = Arrows_x + (5 * Width2Pixel (i)) / 4;
1982 2017
1983 if (!name || name == Arrows[i].name) 2018 if (!name || name == Arrows[i].name)
1984 rxvt_Draw_Triangle (display->display, menuBar.win, top, bot, x, y, w, 2019 rxvt_Draw_Triangle (display->display, menuBar.win, top, bot, x, y, w,
1985 Arrows[i].name); 2020 Arrows[i].name);
1986 } 2021 }
1988} 2023}
1989 2024
1990void 2025void
1991rxvt_term::menubar_expose () 2026rxvt_term::menubar_expose ()
1992{ 2027{
1993 menu_t *menu; 2028 menu_t *menu;
1994 int x; 2029 int x;
1995 2030
1996 if (!menubar_visible () || menuBar.win == 0) 2031 if (!menubar_visible () || menuBar.win == 0)
1997 return; 2032 return;
1998 2033
1999 if (menubarGC == None) 2034 if (menubarGC == None)
2000 { 2035 {
2001 /* Create the graphics context */ 2036 /* Create the graphics context */
2002 XGCValues gcvalue; 2037 XGCValues gcvalue;
2003
2004 gcvalue.font = TermWin.font->fid;
2005 2038
2006 gcvalue.foreground = (XDEPTH <= 2 ? PixColors[Color_fg] 2039 gcvalue.foreground = (XDEPTH <= 2 ? PixColors[Color_fg]
2007 : PixColors[Color_Black]); 2040 : PixColors[Color_Black]);
2008 menubarGC = XCreateGC (display->display, menuBar.win, 2041 menubarGC = XCreateGC (display->display, menuBar.win,
2009 GCForeground | GCFont, &gcvalue); 2042 GCForeground, &gcvalue);
2010 2043
2011 } 2044 }
2012 /* make sure the font is correct */ 2045 /* make sure the font is correct */
2013 XSetFont (display->display, menubarGC, TermWin.font->fid);
2014 XSetFont (display->display, botShadowGC, TermWin.font->fid);
2015 XClearWindow (display->display, menuBar.win); 2046 XClearWindow (display->display, menuBar.win);
2016 2047
2017 menu_hide_all (); 2048 menu_hide_all ();
2018 2049
2019 x = 0; 2050 x = 0;
2031 2062
2032 if (x >= TermWin.ncol) 2063 if (x >= TermWin.ncol)
2033 len = (TermWin.ncol - (menu->x + HSPACE)); 2064 len = (TermWin.ncol - (menu->x + HSPACE));
2034 2065
2035 drawbox_menubar (menu->x, len, +1); 2066 drawbox_menubar (menu->x, len, +1);
2036 draw_string (display->display, menuBar.win, menubarGC, 2067 draw_string (*menuBar.drawable, menubarGC, TermWin.fontset,
2037 (Width2Pixel (menu->x) + Width2Pixel (HSPACE) / 2), 2068 (Width2Pixel (menu->x) + Width2Pixel (HSPACE) / 2),
2038 menuBar_height () - SHADOW, menu->name, len); 2069 SHADOW, menu->name, len);
2039 2070
2040 if (x >= TermWin.ncol) 2071 if (x >= TermWin.ncol)
2041 break; 2072 break;
2042 } 2073 }
2043 } 2074 }
2094 } 2125 }
2095 title[len] = '\0'; 2126 title[len] = '\0';
2096 2127
2097 ncol -= (x + len + HSPACE); 2128 ncol -= (x + len + HSPACE);
2098 if (len > 0 && ncol >= 0) 2129 if (len > 0 && ncol >= 0)
2099 draw_string (display->display, menuBar.win, menubarGC, 2130 draw_string (*menuBar.drawable, menubarGC, TermWin.fontset,
2100 Width2Pixel (x) + Width2Pixel (ncol + HSPACE) / 2, 2131 Width2Pixel (x) + Width2Pixel (ncol + HSPACE) / 2,
2101 menuBar_height () - SHADOW, title, len); 2132 SHADOW, title, len);
2102 } 2133 }
2103} 2134}
2104 2135
2105int 2136int
2106rxvt_term::menubar_mapping (int map) 2137rxvt_term::menubar_mapping (int map)
2129} 2160}
2130 2161
2131int 2162int
2132rxvt_term::menu_select (XButtonEvent &ev) 2163rxvt_term::menu_select (XButtonEvent &ev)
2133{ 2164{
2134 menuitem_t *thisitem, *item = NULL; 2165 menuitem_t *thisitem, *item = NULL;
2135 int this_y, y; 2166 int this_y, y;
2136 menu_t *ActiveMenu = ActiveMenu;
2137 2167
2138 Window unused_root, unused_child; 2168 Window unused_root, unused_child;
2139 int unused_root_x, unused_root_y; 2169 int unused_root_x, unused_root_y;
2140 unsigned int unused_mask; 2170 unsigned int unused_mask;
2141 2171
2142 if (ActiveMenu == NULL) 2172 if (ActiveMenu == NULL)
2143 return 0; 2173 return 0;
2144 2174
2145 XQueryPointer (display->display, ActiveMenu->win, 2175 XQueryPointer (display->display, ActiveMenu->win,
2146 &unused_root, &unused_child, 2176 &unused_root, &unused_child,
2147 &unused_root_x, &unused_root_y, 2177 &unused_root_x, &unused_root_y,
2148 &ev.x, &ev.y, &unused_mask); 2178 &ev.x, &ev.y, &unused_mask);
2149 2179
2150 if (ActiveMenu->parent != NULL && (ev.x < 0 || ev.y < 0)) 2180 if (ActiveMenu->parent != NULL && (ev.x < 0 || ev.y < 0))
2151 { 2181 {
2152 menu_hide (); 2182 menu_hide ();
2153 return 1; 2183 return 1;
2154 } 2184 }
2185
2155 /* determine the menu item corresponding to the Y index */ 2186 /* determine the menu item corresponding to the Y index */
2156 y = SHADOW; 2187 y = SHADOW;
2157 if (ev.x >= 0 && ev.x <= (ActiveMenu->w - SHADOW)) 2188 if (ev.x >= 0 && ev.x <= (ActiveMenu->w - SHADOW))
2158 { 2189 {
2159 for (item = ActiveMenu->head; item != NULL; item = item->next) 2190 for (item = ActiveMenu->head; item != NULL; item = item->next)
2160 { 2191 {
2161 int h = HEIGHT_TEXT + 2 * SHADOW; 2192 int h = HEIGHT_TEXT + 2 * SHADOW;
2162 2193
2163 if (isSeparator (item->name)) 2194 if (isSeparator (item->name))
2164 h = HEIGHT_SEPARATOR; 2195 h = HEIGHT_SEPARATOR;
2165 else if (ev.y >= y && ev.y < (y + h)) 2196 else if (ev.y >= y && ev.y < (y + h))
2166 break; 2197 break;
2198
2167 y += h; 2199 y += h;
2168 } 2200 }
2169 } 2201 }
2202
2170 if (item == NULL && ev.type == ButtonRelease) 2203 if (item == NULL && ev.type == ButtonRelease)
2171 { 2204 {
2172 menu_hide_all (); 2205 menu_hide_all ();
2173 return 0; 2206 return 0;
2174 } 2207 }
2208
2175 thisitem = item; 2209 thisitem = item;
2176 this_y = y - SHADOW; 2210 this_y = y - SHADOW;
2177 2211
2178 /* erase the last item */ 2212 /* erase the last item */
2179 if (ActiveMenu->item != NULL) 2213 if (ActiveMenu->item != NULL)
2180 { 2214 {
2181 if (ActiveMenu->item != thisitem) 2215 if (ActiveMenu->item != thisitem)
2182 { 2216 {
2183 for (y = 0, item = ActiveMenu->head; item != NULL; 2217 for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next)
2184 item = item->next)
2185 { 2218 {
2186 int h; 2219 int h;
2187 2220
2188 if (isSeparator (item->name)) 2221 if (isSeparator (item->name))
2189 h = HEIGHT_SEPARATOR; 2222 h = HEIGHT_SEPARATOR;
2190 else if (item == ActiveMenu->item) 2223 else if (item == ActiveMenu->item)
2191 { 2224 {
2192 /* erase old menuitem */ 2225 /* erase old menuitem */
2193 drawbox_menuitem (y, 0); /* No Shadow */ 2226 drawbox_menuitem (y, 0); /* No Shadow */
2194 if (item->entry.type == MenuSubMenu) 2227 if (item->entry.type == MenuSubMenu)
2195 drawtriangle (ActiveMenu->w, y, +1); 2228 drawtriangle (ActiveMenu->w, y, +1);
2229
2196 break; 2230 break;
2197 } 2231 }
2198 else 2232 else
2199 h = HEIGHT_TEXT + 2 * SHADOW; 2233 h = HEIGHT_TEXT + 2 * SHADOW;
2234
2200 y += h; 2235 y += h;
2201 } 2236 }
2202 } 2237 }
2203 else 2238 else
2204 { 2239 {
2213 break; 2248 break;
2214 2249
2215 case MenuAction: 2250 case MenuAction:
2216 case MenuTerminalAction: 2251 case MenuTerminalAction:
2217 drawbox_menuitem (this_y, -1); 2252 drawbox_menuitem (this_y, -1);
2218 {
2219#ifdef HAVE_NANOSLEEP 2253#ifdef HAVE_NANOSLEEP
2220 struct timespec rqt; 2254 struct timespec rqt;
2221 2255
2222 rqt.tv_sec = 0; 2256 rqt.tv_sec = 0;
2223 rqt.tv_nsec = MENU_DELAY_USEC * 1000; 2257 rqt.tv_nsec = MENU_DELAY_USEC * 1000;
2224 nanosleep (&rqt, NULL); 2258 nanosleep (&rqt, NULL);
2225#else 2259#else
2226 /* use select for timing */ 2260 /* use select for timing */
2227 struct timeval tv; 2261 struct timeval tv;
2228 2262
2229 tv.tv_sec = 0; 2263 tv.tv_sec = 0;
2230 tv.tv_usec = MENU_DELAY_USEC; 2264 tv.tv_usec = MENU_DELAY_USEC;
2231 select (0, NULL, NULL, NULL, &tv); 2265 select (0, NULL, NULL, NULL, &tv);
2232#endif 2266#endif
2233
2234 }
2235 /* remove menu before sending keys to the application */ 2267 /* remove menu before sending keys to the application */
2236 menu_hide_all (); 2268 menu_hide_all ();
2237#ifndef DEBUG_MENU 2269#ifndef DEBUG_MENU
2238 action_dispatch (& (item->entry.action)); 2270 action_dispatch (& (item->entry.action));
2239#else /* DEBUG_MENU */ 2271#else /* DEBUG_MENU */
2250 break; 2282 break;
2251 } 2283 }
2252 return 0; 2284 return 0;
2253 } 2285 }
2254 } 2286 }
2287
2255DoMenu: 2288DoMenu:
2256 ActiveMenu->item = thisitem; 2289 ActiveMenu->item = thisitem;
2257 y = this_y; 2290 y = this_y;
2291
2258 if (item != NULL) 2292 if (thisitem != NULL)
2259 { 2293 {
2260 item = ActiveMenu->item; 2294 item = ActiveMenu->item;
2261 if (item->entry.type != MenuLabel) 2295 if (item->entry.type != MenuLabel)
2262 drawbox_menuitem (y, +1); 2296 drawbox_menuitem (y, +1);
2297
2263 if (item->entry.type == MenuSubMenu) 2298 if (item->entry.type == MenuSubMenu)
2264 { 2299 {
2265 int x; 2300 int x;
2266 2301
2267 drawtriangle (ActiveMenu->w, y, -1); 2302 drawtriangle (ActiveMenu->w, y, -1);
2268 2303
2269 x = ev.x + (ActiveMenu->parent 2304 x = ev.x + (ActiveMenu->parent
2270 ? ActiveMenu->x 2305 ? ActiveMenu->x
2282} 2317}
2283 2318
2284void 2319void
2285rxvt_term::menubar_select (XButtonEvent &ev) 2320rxvt_term::menubar_select (XButtonEvent &ev)
2286{ 2321{
2287 menu_t *menu = NULL; 2322 menu_t *menu = NULL;
2288 2323
2289 /* determine the pulldown menu corresponding to the X index */ 2324 /* determine the pulldown menu corresponding to the X index */
2290 if (ev.y >= 0 && ev.y <= menuBar_height () && CurrentBar != NULL) 2325 if (ev.y >= 0 && ev.y <= menuBar_height () && CurrentBar != NULL)
2291 { 2326 {
2292 for (menu = CurrentBar->head; menu != NULL; menu = menu->next) 2327 for (menu = CurrentBar->head; menu != NULL; menu = menu->next)
2293 { 2328 {
2294 int x = Width2Pixel (menu->x); 2329 int x = Width2Pixel (menu->x);
2295 int w = Width2Pixel (menu->len + HSPACE); 2330 int w = Width2Pixel (menu->len + HSPACE);
2296 2331
2297 if ((ev.x >= x && ev.x < x + w)) 2332 if ((ev.x >= x && ev.x < x + w))
2298 break; 2333 break;
2299 } 2334 }
2300 } 2335 }
2398 menu_select (ev); 2433 menu_select (ev);
2399 break; 2434 break;
2400 2435
2401 case MotionNotify: 2436 case MotionNotify:
2402 while (XCheckTypedWindowEvent (display->display, TermWin.parent[0], 2437 while (XCheckTypedWindowEvent (display->display, TermWin.parent[0],
2403 MotionNotify, (XEvent *)&ev)) ; 2438 MotionNotify, (XEvent *)&ev)) ;
2404 2439
2405 if (ActiveMenu) 2440 if (ActiveMenu)
2406 while (menu_select (ev)) ; 2441 while (menu_select (ev)) ;
2407 else 2442 else
2408 ev.y = -1; 2443 ev.y = -1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines