Site hosted by Angelfire.com: Build your free website today!

Hands-on Projects for the Linux Graphics Subsystem

New book from Christos Karayiannis

Available in Amazon Kindle format at:

amazon.com   amazon.co.uk   amazon.de   amazon.es   amazon.fr   amazon.it

X Request Dispatching - A complete case study

In this section we start putting the bricks together to see a complete example of an X Client's request dispatching.

We start with the Xlib programs of section 1.1. At those examples the XMapWindow() Xlib library routine was used to make visible a window on the screen.

From the Xlib Reference Manual we read:

XMapWindow() maps a window, making it eligible for display. Whether it becomes visible it depends on its stacking order among its siblings, the mapping status of its ancestors, and the placement of other visible windows. If all the ancestors are mapped, and it is not obscured by siblings higher in the stacking order, and it is not obscured by unrelated windows (children of ancestors), then the window and all of its mapped subwindows are displayed.

At section 1.2 we saw how the client builds the request message for the XServer. The request type was X_MapWindow, defined in Xproto.h as:

#define X_MapWindow                     8
The XServer reads the protocol message with ReadRequestFromClient() and uses the request type (now given as MAJOROP) as an index to the client's requestVector[] table:
result = (* client->requestVector[MAJOROP])(client);
This process was described in section 3.2.5.3. We saw there that the requestVector[] can be either ProcVector[] or SwappedProcVector[] according to the Big or Small Endianess of the system and that both are defined in tables.c.

The function with index 8 at ProcVector[] is ProcMapWindow(). This routine is implemented as:

int
ProcMapWindow(register ClientPtr client)
{
    register WindowPtr pWin;
    REQUEST(xResourceReq);

    REQUEST_SIZE_MATCH(xResourceReq);
    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
					   SecurityReadAccess);
    if (!pWin)
        return(BadWindow);
    MapWindow(pWin, client);
           /* update cache to say it is mapped */
    return(client->noClientException);
}

Notice that 'stuff', which finds the current window, is explained in section 2.3.

ProcMapWindow() is actually an encapsulation of MapWindow(). This routine is examined in detail at section 3.2.2.13, where the final result was the frame buffer fbSolid() routine that painted the window in the screen. However this time we will follow a different path. The reason is the following 'if' condition, we find at the beginning of MapWindow(), which at the current example is TRUE:

    if ( (pParent = pWin->parent) )
When we initially examined this condition at section 3.2.2.13 because we developed the Root Window, i.e. the initial screen window, it didn't have a parent, however this time that we consider a common window, which has another window or Root window as a parent.

