Ejemplo n.º 1
0
/* Creates a pixmap that is a stretched version of the input
 * pixmap
 */
Pixmap CreateStretchPixmap(
	Display *dpy, Pixmap src, int src_width, int src_height, int src_depth,
	int dest_width, int dest_height, GC gc)
{
	Pixmap pixmap = None;
	Pixmap temp_pixmap;
	GC my_gc = None;

	if (src_width < 0 || src_height < 0 || src_depth < 0 || dest_width < 0)
	{
		return None;
	}
	if (gc == None)
	{
		my_gc = fvwmlib_XCreateGC(dpy, src, 0, 0);
	}
	temp_pixmap = CreateStretchXPixmap(
		dpy, src, src_width, src_height, src_depth, dest_width,
		(gc == None)? my_gc:gc);
	if (temp_pixmap == None)
	{
		if (my_gc)
		{
			XFreeGC(dpy, my_gc);
		}
		return None;
	}
	pixmap = CreateStretchYPixmap(
		dpy, temp_pixmap, dest_width, src_height, src_depth,
		dest_height, (gc == None)? my_gc:gc);
	XFreePixmap(dpy, temp_pixmap);
	if (my_gc)
	{
		XFreeGC(dpy, my_gc);
	}
	return pixmap;
}
Ejemplo n.º 2
0
/* Draws a colorset background into the specified rectangle in the target
 * drawable. */
void SetClippedRectangleBackground(
	Display *dpy, Window win, int x, int y, int width, int height,
	XRectangle *clip, colorset_t *colorset,
	unsigned int depth, GC gc)
{
	GC draw_gc;
	Pixmap pixmap2;
	Pixmap pixmap = None;
	static int last_depth = -1;
	static GC last_gc = None;
	XGCValues xgcv;
	Pixmap clipmask = None;
	GC clip_gc = None;
	Bool keep_aspect = (colorset->pixmap_type == PIXMAP_STRETCH_ASPECT);
	Bool stretch_x = (colorset->pixmap_type == PIXMAP_STRETCH_X)
		|| (colorset->pixmap_type == PIXMAP_STRETCH);
	Bool stretch_y = (colorset->pixmap_type == PIXMAP_STRETCH_Y)
		|| (colorset->pixmap_type == PIXMAP_STRETCH);
	int dest_x, dest_y, dest_w, dest_h;

	if (clip)
	{
		dest_x = clip->x;
		dest_y = clip->y;
		dest_w = clip->width;
		dest_h = clip->height;
	}
	else
	{
		dest_x = x;
		dest_y = y;
		dest_w = width;
		dest_h = height;
	}
	if (CSETS_IS_TRANSPARENT_PR_TINT(colorset))
	{
		XClearArea(dpy, win, dest_x, dest_y, dest_w, dest_h, False);
		PGraphicsTintRectangle(
			dpy, win, colorset->tint, colorset->tint_percent,
			win, True, gc, None, None,
			dest_x, dest_y, dest_w, dest_h);
		return;
	}
	if (CSETS_IS_TRANSPARENT_PR_PURE(colorset))
	{
		XClearArea(dpy, win, dest_x, dest_y, dest_w, dest_h, False);
		/* don't do anything */
		return;
	}
	if (CSETS_IS_TRANSPARENT_ROOT(colorset))
	{
		/* FIXME: optimize this ! */
		x = y = 0;
		width = width + dest_x;
		height = height + dest_y;
	}
	/* minimize gc creation by remembering the last requested depth */
	if (last_gc != None && depth != last_depth)
	{
		XFreeGC(dpy, last_gc);
		last_gc = None;
	}
	if (last_gc == None)
	{
		last_gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv);
	}
	draw_gc = last_gc;
	last_depth = depth;

	if (FHaveShapeExtension && colorset->shape_mask != None)
	{
		clipmask = CreateBackgroundPixmap(
			dpy, 0, width, height, colorset, 1, None, True);
		if (clipmask)
		{
			/* create a GC for clipping */
			xgcv.clip_x_origin = x;
			xgcv.clip_y_origin = y;
			xgcv.clip_mask = clipmask;
			clip_gc = fvwmlib_XCreateGC(
				dpy, win, GCClipXOrigin | GCClipYOrigin |
				GCClipMask, &xgcv);
			draw_gc = clip_gc;
		}
	}

	if (!colorset->pixmap)
	{
		/* use the bg pixel */
		XSetForeground(dpy, draw_gc, colorset->bg);
		XFillRectangle(
			dpy, win, draw_gc, dest_x, dest_y, dest_w, dest_h);
	}
	else
	{
		pixmap = CreateBackgroundPixmap(
			dpy, win, width, height, colorset, depth, gc, False);
		if (keep_aspect)
		{
			/* nothing to do */
		}
		if (stretch_x || stretch_y)
		{
			if (!stretch_x && colorset->width != width)
			{
				pixmap2 = CreateStretchXPixmap(
					dpy, pixmap, colorset->width, height,
					depth, width, gc);
				XFreePixmap(dpy, pixmap);
				pixmap = pixmap2;
			}
			if (!stretch_y && colorset->height != height)
			{
				pixmap2 = CreateStretchYPixmap(
					dpy, pixmap, width, colorset->height,
					depth, height, gc);
				XFreePixmap(dpy, pixmap);
				pixmap = pixmap2;
			}
		}
		else
		{
			pixmap2 = CreateTiledPixmap(
				dpy, pixmap, colorset->width, colorset->height,
				width, height, depth, gc);
			XFreePixmap(dpy, pixmap);
			pixmap = pixmap2;
		}

		if (pixmap)
		{
			/* Copy the pixmap into the rectangle. */
			XCopyArea(
				dpy, pixmap, win, draw_gc,
				dest_x - x, dest_y - y, dest_w, dest_h,
				dest_x, dest_y);
			XFreePixmap(dpy, pixmap);
		}
	}

	if (FHaveShapeExtension)
	{
		if (clipmask != None)
		{
			XFreePixmap(dpy, clipmask);
		}
		if (clip_gc != None)
		{
			XFreeGC(dpy, clip_gc);
		}
	}

	return;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
