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