1706f2543Smrg/* 2706f2543Smrg 3706f2543SmrgCopyright (c) 2006, Red Hat, Inc. 4706f2543Smrg 5706f2543SmrgPermission is hereby granted, free of charge, to any person obtaining a 6706f2543Smrgcopy of this software and associated documentation files (the "Software"), 7706f2543Smrgto deal in the Software without restriction, including without limitation 8706f2543Smrgthe rights to use, copy, modify, merge, publish, distribute, sublicense, 9706f2543Smrgand/or sell copies of the Software, and to permit persons to whom the 10706f2543SmrgSoftware is furnished to do so, subject to the following conditions: 11706f2543Smrg 12706f2543SmrgThe above copyright notice and this permission notice (including the next 13706f2543Smrgparagraph) shall be included in all copies or substantial portions of the 14706f2543SmrgSoftware. 15706f2543Smrg 16706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19706f2543SmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20706f2543SmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21706f2543SmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22706f2543SmrgDEALINGS IN THE SOFTWARE. 23706f2543Smrg 24706f2543SmrgCopyright 1987, 1998 The Open Group 25706f2543Smrg 26706f2543SmrgPermission to use, copy, modify, distribute, and sell this software and its 27706f2543Smrgdocumentation for any purpose is hereby granted without fee, provided that 28706f2543Smrgthe above copyright notice appear in all copies and that both that 29706f2543Smrgcopyright notice and this permission notice appear in supporting 30706f2543Smrgdocumentation. 31706f2543Smrg 32706f2543SmrgThe above copyright notice and this permission notice shall be included 33706f2543Smrgin all copies or substantial portions of the Software. 34706f2543Smrg 35706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 36706f2543SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 37706f2543SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 38706f2543SmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 39706f2543SmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 40706f2543SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 41706f2543SmrgOTHER DEALINGS IN THE SOFTWARE. 42706f2543Smrg 43706f2543SmrgExcept as contained in this notice, the name of The Open Group shall 44706f2543Smrgnot be used in advertising or otherwise to promote the sale, use or 45706f2543Smrgother dealings in this Software without prior written authorization 46706f2543Smrgfrom The Open Group. 47706f2543Smrg 48706f2543Smrg 49706f2543SmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, 50706f2543Smrg 51706f2543Smrg All Rights Reserved 52706f2543Smrg 53706f2543SmrgPermission to use, copy, modify, and distribute this software and its 54706f2543Smrgdocumentation for any purpose and without fee is hereby granted, 55706f2543Smrgprovided that the above copyright notice appear in all copies and that 56706f2543Smrgboth that copyright notice and this permission notice appear in 57706f2543Smrgsupporting documentation, and that the name of Digital not be 58706f2543Smrgused in advertising or publicity pertaining to distribution of the 59706f2543Smrgsoftware without specific, written prior permission. 60706f2543Smrg 61706f2543SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 62706f2543SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 63706f2543SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 64706f2543SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 65706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 66706f2543SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 67706f2543SmrgSOFTWARE. 68706f2543Smrg 69706f2543Smrg*/ 70706f2543Smrg 71706f2543Smrg/* The panoramix components contained the following notice */ 72706f2543Smrg/***************************************************************** 73706f2543Smrg 74706f2543SmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. 75706f2543Smrg 76706f2543SmrgPermission is hereby granted, free of charge, to any person obtaining a copy 77706f2543Smrgof this software and associated documentation files (the "Software"), to deal 78706f2543Smrgin the Software without restriction, including without limitation the rights 79706f2543Smrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 80706f2543Smrgcopies of the Software. 81706f2543Smrg 82706f2543SmrgThe above copyright notice and this permission notice shall be included in 83706f2543Smrgall copies or substantial portions of the Software. 84706f2543Smrg 85706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 86706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 87706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 88706f2543SmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 89706f2543SmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 90706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 91706f2543SmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 92706f2543Smrg 93706f2543SmrgExcept as contained in this notice, the name of Digital Equipment Corporation 94706f2543Smrgshall not be used in advertising or otherwise to promote the sale, use or other 95706f2543Smrgdealings in this Software without prior written authorization from Digital 96706f2543SmrgEquipment Corporation. 97706f2543Smrg 98706f2543Smrg******************************************************************/ 99706f2543Smrg 100706f2543Smrg 101706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 102706f2543Smrg#include <dix-config.h> 103706f2543Smrg#endif 104706f2543Smrg 105706f2543Smrg#include "misc.h" 106706f2543Smrg#include "scrnintstr.h" 107706f2543Smrg#include "os.h" 108706f2543Smrg#include "regionstr.h" 109706f2543Smrg#include "validate.h" 110706f2543Smrg#include "windowstr.h" 111706f2543Smrg#include "input.h" 112706f2543Smrg#include "inputstr.h" 113706f2543Smrg#include "resource.h" 114706f2543Smrg#include "colormapst.h" 115706f2543Smrg#include "cursorstr.h" 116706f2543Smrg#include "dixstruct.h" 117706f2543Smrg#include "gcstruct.h" 118706f2543Smrg#include "servermd.h" 119706f2543Smrg#ifdef PANORAMIX 120706f2543Smrg#include "panoramiX.h" 121706f2543Smrg#include "panoramiXsrv.h" 122706f2543Smrg#endif 123706f2543Smrg#include "dixevents.h" 124706f2543Smrg#include "globals.h" 125706f2543Smrg#include "mi.h" /* miPaintWindow */ 126706f2543Smrg 127706f2543Smrg#include "privates.h" 128706f2543Smrg#include "xace.h" 129706f2543Smrg 130706f2543Smrg/****** 131706f2543Smrg * Window stuff for server 132706f2543Smrg * 133706f2543Smrg * CreateRootWindow, CreateWindow, ChangeWindowAttributes, 134706f2543Smrg * GetWindowAttributes, DeleteWindow, DestroySubWindows, 135706f2543Smrg * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows, 136706f2543Smrg * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow, 137706f2543Smrg * ChangeWindowDeviceCursor 138706f2543Smrg ******/ 139706f2543Smrg 140706f2543SmrgBool bgNoneRoot = FALSE; 141706f2543Smrg 142706f2543Smrgstatic unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11}; 143706f2543Smrgstatic unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88}; 144706f2543Smrg 145706f2543Smrgstatic Bool WindowParentHasDeviceCursor(WindowPtr pWin, 146706f2543Smrg DeviceIntPtr pDev, 147706f2543Smrg CursorPtr pCurs); 148706f2543Smrgstatic Bool 149706f2543SmrgWindowSeekDeviceCursor(WindowPtr pWin, 150706f2543Smrg DeviceIntPtr pDev, 151706f2543Smrg DevCursNodePtr* pNode, 152706f2543Smrg DevCursNodePtr* pPrev); 153706f2543Smrg 154706f2543Smrgint screenIsSaved = SCREEN_SAVER_OFF; 155706f2543Smrg 156706f2543Smrgstatic Bool TileScreenSaver(ScreenPtr pScreen, int kind); 157706f2543Smrg 158706f2543Smrg#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \ 159706f2543Smrg CWDontPropagate | CWOverrideRedirect | CWCursor ) 160706f2543Smrg 161706f2543Smrg#define BOXES_OVERLAP(b1, b2) \ 162706f2543Smrg (!( ((b1)->x2 <= (b2)->x1) || \ 163706f2543Smrg ( ((b1)->x1 >= (b2)->x2)) || \ 164706f2543Smrg ( ((b1)->y2 <= (b2)->y1)) || \ 165706f2543Smrg ( ((b1)->y1 >= (b2)->y2)) ) ) 166706f2543Smrg 167706f2543Smrg#define RedirectSend(pWin) \ 168706f2543Smrg ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask) 169706f2543Smrg 170706f2543Smrg#define SubSend(pWin) \ 171706f2543Smrg ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask) 172706f2543Smrg 173706f2543Smrg#define StrSend(pWin) \ 174706f2543Smrg ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask) 175706f2543Smrg 176706f2543Smrg#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent)) 177706f2543Smrg 178706f2543Smrg#ifdef DEBUG 179706f2543Smrg/****** 180706f2543Smrg * PrintWindowTree 181706f2543Smrg * For debugging only 182706f2543Smrg ******/ 183706f2543Smrg 184706f2543Smrgstatic void 185706f2543SmrgPrintChildren(WindowPtr p1, int indent) 186706f2543Smrg{ 187706f2543Smrg WindowPtr p2; 188706f2543Smrg int i; 189706f2543Smrg 190706f2543Smrg while (p1) 191706f2543Smrg { 192706f2543Smrg p2 = p1->firstChild; 193706f2543Smrg ErrorF("[dix] "); 194706f2543Smrg for (i=0; i<indent; i++) ErrorF(" "); 195706f2543Smrg ErrorF("%lx\n", p1->drawable.id); 196706f2543Smrg RegionPrint(&p1->clipList); 197706f2543Smrg PrintChildren(p2, indent+4); 198706f2543Smrg p1 = p1->nextSib; 199706f2543Smrg } 200706f2543Smrg} 201706f2543Smrg 202706f2543Smrgstatic void 203706f2543SmrgPrintWindowTree(void) 204706f2543Smrg{ 205706f2543Smrg int i; 206706f2543Smrg WindowPtr pWin, p1; 207706f2543Smrg 208706f2543Smrg for (i=0; i<screenInfo.numScreens; i++) 209706f2543Smrg { 210706f2543Smrg ErrorF("[dix] WINDOW %d\n", i); 211706f2543Smrg pWin = screenInfo.screens[i]->root; 212706f2543Smrg RegionPrint(&pWin->clipList); 213706f2543Smrg p1 = pWin->firstChild; 214706f2543Smrg PrintChildren(p1, 4); 215706f2543Smrg } 216706f2543Smrg} 217706f2543Smrg#endif 218706f2543Smrg 219706f2543Smrgint 220706f2543SmrgTraverseTree(WindowPtr pWin, VisitWindowProcPtr func, pointer data) 221706f2543Smrg{ 222706f2543Smrg int result; 223706f2543Smrg WindowPtr pChild; 224706f2543Smrg 225706f2543Smrg if (!(pChild = pWin)) 226706f2543Smrg return WT_NOMATCH; 227706f2543Smrg while (1) 228706f2543Smrg { 229706f2543Smrg result = (* func)(pChild, data); 230706f2543Smrg if (result == WT_STOPWALKING) 231706f2543Smrg return WT_STOPWALKING; 232706f2543Smrg if ((result == WT_WALKCHILDREN) && pChild->firstChild) 233706f2543Smrg { 234706f2543Smrg pChild = pChild->firstChild; 235706f2543Smrg continue; 236706f2543Smrg } 237706f2543Smrg while (!pChild->nextSib && (pChild != pWin)) 238706f2543Smrg pChild = pChild->parent; 239706f2543Smrg if (pChild == pWin) 240706f2543Smrg break; 241706f2543Smrg pChild = pChild->nextSib; 242706f2543Smrg } 243706f2543Smrg return WT_NOMATCH; 244706f2543Smrg} 245706f2543Smrg 246706f2543Smrg/***** 247706f2543Smrg * WalkTree 248706f2543Smrg * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on 249706f2543Smrg * each window. If FUNC returns WT_WALKCHILDREN, traverse the children, 250706f2543Smrg * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING 251706f2543Smrg * exit WalkTree. Does depth-first traverse. 252706f2543Smrg *****/ 253706f2543Smrg 254706f2543Smrgint 255706f2543SmrgWalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data) 256706f2543Smrg{ 257706f2543Smrg return(TraverseTree(pScreen->root, func, data)); 258706f2543Smrg} 259706f2543Smrg 260706f2543Smrg/* hack for forcing backing store on all windows */ 261706f2543Smrgint defaultBackingStore = NotUseful; 262706f2543Smrg/* hack to force no backing store */ 263706f2543SmrgBool disableBackingStore = FALSE; 264706f2543SmrgBool enableBackingStore = FALSE; 265706f2543Smrg 266706f2543Smrgstatic void 267706f2543SmrgSetWindowToDefaults(WindowPtr pWin) 268706f2543Smrg{ 269706f2543Smrg pWin->prevSib = NullWindow; 270706f2543Smrg pWin->firstChild = NullWindow; 271706f2543Smrg pWin->lastChild = NullWindow; 272706f2543Smrg 273706f2543Smrg pWin->valdata = (ValidatePtr)NULL; 274706f2543Smrg pWin->optional = (WindowOptPtr)NULL; 275706f2543Smrg pWin->cursorIsNone = TRUE; 276706f2543Smrg 277706f2543Smrg pWin->backingStore = NotUseful; 278706f2543Smrg pWin->DIXsaveUnder = FALSE; 279706f2543Smrg pWin->backStorage = (pointer) NULL; 280706f2543Smrg 281706f2543Smrg pWin->mapped = FALSE; /* off */ 282706f2543Smrg pWin->realized = FALSE; /* off */ 283706f2543Smrg pWin->viewable = FALSE; 284706f2543Smrg pWin->visibility = VisibilityNotViewable; 285706f2543Smrg pWin->overrideRedirect = FALSE; 286706f2543Smrg pWin->saveUnder = FALSE; 287706f2543Smrg 288706f2543Smrg pWin->bitGravity = ForgetGravity; 289706f2543Smrg pWin->winGravity = NorthWestGravity; 290706f2543Smrg 291706f2543Smrg pWin->eventMask = 0; 292706f2543Smrg pWin->deliverableEvents = 0; 293706f2543Smrg pWin->dontPropagate = 0; 294706f2543Smrg pWin->forcedBS = FALSE; 295706f2543Smrg pWin->redirectDraw = RedirectDrawNone; 296706f2543Smrg pWin->forcedBG = FALSE; 297706f2543Smrg 298706f2543Smrg#ifdef ROOTLESS 299706f2543Smrg pWin->rootlessUnhittable = FALSE; 300706f2543Smrg#endif 301706f2543Smrg 302706f2543Smrg#ifdef COMPOSITE 303706f2543Smrg pWin->damagedDescendants = FALSE; 304706f2543Smrg#endif 305706f2543Smrg} 306706f2543Smrg 307706f2543Smrgstatic void 308706f2543SmrgMakeRootTile(WindowPtr pWin) 309706f2543Smrg{ 310706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 311706f2543Smrg GCPtr pGC; 312706f2543Smrg unsigned char back[128]; 313706f2543Smrg int len = BitmapBytePad(sizeof(long)); 314706f2543Smrg unsigned char *from, *to; 315706f2543Smrg int i, j; 316706f2543Smrg 317706f2543Smrg pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4, 318706f2543Smrg pScreen->rootDepth, 0); 319706f2543Smrg 320706f2543Smrg pWin->backgroundState = BackgroundPixmap; 321706f2543Smrg pGC = GetScratchGC(pScreen->rootDepth, pScreen); 322706f2543Smrg if (!pWin->background.pixmap || !pGC) 323706f2543Smrg FatalError("could not create root tile"); 324706f2543Smrg 325706f2543Smrg { 326706f2543Smrg ChangeGCVal attributes[2]; 327706f2543Smrg 328706f2543Smrg attributes[0].val = pScreen->whitePixel; 329706f2543Smrg attributes[1].val = pScreen->blackPixel; 330706f2543Smrg 331706f2543Smrg (void)ChangeGC(NullClient, pGC, GCForeground | GCBackground, attributes); 332706f2543Smrg } 333706f2543Smrg 334706f2543Smrg ValidateGC((DrawablePtr)pWin->background.pixmap, pGC); 335706f2543Smrg 336706f2543Smrg from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb; 337706f2543Smrg to = back; 338706f2543Smrg 339706f2543Smrg for (i = 4; i > 0; i--, from++) 340706f2543Smrg for (j = len; j > 0; j--) 341706f2543Smrg *to++ = *from; 342706f2543Smrg 343706f2543Smrg (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1, 344706f2543Smrg 0, 0, len, 4, 0, XYBitmap, (char *)back); 345706f2543Smrg 346706f2543Smrg FreeScratchGC(pGC); 347706f2543Smrg 348706f2543Smrg} 349706f2543Smrg 350706f2543Smrg/***** 351706f2543Smrg * CreateRootWindow 352706f2543Smrg * Makes a window at initialization time for specified screen 353706f2543Smrg *****/ 354706f2543Smrg 355706f2543SmrgBool 356706f2543SmrgCreateRootWindow(ScreenPtr pScreen) 357706f2543Smrg{ 358706f2543Smrg WindowPtr pWin; 359706f2543Smrg BoxRec box; 360706f2543Smrg PixmapFormatRec *format; 361706f2543Smrg 362706f2543Smrg pWin = dixAllocateObjectWithPrivates(WindowRec, PRIVATE_WINDOW); 363706f2543Smrg if (!pWin) 364706f2543Smrg return FALSE; 365706f2543Smrg 366706f2543Smrg pScreen->screensaver.pWindow = NULL; 367706f2543Smrg pScreen->screensaver.wid = FakeClientID(0); 368706f2543Smrg pScreen->screensaver.ExternalScreenSaver = NULL; 369706f2543Smrg screenIsSaved = SCREEN_SAVER_OFF; 370706f2543Smrg 371706f2543Smrg pScreen->root = pWin; 372706f2543Smrg 373706f2543Smrg pWin->drawable.pScreen = pScreen; 374706f2543Smrg pWin->drawable.type = DRAWABLE_WINDOW; 375706f2543Smrg 376706f2543Smrg pWin->drawable.depth = pScreen->rootDepth; 377706f2543Smrg for (format = screenInfo.formats; 378706f2543Smrg format->depth != pScreen->rootDepth; 379706f2543Smrg format++) 380706f2543Smrg ; 381706f2543Smrg pWin->drawable.bitsPerPixel = format->bitsPerPixel; 382706f2543Smrg 383706f2543Smrg pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; 384706f2543Smrg 385706f2543Smrg pWin->parent = NullWindow; 386706f2543Smrg SetWindowToDefaults(pWin); 387706f2543Smrg 388706f2543Smrg pWin->optional = malloc(sizeof (WindowOptRec)); 389706f2543Smrg if (!pWin->optional) 390706f2543Smrg return FALSE; 391706f2543Smrg 392706f2543Smrg pWin->optional->dontPropagateMask = 0; 393706f2543Smrg pWin->optional->otherEventMasks = 0; 394706f2543Smrg pWin->optional->otherClients = NULL; 395706f2543Smrg pWin->optional->passiveGrabs = NULL; 396706f2543Smrg pWin->optional->userProps = NULL; 397706f2543Smrg pWin->optional->backingBitPlanes = ~0L; 398706f2543Smrg pWin->optional->backingPixel = 0; 399706f2543Smrg pWin->optional->boundingShape = NULL; 400706f2543Smrg pWin->optional->clipShape = NULL; 401706f2543Smrg pWin->optional->inputShape = NULL; 402706f2543Smrg pWin->optional->inputMasks = NULL; 403706f2543Smrg pWin->optional->deviceCursors = NULL; 404706f2543Smrg pWin->optional->colormap = pScreen->defColormap; 405706f2543Smrg pWin->optional->visual = pScreen->rootVisual; 406706f2543Smrg 407706f2543Smrg pWin->nextSib = NullWindow; 408706f2543Smrg 409706f2543Smrg pWin->drawable.id = FakeClientID(0); 410706f2543Smrg 411706f2543Smrg pWin->origin.x = pWin->origin.y = 0; 412706f2543Smrg pWin->drawable.height = pScreen->height; 413706f2543Smrg pWin->drawable.width = pScreen->width; 414706f2543Smrg pWin->drawable.x = pWin->drawable.y = 0; 415706f2543Smrg 416706f2543Smrg box.x1 = 0; 417706f2543Smrg box.y1 = 0; 418706f2543Smrg box.x2 = pScreen->width; 419706f2543Smrg box.y2 = pScreen->height; 420706f2543Smrg RegionInit(&pWin->clipList, &box, 1); 421706f2543Smrg RegionInit(&pWin->winSize, &box, 1); 422706f2543Smrg RegionInit(&pWin->borderSize, &box, 1); 423706f2543Smrg RegionInit(&pWin->borderClip, &box, 1); 424706f2543Smrg 425706f2543Smrg pWin->drawable.class = InputOutput; 426706f2543Smrg pWin->optional->visual = pScreen->rootVisual; 427706f2543Smrg 428706f2543Smrg pWin->backgroundState = BackgroundPixel; 429706f2543Smrg pWin->background.pixel = pScreen->whitePixel; 430706f2543Smrg 431706f2543Smrg pWin->borderIsPixel = TRUE; 432706f2543Smrg pWin->border.pixel = pScreen->blackPixel; 433706f2543Smrg pWin->borderWidth = 0; 434706f2543Smrg 435706f2543Smrg /* security creation/labeling check 436706f2543Smrg */ 437706f2543Smrg if (XaceHook(XACE_RESOURCE_ACCESS, serverClient, pWin->drawable.id, 438706f2543Smrg RT_WINDOW, pWin, RT_NONE, NULL, DixCreateAccess)) 439706f2543Smrg return FALSE; 440706f2543Smrg 441706f2543Smrg if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin)) 442706f2543Smrg return FALSE; 443706f2543Smrg 444706f2543Smrg if (disableBackingStore) 445706f2543Smrg pScreen->backingStoreSupport = NotUseful; 446706f2543Smrg if (enableBackingStore) 447706f2543Smrg pScreen->backingStoreSupport = Always; 448706f2543Smrg 449706f2543Smrg pScreen->saveUnderSupport = NotUseful; 450706f2543Smrg 451706f2543Smrg return TRUE; 452706f2543Smrg} 453706f2543Smrg 454706f2543Smrgvoid 455706f2543SmrgInitRootWindow(WindowPtr pWin) 456706f2543Smrg{ 457706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 458706f2543Smrg int backFlag = CWBorderPixel | CWCursor | CWBackingStore; 459706f2543Smrg 460706f2543Smrg if (!(*pScreen->CreateWindow)(pWin)) 461706f2543Smrg return; /* XXX */ 462706f2543Smrg (*pScreen->PositionWindow)(pWin, 0, 0); 463706f2543Smrg 464706f2543Smrg pWin->cursorIsNone = FALSE; 465706f2543Smrg pWin->optional->cursor = rootCursor; 466706f2543Smrg rootCursor->refcnt++; 467706f2543Smrg 468706f2543Smrg 469706f2543Smrg if (party_like_its_1989) { 470706f2543Smrg MakeRootTile(pWin); 471706f2543Smrg backFlag |= CWBackPixmap; 472706f2543Smrg } else if (pScreen->canDoBGNoneRoot && bgNoneRoot) { 473706f2543Smrg pWin->backgroundState = XaceBackgroundNoneState(pWin); 474706f2543Smrg pWin->background.pixel = pScreen->whitePixel; 475706f2543Smrg backFlag |= CWBackPixmap; 476706f2543Smrg } else { 477706f2543Smrg pWin->backgroundState = BackgroundPixel; 478706f2543Smrg if (whiteRoot) 479706f2543Smrg pWin->background.pixel = pScreen->whitePixel; 480706f2543Smrg else 481706f2543Smrg pWin->background.pixel = pScreen->blackPixel; 482706f2543Smrg backFlag |= CWBackPixel; 483706f2543Smrg } 484706f2543Smrg 485706f2543Smrg pWin->backingStore = defaultBackingStore; 486706f2543Smrg pWin->forcedBS = (defaultBackingStore != NotUseful); 487706f2543Smrg /* We SHOULD check for an error value here XXX */ 488706f2543Smrg (*pScreen->ChangeWindowAttributes)(pWin, backFlag); 489706f2543Smrg 490706f2543Smrg MapWindow(pWin, serverClient); 491706f2543Smrg} 492706f2543Smrg 493706f2543Smrg/* Set the region to the intersection of the rectangle and the 494706f2543Smrg * window's winSize. The window is typically the parent of the 495706f2543Smrg * window from which the region came. 496706f2543Smrg */ 497706f2543Smrg 498706f2543Smrgstatic void 499706f2543SmrgClippedRegionFromBox(WindowPtr pWin, RegionPtr Rgn, 500706f2543Smrg int x, int y, 501706f2543Smrg int w, int h) 502706f2543Smrg{ 503706f2543Smrg BoxRec box = *RegionExtents(&pWin->winSize); 504706f2543Smrg 505706f2543Smrg /* we do these calculations to avoid overflows */ 506706f2543Smrg if (x > box.x1) 507706f2543Smrg box.x1 = x; 508706f2543Smrg if (y > box.y1) 509706f2543Smrg box.y1 = y; 510706f2543Smrg x += w; 511706f2543Smrg if (x < box.x2) 512706f2543Smrg box.x2 = x; 513706f2543Smrg y += h; 514706f2543Smrg if (y < box.y2) 515706f2543Smrg box.y2 = y; 516706f2543Smrg if (box.x1 > box.x2) 517706f2543Smrg box.x2 = box.x1; 518706f2543Smrg if (box.y1 > box.y2) 519706f2543Smrg box.y2 = box.y1; 520706f2543Smrg RegionReset(Rgn, &box); 521706f2543Smrg RegionIntersect(Rgn, Rgn, &pWin->winSize); 522706f2543Smrg} 523706f2543Smrg 524706f2543Smrgstatic RealChildHeadProc realChildHeadProc = NULL; 525706f2543Smrg 526706f2543Smrgvoid 527706f2543SmrgRegisterRealChildHeadProc (RealChildHeadProc proc) 528706f2543Smrg{ 529706f2543Smrg realChildHeadProc = proc; 530706f2543Smrg} 531706f2543Smrg 532706f2543Smrg 533706f2543SmrgWindowPtr 534706f2543SmrgRealChildHead(WindowPtr pWin) 535706f2543Smrg{ 536706f2543Smrg if (realChildHeadProc) { 537706f2543Smrg return realChildHeadProc (pWin); 538706f2543Smrg } 539706f2543Smrg 540706f2543Smrg if (!pWin->parent && 541706f2543Smrg (screenIsSaved == SCREEN_SAVER_ON) && 542706f2543Smrg (HasSaverWindow (pWin->drawable.pScreen))) 543706f2543Smrg return pWin->firstChild; 544706f2543Smrg else 545706f2543Smrg return NullWindow; 546706f2543Smrg} 547706f2543Smrg 548706f2543Smrg/***** 549706f2543Smrg * CreateWindow 550706f2543Smrg * Makes a window in response to client request 551706f2543Smrg *****/ 552706f2543Smrg 553706f2543SmrgWindowPtr 554706f2543SmrgCreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w, 555706f2543Smrg unsigned h, unsigned bw, unsigned class, Mask vmask, XID *vlist, 556706f2543Smrg int depth, ClientPtr client, VisualID visual, int *error) 557706f2543Smrg{ 558706f2543Smrg WindowPtr pWin; 559706f2543Smrg WindowPtr pHead; 560706f2543Smrg ScreenPtr pScreen; 561706f2543Smrg xEvent event; 562706f2543Smrg int idepth, ivisual; 563706f2543Smrg Bool fOK; 564706f2543Smrg DepthPtr pDepth; 565706f2543Smrg PixmapFormatRec *format; 566706f2543Smrg WindowOptPtr ancwopt; 567706f2543Smrg 568706f2543Smrg if (class == CopyFromParent) 569706f2543Smrg class = pParent->drawable.class; 570706f2543Smrg 571706f2543Smrg if ((class != InputOutput) && (class != InputOnly)) 572706f2543Smrg { 573706f2543Smrg *error = BadValue; 574706f2543Smrg client->errorValue = class; 575706f2543Smrg return NullWindow; 576706f2543Smrg } 577706f2543Smrg 578706f2543Smrg if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) 579706f2543Smrg { 580706f2543Smrg *error = BadMatch; 581706f2543Smrg return NullWindow; 582706f2543Smrg } 583706f2543Smrg 584706f2543Smrg if ((class == InputOnly) && ((bw != 0) || (depth != 0))) 585706f2543Smrg { 586706f2543Smrg *error = BadMatch; 587706f2543Smrg return NullWindow; 588706f2543Smrg } 589706f2543Smrg 590706f2543Smrg pScreen = pParent->drawable.pScreen; 591706f2543Smrg if ((class == InputOutput) && (depth == 0)) 592706f2543Smrg depth = pParent->drawable.depth; 593706f2543Smrg ancwopt = pParent->optional; 594706f2543Smrg if (!ancwopt) 595706f2543Smrg ancwopt = FindWindowWithOptional(pParent)->optional; 596706f2543Smrg if (visual == CopyFromParent) { 597706f2543Smrg visual = ancwopt->visual; 598706f2543Smrg } 599706f2543Smrg 600706f2543Smrg /* Find out if the depth and visual are acceptable for this Screen */ 601706f2543Smrg if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) 602706f2543Smrg { 603706f2543Smrg fOK = FALSE; 604706f2543Smrg for(idepth = 0; idepth < pScreen->numDepths; idepth++) 605706f2543Smrg { 606706f2543Smrg pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; 607706f2543Smrg if ((depth == pDepth->depth) || (depth == 0)) 608706f2543Smrg { 609706f2543Smrg for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) 610706f2543Smrg { 611706f2543Smrg if (visual == pDepth->vids[ivisual]) 612706f2543Smrg { 613706f2543Smrg fOK = TRUE; 614706f2543Smrg break; 615706f2543Smrg } 616706f2543Smrg } 617706f2543Smrg } 618706f2543Smrg } 619706f2543Smrg if (fOK == FALSE) 620706f2543Smrg { 621706f2543Smrg *error = BadMatch; 622706f2543Smrg return NullWindow; 623706f2543Smrg } 624706f2543Smrg } 625706f2543Smrg 626706f2543Smrg if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) && 627706f2543Smrg (class != InputOnly) && 628706f2543Smrg (depth != pParent->drawable.depth)) 629706f2543Smrg { 630706f2543Smrg *error = BadMatch; 631706f2543Smrg return NullWindow; 632706f2543Smrg } 633706f2543Smrg 634706f2543Smrg if (((vmask & CWColormap) == 0) && 635706f2543Smrg (class != InputOnly) && 636706f2543Smrg ((visual != ancwopt->visual) || (ancwopt->colormap == None))) 637706f2543Smrg { 638706f2543Smrg *error = BadMatch; 639706f2543Smrg return NullWindow; 640706f2543Smrg } 641706f2543Smrg 642706f2543Smrg pWin = dixAllocateObjectWithPrivates(WindowRec, PRIVATE_WINDOW); 643706f2543Smrg if (!pWin) 644706f2543Smrg { 645706f2543Smrg *error = BadAlloc; 646706f2543Smrg return NullWindow; 647706f2543Smrg } 648706f2543Smrg pWin->drawable = pParent->drawable; 649706f2543Smrg pWin->drawable.depth = depth; 650706f2543Smrg if (depth == pParent->drawable.depth) 651706f2543Smrg pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel; 652706f2543Smrg else 653706f2543Smrg { 654706f2543Smrg for (format = screenInfo.formats; format->depth != depth; format++) 655706f2543Smrg ; 656706f2543Smrg pWin->drawable.bitsPerPixel = format->bitsPerPixel; 657706f2543Smrg } 658706f2543Smrg if (class == InputOnly) 659706f2543Smrg pWin->drawable.type = (short) UNDRAWABLE_WINDOW; 660706f2543Smrg pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; 661706f2543Smrg 662706f2543Smrg pWin->drawable.id = wid; 663706f2543Smrg pWin->drawable.class = class; 664706f2543Smrg 665706f2543Smrg pWin->parent = pParent; 666706f2543Smrg SetWindowToDefaults(pWin); 667706f2543Smrg 668706f2543Smrg if (visual != ancwopt->visual) 669706f2543Smrg { 670706f2543Smrg if (!MakeWindowOptional (pWin)) 671706f2543Smrg { 672706f2543Smrg dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); 673706f2543Smrg *error = BadAlloc; 674706f2543Smrg return NullWindow; 675706f2543Smrg } 676706f2543Smrg pWin->optional->visual = visual; 677706f2543Smrg pWin->optional->colormap = None; 678706f2543Smrg } 679706f2543Smrg 680706f2543Smrg pWin->borderWidth = bw; 681706f2543Smrg 682706f2543Smrg /* security creation/labeling check 683706f2543Smrg */ 684706f2543Smrg *error = XaceHook(XACE_RESOURCE_ACCESS, client, wid, RT_WINDOW, pWin, 685706f2543Smrg RT_WINDOW, pWin->parent, DixCreateAccess|DixSetAttrAccess); 686706f2543Smrg if (*error != Success) { 687706f2543Smrg dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); 688706f2543Smrg return NullWindow; 689706f2543Smrg } 690706f2543Smrg 691706f2543Smrg pWin->backgroundState = XaceBackgroundNoneState(pWin); 692706f2543Smrg pWin->background.pixel = pScreen->whitePixel; 693706f2543Smrg 694706f2543Smrg pWin->borderIsPixel = pParent->borderIsPixel; 695706f2543Smrg pWin->border = pParent->border; 696706f2543Smrg if (pWin->borderIsPixel == FALSE) 697706f2543Smrg pWin->border.pixmap->refcnt++; 698706f2543Smrg 699706f2543Smrg pWin->origin.x = x + (int)bw; 700706f2543Smrg pWin->origin.y = y + (int)bw; 701706f2543Smrg pWin->drawable.width = w; 702706f2543Smrg pWin->drawable.height = h; 703706f2543Smrg pWin->drawable.x = pParent->drawable.x + x + (int)bw; 704706f2543Smrg pWin->drawable.y = pParent->drawable.y + y + (int)bw; 705706f2543Smrg 706706f2543Smrg /* set up clip list correctly for unobscured WindowPtr */ 707706f2543Smrg RegionNull(&pWin->clipList); 708706f2543Smrg RegionNull(&pWin->borderClip); 709706f2543Smrg RegionNull(&pWin->winSize); 710706f2543Smrg RegionNull(&pWin->borderSize); 711706f2543Smrg 712706f2543Smrg pHead = RealChildHead(pParent); 713706f2543Smrg if (pHead) 714706f2543Smrg { 715706f2543Smrg pWin->nextSib = pHead->nextSib; 716706f2543Smrg if (pHead->nextSib) 717706f2543Smrg pHead->nextSib->prevSib = pWin; 718706f2543Smrg else 719706f2543Smrg pParent->lastChild = pWin; 720706f2543Smrg pHead->nextSib = pWin; 721706f2543Smrg pWin->prevSib = pHead; 722706f2543Smrg } 723706f2543Smrg else 724706f2543Smrg { 725706f2543Smrg pWin->nextSib = pParent->firstChild; 726706f2543Smrg if (pParent->firstChild) 727706f2543Smrg pParent->firstChild->prevSib = pWin; 728706f2543Smrg else 729706f2543Smrg pParent->lastChild = pWin; 730706f2543Smrg pParent->firstChild = pWin; 731706f2543Smrg } 732706f2543Smrg 733706f2543Smrg SetWinSize (pWin); 734706f2543Smrg SetBorderSize (pWin); 735706f2543Smrg 736706f2543Smrg /* We SHOULD check for an error value here XXX */ 737706f2543Smrg if (!(*pScreen->CreateWindow)(pWin)) 738706f2543Smrg { 739706f2543Smrg *error = BadAlloc; 740706f2543Smrg DeleteWindow(pWin, None); 741706f2543Smrg return NullWindow; 742706f2543Smrg } 743706f2543Smrg /* We SHOULD check for an error value here XXX */ 744706f2543Smrg (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y); 745706f2543Smrg 746706f2543Smrg if (!(vmask & CWEventMask)) 747706f2543Smrg RecalculateDeliverableEvents(pWin); 748706f2543Smrg 749706f2543Smrg if (vmask) 750706f2543Smrg *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin)); 751706f2543Smrg else 752706f2543Smrg *error = Success; 753706f2543Smrg 754706f2543Smrg if (*error != Success) 755706f2543Smrg { 756706f2543Smrg DeleteWindow(pWin, None); 757706f2543Smrg return NullWindow; 758706f2543Smrg } 759706f2543Smrg if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful)) 760706f2543Smrg { 761706f2543Smrg XID value = defaultBackingStore; 762706f2543Smrg (void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin)); 763706f2543Smrg pWin->forcedBS = TRUE; 764706f2543Smrg } 765706f2543Smrg 766706f2543Smrg if (SubSend(pParent)) 767706f2543Smrg { 768706f2543Smrg memset(&event, 0, sizeof(xEvent)); 769706f2543Smrg event.u.u.type = CreateNotify; 770706f2543Smrg event.u.createNotify.window = wid; 771706f2543Smrg event.u.createNotify.parent = pParent->drawable.id; 772706f2543Smrg event.u.createNotify.x = x; 773706f2543Smrg event.u.createNotify.y = y; 774706f2543Smrg event.u.createNotify.width = w; 775706f2543Smrg event.u.createNotify.height = h; 776706f2543Smrg event.u.createNotify.borderWidth = bw; 777706f2543Smrg event.u.createNotify.override = pWin->overrideRedirect; 778706f2543Smrg DeliverEvents(pParent, &event, 1, NullWindow); 779706f2543Smrg } 780706f2543Smrg return pWin; 781706f2543Smrg} 782706f2543Smrg 783706f2543Smrgstatic void 784706f2543SmrgDisposeWindowOptional (WindowPtr pWin) 785706f2543Smrg{ 786706f2543Smrg if (!pWin->optional) 787706f2543Smrg return; 788706f2543Smrg /* 789706f2543Smrg * everything is peachy. Delete the optional record 790706f2543Smrg * and clean up 791706f2543Smrg */ 792706f2543Smrg if (pWin->optional->cursor) 793706f2543Smrg { 794706f2543Smrg FreeCursor (pWin->optional->cursor, (Cursor)0); 795706f2543Smrg pWin->cursorIsNone = FALSE; 796706f2543Smrg } 797706f2543Smrg else 798706f2543Smrg pWin->cursorIsNone = TRUE; 799706f2543Smrg 800706f2543Smrg if (pWin->optional->deviceCursors) 801706f2543Smrg { 802706f2543Smrg DevCursorList pList; 803706f2543Smrg DevCursorList pPrev; 804706f2543Smrg pList = pWin->optional->deviceCursors; 805706f2543Smrg while(pList) 806706f2543Smrg { 807706f2543Smrg if (pList->cursor) 808706f2543Smrg FreeCursor(pList->cursor, (XID)0); 809706f2543Smrg pPrev = pList; 810706f2543Smrg pList = pList->next; 811706f2543Smrg free(pPrev); 812706f2543Smrg } 813706f2543Smrg pWin->optional->deviceCursors = NULL; 814706f2543Smrg } 815706f2543Smrg 816706f2543Smrg free(pWin->optional); 817706f2543Smrg pWin->optional = NULL; 818706f2543Smrg} 819706f2543Smrg 820706f2543Smrgstatic void 821706f2543SmrgFreeWindowResources(WindowPtr pWin) 822706f2543Smrg{ 823706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 824706f2543Smrg 825706f2543Smrg DeleteWindowFromAnySaveSet(pWin); 826706f2543Smrg DeleteWindowFromAnySelections(pWin); 827706f2543Smrg DeleteWindowFromAnyEvents(pWin, TRUE); 828706f2543Smrg RegionUninit(&pWin->clipList); 829706f2543Smrg RegionUninit(&pWin->winSize); 830706f2543Smrg RegionUninit(&pWin->borderClip); 831706f2543Smrg RegionUninit(&pWin->borderSize); 832706f2543Smrg if (wBoundingShape (pWin)) 833706f2543Smrg RegionDestroy(wBoundingShape (pWin)); 834706f2543Smrg if (wClipShape (pWin)) 835706f2543Smrg RegionDestroy(wClipShape (pWin)); 836706f2543Smrg if (wInputShape (pWin)) 837706f2543Smrg RegionDestroy(wInputShape (pWin)); 838706f2543Smrg if (pWin->borderIsPixel == FALSE) 839706f2543Smrg (*pScreen->DestroyPixmap)(pWin->border.pixmap); 840706f2543Smrg if (pWin->backgroundState == BackgroundPixmap) 841706f2543Smrg (*pScreen->DestroyPixmap)(pWin->background.pixmap); 842706f2543Smrg 843706f2543Smrg DeleteAllWindowProperties(pWin); 844706f2543Smrg /* We SHOULD check for an error value here XXX */ 845706f2543Smrg (*pScreen->DestroyWindow)(pWin); 846706f2543Smrg DisposeWindowOptional (pWin); 847706f2543Smrg} 848706f2543Smrg 849706f2543Smrgstatic void 850706f2543SmrgCrushTree(WindowPtr pWin) 851706f2543Smrg{ 852706f2543Smrg WindowPtr pChild, pSib, pParent; 853706f2543Smrg UnrealizeWindowProcPtr UnrealizeWindow; 854706f2543Smrg xEvent event; 855706f2543Smrg 856706f2543Smrg if (!(pChild = pWin->firstChild)) 857706f2543Smrg return; 858706f2543Smrg UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow; 859706f2543Smrg while (1) 860706f2543Smrg { 861706f2543Smrg if (pChild->firstChild) 862706f2543Smrg { 863706f2543Smrg pChild = pChild->firstChild; 864706f2543Smrg continue; 865706f2543Smrg } 866706f2543Smrg while (1) 867706f2543Smrg { 868706f2543Smrg pParent = pChild->parent; 869706f2543Smrg if (SubStrSend(pChild, pParent)) 870706f2543Smrg { 871706f2543Smrg memset(&event, 0, sizeof(xEvent)); 872706f2543Smrg event.u.u.type = DestroyNotify; 873706f2543Smrg event.u.destroyNotify.window = pChild->drawable.id; 874706f2543Smrg DeliverEvents(pChild, &event, 1, NullWindow); 875706f2543Smrg } 876706f2543Smrg FreeResource(pChild->drawable.id, RT_WINDOW); 877706f2543Smrg pSib = pChild->nextSib; 878706f2543Smrg pChild->viewable = FALSE; 879706f2543Smrg if (pChild->realized) 880706f2543Smrg { 881706f2543Smrg pChild->realized = FALSE; 882706f2543Smrg (*UnrealizeWindow)(pChild); 883706f2543Smrg } 884706f2543Smrg FreeWindowResources(pChild); 885706f2543Smrg dixFreeObjectWithPrivates(pChild, PRIVATE_WINDOW); 886706f2543Smrg if ( (pChild = pSib) ) 887706f2543Smrg break; 888706f2543Smrg pChild = pParent; 889706f2543Smrg pChild->firstChild = NullWindow; 890706f2543Smrg pChild->lastChild = NullWindow; 891706f2543Smrg if (pChild == pWin) 892706f2543Smrg return; 893706f2543Smrg } 894706f2543Smrg } 895706f2543Smrg} 896706f2543Smrg 897706f2543Smrg/***** 898706f2543Smrg * DeleteWindow 899706f2543Smrg * Deletes child of window then window itself 900706f2543Smrg * If wid is None, don't send any events 901706f2543Smrg *****/ 902706f2543Smrg 903706f2543Smrgint 904706f2543SmrgDeleteWindow(pointer value, XID wid) 905706f2543Smrg { 906706f2543Smrg WindowPtr pParent; 907706f2543Smrg WindowPtr pWin = (WindowPtr)value; 908706f2543Smrg xEvent event; 909706f2543Smrg 910706f2543Smrg UnmapWindow(pWin, FALSE); 911706f2543Smrg 912706f2543Smrg CrushTree(pWin); 913706f2543Smrg 914706f2543Smrg pParent = pWin->parent; 915706f2543Smrg if (wid && pParent && SubStrSend(pWin, pParent)) 916706f2543Smrg { 917706f2543Smrg memset(&event, 0, sizeof(xEvent)); 918706f2543Smrg event.u.u.type = DestroyNotify; 919706f2543Smrg event.u.destroyNotify.window = pWin->drawable.id; 920706f2543Smrg DeliverEvents(pWin, &event, 1, NullWindow); 921706f2543Smrg } 922706f2543Smrg 923706f2543Smrg FreeWindowResources(pWin); 924706f2543Smrg if (pParent) 925706f2543Smrg { 926706f2543Smrg if (pParent->firstChild == pWin) 927706f2543Smrg pParent->firstChild = pWin->nextSib; 928706f2543Smrg if (pParent->lastChild == pWin) 929706f2543Smrg pParent->lastChild = pWin->prevSib; 930706f2543Smrg if (pWin->nextSib) 931706f2543Smrg pWin->nextSib->prevSib = pWin->prevSib; 932706f2543Smrg if (pWin->prevSib) 933706f2543Smrg pWin->prevSib->nextSib = pWin->nextSib; 934706f2543Smrg } 935706f2543Smrg else 936706f2543Smrg pWin->drawable.pScreen->root = NULL; 937706f2543Smrg dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW); 938706f2543Smrg return Success; 939706f2543Smrg} 940706f2543Smrg 941706f2543Smrgint 942706f2543SmrgDestroySubwindows(WindowPtr pWin, ClientPtr client) 943706f2543Smrg{ 944706f2543Smrg /* XXX 945706f2543Smrg * The protocol is quite clear that each window should be 946706f2543Smrg * destroyed in turn, however, unmapping all of the first 947706f2543Smrg * eliminates most of the calls to ValidateTree. So, 948706f2543Smrg * this implementation is incorrect in that all of the 949706f2543Smrg * UnmapNotifies occur before all of the DestroyNotifies. 950706f2543Smrg * If you care, simply delete the call to UnmapSubwindows. 951706f2543Smrg */ 952706f2543Smrg UnmapSubwindows(pWin); 953706f2543Smrg while (pWin->lastChild) { 954706f2543Smrg int rc = XaceHook(XACE_RESOURCE_ACCESS, client, 955706f2543Smrg pWin->lastChild->drawable.id, RT_WINDOW, 956706f2543Smrg pWin->lastChild, RT_NONE, NULL, DixDestroyAccess); 957706f2543Smrg if (rc != Success) 958706f2543Smrg return rc; 959706f2543Smrg FreeResource(pWin->lastChild->drawable.id, RT_NONE); 960706f2543Smrg } 961706f2543Smrg return Success; 962706f2543Smrg} 963706f2543Smrg 964706f2543Smrgstatic void 965706f2543SmrgSetRootWindowBackground(WindowPtr pWin, ScreenPtr pScreen, Mask *index2) 966706f2543Smrg{ 967706f2543Smrg /* following the protocol: "Changing the background of a root window to 968706f2543Smrg * None or ParentRelative restores the default background pixmap" */ 969706f2543Smrg if (bgNoneRoot) { 970706f2543Smrg pWin->backgroundState = XaceBackgroundNoneState(pWin); 971706f2543Smrg pWin->background.pixel = pScreen->whitePixel; 972706f2543Smrg } 973706f2543Smrg else if (party_like_its_1989) 974706f2543Smrg MakeRootTile(pWin); 975706f2543Smrg else { 976706f2543Smrg pWin->backgroundState = BackgroundPixel; 977706f2543Smrg if (whiteRoot) 978706f2543Smrg pWin->background.pixel = pScreen->whitePixel; 979706f2543Smrg else 980706f2543Smrg pWin->background.pixel = pScreen->blackPixel; 981706f2543Smrg *index2 = CWBackPixel; 982706f2543Smrg } 983706f2543Smrg} 984706f2543Smrg 985706f2543Smrg/***** 986706f2543Smrg * ChangeWindowAttributes 987706f2543Smrg * 988706f2543Smrg * The value-mask specifies which attributes are to be changed; the 989706f2543Smrg * value-list contains one value for each one bit in the mask, from least 990706f2543Smrg * to most significant bit in the mask. 991706f2543Smrg *****/ 992706f2543Smrg 993706f2543Smrgint 994706f2543SmrgChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) 995706f2543Smrg{ 996706f2543Smrg XID *pVlist; 997706f2543Smrg PixmapPtr pPixmap; 998706f2543Smrg Pixmap pixID; 999706f2543Smrg CursorPtr pCursor, pOldCursor; 1000706f2543Smrg Cursor cursorID; 1001706f2543Smrg WindowPtr pChild; 1002706f2543Smrg Colormap cmap; 1003706f2543Smrg ColormapPtr pCmap; 1004706f2543Smrg xEvent xE; 1005706f2543Smrg int error, rc; 1006706f2543Smrg ScreenPtr pScreen; 1007706f2543Smrg Mask index2, tmask, vmaskCopy = 0; 1008706f2543Smrg unsigned int val; 1009706f2543Smrg Bool checkOptional = FALSE, borderRelative = FALSE; 1010706f2543Smrg 1011706f2543Smrg if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK))) 1012706f2543Smrg return BadMatch; 1013706f2543Smrg 1014706f2543Smrg error = Success; 1015706f2543Smrg pScreen = pWin->drawable.pScreen; 1016706f2543Smrg pVlist = vlist; 1017706f2543Smrg tmask = vmask; 1018706f2543Smrg while (tmask) 1019706f2543Smrg { 1020706f2543Smrg index2 = (Mask) lowbit (tmask); 1021706f2543Smrg tmask &= ~index2; 1022706f2543Smrg switch (index2) 1023706f2543Smrg { 1024706f2543Smrg case CWBackPixmap: 1025706f2543Smrg pixID = (Pixmap )*pVlist; 1026706f2543Smrg pVlist++; 1027706f2543Smrg if (pWin->backgroundState == ParentRelative) 1028706f2543Smrg borderRelative = TRUE; 1029706f2543Smrg if (pixID == None) 1030706f2543Smrg { 1031706f2543Smrg if (pWin->backgroundState == BackgroundPixmap) 1032706f2543Smrg (*pScreen->DestroyPixmap)(pWin->background.pixmap); 1033706f2543Smrg if (!pWin->parent) 1034706f2543Smrg SetRootWindowBackground(pWin, pScreen, &index2); 1035706f2543Smrg else { 1036706f2543Smrg pWin->backgroundState = XaceBackgroundNoneState(pWin); 1037706f2543Smrg pWin->background.pixel = pScreen->whitePixel; 1038706f2543Smrg } 1039706f2543Smrg } 1040706f2543Smrg else if (pixID == ParentRelative) 1041706f2543Smrg { 1042706f2543Smrg if (pWin->parent && 1043706f2543Smrg pWin->drawable.depth != pWin->parent->drawable.depth) 1044706f2543Smrg { 1045706f2543Smrg error = BadMatch; 1046706f2543Smrg goto PatchUp; 1047706f2543Smrg } 1048706f2543Smrg if (pWin->backgroundState == BackgroundPixmap) 1049706f2543Smrg (*pScreen->DestroyPixmap)(pWin->background.pixmap); 1050706f2543Smrg if (!pWin->parent) 1051706f2543Smrg SetRootWindowBackground(pWin, pScreen, &index2); 1052706f2543Smrg else 1053706f2543Smrg pWin->backgroundState = ParentRelative; 1054706f2543Smrg borderRelative = TRUE; 1055706f2543Smrg /* Note that the parent's backgroundTile's refcnt is NOT 1056706f2543Smrg * incremented. */ 1057706f2543Smrg } 1058706f2543Smrg else 1059706f2543Smrg { 1060706f2543Smrg rc = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, 1061706f2543Smrg client, DixReadAccess); 1062706f2543Smrg if (rc == Success) 1063706f2543Smrg { 1064706f2543Smrg if ((pPixmap->drawable.depth != pWin->drawable.depth) || 1065706f2543Smrg (pPixmap->drawable.pScreen != pScreen)) 1066706f2543Smrg { 1067706f2543Smrg error = BadMatch; 1068706f2543Smrg goto PatchUp; 1069706f2543Smrg } 1070706f2543Smrg if (pWin->backgroundState == BackgroundPixmap) 1071706f2543Smrg (*pScreen->DestroyPixmap)(pWin->background.pixmap); 1072706f2543Smrg pWin->backgroundState = BackgroundPixmap; 1073706f2543Smrg pWin->background.pixmap = pPixmap; 1074706f2543Smrg pPixmap->refcnt++; 1075706f2543Smrg } 1076706f2543Smrg else 1077706f2543Smrg { 1078706f2543Smrg error = rc; 1079706f2543Smrg client->errorValue = pixID; 1080706f2543Smrg goto PatchUp; 1081706f2543Smrg } 1082706f2543Smrg } 1083706f2543Smrg break; 1084706f2543Smrg case CWBackPixel: 1085706f2543Smrg if (pWin->backgroundState == ParentRelative) 1086706f2543Smrg borderRelative = TRUE; 1087706f2543Smrg if (pWin->backgroundState == BackgroundPixmap) 1088706f2543Smrg (*pScreen->DestroyPixmap)(pWin->background.pixmap); 1089706f2543Smrg pWin->backgroundState = BackgroundPixel; 1090706f2543Smrg pWin->background.pixel = (CARD32 ) *pVlist; 1091706f2543Smrg /* background pixel overrides background pixmap, 1092706f2543Smrg so don't let the ddx layer see both bits */ 1093706f2543Smrg vmaskCopy &= ~CWBackPixmap; 1094706f2543Smrg pVlist++; 1095706f2543Smrg break; 1096706f2543Smrg case CWBorderPixmap: 1097706f2543Smrg pixID = (Pixmap ) *pVlist; 1098706f2543Smrg pVlist++; 1099706f2543Smrg if (pixID == CopyFromParent) 1100706f2543Smrg { 1101706f2543Smrg if (!pWin->parent || 1102706f2543Smrg (pWin->drawable.depth != pWin->parent->drawable.depth)) 1103706f2543Smrg { 1104706f2543Smrg error = BadMatch; 1105706f2543Smrg goto PatchUp; 1106706f2543Smrg } 1107706f2543Smrg if (pWin->parent->borderIsPixel == TRUE) { 1108706f2543Smrg if (pWin->borderIsPixel == FALSE) 1109706f2543Smrg (*pScreen->DestroyPixmap)(pWin->border.pixmap); 1110706f2543Smrg pWin->border = pWin->parent->border; 1111706f2543Smrg pWin->borderIsPixel = TRUE; 1112706f2543Smrg index2 = CWBorderPixel; 1113706f2543Smrg break; 1114706f2543Smrg } 1115706f2543Smrg else 1116706f2543Smrg { 1117706f2543Smrg pixID = pWin->parent->border.pixmap->drawable.id; 1118706f2543Smrg } 1119706f2543Smrg } 1120706f2543Smrg rc = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, 1121706f2543Smrg client, DixReadAccess); 1122706f2543Smrg if (rc == Success) 1123706f2543Smrg { 1124706f2543Smrg if ((pPixmap->drawable.depth != pWin->drawable.depth) || 1125706f2543Smrg (pPixmap->drawable.pScreen != pScreen)) 1126706f2543Smrg { 1127706f2543Smrg error = BadMatch; 1128706f2543Smrg goto PatchUp; 1129706f2543Smrg } 1130706f2543Smrg if (pWin->borderIsPixel == FALSE) 1131706f2543Smrg (*pScreen->DestroyPixmap)(pWin->border.pixmap); 1132706f2543Smrg pWin->borderIsPixel = FALSE; 1133706f2543Smrg pWin->border.pixmap = pPixmap; 1134706f2543Smrg pPixmap->refcnt++; 1135706f2543Smrg } 1136706f2543Smrg else 1137706f2543Smrg { 1138706f2543Smrg error = rc; 1139706f2543Smrg client->errorValue = pixID; 1140706f2543Smrg goto PatchUp; 1141706f2543Smrg } 1142706f2543Smrg break; 1143706f2543Smrg case CWBorderPixel: 1144706f2543Smrg if (pWin->borderIsPixel == FALSE) 1145706f2543Smrg (*pScreen->DestroyPixmap)(pWin->border.pixmap); 1146706f2543Smrg pWin->borderIsPixel = TRUE; 1147706f2543Smrg pWin->border.pixel = (CARD32) *pVlist; 1148706f2543Smrg /* border pixel overrides border pixmap, 1149706f2543Smrg so don't let the ddx layer see both bits */ 1150706f2543Smrg vmaskCopy &= ~CWBorderPixmap; 1151706f2543Smrg pVlist++; 1152706f2543Smrg break; 1153706f2543Smrg case CWBitGravity: 1154706f2543Smrg val = (CARD8 )*pVlist; 1155706f2543Smrg pVlist++; 1156706f2543Smrg if (val > StaticGravity) 1157706f2543Smrg { 1158706f2543Smrg error = BadValue; 1159706f2543Smrg client->errorValue = val; 1160706f2543Smrg goto PatchUp; 1161706f2543Smrg } 1162706f2543Smrg pWin->bitGravity = val; 1163706f2543Smrg break; 1164706f2543Smrg case CWWinGravity: 1165706f2543Smrg val = (CARD8 )*pVlist; 1166706f2543Smrg pVlist++; 1167706f2543Smrg if (val > StaticGravity) 1168706f2543Smrg { 1169706f2543Smrg error = BadValue; 1170706f2543Smrg client->errorValue = val; 1171706f2543Smrg goto PatchUp; 1172706f2543Smrg } 1173706f2543Smrg pWin->winGravity = val; 1174706f2543Smrg break; 1175706f2543Smrg case CWBackingStore: 1176706f2543Smrg val = (CARD8 )*pVlist; 1177706f2543Smrg pVlist++; 1178706f2543Smrg if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) 1179706f2543Smrg { 1180706f2543Smrg error = BadValue; 1181706f2543Smrg client->errorValue = val; 1182706f2543Smrg goto PatchUp; 1183706f2543Smrg } 1184706f2543Smrg pWin->backingStore = val; 1185706f2543Smrg pWin->forcedBS = FALSE; 1186706f2543Smrg break; 1187706f2543Smrg case CWBackingPlanes: 1188706f2543Smrg if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) { 1189706f2543Smrg if (!pWin->optional && !MakeWindowOptional (pWin)) 1190706f2543Smrg { 1191706f2543Smrg error = BadAlloc; 1192706f2543Smrg goto PatchUp; 1193706f2543Smrg } 1194706f2543Smrg pWin->optional->backingBitPlanes = (CARD32) *pVlist; 1195706f2543Smrg if ((CARD32)*pVlist == (CARD32)~0L) 1196706f2543Smrg checkOptional = TRUE; 1197706f2543Smrg } 1198706f2543Smrg pVlist++; 1199706f2543Smrg break; 1200706f2543Smrg case CWBackingPixel: 1201706f2543Smrg if (pWin->optional || (CARD32) *pVlist) { 1202706f2543Smrg if (!pWin->optional && !MakeWindowOptional (pWin)) 1203706f2543Smrg { 1204706f2543Smrg error = BadAlloc; 1205706f2543Smrg goto PatchUp; 1206706f2543Smrg } 1207706f2543Smrg pWin->optional->backingPixel = (CARD32) *pVlist; 1208706f2543Smrg if (!*pVlist) 1209706f2543Smrg checkOptional = TRUE; 1210706f2543Smrg } 1211706f2543Smrg pVlist++; 1212706f2543Smrg break; 1213706f2543Smrg case CWSaveUnder: 1214706f2543Smrg val = (BOOL) *pVlist; 1215706f2543Smrg pVlist++; 1216706f2543Smrg if ((val != xTrue) && (val != xFalse)) 1217706f2543Smrg { 1218706f2543Smrg error = BadValue; 1219706f2543Smrg client->errorValue = val; 1220706f2543Smrg goto PatchUp; 1221706f2543Smrg } 1222706f2543Smrg pWin->saveUnder = val; 1223706f2543Smrg break; 1224706f2543Smrg case CWEventMask: 1225706f2543Smrg rc = EventSelectForWindow(pWin, client, (Mask )*pVlist); 1226706f2543Smrg if (rc) 1227706f2543Smrg { 1228706f2543Smrg error = rc; 1229706f2543Smrg goto PatchUp; 1230706f2543Smrg } 1231706f2543Smrg pVlist++; 1232706f2543Smrg break; 1233706f2543Smrg case CWDontPropagate: 1234706f2543Smrg rc = EventSuppressForWindow(pWin, client, (Mask )*pVlist, 1235706f2543Smrg &checkOptional); 1236706f2543Smrg if (rc) 1237706f2543Smrg { 1238706f2543Smrg error = rc; 1239706f2543Smrg goto PatchUp; 1240706f2543Smrg } 1241706f2543Smrg pVlist++; 1242706f2543Smrg break; 1243706f2543Smrg case CWOverrideRedirect: 1244706f2543Smrg val = (BOOL ) *pVlist; 1245706f2543Smrg pVlist++; 1246706f2543Smrg if ((val != xTrue) && (val != xFalse)) 1247706f2543Smrg { 1248706f2543Smrg error = BadValue; 1249706f2543Smrg client->errorValue = val; 1250706f2543Smrg goto PatchUp; 1251706f2543Smrg } 1252706f2543Smrg if (val == xTrue) { 1253706f2543Smrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, 1254706f2543Smrg RT_WINDOW, pWin, RT_NONE, NULL, DixGrabAccess); 1255706f2543Smrg if (rc != Success) { 1256706f2543Smrg error = rc; 1257706f2543Smrg client->errorValue = pWin->drawable.id; 1258706f2543Smrg goto PatchUp; 1259706f2543Smrg } 1260706f2543Smrg } 1261706f2543Smrg pWin->overrideRedirect = val; 1262706f2543Smrg break; 1263706f2543Smrg case CWColormap: 1264706f2543Smrg cmap = (Colormap) *pVlist; 1265706f2543Smrg pVlist++; 1266706f2543Smrg if (cmap == CopyFromParent) 1267706f2543Smrg { 1268706f2543Smrg if (pWin->parent && 1269706f2543Smrg (!pWin->optional || 1270706f2543Smrg pWin->optional->visual == wVisual (pWin->parent))) 1271706f2543Smrg { 1272706f2543Smrg cmap = wColormap (pWin->parent); 1273706f2543Smrg } 1274706f2543Smrg else 1275706f2543Smrg cmap = None; 1276706f2543Smrg } 1277706f2543Smrg if (cmap == None) 1278706f2543Smrg { 1279706f2543Smrg error = BadMatch; 1280706f2543Smrg goto PatchUp; 1281706f2543Smrg } 1282706f2543Smrg rc = dixLookupResourceByType((pointer *)&pCmap, cmap, RT_COLORMAP, 1283706f2543Smrg client, DixUseAccess); 1284706f2543Smrg if (rc != Success) 1285706f2543Smrg { 1286706f2543Smrg error = rc; 1287706f2543Smrg client->errorValue = cmap; 1288706f2543Smrg goto PatchUp; 1289706f2543Smrg } 1290706f2543Smrg if (pCmap->pVisual->vid != wVisual (pWin) || 1291706f2543Smrg pCmap->pScreen != pScreen) 1292706f2543Smrg { 1293706f2543Smrg error = BadMatch; 1294706f2543Smrg goto PatchUp; 1295706f2543Smrg } 1296706f2543Smrg if (cmap != wColormap (pWin)) 1297706f2543Smrg { 1298706f2543Smrg if (!pWin->optional) 1299706f2543Smrg { 1300706f2543Smrg if (!MakeWindowOptional (pWin)) 1301706f2543Smrg { 1302706f2543Smrg error = BadAlloc; 1303706f2543Smrg goto PatchUp; 1304706f2543Smrg } 1305706f2543Smrg } 1306706f2543Smrg else if (pWin->parent && cmap == wColormap (pWin->parent)) 1307706f2543Smrg checkOptional = TRUE; 1308706f2543Smrg 1309706f2543Smrg /* 1310706f2543Smrg * propagate the original colormap to any children 1311706f2543Smrg * inheriting it 1312706f2543Smrg */ 1313706f2543Smrg 1314706f2543Smrg for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib) 1315706f2543Smrg { 1316706f2543Smrg if (!pChild->optional && !MakeWindowOptional (pChild)) 1317706f2543Smrg { 1318706f2543Smrg error = BadAlloc; 1319706f2543Smrg goto PatchUp; 1320706f2543Smrg } 1321706f2543Smrg } 1322706f2543Smrg 1323706f2543Smrg pWin->optional->colormap = cmap; 1324706f2543Smrg 1325706f2543Smrg /* 1326706f2543Smrg * check on any children now matching the new colormap 1327706f2543Smrg */ 1328706f2543Smrg 1329706f2543Smrg for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib) 1330706f2543Smrg { 1331706f2543Smrg if (pChild->optional->colormap == cmap) 1332706f2543Smrg CheckWindowOptionalNeed (pChild); 1333706f2543Smrg } 1334706f2543Smrg 1335706f2543Smrg xE.u.u.type = ColormapNotify; 1336706f2543Smrg xE.u.colormap.window = pWin->drawable.id; 1337706f2543Smrg xE.u.colormap.colormap = cmap; 1338706f2543Smrg xE.u.colormap.new = xTrue; 1339706f2543Smrg xE.u.colormap.state = IsMapInstalled(cmap, pWin); 1340706f2543Smrg DeliverEvents(pWin, &xE, 1, NullWindow); 1341706f2543Smrg } 1342706f2543Smrg break; 1343706f2543Smrg case CWCursor: 1344706f2543Smrg cursorID = (Cursor ) *pVlist; 1345706f2543Smrg pVlist++; 1346706f2543Smrg /* 1347706f2543Smrg * install the new 1348706f2543Smrg */ 1349706f2543Smrg if ( cursorID == None) 1350706f2543Smrg { 1351706f2543Smrg if (pWin == pWin->drawable.pScreen->root) 1352706f2543Smrg pCursor = rootCursor; 1353706f2543Smrg else 1354706f2543Smrg pCursor = (CursorPtr) None; 1355706f2543Smrg } 1356706f2543Smrg else 1357706f2543Smrg { 1358706f2543Smrg rc = dixLookupResourceByType((pointer *)&pCursor, cursorID, 1359706f2543Smrg RT_CURSOR, client, DixUseAccess); 1360706f2543Smrg if (rc != Success) 1361706f2543Smrg { 1362706f2543Smrg error = rc; 1363706f2543Smrg client->errorValue = cursorID; 1364706f2543Smrg goto PatchUp; 1365706f2543Smrg } 1366706f2543Smrg } 1367706f2543Smrg 1368706f2543Smrg if (pCursor != wCursor (pWin)) 1369706f2543Smrg { 1370706f2543Smrg /* 1371706f2543Smrg * patch up child windows so they don't lose cursors. 1372706f2543Smrg */ 1373706f2543Smrg 1374706f2543Smrg for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib) 1375706f2543Smrg { 1376706f2543Smrg if (!pChild->optional && !pChild->cursorIsNone && 1377706f2543Smrg !MakeWindowOptional (pChild)) 1378706f2543Smrg { 1379706f2543Smrg error = BadAlloc; 1380706f2543Smrg goto PatchUp; 1381706f2543Smrg } 1382706f2543Smrg } 1383706f2543Smrg 1384706f2543Smrg pOldCursor = 0; 1385706f2543Smrg if (pCursor == (CursorPtr) None) 1386706f2543Smrg { 1387706f2543Smrg pWin->cursorIsNone = TRUE; 1388706f2543Smrg if (pWin->optional) 1389706f2543Smrg { 1390706f2543Smrg pOldCursor = pWin->optional->cursor; 1391706f2543Smrg pWin->optional->cursor = (CursorPtr) None; 1392706f2543Smrg checkOptional = TRUE; 1393706f2543Smrg } 1394706f2543Smrg } else { 1395706f2543Smrg if (!pWin->optional) 1396706f2543Smrg { 1397706f2543Smrg if (!MakeWindowOptional (pWin)) 1398706f2543Smrg { 1399706f2543Smrg error = BadAlloc; 1400706f2543Smrg goto PatchUp; 1401706f2543Smrg } 1402706f2543Smrg } 1403706f2543Smrg else if (pWin->parent && pCursor == wCursor (pWin->parent)) 1404706f2543Smrg checkOptional = TRUE; 1405706f2543Smrg pOldCursor = pWin->optional->cursor; 1406706f2543Smrg pWin->optional->cursor = pCursor; 1407706f2543Smrg pCursor->refcnt++; 1408706f2543Smrg pWin->cursorIsNone = FALSE; 1409706f2543Smrg /* 1410706f2543Smrg * check on any children now matching the new cursor 1411706f2543Smrg */ 1412706f2543Smrg 1413706f2543Smrg for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib) 1414706f2543Smrg { 1415706f2543Smrg if (pChild->optional && 1416706f2543Smrg (pChild->optional->cursor == pCursor)) 1417706f2543Smrg CheckWindowOptionalNeed (pChild); 1418706f2543Smrg } 1419706f2543Smrg } 1420706f2543Smrg 1421706f2543Smrg if (pWin->realized) 1422706f2543Smrg WindowHasNewCursor( pWin); 1423706f2543Smrg 1424706f2543Smrg /* Can't free cursor until here - old cursor 1425706f2543Smrg * is needed in WindowHasNewCursor 1426706f2543Smrg */ 1427706f2543Smrg if (pOldCursor) 1428706f2543Smrg FreeCursor (pOldCursor, (Cursor)0); 1429706f2543Smrg } 1430706f2543Smrg break; 1431706f2543Smrg default: 1432706f2543Smrg error = BadValue; 1433706f2543Smrg client->errorValue = vmask; 1434706f2543Smrg goto PatchUp; 1435706f2543Smrg } 1436706f2543Smrg vmaskCopy |= index2; 1437706f2543Smrg } 1438706f2543SmrgPatchUp: 1439706f2543Smrg if (checkOptional) 1440706f2543Smrg CheckWindowOptionalNeed (pWin); 1441706f2543Smrg 1442706f2543Smrg /* We SHOULD check for an error value here XXX */ 1443706f2543Smrg (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy); 1444706f2543Smrg 1445706f2543Smrg /* 1446706f2543Smrg If the border contents have changed, redraw the border. 1447706f2543Smrg Note that this has to be done AFTER pScreen->ChangeWindowAttributes 1448706f2543Smrg for the tile to be rotated, and the correct function selected. 1449706f2543Smrg */ 1450706f2543Smrg if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative) 1451706f2543Smrg && pWin->viewable && HasBorder (pWin)) 1452706f2543Smrg { 1453706f2543Smrg RegionRec exposed; 1454706f2543Smrg 1455706f2543Smrg RegionNull(&exposed); 1456706f2543Smrg RegionSubtract(&exposed, &pWin->borderClip, &pWin->winSize); 1457706f2543Smrg miPaintWindow(pWin, &exposed, PW_BORDER); 1458706f2543Smrg RegionUninit(&exposed); 1459706f2543Smrg } 1460706f2543Smrg return error; 1461706f2543Smrg} 1462706f2543Smrg 1463706f2543Smrg 1464706f2543Smrg/***** 1465706f2543Smrg * GetWindowAttributes 1466706f2543Smrg * Notice that this is different than ChangeWindowAttributes 1467706f2543Smrg *****/ 1468706f2543Smrg 1469706f2543Smrgvoid 1470706f2543SmrgGetWindowAttributes(WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa) 1471706f2543Smrg{ 1472706f2543Smrg wa->type = X_Reply; 1473706f2543Smrg wa->bitGravity = pWin->bitGravity; 1474706f2543Smrg wa->winGravity = pWin->winGravity; 1475706f2543Smrg if (pWin->forcedBS && pWin->backingStore != Always) 1476706f2543Smrg wa->backingStore = NotUseful; 1477706f2543Smrg else 1478706f2543Smrg wa->backingStore = pWin->backingStore; 1479706f2543Smrg wa->length = bytes_to_int32(sizeof(xGetWindowAttributesReply) - 1480706f2543Smrg sizeof(xGenericReply)); 1481706f2543Smrg wa->sequenceNumber = client->sequence; 1482706f2543Smrg wa->backingBitPlanes = wBackingBitPlanes (pWin); 1483706f2543Smrg wa->backingPixel = wBackingPixel (pWin); 1484706f2543Smrg wa->saveUnder = (BOOL)pWin->saveUnder; 1485706f2543Smrg wa->override = pWin->overrideRedirect; 1486706f2543Smrg if (!pWin->mapped) 1487706f2543Smrg wa->mapState = IsUnmapped; 1488706f2543Smrg else if (pWin->realized) 1489706f2543Smrg wa->mapState = IsViewable; 1490706f2543Smrg else 1491706f2543Smrg wa->mapState = IsUnviewable; 1492706f2543Smrg 1493706f2543Smrg wa->colormap = wColormap (pWin); 1494706f2543Smrg wa->mapInstalled = (wa->colormap == None) ? xFalse 1495706f2543Smrg : IsMapInstalled(wa->colormap, pWin); 1496706f2543Smrg 1497706f2543Smrg wa->yourEventMask = EventMaskForClient(pWin, client); 1498706f2543Smrg wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin); 1499706f2543Smrg wa->doNotPropagateMask = wDontPropagateMask (pWin); 1500706f2543Smrg wa->class = pWin->drawable.class; 1501706f2543Smrg wa->visualID = wVisual (pWin); 1502706f2543Smrg} 1503706f2543Smrg 1504706f2543Smrg 1505706f2543SmrgWindowPtr 1506706f2543SmrgMoveWindowInStack(WindowPtr pWin, WindowPtr pNextSib) 1507706f2543Smrg{ 1508706f2543Smrg WindowPtr pParent = pWin->parent; 1509706f2543Smrg WindowPtr pFirstChange = pWin; /* highest window where list changes */ 1510706f2543Smrg 1511706f2543Smrg if (pWin->nextSib != pNextSib) 1512706f2543Smrg { 1513706f2543Smrg WindowPtr pOldNextSib = pWin->nextSib; 1514706f2543Smrg 1515706f2543Smrg if (!pNextSib) /* move to bottom */ 1516706f2543Smrg { 1517706f2543Smrg if (pParent->firstChild == pWin) 1518706f2543Smrg pParent->firstChild = pWin->nextSib; 1519706f2543Smrg /* if (pWin->nextSib) */ /* is always True: pNextSib == NULL 1520706f2543Smrg * and pWin->nextSib != pNextSib 1521706f2543Smrg * therefore pWin->nextSib != NULL */ 1522706f2543Smrg pFirstChange = pWin->nextSib; 1523706f2543Smrg pWin->nextSib->prevSib = pWin->prevSib; 1524706f2543Smrg if (pWin->prevSib) 1525706f2543Smrg pWin->prevSib->nextSib = pWin->nextSib; 1526706f2543Smrg pParent->lastChild->nextSib = pWin; 1527706f2543Smrg pWin->prevSib = pParent->lastChild; 1528706f2543Smrg pWin->nextSib = NullWindow; 1529706f2543Smrg pParent->lastChild = pWin; 1530706f2543Smrg } 1531706f2543Smrg else if (pParent->firstChild == pNextSib) /* move to top */ 1532706f2543Smrg { 1533706f2543Smrg pFirstChange = pWin; 1534706f2543Smrg if (pParent->lastChild == pWin) 1535706f2543Smrg pParent->lastChild = pWin->prevSib; 1536706f2543Smrg if (pWin->nextSib) 1537706f2543Smrg pWin->nextSib->prevSib = pWin->prevSib; 1538706f2543Smrg if (pWin->prevSib) 1539706f2543Smrg pWin->prevSib->nextSib = pWin->nextSib; 1540706f2543Smrg pWin->nextSib = pParent->firstChild; 1541706f2543Smrg pWin->prevSib = (WindowPtr ) NULL; 1542706f2543Smrg pNextSib->prevSib = pWin; 1543706f2543Smrg pParent->firstChild = pWin; 1544706f2543Smrg } 1545706f2543Smrg else /* move in middle of list */ 1546706f2543Smrg { 1547706f2543Smrg WindowPtr pOldNext = pWin->nextSib; 1548706f2543Smrg 1549706f2543Smrg pFirstChange = NullWindow; 1550706f2543Smrg if (pParent->firstChild == pWin) 1551706f2543Smrg pFirstChange = pParent->firstChild = pWin->nextSib; 1552706f2543Smrg if (pParent->lastChild == pWin) { 1553706f2543Smrg pFirstChange = pWin; 1554706f2543Smrg pParent->lastChild = pWin->prevSib; 1555706f2543Smrg } 1556706f2543Smrg if (pWin->nextSib) 1557706f2543Smrg pWin->nextSib->prevSib = pWin->prevSib; 1558706f2543Smrg if (pWin->prevSib) 1559706f2543Smrg pWin->prevSib->nextSib = pWin->nextSib; 1560706f2543Smrg pWin->nextSib = pNextSib; 1561706f2543Smrg pWin->prevSib = pNextSib->prevSib; 1562706f2543Smrg if (pNextSib->prevSib) 1563706f2543Smrg pNextSib->prevSib->nextSib = pWin; 1564706f2543Smrg pNextSib->prevSib = pWin; 1565706f2543Smrg if (!pFirstChange) { /* do we know it yet? */ 1566706f2543Smrg pFirstChange = pParent->firstChild; /* no, search from top */ 1567706f2543Smrg while ((pFirstChange != pWin) && (pFirstChange != pOldNext)) 1568706f2543Smrg pFirstChange = pFirstChange->nextSib; 1569706f2543Smrg } 1570706f2543Smrg } 1571706f2543Smrg if(pWin->drawable.pScreen->RestackWindow) 1572706f2543Smrg (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib); 1573706f2543Smrg } 1574706f2543Smrg 1575706f2543Smrg#ifdef ROOTLESS 1576706f2543Smrg /* 1577706f2543Smrg * In rootless mode we can't optimize away window restacks. 1578706f2543Smrg * There may be non-X windows around, so even if the window 1579706f2543Smrg * is in the correct position from X's point of view, 1580706f2543Smrg * the underlying window system may want to reorder it. 1581706f2543Smrg */ 1582706f2543Smrg else if (pWin->drawable.pScreen->RestackWindow) 1583706f2543Smrg (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib); 1584706f2543Smrg#endif 1585706f2543Smrg 1586706f2543Smrg return pFirstChange; 1587706f2543Smrg} 1588706f2543Smrg 1589706f2543Smrgvoid 1590706f2543SmrgSetWinSize (WindowPtr pWin) 1591706f2543Smrg{ 1592706f2543Smrg#ifdef COMPOSITE 1593706f2543Smrg if (pWin->redirectDraw != RedirectDrawNone) 1594706f2543Smrg { 1595706f2543Smrg BoxRec box; 1596706f2543Smrg 1597706f2543Smrg /* 1598706f2543Smrg * Redirected clients get clip list equal to their 1599706f2543Smrg * own geometry, not clipped to their parent 1600706f2543Smrg */ 1601706f2543Smrg box.x1 = pWin->drawable.x; 1602706f2543Smrg box.y1 = pWin->drawable.y; 1603706f2543Smrg box.x2 = pWin->drawable.x + pWin->drawable.width; 1604706f2543Smrg box.y2 = pWin->drawable.y + pWin->drawable.height; 1605706f2543Smrg RegionReset(&pWin->winSize, &box); 1606706f2543Smrg } 1607706f2543Smrg else 1608706f2543Smrg#endif 1609706f2543Smrg ClippedRegionFromBox(pWin->parent, &pWin->winSize, 1610706f2543Smrg pWin->drawable.x, pWin->drawable.y, 1611706f2543Smrg (int)pWin->drawable.width, 1612706f2543Smrg (int)pWin->drawable.height); 1613706f2543Smrg if (wBoundingShape (pWin) || wClipShape (pWin)) { 1614706f2543Smrg RegionTranslate(&pWin->winSize, - pWin->drawable.x, 1615706f2543Smrg - pWin->drawable.y); 1616706f2543Smrg if (wBoundingShape (pWin)) 1617706f2543Smrg RegionIntersect(&pWin->winSize, &pWin->winSize, 1618706f2543Smrg wBoundingShape (pWin)); 1619706f2543Smrg if (wClipShape (pWin)) 1620706f2543Smrg RegionIntersect(&pWin->winSize, &pWin->winSize, 1621706f2543Smrg wClipShape (pWin)); 1622706f2543Smrg RegionTranslate(&pWin->winSize, pWin->drawable.x, 1623706f2543Smrg pWin->drawable.y); 1624706f2543Smrg } 1625706f2543Smrg} 1626706f2543Smrg 1627706f2543Smrgvoid 1628706f2543SmrgSetBorderSize (WindowPtr pWin) 1629706f2543Smrg{ 1630706f2543Smrg int bw; 1631706f2543Smrg 1632706f2543Smrg if (HasBorder (pWin)) { 1633706f2543Smrg bw = wBorderWidth (pWin); 1634706f2543Smrg#ifdef COMPOSITE 1635706f2543Smrg if (pWin->redirectDraw != RedirectDrawNone) 1636706f2543Smrg { 1637706f2543Smrg BoxRec box; 1638706f2543Smrg 1639706f2543Smrg /* 1640706f2543Smrg * Redirected clients get clip list equal to their 1641706f2543Smrg * own geometry, not clipped to their parent 1642706f2543Smrg */ 1643706f2543Smrg box.x1 = pWin->drawable.x - bw; 1644706f2543Smrg box.y1 = pWin->drawable.y - bw; 1645706f2543Smrg box.x2 = pWin->drawable.x + pWin->drawable.width + bw; 1646706f2543Smrg box.y2 = pWin->drawable.y + pWin->drawable.height + bw; 1647706f2543Smrg RegionReset(&pWin->borderSize, &box); 1648706f2543Smrg } 1649706f2543Smrg else 1650706f2543Smrg#endif 1651706f2543Smrg ClippedRegionFromBox(pWin->parent, &pWin->borderSize, 1652706f2543Smrg pWin->drawable.x - bw, pWin->drawable.y - bw, 1653706f2543Smrg (int)(pWin->drawable.width + (bw<<1)), 1654706f2543Smrg (int)(pWin->drawable.height + (bw<<1))); 1655706f2543Smrg if (wBoundingShape (pWin)) { 1656706f2543Smrg RegionTranslate(&pWin->borderSize, - pWin->drawable.x, 1657706f2543Smrg - pWin->drawable.y); 1658706f2543Smrg RegionIntersect(&pWin->borderSize, &pWin->borderSize, 1659706f2543Smrg wBoundingShape (pWin)); 1660706f2543Smrg RegionTranslate(&pWin->borderSize, pWin->drawable.x, 1661706f2543Smrg pWin->drawable.y); 1662706f2543Smrg RegionUnion(&pWin->borderSize, &pWin->borderSize, 1663706f2543Smrg &pWin->winSize); 1664706f2543Smrg } 1665706f2543Smrg } else { 1666706f2543Smrg RegionCopy(&pWin->borderSize, &pWin->winSize); 1667706f2543Smrg } 1668706f2543Smrg} 1669706f2543Smrg 1670706f2543Smrg/** 1671706f2543Smrg * 1672706f2543Smrg * \param x,y new window position 1673706f2543Smrg * \param oldx,oldy old window position 1674706f2543Smrg * \param destx,desty position relative to gravity 1675706f2543Smrg */ 1676706f2543Smrg 1677706f2543Smrgvoid 1678706f2543SmrgGravityTranslate (int x, int y, int oldx, int oldy, 1679706f2543Smrg int dw, int dh, unsigned gravity, 1680706f2543Smrg int *destx, int *desty) 1681706f2543Smrg{ 1682706f2543Smrg switch (gravity) { 1683706f2543Smrg case NorthGravity: 1684706f2543Smrg *destx = x + dw / 2; 1685706f2543Smrg *desty = y; 1686706f2543Smrg break; 1687706f2543Smrg case NorthEastGravity: 1688706f2543Smrg *destx = x + dw; 1689706f2543Smrg *desty = y; 1690706f2543Smrg break; 1691706f2543Smrg case WestGravity: 1692706f2543Smrg *destx = x; 1693706f2543Smrg *desty = y + dh / 2; 1694706f2543Smrg break; 1695706f2543Smrg case CenterGravity: 1696706f2543Smrg *destx = x + dw / 2; 1697706f2543Smrg *desty = y + dh / 2; 1698706f2543Smrg break; 1699706f2543Smrg case EastGravity: 1700706f2543Smrg *destx = x + dw; 1701706f2543Smrg *desty = y + dh / 2; 1702706f2543Smrg break; 1703706f2543Smrg case SouthWestGravity: 1704706f2543Smrg *destx = x; 1705706f2543Smrg *desty = y + dh; 1706706f2543Smrg break; 1707706f2543Smrg case SouthGravity: 1708706f2543Smrg *destx = x + dw / 2; 1709706f2543Smrg *desty = y + dh; 1710706f2543Smrg break; 1711706f2543Smrg case SouthEastGravity: 1712706f2543Smrg *destx = x + dw; 1713706f2543Smrg *desty = y + dh; 1714706f2543Smrg break; 1715706f2543Smrg case StaticGravity: 1716706f2543Smrg *destx = oldx; 1717706f2543Smrg *desty = oldy; 1718706f2543Smrg break; 1719706f2543Smrg default: 1720706f2543Smrg *destx = x; 1721706f2543Smrg *desty = y; 1722706f2543Smrg break; 1723706f2543Smrg } 1724706f2543Smrg} 1725706f2543Smrg 1726706f2543Smrg/* XXX need to retile border on each window with ParentRelative origin */ 1727706f2543Smrgvoid 1728706f2543SmrgResizeChildrenWinSize(WindowPtr pWin, int dx, int dy, int dw, int dh) 1729706f2543Smrg{ 1730706f2543Smrg ScreenPtr pScreen; 1731706f2543Smrg WindowPtr pSib, pChild; 1732706f2543Smrg Bool resized = (dw || dh); 1733706f2543Smrg 1734706f2543Smrg pScreen = pWin->drawable.pScreen; 1735706f2543Smrg 1736706f2543Smrg for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib) 1737706f2543Smrg { 1738706f2543Smrg if (resized && (pSib->winGravity > NorthWestGravity)) 1739706f2543Smrg { 1740706f2543Smrg int cwsx, cwsy; 1741706f2543Smrg 1742706f2543Smrg cwsx = pSib->origin.x; 1743706f2543Smrg cwsy = pSib->origin.y; 1744706f2543Smrg GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh, 1745706f2543Smrg pSib->winGravity, &cwsx, &cwsy); 1746706f2543Smrg if (cwsx != pSib->origin.x || cwsy != pSib->origin.y) 1747706f2543Smrg { 1748706f2543Smrg xEvent event; 1749706f2543Smrg 1750706f2543Smrg event.u.u.type = GravityNotify; 1751706f2543Smrg event.u.gravity.window = pSib->drawable.id; 1752706f2543Smrg event.u.gravity.x = cwsx - wBorderWidth (pSib); 1753706f2543Smrg event.u.gravity.y = cwsy - wBorderWidth (pSib); 1754706f2543Smrg DeliverEvents (pSib, &event, 1, NullWindow); 1755706f2543Smrg pSib->origin.x = cwsx; 1756706f2543Smrg pSib->origin.y = cwsy; 1757706f2543Smrg } 1758706f2543Smrg } 1759706f2543Smrg pSib->drawable.x = pWin->drawable.x + pSib->origin.x; 1760706f2543Smrg pSib->drawable.y = pWin->drawable.y + pSib->origin.y; 1761706f2543Smrg SetWinSize (pSib); 1762706f2543Smrg SetBorderSize (pSib); 1763706f2543Smrg (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y); 1764706f2543Smrg 1765706f2543Smrg if ( (pChild = pSib->firstChild) ) 1766706f2543Smrg { 1767706f2543Smrg while (1) 1768706f2543Smrg { 1769706f2543Smrg pChild->drawable.x = pChild->parent->drawable.x + 1770706f2543Smrg pChild->origin.x; 1771706f2543Smrg pChild->drawable.y = pChild->parent->drawable.y + 1772706f2543Smrg pChild->origin.y; 1773706f2543Smrg SetWinSize (pChild); 1774706f2543Smrg SetBorderSize (pChild); 1775706f2543Smrg (*pScreen->PositionWindow)(pChild, 1776706f2543Smrg pChild->drawable.x, pChild->drawable.y); 1777706f2543Smrg if (pChild->firstChild) 1778706f2543Smrg { 1779706f2543Smrg pChild = pChild->firstChild; 1780706f2543Smrg continue; 1781706f2543Smrg } 1782706f2543Smrg while (!pChild->nextSib && (pChild != pSib)) 1783706f2543Smrg pChild = pChild->parent; 1784706f2543Smrg if (pChild == pSib) 1785706f2543Smrg break; 1786706f2543Smrg pChild = pChild->nextSib; 1787706f2543Smrg } 1788706f2543Smrg } 1789706f2543Smrg } 1790706f2543Smrg} 1791706f2543Smrg 1792706f2543Smrg#define GET_INT16(m, f) \ 1793706f2543Smrg if (m & mask) \ 1794706f2543Smrg { \ 1795706f2543Smrg f = (INT16) *pVlist;\ 1796706f2543Smrg pVlist++; \ 1797706f2543Smrg } 1798706f2543Smrg#define GET_CARD16(m, f) \ 1799706f2543Smrg if (m & mask) \ 1800706f2543Smrg { \ 1801706f2543Smrg f = (CARD16) *pVlist;\ 1802706f2543Smrg pVlist++;\ 1803706f2543Smrg } 1804706f2543Smrg 1805706f2543Smrg#define GET_CARD8(m, f) \ 1806706f2543Smrg if (m & mask) \ 1807706f2543Smrg { \ 1808706f2543Smrg f = (CARD8) *pVlist;\ 1809706f2543Smrg pVlist++;\ 1810706f2543Smrg } 1811706f2543Smrg 1812706f2543Smrg#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight)) 1813706f2543Smrg 1814706f2543Smrg#define IllegalInputOnlyConfigureMask (CWBorderWidth) 1815706f2543Smrg 1816706f2543Smrg/* 1817706f2543Smrg * IsSiblingAboveMe 1818706f2543Smrg * returns Above if pSib above pMe in stack or Below otherwise 1819706f2543Smrg */ 1820706f2543Smrg 1821706f2543Smrgstatic int 1822706f2543SmrgIsSiblingAboveMe( 1823706f2543Smrg WindowPtr pMe, 1824706f2543Smrg WindowPtr pSib) 1825706f2543Smrg{ 1826706f2543Smrg WindowPtr pWin; 1827706f2543Smrg 1828706f2543Smrg pWin = pMe->parent->firstChild; 1829706f2543Smrg while (pWin) 1830706f2543Smrg { 1831706f2543Smrg if (pWin == pSib) 1832706f2543Smrg return Above; 1833706f2543Smrg else if (pWin == pMe) 1834706f2543Smrg return Below; 1835706f2543Smrg pWin = pWin->nextSib; 1836706f2543Smrg } 1837706f2543Smrg return Below; 1838706f2543Smrg} 1839706f2543Smrg 1840706f2543Smrgstatic BoxPtr 1841706f2543SmrgWindowExtents( 1842706f2543Smrg WindowPtr pWin, 1843706f2543Smrg BoxPtr pBox) 1844706f2543Smrg{ 1845706f2543Smrg pBox->x1 = pWin->drawable.x - wBorderWidth (pWin); 1846706f2543Smrg pBox->y1 = pWin->drawable.y - wBorderWidth (pWin); 1847706f2543Smrg pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width 1848706f2543Smrg + wBorderWidth (pWin); 1849706f2543Smrg pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height 1850706f2543Smrg + wBorderWidth (pWin); 1851706f2543Smrg return pBox; 1852706f2543Smrg} 1853706f2543Smrg 1854706f2543Smrg#define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL) 1855706f2543Smrg 1856706f2543Smrgstatic RegionPtr 1857706f2543SmrgMakeBoundingRegion ( 1858706f2543Smrg WindowPtr pWin, 1859706f2543Smrg BoxPtr pBox) 1860706f2543Smrg{ 1861706f2543Smrg RegionPtr pRgn = RegionCreate(pBox, 1); 1862706f2543Smrg if (wBoundingShape (pWin)) { 1863706f2543Smrg RegionTranslate(pRgn, -pWin->origin.x, -pWin->origin.y); 1864706f2543Smrg RegionIntersect(pRgn, pRgn, wBoundingShape (pWin)); 1865706f2543Smrg RegionTranslate(pRgn, pWin->origin.x, pWin->origin.y); 1866706f2543Smrg } 1867706f2543Smrg return pRgn; 1868706f2543Smrg} 1869706f2543Smrg 1870706f2543Smrgstatic Bool 1871706f2543SmrgShapeOverlap ( 1872706f2543Smrg WindowPtr pWin, 1873706f2543Smrg BoxPtr pWinBox, 1874706f2543Smrg WindowPtr pSib, 1875706f2543Smrg BoxPtr pSibBox) 1876706f2543Smrg{ 1877706f2543Smrg RegionPtr pWinRgn, pSibRgn; 1878706f2543Smrg Bool ret; 1879706f2543Smrg 1880706f2543Smrg if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib)) 1881706f2543Smrg return TRUE; 1882706f2543Smrg pWinRgn = MakeBoundingRegion (pWin, pWinBox); 1883706f2543Smrg pSibRgn = MakeBoundingRegion (pSib, pSibBox); 1884706f2543Smrg RegionIntersect(pWinRgn, pWinRgn, pSibRgn); 1885706f2543Smrg ret = RegionNotEmpty(pWinRgn); 1886706f2543Smrg RegionDestroy(pWinRgn); 1887706f2543Smrg RegionDestroy(pSibRgn); 1888706f2543Smrg return ret; 1889706f2543Smrg} 1890706f2543Smrg 1891706f2543Smrgstatic Bool 1892706f2543SmrgAnyWindowOverlapsMe( 1893706f2543Smrg WindowPtr pWin, 1894706f2543Smrg WindowPtr pHead, 1895706f2543Smrg BoxPtr box) 1896706f2543Smrg{ 1897706f2543Smrg WindowPtr pSib; 1898706f2543Smrg BoxRec sboxrec; 1899706f2543Smrg BoxPtr sbox; 1900706f2543Smrg 1901706f2543Smrg for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib) 1902706f2543Smrg { 1903706f2543Smrg if (pSib->mapped) 1904706f2543Smrg { 1905706f2543Smrg sbox = WindowExtents(pSib, &sboxrec); 1906706f2543Smrg if (BOXES_OVERLAP(sbox, box) 1907706f2543Smrg && ShapeOverlap (pWin, box, pSib, sbox) 1908706f2543Smrg ) 1909706f2543Smrg return TRUE; 1910706f2543Smrg } 1911706f2543Smrg } 1912706f2543Smrg return FALSE; 1913706f2543Smrg} 1914706f2543Smrg 1915706f2543Smrgstatic Bool 1916706f2543SmrgIOverlapAnyWindow( 1917706f2543Smrg WindowPtr pWin, 1918706f2543Smrg BoxPtr box) 1919706f2543Smrg{ 1920706f2543Smrg WindowPtr pSib; 1921706f2543Smrg BoxRec sboxrec; 1922706f2543Smrg BoxPtr sbox; 1923706f2543Smrg 1924706f2543Smrg for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib) 1925706f2543Smrg { 1926706f2543Smrg if (pSib->mapped) 1927706f2543Smrg { 1928706f2543Smrg sbox = WindowExtents(pSib, &sboxrec); 1929706f2543Smrg if (BOXES_OVERLAP(sbox, box) 1930706f2543Smrg && ShapeOverlap (pWin, box, pSib, sbox) 1931706f2543Smrg ) 1932706f2543Smrg return TRUE; 1933706f2543Smrg } 1934706f2543Smrg } 1935706f2543Smrg return FALSE; 1936706f2543Smrg} 1937706f2543Smrg 1938706f2543Smrg/* 1939706f2543Smrg * WhereDoIGoInTheStack() 1940706f2543Smrg * Given pWin and pSib and the relationshipe smode, return 1941706f2543Smrg * the window that pWin should go ABOVE. 1942706f2543Smrg * If a pSib is specified: 1943706f2543Smrg * Above: pWin is placed just above pSib 1944706f2543Smrg * Below: pWin is placed just below pSib 1945706f2543Smrg * TopIf: if pSib occludes pWin, then pWin is placed 1946706f2543Smrg * at the top of the stack 1947706f2543Smrg * BottomIf: if pWin occludes pSib, then pWin is 1948706f2543Smrg * placed at the bottom of the stack 1949706f2543Smrg * Opposite: if pSib occludes pWin, then pWin is placed at the 1950706f2543Smrg * top of the stack, else if pWin occludes pSib, then 1951706f2543Smrg * pWin is placed at the bottom of the stack 1952706f2543Smrg * 1953706f2543Smrg * If pSib is NULL: 1954706f2543Smrg * Above: pWin is placed at the top of the stack 1955706f2543Smrg * Below: pWin is placed at the bottom of the stack 1956706f2543Smrg * TopIf: if any sibling occludes pWin, then pWin is placed at 1957706f2543Smrg * the top of the stack 1958706f2543Smrg * BottomIf: if pWin occludes any sibline, then pWin is placed at 1959706f2543Smrg * the bottom of the stack 1960706f2543Smrg * Opposite: if any sibling occludes pWin, then pWin is placed at 1961706f2543Smrg * the top of the stack, else if pWin occludes any 1962706f2543Smrg * sibling, then pWin is placed at the bottom of the stack 1963706f2543Smrg * 1964706f2543Smrg */ 1965706f2543Smrg 1966706f2543Smrgstatic WindowPtr 1967706f2543SmrgWhereDoIGoInTheStack( 1968706f2543Smrg WindowPtr pWin, 1969706f2543Smrg WindowPtr pSib, 1970706f2543Smrg short x, 1971706f2543Smrg short y, 1972706f2543Smrg unsigned short w, 1973706f2543Smrg unsigned short h, 1974706f2543Smrg int smode) 1975706f2543Smrg{ 1976706f2543Smrg BoxRec box; 1977706f2543Smrg WindowPtr pHead, pFirst; 1978706f2543Smrg 1979706f2543Smrg if ((pWin == pWin->parent->firstChild) && 1980706f2543Smrg (pWin == pWin->parent->lastChild)) 1981706f2543Smrg return((WindowPtr ) NULL); 1982706f2543Smrg pHead = RealChildHead(pWin->parent); 1983706f2543Smrg pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild; 1984706f2543Smrg box.x1 = x; 1985706f2543Smrg box.y1 = y; 1986706f2543Smrg box.x2 = x + (int)w; 1987706f2543Smrg box.y2 = y + (int)h; 1988706f2543Smrg switch (smode) 1989706f2543Smrg { 1990706f2543Smrg case Above: 1991706f2543Smrg if (pSib) 1992706f2543Smrg return pSib; 1993706f2543Smrg else if (pWin == pFirst) 1994706f2543Smrg return pWin->nextSib; 1995706f2543Smrg else 1996706f2543Smrg return pFirst; 1997706f2543Smrg case Below: 1998706f2543Smrg if (pSib) 1999706f2543Smrg if (pSib->nextSib != pWin) 2000706f2543Smrg return pSib->nextSib; 2001706f2543Smrg else 2002706f2543Smrg return pWin->nextSib; 2003706f2543Smrg else 2004706f2543Smrg return NullWindow; 2005706f2543Smrg case TopIf: 2006706f2543Smrg if ((!pWin->mapped || (pSib && !pSib->mapped))) 2007706f2543Smrg return pWin->nextSib; 2008706f2543Smrg else if (pSib) 2009706f2543Smrg { 2010706f2543Smrg if ((IsSiblingAboveMe(pWin, pSib) == Above) && 2011706f2543Smrg (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT)) 2012706f2543Smrg return pFirst; 2013706f2543Smrg else 2014706f2543Smrg return pWin->nextSib; 2015706f2543Smrg } 2016706f2543Smrg else if (AnyWindowOverlapsMe(pWin, pHead, &box)) 2017706f2543Smrg return pFirst; 2018706f2543Smrg else 2019706f2543Smrg return pWin->nextSib; 2020706f2543Smrg case BottomIf: 2021706f2543Smrg if ((!pWin->mapped || (pSib && !pSib->mapped))) 2022706f2543Smrg return pWin->nextSib; 2023706f2543Smrg else if (pSib) 2024706f2543Smrg { 2025706f2543Smrg if ((IsSiblingAboveMe(pWin, pSib) == Below) && 2026706f2543Smrg (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT)) 2027706f2543Smrg return NullWindow; 2028706f2543Smrg else 2029706f2543Smrg return pWin->nextSib; 2030706f2543Smrg } 2031706f2543Smrg else if (IOverlapAnyWindow(pWin, &box)) 2032706f2543Smrg return NullWindow; 2033706f2543Smrg else 2034706f2543Smrg return pWin->nextSib; 2035706f2543Smrg case Opposite: 2036706f2543Smrg if ((!pWin->mapped || (pSib && !pSib->mapped))) 2037706f2543Smrg return pWin->nextSib; 2038706f2543Smrg else if (pSib) 2039706f2543Smrg { 2040706f2543Smrg if (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT) 2041706f2543Smrg { 2042706f2543Smrg if (IsSiblingAboveMe(pWin, pSib) == Above) 2043706f2543Smrg return pFirst; 2044706f2543Smrg else 2045706f2543Smrg return NullWindow; 2046706f2543Smrg } 2047706f2543Smrg else 2048706f2543Smrg return pWin->nextSib; 2049706f2543Smrg } 2050706f2543Smrg else if (AnyWindowOverlapsMe(pWin, pHead, &box)) 2051706f2543Smrg { 2052706f2543Smrg /* If I'm occluded, I can't possibly be the first child 2053706f2543Smrg * if (pWin == pWin->parent->firstChild) 2054706f2543Smrg * return pWin->nextSib; 2055706f2543Smrg */ 2056706f2543Smrg return pFirst; 2057706f2543Smrg } 2058706f2543Smrg else if (IOverlapAnyWindow(pWin, &box)) 2059706f2543Smrg return NullWindow; 2060706f2543Smrg else 2061706f2543Smrg return pWin->nextSib; 2062706f2543Smrg default: 2063706f2543Smrg { 2064706f2543Smrg /* should never happen; make something up. */ 2065706f2543Smrg return pWin->nextSib; 2066706f2543Smrg } 2067706f2543Smrg } 2068706f2543Smrg} 2069706f2543Smrg 2070706f2543Smrgstatic void 2071706f2543SmrgReflectStackChange( 2072706f2543Smrg WindowPtr pWin, 2073706f2543Smrg WindowPtr pSib, 2074706f2543Smrg VTKind kind) 2075706f2543Smrg{ 2076706f2543Smrg/* Note that pSib might be NULL */ 2077706f2543Smrg 2078706f2543Smrg Bool WasViewable = (Bool)pWin->viewable; 2079706f2543Smrg Bool anyMarked; 2080706f2543Smrg WindowPtr pFirstChange; 2081706f2543Smrg WindowPtr pLayerWin; 2082706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 2083706f2543Smrg 2084706f2543Smrg /* if this is a root window, can't be restacked */ 2085706f2543Smrg if (!pWin->parent) 2086706f2543Smrg return; 2087706f2543Smrg 2088706f2543Smrg pFirstChange = MoveWindowInStack(pWin, pSib); 2089706f2543Smrg 2090706f2543Smrg if (WasViewable) 2091706f2543Smrg { 2092706f2543Smrg anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange, 2093706f2543Smrg &pLayerWin); 2094706f2543Smrg if (pLayerWin != pWin) pFirstChange = pLayerWin; 2095706f2543Smrg if (anyMarked) 2096706f2543Smrg { 2097706f2543Smrg (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind); 2098706f2543Smrg (*pScreen->HandleExposures)(pLayerWin->parent); 2099706f2543Smrg } 2100706f2543Smrg if (anyMarked && pWin->drawable.pScreen->PostValidateTree) 2101706f2543Smrg (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind); 2102706f2543Smrg } 2103706f2543Smrg if (pWin->realized) 2104706f2543Smrg WindowsRestructured (); 2105706f2543Smrg} 2106706f2543Smrg 2107706f2543Smrg/***** 2108706f2543Smrg * ConfigureWindow 2109706f2543Smrg *****/ 2110706f2543Smrg 2111706f2543Smrgint 2112706f2543SmrgConfigureWindow(WindowPtr pWin, Mask mask, XID *vlist, ClientPtr client) 2113706f2543Smrg{ 2114706f2543Smrg#define RESTACK_WIN 0 2115706f2543Smrg#define MOVE_WIN 1 2116706f2543Smrg#define RESIZE_WIN 2 2117706f2543Smrg#define REBORDER_WIN 3 2118706f2543Smrg WindowPtr pSib = NullWindow; 2119706f2543Smrg WindowPtr pParent = pWin->parent; 2120706f2543Smrg Window sibwid = 0; 2121706f2543Smrg Mask index2, tmask; 2122706f2543Smrg XID *pVlist; 2123706f2543Smrg short x, y, beforeX, beforeY; 2124706f2543Smrg unsigned short w = pWin->drawable.width, 2125706f2543Smrg h = pWin->drawable.height, 2126706f2543Smrg bw = pWin->borderWidth; 2127706f2543Smrg int rc, action, smode = Above; 2128706f2543Smrg xEvent event; 2129706f2543Smrg 2130706f2543Smrg if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask)) 2131706f2543Smrg return BadMatch; 2132706f2543Smrg 2133706f2543Smrg if ((mask & CWSibling) && !(mask & CWStackMode)) 2134706f2543Smrg return BadMatch; 2135706f2543Smrg 2136706f2543Smrg pVlist = vlist; 2137706f2543Smrg 2138706f2543Smrg if (pParent) 2139706f2543Smrg { 2140706f2543Smrg x = pWin->drawable.x - pParent->drawable.x - (int)bw; 2141706f2543Smrg y = pWin->drawable.y - pParent->drawable.y - (int)bw; 2142706f2543Smrg } 2143706f2543Smrg else 2144706f2543Smrg { 2145706f2543Smrg x = pWin->drawable.x; 2146706f2543Smrg y = pWin->drawable.y; 2147706f2543Smrg } 2148706f2543Smrg beforeX = x; 2149706f2543Smrg beforeY = y; 2150706f2543Smrg action = RESTACK_WIN; 2151706f2543Smrg if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth)))) 2152706f2543Smrg { 2153706f2543Smrg GET_INT16(CWX, x); 2154706f2543Smrg GET_INT16(CWY, y); 2155706f2543Smrg action = MOVE_WIN; 2156706f2543Smrg } 2157706f2543Smrg /* or should be resized */ 2158706f2543Smrg else if (mask & (CWX | CWY | CWWidth | CWHeight)) 2159706f2543Smrg { 2160706f2543Smrg GET_INT16(CWX, x); 2161706f2543Smrg GET_INT16(CWY, y); 2162706f2543Smrg GET_CARD16(CWWidth, w); 2163706f2543Smrg GET_CARD16 (CWHeight, h); 2164706f2543Smrg if (!w || !h) 2165706f2543Smrg { 2166706f2543Smrg client->errorValue = 0; 2167706f2543Smrg return BadValue; 2168706f2543Smrg } 2169706f2543Smrg action = RESIZE_WIN; 2170706f2543Smrg } 2171706f2543Smrg tmask = mask & ~ChangeMask; 2172706f2543Smrg while (tmask) 2173706f2543Smrg { 2174706f2543Smrg index2 = (Mask)lowbit (tmask); 2175706f2543Smrg tmask &= ~index2; 2176706f2543Smrg switch (index2) 2177706f2543Smrg { 2178706f2543Smrg case CWBorderWidth: 2179706f2543Smrg GET_CARD16(CWBorderWidth, bw); 2180706f2543Smrg break; 2181706f2543Smrg case CWSibling: 2182706f2543Smrg sibwid = (Window ) *pVlist; 2183706f2543Smrg pVlist++; 2184706f2543Smrg rc = dixLookupWindow(&pSib, sibwid, client, DixGetAttrAccess); 2185706f2543Smrg if (rc != Success) 2186706f2543Smrg { 2187706f2543Smrg client->errorValue = sibwid; 2188706f2543Smrg return rc; 2189706f2543Smrg } 2190706f2543Smrg if (pSib->parent != pParent) 2191706f2543Smrg return BadMatch; 2192706f2543Smrg if (pSib == pWin) 2193706f2543Smrg return BadMatch; 2194706f2543Smrg break; 2195706f2543Smrg case CWStackMode: 2196706f2543Smrg GET_CARD8(CWStackMode, smode); 2197706f2543Smrg if ((smode != TopIf) && (smode != BottomIf) && 2198706f2543Smrg (smode != Opposite) && (smode != Above) && (smode != Below)) 2199706f2543Smrg { 2200706f2543Smrg client->errorValue = smode; 2201706f2543Smrg return BadValue; 2202706f2543Smrg } 2203706f2543Smrg break; 2204706f2543Smrg default: 2205706f2543Smrg client->errorValue = mask; 2206706f2543Smrg return BadValue; 2207706f2543Smrg } 2208706f2543Smrg } 2209706f2543Smrg /* root really can't be reconfigured, so just return */ 2210706f2543Smrg if (!pParent) 2211706f2543Smrg return Success; 2212706f2543Smrg 2213706f2543Smrg /* Figure out if the window should be moved. Doesnt 2214706f2543Smrg make the changes to the window if event sent */ 2215706f2543Smrg 2216706f2543Smrg if (mask & CWStackMode) 2217706f2543Smrg pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x, 2218706f2543Smrg pParent->drawable.y + y, 2219706f2543Smrg w + (bw << 1), h + (bw << 1), smode); 2220706f2543Smrg else 2221706f2543Smrg pSib = pWin->nextSib; 2222706f2543Smrg 2223706f2543Smrg 2224706f2543Smrg if ((!pWin->overrideRedirect) && 2225706f2543Smrg (RedirectSend(pParent) 2226706f2543Smrg )) 2227706f2543Smrg { 2228706f2543Smrg memset(&event, 0, sizeof(xEvent)); 2229706f2543Smrg event.u.u.type = ConfigureRequest; 2230706f2543Smrg event.u.configureRequest.window = pWin->drawable.id; 2231706f2543Smrg if (mask & CWSibling) 2232706f2543Smrg event.u.configureRequest.sibling = sibwid; 2233706f2543Smrg else 2234706f2543Smrg event.u.configureRequest.sibling = None; 2235706f2543Smrg if (mask & CWStackMode) 2236706f2543Smrg event.u.u.detail = smode; 2237706f2543Smrg else 2238706f2543Smrg event.u.u.detail = Above; 2239706f2543Smrg event.u.configureRequest.x = x; 2240706f2543Smrg event.u.configureRequest.y = y; 2241706f2543Smrg#ifdef PANORAMIX 2242706f2543Smrg if(!noPanoramiXExtension && (!pParent || !pParent->parent)) { 2243706f2543Smrg event.u.configureRequest.x += screenInfo.screens[0]->x; 2244706f2543Smrg event.u.configureRequest.y += screenInfo.screens[0]->y; 2245706f2543Smrg } 2246706f2543Smrg#endif 2247706f2543Smrg event.u.configureRequest.width = w; 2248706f2543Smrg event.u.configureRequest.height = h; 2249706f2543Smrg event.u.configureRequest.borderWidth = bw; 2250706f2543Smrg event.u.configureRequest.valueMask = mask; 2251706f2543Smrg event.u.configureRequest.parent = pParent->drawable.id; 2252706f2543Smrg if (MaybeDeliverEventsToClient(pParent, &event, 1, 2253706f2543Smrg SubstructureRedirectMask, client) == 1) 2254706f2543Smrg return Success; 2255706f2543Smrg } 2256706f2543Smrg if (action == RESIZE_WIN) 2257706f2543Smrg { 2258706f2543Smrg Bool size_change = (w != pWin->drawable.width) 2259706f2543Smrg || (h != pWin->drawable.height); 2260706f2543Smrg if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask)) 2261706f2543Smrg { 2262706f2543Smrg xEvent eventT; 2263706f2543Smrg memset(&eventT, 0, sizeof(xEvent)); 2264706f2543Smrg eventT.u.u.type = ResizeRequest; 2265706f2543Smrg eventT.u.resizeRequest.window = pWin->drawable.id; 2266706f2543Smrg eventT.u.resizeRequest.width = w; 2267706f2543Smrg eventT.u.resizeRequest.height = h; 2268706f2543Smrg if (MaybeDeliverEventsToClient(pWin, &eventT, 1, 2269706f2543Smrg ResizeRedirectMask, client) == 1) 2270706f2543Smrg { 2271706f2543Smrg /* if event is delivered, leave the actual size alone. */ 2272706f2543Smrg w = pWin->drawable.width; 2273706f2543Smrg h = pWin->drawable.height; 2274706f2543Smrg size_change = FALSE; 2275706f2543Smrg } 2276706f2543Smrg } 2277706f2543Smrg if (!size_change) 2278706f2543Smrg { 2279706f2543Smrg if (mask & (CWX | CWY)) 2280706f2543Smrg action = MOVE_WIN; 2281706f2543Smrg else if (mask & (CWStackMode | CWBorderWidth)) 2282706f2543Smrg action = RESTACK_WIN; 2283706f2543Smrg else /* really nothing to do */ 2284706f2543Smrg return(Success) ; 2285706f2543Smrg } 2286706f2543Smrg } 2287706f2543Smrg 2288706f2543Smrg if (action == RESIZE_WIN) 2289706f2543Smrg /* we've already checked whether there's really a size change */ 2290706f2543Smrg goto ActuallyDoSomething; 2291706f2543Smrg if ((mask & CWX) && (x != beforeX)) 2292706f2543Smrg goto ActuallyDoSomething; 2293706f2543Smrg if ((mask & CWY) && (y != beforeY)) 2294706f2543Smrg goto ActuallyDoSomething; 2295706f2543Smrg if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin))) 2296706f2543Smrg goto ActuallyDoSomething; 2297706f2543Smrg if (mask & CWStackMode) 2298706f2543Smrg { 2299706f2543Smrg#ifndef ROOTLESS 2300706f2543Smrg /* See above for why we always reorder in rootless mode. */ 2301706f2543Smrg if (pWin->nextSib != pSib) 2302706f2543Smrg#endif 2303706f2543Smrg goto ActuallyDoSomething; 2304706f2543Smrg } 2305706f2543Smrg return Success; 2306706f2543Smrg 2307706f2543SmrgActuallyDoSomething: 2308706f2543Smrg if (pWin->drawable.pScreen->ConfigNotify) 2309706f2543Smrg { 2310706f2543Smrg int ret; 2311706f2543Smrg ret = (*pWin->drawable.pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib); 2312706f2543Smrg if (ret) { 2313706f2543Smrg client->errorValue = 0; 2314706f2543Smrg return ret; 2315706f2543Smrg } 2316706f2543Smrg } 2317706f2543Smrg 2318706f2543Smrg if (SubStrSend(pWin, pParent)) 2319706f2543Smrg { 2320706f2543Smrg memset(&event, 0, sizeof(xEvent)); 2321706f2543Smrg event.u.u.type = ConfigureNotify; 2322706f2543Smrg event.u.configureNotify.window = pWin->drawable.id; 2323706f2543Smrg if (pSib) 2324706f2543Smrg event.u.configureNotify.aboveSibling = pSib->drawable.id; 2325706f2543Smrg else 2326706f2543Smrg event.u.configureNotify.aboveSibling = None; 2327706f2543Smrg event.u.configureNotify.x = x; 2328706f2543Smrg event.u.configureNotify.y = y; 2329706f2543Smrg#ifdef PANORAMIX 2330706f2543Smrg if(!noPanoramiXExtension && (!pParent || !pParent->parent)) { 2331706f2543Smrg event.u.configureNotify.x += screenInfo.screens[0]->x; 2332706f2543Smrg event.u.configureNotify.y += screenInfo.screens[0]->y; 2333706f2543Smrg } 2334706f2543Smrg#endif 2335706f2543Smrg event.u.configureNotify.width = w; 2336706f2543Smrg event.u.configureNotify.height = h; 2337706f2543Smrg event.u.configureNotify.borderWidth = bw; 2338706f2543Smrg event.u.configureNotify.override = pWin->overrideRedirect; 2339706f2543Smrg DeliverEvents(pWin, &event, 1, NullWindow); 2340706f2543Smrg } 2341706f2543Smrg if (mask & CWBorderWidth) 2342706f2543Smrg { 2343706f2543Smrg if (action == RESTACK_WIN) 2344706f2543Smrg { 2345706f2543Smrg action = MOVE_WIN; 2346706f2543Smrg pWin->borderWidth = bw; 2347706f2543Smrg } 2348706f2543Smrg else if ((action == MOVE_WIN) && 2349706f2543Smrg (beforeX + wBorderWidth (pWin) == x + (int)bw) && 2350706f2543Smrg (beforeY + wBorderWidth (pWin) == y + (int)bw)) 2351706f2543Smrg { 2352706f2543Smrg action = REBORDER_WIN; 2353706f2543Smrg (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw); 2354706f2543Smrg } 2355706f2543Smrg else 2356706f2543Smrg pWin->borderWidth = bw; 2357706f2543Smrg } 2358706f2543Smrg if (action == MOVE_WIN) 2359706f2543Smrg (*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib, 2360706f2543Smrg (mask & CWBorderWidth) ? VTOther : VTMove); 2361706f2543Smrg else if (action == RESIZE_WIN) 2362706f2543Smrg (*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib); 2363706f2543Smrg else if (mask & CWStackMode) 2364706f2543Smrg ReflectStackChange(pWin, pSib, VTOther); 2365706f2543Smrg 2366706f2543Smrg if (action != RESTACK_WIN) 2367706f2543Smrg CheckCursorConfinement(pWin); 2368706f2543Smrg return Success; 2369706f2543Smrg#undef RESTACK_WIN 2370706f2543Smrg#undef MOVE_WIN 2371706f2543Smrg#undef RESIZE_WIN 2372706f2543Smrg#undef REBORDER_WIN 2373706f2543Smrg} 2374706f2543Smrg 2375706f2543Smrg 2376706f2543Smrg/****** 2377706f2543Smrg * 2378706f2543Smrg * CirculateWindow 2379706f2543Smrg * For RaiseLowest, raises the lowest mapped child (if any) that is 2380706f2543Smrg * obscured by another child to the top of the stack. For LowerHighest, 2381706f2543Smrg * lowers the highest mapped child (if any) that is obscuring another 2382706f2543Smrg * child to the bottom of the stack. Exposure processing is performed 2383706f2543Smrg * 2384706f2543Smrg ******/ 2385706f2543Smrg 2386706f2543Smrgint 2387706f2543SmrgCirculateWindow(WindowPtr pParent, int direction, ClientPtr client) 2388706f2543Smrg{ 2389706f2543Smrg WindowPtr pWin, pHead, pFirst; 2390706f2543Smrg xEvent event; 2391706f2543Smrg BoxRec box; 2392706f2543Smrg 2393706f2543Smrg pHead = RealChildHead(pParent); 2394706f2543Smrg pFirst = pHead ? pHead->nextSib : pParent->firstChild; 2395706f2543Smrg if (direction == RaiseLowest) 2396706f2543Smrg { 2397706f2543Smrg for (pWin = pParent->lastChild; 2398706f2543Smrg (pWin != pHead) && 2399706f2543Smrg !(pWin->mapped && 2400706f2543Smrg AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box))); 2401706f2543Smrg pWin = pWin->prevSib) ; 2402706f2543Smrg if (pWin == pHead) 2403706f2543Smrg return Success; 2404706f2543Smrg } 2405706f2543Smrg else 2406706f2543Smrg { 2407706f2543Smrg for (pWin = pFirst; 2408706f2543Smrg pWin && 2409706f2543Smrg !(pWin->mapped && 2410706f2543Smrg IOverlapAnyWindow(pWin, WindowExtents(pWin, &box))); 2411706f2543Smrg pWin = pWin->nextSib) ; 2412706f2543Smrg if (!pWin) 2413706f2543Smrg return Success; 2414706f2543Smrg } 2415706f2543Smrg 2416706f2543Smrg event.u.circulate.window = pWin->drawable.id; 2417706f2543Smrg event.u.circulate.parent = pParent->drawable.id; 2418706f2543Smrg event.u.circulate.event = pParent->drawable.id; 2419706f2543Smrg if (direction == RaiseLowest) 2420706f2543Smrg event.u.circulate.place = PlaceOnTop; 2421706f2543Smrg else 2422706f2543Smrg event.u.circulate.place = PlaceOnBottom; 2423706f2543Smrg 2424706f2543Smrg if (RedirectSend(pParent)) 2425706f2543Smrg { 2426706f2543Smrg event.u.u.type = CirculateRequest; 2427706f2543Smrg if (MaybeDeliverEventsToClient(pParent, &event, 1, 2428706f2543Smrg SubstructureRedirectMask, client) == 1) 2429706f2543Smrg return Success; 2430706f2543Smrg } 2431706f2543Smrg 2432706f2543Smrg event.u.u.type = CirculateNotify; 2433706f2543Smrg DeliverEvents(pWin, &event, 1, NullWindow); 2434706f2543Smrg ReflectStackChange(pWin, 2435706f2543Smrg (direction == RaiseLowest) ? pFirst : NullWindow, 2436706f2543Smrg VTStack); 2437706f2543Smrg 2438706f2543Smrg return Success; 2439706f2543Smrg} 2440706f2543Smrg 2441706f2543Smrgstatic int 2442706f2543SmrgCompareWIDs( 2443706f2543Smrg WindowPtr pWin, 2444706f2543Smrg pointer value) /* must conform to VisitWindowProcPtr */ 2445706f2543Smrg{ 2446706f2543Smrg Window *wid = (Window *)value; 2447706f2543Smrg 2448706f2543Smrg if (pWin->drawable.id == *wid) 2449706f2543Smrg return WT_STOPWALKING; 2450706f2543Smrg else 2451706f2543Smrg return WT_WALKCHILDREN; 2452706f2543Smrg} 2453706f2543Smrg 2454706f2543Smrg/***** 2455706f2543Smrg * ReparentWindow 2456706f2543Smrg *****/ 2457706f2543Smrg 2458706f2543Smrgint 2459706f2543SmrgReparentWindow(WindowPtr pWin, WindowPtr pParent, 2460706f2543Smrg int x, int y, ClientPtr client) 2461706f2543Smrg{ 2462706f2543Smrg WindowPtr pPrev, pPriorParent; 2463706f2543Smrg Bool WasMapped = (Bool)(pWin->mapped); 2464706f2543Smrg xEvent event; 2465706f2543Smrg int bw = wBorderWidth (pWin); 2466706f2543Smrg ScreenPtr pScreen; 2467706f2543Smrg 2468706f2543Smrg pScreen = pWin->drawable.pScreen; 2469706f2543Smrg if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING) 2470706f2543Smrg return BadMatch; 2471706f2543Smrg if (!MakeWindowOptional(pWin)) 2472706f2543Smrg return BadAlloc; 2473706f2543Smrg 2474706f2543Smrg if (WasMapped) 2475706f2543Smrg UnmapWindow(pWin, FALSE); 2476706f2543Smrg 2477706f2543Smrg memset(&event, 0, sizeof(xEvent)); 2478706f2543Smrg event.u.u.type = ReparentNotify; 2479706f2543Smrg event.u.reparent.window = pWin->drawable.id; 2480706f2543Smrg event.u.reparent.parent = pParent->drawable.id; 2481706f2543Smrg event.u.reparent.x = x; 2482706f2543Smrg event.u.reparent.y = y; 2483706f2543Smrg#ifdef PANORAMIX 2484706f2543Smrg if(!noPanoramiXExtension && !pParent->parent) { 2485706f2543Smrg event.u.reparent.x += screenInfo.screens[0]->x; 2486706f2543Smrg event.u.reparent.y += screenInfo.screens[0]->y; 2487706f2543Smrg } 2488706f2543Smrg#endif 2489706f2543Smrg event.u.reparent.override = pWin->overrideRedirect; 2490706f2543Smrg DeliverEvents(pWin, &event, 1, pParent); 2491706f2543Smrg 2492706f2543Smrg /* take out of sibling chain */ 2493706f2543Smrg 2494706f2543Smrg pPriorParent = pPrev = pWin->parent; 2495706f2543Smrg if (pPrev->firstChild == pWin) 2496706f2543Smrg pPrev->firstChild = pWin->nextSib; 2497706f2543Smrg if (pPrev->lastChild == pWin) 2498706f2543Smrg pPrev->lastChild = pWin->prevSib; 2499706f2543Smrg 2500706f2543Smrg if (pWin->nextSib) 2501706f2543Smrg pWin->nextSib->prevSib = pWin->prevSib; 2502706f2543Smrg if (pWin->prevSib) 2503706f2543Smrg pWin->prevSib->nextSib = pWin->nextSib; 2504706f2543Smrg 2505706f2543Smrg /* insert at begining of pParent */ 2506706f2543Smrg pWin->parent = pParent; 2507706f2543Smrg pPrev = RealChildHead(pParent); 2508706f2543Smrg if (pPrev) 2509706f2543Smrg { 2510706f2543Smrg pWin->nextSib = pPrev->nextSib; 2511706f2543Smrg if (pPrev->nextSib) 2512706f2543Smrg pPrev->nextSib->prevSib = pWin; 2513706f2543Smrg else 2514706f2543Smrg pParent->lastChild = pWin; 2515706f2543Smrg pPrev->nextSib = pWin; 2516706f2543Smrg pWin->prevSib = pPrev; 2517706f2543Smrg } 2518706f2543Smrg else 2519706f2543Smrg { 2520706f2543Smrg pWin->nextSib = pParent->firstChild; 2521706f2543Smrg pWin->prevSib = NullWindow; 2522706f2543Smrg if (pParent->firstChild) 2523706f2543Smrg pParent->firstChild->prevSib = pWin; 2524706f2543Smrg else 2525706f2543Smrg pParent->lastChild = pWin; 2526706f2543Smrg pParent->firstChild = pWin; 2527706f2543Smrg } 2528706f2543Smrg 2529706f2543Smrg pWin->origin.x = x + bw; 2530706f2543Smrg pWin->origin.y = y + bw; 2531706f2543Smrg pWin->drawable.x = x + bw + pParent->drawable.x; 2532706f2543Smrg pWin->drawable.y = y + bw + pParent->drawable.y; 2533706f2543Smrg 2534706f2543Smrg /* clip to parent */ 2535706f2543Smrg SetWinSize (pWin); 2536706f2543Smrg SetBorderSize (pWin); 2537706f2543Smrg 2538706f2543Smrg if (pScreen->ReparentWindow) 2539706f2543Smrg (*pScreen->ReparentWindow)(pWin, pPriorParent); 2540706f2543Smrg (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y); 2541706f2543Smrg ResizeChildrenWinSize(pWin, 0, 0, 0, 0); 2542706f2543Smrg 2543706f2543Smrg CheckWindowOptionalNeed(pWin); 2544706f2543Smrg 2545706f2543Smrg if (WasMapped) 2546706f2543Smrg MapWindow(pWin, client); 2547706f2543Smrg RecalculateDeliverableEvents(pWin); 2548706f2543Smrg return Success; 2549706f2543Smrg} 2550706f2543Smrg 2551706f2543Smrgstatic void 2552706f2543SmrgRealizeTree(WindowPtr pWin) 2553706f2543Smrg{ 2554706f2543Smrg WindowPtr pChild; 2555706f2543Smrg RealizeWindowProcPtr Realize; 2556706f2543Smrg 2557706f2543Smrg Realize = pWin->drawable.pScreen->RealizeWindow; 2558706f2543Smrg pChild = pWin; 2559706f2543Smrg while (1) 2560706f2543Smrg { 2561706f2543Smrg if (pChild->mapped) 2562706f2543Smrg { 2563706f2543Smrg pChild->realized = TRUE; 2564706f2543Smrg pChild->viewable = (pChild->drawable.class == InputOutput); 2565706f2543Smrg (* Realize)(pChild); 2566706f2543Smrg if (pChild->firstChild) 2567706f2543Smrg { 2568706f2543Smrg pChild = pChild->firstChild; 2569706f2543Smrg continue; 2570706f2543Smrg } 2571706f2543Smrg } 2572706f2543Smrg while (!pChild->nextSib && (pChild != pWin)) 2573706f2543Smrg pChild = pChild->parent; 2574706f2543Smrg if (pChild == pWin) 2575706f2543Smrg return; 2576706f2543Smrg pChild = pChild->nextSib; 2577706f2543Smrg } 2578706f2543Smrg} 2579706f2543Smrg 2580706f2543Smrgstatic WindowPtr windowDisableMapUnmapEvents; 2581706f2543Smrg 2582706f2543Smrgvoid 2583706f2543SmrgDisableMapUnmapEvents(WindowPtr pWin) 2584706f2543Smrg{ 2585706f2543Smrg assert (windowDisableMapUnmapEvents == NULL); 2586706f2543Smrg 2587706f2543Smrg windowDisableMapUnmapEvents = pWin; 2588706f2543Smrg} 2589706f2543Smrg 2590706f2543Smrgvoid 2591706f2543SmrgEnableMapUnmapEvents(WindowPtr pWin) 2592706f2543Smrg{ 2593706f2543Smrg assert (windowDisableMapUnmapEvents != NULL); 2594706f2543Smrg 2595706f2543Smrg windowDisableMapUnmapEvents = NULL; 2596706f2543Smrg} 2597706f2543Smrg 2598706f2543Smrgstatic Bool 2599706f2543SmrgMapUnmapEventsEnabled(WindowPtr pWin) 2600706f2543Smrg{ 2601706f2543Smrg return pWin != windowDisableMapUnmapEvents; 2602706f2543Smrg} 2603706f2543Smrg 2604706f2543Smrg/***** 2605706f2543Smrg * MapWindow 2606706f2543Smrg * If some other client has selected SubStructureReDirect on the parent 2607706f2543Smrg * and override-redirect is xFalse, then a MapRequest event is generated, 2608706f2543Smrg * but the window remains unmapped. Otherwise, the window is mapped and a 2609706f2543Smrg * MapNotify event is generated. 2610706f2543Smrg *****/ 2611706f2543Smrg 2612706f2543Smrgint 2613706f2543SmrgMapWindow(WindowPtr pWin, ClientPtr client) 2614706f2543Smrg{ 2615706f2543Smrg ScreenPtr pScreen; 2616706f2543Smrg 2617706f2543Smrg WindowPtr pParent; 2618706f2543Smrg WindowPtr pLayerWin; 2619706f2543Smrg 2620706f2543Smrg if (pWin->mapped) 2621706f2543Smrg return Success; 2622706f2543Smrg 2623706f2543Smrg /* general check for permission to map window */ 2624706f2543Smrg if (XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, RT_WINDOW, 2625706f2543Smrg pWin, RT_NONE, NULL, DixShowAccess) != Success) 2626706f2543Smrg return Success; 2627706f2543Smrg 2628706f2543Smrg pScreen = pWin->drawable.pScreen; 2629706f2543Smrg if ( (pParent = pWin->parent) ) 2630706f2543Smrg { 2631706f2543Smrg xEvent event; 2632706f2543Smrg Bool anyMarked; 2633706f2543Smrg 2634706f2543Smrg if ((!pWin->overrideRedirect) && 2635706f2543Smrg (RedirectSend(pParent) 2636706f2543Smrg )) 2637706f2543Smrg { 2638706f2543Smrg memset(&event, 0, sizeof(xEvent)); 2639706f2543Smrg event.u.u.type = MapRequest; 2640706f2543Smrg event.u.mapRequest.window = pWin->drawable.id; 2641706f2543Smrg event.u.mapRequest.parent = pParent->drawable.id; 2642706f2543Smrg 2643706f2543Smrg if (MaybeDeliverEventsToClient(pParent, &event, 1, 2644706f2543Smrg SubstructureRedirectMask, client) == 1) 2645706f2543Smrg return Success; 2646706f2543Smrg } 2647706f2543Smrg 2648706f2543Smrg pWin->mapped = TRUE; 2649706f2543Smrg if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin)) 2650706f2543Smrg { 2651706f2543Smrg memset(&event, 0, sizeof(xEvent)); 2652706f2543Smrg event.u.u.type = MapNotify; 2653706f2543Smrg event.u.mapNotify.window = pWin->drawable.id; 2654706f2543Smrg event.u.mapNotify.override = pWin->overrideRedirect; 2655706f2543Smrg DeliverEvents(pWin, &event, 1, NullWindow); 2656706f2543Smrg } 2657706f2543Smrg 2658706f2543Smrg if (!pParent->realized) 2659706f2543Smrg return Success; 2660706f2543Smrg RealizeTree(pWin); 2661706f2543Smrg if (pWin->viewable) 2662706f2543Smrg { 2663706f2543Smrg anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, 2664706f2543Smrg &pLayerWin); 2665706f2543Smrg if (anyMarked) 2666706f2543Smrg { 2667706f2543Smrg (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap); 2668706f2543Smrg (*pScreen->HandleExposures)(pLayerWin->parent); 2669706f2543Smrg } 2670706f2543Smrg if (anyMarked && pScreen->PostValidateTree) 2671706f2543Smrg (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap); 2672706f2543Smrg } 2673706f2543Smrg WindowsRestructured (); 2674706f2543Smrg } 2675706f2543Smrg else 2676706f2543Smrg { 2677706f2543Smrg RegionRec temp; 2678706f2543Smrg 2679706f2543Smrg pWin->mapped = TRUE; 2680706f2543Smrg pWin->realized = TRUE; /* for roots */ 2681706f2543Smrg pWin->viewable = pWin->drawable.class == InputOutput; 2682706f2543Smrg /* We SHOULD check for an error value here XXX */ 2683706f2543Smrg (*pScreen->RealizeWindow)(pWin); 2684706f2543Smrg if (pScreen->ClipNotify) 2685706f2543Smrg (*pScreen->ClipNotify) (pWin, 0, 0); 2686706f2543Smrg if (pScreen->PostValidateTree) 2687706f2543Smrg (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap); 2688706f2543Smrg RegionNull(&temp); 2689706f2543Smrg RegionCopy(&temp, &pWin->clipList); 2690706f2543Smrg (*pScreen->WindowExposures) (pWin, &temp, NullRegion); 2691706f2543Smrg RegionUninit(&temp); 2692706f2543Smrg } 2693706f2543Smrg 2694706f2543Smrg return Success; 2695706f2543Smrg} 2696706f2543Smrg 2697706f2543Smrg 2698706f2543Smrg/***** 2699706f2543Smrg * MapSubwindows 2700706f2543Smrg * Performs a MapWindow all unmapped children of the window, in top 2701706f2543Smrg * to bottom stacking order. 2702706f2543Smrg *****/ 2703706f2543Smrg 2704706f2543Smrgvoid 2705706f2543SmrgMapSubwindows(WindowPtr pParent, ClientPtr client) 2706706f2543Smrg{ 2707706f2543Smrg WindowPtr pWin; 2708706f2543Smrg WindowPtr pFirstMapped = NullWindow; 2709706f2543Smrg ScreenPtr pScreen; 2710706f2543Smrg Mask parentRedirect; 2711706f2543Smrg Mask parentNotify; 2712706f2543Smrg xEvent event; 2713706f2543Smrg Bool anyMarked; 2714706f2543Smrg WindowPtr pLayerWin; 2715706f2543Smrg 2716706f2543Smrg pScreen = pParent->drawable.pScreen; 2717706f2543Smrg parentRedirect = RedirectSend(pParent); 2718706f2543Smrg parentNotify = SubSend(pParent); 2719706f2543Smrg anyMarked = FALSE; 2720706f2543Smrg for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib) 2721706f2543Smrg { 2722706f2543Smrg if (!pWin->mapped) 2723706f2543Smrg { 2724706f2543Smrg if (parentRedirect && !pWin->overrideRedirect) 2725706f2543Smrg { 2726706f2543Smrg memset(&event, 0, sizeof(xEvent)); 2727706f2543Smrg event.u.u.type = MapRequest; 2728706f2543Smrg event.u.mapRequest.window = pWin->drawable.id; 2729706f2543Smrg event.u.mapRequest.parent = pParent->drawable.id; 2730706f2543Smrg 2731706f2543Smrg if (MaybeDeliverEventsToClient(pParent, &event, 1, 2732706f2543Smrg SubstructureRedirectMask, client) == 1) 2733706f2543Smrg continue; 2734706f2543Smrg } 2735706f2543Smrg 2736706f2543Smrg pWin->mapped = TRUE; 2737706f2543Smrg if (parentNotify || StrSend(pWin)) 2738706f2543Smrg { 2739706f2543Smrg memset(&event, 0, sizeof(xEvent)); 2740706f2543Smrg event.u.u.type = MapNotify; 2741706f2543Smrg event.u.mapNotify.window = pWin->drawable.id; 2742706f2543Smrg event.u.mapNotify.override = pWin->overrideRedirect; 2743706f2543Smrg DeliverEvents(pWin, &event, 1, NullWindow); 2744706f2543Smrg } 2745706f2543Smrg 2746706f2543Smrg if (!pFirstMapped) 2747706f2543Smrg pFirstMapped = pWin; 2748706f2543Smrg if (pParent->realized) 2749706f2543Smrg { 2750706f2543Smrg RealizeTree(pWin); 2751706f2543Smrg if (pWin->viewable) 2752706f2543Smrg { 2753706f2543Smrg anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 2754706f2543Smrg (WindowPtr *)NULL); 2755706f2543Smrg } 2756706f2543Smrg } 2757706f2543Smrg } 2758706f2543Smrg } 2759706f2543Smrg 2760706f2543Smrg if (pFirstMapped) 2761706f2543Smrg { 2762706f2543Smrg pLayerWin = (*pScreen->GetLayerWindow)(pParent); 2763706f2543Smrg if (pLayerWin->parent != pParent) { 2764706f2543Smrg anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin, 2765706f2543Smrg pLayerWin, 2766706f2543Smrg (WindowPtr *)NULL); 2767706f2543Smrg pFirstMapped = pLayerWin; 2768706f2543Smrg } 2769706f2543Smrg if (anyMarked) 2770706f2543Smrg { 2771706f2543Smrg (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap); 2772706f2543Smrg (*pScreen->HandleExposures)(pLayerWin->parent); 2773706f2543Smrg } 2774706f2543Smrg if (anyMarked && pScreen->PostValidateTree) 2775706f2543Smrg (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped, 2776706f2543Smrg VTMap); 2777706f2543Smrg WindowsRestructured (); 2778706f2543Smrg } 2779706f2543Smrg} 2780706f2543Smrg 2781706f2543Smrgstatic void 2782706f2543SmrgUnrealizeTree( 2783706f2543Smrg WindowPtr pWin, 2784706f2543Smrg Bool fromConfigure) 2785706f2543Smrg{ 2786706f2543Smrg WindowPtr pChild; 2787706f2543Smrg UnrealizeWindowProcPtr Unrealize; 2788706f2543Smrg MarkUnrealizedWindowProcPtr MarkUnrealizedWindow; 2789706f2543Smrg 2790706f2543Smrg Unrealize = pWin->drawable.pScreen->UnrealizeWindow; 2791706f2543Smrg MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow; 2792706f2543Smrg pChild = pWin; 2793706f2543Smrg while (1) 2794706f2543Smrg { 2795706f2543Smrg if (pChild->realized) 2796706f2543Smrg { 2797706f2543Smrg pChild->realized = FALSE; 2798706f2543Smrg pChild->visibility = VisibilityNotViewable; 2799706f2543Smrg#ifdef PANORAMIX 2800706f2543Smrg if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) { 2801706f2543Smrg PanoramiXRes *win; 2802706f2543Smrg int rc = dixLookupResourceByType((pointer *)&win, 2803706f2543Smrg pChild->drawable.id, XRT_WINDOW, 2804706f2543Smrg serverClient, DixWriteAccess); 2805706f2543Smrg if (rc == Success) 2806706f2543Smrg win->u.win.visibility = VisibilityNotViewable; 2807706f2543Smrg } 2808706f2543Smrg#endif 2809706f2543Smrg (* Unrealize)(pChild); 2810706f2543Smrg if (MapUnmapEventsEnabled(pWin)) 2811706f2543Smrg DeleteWindowFromAnyEvents(pChild, FALSE); 2812706f2543Smrg if (pChild->viewable) 2813706f2543Smrg { 2814706f2543Smrg pChild->viewable = FALSE; 2815706f2543Smrg (* MarkUnrealizedWindow)(pChild, pWin, fromConfigure); 2816706f2543Smrg pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; 2817706f2543Smrg } 2818706f2543Smrg if (pChild->firstChild) 2819706f2543Smrg { 2820706f2543Smrg pChild = pChild->firstChild; 2821706f2543Smrg continue; 2822706f2543Smrg } 2823706f2543Smrg } 2824706f2543Smrg while (!pChild->nextSib && (pChild != pWin)) 2825706f2543Smrg pChild = pChild->parent; 2826706f2543Smrg if (pChild == pWin) 2827706f2543Smrg return; 2828706f2543Smrg pChild = pChild->nextSib; 2829706f2543Smrg } 2830706f2543Smrg} 2831706f2543Smrg 2832706f2543Smrg/***** 2833706f2543Smrg * UnmapWindow 2834706f2543Smrg * If the window is already unmapped, this request has no effect. 2835706f2543Smrg * Otherwise, the window is unmapped and an UnMapNotify event is 2836706f2543Smrg * generated. Cannot unmap a root window. 2837706f2543Smrg *****/ 2838706f2543Smrg 2839706f2543Smrgint 2840706f2543SmrgUnmapWindow(WindowPtr pWin, Bool fromConfigure) 2841706f2543Smrg{ 2842706f2543Smrg WindowPtr pParent; 2843706f2543Smrg xEvent event; 2844706f2543Smrg Bool wasRealized = (Bool)pWin->realized; 2845706f2543Smrg Bool wasViewable = (Bool)pWin->viewable; 2846706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 2847706f2543Smrg WindowPtr pLayerWin = pWin; 2848706f2543Smrg 2849706f2543Smrg if ((!pWin->mapped) || (!(pParent = pWin->parent))) 2850706f2543Smrg return Success; 2851706f2543Smrg if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin)) 2852706f2543Smrg { 2853706f2543Smrg memset(&event, 0, sizeof(xEvent)); 2854706f2543Smrg event.u.u.type = UnmapNotify; 2855706f2543Smrg event.u.unmapNotify.window = pWin->drawable.id; 2856706f2543Smrg event.u.unmapNotify.fromConfigure = fromConfigure; 2857706f2543Smrg DeliverEvents(pWin, &event, 1, NullWindow); 2858706f2543Smrg } 2859706f2543Smrg if (wasViewable && !fromConfigure) 2860706f2543Smrg { 2861706f2543Smrg pWin->valdata = UnmapValData; 2862706f2543Smrg (*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin); 2863706f2543Smrg (*pScreen->MarkWindow)(pLayerWin->parent); 2864706f2543Smrg } 2865706f2543Smrg pWin->mapped = FALSE; 2866706f2543Smrg if (wasRealized) 2867706f2543Smrg UnrealizeTree(pWin, fromConfigure); 2868706f2543Smrg if (wasViewable) 2869706f2543Smrg { 2870706f2543Smrg if (!fromConfigure) 2871706f2543Smrg { 2872706f2543Smrg (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap); 2873706f2543Smrg (*pScreen->HandleExposures)(pLayerWin->parent); 2874706f2543Smrg } 2875706f2543Smrg if (!fromConfigure && pScreen->PostValidateTree) 2876706f2543Smrg (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap); 2877706f2543Smrg } 2878706f2543Smrg if (wasRealized && !fromConfigure) 2879706f2543Smrg WindowsRestructured (); 2880706f2543Smrg return Success; 2881706f2543Smrg} 2882706f2543Smrg 2883706f2543Smrg/***** 2884706f2543Smrg * UnmapSubwindows 2885706f2543Smrg * Performs an UnmapWindow request with the specified mode on all mapped 2886706f2543Smrg * children of the window, in bottom to top stacking order. 2887706f2543Smrg *****/ 2888706f2543Smrg 2889706f2543Smrgvoid 2890706f2543SmrgUnmapSubwindows(WindowPtr pWin) 2891706f2543Smrg{ 2892706f2543Smrg WindowPtr pChild, pHead; 2893706f2543Smrg xEvent event; 2894706f2543Smrg Bool wasRealized = (Bool)pWin->realized; 2895706f2543Smrg Bool wasViewable = (Bool)pWin->viewable; 2896706f2543Smrg Bool anyMarked = FALSE; 2897706f2543Smrg Mask parentNotify; 2898706f2543Smrg WindowPtr pLayerWin = NULL; 2899706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 2900706f2543Smrg 2901706f2543Smrg if (!pWin->firstChild) 2902706f2543Smrg return; 2903706f2543Smrg parentNotify = SubSend(pWin); 2904706f2543Smrg pHead = RealChildHead(pWin); 2905706f2543Smrg 2906706f2543Smrg if (wasViewable) 2907706f2543Smrg pLayerWin = (*pScreen->GetLayerWindow)(pWin); 2908706f2543Smrg 2909706f2543Smrg for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) 2910706f2543Smrg { 2911706f2543Smrg if (pChild->mapped) 2912706f2543Smrg { 2913706f2543Smrg if (parentNotify || StrSend(pChild)) 2914706f2543Smrg { 2915706f2543Smrg event.u.u.type = UnmapNotify; 2916706f2543Smrg event.u.unmapNotify.window = pChild->drawable.id; 2917706f2543Smrg event.u.unmapNotify.fromConfigure = xFalse; 2918706f2543Smrg DeliverEvents(pChild, &event, 1, NullWindow); 2919706f2543Smrg } 2920706f2543Smrg if (pChild->viewable) 2921706f2543Smrg { 2922706f2543Smrg pChild->valdata = UnmapValData; 2923706f2543Smrg anyMarked = TRUE; 2924706f2543Smrg } 2925706f2543Smrg pChild->mapped = FALSE; 2926706f2543Smrg if (pChild->realized) 2927706f2543Smrg UnrealizeTree(pChild, FALSE); 2928706f2543Smrg if (wasViewable) 2929706f2543Smrg { 2930706f2543Smrg } 2931706f2543Smrg } 2932706f2543Smrg } 2933706f2543Smrg if (wasViewable) 2934706f2543Smrg { 2935706f2543Smrg if (anyMarked) 2936706f2543Smrg { 2937706f2543Smrg if (pLayerWin->parent == pWin) 2938706f2543Smrg (*pScreen->MarkWindow)(pWin); 2939706f2543Smrg else 2940706f2543Smrg { 2941706f2543Smrg WindowPtr ptmp; 2942706f2543Smrg (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin, 2943706f2543Smrg (WindowPtr *)NULL); 2944706f2543Smrg (*pScreen->MarkWindow)(pLayerWin->parent); 2945706f2543Smrg 2946706f2543Smrg /* Windows between pWin and pLayerWin may not have been marked */ 2947706f2543Smrg ptmp = pWin; 2948706f2543Smrg 2949706f2543Smrg while (ptmp != pLayerWin->parent) 2950706f2543Smrg { 2951706f2543Smrg (*pScreen->MarkWindow)(ptmp); 2952706f2543Smrg ptmp = ptmp->parent; 2953706f2543Smrg } 2954706f2543Smrg pHead = pWin->firstChild; 2955706f2543Smrg } 2956706f2543Smrg (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap); 2957706f2543Smrg (*pScreen->HandleExposures)(pLayerWin->parent); 2958706f2543Smrg } 2959706f2543Smrg if (anyMarked && pScreen->PostValidateTree) 2960706f2543Smrg (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap); 2961706f2543Smrg } 2962706f2543Smrg if (wasRealized) 2963706f2543Smrg WindowsRestructured (); 2964706f2543Smrg} 2965706f2543Smrg 2966706f2543Smrg 2967706f2543Smrgvoid 2968706f2543SmrgHandleSaveSet(ClientPtr client) 2969706f2543Smrg{ 2970706f2543Smrg WindowPtr pParent, pWin; 2971706f2543Smrg int j; 2972706f2543Smrg 2973706f2543Smrg for (j=0; j<client->numSaved; j++) 2974706f2543Smrg { 2975706f2543Smrg pWin = SaveSetWindow(client->saveSet[j]); 2976706f2543Smrg#ifdef XFIXES 2977706f2543Smrg if (SaveSetToRoot(client->saveSet[j])) 2978706f2543Smrg pParent = pWin->drawable.pScreen->root; 2979706f2543Smrg else 2980706f2543Smrg#endif 2981706f2543Smrg { 2982706f2543Smrg pParent = pWin->parent; 2983706f2543Smrg while (pParent && (wClient (pParent) == client)) 2984706f2543Smrg pParent = pParent->parent; 2985706f2543Smrg } 2986706f2543Smrg if (pParent) 2987706f2543Smrg { 2988706f2543Smrg if (pParent != pWin->parent) 2989706f2543Smrg { 2990706f2543Smrg#ifdef XFIXES 2991706f2543Smrg /* unmap first so that ReparentWindow doesn't remap */ 2992706f2543Smrg if (!SaveSetShouldMap (client->saveSet[j])) 2993706f2543Smrg UnmapWindow(pWin, FALSE); 2994706f2543Smrg#endif 2995706f2543Smrg ReparentWindow(pWin, pParent, 2996706f2543Smrg pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x, 2997706f2543Smrg pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y, 2998706f2543Smrg client); 2999706f2543Smrg if(!pWin->realized && pWin->mapped) 3000706f2543Smrg pWin->mapped = FALSE; 3001706f2543Smrg } 3002706f2543Smrg#ifdef XFIXES 3003706f2543Smrg if (SaveSetShouldMap (client->saveSet[j])) 3004706f2543Smrg#endif 3005706f2543Smrg MapWindow(pWin, client); 3006706f2543Smrg } 3007706f2543Smrg } 3008706f2543Smrg free(client->saveSet); 3009706f2543Smrg client->numSaved = 0; 3010706f2543Smrg client->saveSet = (SaveSetElt *)NULL; 3011706f2543Smrg} 3012706f2543Smrg 3013706f2543Smrg/** 3014706f2543Smrg * 3015706f2543Smrg * \param x,y in root 3016706f2543Smrg */ 3017706f2543SmrgBool 3018706f2543SmrgPointInWindowIsVisible(WindowPtr pWin, int x, int y) 3019706f2543Smrg{ 3020706f2543Smrg BoxRec box; 3021706f2543Smrg 3022706f2543Smrg if (!pWin->realized) 3023706f2543Smrg return FALSE; 3024706f2543Smrg if (RegionContainsPoint(&pWin->borderClip, 3025706f2543Smrg x, y, &box) 3026706f2543Smrg && (!wInputShape(pWin) || 3027706f2543Smrg RegionContainsPoint(wInputShape(pWin), 3028706f2543Smrg x - pWin->drawable.x, 3029706f2543Smrg y - pWin->drawable.y, &box))) 3030706f2543Smrg return TRUE; 3031706f2543Smrg return FALSE; 3032706f2543Smrg} 3033706f2543Smrg 3034706f2543Smrg 3035706f2543SmrgRegionPtr 3036706f2543SmrgNotClippedByChildren(WindowPtr pWin) 3037706f2543Smrg{ 3038706f2543Smrg RegionPtr pReg = RegionCreate(NullBox, 1); 3039706f2543Smrg if (pWin->parent || 3040706f2543Smrg screenIsSaved != SCREEN_SAVER_ON || 3041706f2543Smrg !HasSaverWindow (pWin->drawable.pScreen)) 3042706f2543Smrg { 3043706f2543Smrg RegionIntersect(pReg, &pWin->borderClip, &pWin->winSize); 3044706f2543Smrg } 3045706f2543Smrg return pReg; 3046706f2543Smrg} 3047706f2543Smrg 3048706f2543Smrgvoid 3049706f2543SmrgSendVisibilityNotify(WindowPtr pWin) 3050706f2543Smrg{ 3051706f2543Smrg xEvent event; 3052706f2543Smrg unsigned int visibility = pWin->visibility; 3053706f2543Smrg 3054706f2543Smrg if (!MapUnmapEventsEnabled(pWin)) 3055706f2543Smrg return; 3056706f2543Smrg#ifdef PANORAMIX 3057706f2543Smrg /* This is not quite correct yet, but it's close */ 3058706f2543Smrg if(!noPanoramiXExtension) { 3059706f2543Smrg PanoramiXRes *win; 3060706f2543Smrg WindowPtr pWin2; 3061706f2543Smrg int rc, i, Scrnum; 3062706f2543Smrg 3063706f2543Smrg Scrnum = pWin->drawable.pScreen->myNum; 3064706f2543Smrg 3065706f2543Smrg win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum); 3066706f2543Smrg 3067706f2543Smrg if(!win || (win->u.win.visibility == visibility)) 3068706f2543Smrg return; 3069706f2543Smrg 3070706f2543Smrg switch(visibility) { 3071706f2543Smrg case VisibilityUnobscured: 3072706f2543Smrg for(i = 0; i < PanoramiXNumScreens; i++) { 3073706f2543Smrg if(i == Scrnum) continue; 3074706f2543Smrg 3075706f2543Smrg rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, 3076706f2543Smrg DixWriteAccess); 3077706f2543Smrg 3078706f2543Smrg if (rc == Success) { 3079706f2543Smrg if(pWin2->visibility == VisibilityPartiallyObscured) 3080706f2543Smrg return; 3081706f2543Smrg 3082706f2543Smrg if(!i) pWin = pWin2; 3083706f2543Smrg } 3084706f2543Smrg } 3085706f2543Smrg break; 3086706f2543Smrg case VisibilityPartiallyObscured: 3087706f2543Smrg if(Scrnum) { 3088706f2543Smrg rc = dixLookupWindow(&pWin2, win->info[0].id, serverClient, 3089706f2543Smrg DixWriteAccess); 3090706f2543Smrg if (rc == Success) pWin = pWin2; 3091706f2543Smrg } 3092706f2543Smrg break; 3093706f2543Smrg case VisibilityFullyObscured: 3094706f2543Smrg for(i = 0; i < PanoramiXNumScreens; i++) { 3095706f2543Smrg if(i == Scrnum) continue; 3096706f2543Smrg 3097706f2543Smrg rc = dixLookupWindow(&pWin2, win->info[i].id, serverClient, 3098706f2543Smrg DixWriteAccess); 3099706f2543Smrg 3100706f2543Smrg if (rc == Success) { 3101706f2543Smrg if(pWin2->visibility != VisibilityFullyObscured) 3102706f2543Smrg return; 3103706f2543Smrg 3104706f2543Smrg if(!i) pWin = pWin2; 3105706f2543Smrg } 3106706f2543Smrg } 3107706f2543Smrg break; 3108706f2543Smrg } 3109706f2543Smrg 3110706f2543Smrg win->u.win.visibility = visibility; 3111706f2543Smrg } 3112706f2543Smrg#endif 3113706f2543Smrg 3114706f2543Smrg memset(&event, 0, sizeof(xEvent)); 3115706f2543Smrg event.u.u.type = VisibilityNotify; 3116706f2543Smrg event.u.visibility.window = pWin->drawable.id; 3117706f2543Smrg event.u.visibility.state = visibility; 3118706f2543Smrg DeliverEvents(pWin, &event, 1, NullWindow); 3119706f2543Smrg} 3120706f2543Smrg 3121706f2543Smrg#define RANDOM_WIDTH 32 3122706f2543Smrgint 3123706f2543SmrgdixSaveScreens(ClientPtr client, int on, int mode) 3124706f2543Smrg{ 3125706f2543Smrg int rc, i, what, type; 3126706f2543Smrg 3127706f2543Smrg if (on == SCREEN_SAVER_FORCER) 3128706f2543Smrg { 3129706f2543Smrg if (mode == ScreenSaverReset) 3130706f2543Smrg what = SCREEN_SAVER_OFF; 3131706f2543Smrg else 3132706f2543Smrg what = SCREEN_SAVER_ON; 3133706f2543Smrg type = what; 3134706f2543Smrg } 3135706f2543Smrg else 3136706f2543Smrg { 3137706f2543Smrg what = on; 3138706f2543Smrg type = what; 3139706f2543Smrg if (what == screenIsSaved) 3140706f2543Smrg type = SCREEN_SAVER_CYCLE; 3141706f2543Smrg } 3142706f2543Smrg 3143706f2543Smrg for (i = 0; i < screenInfo.numScreens; i++) { 3144706f2543Smrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 3145706f2543Smrg DixShowAccess | DixHideAccess); 3146706f2543Smrg if (rc != Success) 3147706f2543Smrg return rc; 3148706f2543Smrg } 3149706f2543Smrg for (i = 0; i < screenInfo.numScreens; i++) 3150706f2543Smrg { 3151706f2543Smrg ScreenPtr pScreen = screenInfo.screens[i]; 3152706f2543Smrg if (on == SCREEN_SAVER_FORCER) 3153706f2543Smrg (* pScreen->SaveScreen) (pScreen, on); 3154706f2543Smrg if (pScreen->screensaver.ExternalScreenSaver) 3155706f2543Smrg { 3156706f2543Smrg if ((*pScreen->screensaver.ExternalScreenSaver) 3157706f2543Smrg (pScreen, type, on == SCREEN_SAVER_FORCER)) 3158706f2543Smrg continue; 3159706f2543Smrg } 3160706f2543Smrg if (type == screenIsSaved) 3161706f2543Smrg continue; 3162706f2543Smrg switch (type) { 3163706f2543Smrg case SCREEN_SAVER_OFF: 3164706f2543Smrg if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED) 3165706f2543Smrg { 3166706f2543Smrg (* pScreen->SaveScreen) (pScreen, what); 3167706f2543Smrg } 3168706f2543Smrg else if (HasSaverWindow (pScreen)) 3169706f2543Smrg { 3170706f2543Smrg pScreen->screensaver.pWindow = NullWindow; 3171706f2543Smrg FreeResource(pScreen->screensaver.wid, RT_NONE); 3172706f2543Smrg } 3173706f2543Smrg break; 3174706f2543Smrg case SCREEN_SAVER_CYCLE: 3175706f2543Smrg if (pScreen->screensaver.blanked == SCREEN_IS_TILED) 3176706f2543Smrg { 3177706f2543Smrg WindowPtr pWin = pScreen->screensaver.pWindow; 3178706f2543Smrg /* make it look like screen saver is off, so that 3179706f2543Smrg * NotClippedByChildren will compute a clip list 3180706f2543Smrg * for the root window, so miPaintWindow works 3181706f2543Smrg */ 3182706f2543Smrg screenIsSaved = SCREEN_SAVER_OFF; 3183706f2543Smrg (*pWin->drawable.pScreen->MoveWindow)(pWin, 3184706f2543Smrg (short)(-(rand() % RANDOM_WIDTH)), 3185706f2543Smrg (short)(-(rand() % RANDOM_WIDTH)), 3186706f2543Smrg pWin->nextSib, VTMove); 3187706f2543Smrg screenIsSaved = SCREEN_SAVER_ON; 3188706f2543Smrg } 3189706f2543Smrg /* 3190706f2543Smrg * Call the DDX saver in case it wants to do something 3191706f2543Smrg * at cycle time 3192706f2543Smrg */ 3193706f2543Smrg else if (pScreen->screensaver.blanked == SCREEN_IS_BLANKED) 3194706f2543Smrg { 3195706f2543Smrg (* pScreen->SaveScreen) (pScreen, type); 3196706f2543Smrg } 3197706f2543Smrg break; 3198706f2543Smrg case SCREEN_SAVER_ON: 3199706f2543Smrg if (ScreenSaverBlanking != DontPreferBlanking) 3200706f2543Smrg { 3201706f2543Smrg if ((* pScreen->SaveScreen) (pScreen, what)) 3202706f2543Smrg { 3203706f2543Smrg pScreen->screensaver.blanked = SCREEN_IS_BLANKED; 3204706f2543Smrg continue; 3205706f2543Smrg } 3206706f2543Smrg if ((ScreenSaverAllowExposures != DontAllowExposures) && 3207706f2543Smrg TileScreenSaver(pScreen, SCREEN_IS_BLACK)) 3208706f2543Smrg { 3209706f2543Smrg pScreen->screensaver.blanked = SCREEN_IS_BLACK; 3210706f2543Smrg continue; 3211706f2543Smrg } 3212706f2543Smrg } 3213706f2543Smrg if ((ScreenSaverAllowExposures != DontAllowExposures) && 3214706f2543Smrg TileScreenSaver(pScreen, SCREEN_IS_TILED)) 3215706f2543Smrg { 3216706f2543Smrg pScreen->screensaver.blanked = SCREEN_IS_TILED; 3217706f2543Smrg } 3218706f2543Smrg else 3219706f2543Smrg pScreen->screensaver.blanked = SCREEN_ISNT_SAVED; 3220706f2543Smrg break; 3221706f2543Smrg } 3222706f2543Smrg } 3223706f2543Smrg screenIsSaved = what; 3224706f2543Smrg if (mode == ScreenSaverReset) { 3225706f2543Smrg if (on == SCREEN_SAVER_FORCER) { 3226706f2543Smrg UpdateCurrentTimeIf(); 3227706f2543Smrg lastDeviceEventTime = currentTime; 3228706f2543Smrg } 3229706f2543Smrg SetScreenSaverTimer(); 3230706f2543Smrg } 3231706f2543Smrg return Success; 3232706f2543Smrg} 3233706f2543Smrg 3234706f2543Smrgint 3235706f2543SmrgSaveScreens(int on, int mode) 3236706f2543Smrg{ 3237706f2543Smrg return dixSaveScreens(serverClient, on, mode); 3238706f2543Smrg} 3239706f2543Smrg 3240706f2543Smrgstatic Bool 3241706f2543SmrgTileScreenSaver(ScreenPtr pScreen, int kind) 3242706f2543Smrg{ 3243706f2543Smrg int j; 3244706f2543Smrg int result; 3245706f2543Smrg XID attributes[3]; 3246706f2543Smrg Mask mask; 3247706f2543Smrg WindowPtr pWin; 3248706f2543Smrg CursorMetricRec cm; 3249706f2543Smrg unsigned char *srcbits, *mskbits; 3250706f2543Smrg CursorPtr cursor; 3251706f2543Smrg XID cursorID = 0; 3252706f2543Smrg int attri; 3253706f2543Smrg 3254706f2543Smrg mask = 0; 3255706f2543Smrg attri = 0; 3256706f2543Smrg switch (kind) { 3257706f2543Smrg case SCREEN_IS_TILED: 3258706f2543Smrg switch (pScreen->root->backgroundState) { 3259706f2543Smrg case BackgroundPixel: 3260706f2543Smrg attributes[attri++] = pScreen->root->background.pixel; 3261706f2543Smrg mask |= CWBackPixel; 3262706f2543Smrg break; 3263706f2543Smrg case BackgroundPixmap: 3264706f2543Smrg attributes[attri++] = None; 3265706f2543Smrg mask |= CWBackPixmap; 3266706f2543Smrg break; 3267706f2543Smrg default: 3268706f2543Smrg break; 3269706f2543Smrg } 3270706f2543Smrg break; 3271706f2543Smrg case SCREEN_IS_BLACK: 3272706f2543Smrg attributes[attri++] = pScreen->root->drawable.pScreen->blackPixel; 3273706f2543Smrg mask |= CWBackPixel; 3274706f2543Smrg break; 3275706f2543Smrg } 3276706f2543Smrg mask |= CWOverrideRedirect; 3277706f2543Smrg attributes[attri++] = xTrue; 3278706f2543Smrg 3279706f2543Smrg /* 3280706f2543Smrg * create a blank cursor 3281706f2543Smrg */ 3282706f2543Smrg 3283706f2543Smrg cm.width=16; 3284706f2543Smrg cm.height=16; 3285706f2543Smrg cm.xhot=8; 3286706f2543Smrg cm.yhot=8; 3287706f2543Smrg srcbits = malloc( BitmapBytePad(32)*16); 3288706f2543Smrg mskbits = malloc( BitmapBytePad(32)*16); 3289706f2543Smrg if (!srcbits || !mskbits) 3290706f2543Smrg { 3291706f2543Smrg free(srcbits); 3292706f2543Smrg free(mskbits); 3293706f2543Smrg cursor = 0; 3294706f2543Smrg } 3295706f2543Smrg else 3296706f2543Smrg { 3297706f2543Smrg for (j=0; j<BitmapBytePad(32)*16; j++) 3298706f2543Smrg srcbits[j] = mskbits[j] = 0x0; 3299706f2543Smrg result = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 0, 0, 0, 0, 0, 0, 3300706f2543Smrg &cursor, serverClient, (XID)0); 3301706f2543Smrg if (cursor) 3302706f2543Smrg { 3303706f2543Smrg cursorID = FakeClientID(0); 3304706f2543Smrg if (AddResource (cursorID, RT_CURSOR, (pointer) cursor)) 3305706f2543Smrg { 3306706f2543Smrg attributes[attri] = cursorID; 3307706f2543Smrg mask |= CWCursor; 3308706f2543Smrg } 3309706f2543Smrg else 3310706f2543Smrg cursor = 0; 3311706f2543Smrg } 3312706f2543Smrg else 3313706f2543Smrg { 3314706f2543Smrg free(srcbits); 3315706f2543Smrg free(mskbits); 3316706f2543Smrg } 3317706f2543Smrg } 3318706f2543Smrg 3319706f2543Smrg pWin = pScreen->screensaver.pWindow = 3320706f2543Smrg CreateWindow(pScreen->screensaver.wid, 3321706f2543Smrg pScreen->root, 3322706f2543Smrg -RANDOM_WIDTH, -RANDOM_WIDTH, 3323706f2543Smrg (unsigned short)pScreen->width + RANDOM_WIDTH, 3324706f2543Smrg (unsigned short)pScreen->height + RANDOM_WIDTH, 3325706f2543Smrg 0, InputOutput, mask, attributes, 0, serverClient, 3326706f2543Smrg wVisual (pScreen->root), &result); 3327706f2543Smrg 3328706f2543Smrg if (cursor) 3329706f2543Smrg FreeResource (cursorID, RT_NONE); 3330706f2543Smrg 3331706f2543Smrg if (!pWin) 3332706f2543Smrg return FALSE; 3333706f2543Smrg 3334706f2543Smrg if (!AddResource(pWin->drawable.id, RT_WINDOW, 3335706f2543Smrg (pointer)pScreen->screensaver.pWindow)) 3336706f2543Smrg return FALSE; 3337706f2543Smrg 3338706f2543Smrg if (mask & CWBackPixmap) 3339706f2543Smrg { 3340706f2543Smrg MakeRootTile (pWin); 3341706f2543Smrg (*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap); 3342706f2543Smrg } 3343706f2543Smrg MapWindow(pWin, serverClient); 3344706f2543Smrg return TRUE; 3345706f2543Smrg} 3346706f2543Smrg 3347706f2543Smrg/* 3348706f2543Smrg * FindWindowWithOptional 3349706f2543Smrg * 3350706f2543Smrg * search ancestors of the given window for an entry containing 3351706f2543Smrg * a WindowOpt structure. Assumptions: some parent will 3352706f2543Smrg * contain the structure. 3353706f2543Smrg */ 3354706f2543Smrg 3355706f2543SmrgWindowPtr 3356706f2543SmrgFindWindowWithOptional (WindowPtr w) 3357706f2543Smrg{ 3358706f2543Smrg do 3359706f2543Smrg w = w->parent; 3360706f2543Smrg while (!w->optional); 3361706f2543Smrg return w; 3362706f2543Smrg} 3363706f2543Smrg 3364706f2543Smrg/* 3365706f2543Smrg * CheckWindowOptionalNeed 3366706f2543Smrg * 3367706f2543Smrg * check each optional entry in the given window to see if 3368706f2543Smrg * the value is satisfied by the default rules. If so, 3369706f2543Smrg * release the optional record 3370706f2543Smrg */ 3371706f2543Smrg 3372706f2543Smrgvoid 3373706f2543SmrgCheckWindowOptionalNeed (WindowPtr w) 3374706f2543Smrg{ 3375706f2543Smrg WindowOptPtr optional; 3376706f2543Smrg WindowOptPtr parentOptional; 3377706f2543Smrg 3378706f2543Smrg if (!w->parent || !w->optional) 3379706f2543Smrg return; 3380706f2543Smrg optional = w->optional; 3381706f2543Smrg if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate]) 3382706f2543Smrg return; 3383706f2543Smrg if (optional->otherEventMasks != 0) 3384706f2543Smrg return; 3385706f2543Smrg if (optional->otherClients != NULL) 3386706f2543Smrg return; 3387706f2543Smrg if (optional->passiveGrabs != NULL) 3388706f2543Smrg return; 3389706f2543Smrg if (optional->userProps != NULL) 3390706f2543Smrg return; 3391706f2543Smrg if (optional->backingBitPlanes != ~0L) 3392706f2543Smrg return; 3393706f2543Smrg if (optional->backingPixel != 0) 3394706f2543Smrg return; 3395706f2543Smrg if (optional->boundingShape != NULL) 3396706f2543Smrg return; 3397706f2543Smrg if (optional->clipShape != NULL) 3398706f2543Smrg return; 3399706f2543Smrg if (optional->inputShape != NULL) 3400706f2543Smrg return; 3401706f2543Smrg if (optional->inputMasks != NULL) 3402706f2543Smrg return; 3403706f2543Smrg if (optional->deviceCursors != NULL) 3404706f2543Smrg { 3405706f2543Smrg DevCursNodePtr pNode = optional->deviceCursors; 3406706f2543Smrg while(pNode) 3407706f2543Smrg { 3408706f2543Smrg if (pNode->cursor != None) 3409706f2543Smrg return; 3410706f2543Smrg pNode = pNode->next; 3411706f2543Smrg } 3412706f2543Smrg } 3413706f2543Smrg 3414706f2543Smrg parentOptional = FindWindowWithOptional(w)->optional; 3415706f2543Smrg if (optional->visual != parentOptional->visual) 3416706f2543Smrg return; 3417706f2543Smrg if (optional->cursor != None && 3418706f2543Smrg (optional->cursor != parentOptional->cursor || 3419706f2543Smrg w->parent->cursorIsNone)) 3420706f2543Smrg return; 3421706f2543Smrg if (optional->colormap != parentOptional->colormap) 3422706f2543Smrg return; 3423706f2543Smrg DisposeWindowOptional (w); 3424706f2543Smrg} 3425706f2543Smrg 3426706f2543Smrg/* 3427706f2543Smrg * MakeWindowOptional 3428706f2543Smrg * 3429706f2543Smrg * create an optional record and initialize it with the default 3430706f2543Smrg * values. 3431706f2543Smrg */ 3432706f2543Smrg 3433706f2543SmrgBool 3434706f2543SmrgMakeWindowOptional (WindowPtr pWin) 3435706f2543Smrg{ 3436706f2543Smrg WindowOptPtr optional; 3437706f2543Smrg WindowOptPtr parentOptional; 3438706f2543Smrg 3439706f2543Smrg if (pWin->optional) 3440706f2543Smrg return TRUE; 3441706f2543Smrg optional = malloc(sizeof (WindowOptRec)); 3442706f2543Smrg if (!optional) 3443706f2543Smrg return FALSE; 3444706f2543Smrg optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate]; 3445706f2543Smrg optional->otherEventMasks = 0; 3446706f2543Smrg optional->otherClients = NULL; 3447706f2543Smrg optional->passiveGrabs = NULL; 3448706f2543Smrg optional->userProps = NULL; 3449706f2543Smrg optional->backingBitPlanes = ~0L; 3450706f2543Smrg optional->backingPixel = 0; 3451706f2543Smrg optional->boundingShape = NULL; 3452706f2543Smrg optional->clipShape = NULL; 3453706f2543Smrg optional->inputShape = NULL; 3454706f2543Smrg optional->inputMasks = NULL; 3455706f2543Smrg optional->deviceCursors = NULL; 3456706f2543Smrg 3457706f2543Smrg parentOptional = FindWindowWithOptional(pWin)->optional; 3458706f2543Smrg optional->visual = parentOptional->visual; 3459706f2543Smrg if (!pWin->cursorIsNone) 3460706f2543Smrg { 3461706f2543Smrg optional->cursor = parentOptional->cursor; 3462706f2543Smrg optional->cursor->refcnt++; 3463706f2543Smrg } 3464706f2543Smrg else 3465706f2543Smrg { 3466706f2543Smrg optional->cursor = None; 3467706f2543Smrg } 3468706f2543Smrg optional->colormap = parentOptional->colormap; 3469706f2543Smrg pWin->optional = optional; 3470706f2543Smrg return TRUE; 3471706f2543Smrg} 3472706f2543Smrg 3473706f2543Smrg/* 3474706f2543Smrg * Changes the cursor struct for the given device and the given window. 3475706f2543Smrg * A cursor that does not have a device cursor set will use whatever the 3476706f2543Smrg * standard cursor is for the window. If all devices have a cursor set, 3477706f2543Smrg * changing the window cursor (e.g. using XDefineCursor()) will not have any 3478706f2543Smrg * visible effect. Only when one of the device cursors is set to None again, 3479706f2543Smrg * this device's cursor will display the changed standard cursor. 3480706f2543Smrg * 3481706f2543Smrg * CursorIsNone of the window struct is NOT modified if you set a device 3482706f2543Smrg * cursor. 3483706f2543Smrg * 3484706f2543Smrg * Assumption: If there is a node for a device in the list, the device has a 3485706f2543Smrg * cursor. If the cursor is set to None, it is inherited by the parent. 3486706f2543Smrg */ 3487706f2543Smrgint 3488706f2543SmrgChangeWindowDeviceCursor(WindowPtr pWin, 3489706f2543Smrg DeviceIntPtr pDev, 3490706f2543Smrg CursorPtr pCursor) 3491706f2543Smrg{ 3492706f2543Smrg DevCursNodePtr pNode, pPrev; 3493706f2543Smrg CursorPtr pOldCursor = NULL; 3494706f2543Smrg ScreenPtr pScreen; 3495706f2543Smrg WindowPtr pChild; 3496706f2543Smrg 3497706f2543Smrg if (!pWin->optional && !MakeWindowOptional(pWin)) 3498706f2543Smrg return BadAlloc; 3499706f2543Smrg 3500706f2543Smrg /* 1) Check if window has device cursor set 3501706f2543Smrg * Yes: 1.1) swap cursor with given cursor if parent does not have same 3502706f2543Smrg * cursor, free old cursor 3503706f2543Smrg * 1.2) free old cursor, use parent cursor 3504706f2543Smrg * No: 1.1) add node to beginning of list. 3505706f2543Smrg * 1.2) add cursor to node if parent does not have same cursor 3506706f2543Smrg * 1.3) use parent cursor if parent does not have same cursor 3507706f2543Smrg * 2) Patch up children if child has a devcursor 3508706f2543Smrg * 2.1) if child has cursor None, it inherited from parent, set to old 3509706f2543Smrg * cursor 3510706f2543Smrg * 2.2) if child has same cursor as new cursor, remove and set to None 3511706f2543Smrg */ 3512706f2543Smrg 3513706f2543Smrg pScreen = pWin->drawable.pScreen; 3514706f2543Smrg 3515706f2543Smrg if (WindowSeekDeviceCursor(pWin, pDev, &pNode, &pPrev)) 3516706f2543Smrg { 3517706f2543Smrg /* has device cursor */ 3518706f2543Smrg 3519706f2543Smrg if (pNode->cursor == pCursor) 3520706f2543Smrg return Success; 3521706f2543Smrg 3522706f2543Smrg pOldCursor = pNode->cursor; 3523706f2543Smrg 3524706f2543Smrg if (!pCursor) /* remove from list */ 3525706f2543Smrg { 3526706f2543Smrg if(pPrev) 3527706f2543Smrg pPrev->next = pNode->next; 3528706f2543Smrg else 3529706f2543Smrg /* first item in list */ 3530706f2543Smrg pWin->optional->deviceCursors = pNode->next; 3531706f2543Smrg 3532706f2543Smrg free(pNode); 3533706f2543Smrg goto out; 3534706f2543Smrg } 3535706f2543Smrg 3536706f2543Smrg } else 3537706f2543Smrg { 3538706f2543Smrg /* no device cursor yet */ 3539706f2543Smrg DevCursNodePtr pNewNode; 3540706f2543Smrg 3541706f2543Smrg if (!pCursor) 3542706f2543Smrg return Success; 3543706f2543Smrg 3544706f2543Smrg pNewNode = malloc(sizeof(DevCursNodeRec)); 3545706f2543Smrg pNewNode->dev = pDev; 3546706f2543Smrg pNewNode->next = pWin->optional->deviceCursors; 3547706f2543Smrg pWin->optional->deviceCursors = pNewNode; 3548706f2543Smrg pNode = pNewNode; 3549706f2543Smrg 3550706f2543Smrg } 3551706f2543Smrg 3552706f2543Smrg if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor)) 3553706f2543Smrg pNode->cursor = None; 3554706f2543Smrg else 3555706f2543Smrg { 3556706f2543Smrg pNode->cursor = pCursor; 3557706f2543Smrg pCursor->refcnt++; 3558706f2543Smrg } 3559706f2543Smrg 3560706f2543Smrg pNode = pPrev = NULL; 3561706f2543Smrg /* fix up children */ 3562706f2543Smrg for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) 3563706f2543Smrg { 3564706f2543Smrg if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) 3565706f2543Smrg { 3566706f2543Smrg if (pNode->cursor == None) /* inherited from parent */ 3567706f2543Smrg { 3568706f2543Smrg pNode->cursor = pOldCursor; 3569706f2543Smrg pOldCursor->refcnt++; 3570706f2543Smrg } else if (pNode->cursor == pCursor) 3571706f2543Smrg { 3572706f2543Smrg pNode->cursor = None; 3573706f2543Smrg FreeCursor(pCursor, (Cursor)0); /* fix up refcnt */ 3574706f2543Smrg } 3575706f2543Smrg } 3576706f2543Smrg } 3577706f2543Smrg 3578706f2543Smrgout: 3579706f2543Smrg if (pWin->realized) 3580706f2543Smrg WindowHasNewCursor(pWin); 3581706f2543Smrg 3582706f2543Smrg if (pOldCursor) 3583706f2543Smrg FreeCursor(pOldCursor, (Cursor)0); 3584706f2543Smrg 3585706f2543Smrg /* FIXME: We SHOULD check for an error value here XXX 3586706f2543Smrg (comment taken from ChangeWindowAttributes) */ 3587706f2543Smrg (*pScreen->ChangeWindowAttributes)(pWin, CWCursor); 3588706f2543Smrg 3589706f2543Smrg return Success; 3590706f2543Smrg} 3591706f2543Smrg 3592706f2543Smrg/* Get device cursor for given device or None if none is set */ 3593706f2543SmrgCursorPtr 3594706f2543SmrgWindowGetDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev) 3595706f2543Smrg{ 3596706f2543Smrg DevCursorList pList; 3597706f2543Smrg 3598706f2543Smrg if (!pWin->optional || !pWin->optional->deviceCursors) 3599706f2543Smrg return NULL; 3600706f2543Smrg 3601706f2543Smrg pList = pWin->optional->deviceCursors; 3602706f2543Smrg 3603706f2543Smrg while(pList) 3604706f2543Smrg { 3605706f2543Smrg if (pList->dev == pDev) 3606706f2543Smrg { 3607706f2543Smrg if (pList->cursor == None) /* inherited from parent */ 3608706f2543Smrg return WindowGetDeviceCursor(pWin->parent, pDev); 3609706f2543Smrg else 3610706f2543Smrg return pList->cursor; 3611706f2543Smrg } 3612706f2543Smrg pList = pList->next; 3613706f2543Smrg } 3614706f2543Smrg return NULL; 3615706f2543Smrg} 3616706f2543Smrg 3617706f2543Smrg/* Searches for a DevCursorNode for the given window and device. If one is 3618706f2543Smrg * found, return True and set pNode and pPrev to the node and to the node 3619706f2543Smrg * before the node respectively. Otherwise return False. 3620706f2543Smrg * If the device is the first in list, pPrev is set to NULL. 3621706f2543Smrg */ 3622706f2543Smrgstatic Bool 3623706f2543SmrgWindowSeekDeviceCursor(WindowPtr pWin, 3624706f2543Smrg DeviceIntPtr pDev, 3625706f2543Smrg DevCursNodePtr* pNode, 3626706f2543Smrg DevCursNodePtr* pPrev) 3627706f2543Smrg{ 3628706f2543Smrg DevCursorList pList; 3629706f2543Smrg 3630706f2543Smrg if (!pWin->optional) 3631706f2543Smrg return FALSE; 3632706f2543Smrg 3633706f2543Smrg pList = pWin->optional->deviceCursors; 3634706f2543Smrg 3635706f2543Smrg if (pList && pList->dev == pDev) 3636706f2543Smrg { 3637706f2543Smrg *pNode = pList; 3638706f2543Smrg *pPrev = NULL; 3639706f2543Smrg return TRUE; 3640706f2543Smrg } 3641706f2543Smrg 3642706f2543Smrg while(pList) 3643706f2543Smrg { 3644706f2543Smrg if (pList->next) 3645706f2543Smrg { 3646706f2543Smrg if (pList->next->dev == pDev) 3647706f2543Smrg { 3648706f2543Smrg *pNode = pList->next; 3649706f2543Smrg *pPrev = pList; 3650706f2543Smrg return TRUE; 3651706f2543Smrg } 3652706f2543Smrg } 3653706f2543Smrg pList = pList->next; 3654706f2543Smrg } 3655706f2543Smrg return FALSE; 3656706f2543Smrg} 3657706f2543Smrg 3658706f2543Smrg/* Return True if a parent has the same device cursor set or False if 3659706f2543Smrg * otherwise 3660706f2543Smrg */ 3661706f2543Smrgstatic Bool 3662706f2543SmrgWindowParentHasDeviceCursor(WindowPtr pWin, 3663706f2543Smrg DeviceIntPtr pDev, 3664706f2543Smrg CursorPtr pCursor) 3665706f2543Smrg{ 3666706f2543Smrg WindowPtr pParent; 3667706f2543Smrg DevCursNodePtr pParentNode, pParentPrev; 3668706f2543Smrg 3669706f2543Smrg pParent = pWin->parent; 3670706f2543Smrg while(pParent) 3671706f2543Smrg { 3672706f2543Smrg if (WindowSeekDeviceCursor(pParent, pDev, 3673706f2543Smrg &pParentNode, &pParentPrev)) 3674706f2543Smrg { 3675706f2543Smrg /* if there is a node in the list, the win has a dev cursor */ 3676706f2543Smrg if (!pParentNode->cursor) /* inherited. */ 3677706f2543Smrg pParent = pParent->parent; 3678706f2543Smrg else if (pParentNode->cursor == pCursor) /* inherit */ 3679706f2543Smrg return TRUE; 3680706f2543Smrg else /* different cursor */ 3681706f2543Smrg return FALSE; 3682706f2543Smrg } 3683706f2543Smrg else 3684706f2543Smrg /* parent does not have a device cursor for our device */ 3685706f2543Smrg return FALSE; 3686706f2543Smrg } 3687706f2543Smrg return FALSE; 3688706f2543Smrg} 3689