In the current case the iportant part is the following MapWindow() instruction:


	    if (anyMarked)
	    {
		(*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
		(*pScreen->HandleExposures)(pLayerWin->parent);
	    }

MapWindow callsMarkOverlappedWindows to flag those windows which need to be reclipped. It then calls ValidateTree to calculate the new clip lists, and determine newly exposed areas of the screen. On return from ValidateTree, MapWindow calls HandleExposures to draw background in any windows that have exposure regions.

The boolean variable anyMarked was filled from the next instruction:

	if (pWin->viewable)
	{
	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
							  &pLayerWin);
The MarkOverlappedWindows specific routine as seen in section 3.2.2.12 is miMarkOverlappedWindows():
    pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
This is implemented as:

Bool
miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
    WindowPtr pWin;
    WindowPtr pFirst;
    WindowPtr *ppLayerWin;
{
    register BoxPtr box;
    register WindowPtr pChild, pLast;
    Bool anyMarked = FALSE;
    MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
    ScreenPtr pScreen;

    pScreen = pWin->drawable.pScreen;

    /* 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 (REGION_BROKEN (pScreen, &pChild->winSize))
		    SetWinSize (pChild);
		if (REGION_BROKEN (pScreen, &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 = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize);
	pLast = pChild->parent->lastChild;
	while (1)
	{
	    if (pChild->viewable)
	    {
		if (REGION_BROKEN (pScreen, &pChild->winSize))
		    SetWinSize (pChild);
		if (REGION_BROKEN (pScreen, &pChild->borderSize))
		    SetBorderSize (pChild);
		if (RECT_IN_REGION(pScreen, &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;
}

REGION_BROKEN:

REGION_BROKEN finds if a region is valid (with data other than {0,0}). For the struct _Region see section 3.2.2.13.

REGION_BROKEN is defined as:

#define REGION_BROKEN(_pScreen, _pReg) \
    (REGION_SCREEN(_pScreen), miRegionBroken(_pReg))

where REGION_SCREEN is defined as:

#define REGION_SCREEN(_pScreen) (void)((REG_pScreen)->myNum)

REG_pScreen is defined as:

	

#define REG_pScreen	screenInfo.screens[0]

miRegionBroken() is defined as:

Bool
miRegionBroken(RegionPtr pReg)
{
    good(pReg);
    return (REGION_NAR(pReg));
}

good is defined as:

#define good(reg) assert(miValidRegion(reg))

REGION_NAR is defined as:

#define REGION_NAR(reg)	((reg)->data == &miBrokenData)

miBrokenData is defined as:

RegDataRec  miBrokenData = {0, 0};

Example:

The following figure illustrates a window landscape where the grey is the Root window and the other are numbered from 1 to 5, with window 1 being the parent of 2 and 5 and 2 being the parent of 3 and 4:

With the miMarkOverlappedWindows() call with window 1 as the first argument the arrows present the window order for whom (* MarkWindow)() is called:

Notice that at the end of this process the parent window, in this example the root window is also marked.

MarkWindow is defined in miMarkOverlappedWindows() as:

MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
and for the examples we follow this is determined in section 3.2.2.12 as:
pScreen->MarkWindow = miMarkWindow;

miMarkWindow() is implemented as:

void
miMarkWindow(pWin)
    register WindowPtr pWin;
{
    register ValidatePtr val;

    if (pWin->valdata)
	return;
    val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
    val->before.oldAbsCorner.x = pWin->drawable.x;
    val->before.oldAbsCorner.y = pWin->drawable.y;
    val->before.borderVisible = NullRegion;
    val->before.resized = FALSE;
    pWin->valdata = val;
}

The drawable, which can be either a window or a pixmap is defined in pixmapstr.h as:

typedef struct _Drawable {
    unsigned char	type;	/* DRAWABLE_ */
    unsigned char	class;	/* specific to type */
    unsigned char	depth;
    unsigned char	bitsPerPixel;
    unsigned long	id;	/* resource id */
    short		x;	/* window: screen absolute, pixmap: 0 */
    short		y;	/* window: screen absolute, pixmap: 0 */
    unsigned short	width;
    unsigned short	height;
    ScreenPtr		pScreen;
    unsigned long	serialNumber;
} DrawableRec;

x and y are the x, y dimensions of the window from the upper-left corner of the screen. By filling pWin->valdata the window is marked as "needs reclipping". Notice that valdata is filled with the 'before' part of the ValidateRec union (for ValidateRec see 'What is valdata' bollow).

We continue here with ValidateTree and HandleExposures

As we see in section 3.2.2.12 the screen specific ValidateTree routine is miValidateTree() and the screen specific HandleExposures is miHandleValidateExposures():



    pScreen->ValidateTree = miValidateTree;
    . . .
    pScreen->HandleExposures = miHandleValidateExposures;

miValidateTree()

miValidateTree() is implemented as:

/*
 *-----------------------------------------------------------------------
 * miValidateTree --
 *	Recomputes the clip list for pParent and all its inferiors.
 *
 * Results:
 *	Always returns 1.
 *
 * Side Effects:
 *	The clipList, borderClip, exposed, and borderExposed regions for
 *	each marked window are altered.
 *
 * Notes:
 *	This routine assumes that all affected windows have been marked
 *	(valdata created) and their winSize and borderSize regions
 *	adjusted to correspond to their new positions. The borderClip and
 *	clipList regions should not have been touched.
 *
 *	The top-most level is treated differently from all lower levels
 *	because pParent is unchanged. For the top level, we merge the
 *	regions taken up by the marked children back into the clipList
 *	for pParent, thus forming a region from which the marked children
 *	can claim their areas. For lower levels, where the old clipList
 *	and borderClip are invalid, we can't do this and have to do the
 *	extra operations done in miComputeClips, but this is much faster
 *	e.g. when only one child has moved...
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
int
miValidateTree (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	  	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 */
    register ScreenPtr	pScreen;
    register WindowPtr	pWin;
    Bool		overlap;
    int			viewvals;
    Bool		forward;

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

    REGION_NULL(pScreen, &childClip);
    REGION_NULL(pScreen, &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.
     */
    REGION_NULL(pScreen, &totalClip);
    viewvals = 0;
    if (REGION_BROKEN (pScreen, &pParent->clipList) &&
	!REGION_BROKEN (pScreen, &pParent->borderClip))
    {
	kind = VTBroken;
	/*
	 * When rebuilding clip lists after out of memory,
	 * assume everything is busted.
	 */
	forward = TRUE;
	REGION_COPY (pScreen, &totalClip, &pParent->borderClip);
	REGION_INTERSECT (pScreen, &totalClip, &totalClip, &pParent->winSize);
	
	for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib)
	{
	    if (pWin->viewable)
		REGION_SUBTRACT (pScreen, &totalClip, &totalClip, &pWin->borderSize);
	}
	for (pWin = pChild; pWin; pWin = pWin->nextSib)
	    if (pWin->valdata && pWin->viewable)
		viewvals++;
	
	REGION_EMPTY (pScreen, &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 && miGetRedirectBorderClipProc)
			pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
#endif
		    REGION_APPEND( pScreen, &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 && miGetRedirectBorderClipProc)
			pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
#endif
		    REGION_APPEND( pScreen, &totalClip, pBorderClip );
		    if (pWin->viewable)
			viewvals++;
		}
		if (pWin == pChild)
		    break;
		pWin = pWin->prevSib;
	    }
	}
	REGION_VALIDATE( pScreen, &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)
    {
	REGION_UNION( pScreen, &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.
	     */
	    REGION_NULL(pScreen, &childUnion);
	    if (forward)
	    {
		for (pWin = pChild; pWin; pWin = pWin->nextSib)
		    if (pWin->valdata && pWin->viewable)
			REGION_APPEND( pScreen, &childUnion,
						   &pWin->borderSize);
	    }
	    else
	    {
		pWin = pParent->lastChild;
		while (1)
		{
		    if (pWin->valdata && pWin->viewable)
			REGION_APPEND( pScreen, &childUnion,
						   &pWin->borderSize);
		    if (pWin == pChild)
			break;
		    pWin = pWin->prevSib;
		}
	    }
	    REGION_VALIDATE(pScreen, &childUnion, &overlap);
	    if (overlap)
		REGION_UNINIT(pScreen, &childUnion);
	}
    }

    for (pWin = pChild;
	 pWin != NullWindow;
	 pWin = pWin->nextSib)
    {
	if (pWin->viewable) {

	    if (pWin->valdata) {
		REGION_INTERSECT( pScreen, &childClip,
					&totalClip,
 					&pWin->borderSize);
		miComputeClips (pWin, pScreen, &childClip, kind, &exposed);
		if (overlap)
		{
		    REGION_SUBTRACT( pScreen, &totalClip,
				       	   &totalClip,
				       	   &pWin->borderSize);
		}
	    } else if (pWin->visibility == VisibilityNotViewable) {
		miTreeObscured(pWin);
	    }
	} else {
	    if (pWin->valdata) {
		REGION_EMPTY( pScreen, &pWin->clipList);
		if (pScreen->ClipNotify)
		    (* pScreen->ClipNotify) (pWin, 0, 0);
		REGION_EMPTY( pScreen, &pWin->borderClip);
		pWin->valdata = (ValidatePtr)NULL;
	    }
	}
    }

    REGION_UNINIT( pScreen, &childClip);
    if (!overlap)
    {
	REGION_SUBTRACT(pScreen, &totalClip, &totalClip, &childUnion);
	REGION_UNINIT(pScreen, &childUnion);
    }

    REGION_NULL(pScreen, &pParent->valdata->after.exposed);
    REGION_NULL(pScreen, &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.
	 */
	REGION_SUBTRACT( pScreen, &pParent->valdata->after.exposed,
			       &totalClip, &pParent->clipList);
	/* fall through */
    case VTMap:
	if (pParent->backStorage) {
	    REGION_SUBTRACT( pScreen, &exposed, &pParent->clipList, &totalClip);
	    (* pScreen->SaveDoomedAreas)(pParent, &exposed, 0, 0);
	}
	
	REGION_COPY( pScreen, &pParent->clipList, &totalClip);
	pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;

	break;
    }

    REGION_UNINIT( pScreen, &totalClip);
    REGION_UNINIT( pScreen, &exposed);
    if (pScreen->ClipNotify)
	(*pScreen->ClipNotify) (pParent, 0, 0);
    return (1);
}

