/***********************************************************
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its 
documentation for any purpose and without fee is hereby granted, 
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in 
supporting documentation, and that the names of Digital or MIT not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.  

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

******************************************************************/

/* $Header: window.c,v 1.144 87/06/16 15:27:22 toddb Exp $ */

#include "X.h"
#define NEED←REPLIES
#define NEED←EVENTS
#include "Xproto.h"
#include "misc.h"
#include "scrnintstr.h"
#include "os.h"
#include "regionstr.h"
#include "windowstr.h"
#include "input.h"
#include "resource.h"
#include "colormapst.h"
#include "cursorstr.h"
#include "dixstruct.h"
#include "gcstruct.h"
#include "opaque.h"

/******
 * Window stuff for server 
 *
 *    CreateRootWindow, CreateWindow, ChangeWindowAttributes,
 *    GetWindowAttributes, DeleteWindow, DestroySubWindows,
 *    HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
 *    UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
 *
 ******/

extern long ←back[16];
extern void ResizeChildrenWinSize();
extern void MoveWindowInStack();
extern void DoObscures();
extern void fixChildrenWinSize();
extern void DoObscures();
extern void HandleExposures();

typedef struct ←ScreenSaverStuff {
    WindowPtr pWindow;
    XID       wid;
    XID       cid;
    BYTE      blanked;
} ScreenSaverStuffRec;

#define SCREEN←IS←BLANKED   0
#define SCREEN←IS←TILED     1
#define SCREEN←ISNT←SAVED   2

extern int ScreenSaverBlanking, ScreenSaverAllowExposures;
extern int screenIsSaved ;

extern ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];

extern WindowRec WindowTable[];
extern int (* ReplySwapVector[256]) ();

extern void MoveWindow();
extern int ExposeAll();

#define INPUTONLY←LEGAL←MASK (CWWinGravity | CWEventMask | \
			      CWDontPropagate | CWCursor )

static void
SlideAndSizeWindow(pWin, x, y, w, h, pSib, above)
    WindowPtr pWin;
    short x,y;
    unsigned short w, h;
    WindowPtr pSib;
    int above;
{
    WindowPtr pParent;
    Bool WasMapped = (Bool)(pWin->realized);
    BoxRec box;
    unsigned short width = pWin->clientWinSize.width,
                   height = pWin->clientWinSize.height;    
    short oldx = pWin->absCorner.x,
          oldy = pWin->absCorner.y,
          bw = pWin->borderWidth;
    short dw, dh;
    Bool XYSame = FALSE;
    DDXPointRec oldpt;
    RegionPtr oldRegion;
    Bool anyMarked;
    register ScreenPtr pScreen;
    BoxPtr pBox;

    /* if this is a root window, can't be resized */
    if (!(pParent = pWin->parent)) 
        return ;

    pScreen = pWin->drawable.pScreen;
    if (WasMapped) 
    {
        if ((pWin->bitGravity != ForgetGravity) ||
            (pWin->backgroundTile == (PixmapPtr)ParentRelative))
            oldRegion = NotClippedByChildren(pWin);
        pBox = (* pScreen->RegionExtents)(pWin->borderSize);
	anyMarked = MarkSiblingsBelowMe(pWin, pBox, TRUE);
    }
    pWin->clientWinSize.x = x + bw;
    pWin->clientWinSize.y = y + bw;
    pWin->clientWinSize.height = h;
    pWin->clientWinSize.width = w;
    XYSame = ((pParent->absCorner.x + x == pWin->absCorner.x) 
	      && (pParent->absCorner.y + y == pWin->absCorner.y));
    pWin->oldAbsCorner.x = oldx;
    pWin->oldAbsCorner.y = oldy;
    oldpt.x = oldx;
    oldpt.y = oldy;

    pWin->absCorner.x = pParent->absCorner.x + x + bw;
    pWin->absCorner.y = pParent->absCorner.y + y + bw;

    box.x1 = pWin->absCorner.x;
    box.y1 = pWin->absCorner.y;
    box.x2 = pWin->absCorner.x + w;
    box.y2 = pWin->absCorner.y + h;
    (* pScreen->RegionReset)(pWin->winSize, &box);
    (* pScreen->Intersect)(pWin->winSize, pWin->winSize, pParent->winSize);

    if (pWin->borderWidth)
    {
	box.x1 -= bw;
	box.y1 -= bw;
	box.x2 += bw;
	box.y2 += bw;
	(* pScreen->RegionReset)(pWin->borderSize, &box);
        (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize, 
				     pParent->winSize);
    }
    else
        (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize);

    dw = w - width;
    dh = h - height;
    ResizeChildrenWinSize(pWin, XYSame, dw, dh);

    /* let the hardware adjust background and border pixmaps, if any */
    (* pScreen->PositionWindow)(pWin, pWin->absCorner.x, pWin->absCorner.y);

    if (!pSib || (above == Above))
        MoveWindowInStack(pWin, pSib);
    else
        MoveWindowInStack(pSib, pWin);

    if (WasMapped) 
    {
        RegionPtr pRegion;

        if (!pSib || (above == Above))
	    anyMarked = MarkSiblingsBelowMe(pWin, pBox, TRUE) ||  anyMarked;
        else
	    anyMarked = MarkSiblingsBelowMe(pSib, pBox, TRUE) ||  anyMarked;

        if ((pWin->bitGravity == ForgetGravity) ||
            (pWin->backgroundTile == (PixmapPtr)ParentRelative))
	{
	    (* pScreen->ValidateTree)(pParent, (WindowPtr )NULL, 
						     TRUE, anyMarked);
	    TraverseTree(pWin, ExposeAll, (pointer)pScreen); 
	    DoObscures(pParent); 
	    HandleExposures(pParent);
	}
	else
	{
	    pRegion = (* pScreen->RegionCreate)((BoxPtr)NULL, 1);
	    (* pScreen->RegionCopy)(pRegion, pWin->clipList);

	    x = pWin->absCorner.x;
	    y = pWin->absCorner.y;
	    switch (pWin->bitGravity)
	    {
              case UnmapGravity:
	      case NorthWestGravity: 
		    break;
              case NorthGravity:  
                   x += dw/2;
		   break;
              case NorthEastGravity:    
		   x += dw;	     
		   break;
              case WestGravity:         
                   y += dh/2;
                   break;
              case CenterGravity:    
                   x += dw/2;
		   y += dh/2;
                   break;
              case EastGravity:         
                   x += dw;
		   y += dh/2;
                   break;
              case SouthWestGravity:    
		   y += dh;
                   break;
              case SouthGravity:        
                   x += dw/2;
		   y += dh;
                   break;
              case SouthEastGravity:    
                   x += dw;
		   y += dh;
		   break;
	      case StaticGravity:
		   x = oldx;
		   y = oldy;
		   break;
	      default:
                   break;
	    }
	    if (dw < 0)
	    {
		width = w;
		if (x < pWin->absCorner.x) x = pWin->absCorner.x;
	    }
	    if (dh < 0)
	    {
		height = h;
		if (y < pWin->absCorner.y) y = pWin->absCorner.y;
	    }
            if (pWin->bitGravity == UnmapGravity)
	    {
                UnmapWindow(pSib, DONT←HANDLE←EXPOSURES, SEND←NOTIFICATION, TRUE);
	    	(* pScreen->RegionDestroy)(pRegion);
	        (* pScreen->RegionDestroy)(oldRegion);
		return ;
            }                    
	    (* pScreen->ValidateTree)(pParent, 
			       (anyMarked ? pWin : (WindowPtr )NULL), 
			       TRUE, anyMarked);
	    DoObscures(pParent);
	    if (pWin->backStorage && (pWin->backingStore != NotUseful))
	    {
		ErrorF("Going to translate backing store %d %d\n",
		       oldx - x, oldy - y);
                (* pWin->backStorage->TranslateBackingStore) (pWin, 
							      oldx - x, oldy - y);
	    }
            oldpt.x = oldx - x + pWin->absCorner.x;
	    oldpt.y = oldy - y + pWin->absCorner.y;
	    (* pWin->CopyWindow)(pWin, oldpt, oldRegion);

	    /* Note that oldRegion is *translated* by CopyWindow */

	    (* pScreen->Subtract)(pWin->exposed, pWin->clipList, oldRegion);
	    (* pScreen->Subtract)(pParent->exposed, pParent->exposed, 
				  pWin->borderSize);
	    (* pScreen->RegionDestroy)(pRegion);
	    if (!XYSame && (IS←VALID←PIXMAP(pWin->backgroundTile )))
			/* tile was "rotated" so redraw entire thing */
	        (* pScreen->Subtract)(pWin->borderExposed, 
			 pWin->borderClip, pWin->winSize);
	    HandleExposures(pParent);
	    (* pScreen->RegionDestroy)(oldRegion);
	}
    }
}

static void
ChangeBorderWidth(pWin, width)
    WindowPtr pWin;
    int width;
{
    WindowPtr pParent;
    BoxRec box;
    BoxPtr pBox;
    int oldwidth;
    Bool anyMarked;
    register ScreenPtr pScreen;
    RegionPtr oldRegion;
    DDXPointRec oldpt;
    Bool WasMapped = (Bool)(pWin->realized);

    oldwidth = pWin->borderWidth;
    if (oldwidth == width) 
        return ;
    pScreen = pWin->drawable.pScreen;
    pParent = pWin->parent;
    pWin->borderWidth = width;

    oldpt.x = pWin->absCorner.x;
    oldpt.y = pWin->absCorner.y;
    pWin->oldAbsCorner.x = oldpt.x;
    pWin->oldAbsCorner.y = oldpt.y;

    pWin->clientWinSize.x += width - oldwidth;
    pWin->clientWinSize.y += width - oldwidth;
    pWin->absCorner.x += width - oldwidth;
    pWin->absCorner.y += width - oldwidth;

    if (WasMapped)
    {
        oldRegion = (* pScreen->RegionCreate)((BoxPtr)NULL, 1);
        (* pScreen->RegionCopy)(oldRegion, pWin->borderClip);
    }


    box.x1 = pWin->absCorner.x;
    box.y1 = pWin->absCorner.y;
    box.x2 = box.x1 + pWin->clientWinSize.width;
    box.y2 = box.y1 + pWin->clientWinSize.height;
    (* pScreen->RegionReset)(pWin->winSize, &box);
    (* pScreen->Intersect)(pWin->winSize, pWin->winSize, pParent->winSize);

    if (width)
    {
	box.x1 -= width;
	box.y1 -= width;
	box.x2 += width;
	box.y2 += width;
	(* pScreen->RegionReset)(pWin->borderSize, &box);
        (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize, 
			       pParent->winSize);
    }
    else
        (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize);

    if (WasMapped)
    {
        if (width < oldwidth)
            pBox = (* pScreen->RegionExtents)(oldRegion);
        else        
            pBox = (* pScreen->RegionExtents)(pWin->borderSize);
        anyMarked = MarkSiblingsBelowMe(pWin, pBox, TRUE);

        (* pScreen->ValidateTree)(pParent,(anyMarked ? pWin : (WindowPtr)NULL),
					     TRUE, anyMarked );  

        (* pWin->CopyWindow)(pWin, oldpt, oldRegion);

        if (width > oldwidth)
        {
            DoObscures(pParent);
	    (* pScreen->Subtract)(pWin->borderExposed,
				  pWin->borderClip, pWin->winSize);
    	    (* pWin->PaintWindowBorder)(pWin, pWin->borderExposed, PW←BORDER);
	    (* pScreen->RegionEmpty)(pWin->borderExposed);
	}
	else if (oldwidth > width)
            HandleExposures(pParent);

	(* pScreen->RegionDestroy)(oldRegion);

    }
}


/*****
 * ConfigureWindow
 *****/

#define GET←INT16(m, f) \
  	if (m & mask) \
          { \
             f = (short) *pVlist;\
 	    pVlist++; \
         }
#define GET←CARD16(m, f) \
 	if (m & mask) \
         { \
            f = (CARD16) *pVlist;\
 	    pVlist++;\
         }

#define GET←CARD8(m, f) \
 	if (m & mask) \
         { \
            f = (CARD8) *pVlist;\
 	    pVlist++;\
         }

