Beispiel #1
0
/*
 * RootlessMarkOverlappedWindows
 *  MarkOverlappedWindows is modified to ignore overlapping
 *  top-level windows.
 */
static Bool
RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
                              WindowPtr *ppLayerWin)
{
    RegionRec saveRoot;
    Bool result;
    ScreenPtr pScreen = pWin->drawable.pScreen;
    SCREEN_UNWRAP(pScreen, MarkOverlappedWindows);
    RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start ");

    HUGE_ROOT(pWin);
    if (IsRoot(pWin)) {
        // root - mark nothing
        RL_DEBUG_MSG("is root not marking ");
        result = FALSE;
    }
    else if (! IsTopLevel(pWin)) {
        // not top-level window - mark normally
        result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin);
    }
    else {
        //top-level window - mark children ONLY - NO overlaps with sibs (?)
        // This code copied from miMarkOverlappedWindows()

        register WindowPtr pChild;
        Bool anyMarked = FALSE;
        MarkWindowProcPtr MarkWindow = pScreen->MarkWindow;

        RL_DEBUG_MSG("is top level! ");
        /* single layered systems are easy */
        if (ppLayerWin) *ppLayerWin = pWin;

        if (pWin == pFirst) {
            /* Blindly mark pWin and all of its inferiors.   This is a slight
             * overkill if there are mapped windows that outside pWin's border,
             * but it's better than wasting time on RectIn checks.
             */
            pChild = pWin;
            while (1) {
                if (pChild->viewable) {
                    if (RegionBroken(&pChild->winSize))
                        SetWinSize (pChild);
                    if (RegionBroken(&pChild->borderSize))
                        SetBorderSize (pChild);
                    (* MarkWindow)(pChild);
                    if (pChild->firstChild) {
                        pChild = pChild->firstChild;
                        continue;
                    }
                }
                while (!pChild->nextSib && (pChild != pWin))
                    pChild = pChild->parent;
                if (pChild == pWin)
                    break;
                pChild = pChild->nextSib;
            }
            anyMarked = TRUE;
            pFirst = pFirst->nextSib;
        }
        if (anyMarked)
            (* MarkWindow)(pWin->parent);
        result = anyMarked;
    }
    NORMAL_ROOT(pWin);
    SCREEN_WRAP(pScreen, MarkOverlappedWindows);
    RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n");

    return result;
}
Beispiel #2
0
Bool
miMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin)
{
    BoxPtr box;
    WindowPtr pChild, pLast;
    Bool anyMarked = FALSE;
    MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;

    /* single layered systems are easy */
    if (ppLayerWin)
        *ppLayerWin = pWin;

    if (pWin == pFirst) {
        /* Blindly mark pWin and all of its inferiors.   This is a slight
         * overkill if there are mapped windows that outside pWin's border,
         * but it's better than wasting time on RectIn checks.
         */
        pChild = pWin;
        while (1) {
            if (pChild->viewable) {
                if (RegionBroken(&pChild->winSize))
                    SetWinSize(pChild);
                if (RegionBroken(&pChild->borderSize))
                    SetBorderSize(pChild);
                (*MarkWindow) (pChild);
                if (pChild->firstChild) {
                    pChild = pChild->firstChild;
                    continue;
                }
            }
            while (!pChild->nextSib && (pChild != pWin))
                pChild = pChild->parent;
            if (pChild == pWin)
                break;
            pChild = pChild->nextSib;
        }
        anyMarked = TRUE;
        pFirst = pFirst->nextSib;
    }
    if ((pChild = pFirst)) {
        box = RegionExtents(&pWin->borderSize);
        pLast = pChild->parent->lastChild;
        while (1) {
            if (pChild->viewable) {
                if (RegionBroken(&pChild->winSize))
                    SetWinSize(pChild);
                if (RegionBroken(&pChild->borderSize))
                    SetBorderSize(pChild);
                if (RegionContainsRect(&pChild->borderSize, box)) {
                    (*MarkWindow) (pChild);
                    anyMarked = TRUE;
                    if (pChild->firstChild) {
                        pChild = pChild->firstChild;
                        continue;
                    }
                }
            }
            while (!pChild->nextSib && (pChild != pLast))
                pChild = pChild->parent;
            if (pChild == pLast)
                break;
            pChild = pChild->nextSib;
        }
    }
    if (anyMarked)
        (*MarkWindow) (pWin->parent);
    return anyMarked;
}
Beispiel #3
0
/*ARGSUSED*/
int
miValidateTree (
    WindowPtr		pParent,    /* Parent to validate */
    WindowPtr		pChild,     /* First child of pParent that was
				     * affected */
    VTKind		kind        /* What kind of configuration caused call */
    )
{
    RegionRec	  	totalClip;  /* Total clipping region available to
				     * the marked children. pParent's clipList
				     * merged with the borderClips of all
				     * the marked children. */
    RegionRec	  	childClip;  /* The new borderClip for the current
				     * child */
    RegionRec		childUnion; /* the space covered by borderSize for
				     * all marked children */
    RegionRec		exposed;    /* For intermediate calculations */
    ScreenPtr		pScreen;
    WindowPtr		pWin;
    Bool		overlap;
    int			viewvals;
    Bool		forward;

    pScreen = pParent->drawable.pScreen;
    if (pChild == NullWindow)
	pChild = pParent->firstChild;

    RegionNull(&childClip);
    RegionNull(&exposed);

    /*
     * compute the area of the parent window occupied
     * by the marked children + the parent itself.  This
     * is the area which can be divied up among the marked
     * children in their new configuration.
     */
    RegionNull(&totalClip);
    viewvals = 0;
    if (RegionBroken(&pParent->clipList) &&
	!RegionBroken(&pParent->borderClip))
    {
	kind = VTBroken;
	/*
	 * When rebuilding clip lists after out of memory,
	 * assume everything is busted.
	 */
	forward = TRUE;
	RegionCopy(&totalClip, &pParent->borderClip);
	RegionIntersect(&totalClip, &totalClip, &pParent->winSize);
	
	for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib)
	{
	    if (pWin->viewable && !TreatAsTransparent (pWin))
		RegionSubtract(&totalClip, &totalClip, &pWin->borderSize);
	}
	for (pWin = pChild; pWin; pWin = pWin->nextSib)
	    if (pWin->valdata && pWin->viewable)
		viewvals++;
	
	RegionEmpty(&pParent->clipList);
    }
    else 
    {
	if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
	    ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
	     (pChild->drawable.x < pParent->lastChild->drawable.x)))
	{
	    forward = TRUE;
	    for (pWin = pChild; pWin; pWin = pWin->nextSib)
	    {
		if (pWin->valdata)
		{
		    RegionPtr	pBorderClip = &pWin->borderClip;
#ifdef COMPOSITE
		    if (pWin->redirectDraw != RedirectDrawNone && miGetRedirectBorderClipProc)
			pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
#endif
		    RegionAppend(&totalClip, pBorderClip );
		    if (pWin->viewable)
			viewvals++;
		}
	    }
	}
	else
	{
	    forward = FALSE;
	    pWin = pParent->lastChild;
	    while (1)
	    {
		if (pWin->valdata)
		{
		    RegionPtr	pBorderClip = &pWin->borderClip;
#ifdef COMPOSITE
		    if (pWin->redirectDraw != RedirectDrawNone && miGetRedirectBorderClipProc)
			pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
#endif
		    RegionAppend(&totalClip, pBorderClip );
		    if (pWin->viewable)
			viewvals++;
		}
		if (pWin == pChild)
		    break;
		pWin = pWin->prevSib;
	    }
	}
	RegionValidate(&totalClip, &overlap);
    }

    /*
     * Now go through the children of the root and figure their new
     * borderClips from the totalClip, passing that off to miComputeClips
     * to handle recursively. Once that's done, we remove the child
     * from the totalClip to clip any siblings below it.
     */

    overlap = TRUE;
    if (kind != VTStack)
    {
	RegionUnion(&totalClip, &totalClip, &pParent->clipList);
	if (viewvals > 1)
	{
	    /*
	     * precompute childUnion to discover whether any of them
	     * overlap.  This seems redundant, but performance studies
	     * have demonstrated that the cost of this loop is
	     * lower than the cost of multiple Subtracts in the
	     * loop below.
	     */
	    RegionNull(&childUnion);
	    if (forward)
	    {
		for (pWin = pChild; pWin; pWin = pWin->nextSib)
		    if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin))
			RegionAppend(&childUnion,
						   &pWin->borderSize);
	    }
	    else
	    {
		pWin = pParent->lastChild;
		while (1)
		{
		    if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin))
			RegionAppend(&childUnion,
						   &pWin->borderSize);
		    if (pWin == pChild)
			break;
		    pWin = pWin->prevSib;
		}
	    }
	    RegionValidate(&childUnion, &overlap);
	    if (overlap)
		RegionUninit(&childUnion);
	}
    }

    for (pWin = pChild;
	 pWin != NullWindow;
	 pWin = pWin->nextSib)
    {
	if (pWin->viewable) {
	    if (pWin->valdata) {
		RegionIntersect(&childClip,
					&totalClip,
 					&pWin->borderSize);
		miComputeClips (pWin, pScreen, &childClip, kind, &exposed);
		if (overlap && !TreatAsTransparent (pWin))
		{
		    RegionSubtract(&totalClip,
				       	   &totalClip,
				       	   &pWin->borderSize);
		}
	    } else if (pWin->visibility == VisibilityNotViewable) {
		miTreeObscured(pWin);
	    }
	} else {
	    if (pWin->valdata) {
		RegionEmpty(&pWin->clipList);
		if (pScreen->ClipNotify)
		    (* pScreen->ClipNotify) (pWin, 0, 0);
		RegionEmpty(&pWin->borderClip);
		pWin->valdata = NULL;
	    }
	}
    }

    RegionUninit(&childClip);
    if (!overlap)
    {
	RegionSubtract(&totalClip, &totalClip, &childUnion);
	RegionUninit(&childUnion);
    }

    RegionNull(&pParent->valdata->after.exposed);
    RegionNull(&pParent->valdata->after.borderExposed);

    /*
     * each case below is responsible for updating the
     * clipList and serial number for the parent window
     */

    switch (kind) {
    case VTStack:
	break;
    default:
	/*
	 * totalClip contains the new clipList for the parent. Figure out
	 * exposures and obscures as per miComputeClips and reset the parent's
	 * clipList.
	 */
	RegionSubtract(&pParent->valdata->after.exposed,
			       &totalClip, &pParent->clipList);
	/* fall through */
    case VTMap:
	RegionCopy(&pParent->clipList, &totalClip);
	pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
	break;
    }

    RegionUninit(&totalClip);
    RegionUninit(&exposed);
    if (pScreen->ClipNotify)
	(*pScreen->ClipNotify) (pParent, 0, 0);
    return 1;
}
// fixme this is ugly
// Xprint/ValTree.c doesn't work, but maybe that method can?
int
RootlessMiValidateTree (WindowPtr pRoot, /* Parent to validate */
			WindowPtr pChild, /* First child of pRoot that was
					   * affected */
			VTKind kind /* What kind of configuration caused call */)
{
    RegionRec	  	childClip;  /* The new borderClip for the current
				     * child */
    RegionRec		exposed;    /* For intermediate calculations */
    register ScreenPtr	pScreen;
    register WindowPtr	pWin;

    pScreen = pRoot->drawable.pScreen;
    if (pChild == NullWindow)
	pChild = pRoot->firstChild;

    RegionNull(&childClip);
    RegionNull(&exposed);

    if (RegionBroken(&pRoot->clipList) &&
	!RegionBroken(&pRoot->borderClip))
    {
        // fixme this might not work, but hopefully doesn't happen anyway.
        kind = VTBroken;
        RegionEmpty(&pRoot->clipList);
        ErrorF("ValidateTree: BUSTED!\n");
    }

    /* 
     * Recursively compute the clips for all children of the root. 
     * They don't clip against each other or the root itself, so 
     * childClip is always reset to that child's size.
     */

    for (pWin = pChild;
	 pWin != NullWindow;
	 pWin = pWin->nextSib)
    {
        if (pWin->viewable) {
            if (pWin->valdata) {
                RegionCopy(&childClip, &pWin->borderSize);
                RootlessComputeClips (pWin, pScreen, &childClip, kind, &exposed);
            } else if (pWin->visibility == VisibilityNotViewable) {
                RootlessTreeObscured(pWin);
            }
        } else {
            if (pWin->valdata) {
                RegionEmpty(&pWin->clipList);
                if (pScreen->ClipNotify)
                    (* pScreen->ClipNotify) (pWin, 0, 0);
                RegionEmpty(&pWin->borderClip);
                pWin->valdata = NULL;
            }
        }
    }

    RegionUninit(&childClip);

    /* The root is never clipped by its children, so nothing on the root 
       is ever exposed by moving or mapping its children. */
    RegionNull(&pRoot->valdata->after.exposed);
    RegionNull(&pRoot->valdata->after.borderExposed);

    return 1;
}