예제 #1
0
/* create a pixmap suitable for plonking on the background of a part of a
 * window */
Pixmap CreateOffsetBackgroundPixmap(
	Display *dpy, Window win, int x, int y, int width, int height,
	colorset_t *colorset, unsigned int depth, GC gc, Bool is_shape_mask)
{
	Pixmap pixmap = None;
	Pixmap cs_pixmap = None;
	XGCValues xgcv;
	static GC shape_gc = None;
	GC fill_gc = None; /* not static as dpy may change (FvwmBacker) */
	int cs_width;
	int cs_height;
	Bool cs_keep_aspect;
	Bool cs_stretch_x;
	Bool cs_stretch_y;

	if (colorset->pixmap == ParentRelative && !is_shape_mask &&
	    colorset->tint_percent > 0)
	{
		FvwmRenderAttributes fra;

		fra.mask = FRAM_DEST_IS_A_WINDOW | FRAM_HAVE_TINT;
		fra.tint = colorset->tint;
		fra.tint_percent = colorset->tint_percent;
		MyXGrabServer(dpy);
		pixmap = PGraphicsCreateTransparency(
			dpy, win, &fra, gc, x, y, width, height, True);
		MyXUngrabServer(dpy);
		if (pixmap == None)
		{
			return ParentRelative;
		}
		return pixmap;
	}
	else if (colorset->pixmap == ParentRelative && !is_shape_mask)
	{
		return ParentRelative;
	}
	else if (CSETS_IS_TRANSPARENT_ROOT(colorset) && colorset->pixmap
		 && !is_shape_mask)
	{
		int sx,sy;
		int h,w;
		XID dummy;

		cs_pixmap = colorset->pixmap;
		cs_width = colorset->width;
		cs_height = colorset->height;
		if (CSETS_IS_TRANSPARENT_ROOT_PURE(colorset))
		{
			/* check if it is still here */
			union {
				XID junk;
				unsigned int ui_junk;
				int i_junk;
			} XID_int;
			/* a priori we should grab the server, but this
			 * cause PositiveWrite error when you move a
			 * window with a transparent title bar */
			if (!XGetGeometry(
				    dpy, colorset->pixmap, &XID_int.junk,
				    &XID_int.i_junk, &XID_int.i_junk,
				    (unsigned int *)&w, (unsigned int *)&h,
				    &XID_int.ui_junk,
				    &XID_int.ui_junk) ||
			    w != cs_width || h != cs_height)
			{
				return None;
			}
		}
		XTranslateCoordinates(
			dpy, win, DefaultRootWindow(dpy), x, y, &sx, &sy,
			&dummy);
		pixmap = XCreatePixmap(dpy, win, width, height, Pdepth);
		if (!pixmap)
		{
			return None;
		}
		/* make sx and sy positif */
		while (sx < 0)
		{
			sx = sx + cs_width;
		}
		while (sy < 0)
		{
			sy = sy + cs_height;
		}
		/* make sx and sy in (0,0,cs_width,cs_height) */
		while (sx >= cs_width)
		{
			sx = sx - cs_width;
		}
		while (sy >= cs_height)
		{
			sy = sy - cs_height;
		}
		xgcv.fill_style = FillTiled;
		xgcv.tile = cs_pixmap;
		xgcv.ts_x_origin = cs_width-sx;
		xgcv.ts_y_origin = cs_height-sy;
		fill_gc = fvwmlib_XCreateGC(
			dpy, win, GCTile | GCTileStipXOrigin |
			GCTileStipYOrigin | GCFillStyle, &xgcv);
		if (fill_gc == None)
		{
			XFreePixmap(dpy, pixmap);
			return None;
		}
		XSync(dpy, False);
		is_bad_gc = 0;
		ferror_set_temp_error_handler(BadGCErrorHandler);
		XFillRectangle(dpy, pixmap, fill_gc, 0, 0, width, height);
		if (
			is_bad_gc == 0 &&
			CSETS_IS_TRANSPARENT_ROOT_PURE(colorset) &&
			colorset->tint_percent > 0)
		{
			FvwmRenderAttributes fra;

			fra.mask = FRAM_HAVE_TINT;
			fra.tint = colorset->tint;
			fra.tint_percent = colorset->tint_percent;
			PGraphicsRenderPixmaps(
				dpy, win, pixmap, None, None,
				Pdepth, &fra, pixmap,
				fill_gc, None, None,
				0, 0, width, height,
				0, 0, width, height, False);
		}
		XSync(dpy, False);
		ferror_reset_temp_error_handler();
		if (is_bad_gc == 1)
		{
			is_bad_gc = 0;
			XFreePixmap(dpy, pixmap);
			pixmap = None;
		}
		XFreeGC(dpy,fill_gc);
		return pixmap;
	}
	if (!is_shape_mask)
	{
		cs_pixmap = colorset->pixmap;
		cs_width = colorset->width;
		cs_height = colorset->height;
		cs_keep_aspect =
			(colorset->pixmap_type == PIXMAP_STRETCH_ASPECT);
		cs_stretch_x = (colorset->pixmap_type == PIXMAP_STRETCH_X)
			|| (colorset->pixmap_type == PIXMAP_STRETCH);
		cs_stretch_y = (colorset->pixmap_type == PIXMAP_STRETCH_Y)
			|| (colorset->pixmap_type == PIXMAP_STRETCH);
	}
	else
	{
		/* In spite of the name, win contains the pixmap */
		cs_pixmap = colorset->shape_mask;
		win = colorset->shape_mask;
		if (shape_gc == None)
		{
			xgcv.foreground = 1;
			xgcv.background = 0;
			/* create a gc for 1 bit depth */
			shape_gc = fvwmlib_XCreateGC(
				dpy, win, GCForeground|GCBackground, &xgcv);
		}
		gc = shape_gc;
		cs_width = colorset->shape_width;
		cs_height = colorset->shape_height;
		cs_keep_aspect = (colorset->shape_type == SHAPE_STRETCH_ASPECT);
		cs_stretch_x = !(colorset->shape_type == SHAPE_TILED);
		cs_stretch_y = !(colorset->shape_type == SHAPE_TILED);
	}

	if (cs_pixmap == None)
	{
		xgcv.foreground = colorset->bg;
		fill_gc = fvwmlib_XCreateGC(dpy, win, GCForeground, &xgcv);
		/* create a solid pixmap - not very useful most of the time */
		pixmap = XCreatePixmap(dpy, win, 1, 1, depth);
		XFillRectangle(dpy, pixmap, fill_gc, 0, 0, 1, 1);
		XFreeGC(dpy,fill_gc);
	}
	else if (cs_keep_aspect)
	{
		Bool trim_side;
		int big_width, big_height;
		Pixmap big_pixmap;
		int x, y;

		/* make a pixmap big enough to cover the destination but with
		 * the aspect ratio of the cs_pixmap */
		trim_side = get_aspect_dimensions(
			&big_width, &big_height, width, height, cs_width,
			cs_height);
		big_pixmap = CreateStretchPixmap(
			dpy, cs_pixmap, cs_width, cs_height, depth, big_width,
			big_height, gc);

		/* work out where to trim */
		x = trim_side ? (big_width - width) / 2 : 0;
		y = trim_side ? 0 : (big_height - height) / 2;

		pixmap = XCreatePixmap(dpy, cs_pixmap, width, height, depth);
		if (pixmap && big_pixmap)
		{
			XCopyArea(
				dpy, big_pixmap, pixmap, gc, x, y, width,
				height, 0, 0);
		}
		if (big_pixmap)
		{
			XFreePixmap(dpy, big_pixmap);
		}
	}
	else if (!cs_stretch_x && !cs_stretch_y)
	{
		/* it's a tiled pixmap, create an unstretched one */
		if (!is_shape_mask)
		{
			pixmap = XCreatePixmap(
				dpy, cs_pixmap, cs_width, cs_height, depth);
			if (pixmap)
			{
				XCopyArea(
					dpy, cs_pixmap, pixmap, gc, 0, 0,
					cs_width, cs_height, 0, 0);
			}
		}
		else
		{
			/* can't tile masks, create a tiled version of the
			 * mask */
			pixmap = CreateTiledPixmap(
				dpy, cs_pixmap, cs_width, cs_height, width,
				height, 1, gc);
		}
	}
	else if (!cs_stretch_x)
	{
		/* it's an HGradient */
		pixmap = CreateStretchYPixmap(
			dpy, cs_pixmap, cs_width, cs_height, depth, height, gc);
	}
	else if (!cs_stretch_y)
	{
		/* it's a VGradient */
		pixmap = CreateStretchXPixmap(
			dpy, cs_pixmap, cs_width, cs_height, depth, width, gc);
	}
	else
	{
		/* It's a full window pixmap */
		pixmap = CreateStretchPixmap(
			dpy, cs_pixmap, cs_width, cs_height, depth, width,
			height, gc);
	}

	if (x != 0 || y != 0)
	{
		Pixmap p2;

		p2 = ScrollPixmap(
			dpy, pixmap, gc, x, y, width, height,
			depth);
		if (p2 != None && p2 != ParentRelative && p2 != pixmap)
		{
			XFreePixmap(dpy, pixmap);
			pixmap = p2;
		}
	}

	return pixmap;
}
예제 #2
0
파일: Colorset.c 프로젝트: att/uwin
/* sets a window background from a colorset
 * if width or height are zero the window size is queried
 */
