window.c revision 05b261ec
105b261ecSmrg/*
205b261ecSmrg
305b261ecSmrgCopyright (c) 2006, Red Hat, Inc.
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its
605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that
705b261ecSmrgthe above copyright notice appear in all copies and that both that
805b261ecSmrgcopyright notice and this permission notice appear in supporting
905b261ecSmrgdocumentation.
1005b261ecSmrg
1105b261ecSmrgThe above copyright notice and this permission notice shall be included in
1205b261ecSmrgall copies or substantial portions of the Software.
1305b261ecSmrg
1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1705b261ecSmrgRED HAT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
1805b261ecSmrgIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2005b261ecSmrg
2105b261ecSmrgExcept as contained in this notice, the name of Red Hat shall not be
2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings
2305b261ecSmrgin this Software without prior written authorization from Red Hat.
2405b261ecSmrg
2505b261ecSmrgCopyright 1987, 1998  The Open Group
2605b261ecSmrg
2705b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its
2805b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that
2905b261ecSmrgthe above copyright notice appear in all copies and that both that
3005b261ecSmrgcopyright notice and this permission notice appear in supporting
3105b261ecSmrgdocumentation.
3205b261ecSmrg
3305b261ecSmrgThe above copyright notice and this permission notice shall be included
3405b261ecSmrgin all copies or substantial portions of the Software.
3505b261ecSmrg
3605b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
3705b261ecSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3805b261ecSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
3905b261ecSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
4005b261ecSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
4105b261ecSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
4205b261ecSmrgOTHER DEALINGS IN THE SOFTWARE.
4305b261ecSmrg
4405b261ecSmrgExcept as contained in this notice, the name of The Open Group shall
4505b261ecSmrgnot be used in advertising or otherwise to promote the sale, use or
4605b261ecSmrgother dealings in this Software without prior written authorization
4705b261ecSmrgfrom The Open Group.
4805b261ecSmrg
4905b261ecSmrg
5005b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
5105b261ecSmrg
5205b261ecSmrg			All Rights Reserved
5305b261ecSmrg
5405b261ecSmrgPermission to use, copy, modify, and distribute this software and its
5505b261ecSmrgdocumentation for any purpose and without fee is hereby granted,
5605b261ecSmrgprovided that the above copyright notice appear in all copies and that
5705b261ecSmrgboth that copyright notice and this permission notice appear in
5805b261ecSmrgsupporting documentation, and that the name of Digital not be
5905b261ecSmrgused in advertising or publicity pertaining to distribution of the
6005b261ecSmrgsoftware without specific, written prior permission.
6105b261ecSmrg
6205b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
6305b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
6405b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
6505b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
6605b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
6705b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
6805b261ecSmrgSOFTWARE.
6905b261ecSmrg
7005b261ecSmrg*/
7105b261ecSmrg
7205b261ecSmrg/* The panoramix components contained the following notice */
7305b261ecSmrg/*****************************************************************
7405b261ecSmrg
7505b261ecSmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
7605b261ecSmrg
7705b261ecSmrgPermission is hereby granted, free of charge, to any person obtaining a copy
7805b261ecSmrgof this software and associated documentation files (the "Software"), to deal
7905b261ecSmrgin the Software without restriction, including without limitation the rights
8005b261ecSmrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8105b261ecSmrgcopies of the Software.
8205b261ecSmrg
8305b261ecSmrgThe above copyright notice and this permission notice shall be included in
8405b261ecSmrgall copies or substantial portions of the Software.
8505b261ecSmrg
8605b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8705b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
8805b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
8905b261ecSmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
9005b261ecSmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
9105b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
9205b261ecSmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9305b261ecSmrg
9405b261ecSmrgExcept as contained in this notice, the name of Digital Equipment Corporation
9505b261ecSmrgshall not be used in advertising or otherwise to promote the sale, use or other
9605b261ecSmrgdealings in this Software without prior written authorization from Digital
9705b261ecSmrgEquipment Corporation.
9805b261ecSmrg
9905b261ecSmrg******************************************************************/
10005b261ecSmrg
10105b261ecSmrg
10205b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
10305b261ecSmrg#include <dix-config.h>
10405b261ecSmrg#endif
10505b261ecSmrg
10605b261ecSmrg#include "misc.h"
10705b261ecSmrg#include "scrnintstr.h"
10805b261ecSmrg#include "os.h"
10905b261ecSmrg#include "regionstr.h"
11005b261ecSmrg#include "validate.h"
11105b261ecSmrg#include "windowstr.h"
11205b261ecSmrg#include "input.h"
11305b261ecSmrg#include "resource.h"
11405b261ecSmrg#include "colormapst.h"
11505b261ecSmrg#include "cursorstr.h"
11605b261ecSmrg#include "dixstruct.h"
11705b261ecSmrg#include "gcstruct.h"
11805b261ecSmrg#include "servermd.h"
11905b261ecSmrg#ifdef PANORAMIX
12005b261ecSmrg#include "panoramiX.h"
12105b261ecSmrg#include "panoramiXsrv.h"
12205b261ecSmrg#endif
12305b261ecSmrg#include "dixevents.h"
12405b261ecSmrg#include "globals.h"
12505b261ecSmrg
12605b261ecSmrg#ifdef XAPPGROUP
12705b261ecSmrg#include "appgroup.h"
12805b261ecSmrg#endif
12905b261ecSmrg#include "xace.h"
13005b261ecSmrg
13105b261ecSmrg/******
13205b261ecSmrg * Window stuff for server
13305b261ecSmrg *
13405b261ecSmrg *    CreateRootWindow, CreateWindow, ChangeWindowAttributes,
13505b261ecSmrg *    GetWindowAttributes, DeleteWindow, DestroySubWindows,
13605b261ecSmrg *    HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
13705b261ecSmrg *    UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
13805b261ecSmrg *
13905b261ecSmrg ******/
14005b261ecSmrg
14105b261ecSmrgstatic unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
14205b261ecSmrgstatic unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
14305b261ecSmrg
14405b261ecSmrg_X_EXPORT int screenIsSaved = SCREEN_SAVER_OFF;
14505b261ecSmrg
14605b261ecSmrg_X_EXPORT ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
14705b261ecSmrg
14805b261ecSmrg#if 0
14905b261ecSmrgextern void DeleteWindowFromAnyEvents();
15005b261ecSmrgextern Mask EventMaskForClient();
15105b261ecSmrgextern void WindowHasNewCursor();
15205b261ecSmrgextern void RecalculateDeliverableEvents();
15305b261ecSmrg#endif
15405b261ecSmrg
15505b261ecSmrgstatic Bool TileScreenSaver(int i, int kind);
15605b261ecSmrg
15705b261ecSmrg
15805b261ecSmrg#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
15905b261ecSmrg			      CWDontPropagate | CWOverrideRedirect | CWCursor )
16005b261ecSmrg
16105b261ecSmrg#define BOXES_OVERLAP(b1, b2) \
16205b261ecSmrg      (!( ((b1)->x2 <= (b2)->x1)  || \
16305b261ecSmrg	( ((b1)->x1 >= (b2)->x2)) || \
16405b261ecSmrg	( ((b1)->y2 <= (b2)->y1)) || \
16505b261ecSmrg	( ((b1)->y1 >= (b2)->y2)) ) )
16605b261ecSmrg
16705b261ecSmrg#define RedirectSend(pWin) \
16805b261ecSmrg    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
16905b261ecSmrg
17005b261ecSmrg#define SubSend(pWin) \
17105b261ecSmrg    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
17205b261ecSmrg
17305b261ecSmrg#define StrSend(pWin) \
17405b261ecSmrg    ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
17505b261ecSmrg
17605b261ecSmrg#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
17705b261ecSmrg
17805b261ecSmrg
17905b261ecSmrg_X_EXPORT int numSaveUndersViewable = 0;
18005b261ecSmrg_X_EXPORT int deltaSaveUndersViewable = 0;
18105b261ecSmrg
18205b261ecSmrg#ifdef DEBUG
18305b261ecSmrg/******
18405b261ecSmrg * PrintWindowTree
18505b261ecSmrg *    For debugging only
18605b261ecSmrg ******/
18705b261ecSmrg
18805b261ecSmrgstatic void
18905b261ecSmrgPrintChildren(WindowPtr p1, int indent)
19005b261ecSmrg{
19105b261ecSmrg    WindowPtr p2;
19205b261ecSmrg    int i;
19305b261ecSmrg
19405b261ecSmrg    while (p1)
19505b261ecSmrg    {
19605b261ecSmrg	p2 = p1->firstChild;
19705b261ecSmrg	for (i=0; i<indent; i++) ErrorF( " ");
19805b261ecSmrg	ErrorF( "%lx\n", p1->drawable.id);
19905b261ecSmrg	miPrintRegion(&p1->clipList);
20005b261ecSmrg	PrintChildren(p2, indent+4);
20105b261ecSmrg	p1 = p1->nextSib;
20205b261ecSmrg    }
20305b261ecSmrg}
20405b261ecSmrg
20505b261ecSmrgstatic void
20605b261ecSmrgPrintWindowTree(void)
20705b261ecSmrg{
20805b261ecSmrg    int i;
20905b261ecSmrg    WindowPtr pWin, p1;
21005b261ecSmrg
21105b261ecSmrg    for (i=0; i<screenInfo.numScreens; i++)
21205b261ecSmrg    {
21305b261ecSmrg	ErrorF( "WINDOW %d\n", i);
21405b261ecSmrg	pWin = WindowTable[i];
21505b261ecSmrg	miPrintRegion(&pWin->clipList);
21605b261ecSmrg	p1 = pWin->firstChild;
21705b261ecSmrg	PrintChildren(p1, 4);
21805b261ecSmrg    }
21905b261ecSmrg}
22005b261ecSmrg#endif
22105b261ecSmrg
22205b261ecSmrg_X_EXPORT int
22305b261ecSmrgTraverseTree(WindowPtr pWin, VisitWindowProcPtr func, pointer data)
22405b261ecSmrg{
22505b261ecSmrg    int result;
22605b261ecSmrg    WindowPtr pChild;
22705b261ecSmrg
22805b261ecSmrg    if (!(pChild = pWin))
22905b261ecSmrg       return(WT_NOMATCH);
23005b261ecSmrg    while (1)
23105b261ecSmrg    {
23205b261ecSmrg	result = (* func)(pChild, data);
23305b261ecSmrg	if (result == WT_STOPWALKING)
23405b261ecSmrg	    return(WT_STOPWALKING);
23505b261ecSmrg	if ((result == WT_WALKCHILDREN) && pChild->firstChild)
23605b261ecSmrg	{
23705b261ecSmrg	    pChild = pChild->firstChild;
23805b261ecSmrg	    continue;
23905b261ecSmrg	}
24005b261ecSmrg	while (!pChild->nextSib && (pChild != pWin))
24105b261ecSmrg	    pChild = pChild->parent;
24205b261ecSmrg	if (pChild == pWin)
24305b261ecSmrg	    break;
24405b261ecSmrg	pChild = pChild->nextSib;
24505b261ecSmrg    }
24605b261ecSmrg    return(WT_NOMATCH);
24705b261ecSmrg}
24805b261ecSmrg
24905b261ecSmrg/*****
25005b261ecSmrg * WalkTree
25105b261ecSmrg *   Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
25205b261ecSmrg *   each window.  If FUNC returns WT_WALKCHILDREN, traverse the children,
25305b261ecSmrg *   if it returns WT_DONTWALKCHILDREN, dont.  If it returns WT_STOPWALKING
25405b261ecSmrg *   exit WalkTree.  Does depth-first traverse.
25505b261ecSmrg *****/
25605b261ecSmrg
25705b261ecSmrg_X_EXPORT int
25805b261ecSmrgWalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
25905b261ecSmrg{
26005b261ecSmrg    return(TraverseTree(WindowTable[pScreen->myNum], func, data));
26105b261ecSmrg}
26205b261ecSmrg
26305b261ecSmrg/* hack for forcing backing store on all windows */
26405b261ecSmrgint	defaultBackingStore = NotUseful;
26505b261ecSmrg/* hack to force no backing store */
26605b261ecSmrgBool	disableBackingStore = FALSE;
26705b261ecSmrgBool	enableBackingStore = FALSE;
26805b261ecSmrg/* hack to force no save unders */
26905b261ecSmrgBool	disableSaveUnders = FALSE;
27005b261ecSmrg
27105b261ecSmrgstatic void
27205b261ecSmrgSetWindowToDefaults(WindowPtr pWin)
27305b261ecSmrg{
27405b261ecSmrg    pWin->prevSib = NullWindow;
27505b261ecSmrg    pWin->firstChild = NullWindow;
27605b261ecSmrg    pWin->lastChild = NullWindow;
27705b261ecSmrg
27805b261ecSmrg    pWin->valdata = (ValidatePtr)NULL;
27905b261ecSmrg    pWin->optional = (WindowOptPtr)NULL;
28005b261ecSmrg    pWin->cursorIsNone = TRUE;
28105b261ecSmrg
28205b261ecSmrg    pWin->backingStore = NotUseful;
28305b261ecSmrg    pWin->DIXsaveUnder = FALSE;
28405b261ecSmrg    pWin->backStorage = (pointer) NULL;
28505b261ecSmrg
28605b261ecSmrg    pWin->mapped = FALSE;	    /* off */
28705b261ecSmrg    pWin->realized = FALSE;	/* off */
28805b261ecSmrg    pWin->viewable = FALSE;
28905b261ecSmrg    pWin->visibility = VisibilityNotViewable;
29005b261ecSmrg    pWin->overrideRedirect = FALSE;
29105b261ecSmrg    pWin->saveUnder = FALSE;
29205b261ecSmrg
29305b261ecSmrg    pWin->bitGravity = ForgetGravity;
29405b261ecSmrg    pWin->winGravity = NorthWestGravity;
29505b261ecSmrg
29605b261ecSmrg    pWin->eventMask = 0;
29705b261ecSmrg    pWin->deliverableEvents = 0;
29805b261ecSmrg    pWin->dontPropagate = 0;
29905b261ecSmrg    pWin->forcedBS = FALSE;
30005b261ecSmrg#ifdef COMPOSITE
30105b261ecSmrg    pWin->redirectDraw = RedirectDrawNone;
30205b261ecSmrg#endif
30305b261ecSmrg}
30405b261ecSmrg
30505b261ecSmrgstatic void
30605b261ecSmrgMakeRootTile(WindowPtr pWin)
30705b261ecSmrg{
30805b261ecSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
30905b261ecSmrg    GCPtr pGC;
31005b261ecSmrg    unsigned char back[128];
31105b261ecSmrg    int len = BitmapBytePad(sizeof(long));
31205b261ecSmrg    unsigned char *from, *to;
31305b261ecSmrg    int i, j;
31405b261ecSmrg
31505b261ecSmrg    pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
31605b261ecSmrg						    pScreen->rootDepth);
31705b261ecSmrg
31805b261ecSmrg    pWin->backgroundState = BackgroundPixmap;
31905b261ecSmrg    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
32005b261ecSmrg    if (!pWin->background.pixmap || !pGC)
32105b261ecSmrg	FatalError("could not create root tile");
32205b261ecSmrg
32305b261ecSmrg    {
32405b261ecSmrg	CARD32 attributes[2];
32505b261ecSmrg
32605b261ecSmrg	attributes[0] = pScreen->whitePixel;
32705b261ecSmrg	attributes[1] = pScreen->blackPixel;
32805b261ecSmrg
32905b261ecSmrg	(void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
33005b261ecSmrg    }
33105b261ecSmrg
33205b261ecSmrg   ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
33305b261ecSmrg
33405b261ecSmrg   from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
33505b261ecSmrg   to = back;
33605b261ecSmrg
33705b261ecSmrg   for (i = 4; i > 0; i--, from++)
33805b261ecSmrg	for (j = len; j > 0; j--)
33905b261ecSmrg	    *to++ = *from;
34005b261ecSmrg
34105b261ecSmrg   (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
34205b261ecSmrg		    0, 0, len, 4, 0, XYBitmap, (char *)back);
34305b261ecSmrg
34405b261ecSmrg   FreeScratchGC(pGC);
34505b261ecSmrg
34605b261ecSmrg}
34705b261ecSmrg
34805b261ecSmrgWindowPtr
34905b261ecSmrgAllocateWindow(ScreenPtr pScreen)
35005b261ecSmrg{
35105b261ecSmrg    WindowPtr pWin;
35205b261ecSmrg    char *ptr;
35305b261ecSmrg    DevUnion *ppriv;
35405b261ecSmrg    unsigned *sizes;
35505b261ecSmrg    unsigned size;
35605b261ecSmrg    int i;
35705b261ecSmrg
35805b261ecSmrg    pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
35905b261ecSmrg    if (pWin)
36005b261ecSmrg    {
36105b261ecSmrg	ppriv = (DevUnion *)(pWin + 1);
36205b261ecSmrg	pWin->devPrivates = ppriv;
36305b261ecSmrg	sizes = pScreen->WindowPrivateSizes;
36405b261ecSmrg	ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
36505b261ecSmrg	for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
36605b261ecSmrg	{
36705b261ecSmrg	    if ( (size = *sizes) )
36805b261ecSmrg	    {
36905b261ecSmrg		ppriv->ptr = (pointer)ptr;
37005b261ecSmrg		ptr += size;
37105b261ecSmrg	    }
37205b261ecSmrg	    else
37305b261ecSmrg		ppriv->ptr = (pointer)NULL;
37405b261ecSmrg	}
37505b261ecSmrg#if _XSERVER64
37605b261ecSmrg	pWin->drawable.pad0 = 0;
37705b261ecSmrg        pWin->drawable.pad1 = 0;
37805b261ecSmrg#endif
37905b261ecSmrg    }
38005b261ecSmrg    return pWin;
38105b261ecSmrg}
38205b261ecSmrg
38305b261ecSmrg/*****
38405b261ecSmrg * CreateRootWindow
38505b261ecSmrg *    Makes a window at initialization time for specified screen
38605b261ecSmrg *****/
38705b261ecSmrg
38805b261ecSmrgBool
38905b261ecSmrgCreateRootWindow(ScreenPtr pScreen)
39005b261ecSmrg{
39105b261ecSmrg    WindowPtr	pWin;
39205b261ecSmrg    BoxRec	box;
39305b261ecSmrg    PixmapFormatRec *format;
39405b261ecSmrg
39505b261ecSmrg    pWin = AllocateWindow(pScreen);
39605b261ecSmrg    if (!pWin)
39705b261ecSmrg	return FALSE;
39805b261ecSmrg
39905b261ecSmrg    savedScreenInfo[pScreen->myNum].pWindow = NULL;
40005b261ecSmrg    savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
40105b261ecSmrg    savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
40205b261ecSmrg    screenIsSaved = SCREEN_SAVER_OFF;
40305b261ecSmrg
40405b261ecSmrg    WindowTable[pScreen->myNum] = pWin;
40505b261ecSmrg
40605b261ecSmrg    pWin->drawable.pScreen = pScreen;
40705b261ecSmrg    pWin->drawable.type = DRAWABLE_WINDOW;
40805b261ecSmrg
40905b261ecSmrg    pWin->drawable.depth = pScreen->rootDepth;
41005b261ecSmrg    for (format = screenInfo.formats;
41105b261ecSmrg	 format->depth != pScreen->rootDepth;
41205b261ecSmrg	 format++)
41305b261ecSmrg	;
41405b261ecSmrg    pWin->drawable.bitsPerPixel = format->bitsPerPixel;
41505b261ecSmrg
41605b261ecSmrg    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
41705b261ecSmrg
41805b261ecSmrg    pWin->parent = NullWindow;
41905b261ecSmrg    SetWindowToDefaults(pWin);
42005b261ecSmrg
42105b261ecSmrg    pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
42205b261ecSmrg    if (!pWin->optional)
42305b261ecSmrg        return FALSE;
42405b261ecSmrg
42505b261ecSmrg    pWin->optional->dontPropagateMask = 0;
42605b261ecSmrg    pWin->optional->otherEventMasks = 0;
42705b261ecSmrg    pWin->optional->otherClients = NULL;
42805b261ecSmrg    pWin->optional->passiveGrabs = NULL;
42905b261ecSmrg    pWin->optional->userProps = NULL;
43005b261ecSmrg    pWin->optional->backingBitPlanes = ~0L;
43105b261ecSmrg    pWin->optional->backingPixel = 0;
43205b261ecSmrg#ifdef SHAPE
43305b261ecSmrg    pWin->optional->boundingShape = NULL;
43405b261ecSmrg    pWin->optional->clipShape = NULL;
43505b261ecSmrg    pWin->optional->inputShape = NULL;
43605b261ecSmrg#endif
43705b261ecSmrg#ifdef XINPUT
43805b261ecSmrg    pWin->optional->inputMasks = NULL;
43905b261ecSmrg#endif
44005b261ecSmrg    pWin->optional->colormap = pScreen->defColormap;
44105b261ecSmrg    pWin->optional->visual = pScreen->rootVisual;
44205b261ecSmrg
44305b261ecSmrg    pWin->nextSib = NullWindow;
44405b261ecSmrg
44505b261ecSmrg    pWin->drawable.id = FakeClientID(0);
44605b261ecSmrg
44705b261ecSmrg    pWin->origin.x = pWin->origin.y = 0;
44805b261ecSmrg    pWin->drawable.height = pScreen->height;
44905b261ecSmrg    pWin->drawable.width = pScreen->width;
45005b261ecSmrg    pWin->drawable.x = pWin->drawable.y = 0;
45105b261ecSmrg
45205b261ecSmrg    box.x1 = 0;
45305b261ecSmrg    box.y1 = 0;
45405b261ecSmrg    box.x2 = pScreen->width;
45505b261ecSmrg    box.y2 = pScreen->height;
45605b261ecSmrg    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
45705b261ecSmrg    REGION_INIT(pScreen, &pWin->winSize, &box, 1);
45805b261ecSmrg    REGION_INIT(pScreen, &pWin->borderSize, &box, 1);
45905b261ecSmrg    REGION_INIT(pScreen, &pWin->borderClip, &box, 1);
46005b261ecSmrg
46105b261ecSmrg    pWin->drawable.class = InputOutput;
46205b261ecSmrg    pWin->optional->visual = pScreen->rootVisual;
46305b261ecSmrg
46405b261ecSmrg    pWin->backgroundState = BackgroundPixel;
46505b261ecSmrg    pWin->background.pixel = pScreen->whitePixel;
46605b261ecSmrg
46705b261ecSmrg    pWin->borderIsPixel = TRUE;
46805b261ecSmrg    pWin->border.pixel = pScreen->blackPixel;
46905b261ecSmrg    pWin->borderWidth = 0;
47005b261ecSmrg
47105b261ecSmrg    if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
47205b261ecSmrg	return FALSE;
47305b261ecSmrg
47405b261ecSmrg    if (disableBackingStore)
47505b261ecSmrg	pScreen->backingStoreSupport = NotUseful;
47605b261ecSmrg    if (enableBackingStore)
47705b261ecSmrg	pScreen->backingStoreSupport = Always;
47805b261ecSmrg
47905b261ecSmrg#ifdef DO_SAVE_UNDERS
48005b261ecSmrg    if ((pScreen->backingStoreSupport != NotUseful) &&
48105b261ecSmrg	(pScreen->saveUnderSupport == NotUseful))
48205b261ecSmrg    {
48305b261ecSmrg	/*
48405b261ecSmrg	 * If the screen has backing-store but no save-unders, let the
48505b261ecSmrg	 * clients know we can support save-unders using backing-store.
48605b261ecSmrg	 */
48705b261ecSmrg	pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
48805b261ecSmrg    }
48905b261ecSmrg#endif /* DO_SAVE_UNDERS */
49005b261ecSmrg
49105b261ecSmrg    if (disableSaveUnders)
49205b261ecSmrg	pScreen->saveUnderSupport = NotUseful;
49305b261ecSmrg
49405b261ecSmrg    return TRUE;
49505b261ecSmrg}
49605b261ecSmrg
49705b261ecSmrgvoid
49805b261ecSmrgInitRootWindow(WindowPtr pWin)
49905b261ecSmrg{
50005b261ecSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
50105b261ecSmrg    int backFlag = CWBorderPixel | CWCursor | CWBackingStore;
50205b261ecSmrg
50305b261ecSmrg    if (!(*pScreen->CreateWindow)(pWin))
50405b261ecSmrg	return; /* XXX */
50505b261ecSmrg    (*pScreen->PositionWindow)(pWin, 0, 0);
50605b261ecSmrg
50705b261ecSmrg    pWin->cursorIsNone = FALSE;
50805b261ecSmrg    pWin->optional->cursor = rootCursor;
50905b261ecSmrg    rootCursor->refcnt++;
51005b261ecSmrg
51105b261ecSmrg    if (!blackRoot && !whiteRoot) {
51205b261ecSmrg        MakeRootTile(pWin);
51305b261ecSmrg        backFlag |= CWBackPixmap;
51405b261ecSmrg    }
51505b261ecSmrg    else {
51605b261ecSmrg        if (blackRoot)
51705b261ecSmrg            pWin->background.pixel = pScreen->blackPixel;
51805b261ecSmrg        else
51905b261ecSmrg            pWin->background.pixel = pScreen->whitePixel;
52005b261ecSmrg        backFlag |= CWBackPixel;
52105b261ecSmrg    }
52205b261ecSmrg
52305b261ecSmrg    pWin->backingStore = defaultBackingStore;
52405b261ecSmrg    pWin->forcedBS = (defaultBackingStore != NotUseful);
52505b261ecSmrg    /* We SHOULD check for an error value here XXX */
52605b261ecSmrg    (*pScreen->ChangeWindowAttributes)(pWin, backFlag);
52705b261ecSmrg
52805b261ecSmrg    XaceHook(XACE_WINDOW_INIT, serverClient, pWin);
52905b261ecSmrg
53005b261ecSmrg    MapWindow(pWin, serverClient);
53105b261ecSmrg}
53205b261ecSmrg
53305b261ecSmrg/* Set the region to the intersection of the rectangle and the
53405b261ecSmrg * window's winSize.  The window is typically the parent of the
53505b261ecSmrg * window from which the region came.
53605b261ecSmrg */
53705b261ecSmrg
53805b261ecSmrgstatic void
53905b261ecSmrgClippedRegionFromBox(WindowPtr pWin, RegionPtr Rgn,
54005b261ecSmrg                     int x, int y,
54105b261ecSmrg                     int w, int h)
54205b261ecSmrg{
54305b261ecSmrg    ScreenPtr pScreen;
54405b261ecSmrg    BoxRec box;
54505b261ecSmrg
54605b261ecSmrg    pScreen = pWin->drawable.pScreen;
54705b261ecSmrg
54805b261ecSmrg    box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
54905b261ecSmrg    /* we do these calculations to avoid overflows */
55005b261ecSmrg    if (x > box.x1)
55105b261ecSmrg	box.x1 = x;
55205b261ecSmrg    if (y > box.y1)
55305b261ecSmrg	box.y1 = y;
55405b261ecSmrg    x += w;
55505b261ecSmrg    if (x < box.x2)
55605b261ecSmrg	box.x2 = x;
55705b261ecSmrg    y += h;
55805b261ecSmrg    if (y < box.y2)
55905b261ecSmrg	box.y2 = y;
56005b261ecSmrg    if (box.x1 > box.x2)
56105b261ecSmrg	box.x2 = box.x1;
56205b261ecSmrg    if (box.y1 > box.y2)
56305b261ecSmrg	box.y2 = box.y1;
56405b261ecSmrg    REGION_RESET(pScreen, Rgn, &box);
56505b261ecSmrg    REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize);
56605b261ecSmrg}
56705b261ecSmrg
56805b261ecSmrgstatic RealChildHeadProc realChildHeadProc = NULL;
56905b261ecSmrg
57005b261ecSmrgvoid
57105b261ecSmrgRegisterRealChildHeadProc (RealChildHeadProc proc)
57205b261ecSmrg{
57305b261ecSmrg    realChildHeadProc = proc;
57405b261ecSmrg}
57505b261ecSmrg
57605b261ecSmrg
57705b261ecSmrgWindowPtr
57805b261ecSmrgRealChildHead(WindowPtr pWin)
57905b261ecSmrg{
58005b261ecSmrg    if (realChildHeadProc) {
58105b261ecSmrg	return realChildHeadProc (pWin);
58205b261ecSmrg    }
58305b261ecSmrg
58405b261ecSmrg    if (!pWin->parent &&
58505b261ecSmrg	(screenIsSaved == SCREEN_SAVER_ON) &&
58605b261ecSmrg	(HasSaverWindow (pWin->drawable.pScreen->myNum)))
58705b261ecSmrg	return (pWin->firstChild);
58805b261ecSmrg    else
58905b261ecSmrg	return (NullWindow);
59005b261ecSmrg}
59105b261ecSmrg
59205b261ecSmrg/*****
59305b261ecSmrg * CreateWindow
59405b261ecSmrg *    Makes a window in response to client request
59505b261ecSmrg *****/
59605b261ecSmrg
59705b261ecSmrg_X_EXPORT WindowPtr
59805b261ecSmrgCreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w,
59905b261ecSmrg             unsigned h, unsigned bw, unsigned class, Mask vmask, XID *vlist,
60005b261ecSmrg             int depth, ClientPtr client, VisualID visual, int *error)
60105b261ecSmrg{
60205b261ecSmrg    WindowPtr pWin;
60305b261ecSmrg    WindowPtr pHead;
60405b261ecSmrg    ScreenPtr pScreen;
60505b261ecSmrg    xEvent event;
60605b261ecSmrg    int idepth, ivisual;
60705b261ecSmrg    Bool fOK;
60805b261ecSmrg    DepthPtr pDepth;
60905b261ecSmrg    PixmapFormatRec *format;
61005b261ecSmrg    WindowOptPtr ancwopt;
61105b261ecSmrg
61205b261ecSmrg    if (class == CopyFromParent)
61305b261ecSmrg	class = pParent->drawable.class;
61405b261ecSmrg
61505b261ecSmrg    if ((class != InputOutput) && (class != InputOnly))
61605b261ecSmrg    {
61705b261ecSmrg	*error = BadValue;
61805b261ecSmrg	client->errorValue = class;
61905b261ecSmrg	return NullWindow;
62005b261ecSmrg    }
62105b261ecSmrg
62205b261ecSmrg    if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
62305b261ecSmrg    {
62405b261ecSmrg	*error = BadMatch;
62505b261ecSmrg	return NullWindow;
62605b261ecSmrg    }
62705b261ecSmrg
62805b261ecSmrg    if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
62905b261ecSmrg    {
63005b261ecSmrg	*error = BadMatch;
63105b261ecSmrg	return NullWindow;
63205b261ecSmrg    }
63305b261ecSmrg
63405b261ecSmrg    pScreen = pParent->drawable.pScreen;
63505b261ecSmrg    if ((class == InputOutput) && (depth == 0))
63605b261ecSmrg	 depth = pParent->drawable.depth;
63705b261ecSmrg    ancwopt = pParent->optional;
63805b261ecSmrg    if (!ancwopt)
63905b261ecSmrg	ancwopt = FindWindowWithOptional(pParent)->optional;
64005b261ecSmrg    if (visual == CopyFromParent) {
64105b261ecSmrg#ifdef XAPPGROUP
64205b261ecSmrg	VisualID ag_visual;
64305b261ecSmrg
64405b261ecSmrg	if (client->appgroup && !pParent->parent &&
64505b261ecSmrg	    (ag_visual = XagRootVisual (client)))
64605b261ecSmrg	    visual = ag_visual;
64705b261ecSmrg	else
64805b261ecSmrg#endif
64905b261ecSmrg	visual = ancwopt->visual;
65005b261ecSmrg    }
65105b261ecSmrg
65205b261ecSmrg    /* Find out if the depth and visual are acceptable for this Screen */
65305b261ecSmrg    if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
65405b261ecSmrg    {
65505b261ecSmrg	fOK = FALSE;
65605b261ecSmrg	for(idepth = 0; idepth < pScreen->numDepths; idepth++)
65705b261ecSmrg	{
65805b261ecSmrg	    pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
65905b261ecSmrg	    if ((depth == pDepth->depth) || (depth == 0))
66005b261ecSmrg	    {
66105b261ecSmrg		for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
66205b261ecSmrg		{
66305b261ecSmrg		    if (visual == pDepth->vids[ivisual])
66405b261ecSmrg		    {
66505b261ecSmrg			fOK = TRUE;
66605b261ecSmrg			break;
66705b261ecSmrg		    }
66805b261ecSmrg		}
66905b261ecSmrg	    }
67005b261ecSmrg	}
67105b261ecSmrg	if (fOK == FALSE)
67205b261ecSmrg	{
67305b261ecSmrg	    *error = BadMatch;
67405b261ecSmrg	    return NullWindow;
67505b261ecSmrg	}
67605b261ecSmrg    }
67705b261ecSmrg
67805b261ecSmrg    if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
67905b261ecSmrg	(class != InputOnly) &&
68005b261ecSmrg	(depth != pParent->drawable.depth))
68105b261ecSmrg    {
68205b261ecSmrg	*error = BadMatch;
68305b261ecSmrg	return NullWindow;
68405b261ecSmrg    }
68505b261ecSmrg
68605b261ecSmrg    if (((vmask & CWColormap) == 0) &&
68705b261ecSmrg	(class != InputOnly) &&
68805b261ecSmrg	((visual != ancwopt->visual) || (ancwopt->colormap == None)))
68905b261ecSmrg    {
69005b261ecSmrg	*error = BadMatch;
69105b261ecSmrg	return NullWindow;
69205b261ecSmrg    }
69305b261ecSmrg
69405b261ecSmrg    pWin = AllocateWindow(pScreen);
69505b261ecSmrg    if (!pWin)
69605b261ecSmrg    {
69705b261ecSmrg	*error = BadAlloc;
69805b261ecSmrg	return NullWindow;
69905b261ecSmrg    }
70005b261ecSmrg    pWin->drawable = pParent->drawable;
70105b261ecSmrg    pWin->drawable.depth = depth;
70205b261ecSmrg    if (depth == pParent->drawable.depth)
70305b261ecSmrg	pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
70405b261ecSmrg    else
70505b261ecSmrg    {
70605b261ecSmrg	for (format = screenInfo.formats; format->depth != depth; format++)
70705b261ecSmrg	    ;
70805b261ecSmrg	pWin->drawable.bitsPerPixel = format->bitsPerPixel;
70905b261ecSmrg    }
71005b261ecSmrg    if (class == InputOnly)
71105b261ecSmrg	pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
71205b261ecSmrg    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
71305b261ecSmrg
71405b261ecSmrg    pWin->drawable.id = wid;
71505b261ecSmrg    pWin->drawable.class = class;
71605b261ecSmrg
71705b261ecSmrg    pWin->parent = pParent;
71805b261ecSmrg    SetWindowToDefaults(pWin);
71905b261ecSmrg
72005b261ecSmrg    if (visual != ancwopt->visual)
72105b261ecSmrg    {
72205b261ecSmrg	if (!MakeWindowOptional (pWin))
72305b261ecSmrg	{
72405b261ecSmrg	    xfree (pWin);
72505b261ecSmrg	    *error = BadAlloc;
72605b261ecSmrg	    return NullWindow;
72705b261ecSmrg	}
72805b261ecSmrg	pWin->optional->visual = visual;
72905b261ecSmrg	pWin->optional->colormap = None;
73005b261ecSmrg    }
73105b261ecSmrg
73205b261ecSmrg    pWin->borderWidth = bw;
73305b261ecSmrg
73405b261ecSmrg    /*  can't let untrusted clients have background None windows;
73505b261ecSmrg     *  they make it too easy to steal window contents
73605b261ecSmrg     */
73705b261ecSmrg    if (XaceHook(XACE_BACKGRND_ACCESS, client, pWin))
73805b261ecSmrg	pWin->backgroundState = None;
73905b261ecSmrg    else {
74005b261ecSmrg	pWin->backgroundState = BackgroundPixel;
74105b261ecSmrg	pWin->background.pixel = 0;
74205b261ecSmrg    }
74305b261ecSmrg
74405b261ecSmrg    pWin->borderIsPixel = pParent->borderIsPixel;
74505b261ecSmrg    pWin->border = pParent->border;
74605b261ecSmrg    if (pWin->borderIsPixel == FALSE)
74705b261ecSmrg	pWin->border.pixmap->refcnt++;
74805b261ecSmrg
74905b261ecSmrg    pWin->origin.x = x + (int)bw;
75005b261ecSmrg    pWin->origin.y = y + (int)bw;
75105b261ecSmrg    pWin->drawable.width = w;
75205b261ecSmrg    pWin->drawable.height = h;
75305b261ecSmrg    pWin->drawable.x = pParent->drawable.x + x + (int)bw;
75405b261ecSmrg    pWin->drawable.y = pParent->drawable.y + y + (int)bw;
75505b261ecSmrg
75605b261ecSmrg	/* set up clip list correctly for unobscured WindowPtr */
75705b261ecSmrg    REGION_NULL(pScreen, &pWin->clipList);
75805b261ecSmrg    REGION_NULL(pScreen, &pWin->borderClip);
75905b261ecSmrg    REGION_NULL(pScreen, &pWin->winSize);
76005b261ecSmrg    REGION_NULL(pScreen, &pWin->borderSize);
76105b261ecSmrg
76205b261ecSmrg    XaceHook(XACE_WINDOW_INIT, client, pWin);
76305b261ecSmrg
76405b261ecSmrg    pHead = RealChildHead(pParent);
76505b261ecSmrg    if (pHead)
76605b261ecSmrg    {
76705b261ecSmrg	pWin->nextSib = pHead->nextSib;
76805b261ecSmrg	if (pHead->nextSib)
76905b261ecSmrg	    pHead->nextSib->prevSib = pWin;
77005b261ecSmrg	else
77105b261ecSmrg	    pParent->lastChild = pWin;
77205b261ecSmrg	pHead->nextSib = pWin;
77305b261ecSmrg	pWin->prevSib = pHead;
77405b261ecSmrg    }
77505b261ecSmrg    else
77605b261ecSmrg    {
77705b261ecSmrg	pWin->nextSib = pParent->firstChild;
77805b261ecSmrg	if (pParent->firstChild)
77905b261ecSmrg	    pParent->firstChild->prevSib = pWin;
78005b261ecSmrg	else
78105b261ecSmrg	    pParent->lastChild = pWin;
78205b261ecSmrg	pParent->firstChild = pWin;
78305b261ecSmrg    }
78405b261ecSmrg
78505b261ecSmrg    SetWinSize (pWin);
78605b261ecSmrg    SetBorderSize (pWin);
78705b261ecSmrg
78805b261ecSmrg    /* We SHOULD check for an error value here XXX */
78905b261ecSmrg    if (!(*pScreen->CreateWindow)(pWin))
79005b261ecSmrg    {
79105b261ecSmrg	*error = BadAlloc;
79205b261ecSmrg	DeleteWindow(pWin, None);
79305b261ecSmrg	return NullWindow;
79405b261ecSmrg    }
79505b261ecSmrg    /* We SHOULD check for an error value here XXX */
79605b261ecSmrg    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
79705b261ecSmrg
79805b261ecSmrg    if (!(vmask & CWEventMask))
79905b261ecSmrg	RecalculateDeliverableEvents(pWin);
80005b261ecSmrg
80105b261ecSmrg    if (vmask)
80205b261ecSmrg	*error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
80305b261ecSmrg    else
80405b261ecSmrg	*error = Success;
80505b261ecSmrg
80605b261ecSmrg    if (*error != Success)
80705b261ecSmrg    {
80805b261ecSmrg	DeleteWindow(pWin, None);
80905b261ecSmrg	return NullWindow;
81005b261ecSmrg    }
81105b261ecSmrg    if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
81205b261ecSmrg    {
81305b261ecSmrg	XID value = defaultBackingStore;
81405b261ecSmrg	(void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
81505b261ecSmrg	pWin->forcedBS = TRUE;
81605b261ecSmrg    }
81705b261ecSmrg
81805b261ecSmrg    if (SubSend(pParent))
81905b261ecSmrg    {
82005b261ecSmrg	event.u.u.type = CreateNotify;
82105b261ecSmrg	event.u.createNotify.window = wid;
82205b261ecSmrg	event.u.createNotify.parent = pParent->drawable.id;
82305b261ecSmrg	event.u.createNotify.x = x;
82405b261ecSmrg	event.u.createNotify.y = y;
82505b261ecSmrg	event.u.createNotify.width = w;
82605b261ecSmrg	event.u.createNotify.height = h;
82705b261ecSmrg	event.u.createNotify.borderWidth = bw;
82805b261ecSmrg	event.u.createNotify.override = pWin->overrideRedirect;
82905b261ecSmrg	DeliverEvents(pParent, &event, 1, NullWindow);
83005b261ecSmrg    }
83105b261ecSmrg    return pWin;
83205b261ecSmrg}
83305b261ecSmrg
83405b261ecSmrgstatic void
83505b261ecSmrgDisposeWindowOptional (WindowPtr pWin)
83605b261ecSmrg{
83705b261ecSmrg    if (!pWin->optional)
83805b261ecSmrg	return;
83905b261ecSmrg    /*
84005b261ecSmrg     * everything is peachy.  Delete the optional record
84105b261ecSmrg     * and clean up
84205b261ecSmrg     */
84305b261ecSmrg    if (pWin->optional->cursor)
84405b261ecSmrg    {
84505b261ecSmrg	FreeCursor (pWin->optional->cursor, (Cursor)0);
84605b261ecSmrg	pWin->cursorIsNone = FALSE;
84705b261ecSmrg    }
84805b261ecSmrg    else
84905b261ecSmrg	pWin->cursorIsNone = TRUE;
85005b261ecSmrg    xfree (pWin->optional);
85105b261ecSmrg    pWin->optional = NULL;
85205b261ecSmrg}
85305b261ecSmrg
85405b261ecSmrgstatic void
85505b261ecSmrgFreeWindowResources(WindowPtr pWin)
85605b261ecSmrg{
85705b261ecSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
85805b261ecSmrg
85905b261ecSmrg    DeleteWindowFromAnySaveSet(pWin);
86005b261ecSmrg    DeleteWindowFromAnySelections(pWin);
86105b261ecSmrg    DeleteWindowFromAnyEvents(pWin, TRUE);
86205b261ecSmrg    REGION_UNINIT(pScreen, &pWin->clipList);
86305b261ecSmrg    REGION_UNINIT(pScreen, &pWin->winSize);
86405b261ecSmrg    REGION_UNINIT(pScreen, &pWin->borderClip);
86505b261ecSmrg    REGION_UNINIT(pScreen, &pWin->borderSize);
86605b261ecSmrg#ifdef SHAPE
86705b261ecSmrg    if (wBoundingShape (pWin))
86805b261ecSmrg	REGION_DESTROY(pScreen, wBoundingShape (pWin));
86905b261ecSmrg    if (wClipShape (pWin))
87005b261ecSmrg	REGION_DESTROY(pScreen, wClipShape (pWin));
87105b261ecSmrg    if (wInputShape (pWin))
87205b261ecSmrg	REGION_DESTROY(pScreen, wInputShape (pWin));
87305b261ecSmrg#endif
87405b261ecSmrg    if (pWin->borderIsPixel == FALSE)
87505b261ecSmrg	(*pScreen->DestroyPixmap)(pWin->border.pixmap);
87605b261ecSmrg    if (pWin->backgroundState == BackgroundPixmap)
87705b261ecSmrg	(*pScreen->DestroyPixmap)(pWin->background.pixmap);
87805b261ecSmrg
87905b261ecSmrg    DeleteAllWindowProperties(pWin);
88005b261ecSmrg    /* We SHOULD check for an error value here XXX */
88105b261ecSmrg    (*pScreen->DestroyWindow)(pWin);
88205b261ecSmrg    DisposeWindowOptional (pWin);
88305b261ecSmrg}
88405b261ecSmrg
88505b261ecSmrgstatic void
88605b261ecSmrgCrushTree(WindowPtr pWin)
88705b261ecSmrg{
88805b261ecSmrg    WindowPtr pChild, pSib, pParent;
88905b261ecSmrg    UnrealizeWindowProcPtr UnrealizeWindow;
89005b261ecSmrg    xEvent event;
89105b261ecSmrg
89205b261ecSmrg    if (!(pChild = pWin->firstChild))
89305b261ecSmrg	return;
89405b261ecSmrg    UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
89505b261ecSmrg    while (1)
89605b261ecSmrg    {
89705b261ecSmrg	if (pChild->firstChild)
89805b261ecSmrg	{
89905b261ecSmrg	    pChild = pChild->firstChild;
90005b261ecSmrg	    continue;
90105b261ecSmrg	}
90205b261ecSmrg	while (1)
90305b261ecSmrg	{
90405b261ecSmrg	    pParent = pChild->parent;
90505b261ecSmrg	    if (SubStrSend(pChild, pParent))
90605b261ecSmrg	    {
90705b261ecSmrg		event.u.u.type = DestroyNotify;
90805b261ecSmrg		event.u.destroyNotify.window = pChild->drawable.id;
90905b261ecSmrg		DeliverEvents(pChild, &event, 1, NullWindow);
91005b261ecSmrg	    }
91105b261ecSmrg	    FreeResource(pChild->drawable.id, RT_WINDOW);
91205b261ecSmrg	    pSib = pChild->nextSib;
91305b261ecSmrg#ifdef DO_SAVE_UNDERS
91405b261ecSmrg	    if (pChild->saveUnder && pChild->viewable)
91505b261ecSmrg		deltaSaveUndersViewable--;
91605b261ecSmrg#endif
91705b261ecSmrg	    pChild->viewable = FALSE;
91805b261ecSmrg	    if (pChild->realized)
91905b261ecSmrg	    {
92005b261ecSmrg		pChild->realized = FALSE;
92105b261ecSmrg		(*UnrealizeWindow)(pChild);
92205b261ecSmrg	    }
92305b261ecSmrg	    FreeWindowResources(pChild);
92405b261ecSmrg	    xfree(pChild);
92505b261ecSmrg	    if ( (pChild = pSib) )
92605b261ecSmrg		break;
92705b261ecSmrg	    pChild = pParent;
92805b261ecSmrg	    pChild->firstChild = NullWindow;
92905b261ecSmrg	    pChild->lastChild = NullWindow;
93005b261ecSmrg	    if (pChild == pWin)
93105b261ecSmrg		return;
93205b261ecSmrg	}
93305b261ecSmrg    }
93405b261ecSmrg}
93505b261ecSmrg
93605b261ecSmrg/*****
93705b261ecSmrg *  DeleteWindow
93805b261ecSmrg *	 Deletes child of window then window itself
93905b261ecSmrg *	 If wid is None, don't send any events
94005b261ecSmrg *****/
94105b261ecSmrg
94205b261ecSmrgint
94305b261ecSmrgDeleteWindow(pointer value, XID wid)
94405b261ecSmrg {
94505b261ecSmrg    WindowPtr pParent;
94605b261ecSmrg    WindowPtr pWin = (WindowPtr)value;
94705b261ecSmrg    xEvent event;
94805b261ecSmrg
94905b261ecSmrg    UnmapWindow(pWin, FALSE);
95005b261ecSmrg
95105b261ecSmrg    CrushTree(pWin);
95205b261ecSmrg
95305b261ecSmrg    pParent = pWin->parent;
95405b261ecSmrg    if (wid && pParent && SubStrSend(pWin, pParent))
95505b261ecSmrg    {
95605b261ecSmrg	event.u.u.type = DestroyNotify;
95705b261ecSmrg	event.u.destroyNotify.window = pWin->drawable.id;
95805b261ecSmrg	DeliverEvents(pWin, &event, 1, NullWindow);
95905b261ecSmrg    }
96005b261ecSmrg
96105b261ecSmrg    FreeWindowResources(pWin);
96205b261ecSmrg    if (pParent)
96305b261ecSmrg    {
96405b261ecSmrg	if (pParent->firstChild == pWin)
96505b261ecSmrg	    pParent->firstChild = pWin->nextSib;
96605b261ecSmrg	if (pParent->lastChild == pWin)
96705b261ecSmrg	    pParent->lastChild = pWin->prevSib;
96805b261ecSmrg	if (pWin->nextSib)
96905b261ecSmrg	    pWin->nextSib->prevSib = pWin->prevSib;
97005b261ecSmrg	if (pWin->prevSib)
97105b261ecSmrg	    pWin->prevSib->nextSib = pWin->nextSib;
97205b261ecSmrg    }
97305b261ecSmrg    xfree(pWin);
97405b261ecSmrg    return Success;
97505b261ecSmrg}
97605b261ecSmrg
97705b261ecSmrgvoid
97805b261ecSmrgDestroySubwindows(WindowPtr pWin, ClientPtr client)
97905b261ecSmrg{
98005b261ecSmrg    /* XXX
98105b261ecSmrg     * The protocol is quite clear that each window should be
98205b261ecSmrg     * destroyed in turn, however, unmapping all of the first
98305b261ecSmrg     * eliminates most of the calls to ValidateTree.  So,
98405b261ecSmrg     * this implementation is incorrect in that all of the
98505b261ecSmrg     * UnmapNotifies occur before all of the DestroyNotifies.
98605b261ecSmrg     * If you care, simply delete the call to UnmapSubwindows.
98705b261ecSmrg     */
98805b261ecSmrg    UnmapSubwindows(pWin);
98905b261ecSmrg    while (pWin->lastChild)
99005b261ecSmrg	FreeResource(pWin->lastChild->drawable.id, RT_NONE);
99105b261ecSmrg}
99205b261ecSmrg
99305b261ecSmrg#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
99405b261ecSmrg    ButtonReleaseMask | PointerMotionMask)
99505b261ecSmrg
99605b261ecSmrg/*****
99705b261ecSmrg *  ChangeWindowAttributes
99805b261ecSmrg *
99905b261ecSmrg *  The value-mask specifies which attributes are to be changed; the
100005b261ecSmrg *  value-list contains one value for each one bit in the mask, from least
100105b261ecSmrg *  to most significant bit in the mask.
100205b261ecSmrg *****/
100305b261ecSmrg
100405b261ecSmrg_X_EXPORT int
100505b261ecSmrgChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
100605b261ecSmrg{
100705b261ecSmrg    Mask index2;
100805b261ecSmrg    XID *pVlist;
100905b261ecSmrg    PixmapPtr pPixmap;
101005b261ecSmrg    Pixmap pixID;
101105b261ecSmrg    CursorPtr pCursor, pOldCursor;
101205b261ecSmrg    Cursor cursorID;
101305b261ecSmrg    WindowPtr pChild;
101405b261ecSmrg    Colormap cmap;
101505b261ecSmrg    ColormapPtr	pCmap;
101605b261ecSmrg    xEvent xE;
101705b261ecSmrg    int result;
101805b261ecSmrg    ScreenPtr pScreen;
101905b261ecSmrg    Mask vmaskCopy = 0;
102005b261ecSmrg    Mask tmask;
102105b261ecSmrg    unsigned int val;
102205b261ecSmrg    int error;
102305b261ecSmrg    Bool checkOptional = FALSE;
102405b261ecSmrg    Bool borderRelative = FALSE;
102505b261ecSmrg    WindowPtr pLayerWin;
102605b261ecSmrg
102705b261ecSmrg    if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
102805b261ecSmrg	return BadMatch;
102905b261ecSmrg
103005b261ecSmrg    error = Success;
103105b261ecSmrg    pScreen = pWin->drawable.pScreen;
103205b261ecSmrg    pVlist = vlist;
103305b261ecSmrg    tmask = vmask;
103405b261ecSmrg    while (tmask)
103505b261ecSmrg    {
103605b261ecSmrg	index2 = (Mask) lowbit (tmask);
103705b261ecSmrg	tmask &= ~index2;
103805b261ecSmrg	switch (index2)
103905b261ecSmrg	{
104005b261ecSmrg	  case CWBackPixmap:
104105b261ecSmrg	    pixID = (Pixmap )*pVlist;
104205b261ecSmrg	    pVlist++;
104305b261ecSmrg	    if (pWin->backgroundState == ParentRelative)
104405b261ecSmrg		borderRelative = TRUE;
104505b261ecSmrg	    if (pixID == None)
104605b261ecSmrg	    {
104705b261ecSmrg		/*  can't let untrusted clients have background None windows */
104805b261ecSmrg		if (XaceHook(XACE_BACKGRND_ACCESS, client, pWin)) {
104905b261ecSmrg		    if (pWin->backgroundState == BackgroundPixmap)
105005b261ecSmrg			(*pScreen->DestroyPixmap)(pWin->background.pixmap);
105105b261ecSmrg		    if (!pWin->parent)
105205b261ecSmrg			MakeRootTile(pWin);
105305b261ecSmrg		    else
105405b261ecSmrg			pWin->backgroundState = None;
105505b261ecSmrg		} else {
105605b261ecSmrg		    /* didn't change the backgrnd to None, so don't tell ddx */
105705b261ecSmrg		    index2 = 0;
105805b261ecSmrg		}
105905b261ecSmrg	    }
106005b261ecSmrg	    else if (pixID == ParentRelative)
106105b261ecSmrg	    {
106205b261ecSmrg		if (pWin->parent &&
106305b261ecSmrg		    pWin->drawable.depth != pWin->parent->drawable.depth)
106405b261ecSmrg		{
106505b261ecSmrg		    error = BadMatch;
106605b261ecSmrg		    goto PatchUp;
106705b261ecSmrg		}
106805b261ecSmrg		if (pWin->backgroundState == BackgroundPixmap)
106905b261ecSmrg		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
107005b261ecSmrg		if (!pWin->parent)
107105b261ecSmrg		    MakeRootTile(pWin);
107205b261ecSmrg		else
107305b261ecSmrg		    pWin->backgroundState = ParentRelative;
107405b261ecSmrg		borderRelative = TRUE;
107505b261ecSmrg		/* Note that the parent's backgroundTile's refcnt is NOT
107605b261ecSmrg		 * incremented. */
107705b261ecSmrg	    }
107805b261ecSmrg	    else
107905b261ecSmrg	    {
108005b261ecSmrg		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
108105b261ecSmrg						RT_PIXMAP, DixReadAccess);
108205b261ecSmrg		if (pPixmap != (PixmapPtr) NULL)
108305b261ecSmrg		{
108405b261ecSmrg		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
108505b261ecSmrg			 (pPixmap->drawable.pScreen != pScreen))
108605b261ecSmrg		    {
108705b261ecSmrg			error = BadMatch;
108805b261ecSmrg			goto PatchUp;
108905b261ecSmrg		    }
109005b261ecSmrg		    if (pWin->backgroundState == BackgroundPixmap)
109105b261ecSmrg			(*pScreen->DestroyPixmap)(pWin->background.pixmap);
109205b261ecSmrg		    pWin->backgroundState = BackgroundPixmap;
109305b261ecSmrg		    pWin->background.pixmap = pPixmap;
109405b261ecSmrg		    pPixmap->refcnt++;
109505b261ecSmrg		}
109605b261ecSmrg		else
109705b261ecSmrg		{
109805b261ecSmrg		    error = BadPixmap;
109905b261ecSmrg		    client->errorValue = pixID;
110005b261ecSmrg		    goto PatchUp;
110105b261ecSmrg		}
110205b261ecSmrg	    }
110305b261ecSmrg	    break;
110405b261ecSmrg	  case CWBackPixel:
110505b261ecSmrg	    if (pWin->backgroundState == ParentRelative)
110605b261ecSmrg		borderRelative = TRUE;
110705b261ecSmrg	    if (pWin->backgroundState == BackgroundPixmap)
110805b261ecSmrg		(*pScreen->DestroyPixmap)(pWin->background.pixmap);
110905b261ecSmrg	    pWin->backgroundState = BackgroundPixel;
111005b261ecSmrg	    pWin->background.pixel = (CARD32 ) *pVlist;
111105b261ecSmrg		   /* background pixel overrides background pixmap,
111205b261ecSmrg		      so don't let the ddx layer see both bits */
111305b261ecSmrg	    vmaskCopy &= ~CWBackPixmap;
111405b261ecSmrg	    pVlist++;
111505b261ecSmrg	    break;
111605b261ecSmrg	  case CWBorderPixmap:
111705b261ecSmrg	    pixID = (Pixmap ) *pVlist;
111805b261ecSmrg	    pVlist++;
111905b261ecSmrg	    if (pixID == CopyFromParent)
112005b261ecSmrg	    {
112105b261ecSmrg		if (!pWin->parent ||
112205b261ecSmrg		    (pWin->drawable.depth != pWin->parent->drawable.depth))
112305b261ecSmrg		{
112405b261ecSmrg		    error = BadMatch;
112505b261ecSmrg		    goto PatchUp;
112605b261ecSmrg		}
112705b261ecSmrg		if (pWin->borderIsPixel == FALSE)
112805b261ecSmrg		    (*pScreen->DestroyPixmap)(pWin->border.pixmap);
112905b261ecSmrg		pWin->border = pWin->parent->border;
113005b261ecSmrg		if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
113105b261ecSmrg		{
113205b261ecSmrg		    index2 = CWBorderPixel;
113305b261ecSmrg		}
113405b261ecSmrg		else
113505b261ecSmrg		{
113605b261ecSmrg		    pWin->parent->border.pixmap->refcnt++;
113705b261ecSmrg		}
113805b261ecSmrg	    }
113905b261ecSmrg	    else
114005b261ecSmrg	    {
114105b261ecSmrg		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
114205b261ecSmrg					RT_PIXMAP, DixReadAccess);
114305b261ecSmrg		if (pPixmap)
114405b261ecSmrg		{
114505b261ecSmrg		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
114605b261ecSmrg			 (pPixmap->drawable.pScreen != pScreen))
114705b261ecSmrg		    {
114805b261ecSmrg			error = BadMatch;
114905b261ecSmrg			goto PatchUp;
115005b261ecSmrg		    }
115105b261ecSmrg		    if (pWin->borderIsPixel == FALSE)
115205b261ecSmrg			(*pScreen->DestroyPixmap)(pWin->border.pixmap);
115305b261ecSmrg		    pWin->borderIsPixel = FALSE;
115405b261ecSmrg		    pWin->border.pixmap = pPixmap;
115505b261ecSmrg		    pPixmap->refcnt++;
115605b261ecSmrg		}
115705b261ecSmrg		else
115805b261ecSmrg		{
115905b261ecSmrg		    error = BadPixmap;
116005b261ecSmrg		    client->errorValue = pixID;
116105b261ecSmrg		    goto PatchUp;
116205b261ecSmrg		}
116305b261ecSmrg	    }
116405b261ecSmrg	    break;
116505b261ecSmrg	  case CWBorderPixel:
116605b261ecSmrg	    if (pWin->borderIsPixel == FALSE)
116705b261ecSmrg		(*pScreen->DestroyPixmap)(pWin->border.pixmap);
116805b261ecSmrg	    pWin->borderIsPixel = TRUE;
116905b261ecSmrg	    pWin->border.pixel = (CARD32) *pVlist;
117005b261ecSmrg		    /* border pixel overrides border pixmap,
117105b261ecSmrg		       so don't let the ddx layer see both bits */
117205b261ecSmrg	    vmaskCopy &= ~CWBorderPixmap;
117305b261ecSmrg	    pVlist++;
117405b261ecSmrg	    break;
117505b261ecSmrg	  case CWBitGravity:
117605b261ecSmrg	    val = (CARD8 )*pVlist;
117705b261ecSmrg	    pVlist++;
117805b261ecSmrg	    if (val > StaticGravity)
117905b261ecSmrg	    {
118005b261ecSmrg		error = BadValue;
118105b261ecSmrg		client->errorValue = val;
118205b261ecSmrg		goto PatchUp;
118305b261ecSmrg	    }
118405b261ecSmrg	    pWin->bitGravity = val;
118505b261ecSmrg	    break;
118605b261ecSmrg	  case CWWinGravity:
118705b261ecSmrg	    val = (CARD8 )*pVlist;
118805b261ecSmrg	    pVlist++;
118905b261ecSmrg	    if (val > StaticGravity)
119005b261ecSmrg	    {
119105b261ecSmrg		error = BadValue;
119205b261ecSmrg		client->errorValue = val;
119305b261ecSmrg		goto PatchUp;
119405b261ecSmrg	    }
119505b261ecSmrg	    pWin->winGravity = val;
119605b261ecSmrg	    break;
119705b261ecSmrg	  case CWBackingStore:
119805b261ecSmrg	    val = (CARD8 )*pVlist;
119905b261ecSmrg	    pVlist++;
120005b261ecSmrg	    if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
120105b261ecSmrg	    {
120205b261ecSmrg		error = BadValue;
120305b261ecSmrg		client->errorValue = val;
120405b261ecSmrg		goto PatchUp;
120505b261ecSmrg	    }
120605b261ecSmrg	    pWin->backingStore = val;
120705b261ecSmrg	    pWin->forcedBS = FALSE;
120805b261ecSmrg	    break;
120905b261ecSmrg	  case CWBackingPlanes:
121005b261ecSmrg	    if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
121105b261ecSmrg		if (!pWin->optional && !MakeWindowOptional (pWin))
121205b261ecSmrg		{
121305b261ecSmrg		    error = BadAlloc;
121405b261ecSmrg		    goto PatchUp;
121505b261ecSmrg		}
121605b261ecSmrg		pWin->optional->backingBitPlanes = (CARD32) *pVlist;
121705b261ecSmrg		if ((CARD32)*pVlist == (CARD32)~0L)
121805b261ecSmrg		    checkOptional = TRUE;
121905b261ecSmrg	    }
122005b261ecSmrg	    pVlist++;
122105b261ecSmrg	    break;
122205b261ecSmrg	  case CWBackingPixel:
122305b261ecSmrg	    if (pWin->optional || (CARD32) *pVlist) {
122405b261ecSmrg		if (!pWin->optional && !MakeWindowOptional (pWin))
122505b261ecSmrg		{
122605b261ecSmrg		    error = BadAlloc;
122705b261ecSmrg		    goto PatchUp;
122805b261ecSmrg		}
122905b261ecSmrg		pWin->optional->backingPixel = (CARD32) *pVlist;
123005b261ecSmrg		if (!*pVlist)
123105b261ecSmrg		    checkOptional = TRUE;
123205b261ecSmrg	    }
123305b261ecSmrg	    pVlist++;
123405b261ecSmrg	    break;
123505b261ecSmrg	  case CWSaveUnder:
123605b261ecSmrg	    val = (BOOL) *pVlist;
123705b261ecSmrg	    pVlist++;
123805b261ecSmrg	    if ((val != xTrue) && (val != xFalse))
123905b261ecSmrg	    {
124005b261ecSmrg		error = BadValue;
124105b261ecSmrg		client->errorValue = val;
124205b261ecSmrg		goto PatchUp;
124305b261ecSmrg	    }
124405b261ecSmrg#ifdef DO_SAVE_UNDERS
124505b261ecSmrg	    if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
124605b261ecSmrg		DO_SAVE_UNDERS(pWin))
124705b261ecSmrg	    {
124805b261ecSmrg		/*
124905b261ecSmrg		 * Re-check all siblings and inferiors for obscurity or
125005b261ecSmrg		 * exposition (hee hee).
125105b261ecSmrg		 */
125205b261ecSmrg		if (pWin->saveUnder)
125305b261ecSmrg		    deltaSaveUndersViewable--;
125405b261ecSmrg		else
125505b261ecSmrg		    deltaSaveUndersViewable++;
125605b261ecSmrg		pWin->saveUnder = val;
125705b261ecSmrg
125805b261ecSmrg		if (pWin->firstChild)
125905b261ecSmrg		{
126005b261ecSmrg                    pLayerWin = (*pScreen->GetLayerWindow)(pWin);
126105b261ecSmrg                   if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
126205b261ecSmrg                       (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
126305b261ecSmrg                                                       pWin->nextSib);
126405b261ecSmrg               }
126505b261ecSmrg               else
126605b261ecSmrg               {
126705b261ecSmrg                   if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
126805b261ecSmrg                       (*pScreen->PostChangeSaveUnder)(pWin,
126905b261ecSmrg                                                       pWin->nextSib);
127005b261ecSmrg               }
127105b261ecSmrg	    }
127205b261ecSmrg	    else
127305b261ecSmrg	    {
127405b261ecSmrg		/*  If we're changing the saveUnder attribute of the root
127505b261ecSmrg		 *  window, all we do is set pWin->saveUnder so that
127605b261ecSmrg		 *  GetWindowAttributes returns the right value.  We don't
127705b261ecSmrg		 *  do the "normal" save-under processing (as above).
127805b261ecSmrg		 *  Hope that doesn't cause any problems.
127905b261ecSmrg		 */
128005b261ecSmrg		pWin->saveUnder = val;
128105b261ecSmrg	    }
128205b261ecSmrg#else
128305b261ecSmrg	    pWin->saveUnder = val;
128405b261ecSmrg#endif /* DO_SAVE_UNDERS */
128505b261ecSmrg	    break;
128605b261ecSmrg	  case CWEventMask:
128705b261ecSmrg	    result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
128805b261ecSmrg	    if (result)
128905b261ecSmrg	    {
129005b261ecSmrg		error = result;
129105b261ecSmrg		goto PatchUp;
129205b261ecSmrg	    }
129305b261ecSmrg	    pVlist++;
129405b261ecSmrg	    break;
129505b261ecSmrg	  case CWDontPropagate:
129605b261ecSmrg	    result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
129705b261ecSmrg					    &checkOptional);
129805b261ecSmrg	    if (result)
129905b261ecSmrg	    {
130005b261ecSmrg		error = result;
130105b261ecSmrg		goto PatchUp;
130205b261ecSmrg	    }
130305b261ecSmrg	    pVlist++;
130405b261ecSmrg	    break;
130505b261ecSmrg	  case CWOverrideRedirect:
130605b261ecSmrg	    val = (BOOL ) *pVlist;
130705b261ecSmrg	    pVlist++;
130805b261ecSmrg	    if ((val != xTrue) && (val != xFalse))
130905b261ecSmrg	    {
131005b261ecSmrg		error = BadValue;
131105b261ecSmrg		client->errorValue = val;
131205b261ecSmrg		goto PatchUp;
131305b261ecSmrg	    }
131405b261ecSmrg	    pWin->overrideRedirect = val;
131505b261ecSmrg	    break;
131605b261ecSmrg	  case CWColormap:
131705b261ecSmrg	    cmap = (Colormap) *pVlist;
131805b261ecSmrg	    pVlist++;
131905b261ecSmrg	    if (cmap == CopyFromParent)
132005b261ecSmrg	    {
132105b261ecSmrg#ifdef XAPPGROUP
132205b261ecSmrg		Colormap ag_colormap;
132305b261ecSmrg		ClientPtr win_owner;
132405b261ecSmrg
132505b261ecSmrg		/*
132605b261ecSmrg		 * win_owner == client for CreateWindow, other clients
132705b261ecSmrg		 * can ChangeWindowAttributes
132805b261ecSmrg		 */
132905b261ecSmrg		win_owner = clients[CLIENT_ID(pWin->drawable.id)];
133005b261ecSmrg
133105b261ecSmrg		if ( win_owner && win_owner->appgroup &&
133205b261ecSmrg		    !pWin->parent->parent &&
133305b261ecSmrg		    (ag_colormap = XagDefaultColormap (win_owner)))
133405b261ecSmrg		    cmap = ag_colormap;
133505b261ecSmrg		else
133605b261ecSmrg#endif
133705b261ecSmrg		if (pWin->parent &&
133805b261ecSmrg		    (!pWin->optional ||
133905b261ecSmrg		     pWin->optional->visual == wVisual (pWin->parent)))
134005b261ecSmrg		{
134105b261ecSmrg		    cmap = wColormap (pWin->parent);
134205b261ecSmrg		}
134305b261ecSmrg		else
134405b261ecSmrg		    cmap = None;
134505b261ecSmrg	    }
134605b261ecSmrg	    if (cmap == None)
134705b261ecSmrg	    {
134805b261ecSmrg		error = BadMatch;
134905b261ecSmrg		goto PatchUp;
135005b261ecSmrg	    }
135105b261ecSmrg	    pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
135205b261ecSmrg					      RT_COLORMAP, DixReadAccess);
135305b261ecSmrg	    if (!pCmap)
135405b261ecSmrg	    {
135505b261ecSmrg		error = BadColor;
135605b261ecSmrg		client->errorValue = cmap;
135705b261ecSmrg		goto PatchUp;
135805b261ecSmrg	    }
135905b261ecSmrg	    if (pCmap->pVisual->vid != wVisual (pWin) ||
136005b261ecSmrg		pCmap->pScreen != pScreen)
136105b261ecSmrg	    {
136205b261ecSmrg		error = BadMatch;
136305b261ecSmrg		goto PatchUp;
136405b261ecSmrg	    }
136505b261ecSmrg	    if (cmap != wColormap (pWin))
136605b261ecSmrg	    {
136705b261ecSmrg		if (!pWin->optional)
136805b261ecSmrg		{
136905b261ecSmrg		    if (!MakeWindowOptional (pWin))
137005b261ecSmrg		    {
137105b261ecSmrg			error = BadAlloc;
137205b261ecSmrg			goto PatchUp;
137305b261ecSmrg		    }
137405b261ecSmrg		}
137505b261ecSmrg		else if (pWin->parent && cmap == wColormap (pWin->parent))
137605b261ecSmrg		    checkOptional = TRUE;
137705b261ecSmrg
137805b261ecSmrg		/*
137905b261ecSmrg		 * propagate the original colormap to any children
138005b261ecSmrg		 * inheriting it
138105b261ecSmrg		 */
138205b261ecSmrg
138305b261ecSmrg		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
138405b261ecSmrg		{
138505b261ecSmrg		    if (!pChild->optional && !MakeWindowOptional (pChild))
138605b261ecSmrg		    {
138705b261ecSmrg			error = BadAlloc;
138805b261ecSmrg			goto PatchUp;
138905b261ecSmrg		    }
139005b261ecSmrg		}
139105b261ecSmrg
139205b261ecSmrg		pWin->optional->colormap = cmap;
139305b261ecSmrg
139405b261ecSmrg		/*
139505b261ecSmrg		 * check on any children now matching the new colormap
139605b261ecSmrg		 */
139705b261ecSmrg
139805b261ecSmrg		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
139905b261ecSmrg		{
140005b261ecSmrg		    if (pChild->optional->colormap == cmap)
140105b261ecSmrg			CheckWindowOptionalNeed (pChild);
140205b261ecSmrg		}
140305b261ecSmrg
140405b261ecSmrg		xE.u.u.type = ColormapNotify;
140505b261ecSmrg		xE.u.colormap.window = pWin->drawable.id;
140605b261ecSmrg		xE.u.colormap.colormap = cmap;
140705b261ecSmrg		xE.u.colormap.new = xTrue;
140805b261ecSmrg		xE.u.colormap.state = IsMapInstalled(cmap, pWin);
140905b261ecSmrg		DeliverEvents(pWin, &xE, 1, NullWindow);
141005b261ecSmrg	    }
141105b261ecSmrg	    break;
141205b261ecSmrg	  case CWCursor:
141305b261ecSmrg	    cursorID = (Cursor ) *pVlist;
141405b261ecSmrg	    pVlist++;
141505b261ecSmrg	    /*
141605b261ecSmrg	     * install the new
141705b261ecSmrg	     */
141805b261ecSmrg	    if ( cursorID == None)
141905b261ecSmrg	    {
142005b261ecSmrg		if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
142105b261ecSmrg		    pCursor = rootCursor;
142205b261ecSmrg		else
142305b261ecSmrg		    pCursor = (CursorPtr) None;
142405b261ecSmrg	    }
142505b261ecSmrg	    else
142605b261ecSmrg	    {
142705b261ecSmrg		pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
142805b261ecSmrg						RT_CURSOR, DixReadAccess);
142905b261ecSmrg		if (!pCursor)
143005b261ecSmrg		{
143105b261ecSmrg		    error = BadCursor;
143205b261ecSmrg		    client->errorValue = cursorID;
143305b261ecSmrg		    goto PatchUp;
143405b261ecSmrg		}
143505b261ecSmrg	    }
143605b261ecSmrg
143705b261ecSmrg	    if (pCursor != wCursor (pWin))
143805b261ecSmrg	    {
143905b261ecSmrg		/*
144005b261ecSmrg		 * patch up child windows so they don't lose cursors.
144105b261ecSmrg		 */
144205b261ecSmrg
144305b261ecSmrg		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
144405b261ecSmrg		{
144505b261ecSmrg		    if (!pChild->optional && !pChild->cursorIsNone &&
144605b261ecSmrg			!MakeWindowOptional (pChild))
144705b261ecSmrg		    {
144805b261ecSmrg			error = BadAlloc;
144905b261ecSmrg			goto PatchUp;
145005b261ecSmrg		    }
145105b261ecSmrg		}
145205b261ecSmrg
145305b261ecSmrg		pOldCursor = 0;
145405b261ecSmrg		if (pCursor == (CursorPtr) None)
145505b261ecSmrg		{
145605b261ecSmrg		    pWin->cursorIsNone = TRUE;
145705b261ecSmrg		    if (pWin->optional)
145805b261ecSmrg		    {
145905b261ecSmrg			pOldCursor = pWin->optional->cursor;
146005b261ecSmrg			pWin->optional->cursor = (CursorPtr) None;
146105b261ecSmrg			checkOptional = TRUE;
146205b261ecSmrg		    }
146305b261ecSmrg		} else {
146405b261ecSmrg		    if (!pWin->optional)
146505b261ecSmrg		    {
146605b261ecSmrg			if (!MakeWindowOptional (pWin))
146705b261ecSmrg			{
146805b261ecSmrg			    error = BadAlloc;
146905b261ecSmrg			    goto PatchUp;
147005b261ecSmrg			}
147105b261ecSmrg		    }
147205b261ecSmrg		    else if (pWin->parent && pCursor == wCursor (pWin->parent))
147305b261ecSmrg			checkOptional = TRUE;
147405b261ecSmrg		    pOldCursor = pWin->optional->cursor;
147505b261ecSmrg		    pWin->optional->cursor = pCursor;
147605b261ecSmrg		    pCursor->refcnt++;
147705b261ecSmrg		    pWin->cursorIsNone = FALSE;
147805b261ecSmrg		    /*
147905b261ecSmrg		     * check on any children now matching the new cursor
148005b261ecSmrg		     */
148105b261ecSmrg
148205b261ecSmrg		    for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
148305b261ecSmrg		    {
148405b261ecSmrg			if (pChild->optional &&
148505b261ecSmrg			    (pChild->optional->cursor == pCursor))
148605b261ecSmrg			    CheckWindowOptionalNeed (pChild);
148705b261ecSmrg		    }
148805b261ecSmrg		}
148905b261ecSmrg
149005b261ecSmrg		if (pWin->realized)
149105b261ecSmrg		    WindowHasNewCursor( pWin);
149205b261ecSmrg
149305b261ecSmrg		/* Can't free cursor until here - old cursor
149405b261ecSmrg		 * is needed in WindowHasNewCursor
149505b261ecSmrg		 */
149605b261ecSmrg		if (pOldCursor)
149705b261ecSmrg		    FreeCursor (pOldCursor, (Cursor)0);
149805b261ecSmrg	    }
149905b261ecSmrg	    break;
150005b261ecSmrg	 default:
150105b261ecSmrg	    error = BadValue;
150205b261ecSmrg	    client->errorValue = vmask;
150305b261ecSmrg	    goto PatchUp;
150405b261ecSmrg      }
150505b261ecSmrg      vmaskCopy |= index2;
150605b261ecSmrg    }
150705b261ecSmrgPatchUp:
150805b261ecSmrg    if (checkOptional)
150905b261ecSmrg	CheckWindowOptionalNeed (pWin);
151005b261ecSmrg
151105b261ecSmrg	/* We SHOULD check for an error value here XXX */
151205b261ecSmrg    (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
151305b261ecSmrg
151405b261ecSmrg    /*
151505b261ecSmrg	If the border contents have changed, redraw the border.
151605b261ecSmrg	Note that this has to be done AFTER pScreen->ChangeWindowAttributes
151705b261ecSmrg	for the tile to be rotated, and the correct function selected.
151805b261ecSmrg    */
151905b261ecSmrg    if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
152005b261ecSmrg	&& pWin->viewable && HasBorder (pWin))
152105b261ecSmrg    {
152205b261ecSmrg	RegionRec exposed;
152305b261ecSmrg
152405b261ecSmrg	REGION_NULL(pScreen, &exposed);
152505b261ecSmrg	REGION_SUBTRACT(pScreen, &exposed, &pWin->borderClip, &pWin->winSize);
152605b261ecSmrg	(*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
152705b261ecSmrg	REGION_UNINIT(pScreen, &exposed);
152805b261ecSmrg    }
152905b261ecSmrg    return error;
153005b261ecSmrg}
153105b261ecSmrg
153205b261ecSmrg
153305b261ecSmrg/*****
153405b261ecSmrg * GetWindowAttributes
153505b261ecSmrg *    Notice that this is different than ChangeWindowAttributes
153605b261ecSmrg *****/
153705b261ecSmrg
153805b261ecSmrgvoid
153905b261ecSmrgGetWindowAttributes(WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa)
154005b261ecSmrg{
154105b261ecSmrg    wa->type = X_Reply;
154205b261ecSmrg    wa->bitGravity = pWin->bitGravity;
154305b261ecSmrg    wa->winGravity = pWin->winGravity;
154405b261ecSmrg    if (pWin->forcedBS && pWin->backingStore != Always)
154505b261ecSmrg	wa->backingStore = NotUseful;
154605b261ecSmrg    else
154705b261ecSmrg	wa->backingStore = pWin->backingStore;
154805b261ecSmrg    wa->length = (sizeof(xGetWindowAttributesReply) -
154905b261ecSmrg		 sizeof(xGenericReply)) >> 2;
155005b261ecSmrg    wa->sequenceNumber = client->sequence;
155105b261ecSmrg    wa->backingBitPlanes =  wBackingBitPlanes (pWin);
155205b261ecSmrg    wa->backingPixel =  wBackingPixel (pWin);
155305b261ecSmrg    wa->saveUnder = (BOOL)pWin->saveUnder;
155405b261ecSmrg    wa->override = pWin->overrideRedirect;
155505b261ecSmrg    if (!pWin->mapped)
155605b261ecSmrg	wa->mapState = IsUnmapped;
155705b261ecSmrg    else if (pWin->realized)
155805b261ecSmrg	wa->mapState = IsViewable;
155905b261ecSmrg    else
156005b261ecSmrg	wa->mapState = IsUnviewable;
156105b261ecSmrg
156205b261ecSmrg    wa->colormap =  wColormap (pWin);
156305b261ecSmrg    wa->mapInstalled = (wa->colormap == None) ? xFalse
156405b261ecSmrg				: IsMapInstalled(wa->colormap, pWin);
156505b261ecSmrg
156605b261ecSmrg    wa->yourEventMask = EventMaskForClient(pWin, client);
156705b261ecSmrg    wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
156805b261ecSmrg    wa->doNotPropagateMask = wDontPropagateMask (pWin);
156905b261ecSmrg    wa->class = pWin->drawable.class;
157005b261ecSmrg    wa->visualID = wVisual (pWin);
157105b261ecSmrg}
157205b261ecSmrg
157305b261ecSmrg
157405b261ecSmrg_X_EXPORT WindowPtr
157505b261ecSmrgMoveWindowInStack(WindowPtr pWin, WindowPtr pNextSib)
157605b261ecSmrg{
157705b261ecSmrg    WindowPtr pParent = pWin->parent;
157805b261ecSmrg    WindowPtr pFirstChange = pWin; /* highest window where list changes */
157905b261ecSmrg
158005b261ecSmrg    if (pWin->nextSib != pNextSib)
158105b261ecSmrg    {
158205b261ecSmrg	WindowPtr pOldNextSib = pWin->nextSib;
158305b261ecSmrg
158405b261ecSmrg	if (!pNextSib)	      /* move to bottom */
158505b261ecSmrg	{
158605b261ecSmrg	    if (pParent->firstChild == pWin)
158705b261ecSmrg		pParent->firstChild = pWin->nextSib;
158805b261ecSmrg	    /* if (pWin->nextSib) */	 /* is always True: pNextSib == NULL
158905b261ecSmrg					  * and pWin->nextSib != pNextSib
159005b261ecSmrg					  * therefore pWin->nextSib != NULL */
159105b261ecSmrg	    pFirstChange = pWin->nextSib;
159205b261ecSmrg	    pWin->nextSib->prevSib = pWin->prevSib;
159305b261ecSmrg	    if (pWin->prevSib)
159405b261ecSmrg		pWin->prevSib->nextSib = pWin->nextSib;
159505b261ecSmrg	    pParent->lastChild->nextSib = pWin;
159605b261ecSmrg	    pWin->prevSib = pParent->lastChild;
159705b261ecSmrg	    pWin->nextSib = NullWindow;
159805b261ecSmrg	    pParent->lastChild = pWin;
159905b261ecSmrg	}
160005b261ecSmrg	else if (pParent->firstChild == pNextSib) /* move to top */
160105b261ecSmrg	{
160205b261ecSmrg	    pFirstChange = pWin;
160305b261ecSmrg	    if (pParent->lastChild == pWin)
160405b261ecSmrg	       pParent->lastChild = pWin->prevSib;
160505b261ecSmrg	    if (pWin->nextSib)
160605b261ecSmrg		pWin->nextSib->prevSib = pWin->prevSib;
160705b261ecSmrg	    if (pWin->prevSib)
160805b261ecSmrg		pWin->prevSib->nextSib = pWin->nextSib;
160905b261ecSmrg	    pWin->nextSib = pParent->firstChild;
161005b261ecSmrg	    pWin->prevSib = (WindowPtr ) NULL;
161105b261ecSmrg	    pNextSib->prevSib = pWin;
161205b261ecSmrg	    pParent->firstChild = pWin;
161305b261ecSmrg	}
161405b261ecSmrg	else			/* move in middle of list */
161505b261ecSmrg	{
161605b261ecSmrg	    WindowPtr pOldNext = pWin->nextSib;
161705b261ecSmrg
161805b261ecSmrg	    pFirstChange = NullWindow;
161905b261ecSmrg	    if (pParent->firstChild == pWin)
162005b261ecSmrg		pFirstChange = pParent->firstChild = pWin->nextSib;
162105b261ecSmrg	    if (pParent->lastChild == pWin) {
162205b261ecSmrg	       pFirstChange = pWin;
162305b261ecSmrg	       pParent->lastChild = pWin->prevSib;
162405b261ecSmrg	    }
162505b261ecSmrg	    if (pWin->nextSib)
162605b261ecSmrg		pWin->nextSib->prevSib = pWin->prevSib;
162705b261ecSmrg	    if (pWin->prevSib)
162805b261ecSmrg		pWin->prevSib->nextSib = pWin->nextSib;
162905b261ecSmrg	    pWin->nextSib = pNextSib;
163005b261ecSmrg	    pWin->prevSib = pNextSib->prevSib;
163105b261ecSmrg	    if (pNextSib->prevSib)
163205b261ecSmrg		pNextSib->prevSib->nextSib = pWin;
163305b261ecSmrg	    pNextSib->prevSib = pWin;
163405b261ecSmrg	    if (!pFirstChange) {		     /* do we know it yet? */
163505b261ecSmrg		pFirstChange = pParent->firstChild;  /* no, search from top */
163605b261ecSmrg		while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
163705b261ecSmrg		     pFirstChange = pFirstChange->nextSib;
163805b261ecSmrg	    }
163905b261ecSmrg	}
164005b261ecSmrg	if(pWin->drawable.pScreen->RestackWindow)
164105b261ecSmrg	    (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
164205b261ecSmrg    }
164305b261ecSmrg
164405b261ecSmrg#ifdef ROOTLESS
164505b261ecSmrg    /*
164605b261ecSmrg     * In rootless mode we can't optimize away window restacks.
164705b261ecSmrg     * There may be non-X windows around, so even if the window
164805b261ecSmrg     * is in the correct position from X's point of view,
164905b261ecSmrg     * the underlying window system may want to reorder it.
165005b261ecSmrg     */
165105b261ecSmrg    else if (pWin->drawable.pScreen->RestackWindow)
165205b261ecSmrg        (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib);
165305b261ecSmrg#endif
165405b261ecSmrg
165505b261ecSmrg    return( pFirstChange );
165605b261ecSmrg}
165705b261ecSmrg
165805b261ecSmrg_X_EXPORT RegionPtr
165905b261ecSmrgCreateUnclippedWinSize (WindowPtr pWin)
166005b261ecSmrg{
166105b261ecSmrg    RegionPtr	pRgn;
166205b261ecSmrg    BoxRec	box;
166305b261ecSmrg
166405b261ecSmrg    box.x1 = pWin->drawable.x;
166505b261ecSmrg    box.y1 = pWin->drawable.y;
166605b261ecSmrg    box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
166705b261ecSmrg    box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
166805b261ecSmrg    pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
166905b261ecSmrg#ifdef SHAPE
167005b261ecSmrg    if (wBoundingShape (pWin) || wClipShape (pWin)) {
167105b261ecSmrg	ScreenPtr pScreen;
167205b261ecSmrg        pScreen = pWin->drawable.pScreen;
167305b261ecSmrg
167405b261ecSmrg	REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
167505b261ecSmrg			 - pWin->drawable.y);
167605b261ecSmrg	if (wBoundingShape (pWin))
167705b261ecSmrg	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
167805b261ecSmrg	if (wClipShape (pWin))
167905b261ecSmrg	    REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
168005b261ecSmrg	REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
168105b261ecSmrg    }
168205b261ecSmrg#endif
168305b261ecSmrg    return pRgn;
168405b261ecSmrg}
168505b261ecSmrg
168605b261ecSmrg_X_EXPORT void
168705b261ecSmrgSetWinSize (WindowPtr pWin)
168805b261ecSmrg{
168905b261ecSmrg#ifdef COMPOSITE
169005b261ecSmrg    if (pWin->redirectDraw != RedirectDrawNone)
169105b261ecSmrg    {
169205b261ecSmrg	BoxRec	box;
169305b261ecSmrg
169405b261ecSmrg	/*
169505b261ecSmrg	 * Redirected clients get clip list equal to their
169605b261ecSmrg	 * own geometry, not clipped to their parent
169705b261ecSmrg	 */
169805b261ecSmrg	box.x1 = pWin->drawable.x;
169905b261ecSmrg	box.y1 = pWin->drawable.y;
170005b261ecSmrg	box.x2 = pWin->drawable.x + pWin->drawable.width;
170105b261ecSmrg	box.y2 = pWin->drawable.y + pWin->drawable.height;
170205b261ecSmrg	REGION_RESET (pScreen, &pWin->winSize, &box);
170305b261ecSmrg    }
170405b261ecSmrg    else
170505b261ecSmrg#endif
170605b261ecSmrg    ClippedRegionFromBox(pWin->parent, &pWin->winSize,
170705b261ecSmrg			 pWin->drawable.x, pWin->drawable.y,
170805b261ecSmrg			 (int)pWin->drawable.width,
170905b261ecSmrg			 (int)pWin->drawable.height);
171005b261ecSmrg#ifdef SHAPE
171105b261ecSmrg    if (wBoundingShape (pWin) || wClipShape (pWin)) {
171205b261ecSmrg	ScreenPtr pScreen;
171305b261ecSmrg        pScreen = pWin->drawable.pScreen;
171405b261ecSmrg
171505b261ecSmrg	REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
171605b261ecSmrg			 - pWin->drawable.y);
171705b261ecSmrg	if (wBoundingShape (pWin))
171805b261ecSmrg	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
171905b261ecSmrg			     wBoundingShape (pWin));
172005b261ecSmrg	if (wClipShape (pWin))
172105b261ecSmrg	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
172205b261ecSmrg			     wClipShape (pWin));
172305b261ecSmrg	REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
172405b261ecSmrg			 pWin->drawable.y);
172505b261ecSmrg    }
172605b261ecSmrg#endif
172705b261ecSmrg}
172805b261ecSmrg
172905b261ecSmrg_X_EXPORT void
173005b261ecSmrgSetBorderSize (WindowPtr pWin)
173105b261ecSmrg{
173205b261ecSmrg    int	bw;
173305b261ecSmrg
173405b261ecSmrg    if (HasBorder (pWin)) {
173505b261ecSmrg	bw = wBorderWidth (pWin);
173605b261ecSmrg#ifdef COMPOSITE
173705b261ecSmrg	if (pWin->redirectDraw != RedirectDrawNone)
173805b261ecSmrg	{
173905b261ecSmrg	    BoxRec	box;
174005b261ecSmrg
174105b261ecSmrg	    /*
174205b261ecSmrg	     * Redirected clients get clip list equal to their
174305b261ecSmrg	     * own geometry, not clipped to their parent
174405b261ecSmrg	     */
174505b261ecSmrg	    box.x1 = pWin->drawable.x - bw;
174605b261ecSmrg	    box.y1 = pWin->drawable.y - bw;
174705b261ecSmrg	    box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
174805b261ecSmrg	    box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
174905b261ecSmrg	    REGION_RESET (pScreen, &pWin->borderSize, &box);
175005b261ecSmrg	}
175105b261ecSmrg	else
175205b261ecSmrg#endif
175305b261ecSmrg	ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
175405b261ecSmrg		pWin->drawable.x - bw, pWin->drawable.y - bw,
175505b261ecSmrg		(int)(pWin->drawable.width + (bw<<1)),
175605b261ecSmrg		(int)(pWin->drawable.height + (bw<<1)));
175705b261ecSmrg#ifdef SHAPE
175805b261ecSmrg	if (wBoundingShape (pWin)) {
175905b261ecSmrg	    ScreenPtr pScreen;
176005b261ecSmrg            pScreen = pWin->drawable.pScreen;
176105b261ecSmrg
176205b261ecSmrg	    REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
176305b261ecSmrg			     - pWin->drawable.y);
176405b261ecSmrg	    REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
176505b261ecSmrg			     wBoundingShape (pWin));
176605b261ecSmrg	    REGION_TRANSLATE(pScreen, &pWin->borderSize, pWin->drawable.x,
176705b261ecSmrg			     pWin->drawable.y);
176805b261ecSmrg	    REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
176905b261ecSmrg			 &pWin->winSize);
177005b261ecSmrg	}
177105b261ecSmrg#endif
177205b261ecSmrg    } else {
177305b261ecSmrg	REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
177405b261ecSmrg					       &pWin->winSize);
177505b261ecSmrg    }
177605b261ecSmrg}
177705b261ecSmrg
177805b261ecSmrg/**
177905b261ecSmrg *
178005b261ecSmrg *  \param x,y          new window position
178105b261ecSmrg *  \param oldx,oldy    old window position
178205b261ecSmrg *  \param destx,desty  position relative to gravity
178305b261ecSmrg */
178405b261ecSmrg
178505b261ecSmrg_X_EXPORT void
178605b261ecSmrgGravityTranslate (int x, int y, int oldx, int oldy,
178705b261ecSmrg                  int dw, int dh, unsigned gravity,
178805b261ecSmrg                  int *destx, int *desty)
178905b261ecSmrg{
179005b261ecSmrg    switch (gravity) {
179105b261ecSmrg    case NorthGravity:
179205b261ecSmrg	*destx = x + dw / 2;
179305b261ecSmrg	*desty = y;
179405b261ecSmrg	break;
179505b261ecSmrg    case NorthEastGravity:
179605b261ecSmrg	*destx = x + dw;
179705b261ecSmrg	*desty = y;
179805b261ecSmrg	break;
179905b261ecSmrg    case WestGravity:
180005b261ecSmrg	*destx = x;
180105b261ecSmrg	*desty = y + dh / 2;
180205b261ecSmrg	break;
180305b261ecSmrg    case CenterGravity:
180405b261ecSmrg	*destx = x + dw / 2;
180505b261ecSmrg	*desty = y + dh / 2;
180605b261ecSmrg	break;
180705b261ecSmrg    case EastGravity:
180805b261ecSmrg	*destx = x + dw;
180905b261ecSmrg	*desty = y + dh / 2;
181005b261ecSmrg	break;
181105b261ecSmrg    case SouthWestGravity:
181205b261ecSmrg	*destx = x;
181305b261ecSmrg	*desty = y + dh;
181405b261ecSmrg	break;
181505b261ecSmrg    case SouthGravity:
181605b261ecSmrg	*destx = x + dw / 2;
181705b261ecSmrg	*desty = y + dh;
181805b261ecSmrg	break;
181905b261ecSmrg    case SouthEastGravity:
182005b261ecSmrg	*destx = x + dw;
182105b261ecSmrg	*desty = y + dh;
182205b261ecSmrg	break;
182305b261ecSmrg    case StaticGravity:
182405b261ecSmrg	*destx = oldx;
182505b261ecSmrg	*desty = oldy;
182605b261ecSmrg	break;
182705b261ecSmrg    default:
182805b261ecSmrg	*destx = x;
182905b261ecSmrg	*desty = y;
183005b261ecSmrg	break;
183105b261ecSmrg    }
183205b261ecSmrg}
183305b261ecSmrg
183405b261ecSmrg/* XXX need to retile border on each window with ParentRelative origin */
183505b261ecSmrg_X_EXPORT void
183605b261ecSmrgResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh)
183705b261ecSmrg{
183805b261ecSmrg    ScreenPtr pScreen;
183905b261ecSmrg    WindowPtr pSib, pChild;
184005b261ecSmrg    Bool resized = (dw || dh);
184105b261ecSmrg
184205b261ecSmrg    pScreen = pWin->drawable.pScreen;
184305b261ecSmrg
184405b261ecSmrg    for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
184505b261ecSmrg    {
184605b261ecSmrg	if (resized && (pSib->winGravity > NorthWestGravity))
184705b261ecSmrg	{
184805b261ecSmrg	    int cwsx, cwsy;
184905b261ecSmrg
185005b261ecSmrg	    cwsx = pSib->origin.x;
185105b261ecSmrg	    cwsy = pSib->origin.y;
185205b261ecSmrg	    GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
185305b261ecSmrg			pSib->winGravity, &cwsx, &cwsy);
185405b261ecSmrg	    if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
185505b261ecSmrg	    {
185605b261ecSmrg		xEvent event;
185705b261ecSmrg
185805b261ecSmrg		event.u.u.type = GravityNotify;
185905b261ecSmrg		event.u.gravity.window = pSib->drawable.id;
186005b261ecSmrg		event.u.gravity.x = cwsx - wBorderWidth (pSib);
186105b261ecSmrg		event.u.gravity.y = cwsy - wBorderWidth (pSib);
186205b261ecSmrg		DeliverEvents (pSib, &event, 1, NullWindow);
186305b261ecSmrg		pSib->origin.x = cwsx;
186405b261ecSmrg		pSib->origin.y = cwsy;
186505b261ecSmrg	    }
186605b261ecSmrg	}
186705b261ecSmrg	pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
186805b261ecSmrg	pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
186905b261ecSmrg	SetWinSize (pSib);
187005b261ecSmrg	SetBorderSize (pSib);
187105b261ecSmrg	(*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
187205b261ecSmrg
187305b261ecSmrg	if ( (pChild = pSib->firstChild) )
187405b261ecSmrg	{
187505b261ecSmrg	    while (1)
187605b261ecSmrg	    {
187705b261ecSmrg		pChild->drawable.x = pChild->parent->drawable.x +
187805b261ecSmrg				     pChild->origin.x;
187905b261ecSmrg		pChild->drawable.y = pChild->parent->drawable.y +
188005b261ecSmrg				     pChild->origin.y;
188105b261ecSmrg		SetWinSize (pChild);
188205b261ecSmrg		SetBorderSize (pChild);
188305b261ecSmrg		(*pScreen->PositionWindow)(pChild,
188405b261ecSmrg				    pChild->drawable.x, pChild->drawable.y);
188505b261ecSmrg		if (pChild->firstChild)
188605b261ecSmrg		{
188705b261ecSmrg		    pChild = pChild->firstChild;
188805b261ecSmrg		    continue;
188905b261ecSmrg		}
189005b261ecSmrg		while (!pChild->nextSib && (pChild != pSib))
189105b261ecSmrg		    pChild = pChild->parent;
189205b261ecSmrg		if (pChild == pSib)
189305b261ecSmrg		    break;
189405b261ecSmrg		pChild = pChild->nextSib;
189505b261ecSmrg	    }
189605b261ecSmrg	}
189705b261ecSmrg    }
189805b261ecSmrg}
189905b261ecSmrg
190005b261ecSmrg#define GET_INT16(m, f) \
190105b261ecSmrg	if (m & mask) \
190205b261ecSmrg	  { \
190305b261ecSmrg	     f = (INT16) *pVlist;\
190405b261ecSmrg	    pVlist++; \
190505b261ecSmrg	 }
190605b261ecSmrg#define GET_CARD16(m, f) \
190705b261ecSmrg	if (m & mask) \
190805b261ecSmrg	 { \
190905b261ecSmrg	    f = (CARD16) *pVlist;\
191005b261ecSmrg	    pVlist++;\
191105b261ecSmrg	 }
191205b261ecSmrg
191305b261ecSmrg#define GET_CARD8(m, f) \
191405b261ecSmrg	if (m & mask) \
191505b261ecSmrg	 { \
191605b261ecSmrg	    f = (CARD8) *pVlist;\
191705b261ecSmrg	    pVlist++;\
191805b261ecSmrg	 }
191905b261ecSmrg
192005b261ecSmrg#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
192105b261ecSmrg
192205b261ecSmrg#define IllegalInputOnlyConfigureMask (CWBorderWidth)
192305b261ecSmrg
192405b261ecSmrg/*
192505b261ecSmrg * IsSiblingAboveMe
192605b261ecSmrg *     returns Above if pSib above pMe in stack or Below otherwise
192705b261ecSmrg */
192805b261ecSmrg
192905b261ecSmrgstatic int
193005b261ecSmrgIsSiblingAboveMe(
193105b261ecSmrg    WindowPtr pMe,
193205b261ecSmrg    WindowPtr pSib)
193305b261ecSmrg{
193405b261ecSmrg    WindowPtr pWin;
193505b261ecSmrg
193605b261ecSmrg    pWin = pMe->parent->firstChild;
193705b261ecSmrg    while (pWin)
193805b261ecSmrg    {
193905b261ecSmrg	if (pWin == pSib)
194005b261ecSmrg	    return(Above);
194105b261ecSmrg	else if (pWin == pMe)
194205b261ecSmrg	    return(Below);
194305b261ecSmrg	pWin = pWin->nextSib;
194405b261ecSmrg    }
194505b261ecSmrg    return(Below);
194605b261ecSmrg}
194705b261ecSmrg
194805b261ecSmrgstatic BoxPtr
194905b261ecSmrgWindowExtents(
195005b261ecSmrg    WindowPtr pWin,
195105b261ecSmrg    BoxPtr pBox)
195205b261ecSmrg{
195305b261ecSmrg    pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
195405b261ecSmrg    pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
195505b261ecSmrg    pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
195605b261ecSmrg	       + wBorderWidth (pWin);
195705b261ecSmrg    pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
195805b261ecSmrg	       + wBorderWidth (pWin);
195905b261ecSmrg    return(pBox);
196005b261ecSmrg}
196105b261ecSmrg
196205b261ecSmrg#ifdef SHAPE
196305b261ecSmrg#define IS_SHAPED(pWin)	(wBoundingShape (pWin) != (RegionPtr) NULL)
196405b261ecSmrg
196505b261ecSmrgstatic RegionPtr
196605b261ecSmrgMakeBoundingRegion (
196705b261ecSmrg    WindowPtr	pWin,
196805b261ecSmrg    BoxPtr	pBox)
196905b261ecSmrg{
197005b261ecSmrg    RegionPtr	pRgn;
197105b261ecSmrg    ScreenPtr   pScreen;
197205b261ecSmrg    pScreen = pWin->drawable.pScreen;
197305b261ecSmrg
197405b261ecSmrg    pRgn = REGION_CREATE(pScreen, pBox, 1);
197505b261ecSmrg    if (wBoundingShape (pWin)) {
197605b261ecSmrg	    REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
197705b261ecSmrg						  -pWin->origin.y);
197805b261ecSmrg	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
197905b261ecSmrg	    REGION_TRANSLATE(pScreen, pRgn, pWin->origin.x,
198005b261ecSmrg						  pWin->origin.y);
198105b261ecSmrg    }
198205b261ecSmrg    return pRgn;
198305b261ecSmrg}
198405b261ecSmrg
198505b261ecSmrgstatic Bool
198605b261ecSmrgShapeOverlap (
198705b261ecSmrg    WindowPtr	pWin,
198805b261ecSmrg    BoxPtr	pWinBox,
198905b261ecSmrg    WindowPtr	pSib,
199005b261ecSmrg    BoxPtr	pSibBox)
199105b261ecSmrg{
199205b261ecSmrg    RegionPtr	pWinRgn, pSibRgn;
199305b261ecSmrg    ScreenPtr	pScreen;
199405b261ecSmrg    Bool	ret;
199505b261ecSmrg
199605b261ecSmrg    if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
199705b261ecSmrg	return TRUE;
199805b261ecSmrg    pScreen = pWin->drawable.pScreen;
199905b261ecSmrg    pWinRgn = MakeBoundingRegion (pWin, pWinBox);
200005b261ecSmrg    pSibRgn = MakeBoundingRegion (pSib, pSibBox);
200105b261ecSmrg    REGION_INTERSECT(pScreen, pWinRgn, pWinRgn, pSibRgn);
200205b261ecSmrg    ret = REGION_NOTEMPTY(pScreen, pWinRgn);
200305b261ecSmrg    REGION_DESTROY(pScreen, pWinRgn);
200405b261ecSmrg    REGION_DESTROY(pScreen, pSibRgn);
200505b261ecSmrg    return ret;
200605b261ecSmrg}
200705b261ecSmrg#endif
200805b261ecSmrg
200905b261ecSmrgstatic Bool
201005b261ecSmrgAnyWindowOverlapsMe(
201105b261ecSmrg    WindowPtr pWin,
201205b261ecSmrg    WindowPtr pHead,
201305b261ecSmrg    BoxPtr box)
201405b261ecSmrg{
201505b261ecSmrg    WindowPtr pSib;
201605b261ecSmrg    BoxRec sboxrec;
201705b261ecSmrg    BoxPtr sbox;
201805b261ecSmrg
201905b261ecSmrg    for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
202005b261ecSmrg    {
202105b261ecSmrg	if (pSib->mapped)
202205b261ecSmrg	{
202305b261ecSmrg	    sbox = WindowExtents(pSib, &sboxrec);
202405b261ecSmrg	    if (BOXES_OVERLAP(sbox, box)
202505b261ecSmrg#ifdef SHAPE
202605b261ecSmrg	    && ShapeOverlap (pWin, box, pSib, sbox)
202705b261ecSmrg#endif
202805b261ecSmrg	    )
202905b261ecSmrg		return(TRUE);
203005b261ecSmrg	}
203105b261ecSmrg    }
203205b261ecSmrg    return(FALSE);
203305b261ecSmrg}
203405b261ecSmrg
203505b261ecSmrgstatic Bool
203605b261ecSmrgIOverlapAnyWindow(
203705b261ecSmrg    WindowPtr pWin,
203805b261ecSmrg    BoxPtr box)
203905b261ecSmrg{
204005b261ecSmrg    WindowPtr pSib;
204105b261ecSmrg    BoxRec sboxrec;
204205b261ecSmrg    BoxPtr sbox;
204305b261ecSmrg
204405b261ecSmrg    for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
204505b261ecSmrg    {
204605b261ecSmrg	if (pSib->mapped)
204705b261ecSmrg	{
204805b261ecSmrg	    sbox = WindowExtents(pSib, &sboxrec);
204905b261ecSmrg	    if (BOXES_OVERLAP(sbox, box)
205005b261ecSmrg#ifdef SHAPE
205105b261ecSmrg	    && ShapeOverlap (pWin, box, pSib, sbox)
205205b261ecSmrg#endif
205305b261ecSmrg	    )
205405b261ecSmrg		return(TRUE);
205505b261ecSmrg	}
205605b261ecSmrg    }
205705b261ecSmrg    return(FALSE);
205805b261ecSmrg}
205905b261ecSmrg
206005b261ecSmrg/*
206105b261ecSmrg *   WhereDoIGoInTheStack()
206205b261ecSmrg *	  Given pWin and pSib and the relationshipe smode, return
206305b261ecSmrg *	  the window that pWin should go ABOVE.
206405b261ecSmrg *	  If a pSib is specified:
206505b261ecSmrg *	      Above:  pWin is placed just above pSib
206605b261ecSmrg *	      Below:  pWin is placed just below pSib
206705b261ecSmrg *	      TopIf:  if pSib occludes pWin, then pWin is placed
206805b261ecSmrg *		      at the top of the stack
206905b261ecSmrg *	      BottomIf:	 if pWin occludes pSib, then pWin is
207005b261ecSmrg *			 placed at the bottom of the stack
207105b261ecSmrg *	      Opposite: if pSib occludes pWin, then pWin is placed at the
207205b261ecSmrg *			top of the stack, else if pWin occludes pSib, then
207305b261ecSmrg *			pWin is placed at the bottom of the stack
207405b261ecSmrg *
207505b261ecSmrg *	  If pSib is NULL:
207605b261ecSmrg *	      Above:  pWin is placed at the top of the stack
207705b261ecSmrg *	      Below:  pWin is placed at the bottom of the stack
207805b261ecSmrg *	      TopIf:  if any sibling occludes pWin, then pWin is placed at
207905b261ecSmrg *		      the top of the stack
208005b261ecSmrg *	      BottomIf: if pWin occludes any sibline, then pWin is placed at
208105b261ecSmrg *			the bottom of the stack
208205b261ecSmrg *	      Opposite: if any sibling occludes pWin, then pWin is placed at
208305b261ecSmrg *			the top of the stack, else if pWin occludes any
208405b261ecSmrg *			sibling, then pWin is placed at the bottom of the stack
208505b261ecSmrg *
208605b261ecSmrg */
208705b261ecSmrg
208805b261ecSmrgstatic WindowPtr
208905b261ecSmrgWhereDoIGoInTheStack(
209005b261ecSmrg    WindowPtr pWin,
209105b261ecSmrg    WindowPtr pSib,
209205b261ecSmrg    short x,
209305b261ecSmrg    short y,
209405b261ecSmrg    unsigned short w,
209505b261ecSmrg    unsigned short h,
209605b261ecSmrg    int smode)
209705b261ecSmrg{
209805b261ecSmrg    BoxRec box;
209905b261ecSmrg    ScreenPtr pScreen;
210005b261ecSmrg    WindowPtr pHead, pFirst;
210105b261ecSmrg
210205b261ecSmrg    if ((pWin == pWin->parent->firstChild) &&
210305b261ecSmrg	(pWin == pWin->parent->lastChild))
210405b261ecSmrg	return((WindowPtr ) NULL);
210505b261ecSmrg    pHead = RealChildHead(pWin->parent);
210605b261ecSmrg    pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
210705b261ecSmrg    pScreen = pWin->drawable.pScreen;
210805b261ecSmrg    box.x1 = x;
210905b261ecSmrg    box.y1 = y;
211005b261ecSmrg    box.x2 = x + (int)w;
211105b261ecSmrg    box.y2 = y + (int)h;
211205b261ecSmrg    switch (smode)
211305b261ecSmrg    {
211405b261ecSmrg      case Above:
211505b261ecSmrg	if (pSib)
211605b261ecSmrg	   return(pSib);
211705b261ecSmrg	else if (pWin == pFirst)
211805b261ecSmrg	    return(pWin->nextSib);
211905b261ecSmrg	else
212005b261ecSmrg	    return(pFirst);
212105b261ecSmrg      case Below:
212205b261ecSmrg	if (pSib)
212305b261ecSmrg	    if (pSib->nextSib != pWin)
212405b261ecSmrg		return(pSib->nextSib);
212505b261ecSmrg	    else
212605b261ecSmrg		return(pWin->nextSib);
212705b261ecSmrg	else
212805b261ecSmrg	    return NullWindow;
212905b261ecSmrg      case TopIf:
213005b261ecSmrg	if ((!pWin->mapped || (pSib && !pSib->mapped)))
213105b261ecSmrg	    return(pWin->nextSib);
213205b261ecSmrg	else if (pSib)
213305b261ecSmrg	{
213405b261ecSmrg	    if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
213505b261ecSmrg		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
213605b261ecSmrg		return(pFirst);
213705b261ecSmrg	    else
213805b261ecSmrg		return(pWin->nextSib);
213905b261ecSmrg	}
214005b261ecSmrg	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
214105b261ecSmrg	    return(pFirst);
214205b261ecSmrg	else
214305b261ecSmrg	    return(pWin->nextSib);
214405b261ecSmrg      case BottomIf:
214505b261ecSmrg	if ((!pWin->mapped || (pSib && !pSib->mapped)))
214605b261ecSmrg	    return(pWin->nextSib);
214705b261ecSmrg	else if (pSib)
214805b261ecSmrg	{
214905b261ecSmrg	    if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
215005b261ecSmrg		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
215105b261ecSmrg		return NullWindow;
215205b261ecSmrg	    else
215305b261ecSmrg		return(pWin->nextSib);
215405b261ecSmrg	}
215505b261ecSmrg	else if (IOverlapAnyWindow(pWin, &box))
215605b261ecSmrg	    return NullWindow;
215705b261ecSmrg	else
215805b261ecSmrg	    return(pWin->nextSib);
215905b261ecSmrg      case Opposite:
216005b261ecSmrg	if ((!pWin->mapped || (pSib && !pSib->mapped)))
216105b261ecSmrg	    return(pWin->nextSib);
216205b261ecSmrg	else if (pSib)
216305b261ecSmrg	{
216405b261ecSmrg	    if (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT)
216505b261ecSmrg	    {
216605b261ecSmrg		if (IsSiblingAboveMe(pWin, pSib) == Above)
216705b261ecSmrg		    return(pFirst);
216805b261ecSmrg		else
216905b261ecSmrg		    return NullWindow;
217005b261ecSmrg	    }
217105b261ecSmrg	    else
217205b261ecSmrg		return(pWin->nextSib);
217305b261ecSmrg	}
217405b261ecSmrg	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
217505b261ecSmrg	{
217605b261ecSmrg	    /* If I'm occluded, I can't possibly be the first child
217705b261ecSmrg	     * if (pWin == pWin->parent->firstChild)
217805b261ecSmrg	     *	  return pWin->nextSib;
217905b261ecSmrg	     */
218005b261ecSmrg	    return(pFirst);
218105b261ecSmrg	}
218205b261ecSmrg	else if (IOverlapAnyWindow(pWin, &box))
218305b261ecSmrg	    return NullWindow;
218405b261ecSmrg	else
218505b261ecSmrg	    return pWin->nextSib;
218605b261ecSmrg      default:
218705b261ecSmrg      {
218805b261ecSmrg	ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
218905b261ecSmrg	return pWin->nextSib;
219005b261ecSmrg      }
219105b261ecSmrg    }
219205b261ecSmrg}
219305b261ecSmrg
219405b261ecSmrgstatic void
219505b261ecSmrgReflectStackChange(
219605b261ecSmrg    WindowPtr pWin,
219705b261ecSmrg    WindowPtr pSib,
219805b261ecSmrg    VTKind  kind)
219905b261ecSmrg{
220005b261ecSmrg/* Note that pSib might be NULL */
220105b261ecSmrg
220205b261ecSmrg    Bool WasViewable = (Bool)pWin->viewable;
220305b261ecSmrg    Bool anyMarked;
220405b261ecSmrg    WindowPtr pFirstChange;
220505b261ecSmrg#ifdef DO_SAVE_UNDERS
220605b261ecSmrg    Bool	dosave = FALSE;
220705b261ecSmrg#endif
220805b261ecSmrg    WindowPtr  pLayerWin;
220905b261ecSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
221005b261ecSmrg
221105b261ecSmrg    /* if this is a root window, can't be restacked */
221205b261ecSmrg    if (!pWin->parent)
221305b261ecSmrg	return;
221405b261ecSmrg
221505b261ecSmrg    pFirstChange = MoveWindowInStack(pWin, pSib);
221605b261ecSmrg
221705b261ecSmrg    if (WasViewable)
221805b261ecSmrg    {
221905b261ecSmrg	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
222005b261ecSmrg						      &pLayerWin);
222105b261ecSmrg	if (pLayerWin != pWin) pFirstChange = pLayerWin;
222205b261ecSmrg#ifdef DO_SAVE_UNDERS
222305b261ecSmrg	if (DO_SAVE_UNDERS(pWin))
222405b261ecSmrg	{
222505b261ecSmrg	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
222605b261ecSmrg	}
222705b261ecSmrg#endif /* DO_SAVE_UNDERS */
222805b261ecSmrg	if (anyMarked)
222905b261ecSmrg	{
223005b261ecSmrg	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
223105b261ecSmrg	    (*pScreen->HandleExposures)(pLayerWin->parent);
223205b261ecSmrg	}
223305b261ecSmrg#ifdef DO_SAVE_UNDERS
223405b261ecSmrg	if (dosave)
223505b261ecSmrg	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
223605b261ecSmrg#endif /* DO_SAVE_UNDERS */
223705b261ecSmrg	if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
223805b261ecSmrg	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
223905b261ecSmrg    }
224005b261ecSmrg    if (pWin->realized)
224105b261ecSmrg	WindowsRestructured ();
224205b261ecSmrg}
224305b261ecSmrg
224405b261ecSmrg/*****
224505b261ecSmrg * ConfigureWindow
224605b261ecSmrg *****/
224705b261ecSmrg
224805b261ecSmrgint
224905b261ecSmrgConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client)
225005b261ecSmrg{
225105b261ecSmrg#define RESTACK_WIN    0
225205b261ecSmrg#define MOVE_WIN       1
225305b261ecSmrg#define RESIZE_WIN     2
225405b261ecSmrg#define REBORDER_WIN   3
225505b261ecSmrg    WindowPtr pSib = NullWindow;
225605b261ecSmrg    WindowPtr pParent = pWin->parent;
225705b261ecSmrg    Window sibwid = 0;
225805b261ecSmrg    Mask index2, tmask;
225905b261ecSmrg    XID *pVlist;
226005b261ecSmrg    short x,   y, beforeX, beforeY;
226105b261ecSmrg    unsigned short w = pWin->drawable.width,
226205b261ecSmrg		   h = pWin->drawable.height,
226305b261ecSmrg		   bw = pWin->borderWidth;
226405b261ecSmrg    int action, smode = Above;
226505b261ecSmrg#ifdef XAPPGROUP
226605b261ecSmrg    ClientPtr win_owner;
226705b261ecSmrg    ClientPtr ag_leader = NULL;
226805b261ecSmrg#endif
226905b261ecSmrg    xEvent event;
227005b261ecSmrg
227105b261ecSmrg    if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
227205b261ecSmrg	return(BadMatch);
227305b261ecSmrg
227405b261ecSmrg    if ((mask & CWSibling) && !(mask & CWStackMode))
227505b261ecSmrg	return(BadMatch);
227605b261ecSmrg
227705b261ecSmrg    pVlist = vlist;
227805b261ecSmrg
227905b261ecSmrg    if (pParent)
228005b261ecSmrg    {
228105b261ecSmrg	x = pWin->drawable.x - pParent->drawable.x - (int)bw;
228205b261ecSmrg	y = pWin->drawable.y - pParent->drawable.y - (int)bw;
228305b261ecSmrg    }
228405b261ecSmrg    else
228505b261ecSmrg    {
228605b261ecSmrg	x = pWin->drawable.x;
228705b261ecSmrg	y = pWin->drawable.y;
228805b261ecSmrg    }
228905b261ecSmrg    beforeX = x;
229005b261ecSmrg    beforeY = y;
229105b261ecSmrg    action = RESTACK_WIN;
229205b261ecSmrg    if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
229305b261ecSmrg    {
229405b261ecSmrg	GET_INT16(CWX, x);
229505b261ecSmrg	GET_INT16(CWY, y);
229605b261ecSmrg	action = MOVE_WIN;
229705b261ecSmrg    }
229805b261ecSmrg	/* or should be resized */
229905b261ecSmrg    else if (mask & (CWX |  CWY | CWWidth | CWHeight))
230005b261ecSmrg    {
230105b261ecSmrg	GET_INT16(CWX, x);
230205b261ecSmrg	GET_INT16(CWY, y);
230305b261ecSmrg	GET_CARD16(CWWidth, w);
230405b261ecSmrg	GET_CARD16 (CWHeight, h);
230505b261ecSmrg	if (!w || !h)
230605b261ecSmrg	{
230705b261ecSmrg	    client->errorValue = 0;
230805b261ecSmrg	    return BadValue;
230905b261ecSmrg	}
231005b261ecSmrg	action = RESIZE_WIN;
231105b261ecSmrg    }
231205b261ecSmrg    tmask = mask & ~ChangeMask;
231305b261ecSmrg    while (tmask)
231405b261ecSmrg    {
231505b261ecSmrg	index2 = (Mask)lowbit (tmask);
231605b261ecSmrg	tmask &= ~index2;
231705b261ecSmrg	switch (index2)
231805b261ecSmrg	{
231905b261ecSmrg	  case CWBorderWidth:
232005b261ecSmrg	    GET_CARD16(CWBorderWidth, bw);
232105b261ecSmrg	    break;
232205b261ecSmrg	  case CWSibling:
232305b261ecSmrg	    sibwid = (Window ) *pVlist;
232405b261ecSmrg	    pVlist++;
232505b261ecSmrg	    pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
232605b261ecSmrg						RT_WINDOW, DixReadAccess);
232705b261ecSmrg	    if (!pSib)
232805b261ecSmrg	    {
232905b261ecSmrg		client->errorValue = sibwid;
233005b261ecSmrg		return(BadWindow);
233105b261ecSmrg	    }
233205b261ecSmrg	    if (pSib->parent != pParent)
233305b261ecSmrg		return(BadMatch);
233405b261ecSmrg	    if (pSib == pWin)
233505b261ecSmrg		return(BadMatch);
233605b261ecSmrg	    break;
233705b261ecSmrg	  case CWStackMode:
233805b261ecSmrg	    GET_CARD8(CWStackMode, smode);
233905b261ecSmrg	    if ((smode != TopIf) && (smode != BottomIf) &&
234005b261ecSmrg		(smode != Opposite) && (smode != Above) && (smode != Below))
234105b261ecSmrg	    {
234205b261ecSmrg		client->errorValue = smode;
234305b261ecSmrg		return(BadValue);
234405b261ecSmrg	    }
234505b261ecSmrg	    break;
234605b261ecSmrg	  default:
234705b261ecSmrg	    client->errorValue = mask;
234805b261ecSmrg	    return(BadValue);
234905b261ecSmrg	}
235005b261ecSmrg    }
235105b261ecSmrg	/* root really can't be reconfigured, so just return */
235205b261ecSmrg    if (!pParent)
235305b261ecSmrg	return Success;
235405b261ecSmrg
235505b261ecSmrg	/* Figure out if the window should be moved.  Doesnt
235605b261ecSmrg	   make the changes to the window if event sent */
235705b261ecSmrg
235805b261ecSmrg    if (mask & CWStackMode)
235905b261ecSmrg	pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
236005b261ecSmrg				    pParent->drawable.y + y,
236105b261ecSmrg				    w + (bw << 1), h + (bw << 1), smode);
236205b261ecSmrg    else
236305b261ecSmrg	pSib = pWin->nextSib;
236405b261ecSmrg
236505b261ecSmrg#ifdef XAPPGROUP
236605b261ecSmrg    win_owner = clients[CLIENT_ID(pWin->drawable.id)];
236705b261ecSmrg    ag_leader = XagLeader (win_owner);
236805b261ecSmrg#endif
236905b261ecSmrg
237005b261ecSmrg    if ((!pWin->overrideRedirect) &&
237105b261ecSmrg	(RedirectSend(pParent)
237205b261ecSmrg#ifdef XAPPGROUP
237305b261ecSmrg	|| (win_owner->appgroup && ag_leader &&
237405b261ecSmrg	    XagIsControlledRoot (client, pParent))
237505b261ecSmrg#endif
237605b261ecSmrg	))
237705b261ecSmrg    {
237805b261ecSmrg	event.u.u.type = ConfigureRequest;
237905b261ecSmrg	event.u.configureRequest.window = pWin->drawable.id;
238005b261ecSmrg	if (mask & CWSibling)
238105b261ecSmrg	   event.u.configureRequest.sibling = sibwid;
238205b261ecSmrg	else
238305b261ecSmrg	    event.u.configureRequest.sibling = None;
238405b261ecSmrg	if (mask & CWStackMode)
238505b261ecSmrg	   event.u.u.detail = smode;
238605b261ecSmrg	else
238705b261ecSmrg	    event.u.u.detail = Above;
238805b261ecSmrg	event.u.configureRequest.x = x;
238905b261ecSmrg	event.u.configureRequest.y = y;
239005b261ecSmrg#ifdef PANORAMIX
239105b261ecSmrg	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
239205b261ecSmrg            event.u.configureRequest.x += panoramiXdataPtr[0].x;
239305b261ecSmrg            event.u.configureRequest.y += panoramiXdataPtr[0].y;
239405b261ecSmrg	}
239505b261ecSmrg#endif
239605b261ecSmrg	event.u.configureRequest.width = w;
239705b261ecSmrg	event.u.configureRequest.height = h;
239805b261ecSmrg	event.u.configureRequest.borderWidth = bw;
239905b261ecSmrg	event.u.configureRequest.valueMask = mask;
240005b261ecSmrg#ifdef XAPPGROUP
240105b261ecSmrg	/* make sure if the ag_leader maps the window it goes to the wm */
240205b261ecSmrg	if (ag_leader && ag_leader != client &&
240305b261ecSmrg	    XagIsControlledRoot (client, pParent)) {
240405b261ecSmrg	    event.u.configureRequest.parent = XagId (win_owner);
240505b261ecSmrg	    (void) TryClientEvents (ag_leader, &event, 1,
240605b261ecSmrg				    NoEventMask, NoEventMask, NullGrab);
240705b261ecSmrg	    return Success;
240805b261ecSmrg	}
240905b261ecSmrg#endif
241005b261ecSmrg	event.u.configureRequest.parent = pParent->drawable.id;
241105b261ecSmrg	if (MaybeDeliverEventsToClient(pParent, &event, 1,
241205b261ecSmrg		SubstructureRedirectMask, client) == 1)
241305b261ecSmrg	    return(Success);
241405b261ecSmrg    }
241505b261ecSmrg    if (action == RESIZE_WIN)
241605b261ecSmrg    {
241705b261ecSmrg	Bool size_change = (w != pWin->drawable.width)
241805b261ecSmrg			|| (h != pWin->drawable.height);
241905b261ecSmrg	if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
242005b261ecSmrg	{
242105b261ecSmrg	    xEvent eventT;
242205b261ecSmrg	    eventT.u.u.type = ResizeRequest;
242305b261ecSmrg	    eventT.u.resizeRequest.window = pWin->drawable.id;
242405b261ecSmrg	    eventT.u.resizeRequest.width = w;
242505b261ecSmrg	    eventT.u.resizeRequest.height = h;
242605b261ecSmrg	    if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
242705b261ecSmrg				       ResizeRedirectMask, client) == 1)
242805b261ecSmrg	    {
242905b261ecSmrg		/* if event is delivered, leave the actual size alone. */
243005b261ecSmrg		w = pWin->drawable.width;
243105b261ecSmrg		h = pWin->drawable.height;
243205b261ecSmrg		size_change = FALSE;
243305b261ecSmrg	    }
243405b261ecSmrg	}
243505b261ecSmrg	if (!size_change)
243605b261ecSmrg	{
243705b261ecSmrg	    if (mask & (CWX | CWY))
243805b261ecSmrg		action = MOVE_WIN;
243905b261ecSmrg	    else if (mask & (CWStackMode | CWBorderWidth))
244005b261ecSmrg		action = RESTACK_WIN;
244105b261ecSmrg	    else   /* really nothing to do */
244205b261ecSmrg		return(Success) ;
244305b261ecSmrg	}
244405b261ecSmrg    }
244505b261ecSmrg
244605b261ecSmrg    if (action == RESIZE_WIN)
244705b261ecSmrg	    /* we've already checked whether there's really a size change */
244805b261ecSmrg	    goto ActuallyDoSomething;
244905b261ecSmrg    if ((mask & CWX) && (x != beforeX))
245005b261ecSmrg	    goto ActuallyDoSomething;
245105b261ecSmrg    if ((mask & CWY) && (y != beforeY))
245205b261ecSmrg	    goto ActuallyDoSomething;
245305b261ecSmrg    if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
245405b261ecSmrg	    goto ActuallyDoSomething;
245505b261ecSmrg    if (mask & CWStackMode)
245605b261ecSmrg    {
245705b261ecSmrg#ifndef ROOTLESS
245805b261ecSmrg        /* See above for why we always reorder in rootless mode. */
245905b261ecSmrg	if (pWin->nextSib != pSib)
246005b261ecSmrg#endif
246105b261ecSmrg	    goto ActuallyDoSomething;
246205b261ecSmrg    }
246305b261ecSmrg    return(Success);
246405b261ecSmrg
246505b261ecSmrgActuallyDoSomething:
246605b261ecSmrg    if (SubStrSend(pWin, pParent))
246705b261ecSmrg    {
246805b261ecSmrg	event.u.u.type = ConfigureNotify;
246905b261ecSmrg	event.u.configureNotify.window = pWin->drawable.id;
247005b261ecSmrg	if (pSib)
247105b261ecSmrg	    event.u.configureNotify.aboveSibling = pSib->drawable.id;
247205b261ecSmrg	else
247305b261ecSmrg	    event.u.configureNotify.aboveSibling = None;
247405b261ecSmrg	event.u.configureNotify.x = x;
247505b261ecSmrg	event.u.configureNotify.y = y;
247605b261ecSmrg#ifdef PANORAMIX
247705b261ecSmrg	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
247805b261ecSmrg	    event.u.configureNotify.x += panoramiXdataPtr[0].x;
247905b261ecSmrg            event.u.configureNotify.y += panoramiXdataPtr[0].y;
248005b261ecSmrg	}
248105b261ecSmrg#endif
248205b261ecSmrg	event.u.configureNotify.width = w;
248305b261ecSmrg	event.u.configureNotify.height = h;
248405b261ecSmrg	event.u.configureNotify.borderWidth = bw;
248505b261ecSmrg	event.u.configureNotify.override = pWin->overrideRedirect;
248605b261ecSmrg	DeliverEvents(pWin, &event, 1, NullWindow);
248705b261ecSmrg    }
248805b261ecSmrg    if (mask & CWBorderWidth)
248905b261ecSmrg    {
249005b261ecSmrg	if (action == RESTACK_WIN)
249105b261ecSmrg	{
249205b261ecSmrg	    action = MOVE_WIN;
249305b261ecSmrg	    pWin->borderWidth = bw;
249405b261ecSmrg	}
249505b261ecSmrg	else if ((action == MOVE_WIN) &&
249605b261ecSmrg		 (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
249705b261ecSmrg		 (beforeY + wBorderWidth (pWin) == y + (int)bw))
249805b261ecSmrg	{
249905b261ecSmrg	    action = REBORDER_WIN;
250005b261ecSmrg	    (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
250105b261ecSmrg	}
250205b261ecSmrg	else
250305b261ecSmrg	    pWin->borderWidth = bw;
250405b261ecSmrg    }
250505b261ecSmrg    if (action == MOVE_WIN)
250605b261ecSmrg	(*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
250705b261ecSmrg		   (mask & CWBorderWidth) ? VTOther : VTMove);
250805b261ecSmrg    else if (action == RESIZE_WIN)
250905b261ecSmrg	(*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
251005b261ecSmrg    else if (mask & CWStackMode)
251105b261ecSmrg	ReflectStackChange(pWin, pSib, VTOther);
251205b261ecSmrg
251305b261ecSmrg    if (action != RESTACK_WIN)
251405b261ecSmrg	CheckCursorConfinement(pWin);
251505b261ecSmrg    return(Success);
251605b261ecSmrg#undef RESTACK_WIN
251705b261ecSmrg#undef MOVE_WIN
251805b261ecSmrg#undef RESIZE_WIN
251905b261ecSmrg#undef REBORDER_WIN
252005b261ecSmrg}
252105b261ecSmrg
252205b261ecSmrg
252305b261ecSmrg/******
252405b261ecSmrg *
252505b261ecSmrg * CirculateWindow
252605b261ecSmrg *    For RaiseLowest, raises the lowest mapped child (if any) that is
252705b261ecSmrg *    obscured by another child to the top of the stack.  For LowerHighest,
252805b261ecSmrg *    lowers the highest mapped child (if any) that is obscuring another
252905b261ecSmrg *    child to the bottom of the stack.	 Exposure processing is performed
253005b261ecSmrg *
253105b261ecSmrg ******/
253205b261ecSmrg
253305b261ecSmrgint
253405b261ecSmrgCirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
253505b261ecSmrg{
253605b261ecSmrg    WindowPtr pWin, pHead, pFirst;
253705b261ecSmrg    xEvent event;
253805b261ecSmrg    BoxRec box;
253905b261ecSmrg
254005b261ecSmrg    pHead = RealChildHead(pParent);
254105b261ecSmrg    pFirst = pHead ? pHead->nextSib : pParent->firstChild;
254205b261ecSmrg    if (direction == RaiseLowest)
254305b261ecSmrg    {
254405b261ecSmrg	for (pWin = pParent->lastChild;
254505b261ecSmrg	     (pWin != pHead) &&
254605b261ecSmrg	     !(pWin->mapped &&
254705b261ecSmrg	       AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
254805b261ecSmrg	     pWin = pWin->prevSib) ;
254905b261ecSmrg	if (pWin == pHead)
255005b261ecSmrg	    return Success;
255105b261ecSmrg    }
255205b261ecSmrg    else
255305b261ecSmrg    {
255405b261ecSmrg	for (pWin = pFirst;
255505b261ecSmrg	     pWin &&
255605b261ecSmrg	     !(pWin->mapped &&
255705b261ecSmrg	       IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
255805b261ecSmrg	     pWin = pWin->nextSib) ;
255905b261ecSmrg	if (!pWin)
256005b261ecSmrg	    return Success;
256105b261ecSmrg    }
256205b261ecSmrg
256305b261ecSmrg    event.u.circulate.window = pWin->drawable.id;
256405b261ecSmrg    event.u.circulate.parent = pParent->drawable.id;
256505b261ecSmrg    event.u.circulate.event = pParent->drawable.id;
256605b261ecSmrg    if (direction == RaiseLowest)
256705b261ecSmrg	event.u.circulate.place = PlaceOnTop;
256805b261ecSmrg    else
256905b261ecSmrg	event.u.circulate.place = PlaceOnBottom;
257005b261ecSmrg
257105b261ecSmrg    if (RedirectSend(pParent))
257205b261ecSmrg    {
257305b261ecSmrg	event.u.u.type = CirculateRequest;
257405b261ecSmrg	if (MaybeDeliverEventsToClient(pParent, &event, 1,
257505b261ecSmrg		SubstructureRedirectMask, client) == 1)
257605b261ecSmrg	    return(Success);
257705b261ecSmrg    }
257805b261ecSmrg
257905b261ecSmrg    event.u.u.type = CirculateNotify;
258005b261ecSmrg    DeliverEvents(pWin, &event, 1, NullWindow);
258105b261ecSmrg    ReflectStackChange(pWin,
258205b261ecSmrg		       (direction == RaiseLowest) ? pFirst : NullWindow,
258305b261ecSmrg		       VTStack);
258405b261ecSmrg
258505b261ecSmrg    return(Success);
258605b261ecSmrg}
258705b261ecSmrg
258805b261ecSmrgstatic int
258905b261ecSmrgCompareWIDs(
259005b261ecSmrg    WindowPtr pWin,
259105b261ecSmrg    pointer   value) /* must conform to VisitWindowProcPtr */
259205b261ecSmrg{
259305b261ecSmrg    Window *wid = (Window *)value;
259405b261ecSmrg
259505b261ecSmrg    if (pWin->drawable.id == *wid)
259605b261ecSmrg       return(WT_STOPWALKING);
259705b261ecSmrg    else
259805b261ecSmrg       return(WT_WALKCHILDREN);
259905b261ecSmrg}
260005b261ecSmrg
260105b261ecSmrg/*****
260205b261ecSmrg *  ReparentWindow
260305b261ecSmrg *****/
260405b261ecSmrg
260505b261ecSmrgint
260605b261ecSmrgReparentWindow(WindowPtr pWin, WindowPtr pParent,
260705b261ecSmrg               int x, int y, ClientPtr client)
260805b261ecSmrg{
260905b261ecSmrg    WindowPtr pPrev, pPriorParent;
261005b261ecSmrg    Bool WasMapped = (Bool)(pWin->mapped);
261105b261ecSmrg    xEvent event;
261205b261ecSmrg    int bw = wBorderWidth (pWin);
261305b261ecSmrg    ScreenPtr pScreen;
261405b261ecSmrg
261505b261ecSmrg    pScreen = pWin->drawable.pScreen;
261605b261ecSmrg    if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
261705b261ecSmrg	return(BadMatch);
261805b261ecSmrg    if (!MakeWindowOptional(pWin))
261905b261ecSmrg	return(BadAlloc);
262005b261ecSmrg
262105b261ecSmrg    if (WasMapped)
262205b261ecSmrg       UnmapWindow(pWin, FALSE);
262305b261ecSmrg
262405b261ecSmrg    event.u.u.type = ReparentNotify;
262505b261ecSmrg    event.u.reparent.window = pWin->drawable.id;
262605b261ecSmrg    event.u.reparent.parent = pParent->drawable.id;
262705b261ecSmrg    event.u.reparent.x = x;
262805b261ecSmrg    event.u.reparent.y = y;
262905b261ecSmrg#ifdef PANORAMIX
263005b261ecSmrg    if(!noPanoramiXExtension && !pParent->parent) {
263105b261ecSmrg	event.u.reparent.x += panoramiXdataPtr[0].x;
263205b261ecSmrg	event.u.reparent.y += panoramiXdataPtr[0].y;
263305b261ecSmrg    }
263405b261ecSmrg#endif
263505b261ecSmrg    event.u.reparent.override = pWin->overrideRedirect;
263605b261ecSmrg    DeliverEvents(pWin, &event, 1, pParent);
263705b261ecSmrg
263805b261ecSmrg    /* take out of sibling chain */
263905b261ecSmrg
264005b261ecSmrg    pPriorParent = pPrev = pWin->parent;
264105b261ecSmrg    if (pPrev->firstChild == pWin)
264205b261ecSmrg	pPrev->firstChild = pWin->nextSib;
264305b261ecSmrg    if (pPrev->lastChild == pWin)
264405b261ecSmrg	pPrev->lastChild = pWin->prevSib;
264505b261ecSmrg
264605b261ecSmrg    if (pWin->nextSib)
264705b261ecSmrg	pWin->nextSib->prevSib = pWin->prevSib;
264805b261ecSmrg    if (pWin->prevSib)
264905b261ecSmrg	pWin->prevSib->nextSib = pWin->nextSib;
265005b261ecSmrg
265105b261ecSmrg    /* insert at begining of pParent */
265205b261ecSmrg    pWin->parent = pParent;
265305b261ecSmrg    pPrev = RealChildHead(pParent);
265405b261ecSmrg    if (pPrev)
265505b261ecSmrg    {
265605b261ecSmrg	pWin->nextSib = pPrev->nextSib;
265705b261ecSmrg	if (pPrev->nextSib)
265805b261ecSmrg	    pPrev->nextSib->prevSib = pWin;
265905b261ecSmrg	else
266005b261ecSmrg	    pParent->lastChild = pWin;
266105b261ecSmrg	pPrev->nextSib = pWin;
266205b261ecSmrg	pWin->prevSib = pPrev;
266305b261ecSmrg    }
266405b261ecSmrg    else
266505b261ecSmrg    {
266605b261ecSmrg	pWin->nextSib = pParent->firstChild;
266705b261ecSmrg	pWin->prevSib = NullWindow;
266805b261ecSmrg	if (pParent->firstChild)
266905b261ecSmrg	    pParent->firstChild->prevSib = pWin;
267005b261ecSmrg	else
267105b261ecSmrg	    pParent->lastChild = pWin;
267205b261ecSmrg	pParent->firstChild = pWin;
267305b261ecSmrg    }
267405b261ecSmrg
267505b261ecSmrg    pWin->origin.x = x + bw;
267605b261ecSmrg    pWin->origin.y = y + bw;
267705b261ecSmrg    pWin->drawable.x = x + bw + pParent->drawable.x;
267805b261ecSmrg    pWin->drawable.y = y + bw + pParent->drawable.y;
267905b261ecSmrg
268005b261ecSmrg    /* clip to parent */
268105b261ecSmrg    SetWinSize (pWin);
268205b261ecSmrg    SetBorderSize (pWin);
268305b261ecSmrg
268405b261ecSmrg    if (pScreen->ReparentWindow)
268505b261ecSmrg	(*pScreen->ReparentWindow)(pWin, pPriorParent);
268605b261ecSmrg    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
268705b261ecSmrg    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
268805b261ecSmrg
268905b261ecSmrg    CheckWindowOptionalNeed(pWin);
269005b261ecSmrg
269105b261ecSmrg    if (WasMapped)
269205b261ecSmrg	MapWindow(pWin, client);
269305b261ecSmrg    RecalculateDeliverableEvents(pWin);
269405b261ecSmrg    return(Success);
269505b261ecSmrg}
269605b261ecSmrg
269705b261ecSmrgstatic void
269805b261ecSmrgRealizeTree(WindowPtr pWin)
269905b261ecSmrg{
270005b261ecSmrg    WindowPtr pChild;
270105b261ecSmrg    RealizeWindowProcPtr Realize;
270205b261ecSmrg
270305b261ecSmrg    Realize = pWin->drawable.pScreen->RealizeWindow;
270405b261ecSmrg    pChild = pWin;
270505b261ecSmrg    while (1)
270605b261ecSmrg    {
270705b261ecSmrg	if (pChild->mapped)
270805b261ecSmrg	{
270905b261ecSmrg	    pChild->realized = TRUE;
271005b261ecSmrg#ifdef DO_SAVE_UNDERS
271105b261ecSmrg	    if (pChild->saveUnder)
271205b261ecSmrg		deltaSaveUndersViewable++;
271305b261ecSmrg#endif
271405b261ecSmrg	    pChild->viewable = (pChild->drawable.class == InputOutput);
271505b261ecSmrg	    (* Realize)(pChild);
271605b261ecSmrg	    if (pChild->firstChild)
271705b261ecSmrg	    {
271805b261ecSmrg		pChild = pChild->firstChild;
271905b261ecSmrg		continue;
272005b261ecSmrg	    }
272105b261ecSmrg	}
272205b261ecSmrg	while (!pChild->nextSib && (pChild != pWin))
272305b261ecSmrg	    pChild = pChild->parent;
272405b261ecSmrg	if (pChild == pWin)
272505b261ecSmrg	    return;
272605b261ecSmrg	pChild = pChild->nextSib;
272705b261ecSmrg    }
272805b261ecSmrg}
272905b261ecSmrg
273005b261ecSmrgstatic WindowPtr windowDisableMapUnmapEvents;
273105b261ecSmrg
273205b261ecSmrgvoid
273305b261ecSmrgDisableMapUnmapEvents(WindowPtr pWin)
273405b261ecSmrg{
273505b261ecSmrg    assert (windowDisableMapUnmapEvents == NULL);
273605b261ecSmrg
273705b261ecSmrg    windowDisableMapUnmapEvents = pWin;
273805b261ecSmrg}
273905b261ecSmrg
274005b261ecSmrgvoid
274105b261ecSmrgEnableMapUnmapEvents(WindowPtr pWin)
274205b261ecSmrg{
274305b261ecSmrg    assert (windowDisableMapUnmapEvents != NULL);
274405b261ecSmrg
274505b261ecSmrg    windowDisableMapUnmapEvents = NULL;
274605b261ecSmrg}
274705b261ecSmrg
274805b261ecSmrgstatic Bool
274905b261ecSmrgMapUnmapEventsEnabled(WindowPtr pWin)
275005b261ecSmrg{
275105b261ecSmrg    return pWin != windowDisableMapUnmapEvents;
275205b261ecSmrg}
275305b261ecSmrg
275405b261ecSmrg/*****
275505b261ecSmrg * MapWindow
275605b261ecSmrg *    If some other client has selected SubStructureReDirect on the parent
275705b261ecSmrg *    and override-redirect is xFalse, then a MapRequest event is generated,
275805b261ecSmrg *    but the window remains unmapped.	Otherwise, the window is mapped and a
275905b261ecSmrg *    MapNotify event is generated.
276005b261ecSmrg *****/
276105b261ecSmrg
276205b261ecSmrg_X_EXPORT int
276305b261ecSmrgMapWindow(WindowPtr pWin, ClientPtr client)
276405b261ecSmrg{
276505b261ecSmrg    ScreenPtr pScreen;
276605b261ecSmrg
276705b261ecSmrg    WindowPtr pParent;
276805b261ecSmrg#ifdef DO_SAVE_UNDERS
276905b261ecSmrg    Bool	dosave = FALSE;
277005b261ecSmrg#endif
277105b261ecSmrg    WindowPtr  pLayerWin;
277205b261ecSmrg
277305b261ecSmrg    if (pWin->mapped)
277405b261ecSmrg	return(Success);
277505b261ecSmrg
277605b261ecSmrg    /*  general check for permission to map window */
277705b261ecSmrg    if (!XaceHook(XACE_MAP_ACCESS, client, pWin))
277805b261ecSmrg	 return Success;
277905b261ecSmrg
278005b261ecSmrg    pScreen = pWin->drawable.pScreen;
278105b261ecSmrg    if ( (pParent = pWin->parent) )
278205b261ecSmrg    {
278305b261ecSmrg	xEvent event;
278405b261ecSmrg	Bool anyMarked;
278505b261ecSmrg#ifdef XAPPGROUP
278605b261ecSmrg	ClientPtr win_owner = clients[CLIENT_ID(pWin->drawable.id)];
278705b261ecSmrg	ClientPtr ag_leader = XagLeader (win_owner);
278805b261ecSmrg#endif
278905b261ecSmrg
279005b261ecSmrg	if ((!pWin->overrideRedirect) &&
279105b261ecSmrg	    (RedirectSend(pParent)
279205b261ecSmrg#ifdef XAPPGROUP
279305b261ecSmrg	    || (win_owner->appgroup && ag_leader &&
279405b261ecSmrg		XagIsControlledRoot (client, pParent))
279505b261ecSmrg#endif
279605b261ecSmrg	))
279705b261ecSmrg	{
279805b261ecSmrg	    event.u.u.type = MapRequest;
279905b261ecSmrg	    event.u.mapRequest.window = pWin->drawable.id;
280005b261ecSmrg#ifdef XAPPGROUP
280105b261ecSmrg	    /* make sure if the ag_leader maps the window it goes to the wm */
280205b261ecSmrg	    if (ag_leader && ag_leader != client &&
280305b261ecSmrg		XagIsControlledRoot (client, pParent)) {
280405b261ecSmrg		event.u.mapRequest.parent = XagId (win_owner);
280505b261ecSmrg		(void) TryClientEvents (ag_leader, &event, 1,
280605b261ecSmrg					NoEventMask, NoEventMask, NullGrab);
280705b261ecSmrg		return Success;
280805b261ecSmrg	    }
280905b261ecSmrg#endif
281005b261ecSmrg	    event.u.mapRequest.parent = pParent->drawable.id;
281105b261ecSmrg
281205b261ecSmrg	    if (MaybeDeliverEventsToClient(pParent, &event, 1,
281305b261ecSmrg		SubstructureRedirectMask, client) == 1)
281405b261ecSmrg		return(Success);
281505b261ecSmrg	}
281605b261ecSmrg
281705b261ecSmrg	pWin->mapped = TRUE;
281805b261ecSmrg	if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin))
281905b261ecSmrg	{
282005b261ecSmrg	    event.u.u.type = MapNotify;
282105b261ecSmrg	    event.u.mapNotify.window = pWin->drawable.id;
282205b261ecSmrg	    event.u.mapNotify.override = pWin->overrideRedirect;
282305b261ecSmrg	    DeliverEvents(pWin, &event, 1, NullWindow);
282405b261ecSmrg	}
282505b261ecSmrg
282605b261ecSmrg	if (!pParent->realized)
282705b261ecSmrg	    return(Success);
282805b261ecSmrg	RealizeTree(pWin);
282905b261ecSmrg	if (pWin->viewable)
283005b261ecSmrg	{
283105b261ecSmrg	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
283205b261ecSmrg							  &pLayerWin);
283305b261ecSmrg#ifdef DO_SAVE_UNDERS
283405b261ecSmrg	    if (DO_SAVE_UNDERS(pWin))
283505b261ecSmrg	    {
283605b261ecSmrg		dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
283705b261ecSmrg	    }
283805b261ecSmrg#endif /* DO_SAVE_UNDERS */
283905b261ecSmrg	    if (anyMarked)
284005b261ecSmrg	    {
284105b261ecSmrg		(*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
284205b261ecSmrg		(*pScreen->HandleExposures)(pLayerWin->parent);
284305b261ecSmrg	    }
284405b261ecSmrg#ifdef DO_SAVE_UNDERS
284505b261ecSmrg	    if (dosave)
284605b261ecSmrg		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
284705b261ecSmrg#endif /* DO_SAVE_UNDERS */
284805b261ecSmrg	if (anyMarked && pScreen->PostValidateTree)
284905b261ecSmrg	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
285005b261ecSmrg	}
285105b261ecSmrg	WindowsRestructured ();
285205b261ecSmrg    }
285305b261ecSmrg    else
285405b261ecSmrg    {
285505b261ecSmrg	RegionRec   temp;
285605b261ecSmrg
285705b261ecSmrg	pWin->mapped = TRUE;
285805b261ecSmrg	pWin->realized = TRUE;	   /* for roots */
285905b261ecSmrg	pWin->viewable = pWin->drawable.class == InputOutput;
286005b261ecSmrg	/* We SHOULD check for an error value here XXX */
286105b261ecSmrg	(*pScreen->RealizeWindow)(pWin);
286205b261ecSmrg	if (pScreen->ClipNotify)
286305b261ecSmrg	    (*pScreen->ClipNotify) (pWin, 0, 0);
286405b261ecSmrg	if (pScreen->PostValidateTree)
286505b261ecSmrg	    (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
286605b261ecSmrg	REGION_NULL(pScreen, &temp);
286705b261ecSmrg	REGION_COPY(pScreen, &temp, &pWin->clipList);
286805b261ecSmrg	(*pScreen->WindowExposures) (pWin, &temp, NullRegion);
286905b261ecSmrg	REGION_UNINIT(pScreen, &temp);
287005b261ecSmrg    }
287105b261ecSmrg
287205b261ecSmrg    return(Success);
287305b261ecSmrg}
287405b261ecSmrg
287505b261ecSmrg
287605b261ecSmrg/*****
287705b261ecSmrg * MapSubwindows
287805b261ecSmrg *    Performs a MapWindow all unmapped children of the window, in top
287905b261ecSmrg *    to bottom stacking order.
288005b261ecSmrg *****/
288105b261ecSmrg
288205b261ecSmrgvoid
288305b261ecSmrgMapSubwindows(WindowPtr pParent, ClientPtr client)
288405b261ecSmrg{
288505b261ecSmrg    WindowPtr	pWin;
288605b261ecSmrg    WindowPtr	pFirstMapped = NullWindow;
288705b261ecSmrg#ifdef DO_SAVE_UNDERS
288805b261ecSmrg    WindowPtr	pFirstSaveUndered = NullWindow;
288905b261ecSmrg#endif
289005b261ecSmrg    ScreenPtr	pScreen;
289105b261ecSmrg    Mask	parentRedirect;
289205b261ecSmrg    Mask	parentNotify;
289305b261ecSmrg    xEvent	event;
289405b261ecSmrg    Bool	anyMarked;
289505b261ecSmrg#ifdef DO_SAVE_UNDERS
289605b261ecSmrg    Bool	dosave = FALSE;
289705b261ecSmrg#endif
289805b261ecSmrg    WindowPtr		pLayerWin;
289905b261ecSmrg
290005b261ecSmrg    pScreen = pParent->drawable.pScreen;
290105b261ecSmrg    parentRedirect = RedirectSend(pParent);
290205b261ecSmrg    parentNotify = SubSend(pParent);
290305b261ecSmrg    anyMarked = FALSE;
290405b261ecSmrg    for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
290505b261ecSmrg    {
290605b261ecSmrg	if (!pWin->mapped)
290705b261ecSmrg	{
290805b261ecSmrg	    if (parentRedirect && !pWin->overrideRedirect)
290905b261ecSmrg	    {
291005b261ecSmrg		event.u.u.type = MapRequest;
291105b261ecSmrg		event.u.mapRequest.window = pWin->drawable.id;
291205b261ecSmrg		event.u.mapRequest.parent = pParent->drawable.id;
291305b261ecSmrg
291405b261ecSmrg		if (MaybeDeliverEventsToClient(pParent, &event, 1,
291505b261ecSmrg		    SubstructureRedirectMask, client) == 1)
291605b261ecSmrg		    continue;
291705b261ecSmrg	    }
291805b261ecSmrg
291905b261ecSmrg	    pWin->mapped = TRUE;
292005b261ecSmrg	    if (parentNotify || StrSend(pWin))
292105b261ecSmrg	    {
292205b261ecSmrg		event.u.u.type = MapNotify;
292305b261ecSmrg		event.u.mapNotify.window = pWin->drawable.id;
292405b261ecSmrg		event.u.mapNotify.override = pWin->overrideRedirect;
292505b261ecSmrg		DeliverEvents(pWin, &event, 1, NullWindow);
292605b261ecSmrg	    }
292705b261ecSmrg
292805b261ecSmrg	    if (!pFirstMapped)
292905b261ecSmrg		pFirstMapped = pWin;
293005b261ecSmrg	    if (pParent->realized)
293105b261ecSmrg	    {
293205b261ecSmrg		RealizeTree(pWin);
293305b261ecSmrg		if (pWin->viewable)
293405b261ecSmrg		{
293505b261ecSmrg		    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
293605b261ecSmrg							(WindowPtr *)NULL);
293705b261ecSmrg#ifdef DO_SAVE_UNDERS
293805b261ecSmrg		    if (DO_SAVE_UNDERS(pWin))
293905b261ecSmrg		    {
294005b261ecSmrg			dosave = TRUE;
294105b261ecSmrg		    }
294205b261ecSmrg#endif /* DO_SAVE_UNDERS */
294305b261ecSmrg		}
294405b261ecSmrg	    }
294505b261ecSmrg	}
294605b261ecSmrg    }
294705b261ecSmrg
294805b261ecSmrg    if (pFirstMapped)
294905b261ecSmrg    {
295005b261ecSmrg	pLayerWin = (*pScreen->GetLayerWindow)(pParent);
295105b261ecSmrg	if (pLayerWin->parent != pParent) {
295205b261ecSmrg	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
295305b261ecSmrg							   pLayerWin,
295405b261ecSmrg							   (WindowPtr *)NULL);
295505b261ecSmrg	    pFirstMapped = pLayerWin;
295605b261ecSmrg	}
295705b261ecSmrg        if (anyMarked)
295805b261ecSmrg        {
295905b261ecSmrg#ifdef DO_SAVE_UNDERS
296005b261ecSmrg	    if (pLayerWin->parent != pParent)
296105b261ecSmrg	    {
296205b261ecSmrg		if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
296305b261ecSmrg		{
296405b261ecSmrg		    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
296505b261ecSmrg							 pLayerWin);
296605b261ecSmrg		}
296705b261ecSmrg	    }
296805b261ecSmrg	    else if (dosave)
296905b261ecSmrg	    {
297005b261ecSmrg		dosave = FALSE;
297105b261ecSmrg		for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
297205b261ecSmrg		{
297305b261ecSmrg		    if (DO_SAVE_UNDERS(pWin))
297405b261ecSmrg		    {
297505b261ecSmrg			dosave |= (*pScreen->ChangeSaveUnder)(pWin,
297605b261ecSmrg							      pWin->nextSib);
297705b261ecSmrg			if (dosave && !pFirstSaveUndered)
297805b261ecSmrg			    pFirstSaveUndered = pWin;
297905b261ecSmrg		    }
298005b261ecSmrg		}
298105b261ecSmrg            }
298205b261ecSmrg#endif /* DO_SAVE_UNDERS */
298305b261ecSmrg	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
298405b261ecSmrg	    (*pScreen->HandleExposures)(pLayerWin->parent);
298505b261ecSmrg	}
298605b261ecSmrg#ifdef DO_SAVE_UNDERS
298705b261ecSmrg        if (dosave)
298805b261ecSmrg	    (*pScreen->PostChangeSaveUnder)(pLayerWin,
298905b261ecSmrg					    pFirstSaveUndered->nextSib);
299005b261ecSmrg#endif /* DO_SAVE_UNDERS */
299105b261ecSmrg        if (anyMarked && pScreen->PostValidateTree)
299205b261ecSmrg	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
299305b261ecSmrg					 VTMap);
299405b261ecSmrg        WindowsRestructured ();
299505b261ecSmrg    }
299605b261ecSmrg}
299705b261ecSmrg
299805b261ecSmrgstatic void
299905b261ecSmrgUnrealizeTree(
300005b261ecSmrg    WindowPtr pWin,
300105b261ecSmrg    Bool fromConfigure)
300205b261ecSmrg{
300305b261ecSmrg    WindowPtr pChild;
300405b261ecSmrg    UnrealizeWindowProcPtr Unrealize;
300505b261ecSmrg    MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
300605b261ecSmrg
300705b261ecSmrg    Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
300805b261ecSmrg    MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
300905b261ecSmrg    pChild = pWin;
301005b261ecSmrg    while (1)
301105b261ecSmrg    {
301205b261ecSmrg	if (pChild->realized)
301305b261ecSmrg	{
301405b261ecSmrg	    pChild->realized = FALSE;
301505b261ecSmrg	    pChild->visibility = VisibilityNotViewable;
301605b261ecSmrg#ifdef PANORAMIX
301705b261ecSmrg	    if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
301805b261ecSmrg		PanoramiXRes *win;
301905b261ecSmrg		win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
302005b261ecSmrg							XRT_WINDOW);
302105b261ecSmrg		if(win)
302205b261ecSmrg		   win->u.win.visibility = VisibilityNotViewable;
302305b261ecSmrg	    }
302405b261ecSmrg#endif
302505b261ecSmrg	    (* Unrealize)(pChild);
302605b261ecSmrg	    if (MapUnmapEventsEnabled(pWin))
302705b261ecSmrg		DeleteWindowFromAnyEvents(pChild, FALSE);
302805b261ecSmrg	    if (pChild->viewable)
302905b261ecSmrg	    {
303005b261ecSmrg#ifdef DO_SAVE_UNDERS
303105b261ecSmrg		if (pChild->saveUnder)
303205b261ecSmrg		    deltaSaveUndersViewable--;
303305b261ecSmrg#endif
303405b261ecSmrg		pChild->viewable = FALSE;
303505b261ecSmrg		if (pChild->backStorage)
303605b261ecSmrg		    (*pChild->drawable.pScreen->SaveDoomedAreas)(
303705b261ecSmrg					    pChild, &pChild->clipList, 0, 0);
303805b261ecSmrg		(* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
303905b261ecSmrg		pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
304005b261ecSmrg	    }
304105b261ecSmrg	    if (pChild->firstChild)
304205b261ecSmrg	    {
304305b261ecSmrg		pChild = pChild->firstChild;
304405b261ecSmrg		continue;
304505b261ecSmrg	    }
304605b261ecSmrg	}
304705b261ecSmrg	while (!pChild->nextSib && (pChild != pWin))
304805b261ecSmrg	    pChild = pChild->parent;
304905b261ecSmrg	if (pChild == pWin)
305005b261ecSmrg	    return;
305105b261ecSmrg	pChild = pChild->nextSib;
305205b261ecSmrg    }
305305b261ecSmrg}
305405b261ecSmrg
305505b261ecSmrg/*****
305605b261ecSmrg * UnmapWindow
305705b261ecSmrg *    If the window is already unmapped, this request has no effect.
305805b261ecSmrg *    Otherwise, the window is unmapped and an UnMapNotify event is
305905b261ecSmrg *    generated.  Cannot unmap a root window.
306005b261ecSmrg *****/
306105b261ecSmrg
306205b261ecSmrg_X_EXPORT int
306305b261ecSmrgUnmapWindow(WindowPtr pWin, Bool fromConfigure)
306405b261ecSmrg{
306505b261ecSmrg    WindowPtr pParent;
306605b261ecSmrg    xEvent event;
306705b261ecSmrg    Bool wasRealized = (Bool)pWin->realized;
306805b261ecSmrg    Bool wasViewable = (Bool)pWin->viewable;
306905b261ecSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
307005b261ecSmrg    WindowPtr pLayerWin = pWin;
307105b261ecSmrg
307205b261ecSmrg    if ((!pWin->mapped) || (!(pParent = pWin->parent)))
307305b261ecSmrg	return(Success);
307405b261ecSmrg    if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin))
307505b261ecSmrg    {
307605b261ecSmrg	event.u.u.type = UnmapNotify;
307705b261ecSmrg	event.u.unmapNotify.window = pWin->drawable.id;
307805b261ecSmrg	event.u.unmapNotify.fromConfigure = fromConfigure;
307905b261ecSmrg	DeliverEvents(pWin, &event, 1, NullWindow);
308005b261ecSmrg    }
308105b261ecSmrg    if (wasViewable && !fromConfigure)
308205b261ecSmrg    {
308305b261ecSmrg	pWin->valdata = UnmapValData;
308405b261ecSmrg	(*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
308505b261ecSmrg	(*pScreen->MarkWindow)(pLayerWin->parent);
308605b261ecSmrg    }
308705b261ecSmrg    pWin->mapped = FALSE;
308805b261ecSmrg    if (wasRealized)
308905b261ecSmrg	UnrealizeTree(pWin, fromConfigure);
309005b261ecSmrg    if (wasViewable)
309105b261ecSmrg    {
309205b261ecSmrg	if (!fromConfigure)
309305b261ecSmrg	{
309405b261ecSmrg	    (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
309505b261ecSmrg	    (*pScreen->HandleExposures)(pLayerWin->parent);
309605b261ecSmrg	}
309705b261ecSmrg#ifdef DO_SAVE_UNDERS
309805b261ecSmrg	if (DO_SAVE_UNDERS(pWin))
309905b261ecSmrg	{
310005b261ecSmrg	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
310105b261ecSmrg	    {
310205b261ecSmrg		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
310305b261ecSmrg	    }
310405b261ecSmrg	}
310505b261ecSmrg	pWin->DIXsaveUnder = FALSE;
310605b261ecSmrg#endif /* DO_SAVE_UNDERS */
310705b261ecSmrg	if (!fromConfigure && pScreen->PostValidateTree)
310805b261ecSmrg	    (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
310905b261ecSmrg    }
311005b261ecSmrg    if (wasRealized && !fromConfigure)
311105b261ecSmrg	WindowsRestructured ();
311205b261ecSmrg    return(Success);
311305b261ecSmrg}
311405b261ecSmrg
311505b261ecSmrg/*****
311605b261ecSmrg * UnmapSubwindows
311705b261ecSmrg *    Performs an UnmapWindow request with the specified mode on all mapped
311805b261ecSmrg *    children of the window, in bottom to top stacking order.
311905b261ecSmrg *****/
312005b261ecSmrg
312105b261ecSmrgvoid
312205b261ecSmrgUnmapSubwindows(WindowPtr pWin)
312305b261ecSmrg{
312405b261ecSmrg    WindowPtr pChild, pHead;
312505b261ecSmrg    xEvent event;
312605b261ecSmrg    Bool wasRealized = (Bool)pWin->realized;
312705b261ecSmrg    Bool wasViewable = (Bool)pWin->viewable;
312805b261ecSmrg    Bool anyMarked = FALSE;
312905b261ecSmrg    Mask parentNotify;
313005b261ecSmrg    WindowPtr pLayerWin = NULL;
313105b261ecSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
313205b261ecSmrg
313305b261ecSmrg    if (!pWin->firstChild)
313405b261ecSmrg	return;
313505b261ecSmrg    parentNotify = SubSend(pWin);
313605b261ecSmrg    pHead = RealChildHead(pWin);
313705b261ecSmrg
313805b261ecSmrg    if (wasViewable)
313905b261ecSmrg	pLayerWin = (*pScreen->GetLayerWindow)(pWin);
314005b261ecSmrg
314105b261ecSmrg    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
314205b261ecSmrg    {
314305b261ecSmrg	if (pChild->mapped)
314405b261ecSmrg	{
314505b261ecSmrg	    if (parentNotify || StrSend(pChild))
314605b261ecSmrg	    {
314705b261ecSmrg		event.u.u.type = UnmapNotify;
314805b261ecSmrg		event.u.unmapNotify.window = pChild->drawable.id;
314905b261ecSmrg		event.u.unmapNotify.fromConfigure = xFalse;
315005b261ecSmrg		DeliverEvents(pChild, &event, 1, NullWindow);
315105b261ecSmrg	    }
315205b261ecSmrg	    if (pChild->viewable)
315305b261ecSmrg	    {
315405b261ecSmrg		pChild->valdata = UnmapValData;
315505b261ecSmrg		anyMarked = TRUE;
315605b261ecSmrg	    }
315705b261ecSmrg	    pChild->mapped = FALSE;
315805b261ecSmrg	    if (pChild->realized)
315905b261ecSmrg		UnrealizeTree(pChild, FALSE);
316005b261ecSmrg	    if (wasViewable)
316105b261ecSmrg	    {
316205b261ecSmrg#ifdef DO_SAVE_UNDERS
316305b261ecSmrg		pChild->DIXsaveUnder = FALSE;
316405b261ecSmrg#endif /* DO_SAVE_UNDERS */
316505b261ecSmrg		if (pChild->backStorage)
316605b261ecSmrg		    (*pScreen->SaveDoomedAreas)(
316705b261ecSmrg					    pChild, &pChild->clipList, 0, 0);
316805b261ecSmrg	    }
316905b261ecSmrg	}
317005b261ecSmrg    }
317105b261ecSmrg    if (wasViewable)
317205b261ecSmrg    {
317305b261ecSmrg	if (anyMarked)
317405b261ecSmrg	{
317505b261ecSmrg	    if (pLayerWin->parent == pWin)
317605b261ecSmrg		(*pScreen->MarkWindow)(pWin);
317705b261ecSmrg	    else
317805b261ecSmrg	    {
317905b261ecSmrg		WindowPtr ptmp;
318005b261ecSmrg                (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
318105b261ecSmrg						  (WindowPtr *)NULL);
318205b261ecSmrg		(*pScreen->MarkWindow)(pLayerWin->parent);
318305b261ecSmrg
318405b261ecSmrg		/* Windows between pWin and pLayerWin may not have been marked */
318505b261ecSmrg		ptmp = pWin;
318605b261ecSmrg
318705b261ecSmrg		while (ptmp != pLayerWin->parent)
318805b261ecSmrg		{
318905b261ecSmrg		    (*pScreen->MarkWindow)(ptmp);
319005b261ecSmrg		    ptmp = ptmp->parent;
319105b261ecSmrg		}
319205b261ecSmrg                pHead = pWin->firstChild;
319305b261ecSmrg	    }
319405b261ecSmrg	    (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
319505b261ecSmrg	    (*pScreen->HandleExposures)(pLayerWin->parent);
319605b261ecSmrg	}
319705b261ecSmrg#ifdef DO_SAVE_UNDERS
319805b261ecSmrg	if (DO_SAVE_UNDERS(pWin))
319905b261ecSmrg	{
320005b261ecSmrg	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
320105b261ecSmrg		(*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
320205b261ecSmrg	}
320305b261ecSmrg#endif /* DO_SAVE_UNDERS */
320405b261ecSmrg	if (anyMarked && pScreen->PostValidateTree)
320505b261ecSmrg	    (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
320605b261ecSmrg    }
320705b261ecSmrg    if (wasRealized)
320805b261ecSmrg	WindowsRestructured ();
320905b261ecSmrg}
321005b261ecSmrg
321105b261ecSmrg
321205b261ecSmrgvoid
321305b261ecSmrgHandleSaveSet(ClientPtr client)
321405b261ecSmrg{
321505b261ecSmrg    WindowPtr pParent, pWin;
321605b261ecSmrg    int j;
321705b261ecSmrg
321805b261ecSmrg    for (j=0; j<client->numSaved; j++)
321905b261ecSmrg    {
322005b261ecSmrg	pWin = SaveSetWindow(client->saveSet[j]);
322105b261ecSmrg#ifdef XFIXES
322205b261ecSmrg	if (SaveSetToRoot(client->saveSet[j]))
322305b261ecSmrg	    pParent = WindowTable[pWin->drawable.pScreen->myNum];
322405b261ecSmrg	else
322505b261ecSmrg#endif
322605b261ecSmrg	{
322705b261ecSmrg	    pParent = pWin->parent;
322805b261ecSmrg	    while (pParent && (wClient (pParent) == client))
322905b261ecSmrg		pParent = pParent->parent;
323005b261ecSmrg	}
323105b261ecSmrg	if (pParent)
323205b261ecSmrg	{
323305b261ecSmrg	    if (pParent != pWin->parent)
323405b261ecSmrg	    {
323505b261ecSmrg		ReparentWindow(pWin, pParent,
323605b261ecSmrg			       pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
323705b261ecSmrg			       pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
323805b261ecSmrg			       client);
323905b261ecSmrg		if(!pWin->realized && pWin->mapped)
324005b261ecSmrg		    pWin->mapped = FALSE;
324105b261ecSmrg	    }
324205b261ecSmrg#ifdef XFIXES
324305b261ecSmrg	    if (SaveSetRemap (client->saveSet[j]))
324405b261ecSmrg#endif
324505b261ecSmrg		MapWindow(pWin, client);
324605b261ecSmrg	}
324705b261ecSmrg    }
324805b261ecSmrg    xfree(client->saveSet);
324905b261ecSmrg    client->numSaved = 0;
325005b261ecSmrg    client->saveSet = (SaveSetElt *)NULL;
325105b261ecSmrg}
325205b261ecSmrg
325305b261ecSmrg/**
325405b261ecSmrg *
325505b261ecSmrg * \param x,y  in root
325605b261ecSmrg */
325705b261ecSmrgBool
325805b261ecSmrgPointInWindowIsVisible(WindowPtr pWin, int x, int y)
325905b261ecSmrg{
326005b261ecSmrg    BoxRec box;
326105b261ecSmrg
326205b261ecSmrg    if (!pWin->realized)
326305b261ecSmrg	return (FALSE);
326405b261ecSmrg    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
326505b261ecSmrg						  x, y, &box)
326605b261ecSmrg	&& (!wInputShape(pWin) ||
326705b261ecSmrg	    POINT_IN_REGION(pWin->drawable.pScreen,
326805b261ecSmrg			    wInputShape(pWin),
326905b261ecSmrg			    x - pWin->drawable.x,
327005b261ecSmrg			    y - pWin->drawable.y, &box)))
327105b261ecSmrg	return(TRUE);
327205b261ecSmrg    return(FALSE);
327305b261ecSmrg}
327405b261ecSmrg
327505b261ecSmrg
327605b261ecSmrg_X_EXPORT RegionPtr
327705b261ecSmrgNotClippedByChildren(WindowPtr pWin)
327805b261ecSmrg{
327905b261ecSmrg    ScreenPtr pScreen;
328005b261ecSmrg    RegionPtr pReg;
328105b261ecSmrg
328205b261ecSmrg    pScreen = pWin->drawable.pScreen;
328305b261ecSmrg    pReg = REGION_CREATE(pScreen, NullBox, 1);
328405b261ecSmrg    if (pWin->parent ||
328505b261ecSmrg	screenIsSaved != SCREEN_SAVER_ON ||
328605b261ecSmrg	!HasSaverWindow (pWin->drawable.pScreen->myNum))
328705b261ecSmrg    {
328805b261ecSmrg	REGION_INTERSECT(pScreen, pReg, &pWin->borderClip, &pWin->winSize);
328905b261ecSmrg    }
329005b261ecSmrg    return(pReg);
329105b261ecSmrg}
329205b261ecSmrg
329305b261ecSmrg_X_EXPORT void
329405b261ecSmrgSendVisibilityNotify(WindowPtr pWin)
329505b261ecSmrg{
329605b261ecSmrg    xEvent event;
329705b261ecSmrg#ifndef NO_XINERAMA_PORT
329805b261ecSmrg    unsigned int visibility = pWin->visibility;
329905b261ecSmrg#endif
330005b261ecSmrg#ifdef PANORAMIX
330105b261ecSmrg    /* This is not quite correct yet, but it's close */
330205b261ecSmrg    if(!noPanoramiXExtension) {
330305b261ecSmrg	PanoramiXRes *win;
330405b261ecSmrg	WindowPtr pWin2;
330505b261ecSmrg	int i, Scrnum;
330605b261ecSmrg
330705b261ecSmrg	Scrnum = pWin->drawable.pScreen->myNum;
330805b261ecSmrg
330905b261ecSmrg	win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
331005b261ecSmrg
331105b261ecSmrg	if(!win || (win->u.win.visibility == visibility))
331205b261ecSmrg	    return;
331305b261ecSmrg
331405b261ecSmrg	switch(visibility) {
331505b261ecSmrg	case VisibilityUnobscured:
331605b261ecSmrg	    for(i = 0; i < PanoramiXNumScreens; i++) {
331705b261ecSmrg		if(i == Scrnum) continue;
331805b261ecSmrg
331905b261ecSmrg		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
332005b261ecSmrg
332105b261ecSmrg		if (pWin2) {
332205b261ecSmrg		    if(pWin2->visibility == VisibilityPartiallyObscured)
332305b261ecSmrg		   	return;
332405b261ecSmrg
332505b261ecSmrg		    if(!i) pWin = pWin2;
332605b261ecSmrg		}
332705b261ecSmrg	    }
332805b261ecSmrg	    break;
332905b261ecSmrg	case VisibilityPartiallyObscured:
333005b261ecSmrg	    if(Scrnum) {
333105b261ecSmrg	        pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
333205b261ecSmrg		if (pWin2) pWin = pWin2;
333305b261ecSmrg	    }
333405b261ecSmrg	    break;
333505b261ecSmrg	case VisibilityFullyObscured:
333605b261ecSmrg	    for(i = 0; i < PanoramiXNumScreens; i++) {
333705b261ecSmrg		if(i == Scrnum) continue;
333805b261ecSmrg
333905b261ecSmrg		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
334005b261ecSmrg
334105b261ecSmrg		if (pWin2) {
334205b261ecSmrg		    if(pWin2->visibility != VisibilityFullyObscured)
334305b261ecSmrg		    	return;
334405b261ecSmrg
334505b261ecSmrg		    if(!i) pWin = pWin2;
334605b261ecSmrg		}
334705b261ecSmrg	    }
334805b261ecSmrg	    break;
334905b261ecSmrg	}
335005b261ecSmrg
335105b261ecSmrg	win->u.win.visibility = visibility;
335205b261ecSmrg    }
335305b261ecSmrg#endif
335405b261ecSmrg
335505b261ecSmrg    event.u.u.type = VisibilityNotify;
335605b261ecSmrg    event.u.visibility.window = pWin->drawable.id;
335705b261ecSmrg    event.u.visibility.state = visibility;
335805b261ecSmrg    DeliverEvents(pWin, &event, 1, NullWindow);
335905b261ecSmrg}
336005b261ecSmrg
336105b261ecSmrg#define RANDOM_WIDTH 32
336205b261ecSmrg
336305b261ecSmrg#ifndef NOLOGOHACK
336405b261ecSmrgstatic void DrawLogo(
336505b261ecSmrg    WindowPtr pWin
336605b261ecSmrg);
336705b261ecSmrg#endif
336805b261ecSmrg
336905b261ecSmrg_X_EXPORT void
337005b261ecSmrgSaveScreens(int on, int mode)
337105b261ecSmrg{
337205b261ecSmrg    int i;
337305b261ecSmrg    int what;
337405b261ecSmrg    int type;
337505b261ecSmrg
337605b261ecSmrg    if (on == SCREEN_SAVER_FORCER)
337705b261ecSmrg    {
337805b261ecSmrg	UpdateCurrentTimeIf();
337905b261ecSmrg	lastDeviceEventTime = currentTime;
338005b261ecSmrg	if (mode == ScreenSaverReset)
338105b261ecSmrg	    what = SCREEN_SAVER_OFF;
338205b261ecSmrg	else
338305b261ecSmrg	    what = SCREEN_SAVER_ON;
338405b261ecSmrg	type = what;
338505b261ecSmrg    }
338605b261ecSmrg    else
338705b261ecSmrg    {
338805b261ecSmrg	what = on;
338905b261ecSmrg	type = what;
339005b261ecSmrg	if (what == screenIsSaved)
339105b261ecSmrg	    type = SCREEN_SAVER_CYCLE;
339205b261ecSmrg    }
339305b261ecSmrg    for (i = 0; i < screenInfo.numScreens; i++)
339405b261ecSmrg    {
339505b261ecSmrg	if (on == SCREEN_SAVER_FORCER)
339605b261ecSmrg	   (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
339705b261ecSmrg	if (savedScreenInfo[i].ExternalScreenSaver)
339805b261ecSmrg	{
339905b261ecSmrg	    if ((*savedScreenInfo[i].ExternalScreenSaver)
340005b261ecSmrg		(screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
340105b261ecSmrg		continue;
340205b261ecSmrg	}
340305b261ecSmrg	if (type == screenIsSaved)
340405b261ecSmrg	    continue;
340505b261ecSmrg	switch (type) {
340605b261ecSmrg	case SCREEN_SAVER_OFF:
340705b261ecSmrg	    if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
340805b261ecSmrg	    {
340905b261ecSmrg	       (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
341005b261ecSmrg						      what);
341105b261ecSmrg	    }
341205b261ecSmrg	    else if (HasSaverWindow (i))
341305b261ecSmrg	    {
341405b261ecSmrg		savedScreenInfo[i].pWindow = NullWindow;
341505b261ecSmrg		FreeResource(savedScreenInfo[i].wid, RT_NONE);
341605b261ecSmrg	    }
341705b261ecSmrg	    break;
341805b261ecSmrg	case SCREEN_SAVER_CYCLE:
341905b261ecSmrg	    if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
342005b261ecSmrg	    {
342105b261ecSmrg		WindowPtr pWin = savedScreenInfo[i].pWindow;
342205b261ecSmrg		/* make it look like screen saver is off, so that
342305b261ecSmrg		 * NotClippedByChildren will compute a clip list
342405b261ecSmrg		 * for the root window, so miPaintWindow works
342505b261ecSmrg		 */
342605b261ecSmrg		screenIsSaved = SCREEN_SAVER_OFF;
342705b261ecSmrg#ifndef NOLOGOHACK
342805b261ecSmrg		if (logoScreenSaver)
342905b261ecSmrg		    (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
343005b261ecSmrg#endif
343105b261ecSmrg		(*pWin->drawable.pScreen->MoveWindow)(pWin,
343205b261ecSmrg			   (short)(-(rand() % RANDOM_WIDTH)),
343305b261ecSmrg			   (short)(-(rand() % RANDOM_WIDTH)),
343405b261ecSmrg			   pWin->nextSib, VTMove);
343505b261ecSmrg#ifndef NOLOGOHACK
343605b261ecSmrg		if (logoScreenSaver)
343705b261ecSmrg		    DrawLogo(pWin);
343805b261ecSmrg#endif
343905b261ecSmrg		screenIsSaved = SCREEN_SAVER_ON;
344005b261ecSmrg	    }
344105b261ecSmrg	    /*
344205b261ecSmrg	     * Call the DDX saver in case it wants to do something
344305b261ecSmrg	     * at cycle time
344405b261ecSmrg	     */
344505b261ecSmrg	    else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
344605b261ecSmrg	    {
344705b261ecSmrg		(* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
344805b261ecSmrg						       type);
344905b261ecSmrg	    }
345005b261ecSmrg	    break;
345105b261ecSmrg	case SCREEN_SAVER_ON:
345205b261ecSmrg	    if (ScreenSaverBlanking != DontPreferBlanking)
345305b261ecSmrg	    {
345405b261ecSmrg		if ((* screenInfo.screens[i]->SaveScreen)
345505b261ecSmrg		   (screenInfo.screens[i], what))
345605b261ecSmrg		{
345705b261ecSmrg		   savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
345805b261ecSmrg		   continue;
345905b261ecSmrg		}
346005b261ecSmrg		if ((ScreenSaverAllowExposures != DontAllowExposures) &&
346105b261ecSmrg		    TileScreenSaver(i, SCREEN_IS_BLACK))
346205b261ecSmrg		{
346305b261ecSmrg		    savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
346405b261ecSmrg		    continue;
346505b261ecSmrg		}
346605b261ecSmrg	    }
346705b261ecSmrg	    if ((ScreenSaverAllowExposures != DontAllowExposures) &&
346805b261ecSmrg		TileScreenSaver(i, SCREEN_IS_TILED))
346905b261ecSmrg	    {
347005b261ecSmrg		savedScreenInfo[i].blanked = SCREEN_IS_TILED;
347105b261ecSmrg	    }
347205b261ecSmrg	    else
347305b261ecSmrg		savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
347405b261ecSmrg	    break;
347505b261ecSmrg	}
347605b261ecSmrg    }
347705b261ecSmrg    screenIsSaved = what;
347805b261ecSmrg    if (mode == ScreenSaverReset)
347905b261ecSmrg       SetScreenSaverTimer();
348005b261ecSmrg}
348105b261ecSmrg
348205b261ecSmrgstatic Bool
348305b261ecSmrgTileScreenSaver(int i, int kind)
348405b261ecSmrg{
348505b261ecSmrg    int j;
348605b261ecSmrg    int result;
348705b261ecSmrg    XID attributes[3];
348805b261ecSmrg    Mask mask;
348905b261ecSmrg    WindowPtr pWin;
349005b261ecSmrg    CursorMetricRec cm;
349105b261ecSmrg    unsigned char *srcbits, *mskbits;
349205b261ecSmrg    CursorPtr cursor;
349305b261ecSmrg    XID	cursorID = 0;
349405b261ecSmrg    int	attri;
349505b261ecSmrg
349605b261ecSmrg    mask = 0;
349705b261ecSmrg    attri = 0;
349805b261ecSmrg    switch (kind) {
349905b261ecSmrg    case SCREEN_IS_TILED:
350005b261ecSmrg	switch (WindowTable[i]->backgroundState) {
350105b261ecSmrg	case BackgroundPixel:
350205b261ecSmrg	    attributes[attri++] = WindowTable[i]->background.pixel;
350305b261ecSmrg	    mask |= CWBackPixel;
350405b261ecSmrg	    break;
350505b261ecSmrg	case BackgroundPixmap:
350605b261ecSmrg	    attributes[attri++] = None;
350705b261ecSmrg	    mask |= CWBackPixmap;
350805b261ecSmrg	    break;
350905b261ecSmrg	default:
351005b261ecSmrg	    break;
351105b261ecSmrg	}
351205b261ecSmrg	break;
351305b261ecSmrg    case SCREEN_IS_BLACK:
351405b261ecSmrg	attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
351505b261ecSmrg	mask |= CWBackPixel;
351605b261ecSmrg	break;
351705b261ecSmrg    }
351805b261ecSmrg    mask |= CWOverrideRedirect;
351905b261ecSmrg    attributes[attri++] = xTrue;
352005b261ecSmrg
352105b261ecSmrg    /*
352205b261ecSmrg     * create a blank cursor
352305b261ecSmrg     */
352405b261ecSmrg
352505b261ecSmrg    cm.width=16;
352605b261ecSmrg    cm.height=16;
352705b261ecSmrg    cm.xhot=8;
352805b261ecSmrg    cm.yhot=8;
352905b261ecSmrg    srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
353005b261ecSmrg    mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
353105b261ecSmrg    if (!srcbits || !mskbits)
353205b261ecSmrg    {
353305b261ecSmrg	xfree(srcbits);
353405b261ecSmrg	xfree(mskbits);
353505b261ecSmrg	cursor = 0;
353605b261ecSmrg    }
353705b261ecSmrg    else
353805b261ecSmrg    {
353905b261ecSmrg	for (j=0; j<BitmapBytePad(32)*16; j++)
354005b261ecSmrg	    srcbits[j] = mskbits[j] = 0x0;
354105b261ecSmrg	cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
354205b261ecSmrg	if (cursor)
354305b261ecSmrg	{
354405b261ecSmrg	    cursorID = FakeClientID(0);
354505b261ecSmrg	    if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
354605b261ecSmrg	    {
354705b261ecSmrg		attributes[attri] = cursorID;
354805b261ecSmrg		mask |= CWCursor;
354905b261ecSmrg	    }
355005b261ecSmrg	    else
355105b261ecSmrg		cursor = 0;
355205b261ecSmrg	}
355305b261ecSmrg	else
355405b261ecSmrg	{
355505b261ecSmrg	    xfree (srcbits);
355605b261ecSmrg	    xfree (mskbits);
355705b261ecSmrg	}
355805b261ecSmrg    }
355905b261ecSmrg
356005b261ecSmrg    pWin = savedScreenInfo[i].pWindow =
356105b261ecSmrg	 CreateWindow(savedScreenInfo[i].wid,
356205b261ecSmrg	      WindowTable[i],
356305b261ecSmrg	      -RANDOM_WIDTH, -RANDOM_WIDTH,
356405b261ecSmrg	      (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
356505b261ecSmrg	      (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
356605b261ecSmrg	      0, InputOutput, mask, attributes, 0, serverClient,
356705b261ecSmrg	      wVisual (WindowTable[i]), &result);
356805b261ecSmrg
356905b261ecSmrg    if (cursor)
357005b261ecSmrg	FreeResource (cursorID, RT_NONE);
357105b261ecSmrg
357205b261ecSmrg    if (!pWin)
357305b261ecSmrg	return FALSE;
357405b261ecSmrg
357505b261ecSmrg    if (!AddResource(pWin->drawable.id, RT_WINDOW,
357605b261ecSmrg		     (pointer)savedScreenInfo[i].pWindow))
357705b261ecSmrg	return FALSE;
357805b261ecSmrg
357905b261ecSmrg    if (mask & CWBackPixmap)
358005b261ecSmrg    {
358105b261ecSmrg	MakeRootTile (pWin);
358205b261ecSmrg	(*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
358305b261ecSmrg    }
358405b261ecSmrg    MapWindow(pWin, serverClient);
358505b261ecSmrg#ifndef NOLOGOHACK
358605b261ecSmrg    if (kind == SCREEN_IS_TILED && logoScreenSaver)
358705b261ecSmrg	DrawLogo(pWin);
358805b261ecSmrg#endif
358905b261ecSmrg    return TRUE;
359005b261ecSmrg}
359105b261ecSmrg
359205b261ecSmrg/*
359305b261ecSmrg * FindWindowWithOptional
359405b261ecSmrg *
359505b261ecSmrg * search ancestors of the given window for an entry containing
359605b261ecSmrg * a WindowOpt structure.  Assumptions:	 some parent will
359705b261ecSmrg * contain the structure.
359805b261ecSmrg */
359905b261ecSmrg
360005b261ecSmrg_X_EXPORT WindowPtr
360105b261ecSmrgFindWindowWithOptional (WindowPtr w)
360205b261ecSmrg{
360305b261ecSmrg    do
360405b261ecSmrg	w = w->parent;
360505b261ecSmrg    while (!w->optional);
360605b261ecSmrg    return w;
360705b261ecSmrg}
360805b261ecSmrg
360905b261ecSmrg/*
361005b261ecSmrg * CheckWindowOptionalNeed
361105b261ecSmrg *
361205b261ecSmrg * check each optional entry in the given window to see if
361305b261ecSmrg * the value is satisfied by the default rules.	 If so,
361405b261ecSmrg * release the optional record
361505b261ecSmrg */
361605b261ecSmrg
361705b261ecSmrg_X_EXPORT void
361805b261ecSmrgCheckWindowOptionalNeed (WindowPtr w)
361905b261ecSmrg{
362005b261ecSmrg    WindowOptPtr optional;
362105b261ecSmrg    WindowOptPtr parentOptional;
362205b261ecSmrg
362305b261ecSmrg    if (!w->parent)
362405b261ecSmrg	return;
362505b261ecSmrg    optional = w->optional;
362605b261ecSmrg    if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
362705b261ecSmrg	return;
362805b261ecSmrg    if (optional->otherEventMasks != 0)
362905b261ecSmrg	return;
363005b261ecSmrg    if (optional->otherClients != NULL)
363105b261ecSmrg	return;
363205b261ecSmrg    if (optional->passiveGrabs != NULL)
363305b261ecSmrg	return;
363405b261ecSmrg    if (optional->userProps != NULL)
363505b261ecSmrg	return;
363605b261ecSmrg    if (optional->backingBitPlanes != ~0L)
363705b261ecSmrg	return;
363805b261ecSmrg    if (optional->backingPixel != 0)
363905b261ecSmrg	return;
364005b261ecSmrg#ifdef SHAPE
364105b261ecSmrg    if (optional->boundingShape != NULL)
364205b261ecSmrg	return;
364305b261ecSmrg    if (optional->clipShape != NULL)
364405b261ecSmrg	return;
364505b261ecSmrg    if (optional->inputShape != NULL)
364605b261ecSmrg	return;
364705b261ecSmrg#endif
364805b261ecSmrg#ifdef XINPUT
364905b261ecSmrg    if (optional->inputMasks != NULL)
365005b261ecSmrg	return;
365105b261ecSmrg#endif
365205b261ecSmrg    parentOptional = FindWindowWithOptional(w)->optional;
365305b261ecSmrg    if (optional->visual != parentOptional->visual)
365405b261ecSmrg	return;
365505b261ecSmrg    if (optional->cursor != None &&
365605b261ecSmrg	(optional->cursor != parentOptional->cursor ||
365705b261ecSmrg	 w->parent->cursorIsNone))
365805b261ecSmrg	return;
365905b261ecSmrg    if (optional->colormap != parentOptional->colormap)
366005b261ecSmrg	return;
366105b261ecSmrg    DisposeWindowOptional (w);
366205b261ecSmrg}
366305b261ecSmrg
366405b261ecSmrg/*
366505b261ecSmrg * MakeWindowOptional
366605b261ecSmrg *
366705b261ecSmrg * create an optional record and initialize it with the default
366805b261ecSmrg * values.
366905b261ecSmrg */
367005b261ecSmrg
367105b261ecSmrg_X_EXPORT Bool
367205b261ecSmrgMakeWindowOptional (WindowPtr pWin)
367305b261ecSmrg{
367405b261ecSmrg    WindowOptPtr optional;
367505b261ecSmrg    WindowOptPtr parentOptional;
367605b261ecSmrg
367705b261ecSmrg    if (pWin->optional)
367805b261ecSmrg	return TRUE;
367905b261ecSmrg    optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
368005b261ecSmrg    if (!optional)
368105b261ecSmrg	return FALSE;
368205b261ecSmrg    optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
368305b261ecSmrg    optional->otherEventMasks = 0;
368405b261ecSmrg    optional->otherClients = NULL;
368505b261ecSmrg    optional->passiveGrabs = NULL;
368605b261ecSmrg    optional->userProps = NULL;
368705b261ecSmrg    optional->backingBitPlanes = ~0L;
368805b261ecSmrg    optional->backingPixel = 0;
368905b261ecSmrg#ifdef SHAPE
369005b261ecSmrg    optional->boundingShape = NULL;
369105b261ecSmrg    optional->clipShape = NULL;
369205b261ecSmrg    optional->inputShape = NULL;
369305b261ecSmrg#endif
369405b261ecSmrg#ifdef XINPUT
369505b261ecSmrg    optional->inputMasks = NULL;
369605b261ecSmrg#endif
369705b261ecSmrg    parentOptional = FindWindowWithOptional(pWin)->optional;
369805b261ecSmrg    optional->visual = parentOptional->visual;
369905b261ecSmrg    if (!pWin->cursorIsNone)
370005b261ecSmrg    {
370105b261ecSmrg	optional->cursor = parentOptional->cursor;
370205b261ecSmrg	optional->cursor->refcnt++;
370305b261ecSmrg    }
370405b261ecSmrg    else
370505b261ecSmrg    {
370605b261ecSmrg	optional->cursor = None;
370705b261ecSmrg    }
370805b261ecSmrg    optional->colormap = parentOptional->colormap;
370905b261ecSmrg    pWin->optional = optional;
371005b261ecSmrg    return TRUE;
371105b261ecSmrg}
371205b261ecSmrg
371305b261ecSmrg#ifndef NOLOGOHACK
371405b261ecSmrgstatic void
371505b261ecSmrgDrawLogo(WindowPtr pWin)
371605b261ecSmrg{
371705b261ecSmrg    DrawablePtr pDraw;
371805b261ecSmrg    ScreenPtr pScreen;
371905b261ecSmrg    int x, y;
372005b261ecSmrg    unsigned int width, height, size;
372105b261ecSmrg    GC *pGC;
372205b261ecSmrg    int thin, gap, d31;
372305b261ecSmrg    DDXPointRec poly[4];
372405b261ecSmrg    ChangeGCVal fore[2], back[2];
372505b261ecSmrg    xrgb rgb[2];
372605b261ecSmrg    BITS32 fmask, bmask;
372705b261ecSmrg    ColormapPtr cmap;
372805b261ecSmrg
372905b261ecSmrg    pDraw = (DrawablePtr)pWin;
373005b261ecSmrg    pScreen = pDraw->pScreen;
373105b261ecSmrg    x = -pWin->origin.x;
373205b261ecSmrg    y = -pWin->origin.y;
373305b261ecSmrg    width = pScreen->width;
373405b261ecSmrg    height = pScreen->height;
373505b261ecSmrg    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
373605b261ecSmrg    if (!pGC)
373705b261ecSmrg	return;
373805b261ecSmrg
373905b261ecSmrg    if ((rand() % 100) <= 17) /* make the probability for white fairly low */
374005b261ecSmrg	fore[0].val = pScreen->whitePixel;
374105b261ecSmrg    else
374205b261ecSmrg	fore[0].val = pScreen->blackPixel;
374305b261ecSmrg    if ((pWin->backgroundState == BackgroundPixel) &&
374405b261ecSmrg	(cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
374505b261ecSmrg	Pixel querypixels[2];
374605b261ecSmrg
374705b261ecSmrg	querypixels[0] = fore[0].val;
374805b261ecSmrg	querypixels[1] = pWin->background.pixel;
374905b261ecSmrg	QueryColors(cmap, 2, querypixels, rgb);
375005b261ecSmrg	if ((rgb[0].red == rgb[1].red) &&
375105b261ecSmrg	    (rgb[0].green == rgb[1].green) &&
375205b261ecSmrg	    (rgb[0].blue == rgb[1].blue)) {
375305b261ecSmrg	    if (fore[0].val == pScreen->blackPixel)
375405b261ecSmrg		fore[0].val = pScreen->whitePixel;
375505b261ecSmrg	    else
375605b261ecSmrg		fore[0].val = pScreen->blackPixel;
375705b261ecSmrg	}
375805b261ecSmrg    }
375905b261ecSmrg    fore[1].val = FillSolid;
376005b261ecSmrg    fmask = GCForeground|GCFillStyle;
376105b261ecSmrg    if (pWin->backgroundState == BackgroundPixel) {
376205b261ecSmrg	back[0].val = pWin->background.pixel;
376305b261ecSmrg	back[1].val = FillSolid;
376405b261ecSmrg	bmask = GCForeground|GCFillStyle;
376505b261ecSmrg    } else {
376605b261ecSmrg	back[0].val = 0;
376705b261ecSmrg	back[1].val = 0;
376805b261ecSmrg	dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
376905b261ecSmrg		    NULL, back);
377005b261ecSmrg	back[0].val = FillTiled;
377105b261ecSmrg	back[1].ptr = pWin->background.pixmap;
377205b261ecSmrg	bmask = GCFillStyle|GCTile;
377305b261ecSmrg    }
377405b261ecSmrg
377505b261ecSmrg    /* should be the same as the reference function XmuDrawLogo() */
377605b261ecSmrg
377705b261ecSmrg    size = width;
377805b261ecSmrg    if (height < width)
377905b261ecSmrg	 size = height;
378005b261ecSmrg    size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
378105b261ecSmrg    size &= ~1;
378205b261ecSmrg    x += rand() % (width - size);
378305b261ecSmrg    y += rand() % (height - size);
378405b261ecSmrg
378505b261ecSmrg/*
378605b261ecSmrg * Draw what will be the thin strokes.
378705b261ecSmrg *
378805b261ecSmrg *           -----
378905b261ecSmrg *          /    /
379005b261ecSmrg *         /    /
379105b261ecSmrg *        /    /
379205b261ecSmrg *       /    /
379305b261ecSmrg *      /____/
379405b261ecSmrg *           d
379505b261ecSmrg *
379605b261ecSmrg * Point d is 9/44 (~1/5) of the way across.
379705b261ecSmrg */
379805b261ecSmrg
379905b261ecSmrg    thin = (size / 11);
380005b261ecSmrg    if (thin < 1) thin = 1;
380105b261ecSmrg    gap = (thin+3) / 4;
380205b261ecSmrg    d31 = thin + thin + gap;
380305b261ecSmrg    poly[0].x = x + size;	       poly[0].y = y;
380405b261ecSmrg    poly[1].x = x + size-d31;	       poly[1].y = y;
380505b261ecSmrg    poly[2].x = x + 0;		       poly[2].y = y + size;
380605b261ecSmrg    poly[3].x = x + d31;	       poly[3].y = y + size;
380705b261ecSmrg    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
380805b261ecSmrg    ValidateGC(pDraw, pGC);
380905b261ecSmrg    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
381005b261ecSmrg
381105b261ecSmrg/*
381205b261ecSmrg * Erase area not needed for lower thin stroke.
381305b261ecSmrg *
381405b261ecSmrg *           ------
381505b261ecSmrg *          /	  /
381605b261ecSmrg *         /  __ /
381705b261ecSmrg *        /  /	/
381805b261ecSmrg *       /  /  /
381905b261ecSmrg *      /__/__/
382005b261ecSmrg */
382105b261ecSmrg
382205b261ecSmrg    poly[0].x = x + d31/2;			 poly[0].y = y + size;
382305b261ecSmrg    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
382405b261ecSmrg    poly[2].x = x + (size/2)+(d31-(d31/2));	 poly[2].y = y + size/2;
382505b261ecSmrg    poly[3].x = x + d31;			 poly[3].y = y + size;
382605b261ecSmrg    dixChangeGC(NullClient, pGC, bmask, NULL, back);
382705b261ecSmrg    ValidateGC(pDraw, pGC);
382805b261ecSmrg    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
382905b261ecSmrg
383005b261ecSmrg/*
383105b261ecSmrg * Erase area not needed for upper thin stroke.
383205b261ecSmrg *
383305b261ecSmrg *	     ------
383405b261ecSmrg *	    /  /  /
383505b261ecSmrg *	   /--/	 /
383605b261ecSmrg *	  /	/
383705b261ecSmrg *	 /     /
383805b261ecSmrg *	/_____/
383905b261ecSmrg */
384005b261ecSmrg
384105b261ecSmrg    poly[0].x = x + size - d31/2;		 poly[0].y = y;
384205b261ecSmrg    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
384305b261ecSmrg    poly[2].x = x + (size/2)-(d31-(d31/2));	 poly[2].y = y + size/2;
384405b261ecSmrg    poly[3].x = x + size - d31;			 poly[3].y = y;
384505b261ecSmrg    ValidateGC(pDraw, pGC);
384605b261ecSmrg    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
384705b261ecSmrg
384805b261ecSmrg/*
384905b261ecSmrg * Draw thick stroke.
385005b261ecSmrg * Point b is 1/4 of the way across.
385105b261ecSmrg *
385205b261ecSmrg *      b
385305b261ecSmrg * -----
385405b261ecSmrg * \	\
385505b261ecSmrg *  \	 \
385605b261ecSmrg *   \	  \
385705b261ecSmrg *    \	   \
385805b261ecSmrg *     \____\
385905b261ecSmrg */
386005b261ecSmrg
386105b261ecSmrg    poly[0].x = x;		       poly[0].y = y;
386205b261ecSmrg    poly[1].x = x + size/4;	       poly[1].y = y;
386305b261ecSmrg    poly[2].x = x + size;	       poly[2].y = y + size;
386405b261ecSmrg    poly[3].x = x + size - size/4;     poly[3].y = y + size;
386505b261ecSmrg    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
386605b261ecSmrg    ValidateGC(pDraw, pGC);
386705b261ecSmrg    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
386805b261ecSmrg
386905b261ecSmrg/*
387005b261ecSmrg * Erase to create gap.
387105b261ecSmrg *
387205b261ecSmrg *	    /
387305b261ecSmrg *	   /
387405b261ecSmrg *	  /
387505b261ecSmrg *	 /
387605b261ecSmrg *	/
387705b261ecSmrg */
387805b261ecSmrg
387905b261ecSmrg    poly[0].x = x + size- thin;	      poly[0].y = y;
388005b261ecSmrg    poly[1].x = x + size-( thin+gap);  poly[1].y = y;
388105b261ecSmrg    poly[2].x = x + thin;	      poly[2].y = y + size;
388205b261ecSmrg    poly[3].x = x + thin + gap;	      poly[3].y = y + size;
388305b261ecSmrg    dixChangeGC(NullClient, pGC, bmask, NULL, back);
388405b261ecSmrg    ValidateGC(pDraw, pGC);
388505b261ecSmrg    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
388605b261ecSmrg
388705b261ecSmrg    FreeScratchGC(pGC);
388805b261ecSmrg}
388905b261ecSmrg
389005b261ecSmrg#endif
3891