|
|
1.1 ! root 1: /*********************************************************** ! 2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, ! 3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts. ! 4: ! 5: All Rights Reserved ! 6: ! 7: Permission to use, copy, modify, and distribute this software and its ! 8: documentation for any purpose and without fee is hereby granted, ! 9: provided that the above copyright notice appear in all copies and that ! 10: both that copyright notice and this permission notice appear in ! 11: supporting documentation, and that the names of Digital or MIT not be ! 12: used in advertising or publicity pertaining to distribution of the ! 13: software without specific, written prior permission. ! 14: ! 15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 21: SOFTWARE. ! 22: ! 23: ******************************************************************/ ! 24: ! 25: /* $Header: window.c,v 1.170 87/09/07 18:56:00 rws Exp $ */ ! 26: ! 27: #include "X.h" ! 28: #define NEED_REPLIES ! 29: #define NEED_EVENTS ! 30: #include "Xproto.h" ! 31: #include "misc.h" ! 32: #include "scrnintstr.h" ! 33: #include "os.h" ! 34: #include "regionstr.h" ! 35: #include "windowstr.h" ! 36: #include "input.h" ! 37: #include "resource.h" ! 38: #include "colormapst.h" ! 39: #include "cursorstr.h" ! 40: #include "dixstruct.h" ! 41: #include "gcstruct.h" ! 42: #include "servermd.h" ! 43: ! 44: /****** ! 45: * Window stuff for server ! 46: * ! 47: * CreateRootWindow, CreateWindow, ChangeWindowAttributes, ! 48: * GetWindowAttributes, DeleteWindow, DestroySubWindows, ! 49: * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows, ! 50: * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow, ! 51: * ! 52: ******/ ! 53: ! 54: static long _back[16] = {0x88888888, 0x22222222, 0x44444444, 0x11111111, ! 55: 0x88888888, 0x22222222, 0x44444444, 0x11111111, ! 56: 0x88888888, 0x22222222, 0x44444444, 0x11111111, ! 57: 0x88888888, 0x22222222, 0x44444444, 0x11111111}; ! 58: ! 59: typedef struct _ScreenSaverStuff { ! 60: WindowPtr pWindow; ! 61: XID wid; ! 62: XID cid; ! 63: BYTE blanked; ! 64: } ScreenSaverStuffRec; ! 65: ! 66: #define SCREEN_IS_BLANKED 0 ! 67: #define SCREEN_IS_TILED 1 ! 68: #define SCREEN_ISNT_SAVED 2 ! 69: ! 70: #define DONT_USE_GRAVITY 0 ! 71: #define USE_GRAVITY 1 ! 72: ! 73: extern int ScreenSaverBlanking, ScreenSaverAllowExposures; ! 74: int screenIsSaved = FALSE; ! 75: ! 76: static ScreenSaverStuffRec savedScreenInfo[MAXSCREENS]; ! 77: ! 78: extern WindowRec WindowTable[]; ! 79: extern void (* ReplySwapVector[256]) (); ! 80: ! 81: static void ResizeChildrenWinSize(); ! 82: ! 83: #define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \ ! 84: CWDontPropagate | CWOverrideRedirect | CWCursor ) ! 85: ! 86: /****** ! 87: * PrintWindowTree ! 88: * For debugging only ! 89: ******/ ! 90: ! 91: int ! 92: PrintChildren(p1, indent) ! 93: WindowPtr p1; ! 94: int indent; ! 95: { ! 96: WindowPtr p2; ! 97: int i; ! 98: ! 99: while (p1) ! 100: { ! 101: p2 = p1->firstChild; ! 102: for (i=0; i<indent; i++) ErrorF( " "); ! 103: ErrorF( "%x\n", p1->wid); ! 104: miprintRects(p1->clipList); ! 105: PrintChildren(p2, indent+4); ! 106: p1 = p1->nextSib; ! 107: } ! 108: } ! 109: ! 110: PrintWindowTree() ! 111: { ! 112: int i; ! 113: WindowPtr pWin, p1; ! 114: ! 115: for (i=0; i<screenInfo.numScreens; i++) ! 116: { ! 117: ErrorF( "WINDOW %d\n", i); ! 118: pWin = &WindowTable[i]; ! 119: miprintRects(pWin->clipList); ! 120: p1 = pWin->firstChild; ! 121: PrintChildren(p1, 4); ! 122: } ! 123: } ! 124: ! 125: ! 126: /***** ! 127: * WalkTree ! 128: * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on ! 129: * each window. If FUNC returns WT_WALKCHILDREN, traverse the children, ! 130: * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING ! 131: * exit WalkTree. Does depth-first traverse. ! 132: *****/ ! 133: ! 134: int ! 135: TraverseTree(pWin, func, data) ! 136: WindowPtr pWin; ! 137: int (*func)(); ! 138: pointer data; ! 139: { ! 140: int result; ! 141: WindowPtr pChild; ! 142: ! 143: if (pWin == 0) ! 144: return(WT_NOMATCH); ! 145: result = (* func)(pWin, data); ! 146: ! 147: if (result == WT_STOPWALKING) ! 148: return(WT_STOPWALKING); ! 149: ! 150: if (result == WT_WALKCHILDREN) ! 151: for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) ! 152: if (TraverseTree(pChild, func,data) == WT_STOPWALKING) ! 153: return(WT_STOPWALKING); ! 154: ! 155: return(WT_NOMATCH); ! 156: } ! 157: ! 158: int ! 159: WalkTree(pScreen, func, data) ! 160: ScreenPtr pScreen; ! 161: int (* func)(); ! 162: char *data; ! 163: { ! 164: WindowPtr pWin; ! 165: ! 166: pWin = &WindowTable[pScreen->myNum]; ! 167: return(TraverseTree(pWin, func, data)); ! 168: } ! 169: ! 170: /***** ! 171: * DoObscures(pWin) ! 172: * ! 173: *****/ ! 174: ! 175: static void ! 176: DoObscures(pWin) ! 177: WindowPtr pWin; ! 178: { ! 179: WindowPtr pSib; ! 180: ! 181: if (pWin->backStorage == 0 || (pWin->backingStore == NotUseful)) ! 182: return ; ! 183: if ((* pWin->drawable.pScreen->RegionNotEmpty)(pWin->backStorage->obscured)) ! 184: { ! 185: (*pWin->backStorage->SaveDoomedAreas)( pWin ); ! 186: (* pWin->drawable.pScreen->RegionEmpty)(pWin->backStorage->obscured); ! 187: } ! 188: pSib = pWin->firstChild; ! 189: while (pSib) ! 190: { ! 191: DoObscures(pSib); ! 192: pSib = pSib->nextSib; ! 193: } ! 194: } ! 195: ! 196: /***** ! 197: * HandleExposures(pWin) ! 198: * starting at pWin, draw background in any windows that have exposure ! 199: * regions, translate the regions, restore any backing store, ! 200: * and then send any regions stille xposed to the client ! 201: *****/ ! 202: ! 203: /* NOTE ! 204: the order of painting and restoration needs to be different, ! 205: to avoid an extra repaint of the background. --rgd ! 206: */ ! 207: ! 208: void ! 209: HandleExposures(pWin) ! 210: WindowPtr pWin; ! 211: { ! 212: WindowPtr pSib; ! 213: ! 214: if ((* pWin->drawable.pScreen->RegionNotEmpty)(pWin->borderExposed)) ! 215: { ! 216: (*pWin->PaintWindowBorder)(pWin, pWin->borderExposed, PW_BORDER); ! 217: (* pWin->drawable.pScreen->RegionEmpty)(pWin->borderExposed); ! 218: } ! 219: (* pWin->drawable.pScreen->WindowExposures)(pWin); ! 220: pSib = pWin->firstChild; ! 221: while (pSib) ! 222: { ! 223: HandleExposures(pSib); ! 224: pSib = pSib->nextSib; ! 225: } ! 226: } ! 227: ! 228: extern int NotImplemented(); ! 229: ! 230: static void ! 231: InitProcedures(pWin) ! 232: WindowPtr pWin; ! 233: { ! 234: #ifdef DEBUG ! 235: void (**j) (); ! 236: for (j = &pWin->PaintWindowBackground; ! 237: j < &pWin->ClearToBackground; j++ ) ! 238: *j = (void (*) ())NotImplemented; ! 239: #endif /* DEBUG */ ! 240: ! 241: } ! 242: ! 243: static void ! 244: SetWindowToDefaults(pWin, pScreen) ! 245: WindowPtr pWin; ! 246: ScreenPtr pScreen; ! 247: { ! 248: pWin->prevSib = NullWindow; ! 249: pWin->firstChild = NullWindow; ! 250: pWin->lastChild = NullWindow; ! 251: ! 252: pWin->userProps = (PropertyPtr)NULL; ! 253: ! 254: pWin->backingStore = NotUseful; ! 255: pWin->backStorage = (BackingStorePtr) NULL; ! 256: ! 257: pWin->mapped = 0; /* off */ ! 258: pWin->realized = 0; /* off */ ! 259: pWin->viewable = 0; ! 260: pWin->overrideRedirect = FALSE; ! 261: pWin->saveUnder = FALSE; ! 262: ! 263: pWin->bitGravity = ForgetGravity; ! 264: pWin->winGravity = NorthWestGravity; ! 265: pWin->backingBitPlanes = -1; ! 266: pWin->backingPixel = 0; ! 267: ! 268: pWin->eventMask = 0; ! 269: pWin->dontPropagateMask = 0; ! 270: pWin->allEventMasks = 0; ! 271: pWin->deliverableEvents = 0; ! 272: ! 273: pWin->otherClients = (pointer)NULL; ! 274: pWin->passiveGrabs = (pointer)NULL; ! 275: pWin->colormap = (Colormap)CopyFromParent; ! 276: ! 277: pWin->exposed = (* pScreen->RegionCreate)(NULL, 1); ! 278: pWin->borderExposed = (* pScreen->RegionCreate)(NULL, 1); ! 279: ! 280: } ! 281: ! 282: static void ! 283: MakeRootCursor(pWin) ! 284: WindowPtr pWin; ! 285: { ! 286: unsigned char *srcbits, *mskbits; ! 287: int i; ! 288: if (rootCursor) ! 289: { ! 290: pWin->cursor = rootCursor; ! 291: rootCursor->refcnt++; ! 292: } ! 293: else ! 294: { ! 295: CursorMetricRec cm; ! 296: cm.width=32; ! 297: cm.height=16; ! 298: cm.xhot=8; ! 299: cm.yhot=8; ! 300: ! 301: srcbits = (unsigned char *)Xalloc( PixmapBytePad(32, 1)*16); ! 302: mskbits = (unsigned char *)Xalloc( PixmapBytePad(32, 1)*16); ! 303: for (i=0; i<PixmapBytePad(32, 1)*16; i++) ! 304: { ! 305: srcbits[i] = mskbits[i] = 0xff; ! 306: } ! 307: pWin->cursor = AllocCursor( srcbits, mskbits, &cm, ! 308: ~0, ~0, ~0, 0, 0, 0); ! 309: } ! 310: } ! 311: ! 312: static void ! 313: MakeRootTile(pWin) ! 314: WindowPtr pWin; ! 315: { ! 316: ScreenPtr pScreen = pWin->drawable.pScreen; ! 317: GCPtr pGC; ! 318: ! 319: pWin->backgroundTile = (*pScreen->CreatePixmap)(pScreen, 16, 16, ! 320: pScreen->rootDepth); ! 321: ! 322: pGC = GetScratchGC(pScreen->rootDepth, pScreen); ! 323: ! 324: { ! 325: CARD32 attributes[3]; ! 326: ! 327: attributes[0] = pScreen->whitePixel; ! 328: attributes[1] = pScreen->blackPixel; ! 329: attributes[2] = FALSE; ! 330: ! 331: ChangeGC(pGC, GCForeground | GCBackground | GCGraphicsExposures, ! 332: attributes, 3); ! 333: } ! 334: ! 335: ValidateGC(pWin->backgroundTile, pGC); ! 336: ! 337: (*pGC->PutImage)(pWin->backgroundTile, pGC, 1, ! 338: 0, 0, 16, 16, 0, XYBitmap, _back); ! 339: ! 340: FreeScratchGC(pGC); ! 341: ! 342: } ! 343: ! 344: /***** ! 345: * CreateRootWindow ! 346: * Makes a window at initialization time for specified screen ! 347: *****/ ! 348: ! 349: int ! 350: CreateRootWindow(screen) ! 351: int screen; ! 352: { ! 353: WindowPtr pWin; ! 354: BoxRec box; ! 355: ScreenPtr pScreen; ! 356: ! 357: savedScreenInfo[screen].pWindow = NULL; ! 358: savedScreenInfo[screen].wid = FakeClientID(0); ! 359: savedScreenInfo[screen].cid = FakeClientID(0); ! 360: screenIsSaved = SCREEN_SAVER_OFF; ! 361: ! 362: pWin = &WindowTable[screen]; ! 363: pScreen = &screenInfo.screen[screen]; ! 364: InitProcedures(pWin); ! 365: ! 366: pWin->drawable.pScreen = pScreen; ! 367: pWin->drawable.type = DRAWABLE_WINDOW; ! 368: ! 369: pWin->drawable.depth = pScreen->rootDepth; ! 370: ! 371: pWin->parent = NullWindow; ! 372: SetWindowToDefaults(pWin, pScreen); ! 373: ! 374: pWin->colormap = pScreen->defColormap; ! 375: ! 376: pWin->nextSib = NullWindow; ! 377: ! 378: MakeRootCursor(pWin); ! 379: ! 380: pWin->client = serverClient; /* since belongs to server */ ! 381: pWin->wid = FakeClientID(0); ! 382: ! 383: pWin->clientWinSize.x = pWin->clientWinSize.y = 0; ! 384: pWin->clientWinSize.height = screenInfo.screen[screen].height; ! 385: pWin->clientWinSize.width = screenInfo.screen[screen].width; ! 386: pWin->absCorner.x = pWin->absCorner.y = 0; ! 387: pWin->oldAbsCorner.x = pWin->oldAbsCorner.y = 0; ! 388: ! 389: box.x1 = 0; ! 390: box.y1 = 0; ! 391: box.x2 = screenInfo.screen[screen].width ; ! 392: box.y2 = screenInfo.screen[screen].height; ! 393: pWin->clipList = (* pScreen->RegionCreate)(&box, 1); ! 394: pWin->winSize = (* pScreen->RegionCreate)(&box, 1); ! 395: pWin->borderSize = (* pScreen->RegionCreate)(&box, 1); ! 396: pWin->borderClip = (* pScreen->RegionCreate)(&box, 1); ! 397: ! 398: pWin->class = InputOutput; ! 399: pWin->visual = pScreen->rootVisual; ! 400: ! 401: pWin->backgroundPixel = pScreen->whitePixel; ! 402: ! 403: pWin->borderPixel = pScreen->blackPixel; ! 404: pWin->borderWidth = 0; ! 405: ! 406: AddResource(pWin->wid, RT_WINDOW, pWin, DeleteWindow, RC_CORE); ! 407: ! 408: MakeRootTile(pWin); ! 409: pWin->borderTile = (PixmapPtr)USE_BORDER_PIXEL; ! 410: ! 411: /* re-validate GC for use with root Window */ ! 412: ! 413: (*pScreen->CreateWindow)(pWin); ! 414: MapWindow(pWin, DONT_HANDLE_EXPOSURES, BITS_DISCARDED, ! 415: DONT_SEND_NOTIFICATION, serverClient); ! 416: ! 417: /* We SHOULD check for an error value here XXX */ ! 418: (*pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap | CWBorderPixel); ! 419: ! 420: (*pWin->PaintWindowBackground)(pWin, pWin->clipList, PW_BACKGROUND); ! 421: EventSelectForWindow(pWin, serverClient, 0); ! 422: return(Success); ! 423: } ! 424: ! 425: /***** ! 426: * CreateWindow ! 427: * Makes a window in response to client request ! 428: * XXX What about depth of inputonly windows -- should be 0 ! 429: *****/ ! 430: ! 431: WindowPtr ! 432: CreateWindow(wid, pParent, x, y, w, h, bw, class, vmask, vlist, ! 433: depth, client, visual, error) ! 434: Window wid; ! 435: WindowPtr pParent; /* already looked up in table to do error checking*/ ! 436: short x,y; ! 437: unsigned short w, h, bw; ! 438: int class; ! 439: int vmask; ! 440: long *vlist; ! 441: int depth; ! 442: ClientPtr client; ! 443: VisualID visual; ! 444: int *error; ! 445: { ! 446: WindowPtr pWin; ! 447: ScreenPtr pScreen; ! 448: BoxRec box; ! 449: xEvent event; ! 450: int idepth, ivisual; ! 451: Bool fOK; ! 452: DepthPtr pDepth; ! 453: ! 454: if ((class != InputOnly) && (pParent->class == InputOnly)) ! 455: { ! 456: *error = BadMatch; ! 457: return (WindowPtr)NULL; ! 458: } ! 459: ! 460: if ((class == InputOnly) && ((bw != 0) || (depth != 0))) ! 461: { ! 462: *error = BadMatch; ! 463: return (WindowPtr)NULL; ! 464: } ! 465: ! 466: pScreen = pParent->drawable.pScreen; ! 467: /* Find out if the depth and visual are acceptable for this Screen */ ! 468: fOK = FALSE; ! 469: if ((class == InputOutput && depth == 0) || ! 470: (class == InputOnly) || (class == CopyFromParent)) ! 471: depth = pParent->drawable.depth; ! 472: ! 473: if (visual == CopyFromParent) ! 474: visual = pParent->visual; ! 475: else ! 476: { ! 477: for(idepth = 0; idepth < pScreen->numDepths; idepth++) ! 478: { ! 479: pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; ! 480: if (depth == pDepth->depth) ! 481: { ! 482: for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) ! 483: { ! 484: if (visual == pDepth->vids[ivisual]) ! 485: fOK = TRUE; ! 486: } ! 487: } ! 488: } ! 489: if (fOK == 0) ! 490: { ! 491: *error = BadMatch; ! 492: return (WindowPtr)NULL; ! 493: } ! 494: } ! 495: ! 496: pWin = (WindowPtr ) Xalloc( sizeof(WindowRec) ); ! 497: if (pWin == (WindowPtr) NULL) ! 498: { ! 499: *error = BadAlloc; ! 500: return (WindowPtr)NULL; ! 501: } ! 502: InitProcedures(pWin); ! 503: pWin->drawable = pParent->drawable; ! 504: if (class == InputOutput) ! 505: pWin->drawable.depth = depth; ! 506: else if (class == InputOnly) ! 507: pWin->drawable.type = (short) UNDRAWABLE_WINDOW; ! 508: ! 509: pWin->wid = wid; ! 510: pWin->client = client; ! 511: pWin->visual = visual; ! 512: ! 513: SetWindowToDefaults(pWin, pScreen); ! 514: ! 515: pWin->cursor = (CursorPtr)None; ! 516: ! 517: if (class == CopyFromParent) ! 518: pWin->class = pParent->class; ! 519: else ! 520: pWin->class = class; ! 521: ! 522: pWin->borderWidth = (int) bw; ! 523: pWin->backgroundTile = (PixmapPtr)None; ! 524: pWin->backgroundPixel = pScreen->whitePixel; ! 525: ! 526: if ((pWin->drawable.depth != pParent->drawable.depth) && ! 527: (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0 ))) ! 528: { ! 529: Xfree(pWin); ! 530: *error = BadMatch; ! 531: return (WindowPtr)NULL; ! 532: } ! 533: if ((vmask & (CWBorderPixmap | CWBorderPixel)) != 0) ! 534: /* it will just get fixed in ChangeWindowAttributes */ ! 535: pWin->borderTile = (PixmapPtr)NULL; ! 536: else ! 537: { /* this is WRONG!! XXX */ ! 538: /* should be actually copied */ ! 539: pWin->borderTile = pParent->borderTile; ! 540: if (IS_VALID_PIXMAP(pParent->borderTile)) ! 541: pParent->borderTile->refcnt++; ! 542: } ! 543: pWin->borderPixel = pParent->borderPixel; ! 544: pWin->visibility = VisibilityFullyObscured; ! 545: ! 546: pWin->clientWinSize.x = x + bw; ! 547: pWin->clientWinSize.y = y + bw; ! 548: pWin->clientWinSize.height = h; ! 549: pWin->clientWinSize.width = w; ! 550: pWin->absCorner.x = pWin->oldAbsCorner.x = pParent->absCorner.x + x + bw; ! 551: pWin->absCorner.y = pWin->oldAbsCorner.y = pParent->absCorner.y + y + bw; ! 552: ! 553: /* set up clip list correctly for unobscured WindowPtr */ ! 554: pWin->clipList = (* pScreen->RegionCreate)(NULL, 1); ! 555: pWin->borderClip = (* pScreen->RegionCreate)(NULL, 1); ! 556: box.x1 = pWin->absCorner.x; ! 557: box.y1 = pWin->absCorner.y; ! 558: box.x2 = box.x1 + w; ! 559: box.y2 = box.y1 + h; ! 560: pWin->winSize = (* pScreen->RegionCreate)(&box, 1); ! 561: (* pScreen->Intersect)(pWin->winSize, pWin->winSize, pParent->winSize); ! 562: if (bw) ! 563: { ! 564: box.x1 -= bw; ! 565: box.y1 -= bw; ! 566: box.x2 += bw; ! 567: box.y2 += bw; ! 568: pWin->borderSize = (* pScreen->RegionCreate)(&box, 1); ! 569: (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize, ! 570: pParent->winSize); ! 571: } ! 572: else ! 573: { ! 574: pWin->borderSize = (* pScreen->RegionCreate)(NULL, 1); ! 575: (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize); ! 576: } ! 577: ! 578: pWin->parent = pParent; ! 579: if ((screenIsSaved == SCREEN_SAVER_ON) ! 580: && (pParent == &WindowTable[pScreen->myNum]) ! 581: && (pParent->firstChild) ! 582: && (savedScreenInfo[pScreen->myNum].blanked == SCREEN_IS_TILED)) ! 583: { ! 584: WindowPtr pFirst = pParent->firstChild; ! 585: pWin->nextSib = pFirst->nextSib; ! 586: if (pFirst->nextSib) ! 587: pFirst->nextSib->prevSib = pWin; ! 588: else ! 589: pParent->lastChild = pWin; ! 590: pFirst->nextSib = pWin; ! 591: pWin->prevSib = pFirst; ! 592: } ! 593: else ! 594: { ! 595: pWin->nextSib = pParent->firstChild; ! 596: if (pParent->firstChild) ! 597: pParent->firstChild->prevSib = pWin; ! 598: else ! 599: pParent->lastChild = pWin; ! 600: pParent->firstChild = pWin; ! 601: } ! 602: ! 603: /* We SHOULD check for an error value here XXX */ ! 604: (*pScreen->CreateWindow)(pWin); ! 605: /* We SHOULD check for an error value here XXX */ ! 606: (*pScreen->PositionWindow)(pWin, pWin->absCorner.x, pWin->absCorner.y); ! 607: if ((vmask & CWEventMask) == 0) ! 608: EventSelectForWindow(pWin, client, 0); ! 609: ! 610: if (vmask) ! 611: *error = ChangeWindowAttributes(pWin, vmask, vlist, pWin->client); ! 612: else ! 613: *error = Success; ! 614: ! 615: WindowHasNewCursor( pWin); ! 616: ! 617: event.u.u.type = CreateNotify; ! 618: event.u.createNotify.window = wid; ! 619: event.u.createNotify.parent = pParent->wid; ! 620: event.u.createNotify.x = x; ! 621: event.u.createNotify.y = y; ! 622: event.u.createNotify.width = w; ! 623: event.u.createNotify.height = h; ! 624: event.u.createNotify.borderWidth = bw; ! 625: event.u.createNotify.override = pWin->overrideRedirect; ! 626: DeliverEvents(pWin->parent, &event, 1, NullWindow); ! 627: ! 628: return pWin; ! 629: } ! 630: ! 631: static void ! 632: FreeWindowResources(pWin) ! 633: WindowPtr pWin; ! 634: { ! 635: ScreenPtr pScreen; ! 636: void (* proc)(); ! 637: ! 638: pScreen = pWin->drawable.pScreen; ! 639: ! 640: DeleteWindowFromAnySaveSet(pWin); ! 641: DeleteWindowFromAnySelections(pWin); ! 642: DeleteWindowFromAnyEvents(pWin, TRUE); ! 643: proc = pScreen->RegionDestroy; ! 644: (* proc)(pWin->clipList); ! 645: (* proc)(pWin->winSize); ! 646: (* proc)(pWin->borderClip); ! 647: (* proc)(pWin->borderSize); ! 648: (* proc)(pWin->exposed); ! 649: (* proc)(pWin->borderExposed); ! 650: if (pWin->backStorage) ! 651: { ! 652: (* proc)(pWin->backStorage->obscured); ! 653: Xfree(pWin->backStorage); ! 654: } ! 655: (* pScreen->DestroyPixmap)(pWin->borderTile); ! 656: (* pScreen->DestroyPixmap)(pWin->backgroundTile); ! 657: ! 658: if (pWin->cursor != (CursorPtr)None) ! 659: FreeCursor( pWin->cursor, 0); ! 660: ! 661: DeleteAllWindowProperties(pWin); ! 662: /* We SHOULD check for an error value here XXX */ ! 663: (* pScreen->DestroyWindow)(pWin); ! 664: } ! 665: ! 666: static void ! 667: CrushTree(pWin) ! 668: WindowPtr pWin; ! 669: { ! 670: WindowPtr pSib; ! 671: xEvent event; ! 672: ! 673: if (pWin == (WindowPtr) NULL) ! 674: return; ! 675: while (pWin) ! 676: { ! 677: CrushTree(pWin->firstChild); ! 678: ! 679: event.u.u.type = DestroyNotify; ! 680: event.u.destroyNotify.window = pWin->wid; ! 681: DeliverEvents(pWin, &event, 1, NullWindow); ! 682: ! 683: FreeResource(pWin->wid, RC_CORE); ! 684: pSib = pWin->nextSib; ! 685: pWin->realized = FALSE; ! 686: pWin->viewable = FALSE; ! 687: (* pWin->drawable.pScreen->UnrealizeWindow)(pWin); ! 688: FreeWindowResources(pWin); ! 689: Xfree(pWin); ! 690: pWin = pSib; ! 691: } ! 692: } ! 693: ! 694: /***** ! 695: * DeleteWindow ! 696: * Deletes child of window then window itself ! 697: *****/ ! 698: ! 699: DeleteWindow(pWin, wid) ! 700: WindowPtr pWin; ! 701: int wid; ! 702: { ! 703: WindowPtr pParent; ! 704: xEvent event; ! 705: ! 706: UnmapWindow(pWin, HANDLE_EXPOSURES, SEND_NOTIFICATION, FALSE); ! 707: ! 708: CrushTree(pWin->firstChild); ! 709: ! 710: event.u.u.type = DestroyNotify; ! 711: event.u.destroyNotify.window = pWin->wid; ! 712: DeliverEvents(pWin, &event, 1, NullWindow); ! 713: ! 714: pParent = pWin->parent; ! 715: FreeWindowResources(pWin); ! 716: if (pParent) ! 717: { ! 718: if (pParent->firstChild == pWin) ! 719: pParent->firstChild = pWin->nextSib; ! 720: if (pParent->lastChild == pWin) ! 721: pParent->lastChild = pWin->prevSib; ! 722: if (pWin->nextSib) ! 723: pWin->nextSib->prevSib = pWin->prevSib; ! 724: if (pWin->prevSib) ! 725: pWin->prevSib->nextSib = pWin->nextSib; ! 726: Xfree(pWin); ! 727: } ! 728: } ! 729: ! 730: DestroySubwindows(pWin, client) ! 731: WindowPtr pWin; ! 732: ClientPtr client; ! 733: { ! 734: WindowPtr pChild, pSib; ! 735: xEvent event; ! 736: ! 737: if ((pChild = pWin->lastChild) == (WindowPtr) NULL) ! 738: return; ! 739: while (pChild) ! 740: { ! 741: pSib = pChild->prevSib; ! 742: /* a little lazy evaluation, don't send exposes until all deleted */ ! 743: if (pSib != (WindowPtr) NULL) ! 744: { ! 745: event.u.u.type = UnmapNotify; ! 746: event.u.unmapNotify.window = pWin->wid; ! 747: event.u.unmapNotify.fromConfigure = xFalse; ! 748: DeliverEvents(pWin, &event, 1, NullWindow); ! 749: } ! 750: else ! 751: { ! 752: pChild->nextSib = (WindowPtr)NULL; ! 753: UnmapWindow(pChild, HANDLE_EXPOSURES, SEND_NOTIFICATION, FALSE); ! 754: } ! 755: CrushTree(pChild->firstChild); ! 756: ! 757: event.u.u.type = DestroyNotify; ! 758: event.u.destroyNotify.window = pChild->wid; ! 759: DeliverEvents(pChild, &event, 1, NullWindow); ! 760: ! 761: FreeResource(pChild->wid, RC_CORE); ! 762: FreeWindowResources(pChild); ! 763: Xfree(pChild); ! 764: pChild = pSib; ! 765: } ! 766: pWin->firstChild = (WindowPtr )NULL; ! 767: } ! 768: ! 769: ! 770: /***** ! 771: * ChangeWindowAttributes ! 772: * ! 773: * The value-mask specifies which attributes are to be changed; the ! 774: * value-list contains one value for each one bit in the mask, from least ! 775: * to most significant bit in the mask. ! 776: *****/ ! 777: ! 778: int ! 779: ChangeWindowAttributes(pWin, vmask, vlist, client) ! 780: WindowPtr pWin; ! 781: unsigned int vmask; ! 782: long *vlist; ! 783: ClientPtr client; ! 784: { ! 785: int index; ! 786: long *pVlist; ! 787: PixmapPtr pPixmap; ! 788: Pixmap pixID; ! 789: CursorPtr pCursor; ! 790: Cursor cursorID; ! 791: int result; ! 792: ScreenPtr pScreen; ! 793: unsigned int vmaskCopy = 0; ! 794: int error; ! 795: ! 796: if ((pWin->class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK))) ! 797: return BadMatch; ! 798: ! 799: error = Success; ! 800: pScreen = pWin->drawable.pScreen; ! 801: pVlist = vlist; ! 802: while (vmask) ! 803: { ! 804: index = ffs(vmask) - 1; ! 805: vmask &= ~(index = (1 << index)); ! 806: switch (index) ! 807: { ! 808: case CWBackPixmap: ! 809: pixID = (Pixmap )*pVlist; ! 810: pVlist++; ! 811: if (pixID == None) ! 812: { ! 813: (* pScreen->DestroyPixmap)(pWin->backgroundTile); ! 814: if (pWin->parent == (WindowPtr) NULL) ! 815: MakeRootTile(pWin); ! 816: else ! 817: pWin->backgroundTile = (PixmapPtr)NULL; ! 818: } ! 819: else if (pixID == ParentRelative) ! 820: { ! 821: (* pScreen->DestroyPixmap)(pWin->backgroundTile); ! 822: if (pWin->parent == (WindowPtr) NULL) ! 823: MakeRootTile(pWin); ! 824: else ! 825: pWin->backgroundTile = (PixmapPtr)ParentRelative; ! 826: /* Note that the parent's backgroundTile's refcnt is NOT ! 827: * incremented. */ ! 828: } ! 829: else ! 830: { ! 831: pPixmap = (PixmapPtr)LookupID(pixID, RT_PIXMAP, RC_CORE); ! 832: if (pPixmap != (PixmapPtr) NULL) ! 833: { ! 834: if ((pPixmap->drawable.depth != pWin->drawable.depth) || ! 835: (pPixmap->drawable.pScreen != pScreen)) ! 836: { ! 837: error = BadMatch; ! 838: goto PatchUp; ! 839: } ! 840: (* pScreen->DestroyPixmap)(pWin->backgroundTile); ! 841: pWin->backgroundTile = pPixmap; ! 842: pPixmap->refcnt++; ! 843: } ! 844: else ! 845: { ! 846: error = BadPixmap; ! 847: goto PatchUp; ! 848: } ! 849: } ! 850: break; ! 851: case CWBackPixel: ! 852: pWin->backgroundPixel = (CARD32 ) *pVlist; ! 853: (* pScreen->DestroyPixmap)(pWin->backgroundTile); ! 854: pWin->backgroundTile = (PixmapPtr)USE_BACKGROUND_PIXEL; ! 855: /* background pixel overrides background pixmap, ! 856: so don't let the ddx layer see both bits */ ! 857: vmaskCopy &= ~CWBackPixmap; ! 858: pVlist++; ! 859: break; ! 860: case CWBorderPixmap: ! 861: pixID = (Pixmap ) *pVlist; ! 862: pVlist++; ! 863: if (pixID == CopyFromParent) ! 864: { ! 865: GCPtr pGC; ! 866: PixmapPtr parentPixmap; ! 867: if ((pWin->parent == (WindowPtr) NULL) || (pWin->parent && ! 868: (pWin->drawable.depth != ! 869: pWin->parent->drawable.depth))) ! 870: { ! 871: error = BadMatch; ! 872: goto PatchUp; ! 873: } ! 874: (* pScreen->DestroyPixmap)(pWin->borderTile); ! 875: parentPixmap = pWin->parent->borderTile; ! 876: if (parentPixmap == (PixmapPtr)USE_BORDER_PIXEL) ! 877: { ! 878: pWin->borderTile = (PixmapPtr)USE_BORDER_PIXEL; ! 879: pWin->borderPixel = pWin->parent->borderPixel; ! 880: } ! 881: else ! 882: { ! 883: CARD32 attribute; ! 884: ! 885: pPixmap = (* pWin->drawable.pScreen->CreatePixmap) ! 886: (pWin->drawable.pScreen, parentPixmap->width, ! 887: parentPixmap->height, pWin->drawable.depth); ! 888: pGC = GetScratchGC(pWin->drawable.depth, ! 889: pWin->drawable.pScreen); ! 890: ! 891: attribute = GXcopy; ! 892: ChangeGC(pGC, GCFunction, &attribute, 1); ! 893: ValidateGC(pPixmap, pGC); ! 894: ! 895: (* pGC->CopyArea)(parentPixmap, pPixmap, pGC, 0, 0, ! 896: parentPixmap->width, ! 897: parentPixmap->height, ! 898: pWin->drawable.depth, ! 899: 0, 0); ! 900: pWin->borderTile = pPixmap; ! 901: FreeScratchGC(pGC); ! 902: } ! 903: } ! 904: else ! 905: { ! 906: pPixmap = (PixmapPtr)LookupID(pixID, RT_PIXMAP, RC_CORE); ! 907: if (pPixmap) ! 908: { ! 909: if ((pPixmap->drawable.depth != pWin->drawable.depth) || ! 910: (pPixmap->drawable.pScreen != pScreen)) ! 911: { ! 912: error = BadMatch; ! 913: goto PatchUp; ! 914: } ! 915: (* pScreen->DestroyPixmap)(pWin->borderTile); ! 916: pWin->borderTile = pPixmap; ! 917: pPixmap->refcnt++; ! 918: } ! 919: else ! 920: { ! 921: error = BadPixmap; ! 922: goto PatchUp; ! 923: } ! 924: } ! 925: break; ! 926: case CWBorderPixel: ! 927: pWin->borderPixel = (CARD32) *pVlist; ! 928: (* pScreen->DestroyPixmap)(pWin->borderTile); ! 929: pWin->borderTile = (PixmapPtr)USE_BORDER_PIXEL; ! 930: /* border pixel overrides border pixmap, ! 931: so don't let the ddx layer see both bits */ ! 932: vmaskCopy &= ~CWBorderPixmap; ! 933: pVlist++; ! 934: break; ! 935: case CWBitGravity: ! 936: pWin->bitGravity = (CARD8 )*pVlist; ! 937: pVlist++; ! 938: break; ! 939: case CWWinGravity: ! 940: pWin->winGravity = (CARD8 )*pVlist; ! 941: pVlist++; ! 942: break; ! 943: case CWBackingStore: ! 944: pWin->backingStore = (CARD8 )*pVlist; ! 945: pVlist++; ! 946: break; ! 947: case CWBackingPlanes: ! 948: pWin->backingBitPlanes = (CARD32) *pVlist; ! 949: pVlist++; ! 950: break; ! 951: case CWBackingPixel: ! 952: pWin->backingPixel = (CARD32)*pVlist; ! 953: pVlist++; ! 954: break; ! 955: case CWSaveUnder: ! 956: pWin->saveUnder = (Bool) *pVlist; ! 957: pVlist++; ! 958: break; ! 959: case CWEventMask: ! 960: result = EventSelectForWindow(pWin, client, (long )*pVlist); ! 961: if (result) ! 962: { ! 963: error = result; ! 964: goto PatchUp; ! 965: } ! 966: pVlist++; ! 967: break; ! 968: case CWDontPropagate: ! 969: result = EventSuppressForWindow(pWin, client, (long )*pVlist); ! 970: if (result) ! 971: { ! 972: error = result; ! 973: goto PatchUp; ! 974: } ! 975: pVlist++; ! 976: break; ! 977: case CWOverrideRedirect: ! 978: pWin->overrideRedirect = (Bool ) *pVlist; ! 979: pVlist++; ! 980: break; ! 981: case CWColormap: ! 982: { ! 983: Colormap cmap; ! 984: ColormapPtr pCmap; ! 985: xEvent xE; ! 986: WindowPtr pWinT; ! 987: ! 988: cmap = (Colormap ) *pVlist; ! 989: pWinT = pWin; ! 990: while(cmap == CopyFromParent) ! 991: { ! 992: if(pWinT->parent) ! 993: { ! 994: if (pWinT->parent->colormap != CopyFromParent) ! 995: { ! 996: cmap = pWinT->parent->colormap; ! 997: } ! 998: else ! 999: pWinT = pWinT->parent; ! 1000: } ! 1001: else ! 1002: { ! 1003: error = BadMatch; ! 1004: goto PatchUp; ! 1005: } ! 1006: } ! 1007: pCmap = (ColormapPtr)LookupID(cmap, RT_COLORMAP, RC_CORE); ! 1008: if (pCmap) ! 1009: { ! 1010: if (pCmap->pVisual->vid == pWin->visual) ! 1011: { ! 1012: pWin->colormap = (Colormap ) cmap; ! 1013: xE.u.u.type = ColormapNotify; ! 1014: xE.u.colormap.new = TRUE; ! 1015: xE.u.colormap.state = IsMapInstalled(cmap, pWin); ! 1016: TraverseTree(pWin, TellNewMap, &xE); ! 1017: } ! 1018: else ! 1019: { ! 1020: error = BadMatch; ! 1021: goto PatchUp; ! 1022: } ! 1023: } ! 1024: else ! 1025: { ! 1026: error = BadColor; ! 1027: goto PatchUp; ! 1028: } ! 1029: pVlist++; ! 1030: break; ! 1031: } ! 1032: case CWCursor: ! 1033: cursorID = (Cursor ) *pVlist; ! 1034: pVlist++; ! 1035: /* ! 1036: * install the new ! 1037: */ ! 1038: if ( cursorID == None) ! 1039: { ! 1040: if ( pWin->cursor != None) ! 1041: FreeCursor( pWin->cursor); ! 1042: if (pWin == &WindowTable[pWin->drawable.pScreen->myNum]) ! 1043: MakeRootCursor( pWin); ! 1044: else ! 1045: pWin->cursor = (CursorPtr)None; ! 1046: } ! 1047: else ! 1048: { ! 1049: pCursor = (CursorPtr)LookupID(cursorID, RT_CURSOR, RC_CORE); ! 1050: if (pCursor) ! 1051: { ! 1052: if ( pWin->cursor != None) ! 1053: FreeCursor( pWin->cursor); ! 1054: pWin->cursor = pCursor; ! 1055: pWin->cursor->refcnt++; ! 1056: } ! 1057: else ! 1058: { ! 1059: error = BadCursor; ! 1060: goto PatchUp; ! 1061: } ! 1062: } ! 1063: WindowHasNewCursor( pWin); ! 1064: break; ! 1065: default: break; ! 1066: } ! 1067: vmaskCopy |= index; ! 1068: } ! 1069: PatchUp: ! 1070: /* We SHOULD check for an error value here XXX */ ! 1071: (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy); ! 1072: ! 1073: /* ! 1074: If the border pixel changed, redraw the border. ! 1075: Note that this has to be done AFTER pScreen->ChangeWindowAttributes ! 1076: for the tile to be rotated, and the correct function selected. ! 1077: */ ! 1078: if ((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) ! 1079: && pWin->viewable && pWin->borderWidth) ! 1080: { ! 1081: (* pScreen->Subtract)(pWin->borderExposed, pWin->borderClip, ! 1082: pWin->winSize); ! 1083: (*pWin->PaintWindowBorder)(pWin, pWin->borderExposed, PW_BORDER); ! 1084: (* pScreen->RegionEmpty)(pWin->borderExposed); ! 1085: } ! 1086: return error; ! 1087: } ! 1088: ! 1089: ! 1090: /***** ! 1091: * GetWindowAttributes ! 1092: * Notice that this is different than ChangeWindowAttributes ! 1093: *****/ ! 1094: ! 1095: GetWindowAttributes(pWin, client) ! 1096: WindowPtr pWin; ! 1097: ClientPtr client; ! 1098: { ! 1099: xGetWindowAttributesReply wa; ! 1100: WindowPtr pWinT; ! 1101: ! 1102: wa.type = X_Reply; ! 1103: wa.bitGravity = pWin->bitGravity; ! 1104: wa.winGravity = pWin->winGravity; ! 1105: wa.backingStore = pWin->backingStore; ! 1106: wa.length = (sizeof(xGetWindowAttributesReply) - ! 1107: sizeof(xGenericReply)) >> 2; ! 1108: wa.sequenceNumber = client->sequence; ! 1109: wa.backingBitPlanes = pWin->backingBitPlanes; ! 1110: wa.backingPixel = pWin->backingPixel; ! 1111: wa.saveUnder = (BOOL)pWin->saveUnder; ! 1112: wa.override = pWin->overrideRedirect; ! 1113: if (!pWin->mapped) ! 1114: wa.mapState = IsUnmapped; ! 1115: else if (pWin->realized) ! 1116: wa.mapState = IsViewable; ! 1117: else ! 1118: wa.mapState = IsUnviewable; ! 1119: ! 1120: pWinT = pWin; ! 1121: while (pWinT->colormap == (Colormap)CopyFromParent) ! 1122: pWinT = pWinT->parent; ! 1123: wa.colormap = pWinT->colormap; ! 1124: wa.mapInstalled = IsMapInstalled(wa.colormap, pWin); ! 1125: ! 1126: wa.yourEventMask = EventMaskForClient(pWin, client, &wa.allEventMasks); ! 1127: wa.doNotPropagateMask = pWin->dontPropagateMask ; ! 1128: wa.class = pWin->class; ! 1129: wa.visualID = pWin->visual; ! 1130: ! 1131: WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa); ! 1132: } ! 1133: ! 1134: ! 1135: static WindowPtr ! 1136: MoveWindowInStack(pWin, pNextSib) ! 1137: WindowPtr pWin, pNextSib; ! 1138: { ! 1139: WindowPtr pParent = pWin->parent; ! 1140: WindowPtr pFirstChange = pWin; /* highest window where list changes */ ! 1141: ! 1142: if (pWin->nextSib != pNextSib) ! 1143: { ! 1144: if (!pNextSib) /* move to bottom */ ! 1145: { ! 1146: if (pParent->firstChild == pWin) ! 1147: pParent->firstChild = pWin->nextSib; ! 1148: /* if (pWin->nextSib) */ /* is always True: pNextSib == NULL ! 1149: * and pWin->nextSib != pNextSib ! 1150: * therefore pWin->nextSib != NULL */ ! 1151: pFirstChange = pWin->nextSib; ! 1152: pWin->nextSib->prevSib = pWin->prevSib; ! 1153: /* else pFirstChange = pWin; */ ! 1154: if (pWin->prevSib) ! 1155: pWin->prevSib->nextSib = pWin->nextSib; ! 1156: pParent->lastChild->nextSib = pWin; ! 1157: pWin->prevSib = pParent->lastChild; ! 1158: pWin->nextSib = (WindowPtr )NULL; ! 1159: pParent->lastChild = pWin; ! 1160: } ! 1161: else if (pParent->firstChild == pNextSib) /* move to top */ ! 1162: { ! 1163: pFirstChange = pWin; ! 1164: if (pParent->lastChild == pWin) ! 1165: pParent->lastChild = pWin->prevSib; ! 1166: if (pWin->nextSib) ! 1167: pWin->nextSib->prevSib = pWin->prevSib; ! 1168: if (pWin->prevSib) ! 1169: pWin->prevSib->nextSib = pWin->nextSib; ! 1170: pWin->nextSib = pParent->firstChild; ! 1171: pWin->prevSib = (WindowPtr ) NULL; ! 1172: pNextSib->prevSib = pWin; ! 1173: pParent->firstChild = pWin; ! 1174: } ! 1175: else /* move in middle of list */ ! 1176: { ! 1177: WindowPtr pOldNext = pWin->nextSib; ! 1178: ! 1179: pFirstChange = (WindowPtr )NULL; ! 1180: if (pParent->firstChild == pWin) ! 1181: pFirstChange = pParent->firstChild = pWin->nextSib; ! 1182: if (pParent->lastChild == pWin) { ! 1183: pFirstChange = pWin; ! 1184: pParent->lastChild = pWin->prevSib; ! 1185: } ! 1186: if (pWin->nextSib) ! 1187: pWin->nextSib->prevSib = pWin->prevSib; ! 1188: if (pWin->prevSib) ! 1189: pWin->prevSib->nextSib = pWin->nextSib; ! 1190: pWin->nextSib = pNextSib; ! 1191: pWin->prevSib = pNextSib->prevSib; ! 1192: if (pNextSib->prevSib) ! 1193: pNextSib->prevSib->nextSib = pWin; ! 1194: pNextSib->prevSib = pWin; ! 1195: if (!pFirstChange) { /* do we know it yet? */ ! 1196: pFirstChange = pParent->firstChild; /* no, search from top */ ! 1197: while ((pFirstChange != pWin) && (pFirstChange != pOldNext)) ! 1198: pFirstChange = pFirstChange->nextSib; ! 1199: } ! 1200: } ! 1201: } ! 1202: ! 1203: return( pFirstChange ); ! 1204: } ! 1205: ! 1206: static void ! 1207: MoveWindow(pWin, x, y, pNextSib) ! 1208: WindowPtr pWin; ! 1209: short x,y; ! 1210: WindowPtr pNextSib; ! 1211: { ! 1212: WindowPtr pParent; ! 1213: Bool WasMapped = (Bool)(pWin->realized); ! 1214: BoxRec box; ! 1215: short oldx, oldy, bw; ! 1216: RegionPtr oldRegion; ! 1217: DDXPointRec oldpt; ! 1218: Bool anyMarked; ! 1219: register ScreenPtr pScreen; ! 1220: BoxPtr pBox; ! 1221: WindowPtr windowToValidate = pWin; ! 1222: ! 1223: /* if this is a root window, can't be moved */ ! 1224: if (!(pParent = pWin->parent)) ! 1225: return ; ! 1226: pScreen = pWin->drawable.pScreen; ! 1227: bw = pWin->borderWidth; ! 1228: ! 1229: oldx = pWin->absCorner.x; ! 1230: oldy = pWin->absCorner.y; ! 1231: oldpt.x = oldx; ! 1232: oldpt.y = oldy; ! 1233: if (WasMapped) ! 1234: { ! 1235: oldRegion = (* pScreen->RegionCreate)(NULL, 1); ! 1236: (* pScreen->RegionCopy)(oldRegion, pWin->borderClip); ! 1237: pBox = (* pScreen->RegionExtents)(pWin->borderSize); ! 1238: anyMarked = MarkSiblingsBelowMe(pWin, pBox); ! 1239: } ! 1240: pWin->clientWinSize.x = x + bw; ! 1241: pWin->clientWinSize.y = y + bw; ! 1242: pWin->oldAbsCorner.x = oldx; ! 1243: pWin->oldAbsCorner.y = oldy; ! 1244: pWin->absCorner.x = pParent->absCorner.x + x +bw; ! 1245: pWin->absCorner.y = pParent->absCorner.y + y + bw; ! 1246: ! 1247: box.x1 = pWin->absCorner.x; ! 1248: box.y1 = pWin->absCorner.y; ! 1249: box.x2 = box.x1 + pWin->clientWinSize.width; ! 1250: box.y2 = box.y1+ pWin->clientWinSize.height; ! 1251: (* pScreen->RegionReset)(pWin->winSize, &box); ! 1252: (* pScreen->Intersect)(pWin->winSize, pWin->winSize, pParent->winSize); ! 1253: ! 1254: if (bw) ! 1255: { ! 1256: box.x1 -= bw; ! 1257: box.y1 -= bw; ! 1258: box.x2 += bw; ! 1259: box.y2 += bw; ! 1260: (* pScreen->RegionReset)(pWin->borderSize, &box); ! 1261: (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize, ! 1262: pParent->winSize); ! 1263: } ! 1264: else ! 1265: (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize); ! 1266: ! 1267: (* pScreen->PositionWindow)(pWin,pWin->absCorner.x, pWin->absCorner.y); ! 1268: ! 1269: windowToValidate = MoveWindowInStack(pWin, pNextSib); ! 1270: ! 1271: ResizeChildrenWinSize(pWin, FALSE, 0, 0, DONT_USE_GRAVITY); ! 1272: if (WasMapped) ! 1273: { ! 1274: ! 1275: anyMarked = MarkSiblingsBelowMe(windowToValidate, pBox) || anyMarked; ! 1276: ! 1277: (* pScreen->ValidateTree)(pParent, (WindowPtr)NULL, TRUE, anyMarked); ! 1278: ! 1279: DoObscures(pParent); ! 1280: if (pWin->backgroundTile == (PixmapPtr)ParentRelative) ! 1281: (* pScreen->RegionCopy)(pWin->exposed, pWin->clipList); ! 1282: else ! 1283: { ! 1284: /* ! 1285: * Why subtract borderSize from parent's exposures? parent ! 1286: * exposures aren't supposed to extend into children! ! 1287: */ ! 1288: (* pWin->CopyWindow)(pWin, oldpt, oldRegion); ! 1289: (* pScreen->Subtract)(pParent->exposed, pParent->exposed, ! 1290: pWin->borderSize); ! 1291: ! 1292: } ! 1293: (* pScreen->RegionDestroy)(oldRegion); ! 1294: HandleExposures(pParent); ! 1295: } ! 1296: } ! 1297: ! 1298: static void ! 1299: ResizeChildrenWinSize(pWin, XYSame, dw, dh, useGravity) ! 1300: WindowPtr pWin; ! 1301: Bool XYSame; ! 1302: int dw, dh; ! 1303: Bool useGravity; ! 1304: { ! 1305: WindowPtr pSib; ! 1306: RegionPtr parentReg; ! 1307: BoxRec box; ! 1308: register short x, y, cwsx, cwsy; ! 1309: Bool unmap = FALSE; ! 1310: register ScreenPtr pScreen; ! 1311: xEvent event; ! 1312: ! 1313: pScreen = pWin->drawable.pScreen; ! 1314: parentReg = pWin->winSize; ! 1315: pSib = pWin->firstChild; ! 1316: x = pWin->absCorner.x; ! 1317: y = pWin->absCorner.y; ! 1318: ! 1319: while (pSib) ! 1320: { ! 1321: cwsx = pSib->clientWinSize.x; ! 1322: cwsy = pSib->clientWinSize.y; ! 1323: if (useGravity == USE_GRAVITY) ! 1324: { ! 1325: switch (pSib->winGravity) ! 1326: { ! 1327: case UnmapGravity: ! 1328: unmap = TRUE; ! 1329: case NorthWestGravity: ! 1330: break; ! 1331: case NorthGravity: ! 1332: cwsx += dw/2; ! 1333: break; ! 1334: case NorthEastGravity: ! 1335: cwsx += dw; ! 1336: break; ! 1337: case WestGravity: ! 1338: cwsy += dh/2; ! 1339: break; ! 1340: case CenterGravity: ! 1341: cwsx += dw/2; ! 1342: cwsy += dh/2; ! 1343: break; ! 1344: case EastGravity: ! 1345: cwsx += dw; ! 1346: cwsy += dh/2; ! 1347: break; ! 1348: case SouthWestGravity: ! 1349: cwsy += dh; ! 1350: break; ! 1351: case SouthGravity: ! 1352: cwsx += dw/2; ! 1353: cwsy += dh; ! 1354: break; ! 1355: case SouthEastGravity: ! 1356: cwsx += dw; ! 1357: cwsy += dh; ! 1358: break; ! 1359: case StaticGravity: /* XXX */ ! 1360: break; ! 1361: default: ! 1362: break; ! 1363: } ! 1364: } ! 1365: ! 1366: event.u.u.type = GravityNotify; ! 1367: event.u.gravity.window = pSib->wid; ! 1368: event.u.gravity.x = cwsx; ! 1369: event.u.gravity.y = cwsy; ! 1370: DeliverEvents (pSib, &event, 1, NullWindow); ! 1371: ! 1372: box.x1 = x + cwsx; ! 1373: box.y1 = y + cwsy; ! 1374: box.x2 = box.x1 + pSib->clientWinSize.width; ! 1375: box.y2 = box.y1 + pSib->clientWinSize.height; ! 1376: ! 1377: pSib->oldAbsCorner.x = pSib->absCorner.x; ! 1378: pSib->oldAbsCorner.y = pSib->absCorner.y; ! 1379: pSib->absCorner.x = x + cwsx; ! 1380: pSib->absCorner.y = y + cwsy; ! 1381: ! 1382: (* pScreen->RegionReset)(pSib->winSize, &box); ! 1383: (* pScreen->Intersect)(pSib->winSize, pSib->winSize, ! 1384: parentReg); ! 1385: ! 1386: if (pSib->borderWidth) ! 1387: { ! 1388: box.x1 -= pSib->borderWidth; ! 1389: box.y1 -= pSib->borderWidth; ! 1390: box.x2 += pSib->borderWidth; ! 1391: box.y2 += pSib->borderWidth; ! 1392: (* pScreen->RegionReset)(pSib->borderSize, &box); ! 1393: (* pScreen->Intersect)(pSib->borderSize, ! 1394: pSib->borderSize, parentReg); ! 1395: } ! 1396: else ! 1397: (* pScreen->RegionCopy)(pSib->borderSize, pSib->winSize); ! 1398: (* pScreen->PositionWindow)(pSib, pSib->absCorner.x, pSib->absCorner.y); ! 1399: pSib->marked = 1; ! 1400: if (pSib->firstChild) ! 1401: ResizeChildrenWinSize(pSib, XYSame, 0, 0, DONT_USE_GRAVITY); ! 1402: if (unmap) ! 1403: { ! 1404: UnmapWindow(pSib, DONT_HANDLE_EXPOSURES, SEND_NOTIFICATION, TRUE); ! 1405: unmap = FALSE; ! 1406: } ! 1407: pSib = pSib->nextSib; ! 1408: } ! 1409: } ! 1410: ! 1411: static int ! 1412: ExposeAll(pWin, pScreen) ! 1413: WindowPtr pWin; ! 1414: ScreenPtr pScreen; ! 1415: { ! 1416: if (!pWin) ! 1417: return(WT_NOMATCH); ! 1418: if (pWin->mapped) ! 1419: { ! 1420: (* pScreen->RegionCopy)(pWin->exposed, pWin->clipList); ! 1421: return (WT_WALKCHILDREN); ! 1422: } ! 1423: else ! 1424: return(WT_NOMATCH); ! 1425: } ! 1426: ! 1427: ! 1428: ! 1429: static void ! 1430: SlideAndSizeWindow(pWin, x, y, w, h, pSib) ! 1431: WindowPtr pWin; ! 1432: short x,y; ! 1433: unsigned short w, h; ! 1434: WindowPtr pSib; ! 1435: { ! 1436: WindowPtr pParent; ! 1437: Bool WasMapped = (Bool)(pWin->realized); ! 1438: BoxRec box; ! 1439: unsigned short width = pWin->clientWinSize.width, ! 1440: height = pWin->clientWinSize.height; ! 1441: short oldx = pWin->absCorner.x, ! 1442: oldy = pWin->absCorner.y, ! 1443: bw = pWin->borderWidth; ! 1444: short dw, dh; ! 1445: Bool XYSame = FALSE; ! 1446: DDXPointRec oldpt; ! 1447: RegionPtr oldRegion; ! 1448: Bool anyMarked; ! 1449: register ScreenPtr pScreen; ! 1450: BoxPtr pBox; ! 1451: WindowPtr pFirstChange; ! 1452: ! 1453: /* if this is a root window, can't be resized */ ! 1454: if (!(pParent = pWin->parent)) ! 1455: return ; ! 1456: ! 1457: pScreen = pWin->drawable.pScreen; ! 1458: if (WasMapped) ! 1459: { ! 1460: if ((pWin->bitGravity != ForgetGravity) || ! 1461: (pWin->backgroundTile == (PixmapPtr)ParentRelative)) ! 1462: oldRegion = NotClippedByChildren(pWin); ! 1463: pBox = (* pScreen->RegionExtents)(pWin->borderSize); ! 1464: anyMarked = MarkSiblingsBelowMe(pWin, pBox); ! 1465: } ! 1466: pWin->clientWinSize.x = x + bw; ! 1467: pWin->clientWinSize.y = y + bw; ! 1468: pWin->clientWinSize.height = h; ! 1469: pWin->clientWinSize.width = w; ! 1470: XYSame = ((pParent->absCorner.x + x == pWin->absCorner.x) ! 1471: && (pParent->absCorner.y + y == pWin->absCorner.y)); ! 1472: pWin->oldAbsCorner.x = oldx; ! 1473: pWin->oldAbsCorner.y = oldy; ! 1474: oldpt.x = oldx; ! 1475: oldpt.y = oldy; ! 1476: ! 1477: pWin->absCorner.x = pParent->absCorner.x + x + bw; ! 1478: pWin->absCorner.y = pParent->absCorner.y + y + bw; ! 1479: ! 1480: box.x1 = pWin->absCorner.x; ! 1481: box.y1 = pWin->absCorner.y; ! 1482: box.x2 = pWin->absCorner.x + w; ! 1483: box.y2 = pWin->absCorner.y + h; ! 1484: (* pScreen->RegionReset)(pWin->winSize, &box); ! 1485: (* pScreen->Intersect)(pWin->winSize, pWin->winSize, pParent->winSize); ! 1486: ! 1487: if (pWin->borderWidth) ! 1488: { ! 1489: box.x1 -= bw; ! 1490: box.y1 -= bw; ! 1491: box.x2 += bw; ! 1492: box.y2 += bw; ! 1493: (* pScreen->RegionReset)(pWin->borderSize, &box); ! 1494: (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize, ! 1495: pParent->winSize); ! 1496: } ! 1497: else ! 1498: (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize); ! 1499: ! 1500: dw = w - width; ! 1501: dh = h - height; ! 1502: ResizeChildrenWinSize(pWin, XYSame, dw, dh, USE_GRAVITY); ! 1503: ! 1504: /* let the hardware adjust background and border pixmaps, if any */ ! 1505: (* pScreen->PositionWindow)(pWin, pWin->absCorner.x, pWin->absCorner.y); ! 1506: ! 1507: pFirstChange = MoveWindowInStack(pWin, pSib); ! 1508: ! 1509: if (WasMapped) ! 1510: { ! 1511: RegionPtr pRegion; ! 1512: ! 1513: anyMarked = MarkSiblingsBelowMe(pFirstChange, pBox) || anyMarked; ! 1514: ! 1515: if ((pWin->bitGravity == ForgetGravity) || ! 1516: (pWin->backgroundTile == (PixmapPtr)ParentRelative)) ! 1517: { ! 1518: (* pScreen->ValidateTree)(pParent, pFirstChange, TRUE, anyMarked); ! 1519: /* CopyWindow will step on borders, so re-paint them */ ! 1520: (* pScreen->Subtract)(pWin->borderExposed, ! 1521: pWin->borderClip, pWin->winSize); ! 1522: TraverseTree(pWin, ExposeAll, pScreen); ! 1523: DoObscures(pParent); ! 1524: HandleExposures(pParent); ! 1525: } ! 1526: else ! 1527: { ! 1528: pRegion = (* pScreen->RegionCreate)(NULL, 1); ! 1529: (* pScreen->RegionCopy)(pRegion, pWin->clipList); ! 1530: ! 1531: x = pWin->absCorner.x; ! 1532: y = pWin->absCorner.y; ! 1533: switch (pWin->bitGravity) ! 1534: { ! 1535: case NorthWestGravity: ! 1536: break; ! 1537: case NorthGravity: ! 1538: x += dw/2; ! 1539: break; ! 1540: case NorthEastGravity: ! 1541: x += dw; ! 1542: break; ! 1543: case WestGravity: ! 1544: y += dh/2; ! 1545: break; ! 1546: case CenterGravity: ! 1547: x += dw/2; ! 1548: y += dh/2; ! 1549: break; ! 1550: case EastGravity: ! 1551: x += dw; ! 1552: y += dh/2; ! 1553: break; ! 1554: case SouthWestGravity: ! 1555: y += dh; ! 1556: break; ! 1557: case SouthGravity: ! 1558: x += dw/2; ! 1559: y += dh; ! 1560: break; ! 1561: case SouthEastGravity: ! 1562: x += dw; ! 1563: y += dh; ! 1564: break; ! 1565: case StaticGravity: ! 1566: x = oldx; ! 1567: y = oldy; ! 1568: break; ! 1569: default: ! 1570: break; ! 1571: } ! 1572: ! 1573: (* pScreen->ValidateTree)(pParent, pFirstChange, TRUE, anyMarked); ! 1574: DoObscures(pParent); ! 1575: if (pWin->backStorage && (pWin->backingStore != NotUseful)) ! 1576: { ! 1577: ErrorF("Going to translate backing store %d %d\n", ! 1578: oldx - x, oldy - y); ! 1579: (* pWin->backStorage->TranslateBackingStore) (pWin, ! 1580: oldx - x, oldy - y); ! 1581: } ! 1582: oldpt.x = oldx - x + pWin->absCorner.x; ! 1583: oldpt.y = oldy - y + pWin->absCorner.y; ! 1584: (* pWin->CopyWindow)(pWin, oldpt, oldRegion); ! 1585: ! 1586: ! 1587: /* Note that oldRegion is *translated* by CopyWindow */ ! 1588: ! 1589: /* ! 1590: * We've taken care of those spots in oldRegion so they needn't ! 1591: * be re-exposed... ! 1592: */ ! 1593: (* pScreen->Subtract)(pWin->exposed, pWin->clipList, oldRegion); ! 1594: (* pScreen->RegionDestroy)(pRegion); ! 1595: ! 1596: /* CopyWindow will step on borders, so repaint them */ ! 1597: (* pScreen->Subtract)(pWin->borderExposed, ! 1598: pWin->borderClip, pWin->winSize); ! 1599: ! 1600: HandleExposures(pParent); ! 1601: (* pScreen->RegionDestroy)(oldRegion); ! 1602: } ! 1603: } ! 1604: } ! 1605: ! 1606: static void ! 1607: ChangeBorderWidth(pWin, width) ! 1608: WindowPtr pWin; ! 1609: int width; ! 1610: { ! 1611: WindowPtr pParent; ! 1612: BoxRec box; ! 1613: BoxPtr pBox; ! 1614: int oldwidth; ! 1615: Bool anyMarked; ! 1616: register ScreenPtr pScreen; ! 1617: RegionPtr oldRegion; ! 1618: DDXPointRec oldpt; ! 1619: Bool WasMapped = (Bool)(pWin->realized); ! 1620: ! 1621: oldwidth = pWin->borderWidth; ! 1622: if (oldwidth == width) ! 1623: return ; ! 1624: pScreen = pWin->drawable.pScreen; ! 1625: pParent = pWin->parent; ! 1626: pWin->borderWidth = width; ! 1627: ! 1628: oldpt.x = pWin->absCorner.x; ! 1629: oldpt.y = pWin->absCorner.y; ! 1630: pWin->oldAbsCorner.x = oldpt.x; ! 1631: pWin->oldAbsCorner.y = oldpt.y; ! 1632: ! 1633: pWin->clientWinSize.x += width - oldwidth; ! 1634: pWin->clientWinSize.y += width - oldwidth; ! 1635: pWin->absCorner.x += width - oldwidth; ! 1636: pWin->absCorner.y += width - oldwidth; ! 1637: ! 1638: if (WasMapped) ! 1639: { ! 1640: oldRegion = (* pScreen->RegionCreate)(NULL, 1); ! 1641: (* pScreen->RegionCopy)(oldRegion, pWin->borderClip); ! 1642: } ! 1643: ! 1644: ! 1645: box.x1 = pWin->absCorner.x; ! 1646: box.y1 = pWin->absCorner.y; ! 1647: box.x2 = box.x1 + pWin->clientWinSize.width; ! 1648: box.y2 = box.y1 + pWin->clientWinSize.height; ! 1649: (* pScreen->RegionReset)(pWin->winSize, &box); ! 1650: (* pScreen->Intersect)(pWin->winSize, pWin->winSize, pParent->winSize); ! 1651: ! 1652: if (width) ! 1653: { ! 1654: box.x1 -= width; ! 1655: box.y1 -= width; ! 1656: box.x2 += width; ! 1657: box.y2 += width; ! 1658: (* pScreen->RegionReset)(pWin->borderSize, &box); ! 1659: (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize, ! 1660: pParent->winSize); ! 1661: } ! 1662: else ! 1663: (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize); ! 1664: ! 1665: if (WasMapped) ! 1666: { ! 1667: if (width < oldwidth) ! 1668: pBox = (* pScreen->RegionExtents)(oldRegion); ! 1669: else ! 1670: pBox = (* pScreen->RegionExtents)(pWin->borderSize); ! 1671: anyMarked = MarkSiblingsBelowMe(pWin, pBox); ! 1672: ! 1673: (* pScreen->ValidateTree)(pParent,(anyMarked ? pWin : (WindowPtr)NULL), ! 1674: TRUE, anyMarked ); ! 1675: ! 1676: (* pWin->CopyWindow)(pWin, oldpt, oldRegion); ! 1677: ! 1678: if (width > oldwidth) ! 1679: { ! 1680: DoObscures(pParent); ! 1681: (* pScreen->Subtract)(pWin->borderExposed, ! 1682: pWin->borderClip, pWin->winSize); ! 1683: (* pWin->PaintWindowBorder)(pWin, pWin->borderExposed, PW_BORDER); ! 1684: (* pScreen->RegionEmpty)(pWin->borderExposed); ! 1685: } ! 1686: else if (oldwidth > width) ! 1687: HandleExposures(pParent); ! 1688: ! 1689: (* pScreen->RegionDestroy)(oldRegion); ! 1690: ! 1691: } ! 1692: } ! 1693: ! 1694: ! 1695: #define GET_INT16(m, f) \ ! 1696: if (m & mask) \ ! 1697: { \ ! 1698: f = (short) *pVlist;\ ! 1699: pVlist++; \ ! 1700: } ! 1701: #define GET_CARD16(m, f) \ ! 1702: if (m & mask) \ ! 1703: { \ ! 1704: f = (CARD16) *pVlist;\ ! 1705: pVlist++;\ ! 1706: } ! 1707: ! 1708: #define GET_CARD8(m, f) \ ! 1709: if (m & mask) \ ! 1710: { \ ! 1711: f = (CARD8) *pVlist;\ ! 1712: pVlist++;\ ! 1713: } ! 1714: ! 1715: #define ChangeMask (CWX | CWY | CWWidth | CWHeight) ! 1716: ! 1717: #define IllegalInputOnlyConfigureMask (CWBorderWidth) ! 1718: ! 1719: /* ! 1720: * IsSiblingAboveMe ! 1721: * returns Above if pSib above pMe in stack or Below otherwise ! 1722: */ ! 1723: ! 1724: static int ! 1725: IsSiblingAboveMe(pMe, pSib) ! 1726: WindowPtr pMe, pSib; ! 1727: { ! 1728: WindowPtr pWin; ! 1729: ! 1730: pWin = pMe->parent->firstChild; ! 1731: while (pWin) ! 1732: { ! 1733: if (pWin == pSib) ! 1734: return(Above); ! 1735: else if (pWin == pMe) ! 1736: return(Below); ! 1737: pWin = pWin->nextSib; ! 1738: } ! 1739: return(Below); ! 1740: } ! 1741: ! 1742: static Bool ! 1743: AnyWindowOverlapsMe(pWin, box) ! 1744: WindowPtr pWin; ! 1745: BoxPtr box; ! 1746: { ! 1747: WindowPtr pSib; ! 1748: register ScreenPtr pScreen; ! 1749: ! 1750: pSib = pWin->parent->firstChild; ! 1751: pScreen = pWin->drawable.pScreen; ! 1752: while (pSib) ! 1753: { ! 1754: if (pSib == pWin) ! 1755: return(FALSE); ! 1756: else if ((pSib->mapped) && ! 1757: ((* pScreen->RectIn)(pSib->borderSize, box) != rgnOUT)) ! 1758: return(TRUE); ! 1759: pSib = pSib->nextSib; ! 1760: } ! 1761: return(FALSE); ! 1762: } ! 1763: ! 1764: static WindowPtr ! 1765: IOverlapAnyWindow(pWin, box) ! 1766: WindowPtr pWin; ! 1767: BoxPtr box; ! 1768: { ! 1769: WindowPtr pSib; ! 1770: register ScreenPtr pScreen; ! 1771: ! 1772: pScreen = pWin->drawable.pScreen; ! 1773: pSib = pWin->nextSib; ! 1774: while (pSib) ! 1775: { ! 1776: if ((pSib->mapped) && ! 1777: ((* pScreen->RectIn)(pSib->borderSize, box) != rgnOUT)) ! 1778: return(pSib); ! 1779: pSib = pSib->nextSib; ! 1780: } ! 1781: return((WindowPtr )NULL); ! 1782: } ! 1783: ! 1784: /* ! 1785: * WhereDoIGoInTheStack() ! 1786: * Given pWin and pSib and the relationshipe smode, return ! 1787: * the window that pWin should go ABOVE. ! 1788: * If a pSib is specified: ! 1789: * Above: pWin is placed just above pSib ! 1790: * Below: pWin is placed just below pSib ! 1791: * TopIf: if pSib occludes pWin, then pWin is placed ! 1792: * at the top of the stack ! 1793: * BottomIf: if pWin occludes pSib, then pWin is ! 1794: * placed at the bottom of the stack ! 1795: * Opposite: if pSib occludes pWin, then pWin is placed at the ! 1796: * top of the stack, else if pWin occludes pSib, then ! 1797: * pWin is placed at the bottom of the stack ! 1798: * ! 1799: * If pSib is NULL: ! 1800: * Above: pWin is placed at the top of the stack ! 1801: * Below: pWin is placed at the bottom of the stack ! 1802: * TopIf: if any sibling occludes pWin, then pWin is placed at ! 1803: * the top of the stack ! 1804: * BottomIf: if pWin occludes any sibline, then pWin is placed at ! 1805: * the bottom of the stack ! 1806: * Opposite: if any sibling occludes pWin, then pWin is placed at ! 1807: * the top of the stack, else if pWin occludes any ! 1808: * sibling, then pWin is placed at the bottom of the stack ! 1809: * ! 1810: */ ! 1811: ! 1812: static WindowPtr ! 1813: WhereDoIGoInTheStack(pWin, pSib, x, y, w, h, smode) ! 1814: WindowPtr pWin, pSib; ! 1815: short x, y, w, h; ! 1816: int smode; ! 1817: { ! 1818: BoxRec box; ! 1819: register ScreenPtr pScreen; ! 1820: ! 1821: if ((pWin == pWin->parent->firstChild) && ! 1822: (pWin == pWin->parent->lastChild)) ! 1823: return((WindowPtr ) NULL); ! 1824: pScreen = pWin->drawable.pScreen; ! 1825: box.x1 = x; ! 1826: box.y1 = y; ! 1827: box.x2= x + w; ! 1828: box.y2 = y + h; ! 1829: switch (smode) ! 1830: { ! 1831: case Above: ! 1832: if (pSib) ! 1833: return(pSib); ! 1834: else if (pWin == pWin->parent->firstChild) ! 1835: return(pWin->nextSib); ! 1836: else ! 1837: return(pWin->parent->firstChild); ! 1838: case Below: ! 1839: if (pSib) ! 1840: if (pSib->nextSib != pWin) ! 1841: return(pSib->nextSib); ! 1842: else ! 1843: return(pWin->nextSib); ! 1844: else ! 1845: return((WindowPtr )NULL); ! 1846: case TopIf: ! 1847: if (pSib) ! 1848: { ! 1849: if ((IsSiblingAboveMe(pWin, pSib) == Above) && ! 1850: ((* pScreen->RectIn)(pSib->borderSize, &box) != rgnOUT)) ! 1851: return(pWin->parent->firstChild); ! 1852: else ! 1853: return(pWin->nextSib); ! 1854: } ! 1855: else if (AnyWindowOverlapsMe(pWin, &box)) ! 1856: return(pWin->parent->firstChild); ! 1857: else ! 1858: return(pWin->nextSib); ! 1859: case BottomIf: ! 1860: if (pSib) ! 1861: { ! 1862: if ((IsSiblingAboveMe(pWin, pSib) == Below) && ! 1863: ((* pScreen->RectIn)(pSib->borderSize, &box) != rgnOUT)) ! 1864: return(WindowPtr)NULL; ! 1865: else ! 1866: return(pWin->nextSib); ! 1867: } ! 1868: else if (IOverlapAnyWindow(pWin, &box)) ! 1869: return((WindowPtr)NULL); ! 1870: else ! 1871: return(pWin->nextSib); ! 1872: case Opposite: ! 1873: if (pSib) ! 1874: { ! 1875: if ((* pScreen->RectIn)(pSib->borderSize, &box) != rgnOUT) ! 1876: { ! 1877: if (IsSiblingAboveMe(pWin, pSib) == Above) ! 1878: return(pWin->parent->firstChild); ! 1879: else ! 1880: return((WindowPtr)NULL); ! 1881: } ! 1882: else ! 1883: return(pWin->nextSib); ! 1884: } ! 1885: else if (AnyWindowOverlapsMe(pWin, &box)) ! 1886: { ! 1887: /* If I'm occluded, I can't possibly be the first child ! 1888: * if (pWin == pWin->parent->firstChild) ! 1889: * return pWin->nextSib; ! 1890: */ ! 1891: return(pWin->parent->firstChild); ! 1892: } ! 1893: else if (IOverlapAnyWindow(pWin, &box)) ! 1894: return((WindowPtr)NULL); ! 1895: else ! 1896: return pWin->nextSib; ! 1897: default: ! 1898: { ! 1899: ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode ); ! 1900: return((WindowPtr)pWin->nextSib); ! 1901: } ! 1902: } ! 1903: } ! 1904: ! 1905: static void ! 1906: ReflectStackChange(pWin, pSib) ! 1907: WindowPtr pWin, pSib; ! 1908: { ! 1909: /* Note that pSib might be NULL */ ! 1910: ! 1911: Bool doValidation = (Bool)pWin->realized; ! 1912: WindowPtr pParent; ! 1913: int anyMarked; ! 1914: BoxPtr box; ! 1915: WindowPtr pFirstChange; ! 1916: ! 1917: /* if this is a root window, can't be restacked */ ! 1918: if (!(pParent = pWin->parent)) ! 1919: return ; ! 1920: ! 1921: pFirstChange = MoveWindowInStack(pWin, pSib); ! 1922: ! 1923: if (doValidation) ! 1924: { ! 1925: box = (* pWin->drawable.pScreen->RegionExtents)(pWin->borderSize); ! 1926: anyMarked = MarkSiblingsBelowMe(pFirstChange, box); ! 1927: (* pWin->drawable.pScreen->ValidateTree)(pParent, pFirstChange, ! 1928: TRUE, anyMarked); ! 1929: DoObscures(pParent); ! 1930: HandleExposures(pParent); ! 1931: } ! 1932: } ! 1933: ! 1934: /***** ! 1935: * ConfigureWindow ! 1936: *****/ ! 1937: ! 1938: ! 1939: int ! 1940: ConfigureWindow(pWin, mask, vlist, client) ! 1941: WindowPtr pWin; ! 1942: unsigned long mask; ! 1943: long *vlist; ! 1944: ClientPtr client; ! 1945: { ! 1946: #define RESTACK_WIN 0 ! 1947: #define MOVE_WIN 1 ! 1948: #define RESIZE_WIN 2 ! 1949: WindowPtr pSib = (WindowPtr )NULL; ! 1950: Window sibwid; ! 1951: int index, tmask; ! 1952: long *pVlist; ! 1953: short x, y, beforeX, beforeY; ! 1954: unsigned short w = pWin->clientWinSize.width, ! 1955: h = pWin->clientWinSize.height, ! 1956: bw = pWin->borderWidth; ! 1957: int action, ! 1958: smode = Above; ! 1959: xEvent event; ! 1960: ! 1961: if ((pWin->class == InputOnly) && (mask & IllegalInputOnlyConfigureMask)) ! 1962: return(BadMatch); ! 1963: ! 1964: if ((mask & CWSibling) && !(mask & CWStackMode)) ! 1965: return(BadMatch); ! 1966: ! 1967: pVlist = vlist; ! 1968: ! 1969: if (pWin->parent) ! 1970: { ! 1971: x = pWin->absCorner.x - pWin->parent->absCorner.x - bw; ! 1972: y = pWin->absCorner.y - pWin->parent->absCorner.y - bw; ! 1973: } ! 1974: else ! 1975: { ! 1976: x = pWin->absCorner.x; ! 1977: y = pWin->absCorner.y; ! 1978: } ! 1979: beforeX = x; ! 1980: beforeY = y; ! 1981: action = RESTACK_WIN; ! 1982: if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth)))) ! 1983: { ! 1984: GET_INT16(CWX, x); ! 1985: GET_INT16(CWY, y); ! 1986: action = MOVE_WIN; ! 1987: } ! 1988: /* or should be resized */ ! 1989: else if (mask & (CWX | CWY | CWWidth | CWHeight)) ! 1990: { ! 1991: GET_INT16(CWX, x); ! 1992: GET_INT16(CWY, y); ! 1993: GET_CARD16(CWWidth, w); ! 1994: GET_CARD16 (CWHeight, h); ! 1995: if (!w || !h) ! 1996: return BadValue; ! 1997: action = RESIZE_WIN; ! 1998: } ! 1999: tmask = mask & ~ChangeMask; ! 2000: while (tmask) ! 2001: { ! 2002: index = ffs(tmask) - 1; ! 2003: tmask &= ~(index = (1 << index)); ! 2004: switch (index) ! 2005: { ! 2006: case CWBorderWidth: ! 2007: GET_CARD16(CWBorderWidth, bw); ! 2008: break; ! 2009: case CWSibling: ! 2010: sibwid = (Window ) *pVlist; ! 2011: pVlist++; ! 2012: pSib = (WindowPtr )LookupID(sibwid, RT_WINDOW, RC_CORE); ! 2013: if (!pSib) ! 2014: return(BadWindow); ! 2015: if (pSib->parent != pWin->parent) ! 2016: return(BadMatch); ! 2017: if (pSib == pWin) ! 2018: return(BadMatch); ! 2019: break; ! 2020: case CWStackMode: ! 2021: GET_CARD8(CWStackMode, smode); ! 2022: if ((smode != TopIf) && (smode != BottomIf) && ! 2023: (smode != Opposite) && (smode != Above) && (smode != Below)) ! 2024: return(BadMatch); ! 2025: break; ! 2026: default: ! 2027: return(BadMatch); ! 2028: } ! 2029: } ! 2030: /* root really can't be reconfigured, so just return */ ! 2031: if (!pWin->parent) ! 2032: return Success; ! 2033: ! 2034: /* Figure out if the window should be moved. Doesnt ! 2035: make the changes to the window if event sent */ ! 2036: ! 2037: if (mask & CWStackMode) ! 2038: pSib = WhereDoIGoInTheStack(pWin, pSib, x, y, w, h, smode); ! 2039: else ! 2040: pSib = pWin->nextSib; ! 2041: ! 2042: if ((!pWin->overrideRedirect) && ! 2043: (pWin->parent->allEventMasks & SubstructureRedirectMask)) ! 2044: { ! 2045: event.u.u.type = ConfigureRequest; ! 2046: event.u.configureRequest.window = pWin->wid; ! 2047: event.u.configureRequest.parent = pWin->parent->wid; ! 2048: if (mask & CWSibling) ! 2049: event.u.configureRequest.sibling = sibwid; ! 2050: else ! 2051: event.u.configureRequest.sibling = None; ! 2052: if (mask & CWStackMode) ! 2053: event.u.u.detail = smode; ! 2054: else ! 2055: event.u.u.detail = Above; ! 2056: event.u.configureRequest.x = x; ! 2057: event.u.configureRequest.y = y; ! 2058: event.u.configureRequest.width = w; ! 2059: event.u.configureRequest.height = h; ! 2060: event.u.configureRequest.borderWidth = bw; ! 2061: event.u.configureRequest.valueMask = mask; ! 2062: if (MaybeDeliverEventsToClient(pWin->parent, &event, 1, ! 2063: SubstructureRedirectMask, client) == 1) ! 2064: return(Success); ! 2065: } ! 2066: if (action == RESIZE_WIN) { ! 2067: Bool size_change = (w != pWin->clientWinSize.width) ! 2068: || (h != pWin->clientWinSize.height); ! 2069: if (size_change && (pWin->allEventMasks & ResizeRedirectMask)) { ! 2070: xEvent eventT; ! 2071: eventT.u.u.type = ResizeRequest; ! 2072: eventT.u.resizeRequest.window = pWin->wid; ! 2073: eventT.u.resizeRequest.width = w; ! 2074: eventT.u.resizeRequest.height = h; ! 2075: if (MaybeDeliverEventsToClient(pWin, &eventT, 1, ! 2076: ResizeRedirectMask, client) == 1) { ! 2077: /* if event is delivered, leave the actual size alone. */ ! 2078: w = pWin->clientWinSize.width; ! 2079: h = pWin->clientWinSize.height; ! 2080: size_change = FALSE; ! 2081: } ! 2082: } ! 2083: if (!size_change) { ! 2084: if (mask & (CWX | CWY)) ! 2085: action = MOVE_WIN; ! 2086: else if (mask & (CWStackMode | CWSibling | CWBorderWidth)) ! 2087: action = RESTACK_WIN; ! 2088: else /* really nothing to do */ ! 2089: return(Success) ; ! 2090: } ! 2091: } ! 2092: ! 2093: if (action == RESIZE_WIN) ! 2094: /* we've already checked whether there's really a size change */ ! 2095: goto ActuallyDoSomething; ! 2096: if ((mask & CWX) && (x != beforeX)) ! 2097: goto ActuallyDoSomething; ! 2098: if ((mask & CWY) && (y != beforeY)) ! 2099: goto ActuallyDoSomething; ! 2100: if ((mask & CWBorderWidth) && (bw != pWin->borderWidth)) ! 2101: goto ActuallyDoSomething; ! 2102: if (mask & CWStackMode) ! 2103: { ! 2104: if (pWin->nextSib != pSib) ! 2105: goto ActuallyDoSomething; ! 2106: } ! 2107: return(Success); ! 2108: ! 2109: ActuallyDoSomething: ! 2110: event.u.u.type = ConfigureNotify; ! 2111: event.u.configureNotify.window = pWin->wid; ! 2112: if (pSib) ! 2113: event.u.configureNotify.aboveSibling = pSib->wid; ! 2114: else ! 2115: event.u.configureNotify.aboveSibling = None; ! 2116: event.u.configureNotify.x = x; ! 2117: event.u.configureNotify.y = y; ! 2118: event.u.configureNotify.width = w; ! 2119: event.u.configureNotify.height = h; ! 2120: event.u.configureNotify.borderWidth = bw; ! 2121: event.u.configureNotify.override = pWin->overrideRedirect; ! 2122: DeliverEvents(pWin, &event, 1, NullWindow); ! 2123: ! 2124: if (mask & CWBorderWidth) ! 2125: { ! 2126: if (action == RESTACK_WIN) ! 2127: ChangeBorderWidth(pWin, bw); ! 2128: else ! 2129: pWin->borderWidth = bw; ! 2130: } ! 2131: if (action == MOVE_WIN) ! 2132: MoveWindow(pWin, x, y, pSib); ! 2133: else if (action == RESIZE_WIN) ! 2134: SlideAndSizeWindow(pWin, x, y, w, h, pSib); ! 2135: else if (mask & CWStackMode) ! 2136: ReflectStackChange(pWin, pSib); ! 2137: ! 2138: return(Success); ! 2139: #undef RESTACK_WIN ! 2140: #undef MOVE_WIN ! 2141: #undef RESIZE_WIN ! 2142: } ! 2143: ! 2144: ! 2145: /****** ! 2146: * ! 2147: * CirculateWindow ! 2148: * For RaiseLowest, raises the lowest mapped child (if any) that is ! 2149: * obscured by another child to the top of the stack. For LowerHighest, ! 2150: * lowers the highest mapped child (if any) that is obscuring another ! 2151: * child to the bottom of the stack. Exposure processing is performed ! 2152: * ! 2153: ******/ ! 2154: ! 2155: /* XXX shouldn't this be a case for the stack mode stuff?? */ ! 2156: ! 2157: int ! 2158: CirculateWindow(pParent, direction, client) ! 2159: WindowPtr pParent; ! 2160: int direction; ! 2161: ClientPtr client; ! 2162: { ! 2163: WindowPtr pChild, pSib; ! 2164: xEvent event; ! 2165: register ScreenPtr pScreen; ! 2166: ! 2167: if (pParent->firstChild == pParent->lastChild) ! 2168: return(Success) ; ! 2169: ! 2170: pScreen = pParent->drawable.pScreen; ! 2171: if (direction == RaiseLowest) ! 2172: { ! 2173: pChild = pParent->lastChild; ! 2174: while (pChild) ! 2175: { ! 2176: if (pChild->mapped && (pChild->visibility != VisibilityUnobscured)) ! 2177: { ! 2178: if (pParent->firstChild != pChild) ! 2179: { ! 2180: if (pParent->lastChild == pChild) ! 2181: pParent->lastChild = pChild->prevSib; ! 2182: if (pChild->nextSib) ! 2183: pChild->nextSib->prevSib = pChild->prevSib; ! 2184: if (pChild->prevSib) ! 2185: pChild->prevSib->nextSib = pChild->nextSib; ! 2186: pChild->nextSib = pParent->firstChild; ! 2187: pChild->prevSib = (WindowPtr ) NULL; ! 2188: pParent->firstChild->prevSib = pChild; ! 2189: pParent->firstChild = pChild; ! 2190: pChild->mapped = 0; /* to fool MapWindow */ ! 2191: pSib = pChild; ! 2192: break; ! 2193: } ! 2194: return Success; ! 2195: } ! 2196: pChild = pChild->prevSib; ! 2197: } ! 2198: } ! 2199: else if (direction == LowerHighest) ! 2200: { ! 2201: BoxPtr pBox; ! 2202: ! 2203: pChild = pParent->firstChild; ! 2204: while (pChild) ! 2205: { ! 2206: if (pChild->mapped && (pChild->visibility == VisibilityUnobscured)) ! 2207: { ! 2208: int result; ! 2209: ! 2210: /* HACK -- this search is n squared */ ! 2211: ! 2212: pSib = pChild->nextSib; ! 2213: ! 2214: /* find a sibling that pChild overlaps */ ! 2215: ! 2216: pBox = (* pScreen->RegionExtents)(pChild->borderSize); ! 2217: while (pSib) ! 2218: { ! 2219: if (pSib->realized && (pSib->visibility != VisibilityUnobscured)) ! 2220: { ! 2221: result = (* pScreen->RectIn)(pSib->borderSize, ! 2222: &pBox); ! 2223: if (result != rgnOUT) ! 2224: break; ! 2225: } ! 2226: pSib = pSib->nextSib; ! 2227: } ! 2228: if (pSib) ! 2229: { ! 2230: WindowPtr pNext; ! 2231: pNext = pChild->nextSib; ! 2232: if (pParent->firstChild == pChild) ! 2233: pParent->firstChild = pNext; ! 2234: pNext->prevSib = pChild->prevSib; ! 2235: if (pChild->prevSib) ! 2236: pChild->prevSib->nextSib = pNext; ! 2237: pChild->nextSib = (WindowPtr ) NULL; ! 2238: pChild->prevSib = pParent->lastChild; ! 2239: pParent->lastChild->nextSib = pChild; ! 2240: pParent->lastChild = pChild; ! 2241: pSib->mapped = 0; /* to fool mapWindow */ ! 2242: break; ! 2243: } ! 2244: } ! 2245: pChild = pChild->nextSib; ! 2246: } ! 2247: } ! 2248: if (!pChild) ! 2249: return(Success) ; ! 2250: event.u.circulate.window = pChild->wid; ! 2251: event.u.circulate.parent = pParent->wid; ! 2252: event.u.circulate.event = pParent->wid; ! 2253: if (direction == RaiseLowest) ! 2254: event.u.circulate.place = PlaceOnTop; ! 2255: else ! 2256: event.u.circulate.place = PlaceOnBottom; ! 2257: ! 2258: if (pParent->allEventMasks & SubstructureRedirectMask) ! 2259: { ! 2260: event.u.u.type = CirculateRequest; ! 2261: if (MaybeDeliverEventsToClient(pParent, &event, 1, ! 2262: SubstructureRedirectMask, client) == 1) ! 2263: return(Success); ! 2264: } ! 2265: if (pParent->realized) ! 2266: MapWindow(pSib, HANDLE_EXPOSURES, BITS_DISCARDED, ! 2267: DONT_SEND_NOTIFICATION, client); ! 2268: event.u.u.type = CirculateNotify; ! 2269: DeliverEvents(pParent, &event, 1, NullWindow); ! 2270: return(Success); ! 2271: } ! 2272: ! 2273: /***** ! 2274: * ReparentWindow ! 2275: *****/ ! 2276: ! 2277: static int ! 2278: CompareWIDs(pWin, wid) ! 2279: WindowPtr pWin; ! 2280: int *wid; ! 2281: { ! 2282: if (pWin->wid == *wid) ! 2283: return(WT_STOPWALKING); ! 2284: else ! 2285: return(WT_WALKCHILDREN); ! 2286: } ! 2287: ! 2288: int ! 2289: ReparentWindow(pWin, pParent, x, y, client) ! 2290: WindowPtr pWin, pParent; ! 2291: short x,y; ! 2292: ClientPtr client; ! 2293: { ! 2294: WindowPtr pPrev; ! 2295: Bool WasMapped = (Bool)(pWin->realized); ! 2296: BoxRec box; ! 2297: xEvent event; ! 2298: short oldx, oldy; ! 2299: int bw; ! 2300: register ScreenPtr pScreen; ! 2301: ! 2302: if (pWin == pParent) ! 2303: return(BadWindow); ! 2304: if (TraverseTree(pWin, CompareWIDs, &pParent->wid) == WT_STOPWALKING) ! 2305: return(BadWindow); ! 2306: ! 2307: pScreen = pWin->drawable.pScreen; ! 2308: event.u.u.type = ReparentNotify; ! 2309: event.u.reparent.window = pWin->wid; ! 2310: event.u.reparent.parent = pParent->wid; ! 2311: event.u.reparent.x = x; ! 2312: event.u.reparent.y = y; ! 2313: event.u.reparent.override = pWin->overrideRedirect; ! 2314: DeliverEvents(pWin, &event, 1, pParent); ! 2315: ! 2316: oldx = pWin->absCorner.x; ! 2317: oldy = pWin->absCorner.y; ! 2318: if (WasMapped) ! 2319: UnmapWindow(pWin, HANDLE_EXPOSURES, SEND_NOTIFICATION, FALSE); ! 2320: ! 2321: /* take out of sibling chain */ ! 2322: ! 2323: pPrev = pWin->parent; ! 2324: if (pPrev->firstChild == pWin) ! 2325: pPrev->firstChild = pWin->nextSib; ! 2326: if (pPrev->lastChild == pWin) ! 2327: pPrev->lastChild = pWin->prevSib; ! 2328: ! 2329: if (pWin->nextSib) ! 2330: pWin->nextSib->prevSib = pWin->prevSib; ! 2331: if (pWin->prevSib) ! 2332: pWin->prevSib->nextSib = pWin->nextSib; ! 2333: ! 2334: /* insert at begining of pParent */ ! 2335: pWin->parent = pParent; ! 2336: pWin->nextSib = pParent->firstChild; ! 2337: pWin->prevSib = (WindowPtr )NULL; ! 2338: if (pParent->firstChild) ! 2339: pParent->firstChild->prevSib = pWin; ! 2340: else ! 2341: pParent->lastChild = pWin; ! 2342: pParent->firstChild = pWin; ! 2343: ! 2344: /* clip to parent */ ! 2345: box.x1 = x + pParent->absCorner.x; ! 2346: box.y1 = y + pParent->absCorner.y; ! 2347: box.x2 = box.x1 + pWin->clientWinSize.width; ! 2348: box.y2 = box.y1+ pWin->clientWinSize.height; ! 2349: (* pScreen->RegionReset)(pWin->winSize, &box); ! 2350: (* pScreen->Intersect)(pWin->winSize, pWin->winSize, ! 2351: pParent->winSize); ! 2352: ! 2353: pWin->clientWinSize.x = x; ! 2354: pWin->clientWinSize.y = y; ! 2355: pWin->oldAbsCorner.x = oldx; ! 2356: pWin->oldAbsCorner.y = oldy; ! 2357: pWin->absCorner.x = box.x1; ! 2358: pWin->absCorner.y = box.y1; ! 2359: ! 2360: if (bw = pWin->borderWidth) ! 2361: { ! 2362: box.x1 -= bw; ! 2363: box.y1 -= bw; ! 2364: box.x2 += bw; ! 2365: box.y2 += bw; ! 2366: (* pScreen->RegionReset)(pWin->borderSize, &box); ! 2367: (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize, ! 2368: pParent->winSize); ! 2369: } ! 2370: else ! 2371: (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize); ! 2372: ! 2373: (* pScreen->PositionWindow)(pWin, pWin->absCorner.x, pWin->absCorner.y); ! 2374: ResizeChildrenWinSize(pWin, FALSE, 0, 0, DONT_USE_GRAVITY); ! 2375: ! 2376: if (WasMapped) ! 2377: { ! 2378: MapWindow(pWin, HANDLE_EXPOSURES, BITS_DISCARDED, SEND_NOTIFICATION, ! 2379: client); ! 2380: } ! 2381: RecalculateDeliverableEvents(pParent); ! 2382: return(Success); ! 2383: } ! 2384: ! 2385: static int ! 2386: MarkChildren(pWin, box) ! 2387: WindowPtr pWin; ! 2388: BoxPtr box; ! 2389: { ! 2390: WindowPtr pChild; ! 2391: int anyMarked=0; ! 2392: register ScreenPtr pScreen; ! 2393: ! 2394: pScreen = pWin->drawable.pScreen; ! 2395: pChild = pWin->firstChild; ! 2396: while (pChild) ! 2397: { ! 2398: if (pChild->mapped && ((* pScreen->RectIn)(pChild->borderSize, box))) ! 2399: { ! 2400: anyMarked++; ! 2401: pChild->marked = 1; ! 2402: anyMarked += MarkChildren(pChild, box); ! 2403: } ! 2404: pChild = pChild->nextSib; ! 2405: } ! 2406: return(anyMarked); ! 2407: } ! 2408: ! 2409: static int ! 2410: MarkSiblingsBelowMe(pWin, box) ! 2411: WindowPtr pWin; ! 2412: BoxPtr box; ! 2413: { ! 2414: WindowPtr pSib; ! 2415: int anyMarked = 0; ! 2416: register ScreenPtr pScreen; ! 2417: ! 2418: pScreen = pWin->drawable.pScreen; ! 2419: ! 2420: pSib = pWin; ! 2421: while (pSib) ! 2422: { ! 2423: if (pSib->mapped && ((* pScreen->RectIn)(pSib->borderSize, box))) ! 2424: { ! 2425: pSib->marked = 1; ! 2426: anyMarked++; ! 2427: if (pSib->firstChild) ! 2428: anyMarked += MarkChildren(pSib, box); ! 2429: } ! 2430: pSib = pSib->nextSib; ! 2431: } ! 2432: return(anyMarked); ! 2433: } ! 2434: ! 2435: ! 2436: /***** ! 2437: * MapWindow ! 2438: * If some other client has selected SubStructureReDirect on the parent ! 2439: * and override-redirect is xFalse, then a MapRequest event is generated, ! 2440: * but the window remains unmapped. Otherwise, the window is mapped and a ! 2441: * MapNotify event is generated. ! 2442: *****/ ! 2443: ! 2444: static void ! 2445: RealizeChildren(pWin, client) ! 2446: WindowPtr pWin; ! 2447: ClientPtr client; ! 2448: { ! 2449: WindowPtr pSib; ! 2450: Bool (* Realize)(); ! 2451: ! 2452: pSib = pWin; ! 2453: if (pWin) ! 2454: Realize = pSib->drawable.pScreen->RealizeWindow; ! 2455: while (pSib) ! 2456: { ! 2457: if (pSib->mapped) ! 2458: { ! 2459: pSib->realized = TRUE; ! 2460: pSib->viewable = pSib->class == InputOutput; ! 2461: (* Realize)(pSib); ! 2462: FlushClientCaches(pSib->wid); ! 2463: if (pSib->firstChild) ! 2464: RealizeChildren(pSib->firstChild, client); ! 2465: } ! 2466: pSib = pSib->nextSib; ! 2467: } ! 2468: } ! 2469: ! 2470: int ! 2471: MapWindow(pWin, SendExposures, BitsAvailable, SendNotification, client) ! 2472: ! 2473: WindowPtr pWin; ! 2474: Bool SendExposures; ! 2475: Bool BitsAvailable; ! 2476: ClientPtr client; ! 2477: { ! 2478: register ScreenPtr pScreen; ! 2479: ! 2480: WindowPtr pParent; ! 2481: Bool anyMarked; ! 2482: ! 2483: if (pWin->mapped) ! 2484: return(Success); ! 2485: pScreen = pWin->drawable.pScreen; ! 2486: if (pParent = pWin->parent) ! 2487: { ! 2488: xEvent event; ! 2489: BoxPtr box; ! 2490: ! 2491: if (SendNotification && (!pWin->overrideRedirect) && ! 2492: (pParent->allEventMasks & SubstructureRedirectMask)) ! 2493: { ! 2494: event.u.u.type = MapRequest; ! 2495: event.u.mapRequest.window = pWin->wid; ! 2496: event.u.mapRequest.parent = pParent->wid; ! 2497: ! 2498: if (MaybeDeliverEventsToClient(pParent, &event, 1, ! 2499: SubstructureRedirectMask, client) == 1) ! 2500: return(Success); ! 2501: } ! 2502: ! 2503: pWin->mapped = 1; ! 2504: if (SendNotification) ! 2505: { ! 2506: event.u.u.type = MapNotify; ! 2507: event.u.mapNotify.window = pWin->wid; ! 2508: event.u.mapNotify.override = pWin->overrideRedirect; ! 2509: DeliverEvents(pWin, &event, 1, NullWindow); ! 2510: } ! 2511: ! 2512: pWin->marked = 0; /* so siblings get mapped correctly */ ! 2513: if (!pParent->realized) ! 2514: return(Success); ! 2515: pWin->realized = TRUE; ! 2516: pWin->viewable = pWin->class == InputOutput; ! 2517: /* We SHOULD check for an error value here XXX */ ! 2518: (* pScreen->RealizeWindow)(pWin); ! 2519: if (pWin->firstChild) ! 2520: RealizeChildren(pWin->firstChild, client); ! 2521: box = (* pScreen->RegionExtents)(pWin->borderSize); ! 2522: anyMarked = MarkSiblingsBelowMe(pWin, box); ! 2523: ! 2524: /* kludge; remove when miregion works! */ ! 2525: if (!pParent->parent && ! 2526: (box->x1 == pParent->winSize->extents.x1) && ! 2527: (box->y1 == pParent->winSize->extents.y1) && ! 2528: (box->x2 == pParent->winSize->extents.x2) && ! 2529: (box->y2 == pParent->winSize->extents.y2) && ! 2530: (pParent->firstChild == pWin)) { ! 2531: (*pWin->drawable.pScreen->RegionCopy)(pParent->clipList, ! 2532: pParent->winSize); ! 2533: } ! 2534: /* end of kludge */ ! 2535: ! 2536: (* pScreen->ValidateTree)(pParent, pWin, TRUE, anyMarked); ! 2537: if (SendExposures) ! 2538: { ! 2539: if (!BitsAvailable) ! 2540: { ! 2541: (* pScreen->RegionCopy)(pWin->exposed, pWin->clipList); ! 2542: DoObscures(pParent); ! 2543: HandleExposures(pWin); ! 2544: } ! 2545: else ! 2546: { ! 2547: /* ! 2548: * Children shouldn't be in the parent's exposed region... ! 2549: (* pScreen->Subtract)(pParent->exposed, pParent->exposed, ! 2550: pWin->borderSize); ! 2551: */ ! 2552: (* pScreen->RegionEmpty)(pWin->exposed); ! 2553: DoObscures(pParent); ! 2554: HandleExposures(pWin); ! 2555: } ! 2556: } ! 2557: } ! 2558: else ! 2559: { ! 2560: pWin->mapped = 1; ! 2561: pWin->realized = TRUE; /* for roots */ ! 2562: pWin->viewable = pWin->class == InputOutput; ! 2563: /* We SHOULD check for an error value here XXX */ ! 2564: (* pScreen->RealizeWindow)(pWin); ! 2565: } ! 2566: ! 2567: return(Success); ! 2568: } ! 2569: ! 2570: ! 2571: /***** ! 2572: * MapSubwindows ! 2573: * Performs a MapWindow all unmapped children of the window, in top ! 2574: * to bottom stacking order. ! 2575: *****/ ! 2576: ! 2577: MapSubwindows(pWin, SendExposures, client) ! 2578: WindowPtr pWin; ! 2579: Bool SendExposures; ! 2580: ClientPtr client; ! 2581: { ! 2582: WindowPtr pChild; ! 2583: ! 2584: pChild = pWin->firstChild; ! 2585: while (pChild) ! 2586: { ! 2587: if (!pChild->mapped) ! 2588: /* What about backing store? */ ! 2589: MapWindow(pChild, SendExposures, BITS_DISCARDED, ! 2590: SEND_NOTIFICATION, client); ! 2591: pChild = pChild->nextSib; ! 2592: } ! 2593: } ! 2594: ! 2595: /***** ! 2596: * UnmapWindow ! 2597: * If the window is already unmapped, this request has no effect. ! 2598: * Otherwise, the window is unmapped and an UnMapNotify event is ! 2599: * generated. Cannot unmap a root window. ! 2600: *****/ ! 2601: ! 2602: static void ! 2603: UnrealizeChildren(pWin) ! 2604: WindowPtr pWin; ! 2605: { ! 2606: WindowPtr pSib; ! 2607: void (*RegionEmpty)(); ! 2608: Bool (*Unrealize)(); ! 2609: ! 2610: pSib = pWin; ! 2611: if (pWin) ! 2612: { ! 2613: RegionEmpty = pWin->drawable.pScreen->RegionEmpty; ! 2614: Unrealize = pWin->drawable.pScreen->UnrealizeWindow; ! 2615: } ! 2616: while (pSib) ! 2617: { ! 2618: pSib->realized = pSib->viewable = FALSE; ! 2619: (* Unrealize)(pSib); ! 2620: /* to force exposures later */ ! 2621: (* RegionEmpty)(pSib->clipList); ! 2622: (* RegionEmpty)(pSib->borderClip); ! 2623: (* RegionEmpty)(pSib->exposed); ! 2624: pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; ! 2625: DeleteWindowFromAnyEvents(pSib, FALSE); ! 2626: if (pSib->firstChild) ! 2627: UnrealizeChildren(pSib->firstChild); ! 2628: pSib = pSib->nextSib; ! 2629: } ! 2630: } ! 2631: ! 2632: UnmapWindow(pWin, SendExposures, SendNotification, fromConfigure) ! 2633: WindowPtr pWin; ! 2634: Bool SendExposures, fromConfigure; ! 2635: { ! 2636: WindowPtr pParent; ! 2637: xEvent event; ! 2638: Bool anyMarked; ! 2639: Bool wasMapped = (Bool)pWin->realized; ! 2640: BoxPtr box; ! 2641: ! 2642: if ((!pWin->mapped) || (!(pParent = pWin->parent))) ! 2643: return(Success); ! 2644: if (SendNotification) ! 2645: { ! 2646: event.u.u.type = UnmapNotify; ! 2647: event.u.unmapNotify.window = pWin->wid; ! 2648: event.u.unmapNotify.fromConfigure = fromConfigure; ! 2649: DeliverEvents(pWin, &event, 1, NullWindow); ! 2650: } ! 2651: if (wasMapped) ! 2652: { ! 2653: box = (* pWin->drawable.pScreen->RegionExtents)(pWin->borderSize); ! 2654: anyMarked = MarkSiblingsBelowMe(pWin, box); ! 2655: } ! 2656: pWin->mapped = 0; ! 2657: pWin->realized = pWin->viewable = FALSE; ! 2658: if (wasMapped) ! 2659: { ! 2660: /* We SHOULD check for an error value here XXX */ ! 2661: (* pWin->drawable.pScreen->UnrealizeWindow)(pWin); ! 2662: DeleteWindowFromAnyEvents(pWin, FALSE); ! 2663: if (pWin->firstChild) ! 2664: UnrealizeChildren(pWin->firstChild); ! 2665: (* pWin->drawable.pScreen->ValidateTree)(pParent, pWin, ! 2666: TRUE, anyMarked); ! 2667: if (SendExposures) ! 2668: { ! 2669: HandleExposures(pParent); ! 2670: } ! 2671: } ! 2672: return(Success); ! 2673: } ! 2674: ! 2675: /***** ! 2676: * UnmapSubwindows ! 2677: * Performs an UnMapWindow request with the specified mode on all mapped ! 2678: * children of the window, in bottom to top stacking order. ! 2679: * ! 2680: * XXX: Should use the validation function, not mess with the clip lists ! 2681: * directly, though this way is faster. ! 2682: *****/ ! 2683: ! 2684: UnmapSubwindows(pWin, sendExposures) ! 2685: WindowPtr pWin; ! 2686: Bool sendExposures; ! 2687: { ! 2688: WindowPtr pChild; ! 2689: xEvent event; ! 2690: void (*RegionEmpty)(); ! 2691: Bool (*UnrealizeWindow)(); ! 2692: Bool wasMapped = (Bool)pWin->realized; ! 2693: ! 2694: pChild = pWin->lastChild; ! 2695: event.u.u.type = UnmapNotify; ! 2696: event.u.unmapNotify.fromConfigure = xFalse; ! 2697: RegionEmpty = pWin->drawable.pScreen->RegionEmpty; ! 2698: UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow; ! 2699: while (pChild) ! 2700: { ! 2701: if (pChild->mapped) ! 2702: { ! 2703: event.u.unmapNotify.window = pChild->wid; ! 2704: event.u.unmapNotify.fromConfigure = xFalse; ! 2705: DeliverEvents(pWin, &event, 1, NullWindow); ! 2706: pChild->mapped = 0; ! 2707: if (wasMapped) ! 2708: { ! 2709: pChild->realized = pChild->viewable = FALSE; ! 2710: /* We SHOULD check for an error value here XXX */ ! 2711: (* UnrealizeWindow)(pChild); ! 2712: if (pChild->firstChild) ! 2713: UnrealizeChildren(pChild->firstChild); ! 2714: DeleteWindowFromAnyEvents(pChild, FALSE); ! 2715: (* RegionEmpty)(pChild->clipList);/* to force expsoures later*/ ! 2716: (* RegionEmpty)(pChild->borderClip); ! 2717: (* RegionEmpty)(pChild->borderExposed); ! 2718: (* RegionEmpty)(pChild->exposed); ! 2719: pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; ! 2720: } ! 2721: } ! 2722: pChild = pChild->prevSib; ! 2723: } ! 2724: if ((pWin->lastChild) && wasMapped) ! 2725: { ! 2726: (* pWin->drawable.pScreen->Intersect)(pWin->clipList, ! 2727: pWin->winSize, pWin->borderClip); ! 2728: (* pWin->drawable.pScreen->RegionCopy)(pWin->exposed, pWin->clipList); ! 2729: HandleExposures(pWin); ! 2730: } ! 2731: } ! 2732: ! 2733: ! 2734: void ! 2735: HandleSaveSet(client) ! 2736: ClientPtr client; ! 2737: { ! 2738: WindowPtr pParent, pWin; ! 2739: int j; ! 2740: ! 2741: for (j=0; j<client->numSaved; j++) ! 2742: { ! 2743: pWin = (WindowPtr)client->saveSet[j]; ! 2744: pParent = pWin->parent; ! 2745: while (pParent && (pParent->client == client)) ! 2746: pParent = pParent->parent; ! 2747: if (pParent) ! 2748: { ! 2749: ReparentWindow(pWin, pParent, pWin->absCorner.x, ! 2750: pWin->absCorner.y, client); ! 2751: if(!pWin->realized && pWin->mapped) ! 2752: pWin->mapped = FALSE; ! 2753: MapWindow(pWin, HANDLE_EXPOSURES, BITS_DISCARDED, ! 2754: SEND_NOTIFICATION, client); ! 2755: } ! 2756: } ! 2757: } ! 2758: ! 2759: Bool ! 2760: VisibleBoundingBoxFromPoint(pWin, x, y, box) ! 2761: WindowPtr pWin; ! 2762: int x, y; /* in root */ ! 2763: BoxPtr box; /* "return" value */ ! 2764: { ! 2765: if (!pWin->realized) ! 2766: return (FALSE); ! 2767: if ((* pWin->drawable.pScreen->PointInRegion)(pWin->clipList, x, y, box)) ! 2768: return(TRUE); ! 2769: return(FALSE); ! 2770: } ! 2771: ! 2772: Bool ! 2773: PointInWindowIsVisible(pWin, x, y) ! 2774: WindowPtr pWin; ! 2775: int x, y; /* in root */ ! 2776: { ! 2777: BoxRec box; ! 2778: ! 2779: if (!pWin->realized) ! 2780: return (FALSE); ! 2781: if ((* pWin->drawable.pScreen->PointInRegion)(pWin->clipList, x, y, &box)) ! 2782: return(TRUE); ! 2783: return(FALSE); ! 2784: } ! 2785: ! 2786: ! 2787: RegionPtr ! 2788: NotClippedByChildren(pWin) ! 2789: WindowPtr pWin; ! 2790: { ! 2791: register ScreenPtr pScreen; ! 2792: RegionPtr pReg; ! 2793: ! 2794: pScreen = pWin->drawable.pScreen; ! 2795: pReg = (* pScreen->RegionCreate)(NULL, 1); ! 2796: (* pScreen->Intersect) (pReg, pWin->borderClip, pWin->winSize); ! 2797: return(pReg); ! 2798: } ! 2799: ! 2800: ! 2801: void ! 2802: SendVisibilityNotify(pWin) ! 2803: WindowPtr pWin; ! 2804: { ! 2805: xEvent event; ! 2806: event.u.u.type = VisibilityNotify; ! 2807: event.u.visibility.window = pWin->wid; ! 2808: event.u.visibility.state = pWin->visibility; ! 2809: DeliverEvents(pWin, &event, 1, NullWindow); ! 2810: } ! 2811: ! 2812: ! 2813: #define RANDOM_WIDTH 32 ! 2814: ! 2815: void ! 2816: SaveScreens(on, mode) ! 2817: int on; ! 2818: int mode; ! 2819: { ! 2820: int i, j; ! 2821: int what; ! 2822: unsigned char *srcbits, *mskbits; ! 2823: ! 2824: if (on == SCREEN_SAVER_FORCER) ! 2825: { ! 2826: if (mode == ScreenSaverReset) ! 2827: what = SCREEN_SAVER_OFF; ! 2828: else ! 2829: what = SCREEN_SAVER_ON; ! 2830: if (what == screenIsSaved) ! 2831: return ; ! 2832: } ! 2833: else ! 2834: what = on; ! 2835: for (i = 0; i < screenInfo.numScreens; i++) ! 2836: { ! 2837: if (on == SCREEN_SAVER_FORCER) ! 2838: { ! 2839: (* screenInfo.screen[i].SaveScreen) (&screenInfo.screen[i], on); ! 2840: } ! 2841: if (what == SCREEN_SAVER_OFF) ! 2842: { ! 2843: if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED) ! 2844: { ! 2845: (* screenInfo.screen[i].SaveScreen) (&screenInfo.screen[i], on); ! 2846: } ! 2847: else if (savedScreenInfo[i].blanked == SCREEN_IS_TILED) ! 2848: { ! 2849: FreeResource(savedScreenInfo[i].wid, RC_NONE); ! 2850: savedScreenInfo[i].pWindow = (WindowPtr)NULL; ! 2851: FreeResource(savedScreenInfo[i].cid, RC_NONE); ! 2852: } ! 2853: continue; ! 2854: } ! 2855: else if (what == SCREEN_SAVER_ON) ! 2856: { ! 2857: if (screenIsSaved == SCREEN_SAVER_ON) /* rotate pattern */ ! 2858: { ! 2859: int new_x, new_y; ! 2860: ! 2861: if (savedScreenInfo[i].blanked == SCREEN_IS_TILED) ! 2862: { ! 2863: new_x = random() % RANDOM_WIDTH; ! 2864: new_y = random() % RANDOM_WIDTH; ! 2865: MoveWindow(savedScreenInfo[i].pWindow, -new_x, -new_y, ! 2866: savedScreenInfo[i].pWindow->nextSib); ! 2867: } ! 2868: continue; ! 2869: } ! 2870: if (ScreenSaverBlanking != DontPreferBlanking) ! 2871: { ! 2872: if ((* screenInfo.screen[i].SaveScreen) ! 2873: (&screenInfo.screen[i], what)) ! 2874: { ! 2875: savedScreenInfo[i].blanked = SCREEN_IS_BLANKED; ! 2876: continue; ! 2877: } ! 2878: } ! 2879: if (ScreenSaverAllowExposures != DontAllowExposures) ! 2880: { ! 2881: int result; ! 2882: long attributes[1]; ! 2883: int mask = CWBackPixmap; ! 2884: WindowPtr pWin; ! 2885: CursorMetricRec cm; ! 2886: ! 2887: if (WindowTable[i].backgroundTile == ! 2888: (PixmapPtr)USE_BACKGROUND_PIXEL) ! 2889: { ! 2890: attributes[0] = WindowTable[i].backgroundPixel; ! 2891: mask = CWBackPixel; ! 2892: } ! 2893: else ! 2894: attributes[0] = None; ! 2895: ! 2896: pWin = savedScreenInfo[i].pWindow = ! 2897: /* We SHOULD check for an error value here XXX */ ! 2898: CreateWindow(savedScreenInfo[i].wid, ! 2899: &WindowTable[i], ! 2900: -RANDOM_WIDTH, -RANDOM_WIDTH, ! 2901: screenInfo.screen[i].width + RANDOM_WIDTH, ! 2902: screenInfo.screen[i].height + RANDOM_WIDTH, ! 2903: 0, InputOutput, mask, attributes, 0, 0, ! 2904: WindowTable[i].visual, &result); ! 2905: if (attributes[0] == None) ! 2906: { ! 2907: ! 2908: pWin->backgroundTile = pWin->parent->backgroundTile; ! 2909: pWin->backgroundTile->refcnt++; ! 2910: (* screenInfo.screen[i].ChangeWindowAttributes) ! 2911: (pWin, CWBackPixmap); ! 2912: } ! 2913: AddResource(pWin->wid, RT_WINDOW, ! 2914: savedScreenInfo[i].pWindow, ! 2915: DeleteWindow, RC_CORE); ! 2916: cm.width=32; ! 2917: cm.height=16; ! 2918: cm.xhot=8; ! 2919: cm.yhot=8; ! 2920: srcbits = (unsigned char *)Xalloc( PixmapBytePad(32, 1)*16); ! 2921: mskbits = (unsigned char *)Xalloc( PixmapBytePad(32, 1)*16); ! 2922: for (j=0; j<PixmapBytePad(32, 1)*16; j++) ! 2923: srcbits[j] = mskbits[j] = 0x0; ! 2924: pWin->cursor = AllocCursor( srcbits, mskbits, &cm, ! 2925: ~0, ~0, ~0, 0, 0, 0); ! 2926: AddResource(savedScreenInfo[i].cid, RT_CURSOR, ! 2927: pWin->cursor, ! 2928: FreeCursor, RC_CORE); ! 2929: pWin->cursor->refcnt++; ! 2930: pWin->overrideRedirect = TRUE; ! 2931: MapWindow(pWin, TRUE, FALSE, FALSE, 0); ! 2932: savedScreenInfo[i].blanked = SCREEN_IS_TILED; ! 2933: } ! 2934: else ! 2935: savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED; ! 2936: } ! 2937: } ! 2938: screenIsSaved = what; ! 2939: } ! 2940:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.