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