⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menubar.c

📁 multi-tabed terminal based on rxvt
💻 C
📖 第 1 页 / 共 5 页
字号:
	while (NOT_NULL(p = (unsigned char*) STRCHR(path, '/')))	{	    p[0] = '\0';	    if (path[0] == '\0')	    return NULL;	    if (!STRCMP(path, DOT))	    {		/* nothing to do */	    }	    else if (!STRCMP(path, DOTS))	    {		if (NOT_NULL(*menu))		    *menu = (*menu)->parent;	    }	    else	    {		path = rxvt_menu_find_base(r, menu, path);		if (path[0] != '\0')		/* not found */		{		    p[0] = '/';	/* fix-up name again */		    return path;		}	    }	    path = (p + 1);	}    }    if (!STRCMP(path, DOTS))    {	path += STRLEN(DOTS);	if (NOT_NULL(*menu))	    *menu = (*menu)->parent;	return path;    }    /* find this menu */    if (IS_NULL(*menu))    {	for (m = r->h->MenuBar.tail; NOT_NULL(m); m = m->prev)	{	    if (!STRCMP(path, m->name))	    break;	}    }    else    {	/* find this menu */	for (item = (*menu)->tail; NOT_NULL(item); item = item->prev)	{	    if (		    item->entry.itemType == MenuSubMenu		    && !STRCMP(path, (item->entry.submenu.menu)->name)	       )	    {		m = (item->entry.submenu.menu);		break;	    }	}    }    if (NOT_NULL(m))    {	*menu = m;	path += STRLEN(path);    }    return path;}/* * delete this entire menu *//* INTPROTO */menu_t*rxvt_menu_delete(rxvt_t *r, menu_t *menu){    menu_t	 *parent = NULL, *prev, *next;    menuitem_t	 *item;    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_menu_delete()\n"));    assert( menu != r->h->ActiveMenu ); /* Shouldn't delete current menu */    /* delete the entire menu */    if (IS_NULL(menu)) return NULL;    parent = menu->parent;    /* unlink MENU */    prev = menu->prev;    next = menu->next;    if (NOT_NULL(prev)) prev->next = next;    if (NOT_NULL(next)) next->prev = prev;    if (IS_NULL(parent))    {	/*	 * If we got here, then this menu is either a popup menu, or a pulldown	 * submenu of the main menubar.	 */	const int width = 2 * HSPACE_PIXEL +	    PTEXTWIDTH( r, menu->name, menu->len);	/*	 * Reset start / end of menus in the menubar if we deleted the first /	 * last pulldown menu.	 */	if (r->h->MenuBar.tail == menu) r->h->MenuBar.tail = prev;	if (r->h->MenuBar.head == menu) r->h->MenuBar.head = next;	/*	 * Move all subsequent entries of the menubar to the left. Popups don't	 * have next or prev set, so no worries doing this	 */	for (next = menu->next; NOT_NULL(next); next = next->next)	    next->x -= width;    }    else    {	for (item = parent->tail; NOT_NULL(item); item = item->prev)	{	    if (item->entry.itemType == MenuSubMenu		    && item->entry.submenu.menu == menu)	    {		/* Unlink from the parent menu */		SET_NULL(item->entry.submenu.menu);		rxvt_menuitem_free(r, menu->parent, item);		break;	    }	}    }    item = menu->tail;    while (NOT_NULL(item))    {	menuitem_t   *p = item->prev;	rxvt_menuitem_free(r, menu, item);	item = p;    }    rxvt_free(menu->name);    rxvt_free(menu);    return parent;}/* INTPROTO */menu_t*rxvt_menu_add(rxvt_t *r, menu_t *parent, unsigned char *path){    menu_t	 *menu;    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_menu_add(): Adding menu %s to parent %s\n", path, NOT_NULL(parent) ? (char *)parent->name : "(nil)"));    if (NOT_NULL(STRCHR(path, '/')))    {	unsigned char	*p;	if (path[0] == '/')	{	    /* shouldn't happen */	    path++;	    SET_NULL(parent);	}	while (NOT_NULL(p = (unsigned char*) STRCHR(path, '/')))	{	    p[0] = '\0';	    if (path[0] == '\0')	    return NULL;	    parent = rxvt_menu_add(r, parent, path);	    path = (p + 1);	}    }    if (!STRCMP(path, DOTS))	return (NOT_NULL(parent) ? parent->parent : parent);    if (!STRCMP(path, DOT) || path[0] == '\0')	return parent;    /* allocate a new menu */    menu = (menu_t *) rxvt_malloc(sizeof(menu_t));    menu->lwidth = menu->rwidth = 0;    menu->parent = parent;    menu->len = STRLEN(path);    /* possible integer overflow? */    assert (menu->len > 0 && menu->len+1 > 0);    menu->name = rxvt_malloc((menu->len + 1));    STRCPY(menu->name, path);    /* initialize head/tail */    SET_NULL(menu->head);    SET_NULL(menu->tail);    SET_NULL(menu->prev);    SET_NULL(menu->next);    UNSET_WIN(menu->win);    menu->x = menu->y = menu->height = 0;    SET_NULL(menu->item);    if (IS_NULL(parent))    {	/* Add menus named PopupButton%d to popupMenu[%d] */	if(	    !STRNCASECMP("popupbutton", (char*) path, (sizeof("popupbutton")-1)) &&	    path[sizeof("popupbutton")-1] >= '1' &&	    path[sizeof("popupbutton")-1] <= '3' &&	    path[sizeof("popupbutton")] == '\0'	  )	{	    int i = path[sizeof("popupbutton")-1] - '1';	    /* Free the menu */	    if( r->h->popupMenu[i] )		rxvt_menu_delete( r, r->h->popupMenu[i] );	    r->h->popupMenu[i] = menu;	}	else	{	    /*	     * Add this menu as a the last pulldown menu in the menubar.	     */	    menu->prev = r->h->MenuBar.tail;	    if (NOT_NULL(r->h->MenuBar.tail))		r->h->MenuBar.tail->next = menu;	    r->h->MenuBar.tail = menu;	    /* fix head */	    if (IS_NULL(r->h->MenuBar.head))		r->h->MenuBar.head = menu;	    if (menu->prev)		menu->x = menu->prev->x + 2 * HSPACE_PIXEL		    + PTEXTWIDTH( r, menu->prev->name, menu->prev->len);	}    }    else    {	menuitem_t   *item;	item = rxvt_menuitem_add(r, parent, path, (unsigned char*) "",		(unsigned char*) "");		if (IS_NULL(item))	{	    if (NOT_NULL(menu->name))		rxvt_free( menu->name );	    rxvt_free(menu);	    return parent;	}#ifdef DEBUG	assert(item->entry.itemType == MenuLabel);#endif	item->entry.itemType = MenuSubMenu;	item->entry.submenu.menu = menu;    }    return menu;}/* INTPROTO */voidrxvt_drawbox_menubar(rxvt_t *r, int x, int len, int state){    unsigned long   top, bot;    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_drawbox_menubar()\n"));    /* XXXMENU */    len += HSPACE_PIXEL + SHADOW;    if (x >= TWIN_WIDTH(r))	return;    else if (x + len >= TWIN_WIDTH(r))	len = (TWIN_WIDTH(r) - x);#ifdef MENUBAR_SHADOW_IN    state = -state;#endif    switch (state)    {	case +1:	    top = r->menuBar.topshadow;	    bot = r->menuBar.botshadow;	    break;	    /* SHADOW_OUT */	case -1:	    top = r->menuBar.botshadow;	    bot = r->menuBar.topshadow;	    break;	    /* SHADOW_IN */	default:	    top = bot = r->menuBar.bg;	    break;	    /* neutral */    }    rxvt_draw_shadow(r->Xdisplay, r->menuBar.win, r->menuBar.gc,	top, bot, x, 0, len, rxvt_menubar_height(r));}/* INTPROTO */voidrxvt_menubar_draw_triangle(rxvt_t *r, int x, int y, int state){    unsigned long   top, bot;    int		    w;    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_menubar_draw_triangle()\n"));#ifdef MENU_SHADOW_IN    state = -state;#endif    switch (state)    {	case +1:	    top = r->menuBar.topshadow;	    bot = r->menuBar.botshadow;	    break;	    /* SHADOW_OUT */	case -1:	    top = r->menuBar.botshadow;	    bot = r->menuBar.topshadow;	    break;	    /* SHADOW_IN */	default:	    top = bot = r->menuBar.bg;	    break;	    /* neutral */    }    w = TRIANGLE_WIDTH;    x -= SHADOW + (3 * w / 2);    y += SHADOW*2 + (HEIGHT_TEXT - TRIANGLE_WIDTH)/2;    rxvt_draw_triangle (r->Xdisplay, r->h->ActiveMenu->win, r->menuBar.gc, top, bot, x, y, w, 'r');}/* INTPROTO */voidrxvt_drawbox_menuitem(rxvt_t *r, int y, int state){    unsigned long   top, bot;    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_drawbox_menuitem()\n"));#ifdef MENU_SHADOW_IN    state = -state;#endif    switch (state)    {	case +1:	    top = r->menuBar.topshadow;	    bot = r->menuBar.botshadow;	    break;	    /* SHADOW_OUT */	case -1:	    top = r->menuBar.botshadow;	    bot = r->menuBar.topshadow;	    break;	    /* SHADOW_IN */	default:	    top = bot = r->menuBar.bg;	    break;	    /* neutral */    }    rxvt_draw_shadow (r->Xdisplay, r->h->ActiveMenu->win, r->menuBar.gc,	top, bot,	SHADOW + 0, SHADOW + y,	MENUWIDTH( r->h->ActiveMenu ) - 2 * (SHADOW),	HEIGHT_TEXT + 2 * SHADOW);    XFlush(r->Xdisplay);}#ifdef DEBUG/* INTPROTO */voidrxvt_print_menu_ancestors(menu_t *menu){    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_print_menu_ancestors()\n"));    if (IS_NULL(menu))    {	rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "Top Level menu\n"));	return;    }    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "menu %s ", menu->name));    if (NOT_NULL(menu->parent))    {	menuitem_t   *item;	for (item = menu->parent->head; NOT_NULL(item); item = item->next)	{	    if (item->entry.itemType == MenuSubMenu &&		item->entry.submenu.menu == menu)	    {		break;	    }	}	if (IS_NULL(item))	{	    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "is an orphan!\n"));	    return;	}    }    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "\n"));    rxvt_print_menu_ancestors(menu->parent);}/* INTPROTO */voidrxvt_print_menu_descendants(menu_t *menu){    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_print_menu_descendants()\n"));    menuitem_t	 *item;    menu_t	 *parent;    int		 i, level = 0;    parent = menu;    do      {	level++;	parent = parent->parent;      }    while (NOT_NULL(parent));    for (i = 0; i < level; i++)    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, ">"));    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "%s\n", menu->name));    for (item = menu->head; NOT_NULL(item); item = item->next)    {	if (item->entry.itemType == MenuSubMenu)	{	    if (IS_NULL(item->entry.submenu.menu))		rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "> %s == NULL\n", item->name));	    else		rxvt_print_menu_descendants(item->entry.submenu.menu);	}	else	{	    for (i = 0; i < level; i++)		rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "+"));	    if (item->entry.itemType == MenuLabel)		rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "label: "));	    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "%s\n", item->name));	}    }    for (i = 0; i < level; i++)    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "<"));    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "\n"));}#endif	/* DEBUG *//* * Build a menu with all the titles of current tabs. *//* INTPROTO */voidrxvt_build_tablist(rxvt_t *r, menu_t *menu){    int i;    unsigned char   action[16],		    title[MAX_DISPLAY_TAB_TXT + 4];    assert( menu);    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_build_tablist()\n"));    /*     * Empty menus should get renamed to "Switch to tab".     */    if( !menu->head && STRCMP( menu->name, "Switch to tab"))    {	rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "Renaming menu to Switch to tab\n"));	menu->name = rxvt_realloc( menu->name, 14);	STRCPY( menu->name, "Switch to tab");    }    rxvt_menu_clear( r, menu);    for( i=0; i <= LTAB(r); i++)    {	sprintf( (char*) title, "%2d. %.*s", i+1, MAX_DISPLAY_TAB_TXT-1,		PVTS(r, i)->tab_title);	/* sprintf( action, "]\e]%d;%d\a", Xterm_switchtab, i+1); */	sprintf( (char*) action, "GotoTab %d", i + 1);	rxvt_menuitem_add( r, menu, title, NULL, action);	rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "Added menuentry for %s\n", PVTS(r, i)->tab_title));    }}/* pop up/down the current menu and redraw the menuBar button *//* EXTPROTO */voidrxvt_menu_show(rxvt_t *r){    int		 y, xright;    menu_t	 *ActiveMenu = r->h->ActiveMenu;    menuitem_t	 *item;    unsigned short amenu_width;    rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_menu_show()\n"));    if (IS_NULL(ActiveMenu))	return;    /*     * Popup tablist for menus named tablist, or empty popupbutton menus.     */    if(	 !STRCASECMP( (char*) ActiveMenu->name, "Switch to tab")	 || (	      !STRNCASECMP( (char*) ActiveMenu->name, "popupbutton", 11 )	      && ActiveMenu->head == NULL	    )      )	rxvt_build_tablist( r, ActiveMenu );    if (IS_NULL(ActiveMenu->parent))    {	register int	h;	/* find the height */	for (h = 0, item = ActiveMenu->head; NOT_NULL(item); item = item->next)	    h += isSeparator(item->name) ? HEIGHT_SEPARATOR		     : HEIGHT_TEXT + 2 * SHADOW;	ActiveMenu->height = h + 2 * SHADOW;	if( !( r->h->showingMenu & POPUP_MENU ))	{	    rxvt_drawbox_menubar(r, ActiveMenu->x,		    PTEXTWIDTH( r, ActiveMenu->name, ActiveMenu->len), -1);	    ActiveMenu->y = rxvt_menubar_height( r );	}    }    amenu_width = MENUWIDTH( ActiveMenu );    /*     * Move popup menus, or submenus back on screen if they are not completely     * on screen.     *     * XXX 2006-02-02 gi1242: It would be a LOT nicer if we could move all     * parents of the menu too. We should only do this for popup menus. This is     * what fvwm does :)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -