193 lines
6.5 KiB
C
193 lines
6.5 KiB
C
|
/*
|
||
|
(c) Copyright 1996 Hewlett-Packard Company
|
||
|
(c) Copyright 1996 International Business Machines Corp.
|
||
|
(c) Copyright 1996 Sun Microsystems, Inc.
|
||
|
(c) Copyright 1996 Novell, Inc.
|
||
|
(c) Copyright 1996 Digital Equipment Corp.
|
||
|
(c) Copyright 1996 Fujitsu Limited
|
||
|
(c) Copyright 1996 Hitachi, Ltd.
|
||
|
|
||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
of this software and associated documentation files (the "Software"), to deal
|
||
|
in the Software without restriction, including without limitation the rights
|
||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
copies of the Software, and to permit persons to whom the Software is
|
||
|
furnished to do so, subject to the following conditions:
|
||
|
|
||
|
The above copyright notice and this permission notice shall be included in
|
||
|
all copies or substantial portions of the Software.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
|
||
|
Except as contained in this notice, the names of the copyright holders shall
|
||
|
not be used in advertising or otherwise to promote the sale, use or other
|
||
|
dealings in this Software without prior written authorization from said
|
||
|
copyright holders.
|
||
|
*/
|
||
|
/* $XFree86$ */
|
||
|
|
||
|
#ifdef HAVE_DIX_CONFIG_H
|
||
|
#include <dix-config.h>
|
||
|
#endif
|
||
|
|
||
|
#include <X11/X.h>
|
||
|
#include "scrnintstr.h"
|
||
|
#include "validate.h"
|
||
|
#include "windowstr.h"
|
||
|
#include "mi.h"
|
||
|
#include "regionstr.h"
|
||
|
#include "mivalidate.h"
|
||
|
|
||
|
/*
|
||
|
* XpValidateTree - a validateTree routine which ignores overlapping
|
||
|
* top-level windows when computing the clip lists for such windows.
|
||
|
* This can be used by any driver which maintains a separate memory
|
||
|
* store for each top-level window (with its respective children).
|
||
|
* If the pParent is not the root window, then miValidateTree
|
||
|
* is used unmodified.
|
||
|
*
|
||
|
* The strategy if pParent is the root is to save off the
|
||
|
* current values of pParent->firstChild and pParent->lastChild,
|
||
|
* replacing both with the single child of interest. We save off
|
||
|
* pChild->prevSib and pChild->nextSib, and replace them with NullWindow.
|
||
|
* We save off pParent->clipList, and replace it with
|
||
|
* pParent->winSize - pChild->winSize. We then call miValidateTree
|
||
|
* to do the needed ComputeClips on the pChild's heirarchy.
|
||
|
* pParent's clipList is then recomputed based on the sizes
|
||
|
* of its children, and the saved pointers are restored.
|
||
|
* The trees associated with the siblings of pChild must be descended
|
||
|
* and cleaned of any marks (i.e. the valdata pointer freed, and set to NULL),
|
||
|
* and pParent' AfterValidate structure's exposed field must be updated.
|
||
|
*/
|
||
|
/*ARGSUSED*/
|
||
|
int
|
||
|
XpValidateTree (pParent, pChild, kind)
|
||
|
WindowPtr pParent; /* Parent to validate */
|
||
|
WindowPtr pChild; /* First child of pParent that was
|
||
|
* affected */
|
||
|
VTKind kind; /* What kind of configuration caused call */
|
||
|
{
|
||
|
RegionRec origPrntClip; /* orig clipList for parent */
|
||
|
RegionRec childClip; /* The new borderClip for the current
|
||
|
* child */
|
||
|
RegionRec tmpPrntClip; /* parent clipList - child borderClip */
|
||
|
RegionRec exposed; /* For intermediate calculations */
|
||
|
register ScreenPtr pScreen;
|
||
|
register WindowPtr pWin;
|
||
|
Bool overlap;
|
||
|
int viewvals;
|
||
|
Bool forward;
|
||
|
|
||
|
WindowPtr origFirstChild, origLastChild, origPrevSib, origNextSib;
|
||
|
|
||
|
/*
|
||
|
* If we're validating something other than a top-level window,
|
||
|
* then just invoke miValidateTree.
|
||
|
*/
|
||
|
if(pParent->parent != NullWindow)
|
||
|
return miValidateTree(pParent, pChild, kind);
|
||
|
|
||
|
/*
|
||
|
* If it's a stack change of top levels then it's a no-op for
|
||
|
* this scheme, so we just clean up any marks on windows and return.
|
||
|
*/
|
||
|
if(kind == VTStack)
|
||
|
{
|
||
|
CleanMarks(pParent);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
pScreen = pParent->drawable.pScreen;
|
||
|
if (pChild == NullWindow)
|
||
|
pChild = pParent->firstChild;
|
||
|
|
||
|
/* Save off the existing window heirarchy */
|
||
|
origFirstChild = pParent->firstChild;
|
||
|
origLastChild = pParent->lastChild;
|
||
|
origPrevSib = pChild->prevSib;
|
||
|
origNextSib = pChild->nextSib;
|
||
|
pParent->firstChild = pChild;
|
||
|
pParent->lastChild = pChild;
|
||
|
pChild->prevSib = NullWindow;
|
||
|
pChild->nextSib = NullWindow;
|
||
|
|
||
|
/*
|
||
|
* Set pParent's clipList to be its winSize minus the pChild's
|
||
|
* borderSize.
|
||
|
*/
|
||
|
origPrntClip = pParent->clipList;
|
||
|
REGION_NULL(pScreen, &tmpPrntClip);
|
||
|
REGION_SUBRACT(pScreen, &tmpPrntClip, &pParent->winSize,
|
||
|
&pChild->borderSize);
|
||
|
pParent->clipList = tmpPrntClip;
|
||
|
|
||
|
/*
|
||
|
* Call miValidateTree on the pruned tree.
|
||
|
*/
|
||
|
(void) miValidateTree(pParent, pChild, kind);
|
||
|
|
||
|
/* Restore the saved heirarchy */
|
||
|
pChild->prevSib = origPrevSib;
|
||
|
pChild->nextSib = origNextSib;
|
||
|
pParent->firstChild = origFirstChild;
|
||
|
pParent->lastChild = origLastChild;
|
||
|
|
||
|
/*
|
||
|
* Compute pParent's clipList by taking its winSize and subracting
|
||
|
* the borderSize of each of its children.
|
||
|
*/
|
||
|
for(pWin = pParent->firstChild,
|
||
|
REGION_COPY(pScreen, &pParent->clipList, &pParent->winSize);
|
||
|
pWin != NullWindow;
|
||
|
pWin = pWin->nextSib)
|
||
|
{
|
||
|
REGION_SUBTRACT(pScreen, &pParent->clipList, &pParent->clipList,
|
||
|
&pWin->borderSize);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Compute pParent's AfterValidate structure by subracting the original
|
||
|
* clipList from the newly computed clipList.
|
||
|
*/
|
||
|
REGION_NULL(pScreen, &pParent->valdata->after.exposed);
|
||
|
REGION_SUBTRACT(pScreen, &pParent->valdata->after.exposed,
|
||
|
&pParent->clipList, &origPrntClip);
|
||
|
|
||
|
/*
|
||
|
* Remove the marks from all but pParent and pChild's heirarchy.
|
||
|
* i.e. from all of pChild's siblings and their children.
|
||
|
*/
|
||
|
for(pWin = pParent->firstChild; pWin != NullWindow; pWin = pWin->nextSib)
|
||
|
{
|
||
|
WindowPtr pCurChild = pWin;
|
||
|
|
||
|
if(pCurChild == pChild)
|
||
|
continue;
|
||
|
|
||
|
while (1)
|
||
|
{
|
||
|
if(pCurChild->valdata)
|
||
|
{
|
||
|
xfree(pCurChild->valdata);
|
||
|
pCurChild->valdata = (ValidatePtr)NULL;
|
||
|
}
|
||
|
|
||
|
if (pCurChild->firstChild)
|
||
|
{
|
||
|
pCurChild = pCurChild->firstChild;
|
||
|
continue;
|
||
|
}
|
||
|
while (!pCurChild->nextSib && (pCurChild != pWin))
|
||
|
pCurChild = pCurChild->parent;
|
||
|
if (pCurChild == pWin)
|
||
|
break;
|
||
|
pCurChild = pCurChild->nextSib;
|
||
|
}
|
||
|
}
|
||
|
}
|