miwindow.c revision 4642e01f
1/*********************************************************** 2 3Copyright 1987, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25 26Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 27 28 All Rights Reserved 29 30Permission to use, copy, modify, and distribute this software and its 31documentation for any purpose and without fee is hereby granted, 32provided that the above copyright notice appear in all copies and that 33both that copyright notice and this permission notice appear in 34supporting documentation, and that the name of Digital not be 35used in advertising or publicity pertaining to distribution of the 36software without specific, written prior permission. 37 38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 44SOFTWARE. 45 46******************************************************************/ 47#ifdef HAVE_DIX_CONFIG_H 48#include <dix-config.h> 49#endif 50 51#include <X11/X.h> 52#include "regionstr.h" 53#include "region.h" 54#include "mi.h" 55#include "windowstr.h" 56#include "scrnintstr.h" 57#include "pixmapstr.h" 58#include "mivalidate.h" 59 60_X_EXPORT void 61miClearToBackground(WindowPtr pWin, 62 int x, int y, int w, int h, 63 Bool generateExposures) 64{ 65 BoxRec box; 66 RegionRec reg; 67 RegionPtr pBSReg = NullRegion; 68 ScreenPtr pScreen; 69 BoxPtr extents; 70 int x1, y1, x2, y2; 71 72 /* compute everything using ints to avoid overflow */ 73 74 x1 = pWin->drawable.x + x; 75 y1 = pWin->drawable.y + y; 76 if (w) 77 x2 = x1 + (int) w; 78 else 79 x2 = x1 + (int) pWin->drawable.width - (int) x; 80 if (h) 81 y2 = y1 + h; 82 else 83 y2 = y1 + (int) pWin->drawable.height - (int) y; 84 85 extents = &pWin->clipList.extents; 86 87 /* clip the resulting rectangle to the window clipList extents. This 88 * makes sure that the result will fit in a box, given that the 89 * screen is < 32768 on a side. 90 */ 91 92 if (x1 < extents->x1) 93 x1 = extents->x1; 94 if (x2 > extents->x2) 95 x2 = extents->x2; 96 if (y1 < extents->y1) 97 y1 = extents->y1; 98 if (y2 > extents->y2) 99 y2 = extents->y2; 100 101 if (x2 <= x1 || y2 <= y1) 102 { 103 x2 = x1 = 0; 104 y2 = y1 = 0; 105 } 106 107 box.x1 = x1; 108 box.x2 = x2; 109 box.y1 = y1; 110 box.y2 = y2; 111 112 pScreen = pWin->drawable.pScreen; 113 REGION_INIT(pScreen, ®, &box, 1); 114 115 REGION_INTERSECT(pScreen, ®, ®, &pWin->clipList); 116 if (generateExposures) 117 (*pScreen->WindowExposures)(pWin, ®, pBSReg); 118 else if (pWin->backgroundState != None) 119 miPaintWindow(pWin, ®, PW_BACKGROUND); 120 REGION_UNINIT(pScreen, ®); 121 if (pBSReg) 122 REGION_DESTROY(pScreen, pBSReg); 123} 124 125void 126miMarkWindow(WindowPtr pWin) 127{ 128 ValidatePtr val; 129 130 if (pWin->valdata) 131 return; 132 val = (ValidatePtr)xnfalloc(sizeof(ValidateRec)); 133 val->before.oldAbsCorner.x = pWin->drawable.x; 134 val->before.oldAbsCorner.y = pWin->drawable.y; 135 val->before.borderVisible = NullRegion; 136 val->before.resized = FALSE; 137 pWin->valdata = val; 138} 139 140Bool 141miMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin) 142{ 143 BoxPtr box; 144 WindowPtr pChild, pLast; 145 Bool anyMarked = FALSE; 146 MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow; 147 ScreenPtr pScreen; 148 149 pScreen = pWin->drawable.pScreen; 150 151 /* single layered systems are easy */ 152 if (ppLayerWin) *ppLayerWin = pWin; 153 154 if (pWin == pFirst) 155 { 156 /* Blindly mark pWin and all of its inferiors. This is a slight 157 * overkill if there are mapped windows that outside pWin's border, 158 * but it's better than wasting time on RectIn checks. 159 */ 160 pChild = pWin; 161 while (1) 162 { 163 if (pChild->viewable) 164 { 165 if (REGION_BROKEN (pScreen, &pChild->winSize)) 166 SetWinSize (pChild); 167 if (REGION_BROKEN (pScreen, &pChild->borderSize)) 168 SetBorderSize (pChild); 169 (* MarkWindow)(pChild); 170 if (pChild->firstChild) 171 { 172 pChild = pChild->firstChild; 173 continue; 174 } 175 } 176 while (!pChild->nextSib && (pChild != pWin)) 177 pChild = pChild->parent; 178 if (pChild == pWin) 179 break; 180 pChild = pChild->nextSib; 181 } 182 anyMarked = TRUE; 183 pFirst = pFirst->nextSib; 184 } 185 if ( (pChild = pFirst) ) 186 { 187 box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize); 188 pLast = pChild->parent->lastChild; 189 while (1) 190 { 191 if (pChild->viewable) 192 { 193 if (REGION_BROKEN (pScreen, &pChild->winSize)) 194 SetWinSize (pChild); 195 if (REGION_BROKEN (pScreen, &pChild->borderSize)) 196 SetBorderSize (pChild); 197 if (RECT_IN_REGION(pScreen, &pChild->borderSize, box)) 198 { 199 (* MarkWindow)(pChild); 200 anyMarked = TRUE; 201 if (pChild->firstChild) 202 { 203 pChild = pChild->firstChild; 204 continue; 205 } 206 } 207 } 208 while (!pChild->nextSib && (pChild != pLast)) 209 pChild = pChild->parent; 210 if (pChild == pLast) 211 break; 212 pChild = pChild->nextSib; 213 } 214 } 215 if (anyMarked) 216 (* MarkWindow)(pWin->parent); 217 return anyMarked; 218} 219 220/***** 221 * miHandleValidateExposures(pWin) 222 * starting at pWin, draw background in any windows that have exposure 223 * regions, translate the regions, restore any backing store, 224 * and then send any regions still exposed to the client 225 *****/ 226void 227miHandleValidateExposures(WindowPtr pWin) 228{ 229 WindowPtr pChild; 230 ValidatePtr val; 231 ScreenPtr pScreen; 232 WindowExposuresProcPtr WindowExposures; 233 234 pScreen = pWin->drawable.pScreen; 235 236 pChild = pWin; 237 WindowExposures = pChild->drawable.pScreen->WindowExposures; 238 while (1) 239 { 240 if ( (val = pChild->valdata) ) 241 { 242 if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed)) 243 miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER); 244 REGION_UNINIT(pScreen, &val->after.borderExposed); 245 (*WindowExposures)(pChild, &val->after.exposed, NullRegion); 246 REGION_UNINIT(pScreen, &val->after.exposed); 247 xfree(val); 248 pChild->valdata = (ValidatePtr)NULL; 249 if (pChild->firstChild) 250 { 251 pChild = pChild->firstChild; 252 continue; 253 } 254 } 255 while (!pChild->nextSib && (pChild != pWin)) 256 pChild = pChild->parent; 257 if (pChild == pWin) 258 break; 259 pChild = pChild->nextSib; 260 } 261} 262 263void 264miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind) 265{ 266 WindowPtr pParent; 267 Bool WasViewable = (Bool)(pWin->viewable); 268 short bw; 269 RegionPtr oldRegion = NULL; 270 DDXPointRec oldpt; 271 Bool anyMarked = FALSE; 272 ScreenPtr pScreen; 273 WindowPtr windowToValidate; 274 WindowPtr pLayerWin; 275 276 /* if this is a root window, can't be moved */ 277 if (!(pParent = pWin->parent)) 278 return ; 279 pScreen = pWin->drawable.pScreen; 280 bw = wBorderWidth (pWin); 281 282 oldpt.x = pWin->drawable.x; 283 oldpt.y = pWin->drawable.y; 284 if (WasViewable) 285 { 286 oldRegion = REGION_CREATE(pScreen, NullBox, 1); 287 REGION_COPY(pScreen, oldRegion, &pWin->borderClip); 288 anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin); 289 } 290 pWin->origin.x = x + (int)bw; 291 pWin->origin.y = y + (int)bw; 292 x = pWin->drawable.x = pParent->drawable.x + x + (int)bw; 293 y = pWin->drawable.y = pParent->drawable.y + y + (int)bw; 294 295 SetWinSize (pWin); 296 SetBorderSize (pWin); 297 298 (*pScreen->PositionWindow)(pWin, x, y); 299 300 windowToValidate = MoveWindowInStack(pWin, pNextSib); 301 302 ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0); 303 304 if (WasViewable) 305 { 306 if (pLayerWin == pWin) 307 anyMarked |= (*pScreen->MarkOverlappedWindows) 308 (pWin, windowToValidate, (WindowPtr *)NULL); 309 else 310 anyMarked |= (*pScreen->MarkOverlappedWindows) 311 (pWin, pLayerWin, (WindowPtr *)NULL); 312 313 314 if (anyMarked) 315 { 316 (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind); 317 (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion); 318 REGION_DESTROY(pScreen, oldRegion); 319 /* XXX need to retile border if ParentRelative origin */ 320 (*pScreen->HandleExposures)(pLayerWin->parent); 321 } 322 if (anyMarked && pScreen->PostValidateTree) 323 (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind); 324 } 325 if (pWin->realized) 326 WindowsRestructured (); 327} 328 329 330/* 331 * pValid is a region of the screen which has been 332 * successfully copied -- recomputed exposed regions for affected windows 333 */ 334 335static int 336miRecomputeExposures ( 337 WindowPtr pWin, 338 pointer value) /* must conform to VisitWindowProcPtr */ 339{ 340 ScreenPtr pScreen; 341 RegionPtr pValid = (RegionPtr)value; 342 343 if (pWin->valdata) 344 { 345#ifdef COMPOSITE 346 /* 347 * Redirected windows are not affected by parent window 348 * gravity manipulations, so don't recompute their 349 * exposed areas here. 350 */ 351 if (pWin->redirectDraw != RedirectDrawNone) 352 return WT_DONTWALKCHILDREN; 353#endif 354 pScreen = pWin->drawable.pScreen; 355 /* 356 * compute exposed regions of this window 357 */ 358 REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed, 359 &pWin->clipList, pValid); 360 /* 361 * compute exposed regions of the border 362 */ 363 REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed, 364 &pWin->borderClip, &pWin->winSize); 365 REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed, 366 &pWin->valdata->after.borderExposed, pValid); 367 return WT_WALKCHILDREN; 368 } 369 return WT_NOMATCH; 370} 371 372void 373miSlideAndSizeWindow(WindowPtr pWin, 374 int x, int y, 375 unsigned int w, unsigned int h, 376 WindowPtr pSib) 377{ 378 WindowPtr pParent; 379 Bool WasViewable = (Bool)(pWin->viewable); 380 unsigned short width = pWin->drawable.width, 381 height = pWin->drawable.height; 382 short oldx = pWin->drawable.x, 383 oldy = pWin->drawable.y; 384 int bw = wBorderWidth (pWin); 385 short dw, dh; 386 DDXPointRec oldpt; 387 RegionPtr oldRegion = NULL; 388 Bool anyMarked = FALSE; 389 ScreenPtr pScreen; 390 WindowPtr pFirstChange; 391 WindowPtr pChild; 392 RegionPtr gravitate[StaticGravity + 1]; 393 unsigned g; 394 int nx, ny; /* destination x,y */ 395 int newx, newy; /* new inner window position */ 396 RegionPtr pRegion = NULL; 397 RegionPtr destClip; /* portions of destination already written */ 398 RegionPtr oldWinClip = NULL; /* old clip list for window */ 399 RegionPtr borderVisible = NullRegion; /* visible area of the border */ 400 Bool shrunk = FALSE; /* shrunk in an inner dimension */ 401 Bool moved = FALSE; /* window position changed */ 402 WindowPtr pLayerWin; 403 404 /* if this is a root window, can't be resized */ 405 if (!(pParent = pWin->parent)) 406 return ; 407 408 pScreen = pWin->drawable.pScreen; 409 newx = pParent->drawable.x + x + bw; 410 newy = pParent->drawable.y + y + bw; 411 if (WasViewable) 412 { 413 anyMarked = FALSE; 414 /* 415 * save the visible region of the window 416 */ 417 oldRegion = REGION_CREATE(pScreen, NullBox, 1); 418 REGION_COPY(pScreen, oldRegion, &pWin->winSize); 419 420 /* 421 * categorize child windows into regions to be moved 422 */ 423 for (g = 0; g <= StaticGravity; g++) 424 gravitate[g] = (RegionPtr) NULL; 425 for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) 426 { 427 g = pChild->winGravity; 428 if (g != UnmapGravity) 429 { 430 if (!gravitate[g]) 431 gravitate[g] = REGION_CREATE(pScreen, NullBox, 1); 432 REGION_UNION(pScreen, gravitate[g], 433 gravitate[g], &pChild->borderClip); 434 } 435 else 436 { 437 UnmapWindow(pChild, TRUE); 438 anyMarked = TRUE; 439 } 440 } 441 anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 442 &pLayerWin); 443 444 oldWinClip = NULL; 445 if (pWin->bitGravity != ForgetGravity) 446 { 447 oldWinClip = REGION_CREATE(pScreen, NullBox, 1); 448 REGION_COPY(pScreen, oldWinClip, &pWin->clipList); 449 } 450 /* 451 * if the window is changing size, borderExposed 452 * can't be computed correctly without some help. 453 */ 454 if (pWin->drawable.height > h || pWin->drawable.width > w) 455 shrunk = TRUE; 456 457 if (newx != oldx || newy != oldy) 458 moved = TRUE; 459 460 if ((pWin->drawable.height != h || pWin->drawable.width != w) && 461 HasBorder (pWin)) 462 { 463 borderVisible = REGION_CREATE(pScreen, NullBox, 1); 464 /* for tiled borders, we punt and draw the whole thing */ 465 if (pWin->borderIsPixel || !moved) 466 { 467 if (shrunk || moved) 468 REGION_SUBTRACT(pScreen, borderVisible, 469 &pWin->borderClip, 470 &pWin->winSize); 471 else 472 REGION_COPY(pScreen, borderVisible, 473 &pWin->borderClip); 474 } 475 } 476 } 477 pWin->origin.x = x + bw; 478 pWin->origin.y = y + bw; 479 pWin->drawable.height = h; 480 pWin->drawable.width = w; 481 482 x = pWin->drawable.x = newx; 483 y = pWin->drawable.y = newy; 484 485 SetWinSize (pWin); 486 SetBorderSize (pWin); 487 488 dw = (int)w - (int)width; 489 dh = (int)h - (int)height; 490 ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh); 491 492 /* let the hardware adjust background and border pixmaps, if any */ 493 (*pScreen->PositionWindow)(pWin, x, y); 494 495 pFirstChange = MoveWindowInStack(pWin, pSib); 496 497 if (WasViewable) 498 { 499 pRegion = REGION_CREATE(pScreen, NullBox, 1); 500 501 if (pLayerWin == pWin) 502 anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange, 503 (WindowPtr *)NULL); 504 else 505 anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin, 506 (WindowPtr *)NULL); 507 508 if (pWin->valdata) 509 { 510 pWin->valdata->before.resized = TRUE; 511 pWin->valdata->before.borderVisible = borderVisible; 512 } 513 514 515 if (anyMarked) 516 (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther); 517 /* 518 * the entire window is trashed unless bitGravity 519 * recovers portions of it 520 */ 521 REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList); 522 } 523 524 GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny); 525 526 if (WasViewable) 527 { 528 /* avoid the border */ 529 if (HasBorder (pWin)) 530 { 531 int offx, offy, dx, dy; 532 533 /* kruft to avoid double translates for each gravity */ 534 offx = 0; 535 offy = 0; 536 for (g = 0; g <= StaticGravity; g++) 537 { 538 if (!gravitate[g]) 539 continue; 540 541 /* align winSize to gravitate[g]. 542 * winSize is in new coordinates, 543 * gravitate[g] is still in old coordinates */ 544 GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny); 545 546 dx = (oldx - nx) - offx; 547 dy = (oldy - ny) - offy; 548 if (dx || dy) 549 { 550 REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy); 551 offx += dx; 552 offy += dy; 553 } 554 REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], 555 &pWin->winSize); 556 } 557 /* get winSize back where it belongs */ 558 if (offx || offy) 559 REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy); 560 } 561 /* 562 * add screen bits to the appropriate bucket 563 */ 564 565 if (oldWinClip) 566 { 567 /* 568 * clip to new clipList 569 */ 570 REGION_COPY(pScreen, pRegion, oldWinClip); 571 REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy); 572 REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList); 573 /* 574 * don't step on any gravity bits which will be copied after this 575 * region. Note -- this assumes that the regions will be copied 576 * in gravity order. 577 */ 578 for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) 579 { 580 if (gravitate[g]) 581 REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip, 582 gravitate[g]); 583 } 584 REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny); 585 g = pWin->bitGravity; 586 if (!gravitate[g]) 587 gravitate[g] = oldWinClip; 588 else 589 { 590 REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip); 591 REGION_DESTROY(pScreen, oldWinClip); 592 } 593 } 594 595 /* 596 * move the bits on the screen 597 */ 598 599 destClip = NULL; 600 601 for (g = 0; g <= StaticGravity; g++) 602 { 603 if (!gravitate[g]) 604 continue; 605 606 GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny); 607 608 oldpt.x = oldx + (x - nx); 609 oldpt.y = oldy + (y - ny); 610 611 /* Note that gravitate[g] is *translated* by CopyWindow */ 612 613 /* only copy the remaining useful bits */ 614 615 REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion); 616 617 /* clip to not overwrite already copied areas */ 618 619 if (destClip) { 620 REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y); 621 REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip); 622 REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y); 623 } 624 625 /* and move those bits */ 626 627 if (oldpt.x != x || oldpt.y != y 628#ifdef COMPOSITE 629 || pWin->redirectDraw 630#endif 631 ) 632 { 633 (*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]); 634 } 635 636 /* remove any overwritten bits from the remaining useful bits */ 637 638 REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]); 639 640 /* 641 * recompute exposed regions of child windows 642 */ 643 644 for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) 645 { 646 if (pChild->winGravity != g) 647 continue; 648 REGION_INTERSECT(pScreen, pRegion, 649 &pChild->borderClip, gravitate[g]); 650 TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion); 651 } 652 653 /* 654 * remove the successfully copied regions of the 655 * window from its exposed region 656 */ 657 658 if (g == pWin->bitGravity) 659 REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed, 660 &pWin->valdata->after.exposed, gravitate[g]); 661 if (!destClip) 662 destClip = gravitate[g]; 663 else 664 { 665 REGION_UNION(pScreen, destClip, destClip, gravitate[g]); 666 REGION_DESTROY(pScreen, gravitate[g]); 667 } 668 } 669 670 REGION_DESTROY(pScreen, oldRegion); 671 REGION_DESTROY(pScreen, pRegion); 672 if (destClip) 673 REGION_DESTROY(pScreen, destClip); 674 if (anyMarked) 675 (*pScreen->HandleExposures)(pLayerWin->parent); 676 if (anyMarked && pScreen->PostValidateTree) 677 (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, 678 VTOther); 679 } 680 if (pWin->realized) 681 WindowsRestructured (); 682} 683 684WindowPtr 685miGetLayerWindow(WindowPtr pWin) 686{ 687 return pWin->firstChild; 688} 689 690/****** 691 * 692 * miSetShape 693 * The border/window shape has changed. Recompute winSize/borderSize 694 * and send appropriate exposure events 695 */ 696 697void 698miSetShape(WindowPtr pWin) 699{ 700 Bool WasViewable = (Bool)(pWin->viewable); 701 ScreenPtr pScreen = pWin->drawable.pScreen; 702 Bool anyMarked = FALSE; 703 WindowPtr pLayerWin; 704 705 if (WasViewable) 706 { 707 anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, 708 &pLayerWin); 709 if (pWin->valdata) 710 { 711 if (HasBorder (pWin)) 712 { 713 RegionPtr borderVisible; 714 715 borderVisible = REGION_CREATE(pScreen, NullBox, 1); 716 REGION_SUBTRACT(pScreen, borderVisible, 717 &pWin->borderClip, &pWin->winSize); 718 pWin->valdata->before.borderVisible = borderVisible; 719 } 720 pWin->valdata->before.resized = TRUE; 721 } 722 } 723 724 SetWinSize (pWin); 725 SetBorderSize (pWin); 726 727 ResizeChildrenWinSize(pWin, 0, 0, 0, 0); 728 729 if (WasViewable) 730 { 731 anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 732 (WindowPtr *)NULL); 733 734 735 if (anyMarked) 736 (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther); 737 } 738 739 if (WasViewable) 740 { 741 if (anyMarked) 742 (*pScreen->HandleExposures)(pLayerWin->parent); 743 if (anyMarked && pScreen->PostValidateTree) 744 (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther); 745 } 746 if (pWin->realized) 747 WindowsRestructured (); 748 CheckCursorConfinement(pWin); 749} 750 751/* Keeps the same inside(!) origin */ 752 753void 754miChangeBorderWidth(WindowPtr pWin, unsigned int width) 755{ 756 int oldwidth; 757 Bool anyMarked = FALSE; 758 ScreenPtr pScreen; 759 Bool WasViewable = (Bool)(pWin->viewable); 760 Bool HadBorder; 761 WindowPtr pLayerWin; 762 763 oldwidth = wBorderWidth (pWin); 764 if (oldwidth == width) 765 return; 766 HadBorder = HasBorder(pWin); 767 pScreen = pWin->drawable.pScreen; 768 if (WasViewable && width < oldwidth) 769 anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin); 770 771 pWin->borderWidth = width; 772 SetBorderSize (pWin); 773 774 if (WasViewable) 775 { 776 if (width > oldwidth) 777 { 778 anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, 779 &pLayerWin); 780 /* 781 * save the old border visible region to correctly compute 782 * borderExposed. 783 */ 784 if (pWin->valdata && HadBorder) 785 { 786 RegionPtr borderVisible; 787 borderVisible = REGION_CREATE(pScreen, NULL, 1); 788 REGION_SUBTRACT(pScreen, borderVisible, 789 &pWin->borderClip, &pWin->winSize); 790 pWin->valdata->before.borderVisible = borderVisible; 791 } 792 } 793 794 if (anyMarked) 795 { 796 (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther); 797 (*pScreen->HandleExposures)(pLayerWin->parent); 798 } 799 if (anyMarked && pScreen->PostValidateTree) 800 (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, 801 VTOther); 802 } 803 if (pWin->realized) 804 WindowsRestructured (); 805} 806 807void 808miMarkUnrealizedWindow(WindowPtr pChild, WindowPtr pWin, Bool fromConfigure) 809{ 810 if ((pChild != pWin) || fromConfigure) 811 { 812 REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList); 813 if (pChild->drawable.pScreen->ClipNotify) 814 (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0); 815 REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip); 816 } 817} 818 819_X_EXPORT void 820miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth) 821{ 822 ScreenPtr pScreen; 823 WindowPtr pChild; 824 825 pScreen = pWin->drawable.pScreen; 826 827 for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) 828 { 829 if (pChild->drawable.depth == depth) 830 REGION_UNION(pScreen, pReg, pReg, &pChild->borderClip); 831 832 if (pChild->firstChild) 833 miSegregateChildren(pChild, pReg, depth); 834 } 835} 836