#define ChangeMask (CWX | CWY | CWWidth | CWHeight)

#define IllegalInputOnlyConfigureMask (CWBorderWidth)

/* returns Above if pSib above pMe in stack or Below otherwise */

static Bool
WhereIsSiblingWithRespectToMe(pMe, pSib, above)
    WindowPtr pMe, pSib;
    int *above;
{
    WindowPtr pWin;

    *above = Above;
    pWin = pMe->parent->firstChild;
    while (pWin)
    {
        if (pWin == pSib)
            return(TRUE);
        if (pWin == pMe)
            *above = Below;
        pWin = pWin->nextSib;
    }
    return(FALSE);
}

static Bool
AnyWindowOverlapsMe(pWin, box)
    WindowPtr pWin;
    BoxPtr box;
{
    WindowPtr pSib;
    register ScreenPtr pScreen;

    pSib = pWin->parent->firstChild;
    pScreen = pWin->drawable.pScreen;
    while (pSib)
    {
        if (pSib == pWin)
            return(FALSE);
        else if ((pSib->mapped) && 
		 ((* pScreen->RectIn)(pSib->borderSize, box) != rgnOUT))
            return(TRUE);
        pSib = pSib->nextSib;
    }
    return(FALSE);
}

static WindowPtr
IOverlapAnyWindow(pWin, box)
    WindowPtr pWin;
    BoxPtr box;
{
    WindowPtr pSib;
    register ScreenPtr pScreen;

    pScreen = pWin->drawable.pScreen;
    pSib = pWin->nextSib;
    while (pSib)
    {
        if ((pSib->mapped) &&
	    ((* pScreen->RectIn)(pSib->borderSize, box) != rgnOUT))
            return(pSib);
        pSib = pSib->nextSib;
    }
    return((WindowPtr )NULL);
}


static WindowPtr 
WhereDoIGoInTheStack(pWin, pSib, x, y, w, h, smode, above)
    WindowPtr pWin, pSib;
    short x, y, w, h;
    int smode;
    int *above;     /* return value: if Above, put pWin before pSib, if
		       Below, put pSib before pWin */
{
    BoxRec box;
    register ScreenPtr pScreen;

    *above = smode;
    if ((pWin == pWin->parent->firstChild) && 
	(pWin == pWin->parent->lastChild))
        return((WindowPtr ) NULL);
    pScreen = pWin->drawable.pScreen;
    box.x1 = x;
    box.y1 = y;
    box.x2= x + w;
    box.y2 = y + h;
    switch (smode)
    {
      case Above:
        if (pSib)
           return(pSib);
        else if (pWin == pWin->parent->firstChild)
            return(pWin->nextSib);
        else
            return(pWin->parent->firstChild);
        break;
      case Below:
        if (pSib)
            return(pSib);
        else
            return((WindowPtr )NULL);
        break;
      case TopIf:
      case Opposite:
        if (pSib)
	{
            WhereIsSiblingWithRespectToMe(pWin, pSib, above);
            if ((*above == Above) && 
		((* pScreen->RectIn)(pSib->borderSize, &box) != rgnOUT))
                return(pSib);
	    else if ((smode == Opposite) && 
                 ((*above == Below)&& 
		  ((* pScreen->RectIn)(pSib->borderSize, &box) != rgnOUT)))
		return(pSib);
            else
	    {
		*above = Above;
		return(pSib->nextSib);
	    }
	}
        else if (AnyWindowOverlapsMe(pWin, &box))
	{
	    *above = Above;
            return(pWin->parent->firstChild);
	}
        else  if (smode == TopIf) 
        {
	    *above = Above;
            return(pWin->nextSib);
	}
      case BottomIf:
        if (pSib)
	{
            WhereIsSiblingWithRespectToMe(pWin, pSib, above);
            if ((*above == Below) && 
		((* pScreen->RectIn)(pSib->borderSize, &box) != rgnOUT))
                return(pSib);
            else
                return(pWin->nextSib);
	}
        else if (IOverlapAnyWindow(pWin, &box))
	{
	    *above = Above;
            return((WindowPtr )NULL);
	}
        else
        {
	    *above = Below;
            return(pWin->nextSib);
	}
        break;
    }
    return((WindowPtr)NULL);
}

static void
ReflectStackChange(pWin, pSib, above)
    WindowPtr pWin, pSib;
    int above;
{
/* Note that pSib might be NULL */

    Bool doValidation = (Bool)pWin->realized;
    WindowPtr pParent;
    int anyMarked;
    BoxPtr box;

    /* if this is a root window, can't be restacked */
    if (!(pParent = pWin->parent))
        return ;

    if (doValidation)
    {

        box = (* pWin->drawable.pScreen->RegionExtents)(pWin->borderSize);
        anyMarked = MarkChildren(pParent, box, FALSE);
    }
    if (!pSib || (above == Above))
        MoveWindowInStack(pWin, pSib);
    else
        MoveWindowInStack(pSib, pWin);
    if (doValidation)
    {
        (* pWin->drawable.pScreen->ValidateTree)(pParent, 
					 (anyMarked ? (WindowPtr)NULL : pWin), 
					 TRUE, anyMarked);
	DoObscures(pParent);
	HandleExposures(pParent);
    }
}


int 
ConfigureWindow(pWin, mask, vlist, client)
    WindowPtr pWin;
    unsigned long mask;
    long *vlist;
    ClientPtr client;
{
    WindowPtr pSib = (WindowPtr )NULL;
    Window sibwid;
    long index, tmask;
    long *pVlist;
    short x,   y;
    unsigned short w = pWin->clientWinSize.width,
                   h = pWin->clientWinSize.height,
	           bw = pWin->borderWidth;
    int action, above, 
        smode = Above;
    xEvent event;

    if ((pWin->class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
        return(BadMatch);

    if ((mask & CWSibling) && !(mask & CWStackMode))
        return(BadWindow);

    pVlist = vlist;

    if (pWin->parent)
    {
        x = pWin->absCorner.x - pWin->parent->absCorner.x - bw;
        y = pWin->absCorner.y - pWin->parent->absCorner.y - bw;
    }
    else
    {
        x = pWin->absCorner.x;
        y = pWin->absCorner.y;
    }

    action = 0;	
    if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
    {
	GET←INT16(CWX, x);
 	GET←INT16(CWY, y);
	action = 1;
    }
	/* or should be resized */
    else if (mask & (CWX |  CWY | CWWidth | CWHeight))
    {
	GET←INT16(CWX, x);
	GET←INT16(CWY, y);
	GET←CARD16(CWWidth, w);
	GET←CARD16 (CWHeight, h);
	if (!w || !h)
            return BadValue;
        action = 2;
    }
    tmask = mask & ~ChangeMask;
    while (tmask) 
    {
	index = ffs(tmask) - 1;
	tmask &= ~(index = (1 << index));
	switch (index) 
        {
          case CWBorderWidth:   
	    GET←CARD16(CWBorderWidth, bw);
	    break;
          case CWSibling: 
	    sibwid = (Window ) *pVlist;
	    pVlist++;
            pSib = (WindowPtr )LookupID(sibwid, RT←WINDOW, RC←CORE);
            if (!pSib)
                return(BadWindow);
            if (pSib->parent != pWin->parent)
		return(BadMatch);
	    break;
          case CWStackMode:
	    GET←CARD8(CWStackMode, smode);
	    if ((smode != TopIf) && (smode != BottomIf) &&
 		(smode != Opposite) && (smode != Above) && (smode != Below))
                   return(BadMatch);
	    break;
	  default: 
	    return(BadMatch);
	}
    }
        /* then figure out if the window should be moved.  Doesnt
           make the changes to the window if event sent */

    if (mask & CWStackMode)
        pSib = WhereDoIGoInTheStack(pWin, pSib, x, y, w, h, smode, &above);
    else
    {
	above = Above;
        pSib = pWin->nextSib;
    }

    if ((!pWin->overrideRedirect) && 
        (pWin->parent->allEventMasks & SubstructureRedirectMask))
    {
	event.u.u.type = ConfigureRequest;
	event.u.configureRequest.window = pWin->wid;
	event.u.configureRequest.parent = pWin->parent->wid;
        if (pSib)
	   event.u.configureRequest.aboveSibling = pSib->wid;
        else
       	    event.u.configureRequest.aboveSibling = None;
	event.u.configureRequest.x = x;
	event.u.configureRequest.y = y;
	event.u.configureRequest.width = w;
	event.u.configureRequest.height = h;
	event.u.configureRequest.borderWidth = bw;
	if (MaybeDeliverEventsToClient(pWin->parent, &event, 1, 
	        SubstructureRedirectMask, client) == 1)
    	    return(Success);            
    }
    if ((action == 2) && (pWin->allEventMasks & ResizeRedirectMask))
    {
	xEvent event;

	event.u.u.type = ResizeRequest;
	event.u.resizeRequest.window = pWin->wid;
	event.u.resizeRequest.width = w;
	event.u.resizeRequest.height = h;
	if (MaybeDeliverEventsToClient(pWin, &event, 1, 
				       ResizeRedirectMask, client) == 1)
	{
	    w = pWin->clientWinSize.width;
	    h = pWin->clientWinSize.height;
	    if (mask & (CWX | CWY))
	        action = 1;
	    else
		action = 0;
	}
    }

    event.u.u.type = ConfigureNotify;
    event.u.configureNotify.window = pWin->wid;
    if (pSib)
        event.u.configureNotify.aboveSibling = pSib->wid;
    else
        event.u.configureNotify.aboveSibling = None;
    event.u.configureNotify.x = x;
    event.u.configureNotify.y = y;
    event.u.configureNotify.width = w;
    event.u.configureNotify.height = h;
    event.u.configureNotify.borderWidth = bw;
    event.u.configureNotify.override = pWin->overrideRedirect;
    DeliverEvents(pWin, &event, 1, NullWindow);

    if (mask & CWBorderWidth) 
    {
        if (action == 0)
            ChangeBorderWidth(pWin, (int)bw);
        else
            pWin->borderWidth = bw;
    }
    if (action == 1)
        MoveWindow(pWin, x, y, pSib, above);
    else if (action == 2)
        SlideAndSizeWindow(pWin, x, y, w, h, pSib, above);
    else if (mask & CWStackMode)
        ReflectStackChange(pWin, pSib, above);

    return(Success);
}


/******
 *
 * CirculateWindow
 *    For RaiseLowest, raises the lowest mapped child (if any) that is
 *    obscured by another child to the top of the stack.  For LowerHighest,
 *    lowers the highest mapped child (if any) that is obscuring another
 *    child to the bottom of the stack.  Exposure processing is performed 
 *
 ******/

/* XXX shouldn't this be a case for the stack mode stuff?? */

int
CirculateWindow(pParent, direction, client)
    WindowPtr pParent;
    int direction;
    ClientPtr client;
{
    WindowPtr pChild, pSib;
    xEvent event;
    register ScreenPtr pScreen;

    if (pParent->firstChild == pParent->lastChild) 
        return(Success) ;

    pScreen = pParent->drawable.pScreen;
    if (direction == RaiseLowest)
    {
        pChild = pParent->lastChild;
    	while (pChild)
	{
	    if (pChild->mapped && (pChild->visibility != VisibilityUnobscured))
	    {
                if (pParent->firstChild != pChild)
                {        
		    if (pParent->lastChild == pChild)
			pParent->lastChild = pChild->prevSib;
                    if (pChild->nextSib) 
                        pChild->nextSib->prevSib = pChild->prevSib;
                    if (pChild->prevSib) 
                        pChild->prevSib->nextSib = pChild->nextSib;
                    pChild->nextSib = pParent->firstChild;
                    pChild->prevSib = (WindowPtr ) NULL;
		    pParent->firstChild->prevSib = pChild;
                    pParent->firstChild = pChild;
		    pChild->mapped = 0;   /* to fool MapWindow */
		    pSib = pChild;
		    break;
		}
		return Success;
	    }
	    pChild = pChild->prevSib;
	}
    }
    else if (direction == LowerHighest)
    {
        BoxPtr pBox;

        pChild = pParent->firstChild;
    	while (pChild)
	{
	    if (pChild->mapped && (pChild->visibility == VisibilityUnobscured))
	    {
		int result;

                   /* HACK -- this search is n squared */

		pSib = pChild->nextSib;

                   /* find a sibling that pChild overlaps */

                pBox = (* pScreen->RegionExtents)(pChild->borderSize);
		while (pSib)
	        {
		    if (pSib->realized && (pSib->visibility != VisibilityUnobscured))
		    {
			result = (* pScreen->RectIn)(pSib->borderSize, 
					&pBox);
			if (result != rgnOUT) 
			    break;
		    }
		    pSib = pSib->nextSib;
		}
                if (pSib)
		{
		    WindowPtr pNext;
		    pNext = pChild->nextSib;
		    if (pParent->firstChild == pChild)
			pParent->firstChild = pNext;
                    pNext->prevSib = pChild->prevSib;
                    if (pChild->prevSib) 
                        pChild->prevSib->nextSib = pNext;
                    pChild->nextSib = (WindowPtr ) NULL;
                    pChild->prevSib = pParent->lastChild;
		    pParent->lastChild->nextSib = pChild;
                    pParent->lastChild = pChild;
		    pSib->mapped = 0;  /* to fool mapWindow */
    		    break;
		}
	    }
	    pChild = pChild->nextSib;
	}
    }
    if (!pChild)
        return(Success) ;
    event.u.circulate.window = pChild->wid;
    event.u.circulate.parent = pParent->wid;
    event.u.circulate.event = pParent->wid;
    if (direction == RaiseLowest)
	event.u.circulate.place = PlaceOnTop;
    else
        event.u.circulate.place = PlaceOnBottom;

    if ((!pParent->overrideRedirect) && 
        (pParent->allEventMasks & SubstructureRedirectMask))
    {
	event.u.u.type = CirculateRequest;
	if (MaybeDeliverEventsToClient(pParent, &event, 1, 
	        SubstructureRedirectMask, client) == 1)
    	    return(Success);            
    }
    if (pParent->realized)
        MapWindow(pSib, HANDLE←EXPOSURES, BITS←DISCARDED,
	      DONT←SEND←NOTIFICATION, client);
    event.u.u.type = CirculateNotify;
    DeliverEvents(pParent, &event, 1, NullWindow);
    return(Success);
}

/*****
 *  ReparentWindow
 *****/

static int
CompareWIDs(pWin, wid)
    WindowPtr pWin;
    int *wid;
{
    if (pWin->wid == *wid) 
       return(WT←STOPWALKING);
    else
       return(WT←WALKCHILDREN);
}

int 
ReparentWindow(pWin, pParent, x, y, client)
    WindowPtr pWin, pParent;
    short x,y;
    ClientPtr client;
{
    WindowPtr pPrev;
    Bool WasMapped = (Bool)(pWin->realized);
    BoxRec box;
    xEvent event;
    short oldx, oldy;
    int bw;
    register ScreenPtr pScreen;
    
    if (pWin == pParent) return(BadWindow);
    if (TraverseTree(pWin, CompareWIDs, &pParent->wid) == WT←STOPWALKING)
        return(BadWindow);		

    pScreen = pWin->drawable.pScreen;
    event.u.u.type = ReparentNotify;
    event.u.reparent.window = pWin->wid;
    event.u.reparent.parent = pParent->wid;
    event.u.reparent.x = x;
    event.u.reparent.y = y;
    event.u.reparent.override = pWin->overrideRedirect;
    DeliverEvents(pWin, &event, 1, pParent);

    oldx = pWin->absCorner.x;
    oldy = pWin->absCorner.y;
    if (WasMapped) 
       UnmapWindow(pWin, HANDLE←EXPOSURES, SEND←NOTIFICATION, FALSE);

    /* take out of sibling chain */

    pPrev = pWin->parent;
    if (pPrev->firstChild == pWin)
        pPrev->firstChild = pWin->nextSib;
    if (pPrev->lastChild == pWin)
        pPrev->lastChild = pWin->prevSib;

    if (pWin->nextSib) 
        pWin->nextSib->prevSib = pWin->prevSib;
    if (pWin->prevSib) 
        pWin->prevSib->nextSib = pWin->nextSib;

    /* insert at begining of pParent */
    pWin->parent = pParent;
    pWin->nextSib = pParent->firstChild;
    pWin->prevSib = (WindowPtr )NULL;
    if (pParent->firstChild) 
	pParent->firstChild->prevSib = pWin;
    else
        pParent->lastChild = pWin;
    pParent->firstChild = pWin;

    /* clip to parent */
    box.x1 = x + pParent->absCorner.x;
    box.y1 = y + pParent->absCorner.y;
    box.x2 = box.x1 + pWin->clientWinSize.width;
    box.y2 = box.y1+ pWin->clientWinSize.height;
    (* pScreen->RegionReset)(pWin->winSize, &box);
    (* pScreen->Intersect)(pWin->winSize, pWin->winSize, 
					  pParent->winSize); 

    pWin->clientWinSize.x = x;
    pWin->clientWinSize.y = y;
    pWin->oldAbsCorner.x = oldx;
    pWin->oldAbsCorner.y = oldy;
    pWin->absCorner.x = box.x1;
    pWin->absCorner.y = box.y1;

    if (bw = pWin->borderWidth)
    {
	box.x1 -= bw;
	box.y1 -= bw;
	box.x2 += bw;
	box.y2 += bw;
	(* pScreen->RegionReset)(pWin->borderSize, &box);
        (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize, 
			       pParent->winSize);
    }
    else
        (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize);

    (* pScreen->PositionWindow)(pWin,
					      pWin->absCorner.x,
					      pWin->absCorner.y);
    fixChildrenWinSize(pWin);

    if (WasMapped)    
    {
	(*pScreen->Union)(pParent->clipList, 
			   pWin->borderSize, pParent->clipList);
	(*pScreen->Union)(pPrev->clipList, pWin->borderSize,
			   pPrev->clipList);
	(* pScreen->RegionCopy)(pPrev->exposed, pWin->borderSize);    
	
        MapWindow(pWin, HANDLE←EXPOSURES, BITS←DISCARDED, SEND←NOTIFICATION,
	                                    client);
    }
    RecalculateDeliverableEvents(pParent);
    return(Success);
}

static int
MarkChildren(pWin, box, unionParent)
    WindowPtr pWin;
    BoxPtr box;
    Bool unionParent;
{
    WindowPtr pChild;
    int anyMarked=0;
    register ScreenPtr pScreen;

    pScreen = pWin->drawable.pScreen;
    pChild = pWin->firstChild;
    while (pChild) 
    {
        if (pChild->mapped && ((* pScreen->RectIn)(pChild->borderSize, box)))
        {
	    if (!pChild->marked)
	    {
                (*pScreen->Union)(pWin->clipList, pChild->borderClip,
	    	   pWin->clipList);
                if (unionParent)
	            (*pScreen->Union)(pWin->exposed, 
				   pWin->exposed, pChild->borderClip);    
	    }
            anyMarked++;
	    pChild->marked = 1;
	    anyMarked += MarkChildren(pChild, box, unionParent);
	}
	pChild = pChild->nextSib;
    }
    return(anyMarked);
}

int
MarkSiblingsBelowMe(pWin, box, unionParent)
    WindowPtr pWin;
    BoxPtr box;
    Bool unionParent;
{
    WindowPtr pSib, pParent;
    int anyMarked = 0;
    register ScreenPtr pScreen;

    pScreen = pWin->drawable.pScreen;
    pParent = pWin->parent;

    pSib = pWin;
    while (pSib) 
    {
        if (pSib->mapped && ((* pScreen->RectIn)(pSib->borderSize, box)))
        {
	    if (pParent && (!pSib->marked))
	    {
		(*pScreen->Union)(pParent->clipList,      
			   pSib->borderClip, pParent->clipList);
		if (unionParent)
	            (* pScreen->Union)(pParent->exposed, 
				   pParent->exposed, pSib->borderClip);    
	    }
	    pSib->marked = 1;
	    anyMarked++;
            if (pSib->firstChild)
    	        anyMarked += MarkChildren(pSib, box, unionParent);
	}
	pSib = pSib->nextSib;
    }
    return(anyMarked);
}    


/*****
 * MapWindow
 *    If some other client has selected SubStructureReDirect on the parent
 *    and override-redirect is xFalse, then a MapRequest event is generated,
 *    but the window remains unmapped.  Otherwise, the window is mapped and a
 *    MapNotify event is generated.
 *****/

static void
RealizeChildren(pWin, client)
    WindowPtr pWin;
    ClientPtr client;
{
    WindowPtr pSib;
    Bool (* Realize)();

    pSib = pWin;
    if (pWin)
       Realize = pSib->drawable.pScreen->RealizeWindow;
    while (pSib)
    {
        if (pSib->mapped)
	{
	    pSib->realized = TRUE;
            pSib->viewable = pSib->class == InputOutput;
            (* Realize)(pSib);
	    FlushClientCaches(pSib->wid);
            if (pSib->firstChild) 
                RealizeChildren(pSib->firstChild, client);
	}
        pSib = pSib->nextSib;
    }
}

int
MapWindow(pWin, SendExposures, BitsAvailable, SendNotification, client)

    WindowPtr pWin;
    Bool SendExposures;
    Bool BitsAvailable;
    ClientPtr client;
{
    register ScreenPtr pScreen;

    WindowPtr pParent;
    Bool anyMarked;

    if (pWin->mapped) 
        return(Success);
    pScreen = pWin->drawable.pScreen;
    if (pParent = pWin->parent)
    {
        xEvent event;
        BoxPtr box;

        if (SendNotification && (!pWin->overrideRedirect) && 
	    (pParent->allEventMasks & SubstructureRedirectMask))
	{
	    event.u.u.type = MapRequest;
	    event.u.mapRequest.window = pWin->wid;
	    event.u.mapRequest.parent = pParent->wid;

	    if (MaybeDeliverEventsToClient(pParent, &event, 1, 
	        SubstructureRedirectMask, client) == 1)
    	        return(Success);            
	}

	pWin->mapped = 1;          
        if (SendNotification)
	{
	    event.u.u.type = MapNotify;
	    event.u.mapNotify.window = pWin->wid;
	    event.u.mapNotify.override = pWin->overrideRedirect;
	    DeliverEvents(pWin, &event, 1, NullWindow);
	}

	pWin->marked = 0;         /* so siblings get mapped correctly */


        if (!pParent->realized)
            return(Success);
        pWin->realized = TRUE;
        pWin->viewable = pWin->class == InputOutput;
        (* pScreen->RealizeWindow)(pWin);
        if (pWin->firstChild)
            RealizeChildren(pWin->firstChild, client);    
        box = (* pScreen->RegionExtents)(pWin->borderSize);
        anyMarked = MarkSiblingsBelowMe(pWin, box, FALSE);
	(* pScreen->ValidateTree)(pParent, pWin, TRUE, anyMarked);
        if (SendExposures) 
        {
	    if (!BitsAvailable)
	    {
    	        (* pScreen->RegionCopy)(pWin->exposed, pWin->clipList);  
		DoObscures(pParent);
		HandleExposures(pWin);
	    }
	    else
	    {
                (* pScreen->Subtract)(pParent->exposed, pParent->exposed, 
				      pWin->borderSize);
                (* pScreen->RegionEmpty)(pWin->exposed);
		DoObscures(pParent);
		HandleExposures(pWin);
	    }
	}
    }
    else
    {
	pWin->mapped = 1;
        pWin->realized = TRUE;     /* for roots */
        pWin->viewable = pWin->class == InputOutput;
        (* pScreen->RealizeWindow)(pWin);
    }
    
    return(Success);
}

 
/*****
 * MapSubwindows
 *    Performs a MapWindow all unmapped children of the window, in top
 *    to bottom stacking order.
 *****/

MapSubwindows(pWin, SendExposures, client)
    WindowPtr pWin;
    Bool SendExposures;
    ClientPtr client;
{
    WindowPtr pChild;

    pChild = pWin->firstChild;
    while (pChild) 
    {
	if (!pChild->mapped) 
            MapWindow(pChild, SendExposures, BITS←DISCARDED, 
		      SEND←NOTIFICATION, client);
        pChild = pChild->nextSib;
    }
}

/*****
 * UnmapWindow
 *    If the window is already unmapped, this request has no effect.
 *    Otherwise, the window is unmapped and an UnMapNotify event is
 *    generated.  Cannot unmap a root window.
 *****/
 
static void
UnrealizeChildren(pWin)
    WindowPtr pWin;
{
    WindowPtr pSib;
    void (*RegionEmpty)();
    Bool (*Unrealize)();
    
    pSib = pWin;
    if (pWin)
    {
        RegionEmpty = pWin->drawable.pScreen->RegionEmpty;
        Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
    }
    while (pSib)
    {
	pSib->realized = pSib->viewable = FALSE;
        (* Unrealize)(pSib);
	        /* to force exposures later */
        (* RegionEmpty)(pSib->clipList);    
        (* RegionEmpty)(pSib->borderClip);
	(* RegionEmpty)(pSib->exposed);
	pWin->drawable.serialNumber = NEXT←SERIAL←NUMBER;
        DeleteWindowFromAnyEvents(pSib, FALSE);
        if (pSib->firstChild) 
            UnrealizeChildren(pSib->firstChild);
        pSib = pSib->nextSib;
    }
}

UnmapWindow(pWin, SendExposures, SendNotification, fromConfigure)
    WindowPtr pWin;
    Bool SendExposures, fromConfigure;
{
    WindowPtr pParent;
    xEvent event;
    Bool anyMarked;
    Bool wasMapped = (Bool)pWin->realized;
    BoxPtr box;

    if ((!pWin->mapped) || (!(pParent = pWin->parent))) 
        return(Success);
    if (SendNotification)
    {
	event.u.u.type = UnmapNotify;
	event.u.unmapNotify.window = pWin->wid;
	event.u.unmapNotify.fromConfigure = fromConfigure;
	DeliverEvents(pWin, &event, 1, NullWindow);
    }
    if (wasMapped)
    {
        box = (* pWin->drawable.pScreen->RegionExtents)(pWin->borderSize);
        anyMarked = MarkSiblingsBelowMe(pWin, box, TRUE);
    }
    pWin->mapped = 0;
    pWin->realized = pWin->viewable = FALSE;
    if (wasMapped)
    {
        (* pWin->drawable.pScreen->UnrealizeWindow)(pWin);
        DeleteWindowFromAnyEvents(pWin, FALSE);
        if (pWin->firstChild)
            UnrealizeChildren(pWin->firstChild);
        (* pWin->drawable.pScreen->ValidateTree)(pParent, pWin, 
						 TRUE, anyMarked);
        if (SendExposures)
        {
            void (* RegionEmpty)();

            RegionEmpty = pWin->drawable.pScreen->RegionEmpty;
            (* RegionEmpty)(pWin->clipList);   /* to force expsoures later */
            (* RegionEmpty)(pWin->borderClip);
            (* RegionEmpty)(pWin->borderExposed);
            (* RegionEmpty)(pWin->exposed);      
	    pWin->drawable.serialNumber = NEXT←SERIAL←NUMBER;
	    HandleExposures(pParent);
	}
    }        
    return(Success);
}

/*****
 * UnmapSubwindows
 *    Performs an UnMapWindow request with the specified mode on all mapped
 *    children of the window, in bottom to top stacking order.
 *****/

UnmapSubwindows(pWin, sendExposures)
    WindowPtr pWin;
    Bool sendExposures;
{
    WindowPtr pChild;
    xEvent event;
    Bool anyMarked = TRUE;
    void (*RegionEmpty)();
    Bool (*UnrealizeWindow)();
    Bool wasMapped = (Bool)pWin->realized;

    pChild = pWin->lastChild;
    event.u.u.type = UnmapNotify;
    event.u.unmapNotify.fromConfigure = xFalse;
    RegionEmpty = pWin->drawable.pScreen->RegionEmpty;
    UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;    
    while (pChild) 
    {
	if (pChild->mapped) 
        {
	    event.u.unmapNotify.window = pChild->wid;
	    event.u.unmapNotify.fromConfigure = xFalse;
	    DeliverEvents(pWin, &event, 1, NullWindow);
	    pChild->mapped = 0;
            if (wasMapped)
	    {
    	        pChild->realized = pChild->viewable = FALSE;
                (* UnrealizeWindow)(pChild);
	        if (pChild->firstChild)
                    UnrealizeChildren(pChild->firstChild);
                DeleteWindowFromAnyEvents(pChild, FALSE);
	        (* RegionEmpty)(pChild->clipList);/* to force expsoures later*/
    	        (* RegionEmpty)(pChild->borderClip);
	        (* RegionEmpty)(pChild->borderExposed);
	        (* RegionEmpty)(pChild->exposed);      
	        pChild->drawable.serialNumber = NEXT←SERIAL←NUMBER;
	    }
	}
        pChild = pChild->prevSib;
    }
    if ((pWin->lastChild) && wasMapped)
    {
/*	
        (* pWin->drawable.pScreen->ValidateTree)(pWin, NULL, TRUE, anyMarked);
*/
        (* pWin->drawable.pScreen->Intersect)(pWin->clipList,
				      pWin->winSize, pWin->borderClip);
        (* pWin->drawable.pScreen->RegionCopy)(pWin->exposed, pWin->clipList);
        HandleExposures(pWin);    		
    }
}


void
HandleSaveSet(client)
    ClientPtr client;
{
    WindowPtr pParent, pWin;
    int j;

    for (j=0; j<client->numSaved; j++)
    {
        pWin = (WindowPtr)client->saveSet[j]; 
        pParent = pWin->parent;
        while (pParent && (pParent->client == client))
            pParent = pParent->parent;
        if (pParent)
	{
            ReparentWindow(pWin, pParent, pWin->absCorner.x, 
			   pWin->absCorner.y, client);
	    if(!pWin->realized && pWin->mapped)
		pWin->mapped = FALSE;
            MapWindow(pWin, HANDLE←EXPOSURES, BITS←DISCARDED,
	                    SEND←NOTIFICATION, client);
	}
    }
}
    
Bool
VisibleBoundingBoxFromPoint(pWin, x, y, box)
    WindowPtr pWin;
    int x, y;   /* in root */
    BoxPtr box;   /* "return" value */
{
    if (!pWin->realized)
	return (FALSE);
    if ((* pWin->drawable.pScreen->PointInRegion)(pWin->clipList, x, y, box))
        return(TRUE);
    return(FALSE);
}

Bool
PointInWindowIsVisible(pWin, x, y)
    WindowPtr pWin;
    int x, y;	/* in root */
{
    BoxRec box;

    if (!pWin->realized)
	return (FALSE);
    if ((* pWin->drawable.pScreen->PointInRegion)(pWin->clipList, x, y, &box))
        return(TRUE);
    return(FALSE);
}


RegionPtr 
NotClippedByChildren(pWin)
    WindowPtr pWin;
{
    register ScreenPtr pScreen;
    RegionPtr pReg;

    pScreen = pWin->drawable.pScreen;
    pReg = (* pScreen->RegionCreate)((BoxPtr)NULL, 1);
    if (pWin->firstChild)
        (* pScreen->Intersect)(pReg, pWin->winSize, pWin->borderClip);
    else
        (* pScreen->RegionCopy)(pReg, pWin->clipList);
    return(pReg);
}


void
SendVisibilityNotify(pWin)
    WindowPtr pWin;
{
    xEvent event;
    event.u.u.type = VisibilityNotify;
    event.u.visibility.window = pWin->wid;
    event.u.visibility.state = pWin->visibility;
    DeliverEvents(pWin, &event, 1, NullWindow);
}


#define RANDOM←WIDTH 32

void
SaveScreens(on, mode)
    int on;
    int mode;
{
    int i, j;
    int what;
    unsigned char *srcbits, *mskbits;

    if (on == SCREEN←SAVER←FORCER)
    {
        if (mode == ScreenSaverReset)
            what = SCREEN←SAVER←OFF;
        else               
           what = SCREEN←SAVER←ON;
	if (what == screenIsSaved)
            return ;
    }
    else
        what = on;
    for (i = 0; i < screenInfo.numScreens; i++)
    {
        if (on == SCREEN←SAVER←FORCER)
        {
           (* screenInfo.screen[i].SaveScreen) (&screenInfo.screen[i], on);
        }
        if (what == SCREEN←SAVER←OFF)
        {
	    if (savedScreenInfo[i].blanked == SCREEN←IS←BLANKED)
	    {
	       (* screenInfo.screen[i].SaveScreen) (&screenInfo.screen[i], on);
	    }
            else if (savedScreenInfo[i].blanked == SCREEN←IS←TILED)
	    {
    	        FreeResource((long)savedScreenInfo[i].wid, RC←NONE);
                savedScreenInfo[i].pWindow = (WindowPtr)NULL;
	    }
	    continue;
        }
        else if (what == SCREEN←SAVER←ON) 
        {
            if (screenIsSaved == SCREEN←SAVER←ON)  /* rotate pattern */
            {
	        int new←x, new←y;

		if (savedScreenInfo[i].blanked == SCREEN←IS←TILED)
	        {
	            new←x = random() % RANDOM←WIDTH;
	            new←y = random() % RANDOM←WIDTH;
	            MoveWindow(savedScreenInfo[i].pWindow, -new←x, -new←y, 
		               savedScreenInfo[i].pWindow->nextSib, Above);
		}
		continue;
	    }
            if (ScreenSaverBlanking != DontPreferBlanking) 
	    {
	       if ((* screenInfo.screen[i].SaveScreen)
		   (&screenInfo.screen[i], what))
	       {
	           savedScreenInfo[i].blanked = SCREEN←IS←BLANKED;
                   continue;
	       }
	    }
            if (ScreenSaverAllowExposures != DontAllowExposures)
            {
                int result;
                long attributes[1];
	        int mask = CWBackPixmap;
                WindowPtr pWin;		
		CursorMetricRec cm;
                
                if (WindowTable[i].backgroundTile == 
		    (PixmapPtr)USE←BACKGROUND←PIXEL)
		{
                    attributes[0] = WindowTable[i].backgroundPixel;
		    mask = CWBackPixel;
		}
                else
                    attributes[0] = None;

                pWin = savedScreenInfo[i].pWindow = 
		     CreateWindow(savedScreenInfo[i].wid,
		     &WindowTable[i], 
		     -RANDOM←WIDTH, -RANDOM←WIDTH,
		     (unsigned short)screenInfo.screen[i].width + RANDOM←WIDTH, 
		     (unsigned short)screenInfo.screen[i].height + RANDOM←WIDTH,
		     0, InputOutput, mask, attributes, 0, 0, 
		     WindowTable[i].visual, &result);
                if (attributes[0] == None)
		{
		    
		    pWin->backgroundTile = pWin->parent->backgroundTile;
		    pWin->backgroundTile->refcnt++;
		    (* screenInfo.screen[i].ChangeWindowAttributes)
				(pWin, CWBackPixmap);
		}
	        AddResource(pWin->wid, RT←WINDOW, 
			(pointer)savedScreenInfo[i].pWindow,
			DeleteWindow, RC←CORE);
		cm.width=32;
		cm.height=16;
		cm.xhot=8;
		cm.yhot=8;
                srcbits = (unsigned char *)Xalloc( PixmapBytePad(32, 1)*16); 
		mskbits = (unsigned char *)Xalloc( PixmapBytePad(32, 1)*16); 
                for (j=0; j<PixmapBytePad(32, 1)*16; j++)
    	            srcbits[j] = mskbits[j] = 0x0;
		pWin->cursor = AllocCursor( srcbits, mskbits, &cm,
		    ~0, ~0, ~0, 0, 0, 0);
		AddResource(savedScreenInfo[i].cid, RT←CURSOR,
			(pointer)pWin->cursor,
			FreeCursor, RC←CORE);	
	        pWin->overrideRedirect = TRUE;
                MapWindow(pWin, TRUE, FALSE, FALSE, (ClientPtr)0);
	        savedScreenInfo[i].blanked = SCREEN←IS←TILED;
	    }
            else
	        savedScreenInfo[i].blanked = SCREEN←ISNT←SAVED;
	}
    }
    screenIsSaved = what; 
}