Archivo: Colorset.c Proyecto: att/uwin
/* Draws a colorset background into the specified rectangle in the target
 * drawable. */
void SetRectangleBackground(
  Display *dpy, Window win, int x, int y, int width, int height,
  colorset_struct *colorset, unsigned int depth, GC gc)
{
  GC draw_gc;
  Pixmap pixmap2;
  Pixmap pixmap = None;
  static int last_depth = -1;
  static GC last_gc = None;
  XGCValues xgcv;
  Pixmap clipmask = None;
  GC clip_gc = None;
  Bool keep_aspect = (colorset->pixmap_type == PIXMAP_STRETCH_ASPECT);
  Bool stretch_x = (colorset->pixmap_type == PIXMAP_STRETCH_X)
		   || (colorset->pixmap_type == PIXMAP_STRETCH);
  Bool stretch_y = (colorset->pixmap_type == PIXMAP_STRETCH_Y)
		   || (colorset->pixmap_type == PIXMAP_STRETCH);

  if (colorset->pixmap == ParentRelative)
  {
    XClearArea(dpy, win, x, y, width, height, False);
    /* don't do anything */
    return;
  }
  /* minimize gc creation by remembering the last requested depth */
  if (last_gc != None && depth != last_depth)
  {
    XFreeGC(dpy, last_gc);
    last_gc = None;
  }
  if (last_gc == None)
  {
    last_gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv);
  }
  draw_gc = last_gc;
  last_depth = depth;

  if (FHaveShapeExtension && colorset->shape_mask != None)
  {
    clipmask = CreateBackgroundPixmap(
      dpy, 0, width, height, colorset, 1, None, True);
    if (clipmask)
    {
      /* create a GC for clipping */
      xgcv.clip_x_origin = x;
      xgcv.clip_y_origin = y;
      xgcv.clip_mask = clipmask;
      clip_gc = fvwmlib_XCreateGC(
	dpy, win, GCClipXOrigin|GCClipYOrigin|GCClipMask, &xgcv);
      draw_gc = clip_gc;
    }
  }

  if (!colorset->pixmap)
  {
    /* use the bg pixel */
    XSetForeground(dpy, draw_gc, colorset->bg);
    XFillRectangle(dpy, win, draw_gc, x, y, width, height);
  }
  else
  {
    pixmap = CreateBackgroundPixmap(
      dpy, win, width, height, colorset, depth, gc, False);
    if (keep_aspect)
    {
      /* nothing to do */
    }
    if (stretch_x || stretch_y)
    {
      if (!stretch_x && colorset->width != width)
      {
	pixmap2 = CreateStretchXPixmap(
	  dpy, pixmap, colorset->width, height, depth, width, gc);
	XFreePixmap(dpy, pixmap);
	pixmap = pixmap2;
      }
      if (!stretch_y && colorset->height != height)
      {
	pixmap2 = CreateStretchYPixmap(
	  dpy, pixmap, width, colorset->height, depth, width, gc);
	XFreePixmap(dpy, pixmap);
	pixmap = pixmap2;
      }
    }
    else
    {
      pixmap2 = CreateTiledPixmap(
	dpy, pixmap, colorset->width, colorset->height, width, height, depth,
	gc);
      XFreePixmap(dpy, pixmap);
      pixmap = pixmap2;
    }

    if (pixmap)
    {
      /* Copy the pixmap into the rectangle. */
      XCopyArea(dpy, pixmap, win, draw_gc, 0, 0, width, height, x, y);
      XFreePixmap(dpy, pixmap);
    }
  }

  if (FHaveShapeExtension)
  {
    if (clipmask != None)
      XFreePixmap(dpy, clipmask);
    if (clip_gc != None)
      XFreeGC(dpy, clip_gc);
  }
}
Ejemplo n.º 5
0
Archivo: Colorset.c Proyecto: 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;
}