Beispiel #1
0
static void __focus_grab_buttons(FvwmWindow *fw, Bool client_entered)
{
	int i;
	Bool do_grab_window = False;
	int grab_buttons;

	if (fw == NULL || IS_SCHEDULED_FOR_DESTROY(fw) || !IS_MAPPED(fw))
	{
		/* It is pointless to grab buttons on dieing windows.  Buttons
		 * can not be grabbed when the window is unmapped. */
		return;
	}
	grab_buttons = Scr.buttons2grab;
	do_grab_window = focus_query_grab_buttons(fw, client_entered);
	if (do_grab_window == True)
	{
		grab_buttons |= FP_USE_MOUSE_BUTTONS(FW_FOCUS_POLICY(fw));
	}
	if (grab_buttons != fw->grabbed_buttons)
	{
		MyXGrabServer(dpy);
		for (i = 0; i < NUMBER_OF_EXTENDED_MOUSE_BUTTONS; i++)
		{
			__focus_grab_one_button(fw, i, grab_buttons);
		}
		MyXUngrabServer (dpy);
	}

	return;
}
Beispiel #2
0
/*
    ResyncFvwmStackRing -
    Rebuilds the stacking order ring of FVWM-managed windows. For use in cases
    where apps raise/lower their own windows in a way that makes it difficult to
    determine exactly where they ended up in the stacking order.
    - Based on code from Matthias Clasen.
*/
void  ResyncFvwmStackRing (void)
{
  Window root, parent, *children;
  unsigned int nchildren, i;
  FvwmWindow *t1, *t2;

  MyXGrabServer (dpy);

  if (!XQueryTree (dpy, Scr.Root, &root, &parent, &children, &nchildren))
    {
      MyXUngrabServer (dpy);
      return;
    }

  t2 = &Scr.FvwmRoot;
  for (i = 0; i < nchildren; i++)
    {
      for (t1 = Scr.FvwmRoot.next; t1 != NULL; t1 = t1->next)
	{
          if (t1->flags & ICONIFIED && (!(t1->flags & SUPPRESSICON)))
            {
	      if (t1->icon_w == children[i])
	        {
	          break;
	        }
              else if (t1->icon_pixmap_w == children[i])
	        {
	          break;
	        }
            }
          else
            {
	      if (t1->frame == children[i])
	        {
	          break;
	        }
            }
	}

      if (t1 != NULL && t1 != t2)
	{
          /*
              Move the window to its new position, working from the bottom up
              (that's the way XQueryTree presents the list).
          */
          t1->stack_prev->stack_next = t1->stack_next;  /* Pluck from chain.       */
          t1->stack_next->stack_prev = t1->stack_prev;
          t1->stack_next = t2;                          /* Set new pointers.       */
          t1->stack_prev = t2->stack_prev;
          t2->stack_prev->stack_next = t1;              /* Insert in new position. */
          t2->stack_prev = t1;
          t2 = t1;

	}
    }

  MyXUngrabServer (dpy);

  XFree (children);
}
Beispiel #3
0
/* This function is part of a hack to make focus handling work better with
 * applications that use the passive focus model but manage focus in their own
 * sub windows and should thus use the locally active focus model instead.
 * There are many examples like netscape or ddd. */
void focus_force_refresh_focus(const FvwmWindow *fw)
{
	XWindowAttributes winattrs;

	MyXGrabServer(dpy);
	if (XGetWindowAttributes(dpy, FW_W(fw), &winattrs))
	{
		XSelectInput(
			dpy, FW_W(fw),
			winattrs.your_event_mask & ~FocusChangeMask);
		FOCUS_SET(FW_W(fw), NULL /* we don't expect an event */);
		XSelectInput(dpy, FW_W(fw), winattrs.your_event_mask);
	}
	MyXUngrabServer(dpy);

	return;
}
Beispiel #4
0
/* This function is part of a hack to make focus handling work better with
 * applications that use the passive focus model but manage focus in their own
 * sub windows and should thus use the locally active focus model instead.
 * There are many examples like netscape or ddd. */
void refresh_focus(FvwmWindow *fw)
{
  Bool do_refresh = False;

  if (fw == NULL || fw != get_focus_window() || HAS_NEVER_FOCUS(fw))
  {
    /* only refresh the focus on the currently focused window */
    return;
  }

  /* only refresh the focus for windows with the passive focus model so that
   * we don't disturb focus handling more than necessary */
  switch (fw->focus_model)
  {
  case FM_PASSIVE:
    do_refresh = True;
    break;
  case FM_NO_INPUT:
  case FM_GLOBALLY_ACTIVE:
  case FM_LOCALLY_ACTIVE:
  default:
    do_refresh = False;
    break;
  }
  if (do_refresh)
  {
    XWindowAttributes winattrs;

    MyXGrabServer(dpy);
    if (XGetWindowAttributes(dpy, fw->w, &winattrs))
    {
      XSelectInput(dpy, fw->w, winattrs.your_event_mask & ~FocusChangeMask);
      FOCUS_SET(fw->w);
      XSelectInput(dpy, fw->w, winattrs.your_event_mask);
    }
    MyXUngrabServer(dpy);
  }

  return;
}
Beispiel #5
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;
}
Beispiel #6
0
/* translate a colorset spec into a colorset structure */
void parse_colorset(int n, char *line)
{
	int i;
	int w;
	int h;
	int tmp;
	int percent;
	colorset_t *cs;
	char *optstring;
	char *args;
	char *option;
	char *tmp_str;
	char *fg = NULL;
	char *bg = NULL;
	char *hi = NULL;
	char *sh = NULL;
	char *fgsh = NULL;
	char *tint = NULL;
	char *fg_tint = NULL;
	char *bg_tint = NULL;
	char *icon_tint = NULL;
	Bool have_pixels_changed = False;
	Bool has_icon_pixels_changed = False;
	Bool has_fg_changed = False;
	Bool has_bg_changed = False;
	Bool has_sh_changed = False;
	Bool has_hi_changed = False;
	Bool has_fgsh_changed = False;
	Bool has_fg_alpha_changed = False;
	Bool has_tint_changed = False;
	Bool has_fg_tint_changed = False;
	Bool has_bg_tint_changed = False;
	Bool has_icon_tint_changed = False;
	Bool has_pixmap_changed = False;
	Bool has_shape_changed = False;
	Bool has_image_alpha_changed = False;
	Bool pixmap_is_a_bitmap = False;
	Bool do_reload_pixmap = False;
	Bool is_server_grabbed = False;
	XColor color;
	XGCValues xgcv;
	static char *name = "parse_colorset";
	Window win = Scr.NoFocusWin;
	static GC gc = None;

	/* initialize statics */
	if (gc == None)
	{
		gc = fvwmlib_XCreateGC(dpy, win, 0, &xgcv);
	}

	/* make sure it exists and has sensible contents */
	alloc_colorset(n);
	cs = &Colorset[n];

	/*** Parse the options ***/
	while (line && *line)
	{
		/* Read next option specification delimited by a comma or \0.
		 */
		line = GetQuotedString(
			line, &optstring, ",", NULL, NULL, NULL);
		if (!optstring)
			break;
		args = GetNextToken(optstring, &option);
		if (!option)
		{
			free(optstring);
			break;
		}

		switch((i = GetTokenIndex(option, csetopts, 0, NULL)))
		{
		case 0: /* Foreground */
		case 1: /* Fore */
		case 2: /* fg */
			get_simple_color(
				args, &fg, cs, FG_SUPPLIED, FG_CONTRAST,
				"contrast");
			has_fg_changed = True;
			break;
		case 3: /* Background */
		case 4: /* Back */
		case 5: /* bg */
			get_simple_color(
				args, &bg, cs, BG_SUPPLIED, BG_AVERAGE,
				"average");
			has_bg_changed = True;
			break;
		case 6: /* Hilight */
		case 7: /* Hilite */
		case 8: /* hi */
			get_simple_color(args, &hi, cs, HI_SUPPLIED, 0, NULL);
			has_hi_changed = True;
			break;
		case 9: /* Shadow */
		case 10: /* Shade */
		case 11: /* sh */
			get_simple_color(args, &sh, cs, SH_SUPPLIED, 0, NULL);
			has_sh_changed = True;
			break;
		case 12: /* fgsh */
			get_simple_color(
				args, &fgsh, cs, FGSH_SUPPLIED, 0,NULL);
			has_fgsh_changed = True;
			break;
		case 13: /* fg_alpha */
		case 14: /* fgAlpha */
			if (GetIntegerArguments(args, NULL, &tmp, 1))
			{
				if (tmp > 100)
					tmp = 100;
				else if (tmp < 0)
					tmp = 0;
			}
			else
			{
				tmp = 100;
			}
			if (tmp != cs->fg_alpha_percent)
			{
				cs->fg_alpha_percent = tmp;
				has_fg_alpha_changed = True;
			}
			break;
		case 15: /* TiledPixmap */
		case 16: /* Pixmap */
		case 17: /* AspectPixmap */
			has_pixmap_changed = True;
			free_colorset_background(cs, True);
			tmp_str = PeekToken(args, &args);
			if (tmp_str)
			{
				CopyString(&cs->pixmap_args, tmp_str);
				do_reload_pixmap = True;
				cs->gradient_type = 0;
				/* set the flags */
				if (csetopts[i][0] == 'T')
				{
					cs->pixmap_type = PIXMAP_TILED;
				}
				else if (csetopts[i][0] == 'A')
				{
					cs->pixmap_type = PIXMAP_STRETCH_ASPECT;
				}
				else
				{
					cs->pixmap_type = PIXMAP_STRETCH;
				}
			}
			/* the pixmap is build later */
			break;
		case 18: /* Shape */
		case 19: /* TiledShape */
		case 20: /* AspectShape */
			parse_shape(win, cs, i, args, &has_shape_changed);
			break;
		case 21: /* Plain */
			has_pixmap_changed = True;
			free_colorset_background(cs, True);
			break;
		case 22: /* NoShape */
			has_shape_changed = True;
			if (cs->shape_mask)
			{
				add_to_junk(cs->shape_mask);
				cs->shape_mask = None;
			}
			break;
		case 23: /* Transparent */

			/* This is only allowable when the root depth == fvwm
			 * visual depth otherwise bad match errors happen,
			 * it may be even more restrictive but my tests (on
			 * exceed 6.2) show that only == depth is necessary */

			if (Pdepth != DefaultDepth(dpy, (DefaultScreen(dpy))))
			{
				fvwm_msg(
					ERR, name, "can't do Transparent "
					"when root_depth!=fvwm_depth");
				break;
			}
			has_pixmap_changed = True;
			free_colorset_background(cs, True);
			cs->pixmap = ParentRelative;
			cs->pixmap_type = PIXMAP_STRETCH;
			break;
		case 24: /* RootTransparent */
			if (Pdepth != DefaultDepth(dpy, (DefaultScreen(dpy))))
			{
				fvwm_msg(
					ERR, name, "can't do RootTransparent "
					"when root_depth!=fvwm_depth");
				break;
			}
			free_colorset_background(cs, True);
			has_pixmap_changed = True;
			cs->pixmap_type = PIXMAP_ROOT_PIXMAP_PURE;
			do_reload_pixmap = True;
			tmp_str = PeekToken(args, &args);
			if (StrEquals(tmp_str, "buffer"))
			{
				cs->allows_buffered_transparency = True;
			}
			else
			{
				cs->allows_buffered_transparency = False;
			}
			cs->is_maybe_root_transparent = True;
			break;
		case 25: /* Tint */
		case 26: /* PixmapTint */
		case 27: /* ImageTint */
		case 28: /* TintMask */
			parse_simple_tint(
				cs, args, &tint, TINT_SUPPLIED,
				&has_tint_changed, &percent, "tint");
			if (has_tint_changed)
			{
				cs->tint_percent = percent;
			}
			break;
		case 29: /* NoTint */
			has_tint_changed = True;
			cs->tint_percent = 0;
			cs->color_flags &= ~TINT_SUPPLIED;
			break;
		case 30: /* fgTint */
			parse_simple_tint(
				cs, args, &fg_tint, FG_TINT_SUPPLIED,
				&has_fg_tint_changed, &percent, "fgTint");
			if (has_fg_tint_changed)
			{
				cs->fg_tint_percent = percent;
			}
			break;
		case 31: /* bgTint */
			parse_simple_tint(
				cs, args, &bg_tint, BG_TINT_SUPPLIED,
				&has_bg_tint_changed, &percent, "bgTint");
			if (has_bg_tint_changed)
			{
				cs->bg_tint_percent = percent;
			}
			break;
		case 32: /* dither */
			if (cs->pixmap_args || cs->gradient_args)
			{
				has_pixmap_changed = True;
				do_reload_pixmap = True;
			}
			cs->dither = True;
			break;
		case 33: /* nodither */
			if (cs->pixmap_args || cs->gradient_args)
			{
				has_pixmap_changed = True;
				do_reload_pixmap = True;
			}
			cs->dither = False;
			break;
		case 34: /* Alpha */
		case 35: /* PixmapAlpha */
		case 36: /* ImageAlpha */
			if (GetIntegerArguments(args, NULL, &tmp, 1))
			{
				if (tmp > 100)
					tmp = 100;
				else if (tmp < 0)
					tmp = 0;
			}
			else
			{
				tmp = 100;
			}
			if (tmp != cs->image_alpha_percent)
			{
				has_image_alpha_changed = True;
				cs->image_alpha_percent = tmp;
			}
			break;
                /* dither icon is not dynamic (yet) maybe a bad opt: default
		 * to False ? */
		case 37: /* ditherIcon */
			cs->do_dither_icon = True;
			break;
		case 38: /* DoNotDitherIcon */
			cs->do_dither_icon = False;
			break;
		case 39: /* IconTint */
			parse_simple_tint(
				cs, args, &icon_tint, ICON_TINT_SUPPLIED,
				&has_icon_tint_changed, &percent, "IconTint");
			if (has_icon_tint_changed)
			{
				cs->icon_tint_percent = percent;
				has_icon_pixels_changed = True;
			}
			break;
		case 40: /* NoIconTint */
			has_icon_tint_changed = True;
			if (cs->icon_tint_percent != 0)
			{
				has_icon_pixels_changed = True;
			}
			cs->icon_tint_percent = 0;
			break;
		case 41: /* IconAlpha */
			if (GetIntegerArguments(args, NULL, &tmp, 1))
			{
				if (tmp > 100)
					tmp = 100;
				else if (tmp < 0)
					tmp = 0;
			}
			else
			{
				tmp = 100;
			}
			if (tmp != cs->icon_alpha_percent)
			{
				has_icon_pixels_changed = True;
				cs->icon_alpha_percent = tmp;
			}
			break;
		default:
			/* test for ?Gradient */
			if (option[0] && StrEquals(&option[1], "Gradient"))
			{
				cs->gradient_type = toupper(option[0]);
				if (!IsGradientTypeSupported(cs->gradient_type))
					break;
				has_pixmap_changed = True;
				free_colorset_background(cs, True);
				CopyString(&cs->gradient_args, args);
				do_reload_pixmap = True;
				if (cs->gradient_type == V_GRADIENT)
				{
					cs->pixmap_type = PIXMAP_STRETCH_Y;
				}
				else if (cs->gradient_type == H_GRADIENT)
					cs->pixmap_type = PIXMAP_STRETCH_X;
				else
					cs->pixmap_type = PIXMAP_STRETCH;
			}
			else
			{
				fvwm_msg(
					WARN, name, "bad colorset pixmap "
					"specifier %s %s", option, line);
			}
			break;
		} /* switch */

		if (option)
		{
			free(option);
			option = NULL;
		}
		free(optstring);
		optstring = NULL;
	} /* while (line && *line) */

	/*
	 * ---------- change the "pixmap" tint colour ----------
	 */
	if (has_tint_changed)
	{
		/* user specified colour */
		if (tint != NULL)
		{
			Pixel old_tint = cs->tint;
			PictureFreeColors(dpy, Pcmap, &cs->tint, 1, 0, True);
			cs->tint = GetColor(tint);
			if (old_tint != cs->tint)
			{
				have_pixels_changed = True;
			}
		}
		else if (tint == NULL)
		{
			/* default */
			Pixel old_tint = cs->tint;
			PictureFreeColors(dpy, Pcmap, &cs->tint, 1, 0, True);
			cs->tint = GetColor(black);
			if (old_tint != cs->tint)
			{
				have_pixels_changed = True;
			}
		}
	}

	/*
	 * reload the gradient if the tint or the alpha have changed.
	 * Do this too if we need to recompute the bg average and the
	 * gradient is tinted (perforemence issue).
	 */
	if ((has_tint_changed || has_image_alpha_changed ||
	     (has_bg_changed && (cs->color_flags & BG_AVERAGE) &&
	      cs->tint_percent > 0)) && cs->gradient_args)
	{
		do_reload_pixmap = True;
	}

	/*
	 * reset the pixmap if the tint or the alpha has changed
	 */
	if (!do_reload_pixmap &&
	    (has_tint_changed || has_image_alpha_changed  ||
	     (has_bg_changed && cs->alpha_pixmap != None)))
	{
		if (cs->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE ||
		    cs->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN)
		{
			do_reload_pixmap = True;
		}
		else if (cs->picture != NULL && cs->pixmap)
		{
			XSetClipMask(dpy, gc, cs->picture->mask);
			reset_cs_pixmap(cs, gc);
			XSetClipMask(dpy, gc, None);
			has_pixmap_changed = True;
		}
	}

	/*
	 * (re)build the pixmap or the gradient
	 */
	if (do_reload_pixmap)
	{
		free_colorset_background(cs, False);
		has_pixmap_changed = True;
		if (cs->pixmap_type == PIXMAP_ROOT_PIXMAP_PURE ||
		    cs->pixmap_type == PIXMAP_ROOT_PIXMAP_TRAN)
		{
			cs->pixmap_type = 0;
			if (root_pic.pixmap)
			{
				cs->pixmap = root_pic.pixmap;
				cs->width = root_pic.width;
				cs->height = root_pic.height;
				cs->pixmap_type = PIXMAP_ROOT_PIXMAP_PURE;
#if 0
				fprintf(stderr,"Cset %i LoadRoot 0x%lx\n",
					n, cs->pixmap);
#endif
			}
		}
		else if (cs->pixmap_args)
		{
			parse_pixmap(win, gc, cs, &pixmap_is_a_bitmap);
		}
		else if (cs->gradient_args)
		{
			cs->pixmap = CreateGradientPixmapFromString(
				dpy, win, gc, cs->gradient_type,
				cs->gradient_args, &w, &h, &cs->pixels,
				&cs->nalloc_pixels, cs->dither);
			cs->width = w;
			cs->height = h;
		}
		has_pixmap_changed = True;
	}

	if (cs->picture != NULL && cs->picture->depth != Pdepth)
	{
		pixmap_is_a_bitmap = True;
	}

	/*
	 * ---------- change the background colour ----------
	 */
	if (has_bg_changed ||
	    (has_pixmap_changed && (cs->color_flags & BG_AVERAGE) &&
	     cs->pixmap != None &&
	     cs->pixmap != ParentRelative &&
	     !pixmap_is_a_bitmap))
	{
		Bool do_set_default_background = False;
		Pixmap average_pix = None;

		if (cs->color_flags & BG_AVERAGE)
		{
			if (cs->picture != NULL && cs->picture->picture != None)
			{
				average_pix = cs->picture->picture;
			}
			else if (cs->pixmap != ParentRelative)
			{
				average_pix = cs->pixmap;
			}

			if (average_pix == root_pic.pixmap)
			{
				int w;
				int h;
				XID dummy;

				MyXGrabServer(dpy);
				is_server_grabbed = True;
				if (!XGetGeometry(
				    dpy, average_pix, &dummy,
				    (int *)&dummy, (int *)&dummy,
				    (unsigned int *)&w, (unsigned int *)&h,
				    (unsigned int *)&dummy,
				    (unsigned int *)&dummy))
				{
					average_pix = None;
				}
				else
				{
					if (w != cs->width || h != cs->height)
					{
						average_pix = None;
					}
				}
				if (average_pix == None)
				{
					MyXUngrabServer(dpy);
					is_server_grabbed = False;
				}
			}
		}

		/* note: no average for bitmap */
		if ((cs->color_flags & BG_AVERAGE) && average_pix)
		{
			/* calculate average background color */
			XColor *colors;
			XImage *image;
			XImage *mask_image = None;
			unsigned int i, j, k = 0;
			unsigned long red = 0, blue = 0, green = 0;
			unsigned long tred, tblue, tgreen;
			double dred = 0.0, dblue = 0.0, dgreen = 0.0;

			has_bg_changed = True;
			/* create an array to store all the pixmap colors in */
			/* Note: this may allocate a lot of memory:
			 * cs->width * cs->height * 12 and then the rest of the
			 * procedure can take a lot of times */
			colors = (XColor *)safemalloc(
				cs->width * cs->height * sizeof(XColor));
			/* get the pixmap and mask into an image */
			image = XGetImage(
				dpy, average_pix, 0, 0, cs->width, cs->height,
				AllPlanes, ZPixmap);
			if (cs->mask != None)
			{
				mask_image = XGetImage(
					dpy, cs->mask, 0, 0, cs->width,
					cs->height, AllPlanes, ZPixmap);
			}
			if (is_server_grabbed == True)
			{
				MyXUngrabServer(dpy);
			}
			if (image != None && mask_image != None)
			{
				/* only fetch the pixels that are not masked
				 * out */
				for (i = 0; i < cs->width; i++)
				{
					for (j = 0; j < cs->height; j++)
					{
						if (
							cs->mask == None ||
							XGetPixel(
								mask_image, i,
								j) == 0)
						{
							colors[k++].pixel =
								XGetPixel(
									image,
									i, j);
						}
					}
				}
			}
			if (image != None)
			{
				XDestroyImage(image);
			}
			if (mask_image != None)
			{
				XDestroyImage(mask_image);
			}
			if (k == 0)
			{
				do_set_default_background = True;
			}
			else
			{
				/* look them all up, XQueryColors() can't
				 * handle more than 256 */
				for (i = 0; i < k; i += 256)
				{
					XQueryColors(
						dpy, Pcmap, &colors[i],
						min(k - i, 256));
				}
				/* calculate average, add overflows in a double
				 * .red is short, red is long */
				for (i = 0; i < k; i++)
				{
					tred = red;
					red += colors[i].red;
					if (red < tred)
					{
						dred += (double)tred;
						red = colors[i].red;
					}
					tgreen = green;
					green += colors[i].green;
					if (green < tgreen)
					{
						dgreen += (double)tgreen;
						green = colors[i].green;
					}
					tblue = blue;
					blue += colors[i].blue;
					if (blue < tblue)
					{
						dblue += (double)tblue;
						blue = colors[i].blue;
					}
				}
				dred += red;
				dgreen += green;
				dblue += blue;
				/* get it */
				color.red = dred / k;
				color.green = dgreen / k;
				color.blue = dblue / k;
				{
					Pixel old_bg = cs->bg;

					PictureFreeColors(
						dpy, Pcmap, &cs->bg, 1, 0,
						True);
					PictureAllocColor(
						dpy, Pcmap, &color, True);
					cs->bg = color.pixel;
					if (old_bg != cs->bg)
					{
						have_pixels_changed = True;
					}
				}
			}
			free(colors);
		} /* average */
		else if ((cs->color_flags & BG_SUPPLIED) && bg != NULL)
		{
			/* user specified colour */
			Pixel old_bg = cs->bg;

			PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True);
			cs->bg = GetColor(bg);
			if (old_bg != cs->bg)
			{
				have_pixels_changed = True;
			}
		} /* user specified */
		else if (bg == NULL && has_bg_changed)
		{
			/* default */
			do_set_default_background = True;
		} /* default */
		if (do_set_default_background)
		{
			Pixel old_bg = cs->bg;

			PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True);
			cs->bg = GetColor(white);
			if (old_bg != cs->bg)
			{
				have_pixels_changed = True;
			}
			has_bg_changed = True;
		}

		if (has_bg_changed)
		{
			/* save the bg color for tinting */
			cs->bg_saved = cs->bg;
		}
	} /* has_bg_changed */


	/*
	 * ---------- setup the bg tint colour ----------
	 */
	if (has_bg_tint_changed && cs->bg_tint_percent > 0 && bg_tint != NULL)
	{
		PictureFreeColors(dpy, Pcmap, &cs->bg_tint, 1, 0, True);
		cs->bg_tint = GetColor(bg_tint);
	}

	/*
	 * ---------- tint the bg colour ----------
	 */
	if (has_bg_tint_changed || (has_bg_changed && cs->bg_tint_percent > 0))
	{
		if (cs->bg_tint_percent == 0)
		{
			Pixel old_bg = cs->bg;

			PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True);
			cs->bg = cs->bg_saved;
			if (old_bg != cs->bg)
			{
				have_pixels_changed = True;
				has_bg_changed = True;
			}
		}
		else
		{
			Pixel old_bg = cs->bg;

			PictureFreeColors(dpy, Pcmap, &cs->bg, 1, 0, True);
			cs->bg = GetTintedPixel(
				cs->bg_saved, cs->bg_tint, cs->bg_tint_percent);
			if (old_bg != cs->bg)
			{
				have_pixels_changed = True;
				has_bg_changed = True;
			}
		}
	}

	/*
	 * ---------- setup the fg tint colour ----------
	 */
	if (has_fg_tint_changed && cs->fg_tint_percent > 0 && fg_tint != NULL)
	{
		PictureFreeColors(dpy, Pcmap, &cs->fg_tint, 1, 0, True);
		cs->fg_tint = GetColor(fg_tint);
	}

	/*
	 * ---------- change the foreground colour ----------
	 */
	if (has_fg_changed ||
	    (has_bg_changed && (cs->color_flags & FG_CONTRAST)))
	{
		if (cs->color_flags & FG_CONTRAST)
		{
			Pixel old_fg = cs->fg;

			/* calculate contrasting foreground color */
			color.pixel = cs->bg;
			XQueryColor(dpy, Pcmap, &color);
			color.red = (color.red > 32767) ? 0 : 65535;
			color.green = (color.green > 32767) ? 0 : 65535;
			color.blue = (color.blue > 32767) ? 0 : 65535;

			PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
			PictureAllocColor(dpy, Pcmap, &color, True);
			cs->fg = color.pixel;
			if (old_fg != cs->fg)
			{
				have_pixels_changed = True;
				has_fg_changed = 1;
			}
		} /* contrast */
		else if ((cs->color_flags & FG_SUPPLIED) && fg != NULL)
		{
			/* user specified colour */
			Pixel old_fg = cs->fg;

			PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
			cs->fg = GetColor(fg);
			if (old_fg != cs->fg)
			{
				have_pixels_changed = True;
				has_fg_changed = 1;
			}
		} /* user specified */
		else if (fg == NULL)
		{
			/* default */
			Pixel old_fg = cs->fg;

			PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
			cs->fg = GetColor(black);
			if (old_fg != cs->fg)
			{
				have_pixels_changed = True;
				has_fg_changed = 1;
			}
		}

		/* save the fg color for tinting */
		cs->fg_saved = cs->fg;

	} /* has_fg_changed */

	/*
	 * ---------- tint the foreground colour ----------
	 */
	if (has_fg_tint_changed || (has_fg_changed && cs->fg_tint_percent > 0))
	{
		if (cs->fg_tint_percent == 0)
		{

			Pixel old_fg = cs->fg;

			PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
			cs->fg = cs->fg_saved;
			if (old_fg != cs->fg)
			{
				have_pixels_changed = True;
				has_fg_changed = 1;
			}
		}
		else
		{
			Pixel old_fg = cs->fg;

			PictureFreeColors(dpy, Pcmap, &cs->fg, 1, 0, True);
			cs->fg = GetTintedPixel(
				cs->fg_saved, cs->fg_tint,
				cs->fg_tint_percent);
			if (old_fg != cs->fg)
			{
				have_pixels_changed = True;
				has_fg_changed = 1;
			}
		}
	}


	/*
	 * ---------- change the hilight colour ----------
	 */
	if (has_hi_changed ||
	    (has_bg_changed && !(cs->color_flags & HI_SUPPLIED)))
	{
		has_hi_changed = 1;
		if ((cs->color_flags & HI_SUPPLIED) && hi != NULL)
		{
			/* user specified colour */
			Pixel old_hilite = cs->hilite;

			PictureFreeColors(dpy, Pcmap, &cs->hilite, 1, 0, True);
			cs->hilite = GetColor(hi);
			if (old_hilite != cs->hilite)
			{
					have_pixels_changed = True;
			}
		} /* user specified */
		else if (hi == NULL)
		{
			Pixel old_hilite = cs->hilite;

			PictureFreeColors(dpy, Pcmap, &cs->hilite, 1, 0, True);
			cs->hilite = GetHilite(cs->bg);
			if (old_hilite != cs->hilite)
			{
				have_pixels_changed = True;
			}
		}
	} /* has_hi_changed */

	/*
	 * ---------- change the shadow colour ----------
	 */
	if (has_sh_changed ||
	    (has_bg_changed && !(cs->color_flags & SH_SUPPLIED)))
	{
		has_sh_changed = 1;
		if ((cs->color_flags & SH_SUPPLIED) && sh != NULL)
		{
			/* user specified colour */
			Pixel old_shadow = cs->shadow;

			PictureFreeColors(dpy, Pcmap, &cs->shadow, 1, 0, True);
			cs->shadow = GetColor(sh);
			if (old_shadow != cs->shadow)
			{
				have_pixels_changed = True;
			}
		} /* user specified */
		else if (sh == NULL)
		{
			Pixel old_shadow = cs->shadow;

			PictureFreeColors(dpy, Pcmap, &cs->shadow, 1, 0, True);
			cs->shadow = GetShadow(cs->bg);
			if (old_shadow != cs->shadow)
			{
				have_pixels_changed = True;
			}
		}
	} /* has_sh_changed */

	/*
	 * ---------- change the shadow foreground colour ----------
	 */
	if (has_fgsh_changed ||
	    ((has_fg_changed || has_bg_changed) &&
	     !(cs->color_flags & FGSH_SUPPLIED)))
	{
		has_fgsh_changed = 1;
		if ((cs->color_flags & FGSH_SUPPLIED) && fgsh != NULL)
		{
			/* user specified colour */
			Pixel old_fgsh = cs->fgsh;

			PictureFreeColors(dpy, Pcmap, &cs->fgsh, 1, 0, True);
			cs->fgsh = GetColor(fgsh);
			if (old_fgsh != cs->fgsh)
			{
				have_pixels_changed = True;
			}
		} /* user specified */
		else if (fgsh == NULL)
		{
			Pixel old_fgsh = cs->fgsh;

			PictureFreeColors(dpy, Pcmap, &cs->fgsh, 1, 0, True);
			cs->fgsh = GetForeShadow(cs->fg, cs->bg);
			if (old_fgsh != cs->fgsh)
			{
				have_pixels_changed = True;
			}
		}
	} /* has_fgsh_changed */

	/*
	 * ------- the pixmap is a bitmap: create here cs->pixmap -------
	 */
	if (cs->picture != None && pixmap_is_a_bitmap &&
	    (has_pixmap_changed || has_bg_changed))
	{
		cs->pixmap = XCreatePixmap(
			dpy, win, cs->width, cs->height, Pdepth);
		XSetBackground(dpy, gc, cs->bg);
		XSetForeground(dpy, gc, cs->fg);
		reset_cs_pixmap(cs, gc);
	}

	/*
	 * ------- change the masked out parts of the background pixmap -------
	 */
	if (cs->pixmap != None && cs->pixmap != ParentRelative &&
	    (!CSETS_IS_TRANSPARENT_ROOT(cs)||
	     cs->allows_buffered_transparency) &&
	    (cs->mask != None || cs->alpha_pixmap != None ||
	     cs->image_alpha_percent < 100 || cs->tint_percent > 0) &&
	    (has_pixmap_changed || has_bg_changed || has_image_alpha_changed
	     || has_tint_changed))
	{
		/* Now that we know the background colour we can update the
		 * pixmap background. */
		FvwmRenderAttributes fra;
		Pixmap temp, mask, alpha;

		memset(&fra, 0, sizeof(fra));
		temp = XCreatePixmap(dpy, win, cs->width, cs->height, Pdepth);
		if (cs->picture != NULL)
		{
			mask = cs->picture->mask;
			alpha = cs->picture->alpha;
		}
		else
		{
			mask = None;
			alpha = None;
		}
		XSetForeground(dpy, gc, cs->bg);
		XFillRectangle(
			dpy, temp, gc, 0, 0, cs->width, cs->height);

		fra.mask = FRAM_HAVE_ADDED_ALPHA | FRAM_HAVE_TINT;
		fra.added_alpha_percent = cs->image_alpha_percent;
		fra.tint = cs->tint;
		fra.tint_percent = cs->tint_percent;
		PGraphicsRenderPixmaps(
			dpy, win, cs->pixmap, mask, alpha, Pdepth, &fra,
			temp, gc, Scr.MonoGC, Scr.AlphaGC,
			0, 0, cs->width, cs->height,
			0, 0, cs->width, cs->height, False);
		if (cs->pixmap != root_pic.pixmap)
		{
			add_to_junk(cs->pixmap);
		}
		cs->pixmap = temp;
		has_pixmap_changed = True;
		if (CSETS_IS_TRANSPARENT_ROOT(cs))
		{
			cs->pixmap_type = PIXMAP_ROOT_PIXMAP_TRAN;
		}
	} /* has_pixmap_changed */


	/*
	 * ---------- change the icon tint colour ----------
	 */
	if (has_icon_tint_changed)
	{
		/* user specified colour */
		if (icon_tint != NULL)
		{
			Pixel old_tint = cs->icon_tint;
			PictureFreeColors(
				dpy, Pcmap, &cs->icon_tint, 1, 0, True);
			cs->icon_tint = GetColor(icon_tint);
			if (old_tint != cs->icon_tint)
			{
				has_icon_pixels_changed = True;
			}
		}
		else
		{
			/* default */
			Pixel old_tint = cs->icon_tint;
			PictureFreeColors(
				dpy, Pcmap, &cs->icon_tint, 1, 0, True);
			cs->icon_tint = GetColor(black);
			if (old_tint != cs->icon_tint)
			{
				has_icon_pixels_changed = True;
			}
		}
	}

	/*
	 * ---------- send new colorset to fvwm and clean up ----------
	 */
	/* make sure the server has this to avoid races */
	XSync(dpy, False);

	/* inform modules of the change */
	if (have_pixels_changed || has_pixmap_changed || has_shape_changed ||
	    has_fg_alpha_changed || has_icon_pixels_changed)
	{
		BroadcastColorset(n);
	}

	if (fg)
	{
		free(fg);
	}
	if (bg)
	{
		free(bg);
	}
	if (hi)
	{
		free(hi);
	}
	if (sh)
	{
		free(sh);
	}
	if (fgsh)
	{
		free(fgsh);
	}
	if (tint)
	{
		free(tint);
	}
	if (fg_tint)
	{
		free(fg_tint);
	}
	if (bg_tint)
	{
		free(bg_tint);
	}
	if (icon_tint)
	{
		free(icon_tint);
	}
	return;
}
Beispiel #7
0
/*
 *
 * Looks for an application supplied icon window
 *
 */
void GetIconWindow(struct icon_info *item)
{
	int x, y;
	unsigned int bw;
	Window Junkroot;

	if (!XGetGeometry(
		dpy, item->wmhints->icon_window, &Junkroot, &x, &y,
		(unsigned int *)&item->icon_w, (unsigned int *)&item->icon_h,
		&bw, (unsigned int *)&item->icon_depth))
	{
#if 0
		fprintf(stderr, "[%s][GetIconWindow] WARN -- '%s' has an "
			"invalid icon window hint\n", MyName, item->name);
#endif
		/* disable the icon window hint */
		item->icon_w = 0;
		item->icon_h = 0;
		item->wmhints->icon_window = None;
		item->wmhints->flags &= ~IconWindowHint;
		return;
	}

	item->icon_pixmap_w = item->wmhints->icon_window;

	if (FShapesSupported && (item->wmhints->flags & IconMaskHint))
	{
		SET_ICON_SHAPED(item, True);
		item->icon_maskPixmap = item->wmhints->icon_mask;
	}

	item->icon_w = min(max_icon_width + icon_relief,  item->icon_w);
	item->icon_h = min(max_icon_height + icon_relief, item->icon_h);

	MyXGrabServer(dpy);
	do_allow_bad_access = True;
	XReparentWindow(dpy, item->icon_pixmap_w, icon_win, 0, 0);
	XSetWindowBorderWidth(dpy, item->icon_pixmap_w, 0);
	XSelectInput(dpy, item->icon_pixmap_w, ICON_EVENTS);
	XSync(dpy, 0);
	do_allow_bad_access = False;
	if (was_bad_access)
	{
		/* give up */
#if 0
		fprintf(stderr, "[%s][GetIconWindow] WARN -- BadAcces when "
			"reparenting %s icon window\n", MyName, item->name);
#endif
		XSelectInput(dpy, item->icon_pixmap_w, NoEventMask);
		XUnmapWindow(dpy, item->icon_pixmap_w);
		XReparentWindow(dpy, item->icon_pixmap_w, Root, 0, 0);
		XUnmapWindow(dpy, item->icon_pixmap_w);
		MyXUngrabServer(dpy);
		item->icon_pixmap_w = item->wmhints->icon_window = None;
		item->wmhints->flags &= ~IconWindowHint;
		item->icon_maskPixmap = None;
		item->icon_w = 0;
		item->icon_h = 0;
		was_bad_access = False;
		return;
	}
	MyXUngrabServer(dpy);
	SET_ICON_OURS(item, False);
	SET_PIXMAP_OURS(item, False);
}
Beispiel #8
0
void focus_grab_buttons(FvwmWindow *tmp_win, Bool is_focused)
{
  int i;
  Bool accepts_input_focus;
  Bool do_grab_window = False;
  unsigned char grab_buttons = Scr.buttons2grab;

  if (!tmp_win || IS_SCHEDULED_FOR_DESTROY(tmp_win))
  {
    /* It's pointless to grab buttons on dying windows */
    return;
  }
  accepts_input_focus = do_accept_input_focus(tmp_win);
  if (HAS_SLOPPY_FOCUS(tmp_win) || HAS_MOUSE_FOCUS(tmp_win) ||
       HAS_NEVER_FOCUS(tmp_win))
  {
    if (DO_RAISE_MOUSE_FOCUS_CLICK(tmp_win) &&
        (!is_focused || !is_on_top_of_layer(tmp_win)))
    {
      grab_buttons = ((1 << NUMBER_OF_MOUSE_BUTTONS) - 1);
      do_grab_window = True;
    }
  }
  else if (HAS_CLICK_FOCUS(tmp_win))
  {
    if (is_focused && !is_on_top_of_layer(tmp_win) &&
        DO_NOT_RAISE_CLICK_FOCUS_CLICK(tmp_win) && accepts_input_focus)
    {
      /* don't grab */
    }
    else if ((!is_focused || !is_on_top_of_layer(tmp_win)) &&
             (!DO_NOT_RAISE_CLICK_FOCUS_CLICK(tmp_win) || accepts_input_focus))
    {
      grab_buttons = ((1 << NUMBER_OF_MOUSE_BUTTONS) - 1);
      do_grab_window = True;
    }
  }

#if 0
  /*
      RBW - If we've come here to grab and all buttons are already grabbed,
      or to ungrab and none is grabbed, then we've nothing to do.
  */
  if ((!is_focused && grab_buttons == tmp_win->grabbed_buttons) ||
     (is_focused && ((tmp_win->grabbed_buttons & grab_buttons) == 0)))
  {
    return;
  }
#else
  if (grab_buttons != tmp_win->grabbed_buttons)
#endif
  {
    Bool do_grab;

    MyXGrabServer(dpy);
    Scr.Ungrabbed = (do_grab_window) ? NULL : tmp_win;
    for (i = 0; i < NUMBER_OF_MOUSE_BUTTONS; i++)
    {
#if 0
      /*  RBW - Set flag for grab or ungrab according to how we were called. */
      if (!is_focused||1)
      {
        do_grab = !!(grab_buttons & (1 << i));
      }
      else
      {
        do_grab = !(grab_buttons & (1 << i));
      }
#else
      if ((grab_buttons & (1 << i)) == (tmp_win->grabbed_buttons & (1 << i)))
	continue;
      do_grab = !!(grab_buttons & (1 << i));
#endif

      {
	register unsigned int mods;
	register unsigned int max = GetUnusedModifiers();
	register unsigned int living_modifiers = ~max;

	/* handle all bindings for the dead modifiers */
	for (mods = 0; mods <= max; mods++)
	{
	  /* Since mods starts with 1 we don't need to test if mods
	   * contains a dead modifier. Otherwise both, dead and living
	   * modifiers would be zero ==> mods == 0 */
	  if (!(mods & living_modifiers))
	  {
	    if (do_grab)
	    {
	      XGrabButton(
		dpy, i + 1, mods, tmp_win->Parent, True, ButtonPressMask,
		GrabModeSync, GrabModeAsync, None, None);
              /*  Set each FvwmWindow flag accordingly, as we grab or ungrab. */
              tmp_win->grabbed_buttons |= (1<<i);
	    }
	    else
	    {
	      XUngrabButton(dpy, (i+1), mods, tmp_win->Parent);
              tmp_win->grabbed_buttons &= ~(1<<i);
	    }
	  }
	} /* for */
      }
    } /* for */
    MyXUngrabServer (dpy);

  }

  return;
}
Beispiel #9
0
/******************************************************************************
  AdjustWindow - Resize the window according to maxwidth by number of buttons
******************************************************************************/
void AdjustWindow(void)
{
    int new_width=0,new_height=0,tw,i,total,off_x,off_y;
    char *temp;
    Window frame;
    XWindowAttributes win_attr, frame_attr;

    total = ItemCountD(&windows );
    if (!total)
    {
        if (WindowIsUp==1)
        {
            XUnmapWindow(dpy,win);
            WindowIsUp=2;
        }
        return;
    }
    for(i=0; i<total; i++)
    {
        temp=ItemName(&windows,i);
        if(temp != NULL)
        {
            tw=10+XTextWidth(ButtonFont,temp,strlen(temp));
            tw+=XTextWidth(ButtonFont,"()",2);

#ifdef MINI_ICONS
            tw+=14; /* for title icon */ /* Magic Number ? */
#endif

            new_width=max(new_width,tw);
        }
    }
    new_width=max(new_width, MinWidth);
    new_width=min(new_width, MaxWidth);
    new_height=(total*(fontheight+6+1));
    if (WindowIsUp && (new_height!=win_height  || new_width!=win_width))
    {
        if (Anchor)
        {
            off_x = off_y = 0;
            MyXGrabServer(dpy);
            frame = find_frame_window(win, &off_x, &off_y);
            XGetWindowAttributes(dpy, frame, &frame_attr);
            XGetWindowAttributes(dpy, win, &win_attr);
            win_x = frame_attr.x + frame_attr.border_width + off_x;
            win_y = frame_attr.y + frame_attr.border_width + off_y;

            if (win_grav == SouthEastGravity || win_grav == NorthEastGravity)
                win_x += win_attr.width - new_width;
            if (win_grav == SouthEastGravity || win_grav == SouthWestGravity)
                win_y += win_attr.height - new_height;

            XMoveResizeWindow(dpy, win, win_x, win_y, new_width, new_height);
            MyXUngrabServer(dpy);
        }
        else
            XResizeWindow(dpy, win, new_width, new_height);

    }
    UpdateArray(&buttons,-1,-1,new_width,-1);
    if (new_height>0) win_height = new_height;
    if (new_width>0) win_width = new_width;
    if (WindowIsUp==2)
    {
        XMapWindow(dpy,win);
        WindowIsUp=1;
        WaitForExpose();
    }
}
Beispiel #10
0
/***********************************************************************
 *
 *  Procedure:
 *	HandleUnmapNotify - UnmapNotify event handler
 *
 ************************************************************************/
void HandleUnmapNotify()
{
  int dstx, dsty;
  Window dumwin;
  XEvent dummy;
  extern FvwmWindow *colormap_win;
  int    weMustUnmap;

  DBUG("HandleUnmapNotify","Routine Entered");

  /*
   * Don't ignore events as described below.
   */
  if((Event.xunmap.event != Event.xunmap.window) &&
     (Event.xunmap.event != Scr.Root || !Event.xunmap.send_event))
    {
      return;
    }

  /*
   * The July 27, 1988 ICCCM spec states that a client wishing to switch
   * to WithdrawnState should send a synthetic UnmapNotify with the
   * event field set to (pseudo-)root, in case the window is already
   * unmapped (which is the case for fvwm for IconicState).  Unfortunately,
   * we looked for the FvwmContext using that field, so try the window
   * field also.
   */
  weMustUnmap = 0;
  if (!Tmp_win)
    {
      Event.xany.window = Event.xunmap.window;
      weMustUnmap = 1;
      if (XFindContext(dpy, Event.xany.window,
		       FvwmContext, (caddr_t *)&Tmp_win) == XCNOENT)
	Tmp_win = NULL;
    }

  if(!Tmp_win)
    return;

  if(weMustUnmap)
    XUnmapWindow(dpy, Event.xunmap.window);

  if(Tmp_win ==  Scr.Hilite)
    Scr.Hilite = NULL;

  if(Scr.PreviousFocus == Tmp_win)
    Scr.PreviousFocus = NULL;

  if((Tmp_win == Scr.Focus)&&(Tmp_win->flags & ClickToFocus))
    {
      if(Tmp_win->next)
	{
	  HandleHardFocus(Tmp_win->next);
	}
      else
	SetFocus(Scr.NoFocusWin,NULL,1);
    }

  if(Scr.Focus == Tmp_win)
    SetFocus(Scr.NoFocusWin,NULL,1);

  if(Tmp_win == Scr.pushed_window)
    Scr.pushed_window = NULL;

  if(Tmp_win == colormap_win)
    colormap_win = NULL;

  if ((!(Tmp_win->flags & MAPPED)&&!(Tmp_win->flags&ICONIFIED)))
    {
      return;
    }

  MyXGrabServer(dpy);

  if(XCheckTypedWindowEvent (dpy, Event.xunmap.window, DestroyNotify,&dummy))
    {
      Destroy(Tmp_win);
      MyXUngrabServer (dpy);
      return;
    }

  /*
   * The program may have unmapped the client window, from either
   * NormalState or IconicState.  Handle the transition to WithdrawnState.
   *
   * We need to reparent the window back to the root (so that fvwm exiting
   * won't cause it to get mapped) and then throw away all state (pretend
   * that we've received a DestroyNotify).
   */
  if (XTranslateCoordinates (dpy, Event.xunmap.window, Scr.Root,
			     0, 0, &dstx, &dsty, &dumwin))
    {
      XEvent ev;
      Bool reparented;

      reparented = XCheckTypedWindowEvent (dpy, Event.xunmap.window,
					   ReparentNotify, &ev);
      SetMapStateProp (Tmp_win, WithdrawnState);
      if (reparented)
	{
	  if (Tmp_win->old_bw)
	    XSetWindowBorderWidth (dpy, Event.xunmap.window, Tmp_win->old_bw);
	  if((!(Tmp_win->flags & SUPPRESSICON))&&
	     (Tmp_win->wmhints && (Tmp_win->wmhints->flags & IconWindowHint)))
	    XUnmapWindow (dpy, Tmp_win->wmhints->icon_window);
	}
      else
	{
	  RestoreWithdrawnLocation (Tmp_win,False);
	}
      XRemoveFromSaveSet (dpy, Event.xunmap.window);
      XSelectInput (dpy, Event.xunmap.window, NoEventMask);
      Destroy(Tmp_win);		/* do not need to mash event before */
      /*
       * Flush any pending events for the window.
       */
      /* Bzzt! it could be about to re-map */
/*      while(XCheckWindowEvent(dpy, Event.xunmap.window,
			      StructureNotifyMask | PropertyChangeMask |
			      ColormapChangeMask | VisibilityChangeMask |
			      EnterWindowMask | LeaveWindowMask, &dummy));
      */
    } /* else window no longer exists and we'll get a destroy notify */
  MyXUngrabServer(dpy);

  XFlush (dpy);
}
Beispiel #11
0
/***********************************************************************
 *
 *  Procedure:
 *	HandleMapNotify - MapNotify event handler
 *
 ***********************************************************************/
void HandleMapNotify()
{
  Boolean       OnThisPage    =  False;

  DBUG("HandleMapNotify","Routine Entered");

  if (!Tmp_win)
    {
      if((Event.xmap.override_redirect == True)&&
	 (Event.xmap.window != Scr.NoFocusWin))
	{
	  XSelectInput(dpy,Event.xmap.window,FocusChangeMask);
	  Scr.UnknownWinFocused = Event.xmap.window;
	}
      return;
    }

  /* Except for identifying over-ride redirect window mappings, we
   * don't need or want windows associated with the sunstructurenotifymask */
  if(Event.xmap.event != Event.xmap.window)
    return;

  /*
      Make sure at least part of window is on this page
      before giving it focus...
  */
  if ( (Tmp_win->Desk == Scr.CurrentDesk) &&
       ( ((Tmp_win->frame_x + Tmp_win->frame_width) >= 0 &&
          Tmp_win->frame_x < Scr.MyDisplayWidth) &&
         ((Tmp_win->frame_y + Tmp_win->frame_height) >= 0 &&
          Tmp_win->frame_y < Scr.MyDisplayHeight)
       )
     )
    {
      OnThisPage  =  True;
    }

  /*
   * Need to do the grab to avoid race condition of having server send
   * MapNotify to client before the frame gets mapped; this is bad because
   * the client would think that the window has a chance of being viewable
   * when it really isn't.
   */
  MyXGrabServer (dpy);
  if (Tmp_win->icon_w)
    XUnmapWindow(dpy, Tmp_win->icon_w);
  if(Tmp_win->icon_pixmap_w != None)
    XUnmapWindow(dpy, Tmp_win->icon_pixmap_w);
  XMapSubwindows(dpy, Tmp_win->frame);

  if(Tmp_win->Desk == Scr.CurrentDesk)
    {
      XMapWindow(dpy, Tmp_win->frame);
    }

  if(Tmp_win->flags & ICONIFIED)
    BroadcastPacket(M_DEICONIFY, 3,
                    Tmp_win->w, Tmp_win->frame, (unsigned long)Tmp_win);
  else
    BroadcastPacket(M_MAP, 3,
                    Tmp_win->w,Tmp_win->frame, (unsigned long)Tmp_win);

  if((Tmp_win->flags & ClickToFocus)&&
     ((!Scr.Focus)||(Scr.Focus->flags & ClickToFocus)))
    {
      if (OnThisPage)
        {
          SetFocus(Tmp_win->w,Tmp_win,1);
        }
    }
  if((!(Tmp_win->flags &(BORDER|TITLE)))&&(Tmp_win->boundary_width <2))
    {
      SetBorder(Tmp_win,False,True,True,Tmp_win->frame);
    }
  XSync(dpy,0);
  MyXUngrabServer (dpy);
  XFlush (dpy);
  Tmp_win->flags |= MAPPED;
  Tmp_win->flags &= ~MAP_PENDING;
  Tmp_win->flags &= ~ICONIFIED;
  Tmp_win->flags &= ~ICON_UNMAPPED;
  KeepOnTop();
}
Beispiel #12
0
void HandleMapRequestKeepRaised(Window KeepRaised)
{
  extern long isIconicState;
  extern Boolean PPosOverride;
  Boolean       OnThisPage    =  False;

  Event.xany.window = Event.xmaprequest.window;

  if(XFindContext(dpy, Event.xany.window, FvwmContext,
		  (caddr_t *)&Tmp_win)==XCNOENT)
    Tmp_win = NULL;

  if(!PPosOverride)
    XFlush(dpy);

  /* If the window has never been mapped before ... */
  if(!Tmp_win)
    {
      /* Add decorations. */
      Tmp_win = AddWindow(Event.xany.window);
      if (Tmp_win == NULL)
	return;
    }
  /*
      Make sure at least part of window is on this page
      before giving it focus...
  */
  if ( (Tmp_win->Desk == Scr.CurrentDesk) &&
       ( ((Tmp_win->frame_x + Tmp_win->frame_width) >= 0 &&
          Tmp_win->frame_x < Scr.MyDisplayWidth) &&
         ((Tmp_win->frame_y + Tmp_win->frame_height) >= 0 &&
          Tmp_win->frame_y < Scr.MyDisplayHeight)
       )
     )
    {
      OnThisPage  =  True;
    }

  if(KeepRaised != None)
    XRaiseWindow(dpy,KeepRaised);
  /* If it's not merely iconified, and we have hints, use them. */
  if (!(Tmp_win->flags & ICONIFIED))
    {
      int state;

      if(Tmp_win->wmhints && (Tmp_win->wmhints->flags & StateHint))
	state = Tmp_win->wmhints->initial_state;
      else
	state = NormalState;

      if(Tmp_win->flags & STARTICONIC)
	state = IconicState;

      if(isIconicState != DontCareState)
	state = isIconicState;

      MyXGrabServer(dpy);
      switch (state)
	{
	case DontCareState:
	case NormalState:
	case InactiveState:
	default:
	  if (Tmp_win->Desk == Scr.CurrentDesk)
	    {
	      XMapWindow(dpy, Tmp_win->w);
	      XMapWindow(dpy, Tmp_win->frame);
	      Tmp_win->flags |= MAP_PENDING;
	      SetMapStateProp(Tmp_win, NormalState);
	      if((Tmp_win->flags & ClickToFocus)&&
		 ((!Scr.Focus)||(Scr.Focus->flags & ClickToFocus)))
		{
                  if (OnThisPage)
                    {
		      SetFocus(Tmp_win->w,Tmp_win,1);
                    }
		}
	    }
	  else
	    {
	      XMapWindow(dpy, Tmp_win->w);
	      SetMapStateProp(Tmp_win, NormalState);
	    }
	  break;

	case IconicState:
	  if (Tmp_win->wmhints)
	    {
	      Iconify(Tmp_win,
		      Tmp_win->wmhints->icon_x, Tmp_win->wmhints->icon_y);
	    }
	  else
	    {
	      Iconify(Tmp_win, 0, 0);
	    }
	  break;
	}
      if(!PPosOverride)
	XSync(dpy,0);
      MyXUngrabServer(dpy);
    }
  /* If no hints, or currently an icon, just "deiconify" */
  else
    {
      DeIconify(Tmp_win);
    }
  if(!PPosOverride)
    KeepOnTop();
}