--- rxvt-unicode/src/menubar.C 2004/02/24 00:02:44 1.9 +++ rxvt-unicode/src/menubar.C 2004/08/15 04:54:21 1.19 @@ -1,8 +1,9 @@ /*--------------------------------*-C-*---------------------------------* - * File: menubar.c + * File: menubar.C *----------------------------------------------------------------------* * * Copyright (c) 1997,1998 mj olesen + * Copyright (c) 2004 Marc Lehmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,11 +24,13 @@ *----------------------------------------------------------------------*/ #include "../config.h" /* NECESSARY */ + +#include + #include "rxvt.h" /* NECESSARY */ #ifdef MENUBAR #include "version.h" #include "menubar.h" -#include "menubar.intpro" /* PROTOS for internal routines */ #define Menu_PixelWidth(menu) \ (2 * SHADOW + Width2Pixel ((menu)->width + 3 * HSPACE)) @@ -35,7 +38,7 @@ static const struct { const char name; /* (l)eft, (u)p, (d)own, (r)ight */ - const unsigned char str[5]; /* str[0] = STRLEN (str+1) */ + const unsigned char str[5]; /* str[0] = strlen (str+1) */ } Arrows[NARROWS] = { { 'l', "\003\033[D" }, @@ -46,6 +49,30 @@ /*}}} */ +static void +draw_string (rxvt_drawable &d, GC gc, rxvt_fontset *fs, int x, int y, char *str, int len) +{ + mbstate mbs; + + while (len) + { + wchar_t w; + int l = mbrtowc (&w, str, len, mbs); + + if (l <= 0) + break; + + len -= l; + str += l; + + rxvt_font *font = (*fs)[fs->find_font (w)]; + text_t ch = w; + font->draw (d, x, y, &ch, 1, Color_bg, Color_scroll); + + x += font->width * wcwidth (w); + } +} + /* * find an item called NAME in MENU */ @@ -64,11 +91,11 @@ { if (item->entry.type == MenuSubMenu) { - if (!STRCMP (name, (item->entry.submenu.menu)->name)) + if (!strcmp (name, (item->entry.submenu.menu)->name)) break; } else if ((isSeparator (name) && isSeparator (item->name)) - || !STRCMP (name, item->name)) + || !strcmp (name, item->name)) break; } return item; @@ -127,7 +154,7 @@ unsigned int len; #if defined (DEBUG_MENU) || defined (DEBUG_MENUARROWS) - len = STRLEN (str); + len = strlen (str); fprintf (stderr, " (len %d) = %s\n", len, str); #else len = rxvt_Str_escaped ((char *)str); @@ -238,7 +265,7 @@ *cur, parse[NARROWS]; - MEMSET (parse, 0, sizeof (parse)); + memset (parse, 0, sizeof (parse)); /* fprintf (stderr, "add arrows = `%s'\n", string); */ for (p = string; p != NULL && *p; string = p) @@ -269,7 +296,7 @@ if (cur == &end) { - p = STRCHR (string, '\0'); + p = strchr (string, '\0'); } else { @@ -277,7 +304,7 @@ while (1) { - p = STRCHR (next, '<'); + p = strchr (next, '<'); if (p != NULL) { if (p[1] && p[2] == '>') @@ -287,7 +314,7 @@ else { if (beg.str == NULL) /* no end needed */ - p = STRCHR (next, '\0'); + p = strchr (next, '\0'); break; } next = (p + 1); @@ -335,15 +362,15 @@ len = 0; if (beg.len) { - STRNCPY (str + len, beg.str, beg.len); + strncpy (str + len, beg.str, beg.len); len += beg.len; } - STRNCPY (str + len, parse[i].str, parse[i].len); + strncpy (str + len, parse[i].str, parse[i].len); len += parse[i].len; if (end.len) { - STRNCPY (str + len, end.str, end.len); + strncpy (str + len, end.str, end.len); len += end.len; } str[len] = '\0'; @@ -407,9 +434,9 @@ item->len2 = 0; item->name2 = NULL; - len = STRLEN (name); + len = strlen (name); item->name = (char *)rxvt_malloc (len + 1); - STRCPY (item->name, name); + strcpy (item->name, name); if (name[0] == '.' && name[1] != '.') len = 0; /* hidden menu name */ item->len = len; @@ -431,18 +458,18 @@ Item_Found: if (name2 != NULL && item->name2 == NULL) { - len = STRLEN (name2); + len = strlen (name2); if (len == 0) item->name2 = NULL; else { item->name2 = (char *)rxvt_malloc (len + 1); - STRCPY (item->name2, name2); + strcpy (item->name2, name2); } item->len2 = len; } item->entry.type = MenuLabel; - len = STRLEN (action); + len = strlen (action); if (len == 0 && item->name2 != NULL) { @@ -453,7 +480,7 @@ { unsigned char *str = (unsigned char *)rxvt_malloc (len + 1); - STRCPY (str, action); + strcpy (str, action); if (rxvt_action_type (& (item->entry.action), str) < 0) free (str); @@ -483,31 +510,34 @@ if (path[0] == '\0') return path; - if (STRCHR (path, '/') != NULL) + if (strchr (path, '/') != NULL) { char *p = path; - while ((p = STRCHR (p, '/')) != NULL) + while ((p = strchr (p, '/')) != NULL) { p++; if (*p == '/') path = p; } + if (path[0] == '/') { path++; *menu = NULL; } - while ((p = STRCHR (path, '/')) != NULL) + + while ((p = strchr (path, '/')) != NULL) { p[0] = '\0'; if (path[0] == '\0') return NULL; - if (!STRCMP (path, DOT)) + + if (!strcmp (path, DOT)) { /* nothing to do */ } - else if (!STRCMP (path, DOTS)) + else if (!strcmp (path, DOTS)) { if (*menu != NULL) *menu = (*menu)->parent; @@ -525,21 +555,21 @@ path = (p + 1); } } - if (!STRCMP (path, DOTS)) + + if (!strcmp (path, DOTS)) { - path += STRLEN (DOTS); + path += strlen (DOTS); if (*menu != NULL) *menu = (*menu)->parent; return path; } + /* find this menu */ if (*menu == NULL) { for (m = CurrentBar->tail; m != NULL; m = m->prev) - { - if (!STRCMP (path, m->name)) - break; - } + if (!strcmp (path, m->name)) + break; } else { @@ -547,18 +577,20 @@ for (item = (*menu)->tail; item != NULL; item = item->prev) { if (item->entry.type == MenuSubMenu - && !STRCMP (path, (item->entry.submenu.menu)->name)) + && !strcmp (path, (item->entry.submenu.menu)->name)) { m = (item->entry.submenu.menu); break; } } } + if (m != NULL) { *menu = m; - path += STRLEN (path); + path += strlen (path); } + return path; } @@ -570,7 +602,6 @@ { menu_t *parent = NULL, *prev, *next; menuitem_t *item; - bar_t *CurrentBar = CurrentBar; #ifdef DEBUG_STRICT assert (CurrentBar != NULL); @@ -620,14 +651,13 @@ item = menu->tail; while (item != NULL) { - menuitem_t *p = item->prev; + menuitem_t *p = item->prev; menuitem_free (menu, item); item = p; } - if (menu->name != NULL) - free (menu->name); + free (menu->name); free (menu); return parent; @@ -636,16 +666,15 @@ menu_t * rxvt_term::menu_add (menu_t *parent, char *path) { - menu_t *menu; - bar_t *CurrentBar = CurrentBar; + menu_t *menu; #ifdef DEBUG_STRICT assert (CurrentBar != NULL); #endif - if (STRCHR (path, '/') != NULL) + if (strchr (path, '/') != NULL) { - char *p; + char *p; if (path[0] == '/') { @@ -653,7 +682,7 @@ path++; parent = NULL; } - while ((p = STRCHR (path, '/')) != NULL) + while ((p = strchr (path, '/')) != NULL) { p[0] = '\0'; if (path[0] == '\0') @@ -663,10 +692,10 @@ path = (p + 1); } } - if (!STRCMP (path, DOTS)) + if (!strcmp (path, DOTS)) return (parent != NULL ? parent->parent : parent); - if (!STRCMP (path, DOT) || path[0] == '\0') + if (!strcmp (path, DOT) || path[0] == '\0') return parent; /* allocate a new menu */ @@ -674,15 +703,16 @@ menu->width = 0; menu->parent = parent; - menu->len = STRLEN (path); + menu->len = strlen (path); menu->name = (char *)rxvt_malloc ((menu->len + 1)); - STRCPY (menu->name, path); + strcpy (menu->name, path); /* initialize head/tail */ menu->head = menu->tail = NULL; menu->prev = menu->next = NULL; menu->win = None; + menu->drawable = 0; menu->x = menu->y = menu->w = menu->h = 0; menu->item = NULL; @@ -781,8 +811,7 @@ x -= SHADOW + (3 * w / 2); y += SHADOW * 3; - rxvt_Draw_Triangle (display->display, ActiveMenu->win, top, bot, x, y, w, - 'r'); + rxvt_Draw_Triangle (display->display, ActiveMenu->win, top, bot, x, y, w, 'r'); } void @@ -824,6 +853,7 @@ fprintf (stderr, "Top Level menu\n"); return; } + fprintf (stderr, "menu %s ", menu->name); if (menu->parent != NULL) { @@ -837,12 +867,14 @@ break; } } + if (item == NULL) { fprintf (stderr, "is an orphan!\n"); return; } } + fprintf (stderr, "\n"); rxvt_print_menu_ancestors (menu->parent); } @@ -895,9 +927,8 @@ void rxvt_term::menu_show () { - int x, y, xright; - menu_t *ActiveMenu = ActiveMenu; - menuitem_t *item; + int x, y, xright; + menuitem_t *item; if (ActiveMenu == NULL) return; @@ -922,6 +953,7 @@ : HEIGHT_TEXT + 2 * SHADOW; ActiveMenu->h = h + 2 * SHADOW; } + if (ActiveMenu->win == None) { ActiveMenu->win = XCreateSimpleWindow (display->display, TermWin.vt, @@ -930,8 +962,10 @@ 0, PixColors[Color_fg], PixColors[Color_scroll]); + ActiveMenu->drawable = new rxvt_drawable (display, ActiveMenu->win); XMapWindow (display->display, ActiveMenu->win); } + rxvt_Draw_Shadow (display->display, ActiveMenu->win, topShadowGC, botShadowGC, 0, 0, ActiveMenu->w, ActiveMenu->h); @@ -943,9 +977,9 @@ for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next) { - const int xoff = (SHADOW + Width2Pixel (HSPACE) / 2); - register int h; - GC gc = menubarGC; + const int xoff = (SHADOW + Width2Pixel (HSPACE) / 2); + register int h; + GC gc = menubarGC; if (isSeparator (item->name)) { @@ -961,9 +995,7 @@ int len = item->len; if (item->entry.type == MenuLabel) - { - gc = botShadowGC; - } + gc = botShadowGC; else if (item->entry.type == MenuSubMenu) { int x1, y1; @@ -1001,22 +1033,19 @@ menu->x = (x1 < 0 ? 0 : x1); menu->y = (y1 < 0 ? 0 : y1); } - else if (item->name2 && !STRCMP (name, item->name2)) + else if (item->name2 && !strcmp (name, item->name2)) name = NULL; if (len && name) - draw_string (display->display, ActiveMenu->win, gc, xoff, - 2 * SHADOW + y + TermWin.font->ascent + 1, - name, len); + draw_string (*ActiveMenu->drawable, gc, TermWin.fontset, + xoff, 2 * SHADOW + y, name, len); len = item->len2; name = item->name2; if (len && name) - draw_string (display->display, ActiveMenu->win, gc, - ActiveMenu->w - (xoff + Width2Pixel (xright)), - 2 * SHADOW + y + TermWin.font->ascent + 1, - name, len); + draw_string (*ActiveMenu->drawable, gc, TermWin.fontset, + ActiveMenu->w - (xoff + Width2Pixel (xright)), 2 * SHADOW + y, name, len); h = HEIGHT_TEXT + 2 * SHADOW; } @@ -1027,10 +1056,10 @@ void rxvt_term::menu_display (void (rxvt_term::*update) ()) { - menu_t *ActiveMenu = ActiveMenu; - if (ActiveMenu == NULL) return; + + delete ActiveMenu->drawable; if (ActiveMenu->win != None) XDestroyWindow (display->display, ActiveMenu->win); ActiveMenu->win = None; @@ -1038,6 +1067,7 @@ if (ActiveMenu->parent == NULL) drawbox_menubar (ActiveMenu->x, ActiveMenu->len, +1); + ActiveMenu = ActiveMenu->parent; (this->*update) (); } @@ -1059,7 +1089,7 @@ { if (menu != NULL) { - menuitem_t *item = menu->tail; + menuitem_t *item = menu->tail; while (item != NULL) { @@ -1076,15 +1106,13 @@ void rxvt_term::menubar_clear () { - bar_t *CurrentBar = CurrentBar; - if (CurrentBar != NULL) { - menu_t *menu = CurrentBar->tail; + menu_t *menu = CurrentBar->tail; while (menu != NULL) { - menu_t *prev = menu->prev; + menu_t *prev = menu->prev; menu_delete (menu); menu = prev; @@ -1096,8 +1124,10 @@ free (CurrentBar->title); CurrentBar->title = NULL; } + menuarrow_free (0); /* remove all arrow functions */ } + ActiveMenu = NULL; } @@ -1106,7 +1136,7 @@ bar_t * rxvt_term::menubar_find (const char *name) { - bar_t *bar = CurrentBar; + bar_t *bar = CurrentBar; #ifdef DEBUG_MENUBAR_STACKING fprintf (stderr, "looking for [menu:%s] ...", name ? name : " (nil)"); @@ -1114,11 +1144,11 @@ if (bar == NULL || name == NULL) return NULL; - if (STRLEN (name) && STRCMP (name, "*")) + if (strlen (name) && strcmp (name, "*")) { do { - if (!STRCMP (bar->name, name)) + if (!strcmp (bar->name, name)) { #ifdef DEBUG_MENUBAR_STACKING fprintf (stderr, " found!\n"); @@ -1140,15 +1170,15 @@ int rxvt_term::menubar_push (const char *name) { - int ret = 1; - bar_t *bar; + int ret = 1; + bar_t *bar; if (CurrentBar == NULL) { /* allocate first one */ bar = (bar_t *) rxvt_malloc (sizeof (bar_t)); - MEMSET (bar, 0, sizeof (bar_t)); + memset (bar, 0, sizeof (bar_t)); /* circular linked-list */ bar->next = bar->prev = bar; bar->head = bar->tail = NULL; @@ -1199,12 +1229,13 @@ CurrentBar = bar; } + menubar_clear (); } } /* give menubar this name */ - STRNCPY (CurrentBar->name, name, MAXNAME); + strncpy (CurrentBar->name, name, MAXNAME); CurrentBar->name[MAXNAME - 1] = '\0'; return ret; @@ -1247,14 +1278,14 @@ CurrentBar = prev; } } - while (CurrentBar && !STRCMP (name, "*")); + while (CurrentBar && !strcmp (name, "*")); } void rxvt_action_decode (FILE *fp, action_t *act) { - unsigned char *str; - short len; + unsigned char *str; + short len; if (act == NULL || (len = act->len) == 0 || (str = act->str) == NULL) return; @@ -1287,6 +1318,7 @@ break; } } + /* * control character form is preferred, since backslash-escaping * can be really ugly looking when the backslashes themselves also @@ -1322,8 +1354,10 @@ fprintf (fp, "%c", ch); break; } + len--; } + fprintf (fp, "\n"); } @@ -1347,13 +1381,13 @@ break; case MenuLabel: - fprintf (fp, "{%s}\n", (STRLEN (item->name) ? item->name : "-")); + fprintf (fp, "{%s}\n", (strlen (item->name) ? item->name : "-")); break; case MenuTerminalAction: case MenuAction: fprintf (fp, "{%s}", item->name); - if (item->name2 != NULL && STRLEN (item->name2)) + if (item->name2 != NULL && strlen (item->name2)) fprintf (fp, "{%s}", item->name2); fprintf (fp, "\t"); rxvt_action_decode (fp, & (item->entry.action)); @@ -1375,7 +1409,7 @@ time (&t); fprintf (fp, - "# " APL_SUBCLASS " (%s) Pid: %u\n# Date: %s\n\n", + "# " RESCLASS " (%s) Pid: %u\n# Date: %s\n\n", rs[Rs_name], (unsigned int)getpid (), ctime (&t)); /* dump in reverse order */ @@ -1439,6 +1473,7 @@ file = (char *)rxvt_File_find (filename, ".menu", rs[Rs_path]); if (file == NULL) return; + fp = fopen (file, "rb"); free (file); if (fp == NULL) @@ -1446,7 +1481,7 @@ #if (MENUBAR_MAX > 1) /* semi-colon delimited */ - if ((tag = STRCHR (filename, ';')) != NULL) + if ((tag = strchr (filename, ';')) != NULL) { tag++; if (*tag == '\0') @@ -1554,8 +1589,8 @@ void rxvt_term::menubar_dispatch (char *str) { - int n, cmd; - char *path, *name, *name2; + int n, cmd; + char *path, *name, *name2; if (menubar_visible () && ActiveMenu != NULL) menubar_expose (); @@ -1596,7 +1631,7 @@ do { next++; - if ((next = STRCHR (next, ':')) == NULL) + if ((next = strchr (next, ':')) == NULL) return; /* parse error */ } while (next[1] != ']'); @@ -1606,7 +1641,7 @@ } else { - if ((next = STRCHR (next, ']')) == NULL) + if ((next = strchr (next, ']')) == NULL) return; /* parse error */ /* remove and skip ']' */ *next = '\0'; @@ -1624,20 +1659,20 @@ menu_readonly = saved; } /* these ones don't require menu stacking */ - else if (!STRCMP (str, "clear")) + else if (!strcmp (str, "clear")) { menubar_clear (); } - else if (!STRCMP (str, "done") || rxvt_Str_match (str, "done:")) + else if (!strcmp (str, "done") || rxvt_Str_match (str, "done:")) { menu_readonly = 1; } - else if (!STRCMP (str, "show")) + else if (!strcmp (str, "show")) { map_menuBar (1); menu_readonly = 1; } - else if (!STRCMP (str, "hide")) + else if (!strcmp (str, "hide")) { map_menuBar (0); menu_readonly = 1; @@ -1655,10 +1690,10 @@ { if (*str) { - name = (char *)rxvt_realloc (CurrentBar->title, STRLEN (str) + 1); + name = (char *)rxvt_realloc (CurrentBar->title, strlen (str) + 1); if (name != NULL) { - STRCPY (name, str); + strcpy (name, str); CurrentBar->title = name; } menubar_expose (); @@ -1673,7 +1708,7 @@ else if ((n = rxvt_Str_match (str, "pixmap:")) != 0) { str += n; - xterm_seq (XTerm_Pixmap, str, CHAR_ST); + process_xterm_seq (XTerm_Pixmap, str, CHAR_ST); } #if (MENUBAR_MAX > 1) else if ((n = rxvt_Str_match (str, "rm")) != 0) @@ -1713,7 +1748,7 @@ if (CurrentBar != NULL) menu_readonly = 0; /* allow menu build commands */ } - else if (!STRCMP (str, "dump")) + else if (!strcmp (str, "dump")) { /* dump current menubars to a file */ FILE *fp; @@ -1721,17 +1756,17 @@ /* enough space to hold the results */ char buffer[32]; - sprintf (buffer, "/tmp/" APL_SUBCLASS "-%u", + sprintf (buffer, "/tmp/" RESCLASS "-%u", (unsigned int)getpid ()); if ((fp = fopen (buffer, "wb")) != NULL) { - xterm_seq (XTerm_title, buffer, CHAR_ST); + process_xterm_seq (XTerm_title, buffer, CHAR_ST); menubar_dump (fp); fclose (fp); } } - else if (!STRCMP (str, "next")) + else if (!strcmp (str, "next")) { if (CurrentBar) { @@ -1739,7 +1774,7 @@ menu_readonly = 1; } } - else if (!STRCMP (str, "prev")) + else if (!strcmp (str, "prev")) { if (CurrentBar) { @@ -1747,7 +1782,7 @@ menu_readonly = 1; } } - else if (!STRCMP (str, "swap")) + else if (!strcmp (str, "swap")) { /* swap the top 2 menus */ if (CurrentBar) @@ -1806,24 +1841,24 @@ /* parse STR, allow spaces inside (name) */ if (path[0] != '\0') { - name = STRCHR (path, MENUITEM_BEG); - str = STRCHR (path, MENUITEM_END); + name = strchr (path, MENUITEM_BEG); + str = strchr (path, MENUITEM_END); if (name != NULL || str != NULL) { if (name == NULL || str == NULL || str <= (name + 1) || (name > path && name[-1] != '/')) { - rxvt_print_error ("menu error <%s>\n", path); + rxvt_warn ("menu error A<%s>, continuing.\n", path); break; } if (str[1] == MENUITEM_BEG) { name2 = (str + 2); - str = STRCHR (name2, MENUITEM_END); + str = strchr (name2, MENUITEM_END); if (str == NULL) { - rxvt_print_error ("menu error <%s>\n", path); + rxvt_warn ("menu error B<%s>, continuing.\n", path); break; } name2[-2] = '\0'; /* remove prev MENUITEM_END */ @@ -1855,7 +1890,7 @@ int len; path = menu_find_base (& (BuildMenu), path); - len = STRLEN (path); + len = strlen (path); /* don't allow menus called `*' */ if (path[0] == '*') @@ -1863,7 +1898,7 @@ menu_clear (BuildMenu); break; } - else if (len >= 2 && !STRCMP ((path + len - 2), "/*")) + else if (len >= 2 && !strcmp ((path + len - 2), "/*")) { path[len - 2] = '\0'; } @@ -1872,12 +1907,12 @@ } if (name != NULL && name[0] != '\0') rxvt_menuitem_add (BuildMenu, - (STRCMP (name, SEPARATOR_NAME) ? name : ""), + (strcmp (name, SEPARATOR_NAME) ? name : ""), name2, str); break; case '-': /* delete menu entry */ - if (!STRCMP (path, "/*") && (name == NULL || name[0] == '\0')) + if (!strcmp (path, "/*") && (name == NULL || name[0] == '\0')) { menubar_clear (); BuildMenu = NULL; @@ -1890,7 +1925,7 @@ menu_t *menu = BuildMenu; path = menu_find_base (&menu, path); - len = STRLEN (path); + len = strlen (path); /* submenu called `*' clears all menu items */ if (path[0] == '*') @@ -1898,7 +1933,7 @@ menu_clear (menu); break; /* done */ } - else if (len >= 2 && !STRCMP (&path[len - 2], "/*")) + else if (len >= 2 && !strcmp (&path[len - 2], "/*")) { /* done */ break; @@ -1921,7 +1956,7 @@ menuitem_t *item; menu_t *BuildMenu = BuildMenu; - n1 = STRCMP (name, SEPARATOR_NAME) ? name : ""; + n1 = strcmp (name, SEPARATOR_NAME) ? name : ""; item = rxvt_menuitem_find (BuildMenu, n1); if (item != NULL && item->entry.type != MenuSubMenu) { @@ -1976,9 +2011,9 @@ for (i = 0; i < NARROWS; i++) { - const int w = Width2Pixel (1); - const int y = (menuBar_TotalHeight () - w) / 2; - int x = Arrows_x + (5 * Width2Pixel (i)) / 4; + const int w = Width2Pixel (1); + const int y = (menuBar_TotalHeight () - w) / 2; + int x = Arrows_x + (5 * Width2Pixel (i)) / 4; if (!name || name == Arrows[i].name) rxvt_Draw_Triangle (display->display, menuBar.win, top, bot, x, y, w, @@ -1990,8 +2025,8 @@ void rxvt_term::menubar_expose () { - menu_t *menu; - int x; + menu_t *menu; + int x; if (!menubar_visible () || menuBar.win == 0) return; @@ -2001,17 +2036,13 @@ /* Create the graphics context */ XGCValues gcvalue; - gcvalue.font = TermWin.font->fid; - - gcvalue.foreground = (XDEPTH <= 2 ? PixColors[Color_fg] + gcvalue.foreground = (display->depth <= 2 ? PixColors[Color_fg] : PixColors[Color_Black]); menubarGC = XCreateGC (display->display, menuBar.win, - GCForeground | GCFont, &gcvalue); + GCForeground, &gcvalue); } /* make sure the font is correct */ - XSetFont (display->display, menubarGC, TermWin.font->fid); - XSetFont (display->display, botShadowGC, TermWin.font->fid); XClearWindow (display->display, menuBar.win); menu_hide_all (); @@ -2033,9 +2064,9 @@ len = (TermWin.ncol - (menu->x + HSPACE)); drawbox_menubar (menu->x, len, +1); - draw_string (display->display, menuBar.win, menubarGC, + draw_string (*menuBar.drawable, menubarGC, TermWin.fontset, (Width2Pixel (menu->x) + Width2Pixel (HSPACE) / 2), - menuBar_height () - SHADOW, menu->name, len); + SHADOW, menu->name, len); if (x >= TermWin.ncol) break; @@ -2096,9 +2127,9 @@ ncol -= (x + len + HSPACE); if (len > 0 && ncol >= 0) - draw_string (display->display, menuBar.win, menubarGC, + draw_string (*menuBar.drawable, menubarGC, TermWin.fontset, Width2Pixel (x) + Width2Pixel (ncol + HSPACE) / 2, - menuBar_height () - SHADOW, title, len); + SHADOW, title, len); } } @@ -2131,47 +2162,50 @@ int rxvt_term::menu_select (XButtonEvent &ev) { - menuitem_t *thisitem, *item = NULL; - int this_y, y; - menu_t *ActiveMenu = ActiveMenu; - - Window unused_root, unused_child; - int unused_root_x, unused_root_y; - unsigned int unused_mask; + menuitem_t *thisitem, *item = NULL; + int this_y, y; + + Window unused_root, unused_child; + int unused_root_x, unused_root_y; + unsigned int unused_mask; if (ActiveMenu == NULL) return 0; XQueryPointer (display->display, ActiveMenu->win, - &unused_root, &unused_child, - &unused_root_x, &unused_root_y, - &ev.x, &ev.y, &unused_mask); + &unused_root, &unused_child, + &unused_root_x, &unused_root_y, + &ev.x, &ev.y, &unused_mask); if (ActiveMenu->parent != NULL && (ev.x < 0 || ev.y < 0)) { menu_hide (); return 1; } + /* determine the menu item corresponding to the Y index */ y = SHADOW; if (ev.x >= 0 && ev.x <= (ActiveMenu->w - SHADOW)) { for (item = ActiveMenu->head; item != NULL; item = item->next) { - int h = HEIGHT_TEXT + 2 * SHADOW; + int h = HEIGHT_TEXT + 2 * SHADOW; if (isSeparator (item->name)) h = HEIGHT_SEPARATOR; else if (ev.y >= y && ev.y < (y + h)) break; + y += h; } } + if (item == NULL && ev.type == ButtonRelease) { menu_hide_all (); return 0; } + thisitem = item; this_y = y - SHADOW; @@ -2180,10 +2214,9 @@ { if (ActiveMenu->item != thisitem) { - for (y = 0, item = ActiveMenu->head; item != NULL; - item = item->next) + for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next) { - int h; + int h; if (isSeparator (item->name)) h = HEIGHT_SEPARATOR; @@ -2193,10 +2226,12 @@ drawbox_menuitem (y, 0); /* No Shadow */ if (item->entry.type == MenuSubMenu) drawtriangle (ActiveMenu->w, y, +1); + break; } else h = HEIGHT_TEXT + 2 * SHADOW; + y += h; } } @@ -2215,23 +2250,20 @@ case MenuAction: case MenuTerminalAction: drawbox_menuitem (this_y, -1); - { #ifdef HAVE_NANOSLEEP - struct timespec rqt; + struct timespec rqt; - rqt.tv_sec = 0; - rqt.tv_nsec = MENU_DELAY_USEC * 1000; - nanosleep (&rqt, NULL); + rqt.tv_sec = 0; + rqt.tv_nsec = MENU_DELAY_USEC * 1000; + nanosleep (&rqt, NULL); #else - /* use select for timing */ - struct timeval tv; + /* use select for timing */ + struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = MENU_DELAY_USEC; - select (0, NULL, NULL, NULL, &tv); + tv.tv_sec = 0; + tv.tv_usec = MENU_DELAY_USEC; + select (0, NULL, NULL, NULL, &tv); #endif - - } /* remove menu before sending keys to the application */ menu_hide_all (); #ifndef DEBUG_MENU @@ -2252,17 +2284,20 @@ return 0; } } + DoMenu: ActiveMenu->item = thisitem; y = this_y; - if (item != NULL) + + if (thisitem != NULL) { item = ActiveMenu->item; if (item->entry.type != MenuLabel) drawbox_menuitem (y, +1); + if (item->entry.type == MenuSubMenu) { - int x; + int x; drawtriangle (ActiveMenu->w, y, -1); @@ -2284,15 +2319,15 @@ void rxvt_term::menubar_select (XButtonEvent &ev) { - menu_t *menu = NULL; + menu_t *menu = NULL; /* determine the pulldown menu corresponding to the X index */ if (ev.y >= 0 && ev.y <= menuBar_height () && CurrentBar != NULL) { for (menu = CurrentBar->head; menu != NULL; menu = menu->next) { - int x = Width2Pixel (menu->x); - int w = Width2Pixel (menu->len + HSPACE); + int x = Width2Pixel (menu->x); + int w = Width2Pixel (menu->len + HSPACE); if ((ev.x >= x && ev.x < x + w)) break; @@ -2400,7 +2435,7 @@ case MotionNotify: while (XCheckTypedWindowEvent (display->display, TermWin.parent[0], - MotionNotify, (XEvent *)&ev)) ; + MotionNotify, (XEvent *)&ev)) ; if (ActiveMenu) while (menu_select (ev)) ;