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

📄 pixmap.c

📁 multi-tabed terminal based on rxvt
💻 C
字号:
/*--------------------------------*-C-*---------------------------------* * File:    pixmap.c *----------------------------------------------------------------------* * * All portions of code are copyright by their respective author/s. * Copyright (c) 1997        Carsten Haitzler <raster@zip.com.au> * Copyright (c) 1997,1998   Oezguer Kesim <kesim@math.fu-berlin.de> * Copyright (c) 1998-2001   Geoff Wing <gcw@pobox.com> * Copyright (c) 2004        Jingmin Zhou <jimmyzhou@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 BACKGROUND_IMAGE/*--------------------------------------------------------------------* *         BEGIN `INTERNAL' ROUTINE PROTOTYPES                        * *--------------------------------------------------------------------*/void rxvt_pixmap_incr (unsigned int*, unsigned int*, float*, float*, unsigned int, unsigned int);/*--------------------------------------------------------------------* *         END   `INTERNAL' ROUTINE PROTOTYPES                        * *--------------------------------------------------------------------*//* * These GEOM strings indicate absolute size/position: * @ `WxH+X+Y' * @ `WxH+X'	-> Y = X * @ `WxH'    -> Y = X = 50 * @ `W+X+Y'	-> H = W * @ `W+X'    -> H = W, Y = X * @ `W'	-> H = W, X = Y = 50 * @ `0xH'    -> H *= H/100, X = Y = 50 (W unchanged) * @ `Wx0'    -> W *= W/100, X = Y = 50 (H unchanged) * @ `=+X+Y'	-> (H, W unchanged) * @ `=+X'    -> Y = X (H, W unchanged) * * These GEOM strings adjust position relative to current position: * @ `+X+Y' * @ `+X'      -> Y = X * * And this GEOM string is for querying current scale/position: * @ `?' *//* EXTPROTO */intrxvt_scale_pixmap(rxvt_t *r, int page, const char *geom){    int		 flags, changed = 0;    int		 x = 0, y = 0;    unsigned int    w = 0, h = 0;    unsigned int    n;    char	   *p, *str;    bgPixmap_t	 *bgpixmap = &(PVTS(r, page)->bg);#define MAXLEN_GEOM	sizeof("[1000x1000+1000+1000]")    if (geom == NULL)	return 0;    str = rxvt_malloc(MAXLEN_GEOM + 1);    if (!STRCMP(geom, "?")) {	sprintf(str, "[%dx%d+%d+%d]",	/* can't presume snprintf() ! */	    min(bgpixmap->w, 9999), min(bgpixmap->h, 9999),	    min(bgpixmap->x, 9999), min(bgpixmap->y, 9999));	rxvt_xterm_seq(r, page, XTerm_title, str, CHAR_ST);	rxvt_free(str);	return 0;    }    if ((p = STRCHR(geom, ';')) == NULL)    p = STRCHR(geom, '\0');    n = (p - geom);    if (n <= MAXLEN_GEOM) {    STRNCPY(str, geom, n);    str[n] = '\0';    flags = XParseGeometry(str, &x, &y, &w, &h);    if (!flags) {	flags |= WidthValue;	w = 0;    }		/* default is tile */    if (flags & WidthValue) {	if (!(flags & XValue))	x = 50;	if (!(flags & HeightValue))	h = w;	if (w && !h) {	w = (bgpixmap->w * w) / 100;	h = bgpixmap->h;	} else if (h && !w) {	w = bgpixmap->w;	h = (bgpixmap->h * h) / 100;	}	if (w > 1000)	w = 1000;	if (h > 1000)	h = 1000;	if (bgpixmap->w != (short)w) {	bgpixmap->w = (short)w;	changed++;	}	if (bgpixmap->h != (short)h) {	bgpixmap->h = (short)h;	changed++;	}    }    if (!(flags & YValue)) {	if (flags & XNegative)	flags |= YNegative;	y = x;    }    if (!(flags & WidthValue) && geom[0] != '=') {	x += bgpixmap->x;	y += bgpixmap->y;    } else {	if (flags & XNegative)	x += 100;	if (flags & YNegative)	y += 100;    }    MIN_IT(x, 100);    MIN_IT(y, 100);    MAX_IT(x, 0);    MAX_IT(y, 0);    if (bgpixmap->x != x) {	bgpixmap->x = x;	changed++;    }    if (bgpixmap->y != y) {	bgpixmap->y = y;	changed++;    }    }    rxvt_free(str);    return changed;}/* EXTPROTO */voidrxvt_resize_pixmap(rxvt_t *r, int page){    XGCValues	    gcvalue;    GC		    gc;    unsigned int    width = VT_WIDTH(r);    unsigned int    height = VT_HEIGHT(r);    if (IS_PIXMAP(PVTS(r, page)->pixmap))	XFreePixmap(r->Xdisplay, PVTS(r, page)->pixmap);    if (NOT_PIXMAP(PVTS(r, page)->bg.pixmap))	/* So be it: I'm not using pixmaps */	return;    gcvalue.foreground = r->pixColorsFocus[Color_bg];    gc = XCreateGC(r->Xdisplay, PVTS(r, page)->vt, GCForeground, &gcvalue);    if (IS_GC(gc) && IS_PIXMAP(PVTS(r, page)->bg.pixmap)) {	/* we have a specified pixmap */	unsigned int	w = PVTS(r, page)->bg.w;	unsigned int	h = PVTS(r, page)->bg.h;	unsigned int	x = PVTS(r, page)->bg.x;	unsigned int	y = PVTS(r, page)->bg.y;	unsigned int	xpmh = PVTS(r, page)->xpm_attr.height;	unsigned int	xpmw = PVTS(r, page)->xpm_attr.width;	unsigned int	pixmapw, pixmaph;	/*	 * don't zoom pixmap too much nor expand really small pixmaps	 */	if (w > 1000 || h > 1000)	    w = 1;	else if (width > (10 * xpmw)	     || height > (10 * xpmh))	    w = 0;	/* tile */	if (w == 0) {	    /* basic X tiling - let the X server do it */	    PVTS(r, page)->pixmap = XCreatePixmap(r->Xdisplay,		PVTS(r, page)->vt, xpmw, xpmh, (unsigned int)XDEPTH);	    XCopyArea(r->Xdisplay, PVTS(r, page)->bg.pixmap,		PVTS(r, page)->pixmap, gc, 0, 0, xpmw, xpmh, 0, 0);	    pixmapw = xpmw;	    pixmaph = xpmh;	}	else {	    float	  incr, p;	    Pixmap	  tmp;	    PVTS(r, page)->pixmap = XCreatePixmap(r->Xdisplay,		PVTS(r, page)->vt, width, height, (unsigned int)XDEPTH);	    /* horizontal scaling */	    rxvt_pixmap_incr(&w, &x, &incr, &p, width, xpmw);	    tmp = XCreatePixmap(r->Xdisplay, PVTS(r, page)->vt,		    width, xpmh, (unsigned int)XDEPTH);	    XFillRectangle(r->Xdisplay, tmp, gc, 0, 0, width,		   xpmh);	    for ( /*nil */ ; x < w; x++, p += incr) {		if (p >= xpmw)		    p = 0;		/* copy one column from the original pixmap to the		** tmp pixmap */		XCopyArea(r->Xdisplay, PVTS(r, page)->bg.pixmap, tmp,		    gc, (int)p, 0, 1, xpmh, (int)x, 0);	    }	    /* vertical scaling */	    rxvt_pixmap_incr(&h, &y, &incr, &p, height, xpmh);	    if (y > 0)		XFillRectangle(r->Xdisplay, PVTS(r, page)->pixmap, gc,		    0, 0, width, y);	    if (h < height)		XFillRectangle(r->Xdisplay, PVTS(r, page)->pixmap, gc,		    0, (int)h, width, height - h + 1);	    for ( /*nil */ ; y < h; y++, p += incr) {		if (p >= xpmh)		    p = 0;		/* copy one row from the tmp pixmap to the main		** pixmap */		XCopyArea(r->Xdisplay, tmp, PVTS(r, page)->pixmap, gc,		    0, (int)p, width, 1, 0, (int)y);	    }	    XFreePixmap(r->Xdisplay, tmp);	    pixmapw = width;	    pixmaph = height;	}#ifdef TINTING_SUPPORT# ifdef HAVE_LIBXRENDER	xrenderShadeParentPixmap( r, PVTS(r, page)->pixmap,		0, 0, pixmapw, pixmaph, False);# else	rxvt_shade_pixmap( r, PVTS(r, page)->pixmap,		0, 0, pixmapw, pixmaph);# endif#endif	/* TINTING_SUPPORT */	/* Free gc */	XFreeGC(r->Xdisplay, gc);    }    XSetWindowBackgroundPixmap(r->Xdisplay, PVTS(r, page)->vt,	PVTS(r, page)->pixmap);# ifdef TRANSPARENT    r->h->am_transparent = 0;    r->h->am_pixmap_trans = 0;# endif    XClearWindow(r->Xdisplay, PVTS(r, page)->vt);    XSync(r->Xdisplay, False);}/* * Calculate tiling sizes and increments * At start, p == 0, incr == xpmwidthheight *//* INTPROTO */voidrxvt_pixmap_incr(unsigned int *wh, unsigned int *xy, float *incr, float *p, unsigned int widthheight, unsigned int xpmwidthheight){    unsigned int    cwh, cxy;    float	   cincr, cp;    cp = 0;    cincr = (float)xpmwidthheight;    cxy = *xy;    cwh = *wh;    if (cwh == 1) { /* display one image, no horizontal/vertical scaling */    cincr = (float)widthheight;    if (xpmwidthheight <= widthheight) {	cwh = xpmwidthheight;	cxy = (cxy * (widthheight - cwh)) / 100;    /* beware! order */	cwh += cxy;    } else {	cxy = 0;	cwh = widthheight;    }    } else if (cwh < 10) {  /* fit WH images across/down screen */    cincr *= cwh;    cxy = 0;    cwh = widthheight;    } else {    cincr *= 100.0 / cwh;    if (cwh < 100) {	/* contract */	float	       pos;	cwh = (cwh * widthheight) / 100;	pos = (float)cxy / 100 * widthheight - (cwh / 2);	cxy = (widthheight - cwh);	if (pos <= 0)	cxy = 0;	else if (pos < cxy)	cxy = pos;	cwh += cxy;    } else {	/* expand */	if (cxy > 0) {	/* position */	float	       pos;	pos = (float)cxy / 100 * xpmwidthheight - (cincr / 2);	cp = xpmwidthheight - cincr;	if (pos <= 0)	    cp = 0;	else if (pos < cp)	    cp = pos;	}	cxy = 0;	cwh = widthheight;    }    }    cincr /= widthheight;    *wh = cwh;    *xy = cxy;    *incr = cincr;    *p = cp;}/* EXTPROTO */Pixmaprxvt_load_bg_pixmap(rxvt_t *r, int page, const char *file){    Pixmap	pixmap;    long	w = 0, h = 0;    assert(file != NULL);    pixmap = rxvt_load_pixmap (r, file, &w, &h);    if (IS_PIXMAP(PVTS(r, page)->bg.pixmap))	XFreePixmap (r->Xdisplay, PVTS(r, page)->bg.pixmap);    PVTS(r, page)->bg.pixmap = pixmap;    if( NOT_PIXMAP(pixmap) )    {	if( page == ATAB(r) )	{	    /* Force resetting the background color */	    r->fgbg_tabnum = -1;	    rxvt_set_vt_colors( r, page );	}	return None;    }    PVTS(r, page)->xpm_attr.closeness = 30000;    PVTS(r, page)->xpm_attr.colormap = XCMAP;    PVTS(r, page)->xpm_attr.visual = XVISUAL;    PVTS(r, page)->xpm_attr.depth = XDEPTH;    PVTS(r, page)->xpm_attr.valuemask = (XpmCloseness | XpmColormap |	    XpmVisual | XpmDepth | XpmSize | XpmReturnPixels);    PVTS(r, page)->xpm_attr.width = w;    PVTS(r, page)->xpm_attr.height = h;    rxvt_resize_pixmap(r, page);    return (pixmap);}/* EXTPROTO */Pixmaprxvt_load_pixmap(rxvt_t *r, const char *file, long* pwidth, long* pheight){    char*	    f;    int		    flen;#if defined(USE_JPEG) || defined(USE_PNG)    long	    w = 0, h = 0;#endif    XpmAttributes   xpm_attr;    Pixmap	    pixmap;    UNSET_PIXMAP(pixmap);    assert(file != NULL);    if ((char) 0 == *file) { /* No file to load */	return None;    }    xpm_attr.closeness = 30000;    xpm_attr.colormap = XCMAP;    xpm_attr.visual = XVISUAL;    xpm_attr.depth = XDEPTH;    xpm_attr.valuemask = (XpmCloseness | XpmColormap |	    XpmVisual | XpmDepth | XpmSize | XpmReturnPixels);    /* search environment variables here too */    if (NULL == (f = (char*) rxvt_File_find (file, ".xpm", r->h->rs[Rs_path]))#ifdef USE_JPEG	&& NULL == (f = (char*) rxvt_File_find (file, ".jpg", r->h->rs[Rs_path]))	&& NULL == (f = (char*) rxvt_File_find (file, ".jpeg", r->h->rs[Rs_path]))#endif#ifdef USE_PNG	&& NULL == (f = (char*) rxvt_File_find (file, ".png", r->h->rs[Rs_path]))#endif	)   {	char	       *p;	/* semi-colon delimited */	if (NULL == (p = STRCHR(file, ';')))	    p = STRCHR(file, '\0');	rxvt_msg (DBG_ERROR, DBG_PIXMAP, "couldn't load image file \"%.*s\"", (p - file), file);	return None;    }    flen = STRLEN (f);#ifdef USE_JPEG    if ((flen >= 4 && !STRNCASECMP (f+flen-4, ".jpg", 4)) ||	(flen >= 5 && !STRNCASECMP (f+flen-5, ".jpeg",5)))  {	GC	gc = DefaultGC (r->Xdisplay, XSCREEN);	if (!JpegReadFileToPixmap (r->Xdisplay, XROOT, gc, f,	    &pixmap, &w, &h))	{	    *pwidth = w;	    *pheight = h;	}    }    else#endif#ifdef USE_PNG    if (flen >= 4 && !STRNCASECMP (f+flen-4, ".png", 4))    {	GC	gc = DefaultGC (r->Xdisplay, XSCREEN);	if (!PngReadFileToPixmap (r->Xdisplay, XROOT, gc, f,	    &pixmap, &w, &h))	{	    *pwidth = w;	    *pheight = h;	}    }    else#endif#ifdef HAVE_LIBXPM    if (!XpmReadFileToPixmap(r->Xdisplay, XROOT, f,	&pixmap, NULL, &xpm_attr))  {	*pwidth = xpm_attr.width;	*pheight = xpm_attr.height;    }#endif    {	/* empty to suppress compile error */    }    rxvt_free(f);    if (NOT_PIXMAP(pixmap)) {	char	       *p;	/* semi-colon delimited */	if ((p = STRCHR(file, ';')) == NULL)	p = STRCHR(file, '\0');	rxvt_msg (DBG_ERROR, DBG_PIXMAP, "couldn't load image file \"%.*s\"", (p - file), file);    }    return  (pixmap);}#endif	/* BACKGROUND_IMAGE *//*----------------------- end-of-file (C source) -----------------------*/

⌨️ 快捷键说明

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