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

📄 tabbar.c

📁 Mrxvt是一个小巧
💻 C
📖 第 1 页 / 共 4 页
字号:
#define SET_ARC( arc, ax, ay, awidth, aheight, aangle1, aangle2)	\	(arc).x			= (short) (ax);									\	(arc).y			= (short) (ay);									\	(arc).width		= (unsigned short) (awidth);					\	(arc).height	= (unsigned short) (aheight);					\	(arc).angle1	= (short) (aangle1);							\	(arc).angle2	= (short) (aangle2)#define SET_POINT( point, ax, ay)	\	point.x			= (short) ax;	\	point.y			= (short) ay/* * Refresh tab number page. */voidrefresh_tabbar_tab( rxvt_t *r, int page){	int			i;	XRectangle	rect;	DBG_MSG( 2, ( stderr, "Refreshing tabbar title of page %d\n", page));	if( page < FVTAB(r) || page > LVTAB(r) ) return;	for( i=FVTAB(r), rect.x=TAB_BORDER; i < page; i++)		rect.x += TAB_WIDTH(i);		rect.y		= TAB_TOPOFF;	rect.width	= TAB_WIDTH( page);	rect.height	= 0;	/* Clear the tab completely, and send expose events */	XClearArea( r->Xdisplay, r->tabBar.win,			rect.x, rect.y, rect.width, rect.height, True);}/* * Draw all visible tabs at top. If region is not none, then we clip output to * it. *//* INTPROTO */void rxvt_draw_tabs (rxvt_t* r, Region region){	int		page, x;	if (LTAB(r) < 0 || r->tabBar.win == None || !r->tabBar.state)		/*		 * Nothing to do here :)		 */		return;	/* Sanatization */	assert( LTAB(r)  >= 0		 );	assert( FVTAB(r) >= 0		 );	assert( FVTAB(r) <= LTAB(r)	 );	assert( LVTAB(r) >= 0		 );	assert( LVTAB(r) <= LTAB(r)	 );	assert( ATAB(r)  >= FVTAB(r) );	assert( ATAB(r)  <= LVTAB(r) );	if( region != None )		XSetRegion( r->Xdisplay, r->tabBar.gc, region);	for( page=FVTAB(r), x=TAB_BORDER; page <= LVTAB(r); page++)	{		/*		 * Draw the tab corresponding to "page".		 */		XArc	 		arcs[2];		XPoint	 		points[8];		if( page == ATAB(r) )		{			/*			 * Draw the active tab, and bottom line of the tabbar.			 */			int				clear = 0;	/* use ClearArea or FillRectangle */			if( r->Options2 & Opt2_bottomTabbar )			{				/* Top tabbar line & left of active tab */				SET_POINT( points[0], 0, TAB_TOPOFF);				SET_POINT( points[1], x, TAB_TOPOFF);				SET_POINT( points[2], x, TAB_BOTOFF - TAB_RADIUS);				/* Arc coordinates for rounded tab tops :) */				SET_ARC( arcs[0], x, TAB_BOTOFF - 2*TAB_RADIUS,						2*TAB_RADIUS, 2*TAB_RADIUS, 180*64, 90*64);				SET_ARC( arcs[1],						x + AVTS(r)->tab_width - 2*TAB_RADIUS,						TAB_BOTOFF - 2*TAB_RADIUS,						2*TAB_RADIUS, 2*TAB_RADIUS, 270*64, 90*64);				/* Coordinates for horizontal line below tab. */				SET_POINT( points[3], x + TAB_RADIUS, TAB_BOTOFF);				SET_POINT( points[4],						x + AVTS(r)->tab_width - TAB_RADIUS, TAB_BOTOFF);				/* Right line of tab and top of tabbar. */				SET_POINT( points[5],						x + AVTS(r)->tab_width, TAB_BOTOFF - TAB_RADIUS);				SET_POINT( points[6], x + AVTS(r)->tab_width, TAB_TOPOFF);				SET_POINT( points[7], TWIN_WIDTH(r), TAB_TOPOFF);			}			else	/* if ( r->Options2 & Opt2_bottomTabbar ) */			{				/*				 * Coordinates for the draw bottom line to the left of active				 * tab, and left verticle line of the active tab.				 */				SET_POINT( points[0], 0, TAB_BOTOFF);				SET_POINT( points[1], x, TAB_BOTOFF);				SET_POINT( points[2], x, TAB_TOPOFF + TAB_RADIUS);				/* Arc coordinates for rounded tab tops :) */				SET_ARC( arcs[0], x, TAB_TOPOFF,						2*TAB_RADIUS, 2*TAB_RADIUS, 180*64, -90*64);				SET_ARC( arcs[1],						x + AVTS(r)->tab_width - 2*TAB_RADIUS, TAB_TOPOFF,						2*TAB_RADIUS, 2*TAB_RADIUS, 90*64, -90*64);				/* Coordinates for horizontal line above tab. */				SET_POINT( points[3], x + TAB_RADIUS, TAB_TOPOFF);				SET_POINT( points[4],						x + AVTS(r)->tab_width - TAB_RADIUS, TAB_TOPOFF);				/*				 * Coordinates for vertical line on the right of the active tab, and				 * bottom line of tab bar after active tab.				 */				SET_POINT( points[5], x + AVTS(r)->tab_width,						TAB_TOPOFF + TAB_RADIUS);				SET_POINT( points[6], x + AVTS(r)->tab_width, TAB_BOTOFF);				SET_POINT( points[7], TWIN_WIDTH(r), TAB_BOTOFF);			}#ifdef BACKGROUND_IMAGE			if( r->tabBar.hasPixmap  && (r->Options & Opt_tabPixmap))				clear = 1;	/* use background image */#endif#ifdef TRANSPARENT			if ( ( r->h->am_transparent || r->h->am_pixmap_trans ) &&				(r->Options & Opt_transparent_tabbar))				clear = 1;	/* transparent override background image */#endif			if( !clear )			{				/*				 * Fill the ATAB with the background color.				 */				CHOOSE_GC_FG( r, r->tabBar.bg);				XFillArcs( r->Xdisplay, r->tabBar.win, r->tabBar.gc,						arcs, 2);				XFillPolygon( r->Xdisplay, r->tabBar.win, r->tabBar.gc,						points+1, 6, Convex, CoordModeOrigin);				/*				 * This misses the bottom of the ATAB, so we should color it				 * ourselves.				 *				 * 2006-02-14 gi1242: Drawing with XDrawLine is not enough. For				 * some reason a thin line below is still missed. Be super safe				 * and XFillRectangle it.				 *				 * 2006-05-26 gi1242: The thin line looks kinda nice actually...				 */#if 0				XDrawLine( r->Xdisplay, r->tabBar.win, r->tabBar.gc,						points[1].x, points[1].y,						points[6].x, points[6].y);				XFillRectangle( r->Xdisplay, r->tabBar.win, r->tabBar.gc,						points[1].x, points[1].y,						points[6].x - points[1].x, 2);#endif			}			/*			 * Finally, draw the (boundary) of ATAB here.			 */			CHOOSE_GC_FG( r, r->tabBar.frame);			/* Tabbar line + left of ATAB */			XDrawLines( r->Xdisplay, r->tabBar.win, r->tabBar.gc,					points, 3, CoordModeOrigin);			/* Rounded tab tops :) */			XDrawArcs( r->Xdisplay, r->tabBar.win, r->tabBar.gc, arcs, 2);			/* Top line of ATAB */			XDrawLines( r->Xdisplay, r->tabBar.win, r->tabBar.gc,					points + 3, 2, CoordModeOrigin);			/* Right of ATAB + tab bar line */			XDrawLines( r->Xdisplay, r->tabBar.win, r->tabBar.gc,					points + 5, 3, CoordModeOrigin);			/* Draw the tab title. */			CHOOSE_GC_FG( r, r->tabBar.fg);			draw_title (r, PVTS(r, page)->tab_title,					x + TXT_XOFF, ATAB_EXTRA / 2 + TXT_YOFF, page, region);		}		else /* if( page == ATAB(r) ) */		{			/*			 * Draw the inactive tabs.			 */			CHOOSE_GC_FG( r, r->tabBar.delimit);			if( r->Options2 & Opt2_bottomTabbar )			{				/* Left vertical line */				XDrawLine( r->Xdisplay, r->tabBar.win, r->tabBar.gc,						x, TAB_TOPOFF + 1, /* Dont' interupt tabbar line */						x, TAB_BOTOFF - TAB_RADIUS - ATAB_EXTRA);				/* Draw rounded tab bottoms :). */				SET_ARC( arcs[0], x, TAB_BOTOFF - ATAB_EXTRA - 2*TAB_RADIUS,						2*TAB_RADIUS, 2*TAB_RADIUS, 180*64, 90*64);				SET_ARC( arcs[1],						x + PVTS(r, page)->tab_width - 2*TAB_RADIUS,						TAB_BOTOFF - ATAB_EXTRA - 2*TAB_RADIUS,						2*TAB_RADIUS, 2*TAB_RADIUS, 270*64, 90*64);				XDrawArcs( r->Xdisplay, r->tabBar.win, r->tabBar.gc, arcs, 2);				/* Horizontal line below tab. */				XDrawLine( r->Xdisplay, r->tabBar.win, r->tabBar.gc,						x + TAB_RADIUS, TAB_BOTOFF - ATAB_EXTRA,						x + PVTS(r, page)->tab_width - TAB_RADIUS,						TAB_BOTOFF - ATAB_EXTRA);				/* Right vertical line */				XDrawLine( r->Xdisplay, r->tabBar.win, r->tabBar.gc,						x + PVTS(r, page)->tab_width,						TAB_BOTOFF - TAB_RADIUS - ATAB_EXTRA,						x + PVTS(r, page)->tab_width, TAB_TOPOFF + 1);			}			else /* if( r->Options2 & Opt2_bottomTabbar ) */			{				/* Left vertical line */				XDrawLine( r->Xdisplay, r->tabBar.win, r->tabBar.gc,						x, TAB_BOTOFF-1, x,						TAB_TOPOFF + TAB_RADIUS + ATAB_EXTRA);				/* Draw rounded tab tops :). */				SET_ARC( arcs[0], x, TAB_TOPOFF + ATAB_EXTRA,						2*TAB_RADIUS, 2*TAB_RADIUS, 180*64, -90*64);				SET_ARC( arcs[1],						x + PVTS(r, page)->tab_width - 2*TAB_RADIUS,						TAB_TOPOFF + ATAB_EXTRA,						2*TAB_RADIUS, 2*TAB_RADIUS, 90*64, -90*64);				XDrawArcs( r->Xdisplay, r->tabBar.win, r->tabBar.gc, arcs, 2);				/* Horizontal line above tab. */				XDrawLine( r->Xdisplay, r->tabBar.win, r->tabBar.gc,						x + TAB_RADIUS, TAB_TOPOFF + ATAB_EXTRA,						x + PVTS(r, page)->tab_width - TAB_RADIUS,						TAB_TOPOFF + ATAB_EXTRA);				/* Right vertical line */				XDrawLine( r->Xdisplay, r->tabBar.win, r->tabBar.gc,						x + PVTS(r, page)->tab_width,						TAB_TOPOFF + TAB_RADIUS + ATAB_EXTRA,						x + PVTS(r, page)->tab_width, TAB_BOTOFF-1);			}			/* Choose GC foreground for tab title. */			CHOOSE_GC_FG( r, r->tabBar.ifg);			draw_title (r, PVTS(r, page)->tab_title,					x + TXT_XOFF,					(r->Options2 & Opt2_bottomTabbar ?					 		TXT_YOFF : ATAB_EXTRA + TXT_YOFF),					page, region);			/* Highlight the tab if necessary */			if( PVTS(r, page)->highlight )				rxvt_tabbar_highlight_tab( r, page, True);		}		x += TAB_WIDTH(page);	}	if( region != None) XSetClipMask( r->Xdisplay, r->tabBar.gc, None);}/* EXTPROTO */voidrxvt_tabbar_highlight_tab (rxvt_t* r, short page, Bool force){	register int	i, x;	int				sx, sy;	unsigned int	rw, rh;	XGCValues		gcvalues;	/* Sanatization */	assert (LTAB(r) >= 0);	assert (FVTAB(r) >= 0);	assert (FVTAB(r) <= LTAB(r));	assert (LVTAB(r) >= 0);	assert (LVTAB(r) <= LTAB(r));	assert (ATAB(r) >= FVTAB(r));	assert (ATAB(r) <= LVTAB(r));	assert (page <= LTAB(r));	/* highlight flag is already set, simply return */	if ( !force && PVTS(r, page)->highlight)		return;		/* set highlight flag */	PVTS(r, page)->highlight = 1;	if (LTAB(r) < 0 || r->tabBar.win == None || !r->tabBar.state)		return ;	/* do not highlight invisible/active tab */	if (page < FVTAB(r) || page > LVTAB(r) || page == ATAB(r))		return;	for (i = FVTAB(r), x=TAB_BORDER; i < page; x += TAB_WIDTH(i), i++);	/* set dash-line attributes */	XGetGCValues( r->Xdisplay, r->tabBar.gc,			GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle,			&gcvalues);	XSetLineAttributes (r->Xdisplay, r->tabBar.gc,			1, LineOnOffDash, CapButt, JoinMiter);	XSetForeground (r->Xdisplay, r->tabBar.gc, r->tabBar.ifg);	/* Set dimensions of the highlighted tab rectangle */	sx = x + ( TXT_XOFF / 2 );	sy = (r->Options2 & Opt2_bottomTabbar)		?				TAB_TOPOFF + 1					:				TAB_TOPOFF + ATAB_EXTRA + 1;	rw = PVTS(r, page)->tab_width - TXT_XOFF;	rh = TAB_BOTOFF - TAB_TOPOFF - ATAB_EXTRA - 3;	XDrawRectangle (r->Xdisplay, r->tabBar.win, r->tabBar.gc,		sx, sy, rw, rh);	/* restore solid-line attributes */	XChangeGC( r->Xdisplay, r->tabBar.gc,			GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle,			&gcvalues);}/* * Buttons *//* EXTPROTO */voidrxvt_tabbar_draw_buttons (rxvt_t* r){	register int	i;	int				topoff;	unsigned long	frame;	if (LTAB(r) < 0)		return;	if (None == r->tabBar.win)		return;	if (!r->tabBar.state)		return;	/* whether the buttons are hidden */	if (r->Options2 & Opt2_hideButtons)		return;	topoff = BTN_TOPOFF;#if 0	frame = !(r->Options2 & Opt2_bottomTabbar) ?				r->tabBar.frame : r->tabBar.delimit;#endif	frame = r->tabBar.frame;	CHOOSE_GC_FG (r, r->tabBar.fg);	for (i = NB_XPM; i >= 1; i--)	{#ifdef HAVE_LIBXPM		register int	curimg = NB_XPM - i;		switch (curimg)		{			case XPM_TERM:				img[XPM_TERM] = (LTAB(r) == MAX_PAGES - 1) ? 					img_d[XPM_TERM] : img_e[XPM_TERM];				break;			case XPM_CLOSE:				img[XPM_CLOSE] = ((r->Options2 & Opt2_protectSecondary) &&								PRIMARY != AVTS(r)->current_screen) ?						img_d[XPM_CLOSE] : img_e[XPM_CLOSE];				break;			case XPM_LEFT:				img[XPM_LEFT] = (FVTAB(r) == 0) ? 					img_d[XPM_LEFT] : img_e[XPM_LEFT];				break;			case XPM_RIGHT:				img[XPM_RIGHT] = (LVTAB(r) == LTAB(r)) ? 					img_d[XPM_RIGHT] : img_e[XPM_RIGHT];				break;		}#endif		if (None != img[NB_XPM-i])		{			XCopyArea  (r->Xdisplay, img[NB_XPM-i], r->tabBar.win,				r->tabBar.gc, 0, 0,				BTN_WIDTH, BTN_HEIGHT,				TWIN_WIDTH(r)-(i*(BTN_WIDTH+BTN_SPACE)), topoff);		}	}	CHOOSE_GC_FG (r, r->tabBar.frame);	for (i = NB_XPM; i >= 1; i--)	{		/*		XDrawRectangle (r->Xdisplay, r->tabBar.win,			r->tabBar.gc,			TWIN_WIDTH(r)-(i*(BTN_WIDTH+BTN_SPACE)), topoff,			BTN_WIDTH, BTN_HEIGHT);		*/		int		sx = TWIN_WIDTH(r) - (i*(BTN_WIDTH+BTN_SPACE));		/* draw top line */		XDrawLine (r->Xdisplay, r->tabBar.win, r->tabBar.gc,			sx, topoff, sx + BTN_WIDTH, topoff);		/* draw left line */		XDrawLine (r->Xdisplay, r->tabBar.win, r->tabBar.gc,			sx, topoff, sx, topoff + BTN_HEIGHT);	}	CHOOSE_GC_FG (r, r->tabBar.delimit);	for (i = NB_XPM; i >= 1; i--)	{		int		sx = TWIN_WIDTH(r) - (i*(BTN_WIDTH+BTN_SPACE));		/* draw bottom line */		XDrawLine (r->Xdisplay, r->tabBar.win, r->tabBar.gc,			sx, topoff+BTN_HEIGHT, sx+BTN_WIDTH, topoff+BTN_HEIGHT);		/* draw right line */		XDrawLine (r->Xdisplay, r->tabBar.win, r->tabBar.gc,			sx+BTN_WIDTH, topoff, sx+BTN_WIDTH, topoff+BTN_HEIGHT);	}}/* * Initialize global data structure of all tabs *//* INTPROTO */static voidinit_tabbar (rxvt_t* r){	r->tabBar.state = 0;	/* not mapped yet */	LTAB(r) = -1;	/* the last tab */	r->tabBar.atab = 0;	/* the active tab */	FVTAB(r) = 0;	/* first visiable tab */	LVTAB(r) = 0;	/* last visiable tab */	r->tabBar.ptab = 0;		/* previous active tab */	/* Make sure that font has been initialized */#ifdef XFT_SUPPORT	if (r->Options & Opt_xft)		assert (NULL != r->TermWin.xftfont);	else#endif	assert (None != r->TermWin.font);	assert (r->TermWin.FHEIGHT > 0);	/* resource string are static, needn't to free */	r->tabBar.rsfg =	r->tabBar.rsbg =	r->tabBar.rsifg =	r->tabBar.rsibg = 0;}/* INTPROTO */voidrxvt_kill_page (rxvt_t* r, short page){	kill (PVTS(r, page)->cmd_pid, SIGHUP);}/* * Append a new tab after the last tab. If command is not NULL, run that * command in the tab. If command begins with '!', then run the shell first. *//* EXTPROTO */voidrxvt_append_page( rxvt_t* r, int profile,		const char TAINTED *title, const char *command ){	DBG_MSG( 2, ( stderr, "rxvt_append_page( r, %d, %s, %s )\n",				profile, title ? title : "(nil)",				command ? command : "(nil)" ) );	int		num_fds,			num_cmd_args = 0; /* Number of args we got from parsing command */	char**	argv;	/* Sanitization */	assert( LTAB(r) < MAX_PAGES );	if (LTAB(r) == MAX_PAGES-1)	{		rxvt_print_error( "Too many tabs" );		return ;	}	DBG_MSG( 1, (stderr,"append_page (%s, %s)\n",				title ? title : "NULL",				command ? command : "NULL") );	/* indicate that we add a new tab */	LTAB(r)++;	DBG_MSG( 1, ( stderr, "last page is %d\n", LTAB(r)) );	/*	 * Use command specified with -e only if we're opening the first tab, or the	 * --cmdAllTabs option is specified, and we're not given a command to	 *  execute (e.g. via the NewTab cmd macro).	 */	if(		 cmd_argv			/* Argument specified via -e option */		 && command == NULL	/* No command specified (e.g. via NewTab macro) */		 && (			   LTAB(r)== 0							/* First tab */			   || (r->Options2 & Opt2_cmdAllTabs)	/* -at option */		    )	  )		argv = cmd_argv;	else	{		/* load tab command if necessary*/		if( command == NULL )			command = getProfileOption( r, profile, Rs_command );		if( command != NULL && *command != '!' )		{			/* If "command" starts with '!', we should run it in the shell. */			argv = rxvt_string_to_argv( command, &num_cmd_args );		}		else			argv = NULL;	}	DBG_MSG( 2, ( stderr, "Forking command=%s, argv[0]=%s\n",				command ? command : "(nil)",				( argv && argv[0] ) ? argv[0] : "(nil)" ) );	/*	 * Set the tab title.	 */	if( title == NULL || *title == '\0' )	{		title = getProfileOption( r, profile, Rs_tabtitle );		if( title == NULL || *title == '\0' )		{			if( command && *command != '\0' )				title = command;			else if( argv && argv[0] && *argv[0] != '\0' )				title = argv[0];		}	}	rxvt_create_termwin( r, LTAB(r), profile, title );	/*	 * Run the child process.	 *	 * 2006-02-17 gi1242: Bug -- If the child produces some output and exits	 * quickly, then some of that output is sometimes lost.	 */	if( getProfileOption( r, profile, Rs_cwd ) != NULL )	{		const char	*cwdOption	= getProfileOption( r, profile, Rs_cwd );		char		*cwd		= getcwd( NULL, PATH_MAX ),					child_cwd[PATH_MAX];		int			len = 0;		if( !STRCMP( cwdOption, "." ) )		{			if( ATAB(r) != LTAB(r) )			{				/*				 * Copy working directory of the current tab into child_cwd.				 */				char	proc_cwd[32];			/* 16 is enough */				sprintf( proc_cwd, "/proc/%d/cwd", AVTS(r)->cmd_pid );				if( (len = readlink( proc_cwd, child_cwd, PATH_MAX-1) ) > 0 )					/* readlink does not null terminate */					child_cwd[len] = 0;			}		}				else		{			/* XXX Maybe better to use wordexp and expand ~ & $HOME here */			len  = STRLEN( cwdOption );			MIN_IT( len, PATH_MAX - 1 );			STRNCPY( child_cwd, cwdOption, len );			child_cwd[len] = 0;		}		if( len > 0 && chdir( child_cwd ) == 0 )		{			/* Now in working directory of ATAB */			DBG_MSG( 2, ( stderr, "Running child in directory: %s\n",						child_cwd ));			/* Run command in this new directory. */

⌨️ 快捷键说明

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