miValidateTree() commentary

As seen bellow in the _Window struct firstChild is the top-most child and lastChild is the bottom-most child. firstChild and lastChild are determined by the 'Window stacking order'. When one window overlaps one of its sibling windows the one of the top obscures the other. It is the stacking order that makes the one window appear on the top.

firstChild and lastChild are compared in the miValidateTree() source by its drawable.x and drawable.y fields. We remind that x and y are defined in the _Drawable struct as the coordinates of the upper-left corner.

typedef struct _Drawable {
    unsigned char	type;	/* DRAWABLE_ */
    unsigned char	class;	/* specific to type */
    unsigned char	depth;
    unsigned char	bitsPerPixel;
    unsigned long	id;	/* resource id */
    short		x;	/* window: screen absolute, pixmap: 0 */
    short		y;	/* window: screen absolute, pixmap: 0 */
    unsigned short	width;
    unsigned short	height;
    ScreenPtr		pScreen;
    unsigned long	serialNumber;
} DrawableRec;

The following condition is used to find the order that REGION_APPEND, an encapsulation of miRegionAppend(), appends the address of pWin->borderClip of all child windows along with the parent's clipList to the totalClip. If the condition is true it appends from top-most to bottom-most otherwise the order is reversed.

	if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
	    ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
	     (pChild->drawable.x < pParent->lastChild->drawable.x)))

