?? menubar.c
字號:
cmd = '+'; break; case '+': case '-': str++; /* skip cmd character */ break; case '<': if (str[1] && str[2] == '>') /* arrow commands */ rxvt_menuarrow_add(r, str); break; case '[': /* extended command */ while (str[0] == '[') { unsigned char *next = (++str); /* skip leading '[' */ if (str[0] == ':') /* [:command:] */ { do { next++; if ((next = (unsigned char*) STRCHR(next, ':')) == NULL) return; /* parse error */ } while (next[1] != ']'); /* remove and skip ':]' */ *next = '\0'; next += 2; } else { if ((next = (unsigned char*) STRCHR(next, ']')) == NULL) return; /* parse error */ /* remove and skip ']' */ *next = '\0'; next++; } if (str[0] == ':') rxvt_menubar_dispatcher(r, str + 1); else if (!STRCMP(str, "clear")) rxvt_menubar_clear(r); else if ( !STRCMP((char*) str, "done") || rxvt_str_match( (char*) str, "done:") ) { /* We shouldn't ever get here */ assert(0); } /* * 2006-02-02 gi1242: Using this command in config files will * override the users --showmenu option. Since there are other * escape sequences and shortcuts to do the same, we don't need * this here. */#if 0 else if (!STRCMP(str, "show")) { if (rxvt_menubar_show(r)) rxvt_resize_on_subwin (r, SHOW_MENUBAR); } else if (!STRCMP(str, "hide")) { if (rxvt_menubar_hide(r)) rxvt_resize_on_subwin (r, HIDE_MENUBAR); }#endif else if ((n = rxvt_str_match( (char*) str, "read:")) != 0) { /* read in a menu from a file */ str += n; rxvt_menubar_load_file(r, str); } else if ((n = rxvt_str_match( (char*) str, "title:")) != 0) { str += n; if (*str) { name = rxvt_realloc(r->h->MenuBar.title, STRLEN(str) + 1); if (name != NULL) { STRCPY(name, str); r->h->MenuBar.title = name; } } else { free(r->h->MenuBar.title); r->h->MenuBar.title = NULL; } } else if ((n = rxvt_str_match( (char*) str, "pixmap:")) != 0) { str += n; rxvt_xterm_seq(r, ATAB(r), XTerm_Pixmap, (char*) str, CHAR_ST); } str = next; /* * 2006-02-04 gi1242: Don't clear the menu currently bieng * built. This will enable [read:...] commands to add to the * current menu, instead of the menubar. */#if 0 r->h->BuildMenu = r->h->ActiveMenu = NULL; rxvt_menubar_expose(r);#endif } return; break; } switch (cmd) { case '+': case '-': path = name = str; name2 = NULL; /* parse STR, allow spaces inside (name) */ if (path[0] != '\0') { name = (unsigned char*) STRCHR(path, MENUITEM_BEG); str = (unsigned char*) 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); break; } if (str[1] == MENUITEM_BEG) { name2 = (str + 2); str = (unsigned char*) STRCHR(name2, MENUITEM_END); if (str == NULL) { rxvt_print_error("menu error <%s>\n", path); break; } name2[-2] = '\0'; /* remove prev MENUITEM_END */ } if (name > path && name[-1] == '/') name[-1] = '\0'; *name++ = '\0'; /* delimit */ *str++ = '\0'; /* delimit */ while (isspace((int) *str)) str++; /* skip space */ }# ifdef DEBUG_MENU fprintf(stderr, "`%c' path = <%s>, name = <%s>, name2 = <%s>, action = <%s>\n", cmd, (path ? path : "(nil)"), (name ? name : "(nil)"), (name2 ? name2 : "(nil)"), (str ? str : "(nil)") );# endif } /* process the different commands */ switch (cmd) { case '+': /* add/replace existing menu or menuitem */ if (path[0] != '\0') { int len; DBG_MSG( 3, ( stderr, "Current menu %s\n", r->h->BuildMenu ? r->h->BuildMenu->name : "(nil)")); path = rxvt_menu_find_base(r, &(r->h->BuildMenu), path); len = STRLEN(path); /* don't allow menus called `*' */ if (path[0] == '*') { rxvt_menu_clear(r, r->h->BuildMenu); break; } else if (len >= 2 && !STRCMP((path + len - 2), "/*")) { path[len - 2] = '\0'; } if (path[0] != '\0') r->h->BuildMenu = rxvt_menu_add(r, r->h->BuildMenu, path); } if (name != NULL && name[0] != '\0') rxvt_menuitem_add(r, r->h->BuildMenu, (STRCMP(name, SEPARATOR_NAME) ? name : (unsigned char *) ""), name2, str); break; case '-': /* delete menu entry */ if ( !STRCMP(path, "/*") && (name == NULL || name[0] == '\0') ) { rxvt_menubar_clear(r); r->h->BuildMenu = NULL; break; } else if (path[0] != '\0') { int len; menu_t *menu = r->h->BuildMenu; path = rxvt_menu_find_base(r, &menu, path); len = STRLEN(path); /* submenu called `*' clears all menu items */ if (path[0] == '*') { rxvt_menu_clear(r, menu); break; /* done */ } else if (len >= 2 && !STRCMP(&path[len - 2], "/*")) { /* done */ break; } else if (path[0] != '\0') { r->h->BuildMenu = NULL; break; } else r->h->BuildMenu = menu; } if (r->h->BuildMenu != NULL) { if (name == NULL || name[0] == '\0') r->h->BuildMenu = rxvt_menu_delete(r, r->h->BuildMenu); else { const unsigned char *n1; menuitem_t *item; menu_t *BuildMenu = r->h->BuildMenu; n1 = STRCMP(name, SEPARATOR_NAME) ? name : (unsigned char*) ""; item = rxvt_menuitem_find(BuildMenu, n1); if ( item != NULL && item->entry.itemType != MenuSubMenu ) { rxvt_menuitem_free(r, BuildMenu, item); /* fix up the width */ BuildMenu->lwidth = BuildMenu->rwidth = 0; for (item = BuildMenu->head; item != NULL; item = item->next) { unsigned short l; l = PTEXTWIDTH( r, item->name, item->len); MAX_IT(BuildMenu->lwidth, l); l = PTEXTWIDTH( r, item->name2, item->len2); MAX_IT(BuildMenu->rwidth, l); } } } } break; } break; }}/*** general dispatch routine,** it would be nice to have `sticky' menus*//* EXTPROTO */voidrxvt_menubar_control(rxvt_t *r, XButtonEvent *ev){ DBG_MSG( 2, (stderr, "rxvt_menubar_control()\n")); switch (ev->type) { case ButtonPress: if (ev->button == Button1) rxvt_menubar_select(r, ev); break; case ButtonRelease: if (ev->button == Button1) rxvt_menu_select(r, ev); break; case MotionNotify: while (XCheckTypedWindowEvent(r->Xdisplay, r->TermWin.parent, MotionNotify, (XEvent *) ev)) ; if (r->h->ActiveMenu) while (rxvt_menu_select(r, ev)) ; else ev->y = -1; if (ev->y < 0) { Window unused_root, unused_child; int unused_root_x, unused_root_y; unsigned int unused_mask; XQueryPointer(r->Xdisplay, r->menuBar.win, &unused_root, &unused_child, &unused_root_x, &unused_root_y, &(ev->x), &(ev->y), &unused_mask); rxvt_menubar_select(r, ev); } break; }}/* * read in menubar commands from FILENAME * ignore all input before the tag line [menu] or [menu:???] * * Note that since File_find () is used, FILENAME can be semi-colon * delimited such that the second part can refer to a tag * so that a large `database' of menus can be collected together * * FILENAME = "file" * FILENAME = "file;" * read `file' starting with first [menu] or [menu:???] line * * FILENAME = "file;tag" * read `file' starting with [menu:tag] *//* EXTPROTO */voidrxvt_menubar_load_file(rxvt_t *r, const unsigned char *filename){/* read in a menu from a file */ FILE *fp; unsigned char buffer[256]; unsigned char *p, *file, *tag = NULL; DBG_MSG( 2, (stderr, "rxvt_menubar_load_file()\n")); file = (unsigned char*) rxvt_File_find( (char*) filename, ".menu", r->h->rs[Rs_path]); if (file == NULL) { rxvt_print_error( "Could not open file %s", filename); return; } fp = fopen( (char*) file, "rb"); free(file); if (fp == NULL) return; /* semi-colon delimited */ if ((tag = (unsigned char*) STRCHR(filename, ';')) != NULL) { tag++; if (*tag == '\0') tag = NULL; }# ifdef DEBUG_MENU fprintf(stderr, "[read:%s]\n", filename); if (tag) fprintf(stderr, "looking for [menu:%s]\n", tag);# endif while ((p = (unsigned char*) fgets( (char*) buffer, sizeof(buffer), fp)) != NULL) { int n; if ((n = rxvt_str_match( (char*) p, "[menu")) != 0) { if (tag) { /* looking for [menu:tag] */ if (p[n] == ':' && p[n + 1] != ']') { n++; n += rxvt_str_match( (char*) p + n, (char*) tag); if (p[n] == ']') {# ifdef DEBUG_MENU fprintf(stderr, "[menu:%s]\n", tag);# endif break; } } } else if (p[n] == ':' || p[n] == ']') break; } } /* found [menu], [menu:???] tag */ while (p != NULL) { int n;# ifdef DEBUG_MENU fprintf(stderr, "read line = %s\n", p);# endif /* looking for [done:tag] or [done:] */ if ((n = rxvt_str_match( (char*) p, "[done")) != 0) { if (p[n] == ']') { break; } else if (p[n] == ':') { n++; if (p[n] == ']') { break; } else if (tag) { n += rxvt_str_match( (char*) p + n, (char*) tag); if (p[n] == ']') {# ifdef DEBUG_MENU fprintf(stderr, "[done:%s]\n", tag);# endif break; } } else { /* what? ... skip this line */ p[0] = COMMENT_CHAR; } } } /* * remove leading/trailing space and strip-off leading/trailing quotes * skip blank or comment lines */ rxvt_str_trim( (char*) p); if (*p && *p != '#') rxvt_menubar_dispatcher(r, p); /* get another line */ p = (unsigned char*) fgets( (char*) buffer, sizeof(buffer), fp); } fclose(fp);}/* EXTPROTO */unsigned shortrxvt_menubar_height(rxvt_t *r){ DBG_MSG( 3, (stderr, "rxvt_menubar_height()\n")); /* If menubar is not created or not mapped, return 0 */ return (None == r->menuBar.win || !r->menuBar.state) ? 0 : rxvt_menubar_rheight(r);}/* EXTPROTO */unsigned shortrxvt_menubar_rheight(rxvt_t *r){ DBG_MSG( 3, (stderr, "rxvt_menubar_rheight()\n"));# ifdef XFT_SUPPORT if( r->Options & Opt_xft ) return (r->TermWin.pheight + 2*SHADOW + 2*MENUBAR_MARGIN); else# endif return (r->TermWin.fheight + 2*SHADOW + 2*MENUBAR_MARGIN);}/* EXTPROTO */intrxvt_is_menubar_win(rxvt_t *r, Window w){ DBG_MSG( 3, (stderr, "rxvt_is_menubar_win()\n")); return (w == r->menuBar.win);}/* EXTPROTO */voidrxvt_menubar_resize(rxvt_t *r){ menu_t *menu; int i; DBG_MSG( 2, (stderr, "rxvt_menubar_resize()\n")); if (None != r->menuBar.win && r->menuBar.state) XMoveResizeWindow(r->Xdisplay, r->menuBar.win, 0, 0, TWIN_WIDTH(r), rxvt_menubar_rheight(r)); /* * All submenus now need to be traversed and resized. */ for (menu = r->h->MenuBar.head; menu != NULL; menu = menu->next) { resizeSubMenus( r, menu ); /* X coordinate of menu names in menubar need to be updated */ if( menu->prev ) menu->x = menu->prev->x + 2 * HSPACE_PIXEL + PTEXTWIDTH( r, menu->prev->name, menu->prev->len); } /* * Resize the popup menus if any. */ for( i=0; i < 3; i++) if( r->h->popupMenu[i] ) resizeSubMenus( r, r->h->popupMenu[i]);}/* * Update menu->width for all submenus. *//* INTPROTO */voidresizeSubMenus( rxvt_t *r, menu_t *menu){ menuitem_t *item; menu->lwidth = menu->rwidth = 0; for( item = menu->head; item != NULL; item = item->next) { unsigned short width; width = PTEXTWIDTH( r, item->name, item->len); if( menu->lwidth < width ) menu->lwidth = width; width = PTEXTWIDTH( r, item->name2, item->len2); if( menu->rwidth < width ) menu->rwidth = width; if( item->entry.itemType == MenuSubMenu && item->entry.submenu.menu) resizeSubMenus( r, item->entry.submenu.menu ); }}#endif /* HAVE_MENUBAR *//*----------------------- end-of-file (C source) -----------------------*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -