/* Generates a region containing free space (here the
 * active window counts as free space). The region argument
 * is the start-region (ie: the output dev).
 */
static Region
smartputEmptyRegion (CompWindow *window,
		     Region     region)
{
    CompScreen *s = window->screen;
    CompWindow *w;
    Region     newRegion, tmpRegion;
    XRectangle tmpRect;

    newRegion = XCreateRegion ();
    if (!newRegion)
	return NULL;

    tmpRegion = XCreateRegion ();
    if (!tmpRegion)
    {
	XDestroyRegion (newRegion);
	return NULL;
    }

    XUnionRegion (region, newRegion, newRegion);

    for (w = s->windows; w; w = w->next)
    {
	EMPTY_REGION (tmpRegion);
        if (w->id == window->id)
            continue;

        if (w->invisible || w->hidden || w->minimized)
            continue;

	if (w->wmType & CompWindowTypeDesktopMask)
	    continue;

	if (w->wmType & CompWindowTypeDockMask)
	{
	    if (w->struts)
	    {
		XUnionRectWithRegion (&w->struts->left, tmpRegion, tmpRegion);
		XUnionRectWithRegion (&w->struts->right, tmpRegion, tmpRegion);
		XUnionRectWithRegion (&w->struts->top, tmpRegion, tmpRegion);
		XUnionRectWithRegion (&w->struts->bottom, tmpRegion, tmpRegion);
		XSubtractRegion (newRegion, tmpRegion, newRegion);
	    }
	    continue;
	}

	tmpRect.x = w->serverX - w->input.left;
	tmpRect.y = w->serverY - w->input.top;
	tmpRect.width  = w->serverWidth + w->input.right + w->input.left;
	tmpRect.height = w->serverHeight + w->input.top +
	                 w->input.bottom;
	XUnionRectWithRegion (&tmpRect, tmpRegion, tmpRegion);
	XSubtractRegion (newRegion, tmpRegion, newRegion);
    }

    XDestroyRegion (tmpRegion);

    return newRegion;
}
Beispiel #2
0
static void clonePreparePaintScreen(CompScreen * s, int msSinceLastPaint)
{
	int i;

	CLONE_SCREEN(s);

	if (cs->grab) {
		if (cs->grabIndex) {
			cs->offset -= msSinceLastPaint * 0.005f;
			if (cs->offset < 0.0f)
				cs->offset = 0.0f;
		} else {
			cs->offset += msSinceLastPaint * 0.005f;
			if (cs->offset >= 1.0f)
				cs->offset = 1.0f;
		}
	}

	UNWRAP(cs, s, preparePaintScreen);
	(*s->preparePaintScreen) (s, msSinceLastPaint);
	WRAP(cs, s, preparePaintScreen, clonePreparePaintScreen);

	for (i = 0; i < cs->nClone; i++) {
		CompOutput *src = &s->outputDev[cs->clone[i].src];
		CompOutput *dst = &s->outputDev[cs->clone[i].dst];
		int dx, dy;

		dx = dst->region.extents.x1 - src->region.extents.x1;
		dy = dst->region.extents.y1 - src->region.extents.y1;

		if (s->damageMask & COMP_SCREEN_DAMAGE_REGION_MASK) {
			if (src->width != dst->width
			    || src->height != dst->height) {
				XSubtractRegion(&dst->region, &emptyRegion,
						cs->clone[i].region);
				XUnionRegion(s->damage, cs->clone[i].region,
					     s->damage);
				XSubtractRegion(&src->region, &emptyRegion,
						cs->clone[i].region);
			} else {
				XSubtractRegion(s->damage, &dst->region,
						cs->clone[i].region);
				XOffsetRegion(cs->clone[i].region, dx, dy);
				XUnionRegion(s->damage, cs->clone[i].region,
					     s->damage);
				XSubtractRegion(s->damage, &src->region,
						cs->clone[i].region);
				XOffsetRegion(cs->clone[i].region, -dx, -dy);
			}
		} else {
			XSubtractRegion(&src->region, &emptyRegion,
					cs->clone[i].region);
		}
	}
}
Beispiel #3
0
static Region 
HighlightRegion(CommandWidget cbw)
{
    static Region outerRegion = NULL, innerRegion, emptyRegion;
    XRectangle rect;

    if (cbw->command.highlight_thickness == 0 ||
        cbw->command.highlight_thickness > Min(XtWidth(cbw), XtHeight(cbw)) / 2)
	return (NULL);

    if (outerRegion == NULL) {
	/* save time by allocating scratch regions only once. */
	outerRegion = XCreateRegion();
	innerRegion = XCreateRegion();
	emptyRegion = XCreateRegion();
    }

    rect.x = rect.y = 0;
    rect.width = XtWidth(cbw);
    rect.height = XtHeight(cbw);
    XUnionRectWithRegion(&rect, emptyRegion, outerRegion);
    rect.x = rect.y = cbw->command.highlight_thickness;
    rect.width -= cbw->command.highlight_thickness * 2;
    rect.height -= cbw->command.highlight_thickness * 2;
    XUnionRectWithRegion(&rect, emptyRegion, innerRegion);
    XSubtractRegion(outerRegion, innerRegion, outerRegion);

    return (outerRegion);
}
Beispiel #4
0
/* lpStruct - Destination Region */
DWORD
DrvRegionsDiffRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct)
{
	XSubtractRegion((Region)dwParm1, (Region)dwParm2, (Region)lpStruct);
	return (DWORD)(XEmptyRegion((Region)lpStruct)?
				NULLREGION:COMPLEXREGION);
}
Beispiel #5
0
CompRegion
CompRegion::subtracted (const CompRect &r) const
{
    CompRegion rv;
    rv.priv->makeReal ();
    XSubtractRegion (handle (), r.region (), rv.handle ());
    return rv;
}
Beispiel #6
0
void sClipExclude(const sRect &r)
{
  sVERIFY(ClipIndex != 0);
  Region temp = sRectToRegion(r);
  XSubtractRegion(ClipStack[ClipIndex],temp,ClipStack[ClipIndex]);
  XDestroyRegion(temp);
  sChangedRegions();
}
Beispiel #7
0
EAPI Eina_Bool
ecore_x_xregion_subtract(Ecore_X_XRegion *dst,
                         Ecore_X_XRegion *rm,
                         Ecore_X_XRegion *rs)
{
   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   return XSubtractRegion((Region)rm, (Region)rs, (Region)dst) ? EINA_TRUE : EINA_FALSE;
} /* ecore_x_xregion_subtract */
// Subtract region r from this one
FXRegion FXRegion::operator-(const FXRegion& r) const {
  FXRegion res;
#ifdef WIN32
  CombineRgn((HRGN)res.region,(HRGN)region,(HRGN)r.region,RGN_DIFF);
#else
  XSubtractRegion((Region)region,(Region)r.region,(Region)res.region);
#endif
  return res;
  }
Beispiel #9
0
static PyObject *
region_SubtractRegion(PaxRegionObject *self, PyObject *args)
{
    PaxRegionObject *r;
    if (!PyArg_ParseTuple(args, "O!", &PaxRegionType, &r))
	return NULL;
    XSubtractRegion(self->region, r->region, self->region);
    Py_INCREF(Py_None);
    return Py_None;
}
Beispiel #10
0
// Substract region r from this one
FXRegion& FXRegion::operator-=(const FXRegion& r){
#ifdef WIN32
  CombineRgn((HRGN)region,(HRGN)region,(HRGN)r.region,RGN_DIFF);
#else
  Region res=XCreateRegion();
  XSubtractRegion((Region)region,(Region)r.region,res);
  XDestroyRegion((Region)region);
  region=res;
#endif
  return *this;
  }
Beispiel #11
0
static void
update_wireframe_window (MetaDisplay         *display,
                         Window               xwindow,
                         const MetaRectangle *rect)
{
  XMoveResizeWindow (display->xdisplay,
                     xwindow,
                     rect->x, rect->y,
                     rect->width, rect->height);

#define OUTLINE_WIDTH 3

  if (rect->width > OUTLINE_WIDTH * 2 &&
      rect->height > OUTLINE_WIDTH * 2)
    {
      XRectangle xrect;
      Region inner_xregion;
      Region outer_xregion;

      inner_xregion = XCreateRegion ();
      outer_xregion = XCreateRegion ();

      xrect.x = 0;
      xrect.y = 0;
      xrect.width = rect->width;
      xrect.height = rect->height;

      XUnionRectWithRegion (&xrect, outer_xregion, outer_xregion);

      xrect.x += OUTLINE_WIDTH;
      xrect.y += OUTLINE_WIDTH;
      xrect.width -= OUTLINE_WIDTH * 2;
      xrect.height -= OUTLINE_WIDTH * 2;

      XUnionRectWithRegion (&xrect, inner_xregion, inner_xregion);

      XSubtractRegion (outer_xregion, inner_xregion, outer_xregion);

      XShapeCombineRegion (display->xdisplay, xwindow,
                           ShapeBounding, 0, 0, outer_xregion, ShapeSet);

      XDestroyRegion (outer_xregion);
      XDestroyRegion (inner_xregion);
    }
  else
    {
      /* Unset the shape */
      XShapeCombineMask (display->xdisplay, xwindow,
                         ShapeBounding, 0, 0, None, ShapeSet);
    }
}
Beispiel #12
0
Bool
apc_region_combine( Handle self, Handle other_region, int rgnop)
{
	PRegionSysData r2;
	int d;
	Bool ok = true;

	r2 = GET_REGION(other_region);

	if ( rgnop == rgnopCopy ) {
		if ( REGION ) XDestroyRegion( REGION );
		REGION = XCreateRegion();
		XUnionRegion( REGION, r2->region, REGION);
		HEIGHT = r2-> height;
		return true;
	}

	d = HEIGHT - r2-> height;
	if ( d > 0 )
		XOffsetRegion( r2-> region, 0, d);
	else
		XOffsetRegion( REGION, 0, -d);

	switch (rgnop) {
	case rgnopIntersect:
		XIntersectRegion( REGION, r2->region, REGION);
		break;
	case rgnopUnion:
		XUnionRegion( REGION, r2->region, REGION);
		break;
	case rgnopXor:
		XXorRegion( REGION, r2->region, REGION);
		break;
	case rgnopDiff:
		XSubtractRegion( REGION, r2->region, REGION);
		break;
	default:
		ok = false;
	}
	if ( d > 0 )
		XOffsetRegion( r2-> region, 0, -d);
	else
		HEIGHT = r2-> height;

	return ok;
}
Beispiel #13
0
bool wxRegion::DoSubtract( const wxRegion& region )
{
    wxCHECK_MSG( region.Ok(), false, wxT("invalid region") );

    if (!m_refData)
    {
        m_refData = new wxRegionRefData();
        M_REGIONDATA->m_region = XCreateRegion();
    }
    else
    {
        AllocExclusive();
    }

    XSubtractRegion( M_REGIONDATA->m_region,
                     M_REGIONDATA_OF(region)->m_region,
                     M_REGIONDATA->m_region );

    return true;
}
Beispiel #14
0
// Replace top of stack with top of stack minus this rectangle:
void Fl_Device::clip_out(int x, int y, int w, int h)
{
    if (w <= 0 || h <= 0) return;
    Region current = rstack[rstackptr];
    // current must not be zero, you must push a rectangle first.  I
    // return without doing anything because that makes some old fltk code work:
    if (!current) return;
    fl_transform(x,y);
    Region r = XRectangleRegion(x, y, w, h);
#ifndef _WIN32
    Region temp = XCreateRegion();
    XSubtractRegion(current, r, temp);
    XDestroyRegion(r);
    XDestroyRegion(current);
    rstack[rstackptr] = temp;
#else
    CombineRgn(current,current,r,RGN_DIFF);
    DeleteObject(r);
#endif
    fl_restore_clip();
}
Beispiel #15
0
/*
 * Kreslení
 */
static void expose(XExposeEvent *event)
{
    Region region, region1, region2;
    XRectangle rect;
    
    if(event->count > 0)
	return; /* Kreslit jen po poslední události v øadì */
  
    XDrawArc(display, topwin, my_gc, 20, 20, topwin_w - 40, topwin_h - 40,
	     0, 360 * 64);
    
    region = XCreateRegion();
    region1 = XCreateRegion();
    region2 = XCreateRegion();
    rect.x = rect.y = 0;
    rect.width = 100;
    rect.height = topwin_w - 60;
    XUnionRectWithRegion(&rect, region, region1);
    rect.width = 20;
    rect.height = 10;
    XUnionRectWithRegion(&rect, region2, region);
    XOffsetRegion(region, 50, 100);
    XSubtractRegion(region1, region, region2);
    XDestroyRegion(region);
    region = XCreateRegion();
    rect.width = 100;
    rect.height = 30;
    XUnionRectWithRegion(&rect, region, region1);
    XOffsetRegion(region1, (int)topwin_w - 120, -30 + ((int)topwin_h - 40) / 2);
    XUnionRegion(region1, region2, region);
    XSetRegion(display, my_gc, region);
    XDestroyRegion(region);
    XDestroyRegion(region1);
    XDestroyRegion(region2);
    XSetClipOrigin(display, my_gc, 20, 20);
    XFillArc(display, topwin, my_gc, 20, 20, topwin_w - 40, topwin_h - 40,
	     0, 360 * 64);
    XSetClipMask(display, my_gc, None); /* Zru¹it oøezávání */
}
Beispiel #16
0
void X11Graphics::clear( int xDest, int yDest, int width, int height )
{
    if( width <= 0 || height <= 0 )
    {
        // Clear the transparency mask completely
        XDestroyRegion( m_mask );
        m_mask = XCreateRegion();
    }
    else
    {
        // remove this area from the mask
        XRectangle rect;
        rect.x = xDest;
        rect.y = yDest;
        rect.width = width;
        rect.height = height;
        Region regMask = XCreateRegion();
        XUnionRectWithRegion( &rect, regMask, regMask );
        XSubtractRegion( m_mask, regMask, m_mask );
        XDestroyRegion( regMask );
    }
}
Beispiel #17
0
bool wxRegion::Subtract( const wxRegion& region )
{
#if 0
    if (region.IsNull())
        return FALSE;

    if (!m_refData)
    {
        m_refData = new wxRegionRefData();
        M_REGIONDATA->m_region = XCreateRegion();
    }
    else
    {
        AllocExclusive();
    }

    XSubtractRegion( M_REGIONDATA->m_region,
                     M_REGIONDATA_OF(region)->m_region,
                     M_REGIONDATA->m_region );
#endif
    return TRUE;
}
/*
 * Detect visible windows edges
 */
static void snapUpdateWindowsEdges(CompWindow * w)
{
	CompWindow *c = NULL;
	Edge *e = NULL, *next = NULL;

	SNAP_WINDOW(w);
	Region edgeRegion, resultRegion;
	XRectangle rect;
	Bool remove = FALSE;

	// First add all the windows
	c = w->screen->windows;
	while (c)
	{
		// Just check that we're not trying to snap to current window,
		// that the window is not invisible and of a valid type
		if (c == w || !isSnapWindow(c))
		{
			c = c->next;
			continue;
		}
		snapAddEdge(&sw->edges, &sw->reverseEdges, c->id,
					WIN_Y(c), WIN_X(c), WIN_X(c) + WIN_W(c), TopEdge, FALSE);
		snapAddEdge(&sw->edges, &sw->reverseEdges, c->id,
					WIN_Y(c) + WIN_H(c), WIN_X(c), WIN_X(c) + WIN_W(c),
					BottomEdge, FALSE);
		snapAddEdge(&sw->edges, &sw->reverseEdges, c->id,
					WIN_X(c), WIN_Y(c), WIN_Y(c) + WIN_H(c), LeftEdge, FALSE);
		snapAddEdge(&sw->edges, &sw->reverseEdges, c->id,
					WIN_X(c) + WIN_W(c), WIN_Y(c), WIN_Y(c) + WIN_H(c),
					RightEdge, FALSE);
		c = c->next;
	}

	// Now strip invisible edges
	// Loop through all the windows stack, and through all the edges
	// If an edge has been passed, check if it's in the region window,
	// if the edge is fully under the window, drop it, or if it's only
	// partly covered, cut it/split it in one/two smaller visible edges
	for (c = w->screen->windows; c; c = c->next)
	{
		if (c == w || !isSnapWindow(c))
			continue;
		for (e = sw->edges; e; e = next)
		{
			if (!e->passed)
			{
				if (e->id == c->id)
					e->passed = TRUE;
				next = e->next;
				continue;
			}
			switch (e->type)
			{
				case LeftEdge:
				case RightEdge:
					rect.x = e->position;
					rect.y = e->start;
					rect.width = 1;
					rect.height = e->end - e->start;
					break;
				case TopEdge:
				case BottomEdge:
				default:
					rect.x = e->start;
					rect.y = e->position;
					rect.width = e->end - e->start;
					rect.height = 1;
			}
			// If the edge is in the window region, remove it,
			// if it's partly in the region, split it
			edgeRegion = XCreateRegion();
			resultRegion = XCreateRegion();
			XUnionRectWithRegion(&rect, edgeRegion, edgeRegion);
			XSubtractRegion(edgeRegion, c->region, resultRegion);
			if (XEmptyRegion(resultRegion))
				remove = TRUE;
			else if (!XEqualRegion(edgeRegion, resultRegion))
			{
				snapAddRegionEdges(sw, e, resultRegion);
				remove = TRUE;
			}
			next = e->next;
			if (remove)
			{
				if (e->prev == NULL)
					sw->edges = e->next;
				if (e->next == NULL)
					sw->reverseEdges = e->prev;
				snapRemoveEdge(e);
				remove = FALSE;
			}
			XDestroyRegion(resultRegion);
			XDestroyRegion(edgeRegion);
		}
	}
}
/* This function currently always performs occlusion detection to
   minimize paint regions. OpenGL precision requirements are no good
   enough to guarantee that the results from using occlusion detection
   is the same as without. It's likely not possible to see any
   difference with most hardware but occlusion detection in the
   transformed screen case should be made optional for those who do
   see a difference. */
static void
paintOutputRegion (CompScreen	       *screen,
		   const CompTransform *transform,
		   Region	       region,
		   CompOutput	       *output,
		   unsigned int	       mask)
{
    static Region tmpRegion = NULL;
    CompWindow    *w;
    CompCursor	  *c;
    int		  count, windowMask, odMask, i;
    CompWindow	  *fullscreenWindow = NULL;
    CompWalker    walk;
    Bool          status;
    Bool          withOffset = FALSE;
    CompTransform vTransform;
    int           offX, offY;
    Region        clip = region;
    int           dontcare;

    if (!tmpRegion)
    {
	tmpRegion = XCreateRegion ();
	if (!tmpRegion)
	    return;
    }

    if (mask & PAINT_SCREEN_TRANSFORMED_MASK)
    {
	windowMask     = PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;
	count	       = 1;
    }
    else
    {
	windowMask     = 0;
	count	       = 0;
    }

    XSubtractRegion (region, &emptyRegion, tmpRegion);

    (*screen->initWindowWalker) (screen, &walk);

    if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))
    {
	/* detect occlusions */
	for (w = (*walk.last) (screen); w; w = (*walk.prev) (w))
	{
	    if (w->destroyed)
		continue;

	    if (!w->shaded)
	    {
		if (w->attrib.map_state != IsViewable || !w->damaged)
		    continue;
	    }

	    /* copy region */
	    XSubtractRegion (tmpRegion, &emptyRegion, w->clip);

	    odMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK;
		
	    if ((screen->windowOffsetX != 0 || screen->windowOffsetY != 0) &&
		!windowOnAllViewports (w))
	    {
		withOffset = TRUE;

		getWindowMovementForOffset (w, screen->windowOffsetX,
					    screen->windowOffsetY,
					    &offX, &offY);

		vTransform = *transform;
		matrixTranslate (&vTransform, offX, offY, 0);

		XOffsetRegion (w->clip, -offX, -offY);

		odMask |= PAINT_WINDOW_WITH_OFFSET_MASK;
		status = (*screen->paintWindow) (w, &w->paint, &vTransform,
						 tmpRegion, odMask);
	    }
	    else
	    {
		withOffset = FALSE;
		status = (*screen->paintWindow) (w, &w->paint, transform, tmpRegion,
						 odMask);
	    }

	    if (status)
	    {
		if (withOffset)
		{
		    XOffsetRegion (w->region, offX, offY);
		    XSubtractRegion (tmpRegion, w->region, tmpRegion);
		    XOffsetRegion (w->region, -offX, -offY);
		}
		else
		    XSubtractRegion (tmpRegion, w->region, tmpRegion);

		/* unredirect top most fullscreen windows. */
		/* if the fullscreen window is mate-screensaver and we're
		   on nvidia we want to always unredirect even if this
		   option is disabled to work around LP #160264 */
		if (count == 0 &&
		    (screen->opt[COMP_SCREEN_OPTION_UNREDIRECT_FS].value.b ||
		    (w->resName && !strcmp(w->resName, "mate-screensaver") &&
		    XQueryExtension (screen->display->display, "NV-GLX",
				     &dontcare, &dontcare, &dontcare))))
		{
		    if (XEqualRegion (w->region, &screen->region) &&
			!REGION_NOT_EMPTY (tmpRegion))
		    {
			fullscreenWindow = w;
		    }
		    else
		    {
			for (i = 0; i < screen->nOutputDev; i++)
			    if (XEqualRegion (w->region,
					      &screen->outputDev[i].region))
				fullscreenWindow = w;
		    }
		}
	    }

	    if (!w->invisible)
		count++;
	}
    }

    if (fullscreenWindow)
	unredirectWindow (fullscreenWindow);

    if (!(mask & PAINT_SCREEN_NO_BACKGROUND_MASK))
	paintBackground (screen, tmpRegion,
			 (mask & PAINT_SCREEN_TRANSFORMED_MASK));

    /* paint all windows from bottom to top */
    for (w = (*walk.first) (screen); w; w = (*walk.next) (w))
    {
	if (w->destroyed)
	    continue;

	if (w == fullscreenWindow)
	    continue;

	if (!w->shaded)
	{
	    if (w->attrib.map_state != IsViewable || !w->damaged)
		continue;
	}

	if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))
	    clip = w->clip;

	if ((screen->windowOffsetX != 0 || screen->windowOffsetY != 0) &&
	    !windowOnAllViewports (w))
	{
	    getWindowMovementForOffset (w, screen->windowOffsetX,
					screen->windowOffsetY, &offX, &offY);

	    vTransform = *transform;
	    matrixTranslate (&vTransform, offX, offY, 0);
	    (*screen->paintWindow) (w, &w->paint, &vTransform, clip,
				    windowMask | PAINT_WINDOW_WITH_OFFSET_MASK);
	}
	else
	{
	    (*screen->paintWindow) (w, &w->paint, transform, clip,
				    windowMask);
	}
    }

    if (walk.fini)
	(*walk.fini) (screen, &walk);

    /* paint cursors */
    for (c = screen->cursors; c; c = c->next)
	(*screen->paintCursor) (c, transform, tmpRegion, 0);
}
Beispiel #20
0
static Bool
minDamageWindowRect (CompWindow *w,
                     Bool       initial,
                     BoxPtr     rect)
{
	Bool status = FALSE;

	MIN_SCREEN (w->screen);
	MIN_WINDOW (w);

	if (mw->ignoreDamage)
		return TRUE;

	if (initial)
	{
		if (mw->state == IconicState)
		{
			mw->state = NormalState;

			if (!w->invisible      &&
			    w->iconGeometrySet &&
			    matchEval (&ms->match, w))
			{
				if (!mw->adjust)
				{
					mw->adjust     = TRUE;
					ms->moreAdjust = TRUE;

					mw->tx     = w->iconGeometry.x - w->serverX;
					mw->ty     = w->iconGeometry.y - w->serverY;
					mw->xScale = (float) w->iconGeometry.width  / w->width;
					mw->yScale = (float) w->iconGeometry.height / w->height;

					addWindowDamage (w);
				}
			}
		}
		else if (mw->region && mw->shade < w->height)
		{
			if (ms->shadeStep && !w->invisible)
			{
				XSubtractRegion (w->region, &emptyRegion, mw->region);
				XOffsetRegion (mw->region, -w->attrib.x, -w->attrib.y);

				/* bind pixmap here so we have something to unshade with */
				if (!w->texture->pixmap && !w->bindFailed)
					bindWindow (w);

				ms->moreAdjust = TRUE;
			}
			else
			{
				mw->shade = MAXSHORT;
			}
		}

		mw->newState = NormalState;
	}
	else if (mw->adjust)
	{
		damageTransformedWindowRect (w,
		                         mw->xScale,
		                         mw->yScale,
		                         mw->tx,
		                         mw->ty,
		                         rect);

		status = TRUE;
	}

	UNWRAP (ms, w->screen, damageWindowRect);
	status |= (*w->screen->damageWindowRect) (w, initial, rect);
	WRAP (ms, w->screen, damageWindowRect, minDamageWindowRect);

	return status;
}
Beispiel #21
0
static void
minHandleEvent (XEvent      *event)
{
	CompWindow *w;

	MIN_DISPLAY (&display);

	switch (event->type) {
	case MapNotify:
		w = findWindowAtDisplay (event->xmap.window);
		if (w)
		{
			MIN_WINDOW (w);

			if (mw->adjust)
				mw->state = mw->newState;

			if (mw->region)
				w->height = 0;

			mw->ignoreDamage = TRUE;
			while (mw->unmapCnt)
			{
				unmapWindow (w);
				mw->unmapCnt--;
			}
			mw->ignoreDamage = FALSE;
		}
		break;
	case UnmapNotify:
		w = findWindowAtDisplay (event->xunmap.window);
		if (w)
		{
			MIN_SCREEN (w->screen);

			if (w->pendingUnmaps && onCurrentDesktop (w)) /* Normal -> Iconic */
			{
				MIN_WINDOW (w);

				if (w->shaded)
				{
					if (!mw->region)
						mw->region = XCreateRegion ();

					if (mw->region && ms->shadeStep)
					{
						XSubtractRegion (w->region, &emptyRegion, mw->region);
						XOffsetRegion (mw->region, -w->attrib.x,
						           w->attrib.height +
						           w->attrib.border_width * 2 -
						           w->height - w->attrib.y);

						mw->shade = w->height;

						mw->adjust     = FALSE;
						ms->moreAdjust = TRUE;

						mw->unmapCnt++;
						w->unmapRefCnt++;

						addWindowDamage (w);
					}
				}
				else if (!w->invisible && matchEval (&ms->match, w))
				{
					if (w->iconGeometrySet)
					{
						mw->newState = IconicState;

						mw->xScale = w->paint.xScale;
						mw->yScale = w->paint.yScale;
						mw->tx     = w->attrib.x - w->serverX;
						mw->ty     = w->attrib.y - w->serverY;

						if (mw->region)
						{
							XDestroyRegion (mw->region);
							mw->region = NULL;
						}

						mw->shade = MAXSHORT;

						mw->adjust     = TRUE;
						ms->moreAdjust = TRUE;

						mw->unmapCnt++;
						w->unmapRefCnt++;

						addWindowDamage (w);
					}
				}
			}
			else  /* X -> Withdrawn */
			{
				MIN_WINDOW (w);

				if (mw->adjust)
				{
					mw->adjust = FALSE;
					mw->xScale = mw->yScale = 1.0f;
					mw->tx = mw->ty = 0.0f;
					mw->xVelocity = mw->yVelocity = 0.0f;
					mw->xScaleVelocity = mw->yScaleVelocity = 1.0f;
					mw->shade = MAXSHORT;

					if (mw->region)
					{
						XDestroyRegion (mw->region);
						mw->region = NULL;
					}
				}

				mw->state = NormalState;
			}
		}
	default:
		break;
	}

	UNWRAP (md, &display, handleEvent);
	(*display.handleEvent) (event);
	WRAP (md, &display, handleEvent, minHandleEvent);

	switch (event->type) {
	case MapRequest:
		w = findWindowAtDisplay (event->xmaprequest.window);
		if (w && w->hints && w->hints->initial_state == IconicState)
		{
			MIN_WINDOW (w);
			mw->newState = mw->state = IconicState;
		}
		break;
	default:
		break;
	}
}
Beispiel #22
0
static void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h)
{
	XTransform transform;
	Picture windowPicture;
	Picture primaryPicture;
	XRenderPictureAttributes pa;
	XRenderPictFormat* picFormat;
	double xScalingFactor;
	double yScalingFactor;
	int x2;
	int y2;

	if (xfc->scaledWidth <= 0 || xfc->scaledHeight <= 0)
	{
		WLog_ERR(TAG, "the current window dimensions are invalid");
		return;
	}

	if (xfc->sessionWidth <= 0 || xfc->sessionHeight <= 0)
	{
		WLog_ERR(TAG, "the window dimensions are invalid");
		return;
	}

	xScalingFactor = xfc->sessionWidth / (double)xfc->scaledWidth;
	yScalingFactor = xfc->sessionHeight / (double)xfc->scaledHeight;

	XSetFillStyle(xfc->display, xfc->gc, FillSolid);
	XSetForeground(xfc->display, xfc->gc, 0);

	/* Black out possible space between desktop and window borders */
	{
		XRectangle box1 = { 0, 0, xfc->window->width, xfc->window->height };
		XRectangle box2 = { xfc->offset_x, xfc->offset_y, xfc->scaledWidth, xfc->scaledHeight };
		Region reg1 = XCreateRegion();
		Region reg2 = XCreateRegion();
		XUnionRectWithRegion(&box1, reg1, reg1);
		XUnionRectWithRegion(&box2, reg2, reg2);

		if (XSubtractRegion(reg1, reg2, reg1) && !XEmptyRegion(reg1))
		{
			XSetRegion(xfc->display, xfc->gc, reg1);
			XFillRectangle(xfc->display, xfc->window->handle, xfc->gc, 0, 0, xfc->window->width, xfc->window->height);
			XSetClipMask(xfc->display, xfc->gc, None);
		}

		XDestroyRegion(reg1);
		XDestroyRegion(reg2);
	}

	picFormat = XRenderFindVisualFormat(xfc->display, xfc->visual);

	pa.subwindow_mode = IncludeInferiors;
	primaryPicture = XRenderCreatePicture(xfc->display, xfc->primary, picFormat, CPSubwindowMode, &pa);
	windowPicture = XRenderCreatePicture(xfc->display, xfc->window->handle, picFormat, CPSubwindowMode, &pa);

	XRenderSetPictureFilter(xfc->display, primaryPicture, FilterBilinear, 0, 0);

	transform.matrix[0][0] = XDoubleToFixed(xScalingFactor);
	transform.matrix[0][1] = XDoubleToFixed(0.0);
	transform.matrix[0][2] = XDoubleToFixed(0.0);
	transform.matrix[1][0] = XDoubleToFixed(0.0);
	transform.matrix[1][1] = XDoubleToFixed(yScalingFactor);
	transform.matrix[1][2] = XDoubleToFixed(0.0);
	transform.matrix[2][0] = XDoubleToFixed(0.0);
	transform.matrix[2][1] = XDoubleToFixed(0.0);
	transform.matrix[2][2] = XDoubleToFixed(1.0);

	/* calculate and fix up scaled coordinates */
	x2 = x + w;
	y2 = y + h;
	x = floor(x / xScalingFactor) - 1;
	y = floor(y / yScalingFactor) - 1;
	w = ceil(x2 / xScalingFactor) + 1 - x;
	h = ceil(y2 / yScalingFactor) + 1 - y;

	XRenderSetPictureTransform(xfc->display, primaryPicture, &transform);
	XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, x, y, 0, 0, xfc->offset_x + x, xfc->offset_y + y, w, h);
	XRenderFreePicture(xfc->display, primaryPicture);
	XRenderFreePicture(xfc->display, windowPicture);
}
Beispiel #23
0
static Region
meta_get_bottom_border_region (const MetaFrameGeometry *fgeom,
			       int		        width)
{
    Region     corners_xregion, border_xregion;
    XRectangle xrect;
    int	       top_left_radius;
    int	       top_right_radius;
    int	       bottom_left_radius;
    int	       bottom_right_radius;
    int	       w, i;

    corners_xregion = XCreateRegion ();

    meta_get_corner_radius (fgeom,
			    &top_left_radius,
			    &top_right_radius,
			    &bottom_left_radius,
			    &bottom_right_radius);

    if (bottom_left_radius)
    {
	for (i = 0; i < bottom_left_radius; ++i)
	{
	    w = radius_to_width (bottom_left_radius, i);

	    xrect.x	 = 0;
	    xrect.y	 = fgeom->bottom_height - i - 1;
	    xrect.width  = w;
	    xrect.height = 1;

	    XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
	}
    }

    if (bottom_right_radius)
    {
	for (i = 0; i < bottom_right_radius; ++i)
	{
	    w = radius_to_width (bottom_right_radius, i);

	    xrect.x	 = width - w;
	    xrect.y	 = fgeom->bottom_height - i - 1;
	    xrect.width  = w;
	    xrect.height = 1;

	    XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion);
	}
    }

    border_xregion = XCreateRegion ();

    xrect.x = 0;
    xrect.y = 0;
    xrect.width = width;
    xrect.height = fgeom->bottom_height;

    XUnionRectWithRegion (&xrect, border_xregion, border_xregion);

    XSubtractRegion (border_xregion, corners_xregion, border_xregion);

    XDestroyRegion (corners_xregion);

    return border_xregion;
}
Beispiel #24
0
/*
 * groupHandleButtonReleaseEvent
 *
 */
static void
groupHandleButtonReleaseEvent (CompScreen *s,
                               XEvent     *event)
{
	GroupSelection *group;
	int vx, vy;
	Region newRegion;
	Bool inserted = FALSE;
	Bool wasInTabBar = FALSE;

	GROUP_SCREEN (s);

	if (event->xbutton.button != 1)
		return;

	if (!gs->draggedSlot)
		return;

	if (!gs->dragged)
	{
		groupChangeTab (gs->draggedSlot, RotateUncertain);
		gs->draggedSlot = NULL;

		if (gs->grabState == ScreenGrabTabDrag)
			groupGrabScreen (s, ScreenGrabNone);

		return;
	}

	GROUP_WINDOW (gs->draggedSlot->window);

	newRegion = XCreateRegion ();
	if (!newRegion)
		return;

	XUnionRegion (newRegion, gs->draggedSlot->region, newRegion);

	groupGetDrawOffsetForSlot (gs->draggedSlot, &vx, &vy);
	XOffsetRegion (newRegion, vx, vy);

	for (group = gs->groups; group; group = group->next)
	{
		Bool inTabBar;
		Region clip, buf;
		GroupTabBarSlot *slot;

		if (!group->tabBar || !HAS_TOP_WIN (group))
			continue;

		/* create clipping region */
		clip = groupGetClippingRegion (TOP_TAB (group));
		if (!clip)
			continue;

		buf = XCreateRegion ();
		if (!buf)
		{
			XDestroyRegion (clip);
			continue;
		}

		XIntersectRegion (newRegion, group->tabBar->region, buf);
		XSubtractRegion (buf, clip, buf);
		XDestroyRegion (clip);

		inTabBar = !XEmptyRegion (buf);
		XDestroyRegion (buf);

		if (!inTabBar)
			continue;

		wasInTabBar = TRUE;

		for (slot = group->tabBar->slots; slot; slot = slot->next)
		{
			GroupTabBarSlot *tmpDraggedSlot;
			GroupSelection  *tmpGroup;
			Region slotRegion, buf;
			XRectangle rect;
			Bool inSlot;

			if (slot == gs->draggedSlot)
				continue;

			slotRegion = XCreateRegion ();
			if (!slotRegion)
				continue;

			if (slot->prev && slot->prev != gs->draggedSlot)
			{
				rect.x = slot->prev->region->extents.x2;
			}
			else if (slot->prev && slot->prev == gs->draggedSlot &&
			         gs->draggedSlot->prev)
			{
				rect.x = gs->draggedSlot->prev->region->extents.x2;
			}
			else
				rect.x = group->tabBar->region->extents.x1;

			rect.y = slot->region->extents.y1;

			if (slot->next && slot->next != gs->draggedSlot)
			{
				rect.width = slot->next->region->extents.x1 - rect.x;
			}
			else if (slot->next && slot->next == gs->draggedSlot &&
			         gs->draggedSlot->next)
			{
				rect.width = gs->draggedSlot->next->region->extents.x1 - rect.x;
			}
			else
				rect.width = group->tabBar->region->extents.x2;

			rect.height = slot->region->extents.y2 - slot->region->extents.y1;

			XUnionRectWithRegion (&rect, slotRegion, slotRegion);

			buf = XCreateRegion ();
			if (!buf)
				continue;

			XIntersectRegion (newRegion, slotRegion, buf);
			inSlot = !XEmptyRegion (buf);

			XDestroyRegion (buf);
			XDestroyRegion (slotRegion);

			if (!inSlot)
				continue;

			tmpDraggedSlot = gs->draggedSlot;

			if (group != gw->group)
			{
				CompWindow     *w = gs->draggedSlot->window;
				GroupSelection *tmpGroup = gw->group;
				int oldPosX = WIN_CENTER_X (w);
				int oldPosY = WIN_CENTER_Y (w);

				/* if the dragged window is not the top tab,
				   move it onscreen */
				if (tmpGroup->topTab && !IS_TOP_TAB (w, tmpGroup))
				{
					CompWindow *tw = TOP_TAB (tmpGroup);

					oldPosX = WIN_CENTER_X (tw) + gw->mainTabOffset.x;
					oldPosY = WIN_CENTER_Y (tw) + gw->mainTabOffset.y;

					groupSetWindowVisibility (w, TRUE);
				}

				/* Change the group. */
				groupDeleteGroupWindow (gs->draggedSlot->window);
				groupAddWindowToGroup (gs->draggedSlot->window, group, 0);

				/* we saved the original center position in oldPosX/Y before -
				   now we should apply that to the new main tab offset */
				if (HAS_TOP_WIN (group))
				{
					CompWindow *tw = TOP_TAB (group);
					gw->mainTabOffset.x = oldPosX - WIN_CENTER_X (tw);
					gw->mainTabOffset.y = oldPosY - WIN_CENTER_Y (tw);
				}
			}
			else
				groupUnhookTabBarSlot (group->tabBar, gs->draggedSlot, TRUE);

			gs->draggedSlot = NULL;
			gs->dragged = FALSE;
			inserted = TRUE;

			if ((tmpDraggedSlot->region->extents.x1 +
			     tmpDraggedSlot->region->extents.x2 + (2 * vx)) / 2 >
			    (slot->region->extents.x1 + slot->region->extents.x2) / 2)
			{
				groupInsertTabBarSlotAfter (group->tabBar,
				                            tmpDraggedSlot, slot);
			}
			else
				groupInsertTabBarSlotBefore (group->tabBar,
				                             tmpDraggedSlot, slot);

			groupDamageTabBarRegion (group);

			/* Hide tab-bars. */
			for (tmpGroup = gs->groups; tmpGroup; tmpGroup = tmpGroup->next)
			{
				if (group == tmpGroup)
					groupTabSetVisibility (tmpGroup, TRUE, 0);
				else
					groupTabSetVisibility (tmpGroup, FALSE, PERMANENT);
			}

			break;
		}

		if (inserted)
			break;
	}

	XDestroyRegion (newRegion);

	if (!inserted)
	{
		CompWindow     *draggedSlotWindow = gs->draggedSlot->window;
		GroupSelection *tmpGroup;

		for (tmpGroup = gs->groups; tmpGroup; tmpGroup = tmpGroup->next)
			groupTabSetVisibility (tmpGroup, FALSE, PERMANENT);

		gs->draggedSlot = NULL;
		gs->dragged = FALSE;

		const BananaValue *
		option_dnd_ungroup_window = bananaGetOption (bananaIndex,
		                                             "dnd_ungroup_window",
		                                             s->screenNum);

		if (option_dnd_ungroup_window->b && !wasInTabBar)
		{
			groupRemoveWindowFromGroup (draggedSlotWindow);
		}
		else if (gw->group && gw->group->topTab)
		{
			groupRecalcTabBarPos (gw->group,
			                      (gw->group->tabBar->region->extents.x1 +
			                       gw->group->tabBar->region->extents.x2) / 2,
			                      gw->group->tabBar->region->extents.x1,
			                      gw->group->tabBar->region->extents.x2);
		}

		/* to remove the painted slot */
		damageScreen (s);
	}

	if (gs->grabState == ScreenGrabTabDrag)
		groupGrabScreen (s, ScreenGrabNone);

	if (gs->dragHoverTimeoutHandle)
	{
		compRemoveTimeout (gs->dragHoverTimeoutHandle);
		gs->dragHoverTimeoutHandle = 0;
	}
}
/*
 * Loop on outputDevs and add the extents as edges
 * Note that left side is a right edge, right side a left edge,
 * top side a bottom edge and bottom side a top edge,
 * since they will be snapped as the right/left/bottom/top edge of a window
 */
static void snapUpdateScreenEdges(CompWindow * w)
{
	CompWindow *c = NULL;
	Edge *e = NULL, *next = NULL;

	SNAP_WINDOW(w);
	Region edgeRegion, resultRegion;
	XRectangle rect;
	Bool remove = FALSE;

	XRectangle area;
	int i;

	for (i = 0; i < w->screen->nOutputDev; i++)
	{
		snapScreenGetOutputDevRect(w->screen, i, &area);
		snapAddEdge(&sw->edges, &sw->reverseEdges, 0,
					area.y, area.x, area.x + area.width - 1, BottomEdge, TRUE);
		snapAddEdge(&sw->edges, &sw->reverseEdges, 0,
					area.y + area.height, area.x,
					area.x + area.width - 1, TopEdge, TRUE);
		snapAddEdge(&sw->edges, &sw->reverseEdges, 0,
					area.x, area.y, area.y + area.height - 1, RightEdge, TRUE);
		snapAddEdge(&sw->edges, &sw->reverseEdges, 0,
					area.x + area.width, area.y,
					area.y + area.height - 1, LeftEdge, TRUE);
	}

	// Drop screen edges parts that are under struts, basically apply the
	// same strategy than for windows edges visibility
	for (c = w->screen->windows; c; c = c->next)
	{
		if (c == w || !c->struts)
			continue;
		for (e = sw->edges; e; e = next)
		{
			if (!e->screenEdge)
			{
				next = e->next;
				continue;
			}
			switch (e->type)
			{
				case LeftEdge:
				case RightEdge:
					rect.x = e->position;
					rect.y = e->start;
					rect.width = 1;
					rect.height = e->end - e->start;
					break;
				case TopEdge:
				case BottomEdge:
				default:
					rect.x = e->start;
					rect.y = e->position;
					rect.width = e->end - e->start;
					rect.height = 1;
			}
			edgeRegion = XCreateRegion();
			resultRegion = XCreateRegion();
			XUnionRectWithRegion(&rect, edgeRegion, edgeRegion);
			XSubtractRegion(edgeRegion, c->region, resultRegion);
			if (XEmptyRegion(resultRegion))
				remove = TRUE;
			else if (!XEqualRegion(edgeRegion, resultRegion))
			{
				snapAddRegionEdges(sw, e, resultRegion);
				remove = TRUE;
			}
			next = e->next;
			if (remove)
			{
				if (e->prev == NULL)
					sw->edges = e->next;
				if (e->next == NULL)
					sw->reverseEdges = e->prev;
				snapRemoveEdge(e);
				remove = FALSE;
			}
			XDestroyRegion(resultRegion);
			XDestroyRegion(edgeRegion);
		}
	}
}
Beispiel #26
0
static void
wireframeDrawXlib (WireFrame *wireframe, int width, int height)
{
    ScreenInfo *screen_info = wireframe->screen_info;

    wireframe->mapped = FALSE;
    XUnmapWindow (myScreenGetXDisplay (screen_info), wireframe->xwindow);
    XMoveResizeWindow (myScreenGetXDisplay (screen_info), wireframe->xwindow,
                       wireframe->x, wireframe->y, width, height);

    wireframe->width = width;
    wireframe->height = height;

    if ((wireframe->width > OUTLINE_WIDTH * 2) && (wireframe->height > OUTLINE_WIDTH * 2))
    {
        XRectangle xrect;
        Region inner_xregion;
        Region outer_xregion;

        inner_xregion = XCreateRegion ();
        outer_xregion = XCreateRegion ();

        xrect.x = 0;
        xrect.y = 0;
        xrect.width = wireframe->width;
        xrect.height = wireframe->height;
        XUnionRectWithRegion (&xrect, outer_xregion, outer_xregion);

        xrect.x += OUTLINE_WIDTH;
        xrect.y += OUTLINE_WIDTH;
        xrect.width -= OUTLINE_WIDTH * 2;
        xrect.height -= OUTLINE_WIDTH * 2;

        XUnionRectWithRegion (&xrect, inner_xregion, inner_xregion);

        XSubtractRegion (outer_xregion, inner_xregion, outer_xregion);

        XShapeCombineRegion (myScreenGetXDisplay (screen_info), wireframe->xwindow, ShapeBounding,
                             0, 0, outer_xregion, ShapeSet);

        XDestroyRegion (outer_xregion);
        XDestroyRegion (inner_xregion);
        XMapWindow (myScreenGetXDisplay (screen_info), wireframe->xwindow);
        wireframe->mapped = TRUE;

        XDrawRectangle (myScreenGetXDisplay (screen_info), wireframe->xwindow,
                        screen_info->box_gc,
                        0, 0, wireframe->width - 1, wireframe->height - 1);

        XDrawRectangle (myScreenGetXDisplay (screen_info), wireframe->xwindow,
                        screen_info->box_gc,
                        OUTLINE_WIDTH - 1, OUTLINE_WIDTH - 1,
                        wireframe->width - 2 * (OUTLINE_WIDTH - 1) - 1,
                        wireframe->height- 2 * (OUTLINE_WIDTH - 1) - 1);
    }
    else
    {
        /* Unset the shape */
        XShapeCombineMask (myScreenGetXDisplay (screen_info), wireframe->xwindow,
                           ShapeBounding, 0, 0, None, ShapeSet);
        XMapWindow (myScreenGetXDisplay (screen_info), wireframe->xwindow);
        wireframe->mapped = TRUE;

        XDrawRectangle (myScreenGetXDisplay (screen_info), wireframe->xwindow,
                        screen_info->box_gc,
                        0, 0, wireframe->width - 1, wireframe->height - 1);
    }
}
Beispiel #27
0
void TkSubtractRegion (TkRegion a, TkRegion b, TkRegion c)
{
    XSubtractRegion((Region) a, (Region) b, (Region) c);
}