REGION_APPEND is defined as:

#define REGION_APPEND(_pScreen, dstrgn, rgn) \
    (REGION_SCREEN(_pScreen), miRegionAppend(dstrgn, rgn))

This like other macros found in regionstr.h discard their first argument since they are resolved to comma expressions. Those expressions are evaluated left to right and as an expression is evaluated its value is discarded. The value of the rightmost expression is the value of the comma expression.

The miRegionAppend() is what finally is called. We read at its comment:

 *      "Append" the rgn rectangles onto the end of dstrgn, maintaining
 *      knowledge of YX-banding when it's easy.  Otherwise, dstrgn just
 *      becomes a non-y-x-banded random collection of rectangles, and not
 *      yet a true region.  After a sequence of appends, the caller must
 *      call miRegionValidate to ensure that a valid region is constructed.

After the REGION_APPEND a REGION_VALIDATE is used. This is actually resolved to miRegionValidate():

#define REGION_VALIDATE(_pScreen, badreg, pOverlap) \
    (REGION_SCREEN(_pScreen), miRegionValidate(badreg, pOverlap))

For miRegionValidate() we read at its comment:

 * miRegionValidate --
 * 
 *      Take a ``region'' which is a non-y-x-banded random collection of
 *      rectangles, and compute a nice region which is the union of all the
 *      rectangles.

