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.30 by root, Wed Jan 4 04:42:45 2006 UTC

1/*--------------------------------*-C-*---------------------------------* 1/*--------------------------------*-C-*---------------------------------*
2 * File: menubar.c 2 * File: menubar.C
3 *----------------------------------------------------------------------* 3 *----------------------------------------------------------------------*
4 * 4 *
5 * Copyright (c) 1997,1998 mj olesen <olesen@me.QueensU.CA> 5 * Copyright (c) 1997,1998 mj olesen <olesen@me.QueensU.CA>
6 * Copyright (c) 2004 Marc Lehmann <pcg@goof.com>
6 * 7 *
7 * 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
8 * 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
9 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version. 11 * (at your option) any later version.
21 * refer.html (or refer.txt) contains up-to-date documentation. The 22 * 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. 23 * summary that appears at the end of this file was taken from there.
23 *----------------------------------------------------------------------*/ 24 *----------------------------------------------------------------------*/
24 25
25#include "../config.h" /* NECESSARY */ 26#include "../config.h" /* NECESSARY */
27
28#include <cstdlib>
29
26#include "rxvt.h" /* NECESSARY */ 30#include "rxvt.h" /* NECESSARY */
27#ifdef MENUBAR 31#ifdef MENUBAR
28#include "version.h" 32#include "version.h"
29#include "menubar.h" 33#include "menubar.h"
30#include "menubar.intpro" /* PROTOS for internal routines */
31 34
32#define Menu_PixelWidth(menu) \ 35#define Menu_PixelWidth(menu) \
33 (2 * SHADOW + Width2Pixel ((menu)->width + 3 * HSPACE)) 36 (2 * MENU_SHADOW + Width2Pixel ((menu)->width + 3 * HSPACE))
34 37
35static const struct 38static const struct
36 { 39 {
37 const char name; /* (l)eft, (u)p, (d)own, (r)ight */ 40 const char name; /* (l)eft, (u)p, (d)own, (r)ight */
38 const unsigned char str[5]; /* str[0] = STRLEN (str+1) */ 41 const char str[5]; /* str[0] = strlen (str+1) */
39 } 42 }
40Arrows[NARROWS] = { 43Arrows[NARROWS] = {
41 { 'l', "\003\033[D" }, 44 { 'l', "\003\033[D" },
42 { 'u', "\003\033[A" }, 45 { 'u', "\003\033[A" },
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/*}}} */
48 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}
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 *
53rxvt_menuitem_find (const menu_t *menu, const char *name) 80rxvt_menuitem_find (const menu_t *menu, const char *name)
62 /* find the last item in the menu, this is good for separators */ 89 /* find the last item in the menu, this is good for separators */
63 for (item = menu->tail; item != NULL; item = item->prev) 90 for (item = menu->tail; item != NULL; item = item->prev)
64 { 91 {
65 if (item->entry.type == MenuSubMenu) 92 if (item->entry.type == MenuSubMenu)
66 { 93 {
67 if (!STRCMP (name, (item->entry.submenu.menu)->name)) 94 if (!strcmp (name, (item->entry.submenu.menu)->name))
68 break; 95 break;
69 } 96 }
70 else if ((isSeparator (name) && isSeparator (item->name)) 97 else if ((isSeparator (name) && isSeparator (item->name))
71 || !STRCMP (name, item->name)) 98 || !strcmp (name, item->name))
72 break; 99 break;
73 } 100 }
74 return item; 101 return item;
75} 102}
76 103
120/* 147/*
121 * sort command vs. terminal actions and 148 * sort command vs. terminal actions and
122 * remove the first character of STR if it's '\0' 149 * remove the first character of STR if it's '\0'
123 */ 150 */
124int 151int
125rxvt_action_type (action_t *action, unsigned char *str) 152rxvt_action_type (action_t *action, char *str)
126{ 153{
127 unsigned int len; 154 unsigned int len;
128 155
129#if defined (DEBUG_MENU) || defined (DEBUG_MENUARROWS) 156#if defined (DEBUG_MENU) || defined (DEBUG_MENUARROWS)
130 len = STRLEN (str); 157 len = strlen (str);
131 fprintf (stderr, " (len %d) = %s\n", len, str); 158 fprintf (stderr, " (len %d) = %s\n", len, str);
132#else 159#else
133 len = rxvt_Str_escaped ((char *)str); 160 len = rxvt_Str_escaped ((char *)str);
134#endif 161#endif
135 162
139 /* sort command vs. terminal actions */ 166 /* sort command vs. terminal actions */
140 action->type = MenuAction; 167 action->type = MenuAction;
141 if (str[0] == '\0') 168 if (str[0] == '\0')
142 { 169 {
143 /* the functional equivalent: memmove (str, str+1, len); */ 170 /* the functional equivalent: memmove (str, str+1, len); */
144 unsigned char *dst = (str); 171 char *dst = (str);
145 unsigned char *src = (str + 1); 172 char *src = (str + 1);
146 unsigned char *end = (str + len); 173 char *end = (str + len);
147 174
148 while (src <= end) 175 while (src <= end)
149 *dst++ = *src++; 176 *dst++ = *src++;
150 177
151 len--; /* decrement length */ 178 len--; /* decrement length */
152 if (str[0] != '\0') 179 if (str[0] != '\0')
153 action->type = MenuTerminalAction; 180 action->type = MenuTerminalAction;
154 } 181 }
182
155 action->str = str; 183 action->str = str;
156 action->len = len; 184 action->len = len;
157 185
158 return 0; 186 return 0;
159} 187}
236 beg = { NULL, 0 }, 264 beg = { NULL, 0 },
237 end = { NULL, 0 }, 265 end = { NULL, 0 },
238 *cur, 266 *cur,
239 parse[NARROWS]; 267 parse[NARROWS];
240 268
241 MEMSET (parse, 0, sizeof (parse)); 269 memset (parse, 0, sizeof (parse));
242 270
243 /* fprintf (stderr, "add arrows = `%s'\n", string); */ 271 /* fprintf (stderr, "add arrows = `%s'\n", string); */
244 for (p = string; p != NULL && *p; string = p) 272 for (p = string; p != NULL && *p; string = p)
245 { 273 {
246 p = (string + 3); 274 p = (string + 3);
267 cur->str = string; 295 cur->str = string;
268 cur->len = 0; 296 cur->len = 0;
269 297
270 if (cur == &end) 298 if (cur == &end)
271 { 299 {
272 p = STRCHR (string, '\0'); 300 p = strchr (string, '\0');
273 } 301 }
274 else 302 else
275 { 303 {
276 char *next = string; 304 char *next = string;
277 305
278 while (1) 306 while (1)
279 { 307 {
280 p = STRCHR (next, '<'); 308 p = strchr (next, '<');
281 if (p != NULL) 309 if (p != NULL)
282 { 310 {
283 if (p[1] && p[2] == '>') 311 if (p[1] && p[2] == '>')
284 break; 312 break;
285 /* parsed */ 313 /* parsed */
286 } 314 }
287 else 315 else
288 { 316 {
289 if (beg.str == NULL) /* no end needed */ 317 if (beg.str == NULL) /* no end needed */
290 p = STRCHR (next, '\0'); 318 p = strchr (next, '\0');
291 break; 319 break;
292 } 320 }
293 next = (p + 1); 321 next = (p + 1);
294 } 322 }
295 } 323 }
322 menuarrow_free (Arrows[i].name); 350 menuarrow_free (Arrows[i].name);
323 } 351 }
324 352
325 for (i = 0; i < NARROWS; i++) 353 for (i = 0; i < NARROWS; i++)
326 { 354 {
327 unsigned char *str; 355 char *str;
328 unsigned int len; 356 unsigned int len;
329 357
330 if (!parse[i].len) 358 if (!parse[i].len)
331 continue; 359 continue;
332 360
333 str = (unsigned char *) rxvt_malloc (parse[i].len + xtra_len + 1); 361 str = (char *)rxvt_malloc (parse[i].len + xtra_len + 1);
334 362
335 len = 0; 363 len = 0;
336 if (beg.len) 364 if (beg.len)
337 { 365 {
338 STRNCPY (str + len, beg.str, beg.len); 366 strncpy (str + len, beg.str, beg.len);
339 len += beg.len; 367 len += beg.len;
340 } 368 }
341 STRNCPY (str + len, parse[i].str, parse[i].len); 369 strncpy (str + len, parse[i].str, parse[i].len);
342 len += parse[i].len; 370 len += parse[i].len;
343 371
344 if (end.len) 372 if (end.len)
345 { 373 {
346 STRNCPY (str + len, end.str, end.len); 374 strncpy (str + len, end.str, end.len);
347 len += end.len; 375 len += end.len;
348 } 376 }
349 str[len] = '\0'; 377 str[len] = '\0';
350 378
351#ifdef DEBUG_MENUARROWS 379#ifdef DEBUG_MENUARROWS
405 item = (menuitem_t *) rxvt_malloc (sizeof (menuitem_t)); 433 item = (menuitem_t *) rxvt_malloc (sizeof (menuitem_t));
406 434
407 item->len2 = 0; 435 item->len2 = 0;
408 item->name2 = NULL; 436 item->name2 = NULL;
409 437
410 len = STRLEN (name); 438 len = strlen (name);
411 item->name = (char *)rxvt_malloc (len + 1); 439 item->name = (char *)rxvt_malloc (len + 1);
412 STRCPY (item->name, name); 440 strcpy (item->name, name);
413 if (name[0] == '.' && name[1] != '.') 441 if (name[0] == '.' && name[1] != '.')
414 len = 0; /* hidden menu name */ 442 len = 0; /* hidden menu name */
415 item->len = len; 443 item->len = len;
416 444
417 /* add to tail of list */ 445 /* add to tail of list */
429 * add action 457 * add action
430 */ 458 */
431Item_Found: 459Item_Found:
432 if (name2 != NULL && item->name2 == NULL) 460 if (name2 != NULL && item->name2 == NULL)
433 { 461 {
434 len = STRLEN (name2); 462 len = strlen (name2);
435 if (len == 0) 463 if (len == 0)
436 item->name2 = NULL; 464 item->name2 = NULL;
437 else 465 else
438 { 466 {
439 item->name2 = (char *)rxvt_malloc (len + 1); 467 item->name2 = (char *)rxvt_malloc (len + 1);
440 STRCPY (item->name2, name2); 468 strcpy (item->name2, name2);
441 } 469 }
442 item->len2 = len; 470 item->len2 = len;
443 } 471 }
444 item->entry.type = MenuLabel; 472 item->entry.type = MenuLabel;
445 len = STRLEN (action); 473 len = strlen (action);
446 474
447 if (len == 0 && item->name2 != NULL) 475 if (len == 0 && item->name2 != NULL)
448 { 476 {
449 action = item->name2; 477 action = item->name2;
450 len = item->len2; 478 len = item->len2;
451 } 479 }
452 if (len) 480 if (len)
453 { 481 {
454 unsigned char *str = (unsigned char *)rxvt_malloc (len + 1); 482 char *str = (char *)rxvt_malloc (len + 1);
455 483
456 STRCPY (str, action); 484 strcpy (str, action);
457 485
458 if (rxvt_action_type (& (item->entry.action), str) < 0) 486 if (rxvt_action_type (& (item->entry.action), str) < 0)
459 free (str); 487 free (str);
460 } 488 }
461 /* new item and a possible increase in width */ 489 /* new item and a possible increase in width */
481#endif 509#endif
482 510
483 if (path[0] == '\0') 511 if (path[0] == '\0')
484 return path; 512 return path;
485 513
486 if (STRCHR (path, '/') != NULL) 514 if (strchr (path, '/') != NULL)
487 { 515 {
488 char *p = path; 516 char *p = path;
489 517
490 while ((p = STRCHR (p, '/')) != NULL) 518 while ((p = strchr (p, '/')) != NULL)
491 { 519 {
492 p++; 520 p++;
493 if (*p == '/') 521 if (*p == '/')
494 path = p; 522 path = p;
495 } 523 }
524
496 if (path[0] == '/') 525 if (path[0] == '/')
497 { 526 {
498 path++; 527 path++;
499 *menu = NULL; 528 *menu = NULL;
500 } 529 }
530
501 while ((p = STRCHR (path, '/')) != NULL) 531 while ((p = strchr (path, '/')) != NULL)
502 { 532 {
503 p[0] = '\0'; 533 p[0] = '\0';
504 if (path[0] == '\0') 534 if (path[0] == '\0')
505 return NULL; 535 return NULL;
536
506 if (!STRCMP (path, DOT)) 537 if (!strcmp (path, DOT))
507 { 538 {
508 /* nothing to do */ 539 /* nothing to do */
509 } 540 }
510 else if (!STRCMP (path, DOTS)) 541 else if (!strcmp (path, DOTS))
511 { 542 {
512 if (*menu != NULL) 543 if (*menu != NULL)
513 *menu = (*menu)->parent; 544 *menu = (*menu)->parent;
514 } 545 }
515 else 546 else
523 } 554 }
524 555
525 path = (p + 1); 556 path = (p + 1);
526 } 557 }
527 } 558 }
559
528 if (!STRCMP (path, DOTS)) 560 if (!strcmp (path, DOTS))
529 { 561 {
530 path += STRLEN (DOTS); 562 path += strlen (DOTS);
531 if (*menu != NULL) 563 if (*menu != NULL)
532 *menu = (*menu)->parent; 564 *menu = (*menu)->parent;
533 return path; 565 return path;
534 } 566 }
567
535 /* find this menu */ 568 /* find this menu */
536 if (*menu == NULL) 569 if (*menu == NULL)
537 { 570 {
538 for (m = CurrentBar->tail; m != NULL; m = m->prev) 571 for (m = CurrentBar->tail; m != NULL; m = m->prev)
539 {
540 if (!STRCMP (path, m->name)) 572 if (!strcmp (path, m->name))
541 break; 573 break;
542 }
543 } 574 }
544 else 575 else
545 { 576 {
546 /* find this menu */ 577 /* find this menu */
547 for (item = (*menu)->tail; item != NULL; item = item->prev) 578 for (item = (*menu)->tail; item != NULL; item = item->prev)
548 { 579 {
549 if (item->entry.type == MenuSubMenu 580 if (item->entry.type == MenuSubMenu
550 && !STRCMP (path, (item->entry.submenu.menu)->name)) 581 && !strcmp (path, (item->entry.submenu.menu)->name))
551 { 582 {
552 m = (item->entry.submenu.menu); 583 m = (item->entry.submenu.menu);
553 break; 584 break;
554 } 585 }
555 } 586 }
556 } 587 }
588
557 if (m != NULL) 589 if (m != NULL)
558 { 590 {
559 *menu = m; 591 *menu = m;
560 path += STRLEN (path); 592 path += strlen (path);
561 } 593 }
594
562 return path; 595 return path;
563} 596}
564 597
565/* 598/*
566 * delete this entire menu 599 * delete this entire menu
568menu_t * 601menu_t *
569rxvt_term::menu_delete (menu_t *menu) 602rxvt_term::menu_delete (menu_t *menu)
570{ 603{
571 menu_t *parent = NULL, *prev, *next; 604 menu_t *parent = NULL, *prev, *next;
572 menuitem_t *item; 605 menuitem_t *item;
573 bar_t *CurrentBar = CurrentBar;
574 606
575#ifdef DEBUG_STRICT 607#ifdef DEBUG_STRICT
576 assert (CurrentBar != NULL); 608 assert (CurrentBar != NULL);
577#endif 609#endif
578 610
618 } 650 }
619 651
620 item = menu->tail; 652 item = menu->tail;
621 while (item != NULL) 653 while (item != NULL)
622 { 654 {
623 menuitem_t *p = item->prev; 655 menuitem_t *p = item->prev;
624 656
625 menuitem_free (menu, item); 657 menuitem_free (menu, item);
626 item = p; 658 item = p;
627 } 659 }
628 660
629 if (menu->name != NULL)
630 free (menu->name); 661 free (menu->name);
631 free (menu); 662 free (menu);
632 663
633 return parent; 664 return parent;
634} 665}
635 666
636menu_t * 667menu_t *
637rxvt_term::menu_add (menu_t *parent, char *path) 668rxvt_term::menu_add (menu_t *parent, char *path)
638{ 669{
639 menu_t *menu; 670 menu_t *menu;
640 bar_t *CurrentBar = CurrentBar;
641 671
642#ifdef DEBUG_STRICT 672#ifdef DEBUG_STRICT
643 assert (CurrentBar != NULL); 673 assert (CurrentBar != NULL);
644#endif 674#endif
645 675
646 if (STRCHR (path, '/') != NULL) 676 if (strchr (path, '/') != NULL)
647 { 677 {
648 char *p; 678 char *p;
649 679
650 if (path[0] == '/') 680 if (path[0] == '/')
651 { 681 {
652 /* shouldn't happen */ 682 /* shouldn't happen */
653 path++; 683 path++;
654 parent = NULL; 684 parent = NULL;
655 } 685 }
656 while ((p = STRCHR (path, '/')) != NULL) 686 while ((p = strchr (path, '/')) != NULL)
657 { 687 {
658 p[0] = '\0'; 688 p[0] = '\0';
659 if (path[0] == '\0') 689 if (path[0] == '\0')
660 return NULL; 690 return NULL;
661 691
662 parent = menu_add (parent, path); 692 parent = menu_add (parent, path);
663 path = (p + 1); 693 path = (p + 1);
664 } 694 }
665 } 695 }
666 if (!STRCMP (path, DOTS)) 696 if (!strcmp (path, DOTS))
667 return (parent != NULL ? parent->parent : parent); 697 return (parent != NULL ? parent->parent : parent);
668 698
669 if (!STRCMP (path, DOT) || path[0] == '\0') 699 if (!strcmp (path, DOT) || path[0] == '\0')
670 return parent; 700 return parent;
671 701
672 /* allocate a new menu */ 702 /* allocate a new menu */
673 menu = (menu_t *) rxvt_malloc (sizeof (menu_t)); 703 menu = (menu_t *) rxvt_malloc (sizeof (menu_t));
674 704
675 menu->width = 0; 705 menu->width = 0;
676 menu->parent = parent; 706 menu->parent = parent;
677 menu->len = STRLEN (path); 707 menu->len = strlen (path);
678 menu->name = (char *)rxvt_malloc ((menu->len + 1)); 708 menu->name = (char *)rxvt_malloc ((menu->len + 1));
679 STRCPY (menu->name, path); 709 strcpy (menu->name, path);
680 710
681 /* initialize head/tail */ 711 /* initialize head/tail */
682 menu->head = menu->tail = NULL; 712 menu->head = menu->tail = NULL;
683 menu->prev = menu->next = NULL; 713 menu->prev = menu->next = NULL;
684 714
685 menu->win = None; 715 menu->win = None;
716 menu->drawable = 0;
686 menu->x = menu->y = menu->w = menu->h = 0; 717 menu->x = menu->y = menu->w = menu->h = 0;
687 menu->item = NULL; 718 menu->item = NULL;
688 719
689 /* add to tail of list */ 720 /* add to tail of list */
690 if (parent == NULL) 721 if (parent == NULL)
723{ 754{
724 GC top, bot; 755 GC top, bot;
725 756
726 x = Width2Pixel (x); 757 x = Width2Pixel (x);
727 len = Width2Pixel (len + HSPACE); 758 len = Width2Pixel (len + HSPACE);
728 if (x >= TermWin.width) 759 if (x >= width)
729 return; 760 return;
730 else if (x + len >= TermWin.width) 761 else if (x + len >= width)
731 len = (TermWin_TotalWidth () - x); 762 len = (this->width - x);
732 763
733#ifdef MENUBAR_SHADOW_IN 764#ifdef MENUBAR_SHADOW_IN
734 state = -state; 765 state = -state;
735#endif 766#endif
736 switch (state) 767 switch (state)
774 default: 805 default:
775 top = bot = scrollbarGC; 806 top = bot = scrollbarGC;
776 break; /* neutral */ 807 break; /* neutral */
777 } 808 }
778 809
779 w = Height2Pixel (1) - 2 * SHADOW; 810 w = Height2Pixel (1) - 2 * MENU_SHADOW;
780 811
781 x -= SHADOW + (3 * w / 2); 812 x -= MENU_SHADOW + (3 * w / 2);
782 y += SHADOW * 3; 813 y += MENU_SHADOW * 3;
783 814
784 rxvt_Draw_Triangle (display->display, ActiveMenu->win, top, bot, x, y, w, 815 rxvt_Draw_Triangle (display->display, ActiveMenu->win, top, bot, x, y, w, 'r');
785 'r');
786} 816}
787 817
788void 818void
789rxvt_term::drawbox_menuitem (int y, int state) 819rxvt_term::drawbox_menuitem (int y, int state)
790{ 820{
807 top = bot = scrollbarGC; 837 top = bot = scrollbarGC;
808 break; /* neutral */ 838 break; /* neutral */
809 } 839 }
810 840
811 rxvt_Draw_Shadow (display->display, ActiveMenu->win, top, bot, 841 rxvt_Draw_Shadow (display->display, ActiveMenu->win, top, bot,
812 SHADOW + 0, SHADOW + y, 842 MENU_SHADOW + 0, MENU_SHADOW + y,
813 ActiveMenu->w - 2 * (SHADOW), 843 ActiveMenu->w - 2 * (MENU_SHADOW),
814 HEIGHT_TEXT + 2 * SHADOW); 844 HEIGHT_TEXT + 2 * MENU_SHADOW);
815 XFlush (display->display); 845 XFlush (display->display);
816} 846}
817 847
818#ifdef DEBUG_MENU_LAYOUT 848#ifdef DEBUG_MENU_LAYOUT
819void 849void
822 if (menu == NULL) 852 if (menu == NULL)
823 { 853 {
824 fprintf (stderr, "Top Level menu\n"); 854 fprintf (stderr, "Top Level menu\n");
825 return; 855 return;
826 } 856 }
857
827 fprintf (stderr, "menu %s ", menu->name); 858 fprintf (stderr, "menu %s ", menu->name);
828 if (menu->parent != NULL) 859 if (menu->parent != NULL)
829 { 860 {
830 menuitem_t *item; 861 menuitem_t *item;
831 862
835 && item->entry.submenu.menu == menu) 866 && item->entry.submenu.menu == menu)
836 { 867 {
837 break; 868 break;
838 } 869 }
839 } 870 }
871
840 if (item == NULL) 872 if (item == NULL)
841 { 873 {
842 fprintf (stderr, "is an orphan!\n"); 874 fprintf (stderr, "is an orphan!\n");
843 return; 875 return;
844 } 876 }
845 } 877 }
878
846 fprintf (stderr, "\n"); 879 fprintf (stderr, "\n");
847 rxvt_print_menu_ancestors (menu->parent); 880 rxvt_print_menu_ancestors (menu->parent);
848} 881}
849 882
850void 883void
893 926
894/* pop up/down the current menu and redraw the menuBar button */ 927/* pop up/down the current menu and redraw the menuBar button */
895void 928void
896rxvt_term::menu_show () 929rxvt_term::menu_show ()
897{ 930{
898 int x, y, xright; 931 int x, y, xright;
899 menu_t *ActiveMenu = ActiveMenu;
900 menuitem_t *item; 932 menuitem_t *item;
901 933
902 if (ActiveMenu == NULL) 934 if (ActiveMenu == NULL)
903 return; 935 return;
904 936
905 x = ActiveMenu->x; 937 x = ActiveMenu->x;
911 x = Width2Pixel (x); 943 x = Width2Pixel (x);
912 944
913 ActiveMenu->y = 1; 945 ActiveMenu->y = 1;
914 ActiveMenu->w = Menu_PixelWidth (ActiveMenu); 946 ActiveMenu->w = Menu_PixelWidth (ActiveMenu);
915 947
916 if ((x + ActiveMenu->w) >= TermWin.width) 948 if ((x + ActiveMenu->w) >= width)
917 x = (TermWin_TotalWidth () - ActiveMenu->w); 949 x = (this->width - ActiveMenu->w);
918 950
919 /* find the height */ 951 /* find the height */
920 for (h = 0, item = ActiveMenu->head; item != NULL; item = item->next) 952 for (h = 0, item = ActiveMenu->head; item != NULL; item = item->next)
921 h += isSeparator (item->name) ? HEIGHT_SEPARATOR 953 h += isSeparator (item->name) ? HEIGHT_SEPARATOR
922 : HEIGHT_TEXT + 2 * SHADOW; 954 : HEIGHT_TEXT + 2 * MENU_SHADOW;
923 ActiveMenu->h = h + 2 * SHADOW; 955 ActiveMenu->h = h + 2 * MENU_SHADOW;
924 } 956 }
957
925 if (ActiveMenu->win == None) 958 if (ActiveMenu->win == None)
926 { 959 {
927 ActiveMenu->win = XCreateSimpleWindow (display->display, TermWin.vt, 960 ActiveMenu->win = XCreateSimpleWindow (display->display, vt,
928 x, ActiveMenu->y, 961 x, ActiveMenu->y,
929 ActiveMenu->w, ActiveMenu->h, 962 ActiveMenu->w, ActiveMenu->h,
930 0, 963 0,
931 PixColors[Color_fg], 964 pix_colors[Color_fg],
932 PixColors[Color_scroll]); 965 pix_colors[Color_scroll]);
966 ActiveMenu->drawable = new rxvt_drawable (display, ActiveMenu->win);
933 XMapWindow (display->display, ActiveMenu->win); 967 XMapWindow (display->display, ActiveMenu->win);
934 } 968 }
969
935 rxvt_Draw_Shadow (display->display, ActiveMenu->win, 970 rxvt_Draw_Shadow (display->display, ActiveMenu->win,
936 topShadowGC, botShadowGC, 971 topShadowGC, botShadowGC,
937 0, 0, ActiveMenu->w, ActiveMenu->h); 972 0, 0, ActiveMenu->w, ActiveMenu->h);
938 973
939 /* determine the correct right-alignment */ 974 /* determine the correct right-alignment */
941 if (item->len2 > xright) 976 if (item->len2 > xright)
942 xright = item->len2; 977 xright = item->len2;
943 978
944 for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next) 979 for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next)
945 { 980 {
946 const int xoff = (SHADOW + Width2Pixel (HSPACE) / 2); 981 const int xoff = (MENU_SHADOW + Width2Pixel (HSPACE) / 2);
947 register int h; 982 register int h;
948 GC gc = menubarGC; 983 GC gc = menubarGC;
949 984
950 if (isSeparator (item->name)) 985 if (isSeparator (item->name))
951 { 986 {
952 rxvt_Draw_Shadow (display->display, ActiveMenu->win, 987 rxvt_Draw_Shadow (display->display, ActiveMenu->win,
953 topShadowGC, botShadowGC, 988 topShadowGC, botShadowGC,
954 SHADOW, y + SHADOW + 1, 989 MENU_SHADOW, y + MENU_SHADOW + 1,
955 ActiveMenu->w - 2 * SHADOW, 0); 990 ActiveMenu->w - 2 * MENU_SHADOW, 0);
956 h = HEIGHT_SEPARATOR; 991 h = HEIGHT_SEPARATOR;
957 } 992 }
958 else 993 else
959 { 994 {
960 char *name = item->name; 995 char *name = item->name;
961 int len = item->len; 996 int len = item->len;
962 997
963 if (item->entry.type == MenuLabel) 998 if (item->entry.type == MenuLabel)
964 {
965 gc = botShadowGC; 999 gc = botShadowGC;
966 }
967 else if (item->entry.type == MenuSubMenu) 1000 else if (item->entry.type == MenuSubMenu)
968 { 1001 {
969 int x1, y1; 1002 int x1, y1;
970 menuitem_t *it; 1003 menuitem_t *it;
971 menu_t *menu = item->entry.submenu.menu; 1004 menu_t *menu = item->entry.submenu.menu;
986 x1 += x; 1019 x1 += x;
987 1020
988 /* find the height of this submenu */ 1021 /* find the height of this submenu */
989 for (h = 0, it = menu->head; it != NULL; it = it->next) 1022 for (h = 0, it = menu->head; it != NULL; it = it->next)
990 h += isSeparator (it->name) ? HEIGHT_SEPARATOR 1023 h += isSeparator (it->name) ? HEIGHT_SEPARATOR
991 : HEIGHT_TEXT + 2 * SHADOW; 1024 : HEIGHT_TEXT + 2 * MENU_SHADOW;
992 menu->h = h + 2 * SHADOW; 1025 menu->h = h + 2 * MENU_SHADOW;
993 1026
994 /* ensure menu is in window limits */ 1027 /* ensure menu is in window limits */
995 if ((x1 + menu->w) >= TermWin.width) 1028 if ((x1 + menu->w) >= width)
996 x1 = (TermWin_TotalWidth () - menu->w); 1029 x1 = (this->width - menu->w);
997 1030
998 if ((y1 + menu->h) >= TermWin.height) 1031 if ((y1 + menu->h) >= height)
999 y1 = (TermWin_TotalHeight () - menu->h); 1032 y1 = (this->height - menu->h);
1000 1033
1001 menu->x = (x1 < 0 ? 0 : x1); 1034 menu->x = (x1 < 0 ? 0 : x1);
1002 menu->y = (y1 < 0 ? 0 : y1); 1035 menu->y = (y1 < 0 ? 0 : y1);
1003 } 1036 }
1004 else if (item->name2 && !STRCMP (name, item->name2)) 1037 else if (item->name2 && !strcmp (name, item->name2))
1005 name = NULL; 1038 name = NULL;
1006 1039
1007 if (len && name) 1040 if (len && name)
1008 draw_string (display->display, ActiveMenu->win, gc, xoff, 1041 draw_string (*ActiveMenu->drawable, gc, fontset[0],
1009 2 * SHADOW + y + TermWin.font->ascent + 1, 1042 xoff, 2 * MENU_SHADOW + y, name, len);
1010 name, len);
1011 1043
1012 len = item->len2; 1044 len = item->len2;
1013 name = item->name2; 1045 name = item->name2;
1014 1046
1015 if (len && name) 1047 if (len && name)
1016 draw_string (display->display, ActiveMenu->win, gc, 1048 draw_string (*ActiveMenu->drawable, gc, fontset[0],
1017 ActiveMenu->w - (xoff + Width2Pixel (xright)), 1049 ActiveMenu->w - (xoff + Width2Pixel (xright)), 2 * MENU_SHADOW + y, name, len);
1018 2 * SHADOW + y + TermWin.font->ascent + 1,
1019 name, len);
1020 1050
1021 h = HEIGHT_TEXT + 2 * SHADOW; 1051 h = HEIGHT_TEXT + 2 * MENU_SHADOW;
1022 } 1052 }
1023 y += h; 1053 y += h;
1024 } 1054 }
1025} 1055}
1026 1056
1027void 1057void
1028rxvt_term::menu_display (void (rxvt_term::*update) ()) 1058rxvt_term::menu_display (void (rxvt_term::*update) ())
1029{ 1059{
1030 menu_t *ActiveMenu = ActiveMenu;
1031
1032 if (ActiveMenu == NULL) 1060 if (ActiveMenu == NULL)
1033 return; 1061 return;
1062
1063 delete ActiveMenu->drawable;
1034 if (ActiveMenu->win != None) 1064 if (ActiveMenu->win != None)
1035 XDestroyWindow (display->display, ActiveMenu->win); 1065 XDestroyWindow (display->display, ActiveMenu->win);
1036 ActiveMenu->win = None; 1066 ActiveMenu->win = None;
1037 ActiveMenu->item = NULL; 1067 ActiveMenu->item = NULL;
1038 1068
1039 if (ActiveMenu->parent == NULL) 1069 if (ActiveMenu->parent == NULL)
1040 drawbox_menubar (ActiveMenu->x, ActiveMenu->len, +1); 1070 drawbox_menubar (ActiveMenu->x, ActiveMenu->len, +1);
1071
1041 ActiveMenu = ActiveMenu->parent; 1072 ActiveMenu = ActiveMenu->parent;
1042 (this->*update) (); 1073 (this->*update) ();
1043} 1074}
1044 1075
1045void 1076void
1057void 1088void
1058rxvt_term::menu_clear (menu_t *menu) 1089rxvt_term::menu_clear (menu_t *menu)
1059{ 1090{
1060 if (menu != NULL) 1091 if (menu != NULL)
1061 { 1092 {
1062 menuitem_t *item = menu->tail; 1093 menuitem_t *item = menu->tail;
1063 1094
1064 while (item != NULL) 1095 while (item != NULL)
1065 { 1096 {
1066 menuitem_free (menu, item); 1097 menuitem_free (menu, item);
1067 /* it didn't get freed ... why? */ 1098 /* it didn't get freed ... why? */
1074} 1105}
1075 1106
1076void 1107void
1077rxvt_term::menubar_clear () 1108rxvt_term::menubar_clear ()
1078{ 1109{
1079 bar_t *CurrentBar = CurrentBar;
1080
1081 if (CurrentBar != NULL) 1110 if (CurrentBar != NULL)
1082 { 1111 {
1083 menu_t *menu = CurrentBar->tail; 1112 menu_t *menu = CurrentBar->tail;
1084 1113
1085 while (menu != NULL) 1114 while (menu != NULL)
1086 { 1115 {
1087 menu_t *prev = menu->prev; 1116 menu_t *prev = menu->prev;
1088 1117
1089 menu_delete (menu); 1118 menu_delete (menu);
1090 menu = prev; 1119 menu = prev;
1091 } 1120 }
1092 CurrentBar->head = CurrentBar->tail = NULL; 1121 CurrentBar->head = CurrentBar->tail = NULL;
1094 if (CurrentBar->title) 1123 if (CurrentBar->title)
1095 { 1124 {
1096 free (CurrentBar->title); 1125 free (CurrentBar->title);
1097 CurrentBar->title = NULL; 1126 CurrentBar->title = NULL;
1098 } 1127 }
1128
1099 menuarrow_free (0); /* remove all arrow functions */ 1129 menuarrow_free (0); /* remove all arrow functions */
1100 } 1130 }
1131
1101 ActiveMenu = NULL; 1132 ActiveMenu = NULL;
1102} 1133}
1103 1134
1104#if (MENUBAR_MAX > 1) 1135#if (MENUBAR_MAX > 1)
1105/* find if menu already exists */ 1136/* find if menu already exists */
1106bar_t * 1137bar_t *
1107rxvt_term::menubar_find (const char *name) 1138rxvt_term::menubar_find (const char *name)
1108{ 1139{
1109 bar_t *bar = CurrentBar; 1140 bar_t *bar = CurrentBar;
1110 1141
1111#ifdef DEBUG_MENUBAR_STACKING 1142#ifdef DEBUG_MENUBAR_STACKING
1112 fprintf (stderr, "looking for [menu:%s] ...", name ? name : " (nil)"); 1143 fprintf (stderr, "looking for [menu:%s] ...", name ? name : " (nil)");
1113#endif 1144#endif
1114 if (bar == NULL || name == NULL) 1145 if (bar == NULL || name == NULL)
1115 return NULL; 1146 return NULL;
1116 1147
1117 if (STRLEN (name) && STRCMP (name, "*")) 1148 if (strlen (name) && strcmp (name, "*"))
1118 { 1149 {
1119 do 1150 do
1120 { 1151 {
1121 if (!STRCMP (bar->name, name)) 1152 if (!strcmp (bar->name, name))
1122 { 1153 {
1123#ifdef DEBUG_MENUBAR_STACKING 1154#ifdef DEBUG_MENUBAR_STACKING
1124 fprintf (stderr, " found!\n"); 1155 fprintf (stderr, " found!\n");
1125#endif 1156#endif
1126 return bar; 1157 return bar;
1138} 1169}
1139 1170
1140int 1171int
1141rxvt_term::menubar_push (const char *name) 1172rxvt_term::menubar_push (const char *name)
1142{ 1173{
1143 int ret = 1; 1174 int ret = 1;
1144 bar_t *bar; 1175 bar_t *bar;
1145 1176
1146 if (CurrentBar == NULL) 1177 if (CurrentBar == NULL)
1147 { 1178 {
1148 /* allocate first one */ 1179 /* allocate first one */
1149 bar = (bar_t *) rxvt_malloc (sizeof (bar_t)); 1180 bar = (bar_t *) rxvt_malloc (sizeof (bar_t));
1150 1181
1151 MEMSET (bar, 0, sizeof (bar_t)); 1182 memset (bar, 0, sizeof (bar_t));
1152 /* circular linked-list */ 1183 /* circular linked-list */
1153 bar->next = bar->prev = bar; 1184 bar->next = bar->prev = bar;
1154 bar->head = bar->tail = NULL; 1185 bar->head = bar->tail = NULL;
1155 bar->title = NULL; 1186 bar->title = NULL;
1156 CurrentBar = bar; 1187 CurrentBar = bar;
1197 Nbars++; 1228 Nbars++;
1198 } 1229 }
1199 CurrentBar = bar; 1230 CurrentBar = bar;
1200 1231
1201 } 1232 }
1233
1202 menubar_clear (); 1234 menubar_clear ();
1203 } 1235 }
1204 } 1236 }
1205 1237
1206 /* give menubar this name */ 1238 /* give menubar this name */
1207 STRNCPY (CurrentBar->name, name, MAXNAME); 1239 strncpy (CurrentBar->name, name, MAXNAME);
1208 CurrentBar->name[MAXNAME - 1] = '\0'; 1240 CurrentBar->name[MAXNAME - 1] = '\0';
1209 1241
1210 return ret; 1242 return ret;
1211} 1243}
1212 1244
1245 1277
1246 free (CurrentBar); 1278 free (CurrentBar);
1247 CurrentBar = prev; 1279 CurrentBar = prev;
1248 } 1280 }
1249 } 1281 }
1250 while (CurrentBar && !STRCMP (name, "*")); 1282 while (CurrentBar && !strcmp (name, "*"));
1251} 1283}
1252 1284
1253void 1285void
1254rxvt_action_decode (FILE *fp, action_t *act) 1286rxvt_action_decode (FILE *fp, action_t *act)
1255{ 1287{
1256 unsigned char *str; 1288 char *str;
1257 short len; 1289 short len;
1258 1290
1259 if (act == NULL || (len = act->len) == 0 || (str = act->str) == NULL) 1291 if (act == NULL || (len = act->len) == 0 || (str = act->str) == NULL)
1260 return; 1292 return;
1261 1293
1262 if (act->type == MenuTerminalAction) 1294 if (act->type == MenuTerminalAction)
1285 str++; 1317 str++;
1286 len--; 1318 len--;
1287 break; 1319 break;
1288 } 1320 }
1289 } 1321 }
1322
1290 /* 1323 /*
1291 * control character form is preferred, since backslash-escaping 1324 * control character form is preferred, since backslash-escaping
1292 * can be really ugly looking when the backslashes themselves also 1325 * can be really ugly looking when the backslashes themselves also
1293 * have to be escaped to avoid Shell (or whatever scripting 1326 * have to be escaped to avoid Shell (or whatever scripting
1294 * language) interpretation 1327 * language) interpretation
1295 */ 1328 */
1296 while (len > 0) 1329 while (len > 0)
1297 { 1330 {
1298 unsigned char ch = *str++; 1331 char ch = *str++;
1299 1332
1300 switch (ch) 1333 switch (ch)
1301 { 1334 {
1302 case C0_ESC: 1335 case C0_ESC:
1303 fprintf (fp, "\\E"); 1336 fprintf (fp, "\\E");
1314 case 127: 1347 case 127:
1315 fprintf (fp, "^?"); 1348 fprintf (fp, "^?");
1316 default: 1349 default:
1317 if (ch <= 31) 1350 if (ch <= 31)
1318 fprintf (fp, "^%c", ('@' + ch)); 1351 fprintf (fp, "^%c", ('@' + ch));
1319 else if (ch > 127) 1352 else if ((unsigned char)ch > 127)
1320 fprintf (fp, "\\%o", ch); 1353 fprintf (fp, "\\%o", ch);
1321 else 1354 else
1322 fprintf (fp, "%c", ch); 1355 fprintf (fp, "%c", ch);
1323 break; 1356 break;
1324 } 1357 }
1358
1325 len--; 1359 len--;
1326 } 1360 }
1361
1327 fprintf (fp, "\n"); 1362 fprintf (fp, "\n");
1328} 1363}
1329 1364
1330void 1365void
1331rxvt_menu_dump (FILE *fp, menu_t *menu) 1366rxvt_menu_dump (FILE *fp, menu_t *menu)
1345 else 1380 else
1346 rxvt_menu_dump (fp, item->entry.submenu.menu); 1381 rxvt_menu_dump (fp, item->entry.submenu.menu);
1347 break; 1382 break;
1348 1383
1349 case MenuLabel: 1384 case MenuLabel:
1350 fprintf (fp, "{%s}\n", (STRLEN (item->name) ? item->name : "-")); 1385 fprintf (fp, "{%s}\n", (strlen (item->name) ? item->name : "-"));
1351 break; 1386 break;
1352 1387
1353 case MenuTerminalAction: 1388 case MenuTerminalAction:
1354 case MenuAction: 1389 case MenuAction:
1355 fprintf (fp, "{%s}", item->name); 1390 fprintf (fp, "{%s}", item->name);
1356 if (item->name2 != NULL && STRLEN (item->name2)) 1391 if (item->name2 != NULL && strlen (item->name2))
1357 fprintf (fp, "{%s}", item->name2); 1392 fprintf (fp, "{%s}", item->name2);
1358 fprintf (fp, "\t"); 1393 fprintf (fp, "\t");
1359 rxvt_action_decode (fp, & (item->entry.action)); 1394 rxvt_action_decode (fp, & (item->entry.action));
1360 break; 1395 break;
1361 } 1396 }
1373 if (bar == NULL || fp == NULL) 1408 if (bar == NULL || fp == NULL)
1374 return; 1409 return;
1375 time (&t); 1410 time (&t);
1376 1411
1377 fprintf (fp, 1412 fprintf (fp,
1378 "# " APL_SUBCLASS " (%s) Pid: %u\n# Date: %s\n\n", 1413 "# " RESCLASS " (%s) Pid: %u\n# Date: %s\n\n",
1379 rs[Rs_name], (unsigned int)getpid (), ctime (&t)); 1414 rs[Rs_name], (unsigned int)getpid (), ctime (&t));
1380 1415
1381 /* dump in reverse order */ 1416 /* dump in reverse order */
1382 bar = CurrentBar->prev; 1417 bar = CurrentBar->prev;
1383 do 1418 do
1437 char *p, *file, *tag = NULL; 1472 char *p, *file, *tag = NULL;
1438 1473
1439 file = (char *)rxvt_File_find (filename, ".menu", rs[Rs_path]); 1474 file = (char *)rxvt_File_find (filename, ".menu", rs[Rs_path]);
1440 if (file == NULL) 1475 if (file == NULL)
1441 return; 1476 return;
1477
1442 fp = fopen (file, "rb"); 1478 fp = fopen (file, "rb");
1443 free (file); 1479 free (file);
1444 if (fp == NULL) 1480 if (fp == NULL)
1445 return; 1481 return;
1446 1482
1447#if (MENUBAR_MAX > 1) 1483#if (MENUBAR_MAX > 1)
1448 /* semi-colon delimited */ 1484 /* semi-colon delimited */
1449 if ((tag = STRCHR (filename, ';')) != NULL) 1485 if ((tag = strchr (filename, ';')) != NULL)
1450 { 1486 {
1451 tag++; 1487 tag++;
1452 if (*tag == '\0') 1488 if (*tag == '\0')
1453 tag = NULL; 1489 tag = NULL;
1454 } 1490 }
1528 /* what? ... skip this line */ 1564 /* what? ... skip this line */
1529 p[0] = COMMENT_CHAR; 1565 p[0] = COMMENT_CHAR;
1530 } 1566 }
1531 } 1567 }
1532 } 1568 }
1569
1533 /* 1570 /*
1534 * remove leading/trailing space 1571 * remove leading/trailing space
1535 * and strip-off leading/trailing quotes
1536 * skip blank or comment lines 1572 * skip blank or comment lines
1537 */ 1573 */
1538 rxvt_Str_trim (p); 1574 rxvt_Str_trim (p);
1539 if (*p && *p != '#') 1575 if (*p && *p != '#')
1540 { 1576 {
1552 * user interface for building/deleting and otherwise managing menus 1588 * user interface for building/deleting and otherwise managing menus
1553 */ 1589 */
1554void 1590void
1555rxvt_term::menubar_dispatch (char *str) 1591rxvt_term::menubar_dispatch (char *str)
1556{ 1592{
1557 int n, cmd; 1593 int n, cmd;
1558 char *path, *name, *name2; 1594 char *path, *name, *name2;
1559 1595
1560 if (menubar_visible () && ActiveMenu != NULL) 1596 if (menubar_visible () && ActiveMenu != NULL)
1561 menubar_expose (); 1597 menubar_expose ();
1562 else 1598 else
1563 ActiveMenu = NULL; 1599 ActiveMenu = NULL;
1594 if (str[0] == ':') 1630 if (str[0] == ':')
1595 { /* [:command:] */ 1631 { /* [:command:] */
1596 do 1632 do
1597 { 1633 {
1598 next++; 1634 next++;
1599 if ((next = STRCHR (next, ':')) == NULL) 1635 if ((next = strchr (next, ':')) == NULL)
1600 return; /* parse error */ 1636 return; /* parse error */
1601 } 1637 }
1602 while (next[1] != ']'); 1638 while (next[1] != ']');
1603 /* remove and skip ':]' */ 1639 /* remove and skip ':]' */
1604 *next = '\0'; 1640 *next = '\0';
1605 next += 2; 1641 next += 2;
1606 } 1642 }
1607 else 1643 else
1608 { 1644 {
1609 if ((next = STRCHR (next, ']')) == NULL) 1645 if ((next = strchr (next, ']')) == NULL)
1610 return; /* parse error */ 1646 return; /* parse error */
1611 /* remove and skip ']' */ 1647 /* remove and skip ']' */
1612 *next = '\0'; 1648 *next = '\0';
1613 next++; 1649 next++;
1614 } 1650 }
1622 menu_readonly = 0; 1658 menu_readonly = 0;
1623 menubar_dispatch (str + 1); 1659 menubar_dispatch (str + 1);
1624 menu_readonly = saved; 1660 menu_readonly = saved;
1625 } 1661 }
1626 /* these ones don't require menu stacking */ 1662 /* these ones don't require menu stacking */
1627 else if (!STRCMP (str, "clear")) 1663 else if (!strcmp (str, "clear"))
1628 { 1664 {
1629 menubar_clear (); 1665 menubar_clear ();
1630 } 1666 }
1631 else if (!STRCMP (str, "done") || rxvt_Str_match (str, "done:")) 1667 else if (!strcmp (str, "done") || rxvt_Str_match (str, "done:"))
1632 { 1668 {
1633 menu_readonly = 1; 1669 menu_readonly = 1;
1634 } 1670 }
1635 else if (!STRCMP (str, "show")) 1671 else if (!strcmp (str, "show"))
1636 { 1672 {
1637 map_menuBar (1); 1673 map_menuBar (1);
1638 menu_readonly = 1; 1674 menu_readonly = 1;
1639 } 1675 }
1640 else if (!STRCMP (str, "hide")) 1676 else if (!strcmp (str, "hide"))
1641 { 1677 {
1642 map_menuBar (0); 1678 map_menuBar (0);
1643 menu_readonly = 1; 1679 menu_readonly = 1;
1644 } 1680 }
1645 else if ((n = rxvt_Str_match (str, "read:")) != 0) 1681 else if ((n = rxvt_Str_match (str, "read:")) != 0)
1653 str += n; 1689 str += n;
1654 if (CurrentBar != NULL && !menu_readonly) 1690 if (CurrentBar != NULL && !menu_readonly)
1655 { 1691 {
1656 if (*str) 1692 if (*str)
1657 { 1693 {
1658 name = (char *)rxvt_realloc (CurrentBar->title, STRLEN (str) + 1); 1694 name = (char *)rxvt_realloc (CurrentBar->title, strlen (str) + 1);
1659 if (name != NULL) 1695 if (name != NULL)
1660 { 1696 {
1661 STRCPY (name, str); 1697 strcpy (name, str);
1662 CurrentBar->title = name; 1698 CurrentBar->title = name;
1663 } 1699 }
1664 menubar_expose (); 1700 menubar_expose ();
1665 } 1701 }
1666 else 1702 else
1671 } 1707 }
1672 } 1708 }
1673 else if ((n = rxvt_Str_match (str, "pixmap:")) != 0) 1709 else if ((n = rxvt_Str_match (str, "pixmap:")) != 0)
1674 { 1710 {
1675 str += n; 1711 str += n;
1676 xterm_seq (XTerm_Pixmap, str, CHAR_ST); 1712 process_xterm_seq (XTerm_Pixmap, str, CHAR_ST);
1677 } 1713 }
1678#if (MENUBAR_MAX > 1) 1714#if (MENUBAR_MAX > 1)
1679 else if ((n = rxvt_Str_match (str, "rm")) != 0) 1715 else if ((n = rxvt_Str_match (str, "rm")) != 0)
1680 { 1716 {
1681 str += n; 1717 str += n;
1711 } 1747 }
1712 1748
1713 if (CurrentBar != NULL) 1749 if (CurrentBar != NULL)
1714 menu_readonly = 0; /* allow menu build commands */ 1750 menu_readonly = 0; /* allow menu build commands */
1715 } 1751 }
1716 else if (!STRCMP (str, "dump")) 1752 else if (!strcmp (str, "dump"))
1717 { 1753 {
1718 /* dump current menubars to a file */ 1754 /* dump current menubars to a file */
1719 FILE *fp; 1755 FILE *fp;
1720 1756
1721 /* enough space to hold the results */ 1757 /* enough space to hold the results */
1722 char buffer[32]; 1758 char buffer[32];
1723 1759
1724 sprintf (buffer, "/tmp/" APL_SUBCLASS "-%u", 1760 sprintf (buffer, "/tmp/" RESCLASS "-%u",
1725 (unsigned int)getpid ()); 1761 (unsigned int)getpid ());
1726 1762
1727 if ((fp = fopen (buffer, "wb")) != NULL) 1763 if ((fp = fopen (buffer, "wb")) != NULL)
1728 { 1764 {
1729 xterm_seq (XTerm_title, buffer, CHAR_ST); 1765 process_xterm_seq (XTerm_title, buffer, CHAR_ST);
1730 menubar_dump (fp); 1766 menubar_dump (fp);
1731 fclose (fp); 1767 fclose (fp);
1732 } 1768 }
1733 } 1769 }
1734 else if (!STRCMP (str, "next")) 1770 else if (!strcmp (str, "next"))
1735 { 1771 {
1736 if (CurrentBar) 1772 if (CurrentBar)
1737 { 1773 {
1738 CurrentBar = CurrentBar->next; 1774 CurrentBar = CurrentBar->next;
1739 menu_readonly = 1; 1775 menu_readonly = 1;
1740 } 1776 }
1741 } 1777 }
1742 else if (!STRCMP (str, "prev")) 1778 else if (!strcmp (str, "prev"))
1743 { 1779 {
1744 if (CurrentBar) 1780 if (CurrentBar)
1745 { 1781 {
1746 CurrentBar = CurrentBar->prev; 1782 CurrentBar = CurrentBar->prev;
1747 menu_readonly = 1; 1783 menu_readonly = 1;
1748 } 1784 }
1749 } 1785 }
1750 else if (!STRCMP (str, "swap")) 1786 else if (!strcmp (str, "swap"))
1751 { 1787 {
1752 /* swap the top 2 menus */ 1788 /* swap the top 2 menus */
1753 if (CurrentBar) 1789 if (CurrentBar)
1754 { 1790 {
1755 bar_t *cbprev = CurrentBar->prev; 1791 bar_t *cbprev = CurrentBar->prev;
1804 1840
1805 name2 = NULL; 1841 name2 = NULL;
1806 /* parse STR, allow spaces inside (name) */ 1842 /* parse STR, allow spaces inside (name) */
1807 if (path[0] != '\0') 1843 if (path[0] != '\0')
1808 { 1844 {
1809 name = STRCHR (path, MENUITEM_BEG); 1845 name = strchr (path, MENUITEM_BEG);
1810 str = STRCHR (path, MENUITEM_END); 1846 str = strchr (path, MENUITEM_END);
1811 if (name != NULL || str != NULL) 1847 if (name != NULL || str != NULL)
1812 { 1848 {
1813 if (name == NULL || str == NULL || str <= (name + 1) 1849 if (name == NULL || str == NULL || str <= (name + 1)
1814 || (name > path && name[-1] != '/')) 1850 || (name > path && name[-1] != '/'))
1815 { 1851 {
1816 rxvt_print_error ("menu error <%s>\n", path); 1852 rxvt_warn ("menu error A<%s>, continuing.\n", path);
1817 break; 1853 break;
1818 } 1854 }
1819 if (str[1] == MENUITEM_BEG) 1855 if (str[1] == MENUITEM_BEG)
1820 { 1856 {
1821 name2 = (str + 2); 1857 name2 = (str + 2);
1822 str = STRCHR (name2, MENUITEM_END); 1858 str = strchr (name2, MENUITEM_END);
1823 1859
1824 if (str == NULL) 1860 if (str == NULL)
1825 { 1861 {
1826 rxvt_print_error ("menu error <%s>\n", path); 1862 rxvt_warn ("menu error B<%s>, continuing.\n", path);
1827 break; 1863 break;
1828 } 1864 }
1829 name2[-2] = '\0'; /* remove prev MENUITEM_END */ 1865 name2[-2] = '\0'; /* remove prev MENUITEM_END */
1830 } 1866 }
1831 if (name > path && name[-1] == '/') 1867 if (name > path && name[-1] == '/')
1853 if (path[0] != '\0') 1889 if (path[0] != '\0')
1854 { 1890 {
1855 int len; 1891 int len;
1856 1892
1857 path = menu_find_base (& (BuildMenu), path); 1893 path = menu_find_base (& (BuildMenu), path);
1858 len = STRLEN (path); 1894 len = strlen (path);
1859 1895
1860 /* don't allow menus called `*' */ 1896 /* don't allow menus called `*' */
1861 if (path[0] == '*') 1897 if (path[0] == '*')
1862 { 1898 {
1863 menu_clear (BuildMenu); 1899 menu_clear (BuildMenu);
1864 break; 1900 break;
1865 } 1901 }
1866 else if (len >= 2 && !STRCMP ((path + len - 2), "/*")) 1902 else if (len >= 2 && !strcmp ((path + len - 2), "/*"))
1867 { 1903 {
1868 path[len - 2] = '\0'; 1904 path[len - 2] = '\0';
1869 } 1905 }
1870 if (path[0] != '\0') 1906 if (path[0] != '\0')
1871 BuildMenu = menu_add (BuildMenu, path); 1907 BuildMenu = menu_add (BuildMenu, path);
1872 } 1908 }
1873 if (name != NULL && name[0] != '\0') 1909 if (name != NULL && name[0] != '\0')
1874 rxvt_menuitem_add (BuildMenu, 1910 rxvt_menuitem_add (BuildMenu,
1875 (STRCMP (name, SEPARATOR_NAME) ? name : ""), 1911 (strcmp (name, SEPARATOR_NAME) ? name : ""),
1876 name2, str); 1912 name2, str);
1877 break; 1913 break;
1878 1914
1879 case '-': /* delete menu entry */ 1915 case '-': /* delete menu entry */
1880 if (!STRCMP (path, "/*") && (name == NULL || name[0] == '\0')) 1916 if (!strcmp (path, "/*") && (name == NULL || name[0] == '\0'))
1881 { 1917 {
1882 menubar_clear (); 1918 menubar_clear ();
1883 BuildMenu = NULL; 1919 BuildMenu = NULL;
1884 menubar_expose (); 1920 menubar_expose ();
1885 break; 1921 break;
1888 { 1924 {
1889 int len; 1925 int len;
1890 menu_t *menu = BuildMenu; 1926 menu_t *menu = BuildMenu;
1891 1927
1892 path = menu_find_base (&menu, path); 1928 path = menu_find_base (&menu, path);
1893 len = STRLEN (path); 1929 len = strlen (path);
1894 1930
1895 /* submenu called `*' clears all menu items */ 1931 /* submenu called `*' clears all menu items */
1896 if (path[0] == '*') 1932 if (path[0] == '*')
1897 { 1933 {
1898 menu_clear (menu); 1934 menu_clear (menu);
1899 break; /* done */ 1935 break; /* done */
1900 } 1936 }
1901 else if (len >= 2 && !STRCMP (&path[len - 2], "/*")) 1937 else if (len >= 2 && !strcmp (&path[len - 2], "/*"))
1902 { 1938 {
1903 /* done */ 1939 /* done */
1904 break; 1940 break;
1905 } 1941 }
1906 else if (path[0] != '\0') 1942 else if (path[0] != '\0')
1909 break; 1945 break;
1910 } 1946 }
1911 else 1947 else
1912 BuildMenu = menu; 1948 BuildMenu = menu;
1913 } 1949 }
1950
1914 if (BuildMenu != NULL) 1951 if (BuildMenu != NULL)
1915 { 1952 {
1916 if (name == NULL || name[0] == '\0') 1953 if (name == NULL || name[0] == '\0')
1917 BuildMenu = menu_delete (BuildMenu); 1954 BuildMenu = menu_delete (BuildMenu);
1918 else 1955 else
1919 { 1956 {
1920 const char *n1; 1957 const char *n1;
1921 menuitem_t *item; 1958 menuitem_t *item;
1922 menu_t *BuildMenu = BuildMenu;
1923 1959
1924 n1 = STRCMP (name, SEPARATOR_NAME) ? name : ""; 1960 n1 = strcmp (name, SEPARATOR_NAME) ? name : "";
1925 item = rxvt_menuitem_find (BuildMenu, n1); 1961 item = rxvt_menuitem_find (BuildMenu, n1);
1926 if (item != NULL && item->entry.type != MenuSubMenu) 1962 if (item != NULL && item->entry.type != MenuSubMenu)
1927 { 1963 {
1928 menuitem_free (BuildMenu, item); 1964 menuitem_free (BuildMenu, item);
1929 1965
1932 for (item = BuildMenu->head; item != NULL; 1968 for (item = BuildMenu->head; item != NULL;
1933 item = item->next) 1969 item = item->next)
1934 { 1970 {
1935 short l = item->len + item->len2; 1971 short l = item->len + item->len2;
1936 1972
1937 MAX_IT (BuildMenu->width, l); 1973 max_it (BuildMenu->width, l);
1938 } 1974 }
1939 } 1975 }
1940 } 1976 }
1977
1941 menubar_expose (); 1978 menubar_expose ();
1942 } 1979 }
1943 break; 1980 break;
1944 } 1981 }
1945 break; 1982 break;
1974 if (!Arrows_x) 2011 if (!Arrows_x)
1975 return; 2012 return;
1976 2013
1977 for (i = 0; i < NARROWS; i++) 2014 for (i = 0; i < NARROWS; i++)
1978 { 2015 {
1979 const int w = Width2Pixel (1); 2016 const int w = Width2Pixel (1);
1980 const int y = (menuBar_TotalHeight () - w) / 2; 2017 const int y = (menuBar_TotalHeight () - w) / 2;
1981 int x = Arrows_x + (5 * Width2Pixel (i)) / 4; 2018 int x = Arrows_x + (5 * Width2Pixel (i)) / 4;
1982 2019
1983 if (!name || name == Arrows[i].name) 2020 if (!name || name == Arrows[i].name)
1984 rxvt_Draw_Triangle (display->display, menuBar.win, top, bot, x, y, w, 2021 rxvt_Draw_Triangle (display->display, menuBar.win, top, bot, x, y, w,
1985 Arrows[i].name); 2022 Arrows[i].name);
1986 } 2023 }
1987 XFlush (display->display); 2024 XFlush (display->display);
1988} 2025}
1989 2026
1990void 2027void
1991rxvt_term::menubar_expose () 2028rxvt_term::menubar_expose ()
1992{ 2029{
1993 menu_t *menu; 2030 menu_t *menu;
1994 int x; 2031 int x;
1995 2032
1996 if (!menubar_visible () || menuBar.win == 0) 2033 if (!menubar_visible () || menuBar.win == 0)
1997 return; 2034 return;
1998 2035
1999 if (menubarGC == None) 2036 if (menubarGC == None)
2000 { 2037 {
2001 /* Create the graphics context */ 2038 /* Create the graphics context */
2002 XGCValues gcvalue; 2039 XGCValues gcvalue;
2003 2040
2004 gcvalue.font = TermWin.font->fid;
2005
2006 gcvalue.foreground = (XDEPTH <= 2 ? PixColors[Color_fg] 2041 gcvalue.foreground = (display->depth <= 2 ? pix_colors[Color_fg]
2007 : PixColors[Color_Black]); 2042 : pix_colors[Color_Black]);
2008 menubarGC = XCreateGC (display->display, menuBar.win, 2043 menubarGC = XCreateGC (display->display, menuBar.win,
2009 GCForeground | GCFont, &gcvalue); 2044 GCForeground, &gcvalue);
2010 2045
2011 } 2046 }
2012 /* make sure the font is correct */ 2047 /* 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); 2048 XClearWindow (display->display, menuBar.win);
2016 2049
2017 menu_hide_all (); 2050 menu_hide_all ();
2018 2051
2019 x = 0; 2052 x = 0;
2027 2060
2028#ifdef DEBUG_MENU_LAYOUT 2061#ifdef DEBUG_MENU_LAYOUT
2029 rxvt_print_menu_descendants (menu); 2062 rxvt_print_menu_descendants (menu);
2030#endif 2063#endif
2031 2064
2032 if (x >= TermWin.ncol) 2065 if (x >= ncol)
2033 len = (TermWin.ncol - (menu->x + HSPACE)); 2066 len = (ncol - (menu->x + HSPACE));
2034 2067
2035 drawbox_menubar (menu->x, len, +1); 2068 drawbox_menubar (menu->x, len, +1);
2036 draw_string (display->display, menuBar.win, menubarGC, 2069 draw_string (*menuBar.drawable, menubarGC, fontset[0],
2037 (Width2Pixel (menu->x) + Width2Pixel (HSPACE) / 2), 2070 (Width2Pixel (menu->x) + Width2Pixel (HSPACE) / 2),
2038 menuBar_height () - SHADOW, menu->name, len); 2071 MENU_SHADOW, menu->name, len);
2039 2072
2040 if (x >= TermWin.ncol) 2073 if (x >= ncol)
2041 break; 2074 break;
2042 } 2075 }
2043 } 2076 }
2044 drawbox_menubar (x, TermWin.ncol, (CurrentBar ? +1 : -1)); 2077 drawbox_menubar (x, ncol, (CurrentBar ? +1 : -1));
2045 2078
2046 /* add the menuBar title, if it exists and there's plenty of room */ 2079 /* add the menuBar title, if it exists and there's plenty of room */
2047 Arrows_x = 0; 2080 Arrows_x = 0;
2048 if (x < TermWin.ncol) 2081 if (x < ncol)
2049 { 2082 {
2050 const char *str; 2083 const char *str;
2051 int ncol;
2052 unsigned int len; 2084 unsigned int len;
2053 char title[256]; 2085 char title[256];
2054 2086
2055 ncol = (int)TermWin.ncol;
2056 if (x < (ncol - (NARROWS + 1))) 2087 if (x < (ncol - (NARROWS + 1)))
2057 { 2088 {
2058 ncol -= (NARROWS + 1); 2089 ncol -= (NARROWS + 1);
2059 Arrows_x = Width2Pixel (ncol); 2090 Arrows_x = Width2Pixel (ncol);
2060 } 2091 }
2092
2061 draw_Arrows (0, +1); 2093 draw_Arrows (0, +1);
2062 2094
2063 str = (CurrentBar 2095 str = (CurrentBar
2064 && CurrentBar->title) ? CurrentBar->title : "%n-%v"; 2096 && CurrentBar->title) ? CurrentBar->title : "%n-%v";
2065 for (len = 0; str[0] && len < sizeof (title) - 1; str++) 2097 for (len = 0; str[0] && len < sizeof (title) - 1; str++)
2094 } 2126 }
2095 title[len] = '\0'; 2127 title[len] = '\0';
2096 2128
2097 ncol -= (x + len + HSPACE); 2129 ncol -= (x + len + HSPACE);
2098 if (len > 0 && ncol >= 0) 2130 if (len > 0 && ncol >= 0)
2099 draw_string (display->display, menuBar.win, menubarGC, 2131 draw_string (*menuBar.drawable, menubarGC, fontset[0],
2100 Width2Pixel (x) + Width2Pixel (ncol + HSPACE) / 2, 2132 Width2Pixel (x) + Width2Pixel (ncol + HSPACE) / 2,
2101 menuBar_height () - SHADOW, title, len); 2133 MENU_SHADOW, title, len);
2102 } 2134 }
2103} 2135}
2104 2136
2105int 2137int
2106rxvt_term::menubar_mapping (int map) 2138rxvt_term::menubar_mapping (int map)
2129} 2161}
2130 2162
2131int 2163int
2132rxvt_term::menu_select (XButtonEvent &ev) 2164rxvt_term::menu_select (XButtonEvent &ev)
2133{ 2165{
2134 menuitem_t *thisitem, *item = NULL; 2166 menuitem_t *thisitem, *item = NULL;
2135 int this_y, y; 2167 int this_y, y;
2136 menu_t *ActiveMenu = ActiveMenu;
2137 2168
2138 Window unused_root, unused_child; 2169 Window unused_root, unused_child;
2139 int unused_root_x, unused_root_y; 2170 int unused_root_x, unused_root_y;
2140 unsigned int unused_mask; 2171 unsigned int unused_mask;
2141 2172
2142 if (ActiveMenu == NULL) 2173 if (ActiveMenu == NULL)
2143 return 0; 2174 return 0;
2144 2175
2145 XQueryPointer (display->display, ActiveMenu->win, 2176 XQueryPointer (display->display, ActiveMenu->win,
2146 &unused_root, &unused_child, 2177 &unused_root, &unused_child,
2147 &unused_root_x, &unused_root_y, 2178 &unused_root_x, &unused_root_y,
2148 &ev.x, &ev.y, &unused_mask); 2179 &ev.x, &ev.y, &unused_mask);
2149 2180
2150 if (ActiveMenu->parent != NULL && (ev.x < 0 || ev.y < 0)) 2181 if (ActiveMenu->parent != NULL && (ev.x < 0 || ev.y < 0))
2151 { 2182 {
2152 menu_hide (); 2183 menu_hide ();
2153 return 1; 2184 return 1;
2154 } 2185 }
2186
2155 /* determine the menu item corresponding to the Y index */ 2187 /* determine the menu item corresponding to the Y index */
2156 y = SHADOW; 2188 y = MENU_SHADOW;
2157 if (ev.x >= 0 && ev.x <= (ActiveMenu->w - SHADOW)) 2189 if (ev.x >= 0 && ev.x <= (ActiveMenu->w - MENU_SHADOW))
2158 { 2190 {
2159 for (item = ActiveMenu->head; item != NULL; item = item->next) 2191 for (item = ActiveMenu->head; item != NULL; item = item->next)
2160 { 2192 {
2161 int h = HEIGHT_TEXT + 2 * SHADOW; 2193 int h = HEIGHT_TEXT + 2 * MENU_SHADOW;
2162 2194
2163 if (isSeparator (item->name)) 2195 if (isSeparator (item->name))
2164 h = HEIGHT_SEPARATOR; 2196 h = HEIGHT_SEPARATOR;
2165 else if (ev.y >= y && ev.y < (y + h)) 2197 else if (ev.y >= y && ev.y < (y + h))
2166 break; 2198 break;
2199
2167 y += h; 2200 y += h;
2168 } 2201 }
2169 } 2202 }
2203
2170 if (item == NULL && ev.type == ButtonRelease) 2204 if (item == NULL && ev.type == ButtonRelease)
2171 { 2205 {
2172 menu_hide_all (); 2206 menu_hide_all ();
2173 return 0; 2207 return 0;
2174 } 2208 }
2209
2175 thisitem = item; 2210 thisitem = item;
2176 this_y = y - SHADOW; 2211 this_y = y - MENU_SHADOW;
2177 2212
2178 /* erase the last item */ 2213 /* erase the last item */
2179 if (ActiveMenu->item != NULL) 2214 if (ActiveMenu->item != NULL)
2180 { 2215 {
2181 if (ActiveMenu->item != thisitem) 2216 if (ActiveMenu->item != thisitem)
2182 { 2217 {
2183 for (y = 0, item = ActiveMenu->head; item != NULL; 2218 for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next)
2184 item = item->next)
2185 { 2219 {
2186 int h; 2220 int h;
2187 2221
2188 if (isSeparator (item->name)) 2222 if (isSeparator (item->name))
2189 h = HEIGHT_SEPARATOR; 2223 h = HEIGHT_SEPARATOR;
2190 else if (item == ActiveMenu->item) 2224 else if (item == ActiveMenu->item)
2191 { 2225 {
2192 /* erase old menuitem */ 2226 /* erase old menuitem */
2193 drawbox_menuitem (y, 0); /* No Shadow */ 2227 drawbox_menuitem (y, 0); /* No Shadow */
2194 if (item->entry.type == MenuSubMenu) 2228 if (item->entry.type == MenuSubMenu)
2195 drawtriangle (ActiveMenu->w, y, +1); 2229 drawtriangle (ActiveMenu->w, y, +1);
2230
2196 break; 2231 break;
2197 } 2232 }
2198 else 2233 else
2199 h = HEIGHT_TEXT + 2 * SHADOW; 2234 h = HEIGHT_TEXT + 2 * MENU_SHADOW;
2235
2200 y += h; 2236 y += h;
2201 } 2237 }
2202 } 2238 }
2203 else 2239 else
2204 { 2240 {
2213 break; 2249 break;
2214 2250
2215 case MenuAction: 2251 case MenuAction:
2216 case MenuTerminalAction: 2252 case MenuTerminalAction:
2217 drawbox_menuitem (this_y, -1); 2253 drawbox_menuitem (this_y, -1);
2218 {
2219#ifdef HAVE_NANOSLEEP
2220 struct timespec rqt;
2221
2222 rqt.tv_sec = 0;
2223 rqt.tv_nsec = MENU_DELAY_USEC * 1000;
2224 nanosleep (&rqt, NULL);
2225#else
2226 /* use select for timing */
2227 struct timeval tv;
2228
2229 tv.tv_sec = 0;
2230 tv.tv_usec = MENU_DELAY_USEC; 2254 rxvt_usleep (MENU_DELAY_USEC);
2231 select (0, NULL, NULL, NULL, &tv);
2232#endif
2233
2234 }
2235 /* remove menu before sending keys to the application */ 2255 /* remove menu before sending keys to the application */
2236 menu_hide_all (); 2256 menu_hide_all ();
2237#ifndef DEBUG_MENU 2257#ifndef DEBUG_MENU
2238 action_dispatch (& (item->entry.action)); 2258 action_dispatch (& (item->entry.action));
2239#else /* DEBUG_MENU */ 2259#else /* DEBUG_MENU */
2250 break; 2270 break;
2251 } 2271 }
2252 return 0; 2272 return 0;
2253 } 2273 }
2254 } 2274 }
2275
2255DoMenu: 2276DoMenu:
2256 ActiveMenu->item = thisitem; 2277 ActiveMenu->item = thisitem;
2257 y = this_y; 2278 y = this_y;
2279
2258 if (item != NULL) 2280 if (thisitem != NULL)
2259 { 2281 {
2260 item = ActiveMenu->item; 2282 item = ActiveMenu->item;
2261 if (item->entry.type != MenuLabel) 2283 if (item->entry.type != MenuLabel)
2262 drawbox_menuitem (y, +1); 2284 drawbox_menuitem (y, +1);
2285
2263 if (item->entry.type == MenuSubMenu) 2286 if (item->entry.type == MenuSubMenu)
2264 { 2287 {
2265 int x; 2288 int x;
2266 2289
2267 drawtriangle (ActiveMenu->w, y, -1); 2290 drawtriangle (ActiveMenu->w, y, -1);
2268 2291
2269 x = ev.x + (ActiveMenu->parent 2292 x = ev.x + (ActiveMenu->parent
2270 ? ActiveMenu->x 2293 ? ActiveMenu->x
2282} 2305}
2283 2306
2284void 2307void
2285rxvt_term::menubar_select (XButtonEvent &ev) 2308rxvt_term::menubar_select (XButtonEvent &ev)
2286{ 2309{
2287 menu_t *menu = NULL; 2310 menu_t *menu = NULL;
2288 2311
2289 /* determine the pulldown menu corresponding to the X index */ 2312 /* determine the pulldown menu corresponding to the X index */
2290 if (ev.y >= 0 && ev.y <= menuBar_height () && CurrentBar != NULL) 2313 if (ev.y >= 0 && ev.y <= menuBar_height () && CurrentBar != NULL)
2291 { 2314 {
2292 for (menu = CurrentBar->head; menu != NULL; menu = menu->next) 2315 for (menu = CurrentBar->head; menu != NULL; menu = menu->next)
2293 { 2316 {
2294 int x = Width2Pixel (menu->x); 2317 int x = Width2Pixel (menu->x);
2295 int w = Width2Pixel (menu->len + HSPACE); 2318 int w = Width2Pixel (menu->len + HSPACE);
2296 2319
2297 if ((ev.x >= x && ev.x < x + w)) 2320 if ((ev.x >= x && ev.x < x + w))
2298 break; 2321 break;
2299 } 2322 }
2300 } 2323 }
2314 if (ev.x >= (Arrows_x + (Width2Pixel (4 * i + i)) / 4) 2337 if (ev.x >= (Arrows_x + (Width2Pixel (4 * i + i)) / 4)
2315 && ev.x < (Arrows_x 2338 && ev.x < (Arrows_x
2316 + (Width2Pixel (4 * i + i + 4)) / 4)) 2339 + (Width2Pixel (4 * i + i + 4)) / 4))
2317 { 2340 {
2318 draw_Arrows (Arrows[i].name, -1); 2341 draw_Arrows (Arrows[i].name, -1);
2319 {
2320#ifdef HAVE_NANOSLEEP
2321 struct timespec rqt;
2322
2323 rqt.tv_sec = 0;
2324 rqt.tv_nsec = MENU_DELAY_USEC * 1000;
2325 nanosleep (&rqt, NULL);
2326#else
2327 /* use select for timing */
2328 struct timeval tv;
2329
2330 tv.tv_sec = 0;
2331 tv.tv_usec = MENU_DELAY_USEC; 2342 rxvt_usleep (MENU_DELAY_USEC);
2332 select (0, NULL, NULL, NULL, &tv);
2333#endif
2334
2335 }
2336 draw_Arrows (Arrows[i].name, +1); 2343 draw_Arrows (Arrows[i].name, +1);
2337#ifdef DEBUG_MENUARROWS 2344#ifdef DEBUG_MENUARROWS
2338 fprintf (stderr, "'%c': ", Arrows[i].name); 2345 fprintf (stderr, "'%c': ", Arrows[i].name);
2339 2346
2340 if (CurrentBar == NULL 2347 if (CurrentBar == NULL
2397 if (ev.button == Button1) 2404 if (ev.button == Button1)
2398 menu_select (ev); 2405 menu_select (ev);
2399 break; 2406 break;
2400 2407
2401 case MotionNotify: 2408 case MotionNotify:
2402 while (XCheckTypedWindowEvent (display->display, TermWin.parent[0], 2409 while (XCheckTypedWindowEvent (display->display, parent[0],
2403 MotionNotify, (XEvent *)&ev)) ; 2410 MotionNotify, (XEvent *)&ev));
2404 2411
2405 if (ActiveMenu) 2412 if (ActiveMenu)
2406 while (menu_select (ev)) ; 2413 while (menu_select (ev)) ;
2407 else 2414 else
2408 ev.y = -1; 2415 ev.y = -1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines