miwindow.c revision 9ace9065
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 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 RegionInit(®, &box, 1); 113 114 RegionIntersect(®, ®, &pWin->clipList); 115 if (generateExposures) 116 (*pWin->drawable.pScreen->WindowExposures)(pWin, ®, NULL); 117 else if (pWin->backgroundState != None) 118 miPaintWindow(pWin, ®, PW_BACKGROUND); 119 RegionUninit(®); 120} 121 122void 123miMarkWindow(WindowPtr pWin) 124{ 125 ValidatePtr val; 126 127 if (pWin->valdata) 128 return; 129 val = (ValidatePtr)xnfalloc(sizeof(ValidateRec)); 130 val->before.oldAbsCorner.x = pWin->drawable.x; 131 val->before.oldAbsCorner.y = pWin->drawable.y; 132 val->before.borderVisible = NullRegion; 133 val->before.resized = FALSE; 134 pWin->valdata = val; 135} 136 137Bool 138miMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin) 139{ 140 BoxPtr box; 141 WindowPtr pChild, pLast; 142 Bool anyMarked = FALSE; 143 MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow; 144 145 /* single layered systems are easy */ 146 if (ppLayerWin) *ppLayerWin = pWin; 147 148 if (pWin == pFirst) 149 { 150 /* Blindly mark pWin and all of its inferiors. This is a slight 151 * overkill if there are mapped windows that outside pWin's border, 152 * but it's better than wasting time on RectIn checks. 153 */ 154 pChild = pWin; 155 while (1) 156 { 157 if (pChild->viewable) 158 { 159 if (RegionBroken(&pChild->winSize)) 160 SetWinSize (pChild); 161 if (RegionBroken(&pChild->borderSize)) 162 SetBorderSize (pChild); 163 (* MarkWindow)(pChild); 164 if (pChild->firstChild) 165 { 166 pChild = pChild->firstChild; 167 continue; 168 } 169 } 170 while (!pChild->nextSib && (pChild != pWin)) 171 pChild = pChild->parent; 172 if (pChild == pWin) 173 break; 174 pChild = pChild->nextSib; 175 } 176 anyMarked = TRUE; 177 pFirst = pFirst->nextSib; 178 } 179 if ( (pChild = pFirst) ) 180 { 181 box = RegionExtents(&pWin->borderSize); 182 pLast = pChild->parent->lastChild; 183 while (1) 184 { 185 if (pChild->viewable) 186 { 187 if (RegionBroken(&pChild->winSize)) 188 SetWinSize (pChild); 189 if (RegionBroken(&pChild->borderSize)) 190 SetBorderSize (pChild); 191 if (RegionContainsRect(&pChild->borderSize, box)) 192 { 193 (* MarkWindow)(pChild); 194 anyMarked = TRUE; 195 if (pChild->firstChild) 196 { 197 pChild = pChild->firstChild; 198 continue; 199 } 200 } 201 } 202 while (!pChild->nextSib && (pChild != pLast)) 203 pChild = pChild->parent; 204 if (pChild == pLast) 205 break; 206 pChild = pChild->nextSib; 207 } 208 } 209 if (anyMarked) 210 (* MarkWindow)(pWin->parent); 211 return anyMarked; 212} 213 214/***** 215 * miHandleValidateExposures(pWin) 216 * starting at pWin, draw background in any windows that have exposure 217 * regions, translate the regions, restore any backing store, 218 * and then send any regions still exposed to the client 219 *****/ 220void 221miHandleValidateExposures(WindowPtr pWin) 222{ 223 WindowPtr pChild; 224 ValidatePtr val; 225 WindowExposuresProcPtr WindowExposures; 226 227 pChild = pWin; 228 WindowExposures = pChild->drawable.pScreen->WindowExposures; 229 while (1) 230 { 231 if ( (val = pChild->valdata) ) 232 { 233 if (RegionNotEmpty(&val->after.borderExposed)) 234 miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER); 235 RegionUninit(&val->after.borderExposed); 236 (*WindowExposures)(pChild, &val->after.exposed, NullRegion); 237 RegionUninit(&val->after.exposed); 238 free(val); 239 pChild->valdata = NULL; 240 if (pChild->firstChild) 241 { 242 pChild = pChild->firstChild; 243 continue; 244 } 245 } 246 while (!pChild->nextSib && (pChild != pWin)) 247 pChild = pChild->parent; 248 if (pChild == pWin) 249 break; 250 pChild = pChild->nextSib; 251 } 252} 253 254void 255miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind) 256{ 257 WindowPtr pParent; 258 Bool WasViewable = (Bool)(pWin->viewable); 259 short bw; 260 RegionPtr oldRegion = NULL; 261 DDXPointRec oldpt; 262 Bool anyMarked = FALSE; 263 ScreenPtr pScreen; 264 WindowPtr windowToValidate; 265 WindowPtr pLayerWin; 266 267 /* if this is a root window, can't be moved */ 268 if (!(pParent = pWin->parent)) 269 return ; 270 pScreen = pWin->drawable.pScreen; 271 bw = wBorderWidth (pWin); 272 273 oldpt.x = pWin->drawable.x; 274 oldpt.y = pWin->drawable.y; 275 if (WasViewable) 276 { 277 oldRegion = RegionCreate(NullBox, 1); 278 RegionCopy(oldRegion, &pWin->borderClip); 279 anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin); 280 } 281 pWin->origin.x = x + (int)bw; 282 pWin->origin.y = y + (int)bw; 283 x = pWin->drawable.x = pParent->drawable.x + x + (int)bw; 284 y = pWin->drawable.y = pParent->drawable.y + y + (int)bw; 285 286 SetWinSize (pWin); 287 SetBorderSize (pWin); 288 289 (*pScreen->PositionWindow)(pWin, x, y); 290 291 windowToValidate = MoveWindowInStack(pWin, pNextSib); 292 293 ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0); 294 295 if (WasViewable) 296 { 297 if (pLayerWin == pWin) 298 anyMarked |= (*pScreen->MarkOverlappedWindows) 299 (pWin, windowToValidate, NULL); 300 else 301 anyMarked |= (*pScreen->MarkOverlappedWindows) 302 (pWin, pLayerWin, NULL); 303 304 305 if (anyMarked) 306 { 307 (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind); 308 (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion); 309 RegionDestroy(oldRegion); 310 /* XXX need to retile border if ParentRelative origin */ 311 (*pScreen->HandleExposures)(pLayerWin->parent); 312 } 313 if (anyMarked && pScreen->PostValidateTree) 314 (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind); 315 } 316 if (pWin->realized) 317 WindowsRestructured (); 318} 319 320 321/* 322 * pValid is a region of the screen which has been 323 * successfully copied -- recomputed exposed regions for affected windows 324 */ 325 326static int 327miRecomputeExposures ( 328 WindowPtr pWin, 329 pointer value) /* must conform to VisitWindowProcPtr */ 330{ 331 RegionPtr pValid = (RegionPtr)value; 332 333 if (pWin->valdata) 334 { 335#ifdef COMPOSITE 336 /* 337 * Redirected windows are not affected by parent window 338 * gravity manipulations, so don't recompute their 339 * exposed areas here. 340 */ 341 if (pWin->redirectDraw != RedirectDrawNone) 342 return WT_DONTWALKCHILDREN; 343#endif 344 /* 345 * compute exposed regions of this window 346 */ 347 RegionSubtract(&pWin->valdata->after.exposed, 348 &pWin->clipList, pValid); 349 /* 350 * compute exposed regions of the border 351 */ 352 RegionSubtract(&pWin->valdata->after.borderExposed, 353 &pWin->borderClip, &pWin->winSize); 354 RegionSubtract(&pWin->valdata->after.borderExposed, 355 &pWin->valdata->after.borderExposed, pValid); 356 return WT_WALKCHILDREN; 357 } 358 return WT_NOMATCH; 359} 360 361void 362miSlideAndSizeWindow(WindowPtr pWin, 363 int x, int y, 364 unsigned int w, unsigned int h, 365 WindowPtr pSib) 366{ 367 WindowPtr pParent; 368 Bool WasViewable = (Bool)(pWin->viewable); 369 unsigned short width = pWin->drawable.width, 370 height = pWin->drawable.height; 371 short oldx = pWin->drawable.x, 372 oldy = pWin->drawable.y; 373 int bw = wBorderWidth (pWin); 374 short dw, dh; 375 DDXPointRec oldpt; 376 RegionPtr oldRegion = NULL; 377 Bool anyMarked = FALSE; 378 ScreenPtr pScreen; 379 WindowPtr pFirstChange; 380 WindowPtr pChild; 381 RegionPtr gravitate[StaticGravity + 1]; 382 unsigned g; 383 int nx, ny; /* destination x,y */ 384 int newx, newy; /* new inner window position */ 385 RegionPtr pRegion = NULL; 386 RegionPtr destClip; /* portions of destination already written */ 387 RegionPtr oldWinClip = NULL; /* old clip list for window */ 388 RegionPtr borderVisible = NullRegion; /* visible area of the border */ 389 Bool shrunk = FALSE; /* shrunk in an inner dimension */ 390 Bool moved = FALSE; /* window position changed */ 391 WindowPtr pLayerWin; 392 393 /* if this is a root window, can't be resized */ 394 if (!(pParent = pWin->parent)) 395 return ; 396 397 pScreen = pWin->drawable.pScreen; 398 newx = pParent->drawable.x + x + bw; 399 newy = pParent->drawable.y + y + bw; 400 if (WasViewable) 401 { 402 anyMarked = FALSE; 403 /* 404 * save the visible region of the window 405 */ 406 oldRegion = RegionCreate(NullBox, 1); 407 RegionCopy(oldRegion, &pWin->winSize); 408 409 /* 410 * categorize child windows into regions to be moved 411 */ 412 for (g = 0; g <= StaticGravity; g++) 413 gravitate[g] = (RegionPtr) NULL; 414 for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) 415 { 416 g = pChild->winGravity; 417 if (g != UnmapGravity) 418 { 419 if (!gravitate[g]) 420 gravitate[g] = RegionCreate(NullBox, 1); 421 RegionUnion(gravitate[g], 422 gravitate[g], &pChild->borderClip); 423 } 424 else 425 { 426 UnmapWindow(pChild, TRUE); 427 anyMarked = TRUE; 428 } 429 } 430 anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 431 &pLayerWin); 432 433 oldWinClip = NULL; 434 if (pWin->bitGravity != ForgetGravity) 435 { 436 oldWinClip = RegionCreate(NullBox, 1); 437 RegionCopy(oldWinClip, &pWin->clipList); 438 } 439 /* 440 * if the window is changing size, borderExposed 441 * can't be computed correctly without some help. 442 */ 443 if (pWin->drawable.height > h || pWin->drawable.width > w) 444 shrunk = TRUE; 445 446 if (newx != oldx || newy != oldy) 447 moved = TRUE; 448 449 if ((pWin->drawable.height != h || pWin->drawable.width != w) && 450 HasBorder (pWin)) 451 { 452 borderVisible = RegionCreate(NullBox, 1); 453 /* for tiled borders, we punt and draw the whole thing */ 454 if (pWin->borderIsPixel || !moved) 455 { 456 if (shrunk || moved) 457 RegionSubtract(borderVisible, 458 &pWin->borderClip, 459 &pWin->winSize); 460 else 461 RegionCopy(borderVisible, 462 &pWin->borderClip); 463 } 464 } 465 } 466 pWin->origin.x = x + bw; 467 pWin->origin.y = y + bw; 468 pWin->drawable.height = h; 469 pWin->drawable.width = w; 470 471 x = pWin->drawable.x = newx; 472 y = pWin->drawable.y = newy; 473 474 SetWinSize (pWin); 475 SetBorderSize (pWin); 476 477 dw = (int)w - (int)width; 478 dh = (int)h - (int)height; 479 ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh); 480 481 /* let the hardware adjust background and border pixmaps, if any */ 482 (*pScreen->PositionWindow)(pWin, x, y); 483 484 pFirstChange = MoveWindowInStack(pWin, pSib); 485 486 if (WasViewable) 487 { 488 pRegion = RegionCreate(NullBox, 1); 489 490 if (pLayerWin == pWin) 491 anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange, 492 NULL); 493 else 494 anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin, 495 NULL); 496 497 if (pWin->valdata) 498 { 499 pWin->valdata->before.resized = TRUE; 500 pWin->valdata->before.borderVisible = borderVisible; 501 } 502 503 504 if (anyMarked) 505 (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther); 506 /* 507 * the entire window is trashed unless bitGravity 508 * recovers portions of it 509 */ 510 RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList); 511 } 512 513 GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny); 514 515 if (WasViewable) 516 { 517 /* avoid the border */ 518 if (HasBorder (pWin)) 519 { 520 int offx, offy, dx, dy; 521 522 /* kruft to avoid double translates for each gravity */ 523 offx = 0; 524 offy = 0; 525 for (g = 0; g <= StaticGravity; g++) 526 { 527 if (!gravitate[g]) 528 continue; 529 530 /* align winSize to gravitate[g]. 531 * winSize is in new coordinates, 532 * gravitate[g] is still in old coordinates */ 533 GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny); 534 535 dx = (oldx - nx) - offx; 536 dy = (oldy - ny) - offy; 537 if (dx || dy) 538 { 539 RegionTranslate(&pWin->winSize, dx, dy); 540 offx += dx; 541 offy += dy; 542 } 543 RegionIntersect(gravitate[g], gravitate[g], 544 &pWin->winSize); 545 } 546 /* get winSize back where it belongs */ 547 if (offx || offy) 548 RegionTranslate(&pWin->winSize, -offx, -offy); 549 } 550 /* 551 * add screen bits to the appropriate bucket 552 */ 553 554 if (oldWinClip) 555 { 556 /* 557 * clip to new clipList 558 */ 559 RegionCopy(pRegion, oldWinClip); 560 RegionTranslate(pRegion, nx - oldx, ny - oldy); 561 RegionIntersect(oldWinClip, pRegion, &pWin->clipList); 562 /* 563 * don't step on any gravity bits which will be copied after this 564 * region. Note -- this assumes that the regions will be copied 565 * in gravity order. 566 */ 567 for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) 568 { 569 if (gravitate[g]) 570 RegionSubtract(oldWinClip, oldWinClip, 571 gravitate[g]); 572 } 573 RegionTranslate(oldWinClip, oldx - nx, oldy - ny); 574 g = pWin->bitGravity; 575 if (!gravitate[g]) 576 gravitate[g] = oldWinClip; 577 else 578 { 579 RegionUnion(gravitate[g], gravitate[g], oldWinClip); 580 RegionDestroy(oldWinClip); 581 } 582 } 583 584 /* 585 * move the bits on the screen 586 */ 587 588 destClip = NULL; 589 590 for (g = 0; g <= StaticGravity; g++) 591 { 592 if (!gravitate[g]) 593 continue; 594 595 GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny); 596 597 oldpt.x = oldx + (x - nx); 598 oldpt.y = oldy + (y - ny); 599 600 /* Note that gravitate[g] is *translated* by CopyWindow */ 601 602 /* only copy the remaining useful bits */ 603 604 RegionIntersect(gravitate[g], gravitate[g], oldRegion); 605 606 /* clip to not overwrite already copied areas */ 607 608 if (destClip) { 609 RegionTranslate(destClip, oldpt.x - x, oldpt.y - y); 610 RegionSubtract(gravitate[g], gravitate[g], destClip); 611 RegionTranslate(destClip, x - oldpt.x, y - oldpt.y); 612 } 613 614 /* and move those bits */ 615 616 if (oldpt.x != x || oldpt.y != y 617#ifdef COMPOSITE 618 || pWin->redirectDraw 619#endif 620 ) 621 { 622 (*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]); 623 } 624 625 /* remove any overwritten bits from the remaining useful bits */ 626 627 RegionSubtract(oldRegion, oldRegion, gravitate[g]); 628 629 /* 630 * recompute exposed regions of child windows 631 */ 632 633 for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) 634 { 635 if (pChild->winGravity != g) 636 continue; 637 RegionIntersect(pRegion, 638 &pChild->borderClip, gravitate[g]); 639 TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion); 640 } 641 642 /* 643 * remove the successfully copied regions of the 644 * window from its exposed region 645 */ 646 647 if (g == pWin->bitGravity) 648 RegionSubtract(&pWin->valdata->after.exposed, 649 &pWin->valdata->after.exposed, gravitate[g]); 650 if (!destClip) 651 destClip = gravitate[g]; 652 else 653 { 654 RegionUnion(destClip, destClip, gravitate[g]); 655 RegionDestroy(gravitate[g]); 656 } 657 } 658 659 RegionDestroy(oldRegion); 660 RegionDestroy(pRegion); 661 if (destClip) 662 RegionDestroy(destClip); 663 if (anyMarked) 664 (*pScreen->HandleExposures)(pLayerWin->parent); 665 if (anyMarked && pScreen->PostValidateTree) 666 (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, 667 VTOther); 668 } 669 if (pWin->realized) 670 WindowsRestructured (); 671} 672 673WindowPtr 674miGetLayerWindow(WindowPtr pWin) 675{ 676 return pWin->firstChild; 677} 678 679/****** 680 * 681 * miSetShape 682 * The border/window shape has changed. Recompute winSize/borderSize 683 * and send appropriate exposure events 684 */ 685 686void 687miSetShape(WindowPtr pWin, int kind) 688{ 689 Bool WasViewable = (Bool)(pWin->viewable); 690 ScreenPtr pScreen = pWin->drawable.pScreen; 691 Bool anyMarked = FALSE; 692 WindowPtr pLayerWin; 693 694 if (kind != ShapeInput) { 695 if (WasViewable) 696 { 697 anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, 698 &pLayerWin); 699 if (pWin->valdata) 700 { 701 if (HasBorder (pWin)) 702 { 703 RegionPtr borderVisible; 704 705 borderVisible = RegionCreate(NullBox, 1); 706 RegionSubtract(borderVisible, 707 &pWin->borderClip, &pWin->winSize); 708 pWin->valdata->before.borderVisible = borderVisible; 709 } 710 pWin->valdata->before.resized = TRUE; 711 } 712 } 713 714 SetWinSize (pWin); 715 SetBorderSize (pWin); 716 717 ResizeChildrenWinSize(pWin, 0, 0, 0, 0); 718 719 if (WasViewable) 720 { 721 anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 722 NULL); 723 724 if (anyMarked) 725 (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, 726 VTOther); 727 } 728 729 if (WasViewable) 730 { 731 if (anyMarked) 732 (*pScreen->HandleExposures)(pLayerWin->parent); 733 if (anyMarked && pScreen->PostValidateTree) 734 (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, 735 VTOther); 736 } 737 } 738 if (pWin->realized) 739 WindowsRestructured (); 740 CheckCursorConfinement(pWin); 741} 742 743/* Keeps the same inside(!) origin */ 744 745void 746miChangeBorderWidth(WindowPtr pWin, unsigned int width) 747{ 748 int oldwidth; 749 Bool anyMarked = FALSE; 750 ScreenPtr pScreen; 751 Bool WasViewable = (Bool)(pWin->viewable); 752 Bool HadBorder; 753 WindowPtr pLayerWin; 754 755 oldwidth = wBorderWidth (pWin); 756 if (oldwidth == width) 757 return; 758 HadBorder = HasBorder(pWin); 759 pScreen = pWin->drawable.pScreen; 760 if (WasViewable && width < oldwidth) 761 anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin); 762 763 pWin->borderWidth = width; 764 SetBorderSize (pWin); 765 766 if (WasViewable) 767 { 768 if (width > oldwidth) 769 { 770 anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, 771 &pLayerWin); 772 /* 773 * save the old border visible region to correctly compute 774 * borderExposed. 775 */ 776 if (pWin->valdata && HadBorder) 777 { 778 RegionPtr borderVisible; 779 borderVisible = RegionCreate(NULL, 1); 780 RegionSubtract(borderVisible, 781 &pWin->borderClip, &pWin->winSize); 782 pWin->valdata->before.borderVisible = borderVisible; 783 } 784 } 785 786 if (anyMarked) 787 { 788 (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther); 789 (*pScreen->HandleExposures)(pLayerWin->parent); 790 } 791 if (anyMarked && pScreen->PostValidateTree) 792 (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, 793 VTOther); 794 } 795 if (pWin->realized) 796 WindowsRestructured (); 797} 798 799void 800miMarkUnrealizedWindow(WindowPtr pChild, WindowPtr pWin, Bool fromConfigure) 801{ 802 if ((pChild != pWin) || fromConfigure) 803 { 804 RegionEmpty(&pChild->clipList); 805 if (pChild->drawable.pScreen->ClipNotify) 806 (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0); 807 RegionEmpty(&pChild->borderClip); 808 } 809} 810 811void 812miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth) 813{ 814 WindowPtr pChild; 815 816 for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) 817 { 818 if (pChild->drawable.depth == depth) 819 RegionUnion(pReg, pReg, &pChild->borderClip); 820 821 if (pChild->firstChild) 822 miSegregateChildren(pChild, pReg, depth); 823 } 824} 825