コード例 #1
0
ファイル: Colorset.c プロジェクト: ThomasAdam/fvwm-cvs
/* 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
/* create a pixmap suitable for plonking on the background of a window */
Pixmap CreateBackgroundPixmap(Display *dpy, Window win, int width, int height,
			      colorset_struct *colorset, unsigned int depth,
			      GC gc, Bool is_shape_mask)
{
  Pixmap pixmap = None;
  Pixmap cs_pixmap = None;
  XGCValues xgcv;
  static GC shape_gc = None;
  static GC solid_gc = None;
  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)
  {
    return ParentRelative;
  }
  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;
    if (solid_gc == None)
    {
      /* create a gc for solid drawing */
      solid_gc = fvwmlib_XCreateGC(dpy, win, GCForeground, &xgcv);
    }
    else
    {
      XChangeGC(dpy, solid_gc, GCForeground, &xgcv);
    }
    /* create a solid pixmap - not very useful most of the time */
    pixmap = XCreatePixmap(dpy, win, width, height, depth);
    XFillRectangle(dpy, pixmap, solid_gc, 0, 0, width, height);
  }
  else if (cs_keep_aspect) {
    Bool trim_side;
    int big_width, big_height;
    Pixmap big_pixmap;
    int x, y;

    /* do sides need triming or top/bottom? */
    trim_side = (cs_width * height > cs_height * width);

    /* make a pixmap big enough to cover the destination but with the aspect
     * ratio of the cs_pixmap */
    big_width = trim_side ? height * cs_width / cs_height : width;
    big_height = trim_side ? height : width * cs_height / cs_width;
    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);
  }

  return pixmap;
}