The following instruction then uses REGION_UNION, which resolves to a miUnion() call.

    if (kind != VTStack)
    {
	REGION_UNION( pScreen, &totalClip, &totalClip, &pParent->clipList);

miUnion() merges &totalClip and &pParent->clipList and saves the result back to &totalClip. Recall that totalClip has already included the borderClip of each child window and this region is now merged with the parent's clipList.

Next the whole children list is traversed via the for loop and REGION_INTERSECT (an encapsulation of miIntersect) is used to find the intesection between the totalClip and the borderSize of each. This is passed to miComputeClips() to find the new clipping region for each child and its possible children. This routine is explained in more detail in section 7.1.

REGION_SUBTRACT, which is resolved to miSubtract() subtracts the borderSize of the current child from totalClip, constrained thus the region that another sibling window could occupy and therefore allowing for visibly overlapping among the sibling windows. Notice that the previous apply only to the visible windows.

totalClip after the children spaces are removed are copied to the pParent->clipList. This can differ from the old clipList, since new windows are mapped, etc.

_Window fields of interest

From the Definition of the Porting Layer for the X we read:

The window has several fields used in drawing operations:

• clipList - This region, in conjunction with the client clip region in the gc, is used to clip output. clipList has the window's children subtracted from it, in addition to pieces of sibling windows that overlap this window. To get the list with the children included (subwindow-mode is IncludeInferiors), the routine NotClippedByChildren(pWin) returns the unclipped region.

• borderClip is the region used by CopyWindow and includes the area of the window, its children, and the border, but with the overlapping areas of sibling children removed.

When are winSize, borderSize, borderClip and clipList initialized for a window?

Each CreateWindow() calls SetWinSize() and SetBorderSize() to set the winSize and borderSize respectively. Also it sets clipList and borderSize to NULL. Notice that a CreateWindow() call results from XCreateWindow or XCreateSimpleWindow() Xlib requests that are handled by ProcCreateWindow(), as seen in tables.c. Finally ProcCreateWindow() calls CreateWindow().

borderClip and clipList are initialized for the root window at CreateRootWindow() and all ancestors initialize them when miValidateTree() is called from a root child (for instance when the child is mapped). The root children's borderClip and clipList are used then for their children and so on. This takes place in miValidateTree() just before miComputeClips() is called for each newly born child. The ticket for those calculations is the borderSize of the child.

An Example:

The first image shows two sibling windows. Window 2 request a mapping. In the second image we see the totalClip region, marked as yellow. The third image shows the shrinked totalClip region after the window 2 borderSize is subtracted from totalClip after the miComputeClips() is called for this window. The last image shows the intersection of window 1 with the totalClip region, just before it takes its turn to enter miComputeClips(). The green area is the childClip, which is referred to miComputeClips() as the 'universe'. The universe will be used next for the window 1 clipList calculation and will constrain the available region space for the calculations for the window 1 children, grandchildren, etc (if any).

What is valdata

valdata are used mainly for two reasons: to mark the affected windows and to return the areas that need to be redrawn. valdata is a field of the _Window struct:

   union _Validate	*valdata;

_Validate and ValidateRec are defined in mivalidate.h as:

typedef union _Validate {
    struct BeforeValidate {
	DDXPointRec	oldAbsCorner;	/* old window position */
	RegionPtr	borderVisible;	/* visible region of border, */
					/* non-null when size changes */
	Bool		resized;	/* unclipped winSize has changed - */
					/* don't call SaveDoomedAreas */
    } before;
    struct AfterValidate {
	RegionRec	exposed;	/* exposed regions, absolute pos */
	RegionRec	borderExposed;
    } after;
} ValidateRec;

Also ValidatePtr is defined as:

typedef union _Validate *ValidatePtr;

Because many other _Window fields are used in this section we remind the _Window struct:


typedef struct _Window {
    DrawableRec		drawable;
    WindowPtr		parent;		/* ancestor chain */
    WindowPtr		nextSib;	/* next lower sibling */
    WindowPtr		prevSib;	/* next higher sibling */
    WindowPtr		firstChild;	/* top-most child */
    WindowPtr		lastChild;	/* bottom-most child */
    RegionRec		clipList;	/* clipping rectangle for output */
    RegionRec		borderClip;	/* NotClippedByChildren + border */
    union _Validate	*valdata;
    RegionRec		winSize;
    RegionRec		borderSize;
    DDXPointRec		origin;		/* position relative to parent */
    unsigned short	borderWidth;
    unsigned short	deliverableEvents;
    Mask		eventMask;
    PixUnion		background;
    PixUnion		border;
    pointer		backStorage;	/* null when BS disabled */
    WindowOptPtr	optional;
    unsigned		backgroundState:2; /* None, Relative, Pixel, Pixmap */
    unsigned		borderIsPixel:1;
    unsigned		cursorIsNone:1;	/* else real cursor (might inherit) */
    unsigned		backingStore:2;
    unsigned		saveUnder:1;
    unsigned		DIXsaveUnder:1;
    unsigned		bitGravity:4;
    unsigned		winGravity:4;
    unsigned		overrideRedirect:1;
    unsigned		visibility:2;
    unsigned		mapped:1;
    unsigned		realized:1;	/* ancestors are all mapped */
    unsigned		viewable:1;	/* realized && InputOutput */
    unsigned		dontPropagate:3;/* index into DontPropagateMasks */
    unsigned		forcedBS:1;	/* system-supplied backingStore */
#ifdef NEED_DBE_BUF_BITS
#define DBE_FRONT_BUFFER 1
#define DBE_BACK_BUFFER  0
    unsigned		dstBuffer:1;	/* destination buffer for rendering */
    unsigned		srcBuffer:1;	/* source buffer for rendering */
#endif
#ifdef COMPOSITE
    unsigned		redirectDraw:1;	/* rendering is redirected from here */
#endif
    DevUnion		*devPrivates;
} WindowRec;

What is a Region

As we saw in section 3.2.2.13 struct _Region is defined in regionstr.h as:

typedef struct _Region RegionRec, *RegionPtr;
. . .
typedef struct _RegData {
    long	size;
    long 	numRects;
/*  BoxRec	rects[size];   in memory but not explicitly declared */
} RegDataRec, *RegDataPtr;

struct _Region {
    BoxRec 	extents;
    RegDataPtr	data;
};

where BoxRec is defined in miscstruct.h as:

typedef struct _Box {
    short x1, y1, x2, y2;
} BoxRec;

From the starting comments of miregion.c and Region.c we read:

                                     A Region is simply a set of disjoint
 * (non-overlapping) rectangles, plus an "extent" rectangle which is the
 * smallest single rectangle that contains all the non-overlapping rectangles.

                                  A Region is simply an area, as the name
 * implies, and is implemented as a "y-x-banded" array of rectangles.

                                                                    This array
 * imposes two degrees of order.  First, all rectangles are sorted by top side
 * y coordinate first (y1), and then by left side x coordinate (x1).

                                                                         To
 * explain: Each Region is made up of a certain number of rectangles sorted
 * by y coordinate first, and then by x coordinate.

 * Furthermore, the rectangles are grouped into "bands".  Each rectangle in a
 * band has the same top y coordinate (y1), and each has the same bottom y
 * coordinate (y2).  Thus all rectangles in a band differ only in their left
 * and right side (x1 and x2).  Bands are implicit in the array of rectangles:
 * there is no separate list of band start pointers.
 *
 * The y-x band representation does not minimize rectangles.  In particular,
 * if a rectangle vertically crosses a band (the rectangle has scanlines in 
 * the y1 to y2 area spanned by the band), then the rectangle may be broken
 * down into two or more smaller rectangles stacked one atop the other. 
 *
 *  -----------				    -----------
 *  |         |				    |         |		    band 0
 *  |         |  --------		    -----------  --------
 *  |         |  |      |  in y-x banded    |         |  |      |   band 1
 *  |         |  |      |  form is	    |         |  |      |
 *  -----------  |      |		    -----------  --------
 *               |      |				 |      |   band 2
 *               --------				 --------
 *
 * An added constraint on the rectangles is that they must cover as much
 * horizontal area as possible: no two rectangles within a band are allowed
 * to touch.
 *
 * Whenever possible, bands will be merged together to cover a greater vertical
 * distance (and thus reduce the number of rectangles). Two bands can be merged
 * only if the bottom of one touches the top of the other and they have
 * rectangles in the same places (of the same width, of course).

miHandleValidateExposures()

miHandleValidateExposures() is implemented as:

/*****
 *  miHandleValidateExposures(pWin)
 *    starting at pWin, draw background in any windows that have exposure
 *    regions, translate the regions, restore any backing store,
 *    and then send any regions still exposed to the client
 *****/
void
miHandleValidateExposures(pWin)
    WindowPtr pWin;
{
    register WindowPtr pChild;
    register ValidatePtr val;
    ScreenPtr pScreen;
    WindowExposuresProcPtr WindowExposures;

    pScreen = pWin->drawable.pScreen;

    pChild = pWin;
    WindowExposures = pChild->drawable.pScreen->WindowExposures;

    while (1)
    {
	if ( (val = pChild->valdata) )
	{
	    if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
		(*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
						    &val->after.borderExposed,
						    PW_BORDER);
	    REGION_UNINIT(pScreen, &val->after.borderExposed);
	    (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
	    REGION_UNINIT(pScreen, &val->after.exposed);
	    xfree(val);
	    pChild->valdata = (ValidatePtr)NULL;
	    if (pChild->firstChild)
	    {
		pChild = pChild->firstChild;
		continue;
	    }
	}
	while (!pChild->nextSib && (pChild != pWin))
	    pChild = pChild->parent;
	if (pChild == pWin)
	    break;
	pChild = pChild->nextSib;
    }
}

As seen in section 3.2.2.12 the PaintWindowBorder specific implementation for the configuration we followed in the previous sections is fbPaintWindow(). This function takes as argument the &val->after.borderExposed of the curent window, which is calculated in miComputeClips() (see section 7.1.1) to find the border parts that needs repair.

The next figure, like the miMarkOverlappedWindows() example, shows the Root window and the windows numbered from 1 to 5, with window 1 being the parent of 2 and 5 and 2 being the parent of 3 and 4:

Like miMarkOverlappedWindows() the same algorithm is used to traverse the children windows to implement this time fbPaintWindow(), if it needs to, and miWindowExposures(). For the current example the path is illustrated in the following figure:

We met fbPaintWindow() in section 3.2.2.13. In the current case the following lines are executed in the fbPaintWindow() 'case' statement:

    case PW_BORDER:
	if (pWin->borderIsPixel)
	{
	    fbFillRegionSolid (&pWin->drawable,
			       pRegion,
			       0,
			       fbReplicatePixel (pWin->border.pixel,
						 pWin->drawable.bitsPerPixel));

where the formal argument pRegion is substituted by the the actual argument:
&val->after.borderExposed

fbFillRegionSolid() and fbReplicatePixel() were also discussed in section 3.2.2.13.

Next miHandleValidateExposures() applies WindowExposures on all marked window (pChild->valdata is set). As seen in section 3.2.2.12 the WindowExposures specific implementation is miWindowExposures():

pScreen->WindowExposures = miWindowExposures;
miWindowExposures() is described in section 3.2.2.13. for the current configuration it mainly calls PaintWindowBackground as:
	    (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
PaintWindowBackground for this configuration is fbPaintWindow():
    pScreen->PaintWindowBackground = fbPaintWindow;
fbPaintWindow() is developed in section 3.2.2.12. The part implemented in the current flow is:


    case PW_BACKGROUND:
	switch (pWin->backgroundState) {
	case None:
	    break;
	case ParentRelative:
	    do {
		pWin = pWin->parent;
	    } while (pWin->backgroundState == ParentRelative);
	    (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
							     what);
	    break;
	case BackgroundPixmap:
	    fbFillRegionTiled (&pWin->drawable,
			       pRegion,
			       pWin->background.pixmap);
	    break;
	case BackgroundPixel:
	    fbFillRegionSolid (&pWin->drawable,
			       pRegion,
			       0,
			       fbReplicatePixel (pWin->background.pixel,
						 pWin->drawable.bitsPerPixel));
	    break;
    	}
    	break;

For instance if the backgroundState is set to BackgroundPixmap the background is tiled with the background.pixmap, via fbFillRegionTiled().

REFERENCES

Definition of the Porting Layer for the X
X Window System Protocol
Mapping Windows
Xlib - C Language X Interface
Xlib Programming Manual