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

📄 menubar.c

📁 Mrxvt是一个小巧
💻 C
📖 第 1 页 / 共 5 页
字号:
	item->entry.action.str = NULL; /* If not null will be freed by									 rxvt_action_set */	item->len2 = 0;	item->name2 = NULL;	len = STRLEN(name);	/* possible integer overflow? */	assert (len >= 0 && len + 1 >= 0);	item->name = rxvt_malloc(len + 1);	STRCPY(item->name, name);	if (name[0] == '.' && name[1] != '.')		len = 0;		/* hidden menu name */	item->len = len;	/* add to tail of list */	item->prev = menu->tail;	item->next = NULL;	if (menu->tail != NULL)		(menu->tail)->next = item;	menu->tail = item;	/* fix head */	if (menu->head == NULL)		menu->head = item;	/*	 * add action	 */Item_Found:	if (name2 != NULL && item->name2 == NULL)	{		len = STRLEN(name2);		if (len == 0)			item->name2 = NULL;		else		{			/* possible integer overflow? */			assert (len > 0 && len + 1 > 0);			item->name2 = rxvt_malloc(len + 1);			STRCPY(item->name2, name2);		}		item->len2 = len;	}	item->entry.itemType = MenuLabel;	len = STRLEN(action);	if (len == 0 && item->name2 != NULL)	{		action = item->name2;		len = item->len2;	}	if (len)	{		char	str[NEWARGLIM];		/* possible integer overflow? */		assert (len > 0 && len + 1 > 0);		/* str = rxvt_malloc(len + 1); */		STRCPY(str, action);		item->entry.action.str = NULL;		if( rxvt_set_action( &(item->entry.action), str) )			item->entry.itemType = MenuItem;	}	/* new item and a possible increase in width */	len = PTEXTWIDTH( r, item->name, item->len );	/* Left text width */	if( menu->lwidth < len ) menu->lwidth = len;	len = PTEXTWIDTH( r, item->name2, item->len2);	/* Right text width */	if( menu->rwidth < len ) menu->rwidth = len;	return item;}/* * search for the base starting menu for NAME. * return a pointer to the portion of NAME that remains *//* INTPROTO */unsigned char*rxvt_menu_find_base(rxvt_t *r, menu_t **menu, unsigned char *path){	menu_t		 *m = NULL;	menuitem_t	 *item;	DBG_MSG( 2, (stderr, "rxvt_menu_find_base()\n"));#ifdef DEBUG	assert(menu != NULL);#endif	if (path[0] == '\0')	return path;	if (STRCHR(path, '/') != NULL)	{		unsigned char		   *p = path;		while ((p = (unsigned char*) STRCHR(p, '/')) != NULL)		{			p++;			if (*p == '/')			path = p;		}		if (path[0] == '/')		{			path++;			*menu = NULL;		}		while ((p = (unsigned char*) STRCHR(path, '/')) != NULL)		{			p[0] = '\0';			if (path[0] == '\0')			return NULL;			if (!STRCMP(path, DOT))			{				/* nothing to do */			}			else if (!STRCMP(path, DOTS))			{				if (*menu != NULL)					*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 (*menu != NULL)			*menu = (*menu)->parent;		return path;	}	/* find this menu */	if (*menu == NULL)	{		for (m = r->h->MenuBar.tail; m != NULL; m = m->prev)		{			if (!STRCMP(path, m->name))			break;		}	}	else	{		/* find this menu */		for (item = (*menu)->tail; item != NULL; item = item->prev)		{			if (					item->entry.itemType == MenuSubMenu					&& !STRCMP(path, (item->entry.submenu.menu)->name)			   )			{				m = (item->entry.submenu.menu);				break;			}		}	}	if (m != NULL)	{		*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;	DBG_MSG( 2, (stderr, "rxvt_menu_delete()\n"));	assert( menu != r->h->ActiveMenu ); /* Shouldn't delete current menu */	/* delete the entire menu */	if (menu == NULL) return NULL;	parent = menu->parent;	/* unlink MENU */	prev = menu->prev;	next = menu->next;	if (prev != NULL) prev->next = next;	if (next != NULL) next->prev = prev;	if (parent == NULL)	{		/*		 * 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; next != NULL; next = next->next)			next->x -= width;	}	else	{		for (item = parent->tail; item != NULL; item = item->prev)		{			if (item->entry.itemType == MenuSubMenu					&& item->entry.submenu.menu == menu)			{				/* Unlink from the parent menu */				item->entry.submenu.menu = NULL;				rxvt_menuitem_free(r, menu->parent, item);				break;			}		}	}	item = menu->tail;	while (item != NULL)	{		menuitem_t	 *p = item->prev;		rxvt_menuitem_free(r, menu, item);		item = p;	}	free(menu->name);	free(menu);	return parent;}/* INTPROTO */menu_t*rxvt_menu_add(rxvt_t *r, menu_t *parent, unsigned char *path){	menu_t		 *menu;	DBG_MSG( 2, (stderr, "rxvt_menu_add(): Adding menu %s to parent %s\n",			path, parent ? parent->name : "(nil)"));	if (STRCHR(path, '/') != NULL)	{		unsigned char	*p;		if (path[0] == '/')		{			/* shouldn't happen */			path++;			parent = NULL;		}		while ((p = (unsigned char*) STRCHR(path, '/')) != NULL)		{			p[0] = '\0';			if (path[0] == '\0')			return NULL;			parent = rxvt_menu_add(r, parent, path);			path = (p + 1);		}	}	if (!STRCMP(path, DOTS))		return (parent != NULL ? 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 */	menu->head = menu->tail = NULL;	menu->prev = menu->next = NULL;	menu->win = None;	menu->x = menu->y = menu->height = 0;	menu->item = NULL;	if (parent == NULL)	{		/* Add menus named PopupButton%d to popupMenu[%d] */		if(			!STRNCASECMP( "popupbutton", (char *) path, 11 )			&& path[11] >= '1' && path[11] <= '3'			&& path[12] == '\0'		  )		{			int i = path[11] - '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 (r->h->MenuBar.tail != NULL)				r->h->MenuBar.tail->next = menu;			r->h->MenuBar.tail = menu;			/* fix head */			if (r->h->MenuBar.head == NULL)				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 (item == NULL)		{			if( menu->name != NULL) free( menu->name );			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;	DBG_MSG( 2, (stderr, "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;	DBG_MSG( 2, (stderr, "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;	DBG_MSG( 2, (stderr, "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_MENU_LAYOUT/* INTPROTO */voidrxvt_print_menu_ancestors(menu_t *menu){	DBG_MSG( 2, (stderr, "rxvt_print_menu_ancestors()\n"));	if (menu == NULL)	{		fprintf(stderr, "Top Level menu\n");		return;	}	fprintf(stderr, "menu %s ", menu->name);	if (menu->parent != NULL)	{		menuitem_t	 *item;		for (item = menu->parent->head; item != NULL; item = item->next)		{			if (					item->entry.type == MenuSubMenu					&& item->entry.submenu.menu == menu			   )			{				break;			}		}		if (item == NULL)		{			fprintf(stderr, "is an orphan!\n");			return;		}	}	fprintf(stderr, "\n");	rxvt_print_menu_ancestors(menu->parent);}/* INTPROTO */voidrxvt_print_menu_descendants(menu_t *menu){	DBG_MSG( 2, (stderr, "rxvt_print_menu_descendants()\n"));	menuitem_t	 *item;	menu_t		 *parent;	int			 i, level = 0;	parent = menu;	do	  {		level++;		parent = parent->parent;	  }	while (parent != NULL);	for (i = 0; i < level; i++)	fprintf(stderr, ">");	fprintf(stderr, "%s\n", menu->name);	for (item = menu->head; item != NULL; item = item->next)	{		if (item->entry.type == MenuSubMenu)		{			if (item->entry.submenu.menu == NULL)				fprintf(stderr, "> %s == NULL\n", item->name);			else			rxvt_print_menu_descendants(item->entry.submenu.menu);		}		else		{			for (i = 0; i < level; i++)				fprintf(stderr, "+");			if (item->entry.type == MenuLabel)				fprintf(stderr, "label: ");			fprintf(stderr, "%s\n", item->name);		}	}	for (i = 0; i < level; i++)	fprintf(stderr, "<");	fprintf(stderr, "\n");}#endif/* * 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);	DBG_MSG( 2, (stderr, "rxvt_build_tablist()\n"));	/*

⌨️ 快捷键说明

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