void SetWindowBackgroundWithOffset(
	Display *dpy, Window win, int x_off, int y_off, int width, int height,
	colorset_struct *colorset, unsigned int depth, GC gc, Bool clear_area)
{
	Pixmap pixmap = None;
	Pixmap mask = None;
	XID junk;

	if (0 == width || 0 == height)
	{
		if (!XGetGeometry(
			    dpy, win, &junk, (int *)&junk, (int *)&junk,
			    (unsigned int *)&width, (unsigned int *)&height,
			    (unsigned int *)&junk, (unsigned int *)&junk))
		{
			return;
		}
	}

	if (FHaveShapeExtension && colorset->shape_mask)
	{
		mask = CreateBackgroundPixmap(
			dpy, 0, width, height, colorset, 1, None, True);
		if (mask != None)
		{
			FShapeCombineMask(
				dpy, win, FShapeBounding, 0, 0, mask,
				FShapeSet);
			XFreePixmap(dpy, mask);
		}
	}
	if (!colorset->pixmap)
	{
		/* use the bg pixel */
		XSetWindowBackground(dpy, win, colorset->bg);
		if (clear_area)
		{
			XClearArea(dpy, win, 0, 0, width, height, True);
		}
	}
	else
	{
		if (colorset->pixmap == ParentRelative)
		{
			pixmap = ParentRelative;
		}
		else
		{
			pixmap = CreateBackgroundPixmap(
				dpy, win, width, height, colorset, depth, gc,
				False);
		}
		if (x_off != 0 || y_off != 0)
		{
			Pixmap p2;

			p2 = ScrollPixmap(
				dpy, pixmap, gc, x_off, y_off, width, height,
				depth);
			if (p2 != None && p2 != ParentRelative && p2 != pixmap)
			{
				XFreePixmap(dpy, pixmap);
				pixmap = p2;
			}
		}
		if (pixmap)
		{
			XSetWindowBackgroundPixmap(dpy, win, pixmap);
			if (clear_area)
			{
				XClearArea(dpy, win, 0, 0, width, height, True);
			}
			if (colorset->pixmap != ParentRelative)
			{
				XFreePixmap(dpy, pixmap);
			}
		}
	}

	return;
}