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

📄 tabbar.c

📁 Mrxvt是一个小巧
💻 C
📖 第 1 页 / 共 4 页
字号:
/*--------------------------------*-C-*---------------------------------* * File:	tabbar.c *----------------------------------------------------------------------* * * All portions of code are copyright by their respective author/s. * Copyright (c) 2002        Alexis <materm@tuxfamily.org> * Copyright (c) 2004        Terry Griffin <griffint@pobox.com> * Copyright (c) 2004        Sergey Popov <p_sergey@jungo.com> * Copyright (c) 2004-2005   Jingmin Zhou <jimmyzhou@users.sourceforge.net> * Copyright (c) 2005        Mark Olesen <Mark.Olesen@gmx.net> * Copyright (c) 2005		 Gautam Iyer <gi1242@users.sourceforge.net> * * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------------*/#include "../config.h"#include "rxvt.h"#ifdef HAVE_LIBXPM#include "close_term.xpm"#include "term.xpm"#include "right.xpm"#include "left.xpm"#include "close_term_d.xpm"#include "term_d.xpm"#include "right_d.xpm"#include "left_d.xpm"#else#include "close_term.xbm"#include "term.xbm"#include "right.xbm"#include "left.xbm"#endif /* HAVE_LIBXPM */#ifdef DEBUG_VERBOSE#define DEBUG_LEVEL 1#else #define DEBUG_LEVEL 0#endif#if DEBUG_LEVEL#define DBG_MSG(d,x) if(d <= DEBUG_LEVEL) fprintf x#else#define DBG_MSG(d,x)#endif#ifdef XFT_SUPPORT# define	FHEIGHT pheight# define	FWIDTH	pwidth#else# define	FHEIGHT	fheight# define	FWIDTH	fwidth#endif/* border between the tabs */#define TAB_BORDER		((int) 1)/* margin around the text of the tab */#define TXT_MARGIN		((int) 3)/* * Parameters to draw top tabbar *//* space between top window border and tab top */#define TAB_TOPOFF		((int) 0)/* Extra height of the active tab. */#define ATAB_EXTRA		((int) (ATAB_EXTRA_PERCENT * r->TermWin.FHEIGHT / 100))/* space between top window border and tab bottom */#define TAB_BOTOFF		((int) (r->TermWin.FHEIGHT + 2*TXT_MARGIN) + ATAB_EXTRA)/* Radius of tab corners */#define TAB_RADIUS		(TAB_RADIUS_PERCENT * TXT_XOFF / 100 )/* X offset of text in tab */#define TXT_XOFF		((int) (r->TermWin.FWIDTH - TAB_BORDER))/* height of text in tab */#define TXT_YOFF		((int) (r->TermWin.FHEIGHT + TXT_MARGIN + TAB_BORDER))/* width of No. idx tab */#define TAB_WIDTH(idx)	((int) (TAB_BORDER + r->vts[idx]->tab_width))/* size of button */#define BTN_WIDTH		((int) 18)#define BTN_HEIGHT		((int) 18)/* space between top window border and button top */#define BTN_TOPOFF		(max (0, ((TAB_BOTOFF - BTN_HEIGHT)/2)))/* space between buttons */#define BTN_SPACE		((int) 5)/* width of tabbar that can be used to draw tabs */#define TAB_SPACE		(TWIN_WIDTH(r)- \	((r->Options2 & Opt2_hideButtons) ? 0 : 1) * \	(4 * (BTN_WIDTH+BTN_SPACE) + TAB_BORDER))#define CHOOSE_GC_FG(R, PIXCOL)	\	XSetForeground ((R)->Xdisplay, (R)->tabBar.gc, (PIXCOL))/*******************************************************************************						Begin internal routine prototypes.					  *******************************************************************************//*******************************************************************************						End internal routine prototypes.					  *******************************************************************************/enum {XPM_TERM,XPM_CLOSE,XPM_LEFT,XPM_RIGHT,NB_XPM};#ifdef HAVE_LIBXPMstatic char** xpm_name[] ={	term_xpm,close_term_xpm,	left_xpm,right_xpm};static char** xpm_d_name[] ={	term_d_xpm,close_term_d_xpm,	left_d_xpm,right_d_xpm};#elsestatic char *xpm_name[] ={	term_bits,close_term_bits,	left_bits,right_bits};#endif	static Pixmap img[NB_XPM];#ifdef HAVE_LIBXPMstatic Pixmap img_e[NB_XPM]; /* enable image */static Pixmap img_emask[NB_XPM]; /* shape mask image */static Pixmap img_d[NB_XPM]; /* disable image */static Pixmap img_dmask[NB_XPM]; /* shape mask image */#endif	extern char **cmd_argv;/* * Width between two tabs: * From the left of the first tab to the right of the second tab *//* INTPROTO */static intwidth_between (rxvt_t* r, int start, int end){	register int	i, w=0;		for (i = start; i <= end; i++)		w += TAB_WIDTH(i);		return w;}/* * Find most left tab within specified distance. Note that the * distance does not include the width of tab[start]. It means * distance = (beginning of tab[start] - 0) *//* INTPROTO */static intfind_left_tab (rxvt_t* r, int start, int distance){	register int	i, left;	/* Sanatization */	if (0 == start)		return 0;	/* BUG: tab overlap with button */	if (distance < 0)		return start;	left = distance;	for (i = start - 1; i >= 0; i --)	{		if (left < TAB_WIDTH(i))			break;		left -= (TAB_WIDTH(i));	}	return (i + 1);}/* * Find most right tab within specified distance. Note that the * distance does not include the width of tab[start]. It means * distance = (beginning of first button - end of tab[start]) *//* INTPROTO */static intfind_right_tab (rxvt_t* r, int start, int distance){	register int	i, left;	/* Sanatization */	if (LTAB(r) == start)		return start;	/* BUG: tab overlap with button */	if (distance < 0)		return start;	left = distance;	for (i = start + 1; i <= LTAB(r); i ++)	{		if (left < TAB_WIDTH(i))			break;		left -= (TAB_WIDTH(i));	}	return (i - 1);}/* EXTPROTO *//* * If refresh is true, then the respective parts of the tabbar are redrawn. * NOTE: This function redraws parts of the tabbar soley based on wether the tab * position / width has changed. It does not check to see if the tab titles / * etc has changed. */voidrxvt_tabbar_set_visible_tabs (rxvt_t* r, Bool refresh){	assert( LTAB(r) >= 0 );	/*	 * For Firefox style tabs, we should recompute all tabwidths.	 */#ifdef XFT_SUPPORT	if( (r->Options & Opt_xft) && r->TermWin.xftpfont )	{		int		i;		short	tabWidth = rxvt_tab_width( r, NULL);	/* Firefox style tabs														   don't need the tab														   title */		int		numVisible = (TAB_SPACE - TAB_BORDER)								/ (TAB_BORDER + tabWidth);		int		oldTabWidth = PVTS(r,0)->tab_width,				oldFVtab	= FVTAB(r),				oldLVtab	= LVTAB(r);		/*		 * Reset the widths of all tabs (visible or not).		 */		for (i = 0; i <= LTAB(r); i ++) PVTS(r, i)->tab_width = tabWidth;		/*		 * Set visible tabs. First make sure the active tab is visible		 */		if( numVisible == 1 )			FVTAB(r) = LVTAB(r) = ATAB(r);		else		{			if( ATAB(r) < FVTAB(r) )				/* Make ATAB second last tab that's visible */				FVTAB(r) = max( ATAB(r) - numVisible + 2, 0);			else if ( ATAB(r) >= FVTAB(r) + numVisible )				/* Make ATAB the second tab that's visible */				FVTAB(r) = max( ATAB(r) - 1, 0);			/*			 * Active tab is now visible. Try and make as many other tabs			 * visible.			 */			if( FVTAB(r) + numVisible - 1 > LTAB(r) )			{				LVTAB(r) = LTAB(r);				FVTAB(r) = max( LVTAB(r) - numVisible + 1, 0);			}			else				LVTAB(r) = FVTAB(r) + numVisible - 1;		}		if( refresh && r->tabBar.win != None)		{			/* Clear out the parts of the tabbar that have changed. Expose			 * events will be sent to the tabbar. */			if( tabWidth != oldTabWidth || FVTAB(r) != oldFVtab )				/* Refresh all tabs */				XClearArea( r->Xdisplay, r->tabBar.win,						0, 0, TAB_SPACE, 0, True);			else if( oldLVtab != LVTAB(r) )			{				int x = TAB_BORDER +					(TAB_BORDER + tabWidth) * min( oldLVtab, LVTAB(r));				XClearArea( r->Xdisplay, r->tabBar.win,						x, 0, TAB_SPACE - x + 1, 0, True);			}		}	}	else#endif	{		/* set first visible tab to active tab */		FVTAB(r) = ATAB(r);		/* always try visualize the right tabs */		LVTAB(r) = find_right_tab (r, FVTAB(r),			TAB_SPACE - TAB_WIDTH(FVTAB(r)));		if (LVTAB(r) == LTAB(r) && 0 != FVTAB(r))		{			/* now try to visualize the left tabs */			register int size = TAB_SPACE -				width_between (r, FVTAB(r), LVTAB(r));			FVTAB(r) = find_left_tab (r, FVTAB(r), size);		}		if( refresh && r->tabBar.win != None)			XClearArea( r->Xdisplay, r->tabBar.win, 0, 0, TAB_SPACE, 0, True);	}}/* *	x, y      : starting position of string, no need to adjust y *  str       : string to draw *  len       : byte length of the string, not number of characters! *  multichar : whether the string is multichar string *  active    : active or inactive tab * *  Returns the pixel width of the string drawn. *//* INTPROTO */static intdraw_string (rxvt_t* r, Region clipRegion,		int x, int y, char* str, int len,		__attribute__((unused)) int multichar, int active){#ifdef XFT_SUPPORT	XGlyphInfo	ginfo;#endif#ifdef MULTICHAR_SET	if (multichar)	{		/*		 * Draw the multichar string		 */# ifdef XFT_SUPPORT		if ((r->Options & Opt_xft) && (NULL != r->tabBar.xftwin))		{#  ifdef HAVE_ICONV_H			if (					ENC_NOENC != r->encoding_method					&& (iconv_t) -1 != r->TermWin.xfticonv			   )			{				char			buf[1024];				int				plen = 1023;				char*			pstr = buf;				int				olen = len;				char*			ostr = str;				/* convert to UTF-8 */				iconv (r->TermWin.xfticonv, &ostr, (size_t*) &olen,					&pstr, (size_t*) &plen);				*pstr = (char) 0;	/* set end of string */				rxvt_draw_string_xft (r, r->tabBar.win, r->tabBar.gc,						clipRegion, RS_None, 						active ? USE_BOLD_PFONT : USE_PFONT,						r->tabBar.xftwin,						active ? &(r->tabBar.xftfg) : &(r->tabBar.xftifg),						x, y, buf, len, XftDrawStringUtf8);				if( r->TermWin.xftpfont )				{					XftTextExtentsUtf8( r->Xdisplay, r->TermWin.xftpfont,							(unsigned char*) buf, pstr - buf, &ginfo);					return ginfo.width;				}				else return Width2Pixel( pstr - buf );			}			else#  endif			{				DBG_MSG(1, (stderr, "XFT non-iconv tab title\n"));				rxvt_draw_string_xft (r, r->tabBar.win, r->tabBar.gc,						clipRegion, RS_None,						active ? USE_BOLD_PFONT : USE_PFONT,						r->tabBar.xftwin,						active ? &(r->tabBar.xftfg) : &(r->tabBar.xftifg),						x, y, str, len, XftDrawString8);				if( r->TermWin.xftpfont )				{					XftTextExtents8( r->Xdisplay, r->TermWin.xftpfont,							(unsigned char*) str, len, &ginfo);					return ginfo.width;				}				else return Width2Pixel( len );			}		}		else# endif	/* XFT_SUPPORT */		{			if (ENC_NOENC != r->encoding_method)			{				XSetFont (r->Xdisplay, r->tabBar.gc, r->TermWin.mfont->fid);				r->h->multichar_decode ( (unsigned char*) str, len);				rxvt_draw_string_x11 (r, r->tabBar.win, r->tabBar.gc,						clipRegion, x, y, str, len/2, XDrawString16);			}			else			{				XSetFont (r->Xdisplay, r->tabBar.gc, r->TermWin.font->fid);				rxvt_draw_string_x11 (r, r->tabBar.win, r->tabBar.gc,						clipRegion, x, y, str, len, XDrawString);			}			return Width2Pixel( len );		}	} /* if (multichar) */	else#endif /* MULTICHAR_SET */	{		/*		 * Draw the non-multichar string		 */# ifdef XFT_SUPPORT		if ((r->Options & Opt_xft) && (NULL != r->tabBar.xftwin))		{			rxvt_draw_string_xft (r, r->tabBar.win, r->tabBar.gc,					clipRegion, RS_None,					active ? USE_BOLD_PFONT : USE_PFONT,					r->tabBar.xftwin,					active ? &(r->tabBar.xftfg) : &(r->tabBar.xftifg),					x, y, str, len, XftDrawString8);			if( r->TermWin.xftpfont )			{				XftTextExtents8( r->Xdisplay, r->TermWin.xftpfont,						(unsigned char*) str, len, &ginfo);				return ginfo.width;			}			else return Width2Pixel( len );		}		else# endif	/* XFT_SUPPORT */		{			XSetFont (r->Xdisplay, r->tabBar.gc, r->TermWin.font->fid);			rxvt_draw_string_x11 (r, r->tabBar.win, r->tabBar.gc,					clipRegion, x, y, str, len, XDrawString);			return Width2Pixel( len );		}	}}/* * Draw tab title string * * If region is non-empty, we assume that the caller has set the GC's clipping * to region, and we honor it. *//* INTPROTO */static voiddraw_title (rxvt_t* r, const char* orgstr, int x, int y, int tnum,		Region region){	Region		clipRegion = None;	char		str[MAX_DISPLAY_TAB_TXT + 1];#ifdef MULTICHAR_SET	char		buf[MAX_TAB_TXT + 1];	const char*	sptr;	const char*	ptr;	int			multichar;	int			len;#endif	/*	 * Adjust y offset, and make sure output is restricted to the current tab	 * title.	 */# ifdef XFT_SUPPORT	if ((r->Options & Opt_xft) && (NULL != r->tabBar.xftwin))	{		if( r->TermWin.xftpfont )		{			/*			 * If we use pfont to draw tab titles, the we dont' know how many			 * characters will fit on the title. So we should clip the output			 * correctly.			 */			XRectangle rect;			rect.x = x;			rect.y = y - r->TermWin.pheight;			rect.width = PVTS(r, tnum)->tab_width - 2*TXT_XOFF;			rect.height = r->TermWin.pheight;			clipRegion = XCreateRegion();			XUnionRectWithRegion( &rect, clipRegion, clipRegion);			if( region != None )				XIntersectRegion( clipRegion, region, clipRegion);			XftDrawSetClip( r->tabBar.xftwin, clipRegion);			y -= r->TermWin.xftpfont->descent;		}		else y -= r->TermWin.xftfont->descent;	}	else# endif		y -= r->TermWin.font->descent;	/*	 * Copy the title into str, and null terminate.	 */	STRNCPY (str, orgstr, r->TermWin.maxTabWidth);	str[r->TermWin.maxTabWidth] = (char) 0;	/*	 * Draw the string (different code for multichar / non-multichar).	 */#ifdef MULTICHAR_SET	sptr = ptr = str;	multichar = (*ptr & 0x80);	while (*ptr)	{		if (multichar && (*ptr & 0x80))		/* multichar */			ptr ++;		else if (!multichar && !(*ptr & 0x80))	/* single char */			ptr ++;		else		{			len = ptr - sptr;			/* adjust bytes, must be 2x for multichar */			if (multichar && (len % 2) != 0)			{				len ++; ptr ++;				/* continue to next byte, we shouldn't stop here */				continue;			}			assert (len <= MAX_TAB_TXT);			memcpy (buf, sptr, len);			buf[len] = (char) 0;			x += draw_string (r, clipRegion,					x, y, buf, len, multichar, tnum == ATAB(r));			/* adjust start position */			/* x += Width2Pixel(len); */			/*#ifdef XFT_SUPPORT			if ((r->Options & Opt_xft) && r->tabBar.xftwin)			{				x += Width2Pixel(len);			}			else#endif			{				if (multichar)					x += XTextWidth (r->TermWin.mfont, buf, len/2);				else					x += XTextWidth (r->TermWin.font, buf, len);			}			*/			/* ok, now the next sub-string */			sptr = ptr;			multichar = (*ptr & 0x80);			if ((char) 0 == *ptr)				break;	/* in case ptr is increased at line 356 */			ptr ++;		}	}	/* last sub-string */	len = ptr - sptr;	if (0 != len)		/* in case last sub-string is empty */	{		memcpy (buf, sptr, len);		buf[len] = (char) 0;		draw_string (r, clipRegion,				x, y, buf, len, multichar, tnum == ATAB(r));	}#else	/* MULTICHAR_SET */	draw_string (r, clipRegion,			x, y, str, STRLEN(str), False, tnum == ATAB(r));#endif	/* MULTICHAR_SET */	/*	 * Restore clipping of the xftdrawable / gc.	 */	if( clipRegion != None )	{		XDestroyRegion( clipRegion);		if( region == None )			XSetClipMask( r->Xdisplay, r->tabBar.gc, None);		else			XSetRegion( r->Xdisplay, r->tabBar.gc, region);#ifdef XFT_SUPPORT		if (r->tabBar.xftwin)			XftDrawSetClip( r->tabBar.xftwin, region);#endif	}}

⌨️ 快捷键说明

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