mioverlay.c revision 05b261ec
1 2#ifdef HAVE_DIX_CONFIG_H 3#include <dix-config.h> 4#endif 5 6#include <X11/X.h> 7#include "scrnintstr.h" 8#include "validate.h" 9#include "windowstr.h" 10#include "mi.h" 11#include "gcstruct.h" 12#include "regionstr.h" 13#include "mivalidate.h" 14#include "mioverlay.h" 15#include "migc.h" 16 17#include "globals.h" 18 19 20typedef struct { 21 RegionRec exposed; 22 RegionRec borderExposed; 23 RegionPtr borderVisible; 24 DDXPointRec oldAbsCorner; 25} miOverlayValDataRec, *miOverlayValDataPtr; 26 27typedef struct _TreeRec { 28 WindowPtr pWin; 29 struct _TreeRec *parent; 30 struct _TreeRec *firstChild; 31 struct _TreeRec *lastChild; 32 struct _TreeRec *prevSib; 33 struct _TreeRec *nextSib; 34 RegionRec borderClip; 35 RegionRec clipList; 36 unsigned visibility; 37 miOverlayValDataPtr valdata; 38} miOverlayTreeRec, *miOverlayTreePtr; 39 40typedef struct { 41 miOverlayTreePtr tree; 42} miOverlayWindowRec, *miOverlayWindowPtr; 43 44typedef struct { 45 CloseScreenProcPtr CloseScreen; 46 CreateWindowProcPtr CreateWindow; 47 DestroyWindowProcPtr DestroyWindow; 48 UnrealizeWindowProcPtr UnrealizeWindow; 49 RealizeWindowProcPtr RealizeWindow; 50 miOverlayTransFunc MakeTransparent; 51 miOverlayInOverlayFunc InOverlay; 52 Bool underlayMarked; 53 Bool copyUnderlay; 54} miOverlayScreenRec, *miOverlayScreenPtr; 55 56static unsigned long miOverlayGeneration = 0; 57static int miOverlayWindowIndex = -1; 58static int miOverlayScreenIndex = -1; 59 60static void RebuildTree(WindowPtr); 61static Bool HasUnderlayChildren(WindowPtr); 62static void MarkUnderlayWindow(WindowPtr); 63static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr); 64 65static Bool miOverlayCloseScreen(int, ScreenPtr); 66static Bool miOverlayCreateWindow(WindowPtr); 67static Bool miOverlayDestroyWindow(WindowPtr); 68static Bool miOverlayUnrealizeWindow(WindowPtr); 69static Bool miOverlayRealizeWindow(WindowPtr); 70static void miOverlayMarkWindow(WindowPtr); 71static void miOverlayReparentWindow(WindowPtr, WindowPtr); 72static void miOverlayRestackWindow(WindowPtr, WindowPtr); 73static Bool miOverlayMarkOverlappedWindows(WindowPtr, WindowPtr, WindowPtr*); 74static void miOverlayMarkUnrealizedWindow(WindowPtr, WindowPtr, Bool); 75static int miOverlayValidateTree(WindowPtr, WindowPtr, VTKind); 76static void miOverlayHandleExposures(WindowPtr); 77static void miOverlayMoveWindow(WindowPtr, int, int, WindowPtr, VTKind); 78static void miOverlayWindowExposures(WindowPtr, RegionPtr, RegionPtr); 79static void miOverlayResizeWindow(WindowPtr, int, int, unsigned int, 80 unsigned int, WindowPtr); 81static void miOverlayClearToBackground(WindowPtr, int, int, int, int, Bool); 82 83#ifdef SHAPE 84static void miOverlaySetShape(WindowPtr); 85#endif 86static void miOverlayChangeBorderWidth(WindowPtr, unsigned int); 87 88#define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen) \ 89 ((miOverlayScreenPtr)((pScreen)->devPrivates[miOverlayScreenIndex].ptr)) 90#define MIOVERLAY_GET_WINDOW_PRIVATE(pWin) \ 91 ((miOverlayWindowPtr)((pWin)->devPrivates[miOverlayWindowIndex].ptr)) 92#define MIOVERLAY_GET_WINDOW_TREE(pWin) \ 93 (MIOVERLAY_GET_WINDOW_PRIVATE(pWin)->tree) 94 95#define IN_UNDERLAY(w) MIOVERLAY_GET_WINDOW_TREE(w) 96#define IN_OVERLAY(w) !MIOVERLAY_GET_WINDOW_TREE(w) 97 98#define MARK_OVERLAY(w) miMarkWindow(w) 99#define MARK_UNDERLAY(w) MarkUnderlayWindow(w) 100 101#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \ 102 HasBorder(w) && \ 103 (w)->backgroundState == ParentRelative) 104 105_X_EXPORT Bool 106miInitOverlay( 107 ScreenPtr pScreen, 108 miOverlayInOverlayFunc inOverlayFunc, 109 miOverlayTransFunc transFunc 110){ 111 miOverlayScreenPtr pScreenPriv; 112 113 if(!inOverlayFunc || !transFunc) return FALSE; 114 115 if(miOverlayGeneration != serverGeneration) { 116 if(((miOverlayScreenIndex = AllocateScreenPrivateIndex()) < 0) || 117 ((miOverlayWindowIndex = AllocateWindowPrivateIndex()) < 0)) 118 return FALSE; 119 120 miOverlayGeneration = serverGeneration; 121 } 122 123 if(!AllocateWindowPrivate(pScreen, miOverlayWindowIndex, 124 sizeof(miOverlayWindowRec))) 125 return FALSE; 126 127 if(!(pScreenPriv = xalloc(sizeof(miOverlayScreenRec)))) 128 return FALSE; 129 130 pScreen->devPrivates[miOverlayScreenIndex].ptr = (pointer)pScreenPriv; 131 132 pScreenPriv->InOverlay = inOverlayFunc; 133 pScreenPriv->MakeTransparent = transFunc; 134 pScreenPriv->underlayMarked = FALSE; 135 136 137 pScreenPriv->CloseScreen = pScreen->CloseScreen; 138 pScreenPriv->CreateWindow = pScreen->CreateWindow; 139 pScreenPriv->DestroyWindow = pScreen->DestroyWindow; 140 pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow; 141 pScreenPriv->RealizeWindow = pScreen->RealizeWindow; 142 143 pScreen->CloseScreen = miOverlayCloseScreen; 144 pScreen->CreateWindow = miOverlayCreateWindow; 145 pScreen->DestroyWindow = miOverlayDestroyWindow; 146 pScreen->UnrealizeWindow = miOverlayUnrealizeWindow; 147 pScreen->RealizeWindow = miOverlayRealizeWindow; 148 149 pScreen->ReparentWindow = miOverlayReparentWindow; 150 pScreen->RestackWindow = miOverlayRestackWindow; 151 pScreen->MarkOverlappedWindows = miOverlayMarkOverlappedWindows; 152 pScreen->MarkUnrealizedWindow = miOverlayMarkUnrealizedWindow; 153 pScreen->ValidateTree = miOverlayValidateTree; 154 pScreen->HandleExposures = miOverlayHandleExposures; 155 pScreen->MoveWindow = miOverlayMoveWindow; 156 pScreen->WindowExposures = miOverlayWindowExposures; 157 pScreen->ResizeWindow = miOverlayResizeWindow; 158 pScreen->MarkWindow = miOverlayMarkWindow; 159 pScreen->ClearToBackground = miOverlayClearToBackground; 160#ifdef SHAPE 161 pScreen->SetShape = miOverlaySetShape; 162#endif 163 pScreen->ChangeBorderWidth = miOverlayChangeBorderWidth; 164 165 return TRUE; 166} 167 168 169static Bool 170miOverlayCloseScreen(int i, ScreenPtr pScreen) 171{ 172 miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); 173 174 pScreen->CloseScreen = pScreenPriv->CloseScreen; 175 pScreen->CreateWindow = pScreenPriv->CreateWindow; 176 pScreen->DestroyWindow = pScreenPriv->DestroyWindow; 177 pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow; 178 pScreen->RealizeWindow = pScreenPriv->RealizeWindow; 179 180 xfree(pScreenPriv); 181 182 return (*pScreen->CloseScreen)(i, pScreen); 183} 184 185 186static Bool 187miOverlayCreateWindow(WindowPtr pWin) 188{ 189 ScreenPtr pScreen = pWin->drawable.pScreen; 190 miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); 191 miOverlayWindowPtr pWinPriv = MIOVERLAY_GET_WINDOW_PRIVATE(pWin); 192 miOverlayTreePtr pTree = NULL; 193 Bool result = TRUE; 194 195 pWinPriv->tree = NULL; 196 197 if(!pWin->parent || !((*pScreenPriv->InOverlay)(pWin))) { 198 if(!(pTree = (miOverlayTreePtr)xcalloc(1, sizeof(miOverlayTreeRec)))) 199 return FALSE; 200 } 201 202 if(pScreenPriv->CreateWindow) { 203 pScreen->CreateWindow = pScreenPriv->CreateWindow; 204 result = (*pScreen->CreateWindow)(pWin); 205 pScreen->CreateWindow = miOverlayCreateWindow; 206 } 207 208 if (pTree) { 209 if(result) { 210 pTree->pWin = pWin; 211 pTree->visibility = VisibilityNotViewable; 212 pWinPriv->tree = pTree; 213 if(pWin->parent) { 214 REGION_NULL(pScreen, &(pTree->borderClip)); 215 REGION_NULL(pScreen, &(pTree->clipList)); 216 RebuildTree(pWin); 217 } else { 218 BoxRec fullBox; 219 fullBox.x1 = 0; 220 fullBox.y1 = 0; 221 fullBox.x2 = pScreen->width; 222 fullBox.y2 = pScreen->height; 223 REGION_INIT(pScreen, &(pTree->borderClip), &fullBox, 1); 224 REGION_INIT(pScreen, &(pTree->clipList), &fullBox, 1); 225 } 226 } else xfree(pTree); 227 } 228 229 return TRUE; 230} 231 232 233static Bool 234miOverlayDestroyWindow(WindowPtr pWin) 235{ 236 ScreenPtr pScreen = pWin->drawable.pScreen; 237 miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); 238 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 239 Bool result = TRUE; 240 241 if (pTree) { 242 if(pTree->prevSib) 243 pTree->prevSib->nextSib = pTree->nextSib; 244 else if(pTree->parent) 245 pTree->parent->firstChild = pTree->nextSib; 246 247 if(pTree->nextSib) 248 pTree->nextSib->prevSib = pTree->prevSib; 249 else if(pTree->parent) 250 pTree->parent->lastChild = pTree->prevSib; 251 252 REGION_UNINIT(pScreen, &(pTree->borderClip)); 253 REGION_UNINIT(pScreen, &(pTree->clipList)); 254 xfree(pTree); 255 } 256 257 if(pScreenPriv->DestroyWindow) { 258 pScreen->DestroyWindow = pScreenPriv->DestroyWindow; 259 result = (*pScreen->DestroyWindow)(pWin); 260 pScreen->DestroyWindow = miOverlayDestroyWindow; 261 } 262 263 return result; 264} 265 266static Bool 267miOverlayUnrealizeWindow(WindowPtr pWin) 268{ 269 ScreenPtr pScreen = pWin->drawable.pScreen; 270 miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); 271 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 272 Bool result = TRUE; 273 274 if(pTree) pTree->visibility = VisibilityNotViewable; 275 276 if(pScreenPriv->UnrealizeWindow) { 277 pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow; 278 result = (*pScreen->UnrealizeWindow)(pWin); 279 pScreen->UnrealizeWindow = miOverlayUnrealizeWindow; 280 } 281 282 return result; 283} 284 285 286static Bool 287miOverlayRealizeWindow(WindowPtr pWin) 288{ 289 ScreenPtr pScreen = pWin->drawable.pScreen; 290 miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); 291 Bool result = TRUE; 292 293 if(pScreenPriv->RealizeWindow) { 294 pScreen->RealizeWindow = pScreenPriv->RealizeWindow; 295 result = (*pScreen->RealizeWindow)(pWin); 296 pScreen->RealizeWindow = miOverlayRealizeWindow; 297 } 298 299 /* we only need to catch the root window realization */ 300 301 if(result && !pWin->parent && !((*pScreenPriv->InOverlay)(pWin))) 302 { 303 BoxRec box; 304 box.x1 = box.y1 = 0; 305 box.x2 = pWin->drawable.width; 306 box.y2 = pWin->drawable.height; 307 (*pScreenPriv->MakeTransparent)(pScreen, 1, &box); 308 } 309 310 return result; 311} 312 313 314static void 315miOverlayReparentWindow(WindowPtr pWin, WindowPtr pPriorParent) 316{ 317 if(IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) { 318 /* This could probably be more optimal */ 319 RebuildTree(WindowTable[pWin->drawable.pScreen->myNum]->firstChild); 320 } 321} 322 323static void 324miOverlayRestackWindow(WindowPtr pWin, WindowPtr oldNextSib) 325{ 326 if(IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) { 327 /* This could probably be more optimal */ 328 RebuildTree(pWin); 329 } 330} 331 332 333static Bool 334miOverlayMarkOverlappedWindows( 335 WindowPtr pWin, 336 WindowPtr pFirst, 337 WindowPtr *pLayerWin 338){ 339 ScreenPtr pScreen = pWin->drawable.pScreen; 340 WindowPtr pChild, pLast; 341 Bool overMarked, underMarked, doUnderlay, markAll; 342 miOverlayTreePtr pTree = NULL, tLast, tChild; 343 BoxPtr box; 344 345 overMarked = underMarked = markAll = FALSE; 346 347 if(pLayerWin) *pLayerWin = pWin; /* hah! */ 348 349 doUnderlay = (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)); 350 351 box = REGION_EXTENTS(pScreen, &pWin->borderSize); 352 353 if((pChild = pFirst)) { 354 pLast = pChild->parent->lastChild; 355 while (1) { 356 if (pChild == pWin) markAll = TRUE; 357 358 if(doUnderlay && IN_UNDERLAY(pChild)) 359 pTree = MIOVERLAY_GET_WINDOW_TREE(pChild); 360 361 if(pChild->viewable) { 362 if (REGION_BROKEN (pScreen, &pChild->winSize)) 363 SetWinSize (pChild); 364 if (REGION_BROKEN (pScreen, &pChild->borderSize)) 365 SetBorderSize (pChild); 366 367 if (markAll || 368 RECT_IN_REGION(pScreen, &pChild->borderSize, box)) 369 { 370 MARK_OVERLAY(pChild); 371 overMarked = TRUE; 372 if(doUnderlay && IN_UNDERLAY(pChild)) { 373 MARK_UNDERLAY(pChild); 374 underMarked = TRUE; 375 } 376 if (pChild->firstChild) { 377 pChild = pChild->firstChild; 378 continue; 379 } 380 } 381 } 382 while (!pChild->nextSib && (pChild != pLast)) { 383 pChild = pChild->parent; 384 if(doUnderlay && IN_UNDERLAY(pChild)) 385 pTree = MIOVERLAY_GET_WINDOW_TREE(pChild); 386 } 387 388 if(pChild == pWin) markAll = FALSE; 389 390 if (pChild == pLast) break; 391 392 pChild = pChild->nextSib; 393 } 394 if(overMarked) 395 MARK_OVERLAY(pWin->parent); 396 } 397 398 if(doUnderlay && !pTree) { 399 if(!(pTree = MIOVERLAY_GET_WINDOW_TREE(pWin))) { 400 pChild = pWin->lastChild; 401 while(1) { 402 if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) 403 break; 404 405 if(pChild->lastChild) { 406 pChild = pChild->lastChild; 407 continue; 408 } 409 410 while(!pChild->prevSib) pChild = pChild->parent; 411 412 pChild = pChild->prevSib; 413 } 414 } 415 } 416 417 if(pTree && pTree->nextSib) { 418 tChild = pTree->parent->lastChild; 419 tLast = pTree->nextSib; 420 421 while(1) { 422 if(tChild->pWin->viewable) { 423 if (REGION_BROKEN (pScreen, &tChild->pWin->winSize)) 424 SetWinSize (tChild->pWin); 425 if (REGION_BROKEN (pScreen, &tChild->pWin->borderSize)) 426 SetBorderSize (tChild->pWin); 427 428 if(RECT_IN_REGION(pScreen, &(tChild->pWin->borderSize), box)) 429 { 430 MARK_UNDERLAY(tChild->pWin); 431 underMarked = TRUE; 432 } 433 } 434 435 if(tChild->lastChild) { 436 tChild = tChild->lastChild; 437 continue; 438 } 439 440 while(!tChild->prevSib && (tChild != tLast)) 441 tChild = tChild->parent; 442 443 if(tChild == tLast) break; 444 445 tChild = tChild->prevSib; 446 } 447 } 448 449 if(underMarked) { 450 MARK_UNDERLAY(pTree->parent->pWin); 451 MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->underlayMarked = TRUE; 452 } 453 454 return (underMarked || overMarked); 455} 456 457 458static void 459miOverlayComputeClips( 460 WindowPtr pParent, 461 RegionPtr universe, 462 VTKind kind, 463 RegionPtr exposed 464){ 465 ScreenPtr pScreen = pParent->drawable.pScreen; 466 int oldVis, newVis, dx, dy; 467 BoxRec borderSize; 468 RegionPtr borderVisible; 469 RegionRec childUniverse, childUnion; 470 miOverlayTreePtr tParent = MIOVERLAY_GET_WINDOW_TREE(pParent); 471 miOverlayTreePtr tChild; 472 Bool overlap; 473 474 borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent); 475 borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent); 476 dx = (int) pParent->drawable.x + (int) pParent->drawable.width + 477 wBorderWidth(pParent); 478 if (dx > 32767) dx = 32767; 479 borderSize.x2 = dx; 480 dy = (int) pParent->drawable.y + (int) pParent->drawable.height + 481 wBorderWidth(pParent); 482 if (dy > 32767) dy = 32767; 483 borderSize.y2 = dy; 484 485 oldVis = tParent->visibility; 486 switch (RECT_IN_REGION( pScreen, universe, &borderSize)) { 487 case rgnIN: 488 newVis = VisibilityUnobscured; 489 break; 490 case rgnPART: 491 newVis = VisibilityPartiallyObscured; 492#ifdef SHAPE 493 { 494 RegionPtr pBounding; 495 496 if ((pBounding = wBoundingShape (pParent))) { 497 switch (miShapedWindowIn (pScreen, universe, pBounding, 498 &borderSize, 499 pParent->drawable.x, 500 pParent->drawable.y)) 501 { 502 case rgnIN: 503 newVis = VisibilityUnobscured; 504 break; 505 case rgnOUT: 506 newVis = VisibilityFullyObscured; 507 break; 508 } 509 } 510 } 511#endif 512 break; 513 default: 514 newVis = VisibilityFullyObscured; 515 break; 516 } 517 tParent->visibility = newVis; 518 519 dx = pParent->drawable.x - tParent->valdata->oldAbsCorner.x; 520 dy = pParent->drawable.y - tParent->valdata->oldAbsCorner.y; 521 522 switch (kind) { 523 case VTMap: 524 case VTStack: 525 case VTUnmap: 526 break; 527 case VTMove: 528 if ((oldVis == newVis) && 529 ((oldVis == VisibilityFullyObscured) || 530 (oldVis == VisibilityUnobscured))) 531 { 532 tChild = tParent; 533 while (1) { 534 if (tChild->pWin->viewable) { 535 if (tChild->visibility != VisibilityFullyObscured) { 536 REGION_TRANSLATE( pScreen, &tChild->borderClip, dx, dy); 537 REGION_TRANSLATE( pScreen, &tChild->clipList, dx, dy); 538 539 tChild->pWin->drawable.serialNumber = 540 NEXT_SERIAL_NUMBER; 541 if (pScreen->ClipNotify) 542 (* pScreen->ClipNotify) (tChild->pWin, dx, dy); 543 } 544 if (tChild->valdata) { 545 REGION_NULL(pScreen, &tChild->valdata->borderExposed); 546 if (HasParentRelativeBorder(tChild->pWin)){ 547 REGION_SUBTRACT(pScreen, 548 &tChild->valdata->borderExposed, 549 &tChild->borderClip, 550 &tChild->pWin->winSize); 551 } 552 REGION_NULL(pScreen, &tChild->valdata->exposed); 553 } 554 if (tChild->firstChild) { 555 tChild = tChild->firstChild; 556 continue; 557 } 558 } 559 while (!tChild->nextSib && (tChild != tParent)) 560 tChild = tChild->parent; 561 if (tChild == tParent) 562 break; 563 tChild = tChild->nextSib; 564 } 565 return; 566 } 567 /* fall through */ 568 default: 569 if (dx || dy) { 570 REGION_TRANSLATE( pScreen, &tParent->borderClip, dx, dy); 571 REGION_TRANSLATE( pScreen, &tParent->clipList, dx, dy); 572 } 573 break; 574 case VTBroken: 575 REGION_EMPTY (pScreen, &tParent->borderClip); 576 REGION_EMPTY (pScreen, &tParent->clipList); 577 break; 578 } 579 580 borderVisible = tParent->valdata->borderVisible; 581 REGION_NULL(pScreen, &tParent->valdata->borderExposed); 582 REGION_NULL(pScreen, &tParent->valdata->exposed); 583 584 if (HasBorder (pParent)) { 585 if (borderVisible) { 586 REGION_SUBTRACT( pScreen, exposed, universe, borderVisible); 587 REGION_DESTROY( pScreen, borderVisible); 588 } else 589 REGION_SUBTRACT( pScreen, exposed, universe, &tParent->borderClip); 590 591 if (HasParentRelativeBorder(pParent) && (dx || dy)) 592 REGION_SUBTRACT( pScreen, &tParent->valdata->borderExposed, 593 universe, &pParent->winSize); 594 else 595 REGION_SUBTRACT( pScreen, &tParent->valdata->borderExposed, 596 exposed, &pParent->winSize); 597 598 REGION_COPY( pScreen, &tParent->borderClip, universe); 599 REGION_INTERSECT( pScreen, universe, universe, &pParent->winSize); 600 } 601 else 602 REGION_COPY( pScreen, &tParent->borderClip, universe); 603 604 if ((tChild = tParent->firstChild) && pParent->mapped) { 605 REGION_NULL(pScreen, &childUniverse); 606 REGION_NULL(pScreen, &childUnion); 607 608 for (; tChild; tChild = tChild->nextSib) { 609 if (tChild->pWin->viewable) 610 REGION_APPEND( pScreen, &childUnion, &tChild->pWin->borderSize); 611 } 612 613 REGION_VALIDATE( pScreen, &childUnion, &overlap); 614 615 for (tChild = tParent->firstChild; 616 tChild; 617 tChild = tChild->nextSib) 618 { 619 if (tChild->pWin->viewable) { 620 if (tChild->valdata) { 621 REGION_INTERSECT( pScreen, &childUniverse, universe, 622 &tChild->pWin->borderSize); 623 miOverlayComputeClips (tChild->pWin, &childUniverse, 624 kind, exposed); 625 } 626 if (overlap) 627 REGION_SUBTRACT( pScreen, universe, universe, 628 &tChild->pWin->borderSize); 629 } 630 } 631 if (!overlap) 632 REGION_SUBTRACT( pScreen, universe, universe, &childUnion); 633 REGION_UNINIT( pScreen, &childUnion); 634 REGION_UNINIT( pScreen, &childUniverse); 635 } 636 637 if (oldVis == VisibilityFullyObscured || 638 oldVis == VisibilityNotViewable) 639 { 640 REGION_COPY( pScreen, &tParent->valdata->exposed, universe); 641 } 642 else if (newVis != VisibilityFullyObscured && 643 newVis != VisibilityNotViewable) 644 { 645 REGION_SUBTRACT( pScreen, &tParent->valdata->exposed, 646 universe, &tParent->clipList); 647 } 648 649 /* HACK ALERT - copying contents of regions, instead of regions */ 650 { 651 RegionRec tmp; 652 653 tmp = tParent->clipList; 654 tParent->clipList = *universe; 655 *universe = tmp; 656 } 657 658 pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; 659 660 if (pScreen->ClipNotify) 661 (* pScreen->ClipNotify) (pParent, dx, dy); 662} 663 664 665static void 666miOverlayMarkWindow(WindowPtr pWin) 667{ 668 miOverlayTreePtr pTree = NULL; 669 WindowPtr pChild, pGrandChild; 670 671 miMarkWindow(pWin); 672 673 /* look for UnmapValdata among immediate children */ 674 675 if(!(pChild = pWin->firstChild)) return; 676 677 for( ; pChild; pChild = pChild->nextSib) { 678 if(pChild->valdata == UnmapValData) { 679 if(IN_UNDERLAY(pChild)) { 680 pTree = MIOVERLAY_GET_WINDOW_TREE(pChild); 681 pTree->valdata = (miOverlayValDataPtr)UnmapValData; 682 continue; 683 } else { 684 if(!(pGrandChild = pChild->firstChild)) 685 continue; 686 687 while(1) { 688 if(IN_UNDERLAY(pGrandChild)) { 689 pTree = MIOVERLAY_GET_WINDOW_TREE(pGrandChild); 690 pTree->valdata = (miOverlayValDataPtr)UnmapValData; 691 } else if(pGrandChild->firstChild) { 692 pGrandChild = pGrandChild->firstChild; 693 continue; 694 } 695 696 while(!pGrandChild->nextSib && (pGrandChild != pChild)) 697 pGrandChild = pGrandChild->parent; 698 699 if(pChild == pGrandChild) break; 700 701 pGrandChild = pGrandChild->nextSib; 702 } 703 } 704 } 705 } 706 707 if(pTree) { 708 MARK_UNDERLAY(pTree->parent->pWin); 709 MIOVERLAY_GET_SCREEN_PRIVATE( 710 pWin->drawable.pScreen)->underlayMarked = TRUE; 711 } 712} 713 714static void 715miOverlayMarkUnrealizedWindow( 716 WindowPtr pChild, 717 WindowPtr pWin, 718 Bool fromConfigure 719){ 720 if ((pChild != pWin) || fromConfigure) { 721 miOverlayTreePtr pTree; 722 723 REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList); 724 if (pChild->drawable.pScreen->ClipNotify) 725 (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0); 726 REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip); 727 if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) { 728 if(pTree->valdata != (miOverlayValDataPtr)UnmapValData) { 729 REGION_EMPTY(pChild->drawable.pScreen, &pTree->clipList); 730 REGION_EMPTY(pChild->drawable.pScreen, &pTree->borderClip); 731 } 732 } 733 } 734} 735 736 737static int 738miOverlayValidateTree( 739 WindowPtr pParent, 740 WindowPtr pChild, /* first child effected */ 741 VTKind kind 742){ 743 ScreenPtr pScreen = pParent->drawable.pScreen; 744 miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); 745 RegionRec totalClip, childClip, exposed; 746 miOverlayTreePtr tParent, tChild, tWin; 747 Bool overlap; 748 WindowPtr newParent; 749 750 if(!pPriv->underlayMarked) 751 goto SKIP_UNDERLAY; 752 753 if (!pChild) pChild = pParent->firstChild; 754 755 REGION_NULL(pScreen, &totalClip); 756 REGION_NULL(pScreen, &childClip); 757 REGION_NULL(pScreen, &exposed); 758 759 newParent = pParent; 760 761 while(IN_OVERLAY(newParent)) 762 newParent = newParent->parent; 763 764 tParent = MIOVERLAY_GET_WINDOW_TREE(newParent); 765 766 if(IN_UNDERLAY(pChild)) 767 tChild = MIOVERLAY_GET_WINDOW_TREE(pChild); 768 else 769 tChild = tParent->firstChild; 770 771 if (REGION_BROKEN (pScreen, &tParent->clipList) && 772 !REGION_BROKEN (pScreen, &tParent->borderClip)) 773 { 774 kind = VTBroken; 775 REGION_COPY (pScreen, &totalClip, &tParent->borderClip); 776 REGION_INTERSECT (pScreen, &totalClip, &totalClip, 777 &tParent->pWin->winSize); 778 779 for (tWin = tParent->firstChild; tWin != tChild; tWin = tWin->nextSib) { 780 if (tWin->pWin->viewable) 781 REGION_SUBTRACT (pScreen, &totalClip, &totalClip, 782 &tWin->pWin->borderSize); 783 } 784 REGION_EMPTY (pScreen, &tParent->clipList); 785 } else { 786 for(tWin = tChild; tWin; tWin = tWin->nextSib) { 787 if(tWin->valdata) 788 REGION_APPEND(pScreen, &totalClip, &tWin->borderClip); 789 } 790 REGION_VALIDATE(pScreen, &totalClip, &overlap); 791 } 792 793 if(kind != VTStack) 794 REGION_UNION(pScreen, &totalClip, &totalClip, &tParent->clipList); 795 796 for(tWin = tChild; tWin; tWin = tWin->nextSib) { 797 if(tWin->valdata) { 798 if(tWin->pWin->viewable) { 799 REGION_INTERSECT(pScreen, &childClip, &totalClip, 800 &tWin->pWin->borderSize); 801 miOverlayComputeClips(tWin->pWin, &childClip, kind, &exposed); 802 REGION_SUBTRACT(pScreen, &totalClip, &totalClip, 803 &tWin->pWin->borderSize); 804 } else { /* Means we are unmapping */ 805 REGION_EMPTY(pScreen, &tWin->clipList); 806 REGION_EMPTY( pScreen, &tWin->borderClip); 807 tWin->valdata = NULL; 808 } 809 } 810 } 811 812 REGION_UNINIT(pScreen, &childClip); 813 814 if(!((*pPriv->InOverlay)(newParent))) { 815 REGION_NULL(pScreen, &tParent->valdata->exposed); 816 REGION_NULL(pScreen, &tParent->valdata->borderExposed); 817 } 818 819 switch (kind) { 820 case VTStack: 821 break; 822 default: 823 if(!((*pPriv->InOverlay)(newParent))) 824 REGION_SUBTRACT(pScreen, &tParent->valdata->exposed, &totalClip, 825 &tParent->clipList); 826 /* fall through */ 827 case VTMap: 828 REGION_COPY( pScreen, &tParent->clipList, &totalClip); 829 if(!((*pPriv->InOverlay)(newParent))) 830 newParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; 831 break; 832 } 833 834 REGION_UNINIT( pScreen, &totalClip); 835 REGION_UNINIT( pScreen, &exposed); 836 837SKIP_UNDERLAY: 838 839 miValidateTree(pParent, pChild, kind); 840 841 return 1; 842} 843 844 845static void 846miOverlayHandleExposures(WindowPtr pWin) 847{ 848 ScreenPtr pScreen = pWin->drawable.pScreen; 849 miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); 850 WindowPtr pChild; 851 ValidatePtr val; 852 void (* WindowExposures)(WindowPtr, RegionPtr, RegionPtr); 853 854 WindowExposures = pWin->drawable.pScreen->WindowExposures; 855 if(pPriv->underlayMarked) { 856 miOverlayTreePtr pTree; 857 miOverlayValDataPtr mival; 858 859 pChild = pWin; 860 while(IN_OVERLAY(pChild)) 861 pChild = pChild->parent; 862 863 pTree = MIOVERLAY_GET_WINDOW_TREE(pChild); 864 865 while (1) { 866 if((mival = pTree->valdata)) { 867 if(!((*pPriv->InOverlay)(pTree->pWin))) { 868 if (REGION_NOTEMPTY(pScreen, &mival->borderExposed)) 869 (*pWin->drawable.pScreen->PaintWindowBorder)( 870 pTree->pWin, &mival->borderExposed, PW_BORDER); 871 REGION_UNINIT(pScreen, &mival->borderExposed); 872 873 (*WindowExposures)(pTree->pWin,&mival->exposed,NullRegion); 874 REGION_UNINIT(pScreen, &mival->exposed); 875 } 876 xfree(mival); 877 pTree->valdata = NULL; 878 if (pTree->firstChild) { 879 pTree = pTree->firstChild; 880 continue; 881 } 882 } 883 while (!pTree->nextSib && (pTree->pWin != pChild)) 884 pTree = pTree->parent; 885 if (pTree->pWin == pChild) 886 break; 887 pTree = pTree->nextSib; 888 } 889 pPriv->underlayMarked = FALSE; 890 } 891 892 pChild = pWin; 893 while (1) { 894 if ( (val = pChild->valdata) ) { 895 if(!((*pPriv->InOverlay)(pChild))) { 896 REGION_UNION(pScreen, &val->after.exposed, &val->after.exposed, 897 &val->after.borderExposed); 898 899 if (REGION_NOTEMPTY(pScreen, &val->after.exposed)) { 900 (*(MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent))( 901 pScreen, 902 REGION_NUM_RECTS(&val->after.exposed), 903 REGION_RECTS(&val->after.exposed)); 904 } 905 } else { 906 if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed)) 907 (*pChild->drawable.pScreen->PaintWindowBorder)(pChild, 908 &val->after.borderExposed, 909 PW_BORDER); 910 (*WindowExposures)(pChild, &val->after.exposed, NullRegion); 911 } 912 REGION_UNINIT(pScreen, &val->after.borderExposed); 913 REGION_UNINIT(pScreen, &val->after.exposed); 914 xfree(val); 915 pChild->valdata = (ValidatePtr)NULL; 916 if (pChild->firstChild) 917 { 918 pChild = pChild->firstChild; 919 continue; 920 } 921 } 922 while (!pChild->nextSib && (pChild != pWin)) 923 pChild = pChild->parent; 924 if (pChild == pWin) 925 break; 926 pChild = pChild->nextSib; 927 } 928} 929 930 931static void 932miOverlayMoveWindow( 933 WindowPtr pWin, 934 int x, 935 int y, 936 WindowPtr pNextSib, 937 VTKind kind 938){ 939 ScreenPtr pScreen = pWin->drawable.pScreen; 940 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 941 WindowPtr pParent, windowToValidate; 942 Bool WasViewable = (Bool)(pWin->viewable); 943 short bw; 944 RegionRec overReg, underReg; 945 DDXPointRec oldpt; 946#ifdef DO_SAVE_UNDERS 947 Bool dosave = FALSE; 948#endif 949 950 if (!(pParent = pWin->parent)) 951 return ; 952 bw = wBorderWidth (pWin); 953 954 oldpt.x = pWin->drawable.x; 955 oldpt.y = pWin->drawable.y; 956 if (WasViewable) { 957 REGION_NULL(pScreen, &overReg); 958 REGION_NULL(pScreen, &underReg); 959 if(pTree) { 960 REGION_COPY(pScreen, &overReg, &pWin->borderClip); 961 REGION_COPY(pScreen, &underReg, &pTree->borderClip); 962 } else { 963 REGION_COPY(pScreen, &overReg, &pWin->borderClip); 964 CollectUnderlayChildrenRegions(pWin, &underReg); 965 } 966 (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL); 967 } 968 pWin->origin.x = x + (int)bw; 969 pWin->origin.y = y + (int)bw; 970 x = pWin->drawable.x = pParent->drawable.x + x + (int)bw; 971 y = pWin->drawable.y = pParent->drawable.y + y + (int)bw; 972 973 SetWinSize (pWin); 974 SetBorderSize (pWin); 975 976 (*pScreen->PositionWindow)(pWin, x, y); 977 978 windowToValidate = MoveWindowInStack(pWin, pNextSib); 979 980 ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0); 981 982 if (WasViewable) { 983 miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); 984 (*pScreen->MarkOverlappedWindows) (pWin, windowToValidate, NULL); 985 986#ifdef DO_SAVE_UNDERS 987 if (DO_SAVE_UNDERS(pWin)) 988 dosave = (*pScreen->ChangeSaveUnder)(pWin, windowToValidate); 989#endif /* DO_SAVE_UNDERS */ 990 991 (*pScreen->ValidateTree)(pWin->parent, NullWindow, kind); 992 if(REGION_NOTEMPTY(pScreen, &underReg)) { 993 pPriv->copyUnderlay = TRUE; 994 (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, &underReg); 995 } 996 REGION_UNINIT(pScreen, &underReg); 997 if(REGION_NOTEMPTY(pScreen, &overReg)) { 998 pPriv->copyUnderlay = FALSE; 999 (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, &overReg); 1000 } 1001 REGION_UNINIT(pScreen, &overReg); 1002 (*pScreen->HandleExposures)(pWin->parent); 1003 1004#ifdef DO_SAVE_UNDERS 1005 if (dosave) 1006 (*pScreen->PostChangeSaveUnder)(pWin, windowToValidate); 1007#endif /* DO_SAVE_UNDERS */ 1008 if (pScreen->PostValidateTree) 1009 (*pScreen->PostValidateTree)(pWin->parent, NullWindow, kind); 1010 } 1011 if (pWin->realized) 1012 WindowsRestructured (); 1013} 1014 1015#ifndef RECTLIMIT 1016#define RECTLIMIT 25 1017#endif 1018 1019static void 1020miOverlayWindowExposures( 1021 WindowPtr pWin, 1022 RegionPtr prgn, 1023 RegionPtr other_exposed 1024){ 1025 RegionPtr exposures = prgn; 1026 ScreenPtr pScreen = pWin->drawable.pScreen; 1027 1028 if (pWin->backStorage && prgn) 1029 exposures = (*pScreen->RestoreAreas)(pWin, prgn); 1030 if ((prgn && !REGION_NIL(prgn)) || 1031 (exposures && !REGION_NIL(exposures)) || other_exposed) 1032 { 1033 RegionRec expRec; 1034 int clientInterested; 1035 1036 clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & 1037 ExposureMask; 1038 if (other_exposed) { 1039 if (exposures) { 1040 REGION_UNION(pScreen, other_exposed, exposures, other_exposed); 1041 if (exposures != prgn) 1042 REGION_DESTROY(pScreen, exposures); 1043 } 1044 exposures = other_exposed; 1045 } 1046 if (clientInterested && exposures && 1047 (REGION_NUM_RECTS(exposures) > RECTLIMIT)) 1048 { 1049 miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); 1050 BoxRec box; 1051 1052 box = *REGION_EXTENTS(pScreen, exposures); 1053 if (exposures == prgn) { 1054 exposures = &expRec; 1055 REGION_INIT(pScreen, exposures, &box, 1); 1056 REGION_RESET(pScreen, prgn, &box); 1057 } else { 1058 REGION_RESET(pScreen, exposures, &box); 1059 REGION_UNION(pScreen, prgn, prgn, exposures); 1060 } 1061 /* This is the only reason why we are replacing mi's version 1062 of this file */ 1063 1064 if(!((*pPriv->InOverlay)(pWin))) { 1065 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 1066 REGION_INTERSECT(pScreen, prgn, prgn, &pTree->clipList); 1067 } else 1068 REGION_INTERSECT(pScreen, prgn, prgn, &pWin->clipList); 1069 1070 /* need to clear out new areas of backing store, too */ 1071 if (pWin->backStorage) 1072 (void) (*pScreen->ClearBackingStore)( 1073 pWin, 1074 box.x1 - pWin->drawable.x, 1075 box.y1 - pWin->drawable.y, 1076 box.x2 - box.x1, 1077 box.y2 - box.y1, 1078 FALSE); 1079 } 1080 if (prgn && !REGION_NIL(prgn)) 1081 (*pScreen->PaintWindowBackground)( 1082 pWin, prgn, PW_BACKGROUND); 1083 if (clientInterested && exposures && !REGION_NIL(exposures)) 1084 miSendExposures(pWin, exposures, 1085 pWin->drawable.x, pWin->drawable.y); 1086 if (exposures == &expRec) { 1087 REGION_UNINIT(pScreen, exposures); 1088 } 1089 else if (exposures && exposures != prgn && exposures != other_exposed) 1090 REGION_DESTROY(pScreen, exposures); 1091 if (prgn) 1092 REGION_EMPTY(pScreen, prgn); 1093 } 1094 else if (exposures && exposures != prgn) 1095 REGION_DESTROY(pScreen, exposures); 1096} 1097 1098 1099typedef struct { 1100 RegionPtr over; 1101 RegionPtr under; 1102} miOverlayTwoRegions; 1103 1104static int 1105miOverlayRecomputeExposures ( 1106 WindowPtr pWin, 1107 pointer value 1108){ 1109 ScreenPtr pScreen; 1110 miOverlayTwoRegions *pValid = (miOverlayTwoRegions*)value; 1111 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 1112 1113 /* This prevents warning about pScreen not being used. */ 1114 pWin->drawable.pScreen = pScreen = pWin->drawable.pScreen; 1115 1116 if (pWin->valdata) { 1117 /* 1118 * compute exposed regions of this window 1119 */ 1120 REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed, 1121 &pWin->clipList, pValid->over); 1122 /* 1123 * compute exposed regions of the border 1124 */ 1125 REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed, 1126 &pWin->borderClip, &pWin->winSize); 1127 REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed, 1128 &pWin->valdata->after.borderExposed, pValid->over); 1129 } 1130 1131 if(pTree && pTree->valdata) { 1132 REGION_SUBTRACT(pScreen, &pTree->valdata->exposed, 1133 &pTree->clipList, pValid->under); 1134 REGION_SUBTRACT(pScreen, &pTree->valdata->borderExposed, 1135 &pTree->borderClip, &pWin->winSize); 1136 REGION_SUBTRACT(pScreen, &pTree->valdata->borderExposed, 1137 &pTree->valdata->borderExposed, pValid->under); 1138 } else if (!pWin->valdata) 1139 return WT_NOMATCH; 1140 1141 return WT_WALKCHILDREN; 1142} 1143 1144static void 1145miOverlayResizeWindow( 1146 WindowPtr pWin, 1147 int x, int y, 1148 unsigned int w, unsigned int h, 1149 WindowPtr pSib 1150){ 1151 ScreenPtr pScreen = pWin->drawable.pScreen; 1152 WindowPtr pParent; 1153 miOverlayTreePtr tChild, pTree; 1154 Bool WasViewable = (Bool)(pWin->viewable); 1155 unsigned short width = pWin->drawable.width; 1156 unsigned short height = pWin->drawable.height; 1157 short oldx = pWin->drawable.x; 1158 short oldy = pWin->drawable.y; 1159 int bw = wBorderWidth (pWin); 1160 short dw, dh; 1161 DDXPointRec oldpt; 1162 RegionPtr oldRegion = NULL, oldRegion2 = NULL; 1163 WindowPtr pFirstChange; 1164 WindowPtr pChild; 1165 RegionPtr gravitate[StaticGravity + 1]; 1166 RegionPtr gravitate2[StaticGravity + 1]; 1167 unsigned g; 1168 int nx, ny; /* destination x,y */ 1169 int newx, newy; /* new inner window position */ 1170 RegionPtr pRegion = NULL; 1171 RegionPtr destClip, destClip2; 1172 RegionPtr oldWinClip = NULL, oldWinClip2 = NULL; 1173 RegionPtr borderVisible = NullRegion; 1174 RegionPtr borderVisible2 = NullRegion; 1175 RegionPtr bsExposed = NullRegion; /* backing store exposures */ 1176 Bool shrunk = FALSE; /* shrunk in an inner dimension */ 1177 Bool moved = FALSE; /* window position changed */ 1178#ifdef DO_SAVE_UNDERS 1179 Bool dosave = FALSE; 1180#endif 1181 Bool doUnderlay; 1182 1183 /* if this is a root window, can't be resized */ 1184 if (!(pParent = pWin->parent)) 1185 return ; 1186 1187 pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 1188 doUnderlay = ((pTree) || HasUnderlayChildren(pWin)); 1189 newx = pParent->drawable.x + x + bw; 1190 newy = pParent->drawable.y + y + bw; 1191 if (WasViewable) 1192 { 1193 /* 1194 * save the visible region of the window 1195 */ 1196 oldRegion = REGION_CREATE(pScreen, NullBox, 1); 1197 REGION_COPY(pScreen, oldRegion, &pWin->winSize); 1198 if(doUnderlay) { 1199 oldRegion2 = REGION_CREATE(pScreen, NullBox, 1); 1200 REGION_COPY(pScreen, oldRegion2, &pWin->winSize); 1201 } 1202 1203 /* 1204 * categorize child windows into regions to be moved 1205 */ 1206 for (g = 0; g <= StaticGravity; g++) 1207 gravitate[g] = gravitate2[g] = NULL; 1208 for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { 1209 g = pChild->winGravity; 1210 if (g != UnmapGravity) { 1211 if (!gravitate[g]) 1212 gravitate[g] = REGION_CREATE(pScreen, NullBox, 1); 1213 REGION_UNION(pScreen, gravitate[g], 1214 gravitate[g], &pChild->borderClip); 1215 1216 if(doUnderlay) { 1217 if (!gravitate2[g]) 1218 gravitate2[g] = REGION_CREATE(pScreen, NullBox, 0); 1219 1220 if((tChild = MIOVERLAY_GET_WINDOW_TREE(pChild))) { 1221 REGION_UNION(pScreen, gravitate2[g], 1222 gravitate2[g], &tChild->borderClip); 1223 } else 1224 CollectUnderlayChildrenRegions(pChild, gravitate2[g]); 1225 } 1226 } else { 1227 UnmapWindow(pChild, TRUE); 1228 } 1229 } 1230 (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL); 1231 1232 1233 oldWinClip = oldWinClip2 = NULL; 1234 if (pWin->bitGravity != ForgetGravity) { 1235 oldWinClip = REGION_CREATE(pScreen, NullBox, 1); 1236 REGION_COPY(pScreen, oldWinClip, &pWin->clipList); 1237 if(pTree) { 1238 oldWinClip2 = REGION_CREATE(pScreen, NullBox, 1); 1239 REGION_COPY(pScreen, oldWinClip2, &pTree->clipList); 1240 } 1241 } 1242 /* 1243 * if the window is changing size, borderExposed 1244 * can't be computed correctly without some help. 1245 */ 1246 if (pWin->drawable.height > h || pWin->drawable.width > w) 1247 shrunk = TRUE; 1248 1249 if (newx != oldx || newy != oldy) 1250 moved = TRUE; 1251 1252 if ((pWin->drawable.height != h || pWin->drawable.width != w) && 1253 HasBorder (pWin)) 1254 { 1255 borderVisible = REGION_CREATE(pScreen, NullBox, 1); 1256 if(pTree) 1257 borderVisible2 = REGION_CREATE(pScreen, NullBox, 1); 1258 /* for tiled borders, we punt and draw the whole thing */ 1259 if (pWin->borderIsPixel || !moved) 1260 { 1261 if (shrunk || moved) 1262 REGION_SUBTRACT(pScreen, borderVisible, 1263 &pWin->borderClip, 1264 &pWin->winSize); 1265 else 1266 REGION_COPY(pScreen, borderVisible, 1267 &pWin->borderClip); 1268 if(pTree) { 1269 if (shrunk || moved) 1270 REGION_SUBTRACT(pScreen, borderVisible, 1271 &pTree->borderClip, 1272 &pWin->winSize); 1273 else 1274 REGION_COPY(pScreen, borderVisible, 1275 &pTree->borderClip); 1276 } 1277 } 1278 } 1279 } 1280 pWin->origin.x = x + bw; 1281 pWin->origin.y = y + bw; 1282 pWin->drawable.height = h; 1283 pWin->drawable.width = w; 1284 1285 x = pWin->drawable.x = newx; 1286 y = pWin->drawable.y = newy; 1287 1288 SetWinSize (pWin); 1289 SetBorderSize (pWin); 1290 1291 dw = (int)w - (int)width; 1292 dh = (int)h - (int)height; 1293 ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh); 1294 1295 /* let the hardware adjust background and border pixmaps, if any */ 1296 (*pScreen->PositionWindow)(pWin, x, y); 1297 1298 pFirstChange = MoveWindowInStack(pWin, pSib); 1299 1300 if (WasViewable) { 1301 pRegion = REGION_CREATE(pScreen, NullBox, 1); 1302 if (pWin->backStorage) 1303 REGION_COPY(pScreen, pRegion, &pWin->clipList); 1304 1305 (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange, NULL); 1306 1307 pWin->valdata->before.resized = TRUE; 1308 pWin->valdata->before.borderVisible = borderVisible; 1309 if(pTree) 1310 pTree->valdata->borderVisible = borderVisible2; 1311 1312#ifdef DO_SAVE_UNDERS 1313 if (DO_SAVE_UNDERS(pWin)) 1314 dosave = (*pScreen->ChangeSaveUnder)(pWin, pFirstChange); 1315#endif /* DO_SAVE_UNDERS */ 1316 1317 (*pScreen->ValidateTree)(pWin->parent, pFirstChange, VTOther); 1318 /* 1319 * the entire window is trashed unless bitGravity 1320 * recovers portions of it 1321 */ 1322 REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList); 1323 if(pTree) 1324 REGION_COPY(pScreen, &pTree->valdata->exposed, &pTree->clipList); 1325 } 1326 1327 GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny); 1328 1329 if (pWin->backStorage && ((pWin->backingStore == Always) || WasViewable)) { 1330 if (!WasViewable) 1331 pRegion = &pWin->clipList; /* a convenient empty region */ 1332 if (pWin->bitGravity == ForgetGravity) 1333 bsExposed = (*pScreen->TranslateBackingStore) 1334 (pWin, 0, 0, NullRegion, oldx, oldy); 1335 else 1336 bsExposed = (*pScreen->TranslateBackingStore) 1337 (pWin, nx - x, ny - y, pRegion, oldx, oldy); 1338 } 1339 1340 if (WasViewable) { 1341 miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); 1342 miOverlayTwoRegions TwoRegions; 1343 1344 /* avoid the border */ 1345 if (HasBorder (pWin)) { 1346 int offx, offy, dx, dy; 1347 1348 /* kruft to avoid double translates for each gravity */ 1349 offx = 0; 1350 offy = 0; 1351 for (g = 0; g <= StaticGravity; g++) { 1352 if (!gravitate[g] && !gravitate2[g]) 1353 continue; 1354 1355 /* align winSize to gravitate[g]. 1356 * winSize is in new coordinates, 1357 * gravitate[g] is still in old coordinates */ 1358 GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny); 1359 1360 dx = (oldx - nx) - offx; 1361 dy = (oldy - ny) - offy; 1362 if (dx || dy) { 1363 REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy); 1364 offx += dx; 1365 offy += dy; 1366 } 1367 if(gravitate[g]) 1368 REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], 1369 &pWin->winSize); 1370 if(gravitate2[g]) 1371 REGION_INTERSECT(pScreen, gravitate2[g], gravitate2[g], 1372 &pWin->winSize); 1373 } 1374 /* get winSize back where it belongs */ 1375 if (offx || offy) 1376 REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy); 1377 } 1378 /* 1379 * add screen bits to the appropriate bucket 1380 */ 1381 1382 if (oldWinClip2) 1383 { 1384 REGION_COPY(pScreen, pRegion, oldWinClip2); 1385 REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy); 1386 REGION_INTERSECT(pScreen, oldWinClip2, pRegion, &pTree->clipList); 1387 1388 for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) { 1389 if (gravitate2[g]) 1390 REGION_SUBTRACT(pScreen, oldWinClip2, oldWinClip2, 1391 gravitate2[g]); 1392 } 1393 REGION_TRANSLATE(pScreen, oldWinClip2, oldx - nx, oldy - ny); 1394 g = pWin->bitGravity; 1395 if (!gravitate2[g]) 1396 gravitate2[g] = oldWinClip2; 1397 else { 1398 REGION_UNION(pScreen,gravitate2[g],gravitate2[g],oldWinClip2); 1399 REGION_DESTROY(pScreen, oldWinClip2); 1400 } 1401 } 1402 1403 if (oldWinClip) 1404 { 1405 /* 1406 * clip to new clipList 1407 */ 1408 REGION_COPY(pScreen, pRegion, oldWinClip); 1409 REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy); 1410 REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList); 1411 /* 1412 * don't step on any gravity bits which will be copied after this 1413 * region. Note -- this assumes that the regions will be copied 1414 * in gravity order. 1415 */ 1416 for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) { 1417 if (gravitate[g]) 1418 REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip, 1419 gravitate[g]); 1420 } 1421 REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny); 1422 g = pWin->bitGravity; 1423 if (!gravitate[g]) 1424 gravitate[g] = oldWinClip; 1425 else { 1426 REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip); 1427 REGION_DESTROY(pScreen, oldWinClip); 1428 } 1429 } 1430 1431 /* 1432 * move the bits on the screen 1433 */ 1434 1435 destClip = destClip2 = NULL; 1436 1437 for (g = 0; g <= StaticGravity; g++) { 1438 if (!gravitate[g] && !gravitate2[g]) 1439 continue; 1440 1441 GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny); 1442 1443 oldpt.x = oldx + (x - nx); 1444 oldpt.y = oldy + (y - ny); 1445 1446 /* Note that gravitate[g] is *translated* by CopyWindow */ 1447 1448 /* only copy the remaining useful bits */ 1449 1450 if(gravitate[g]) 1451 REGION_INTERSECT(pScreen, gravitate[g], 1452 gravitate[g], oldRegion); 1453 if(gravitate2[g]) 1454 REGION_INTERSECT(pScreen, gravitate2[g], 1455 gravitate2[g], oldRegion2); 1456 1457 /* clip to not overwrite already copied areas */ 1458 1459 if (destClip && gravitate[g]) { 1460 REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y); 1461 REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip); 1462 REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y); 1463 } 1464 if (destClip2 && gravitate2[g]) { 1465 REGION_TRANSLATE(pScreen, destClip2, oldpt.x - x, oldpt.y - y); 1466 REGION_SUBTRACT(pScreen,gravitate2[g],gravitate2[g],destClip2); 1467 REGION_TRANSLATE(pScreen, destClip2, x - oldpt.x, y - oldpt.y); 1468 } 1469 1470 /* and move those bits */ 1471 1472 if (oldpt.x != x || oldpt.y != y) { 1473 if(gravitate2[g]) { 1474 pPriv->copyUnderlay = TRUE; 1475 (*pWin->drawable.pScreen->CopyWindow)( 1476 pWin, oldpt, gravitate2[g]); 1477 } 1478 if(gravitate[g]) { 1479 pPriv->copyUnderlay = FALSE; 1480 (*pWin->drawable.pScreen->CopyWindow)( 1481 pWin, oldpt, gravitate[g]); 1482 } 1483 } 1484 1485 /* remove any overwritten bits from the remaining useful bits */ 1486 1487 if(gravitate[g]) 1488 REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]); 1489 if(gravitate2[g]) 1490 REGION_SUBTRACT(pScreen, oldRegion2, oldRegion2, gravitate2[g]); 1491 1492 /* 1493 * recompute exposed regions of child windows 1494 */ 1495 1496 1497 for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { 1498 if (pChild->winGravity != g) 1499 continue; 1500 1501 TwoRegions.over = gravitate[g]; 1502 TwoRegions.under = gravitate2[g]; 1503 1504 TraverseTree (pChild, miOverlayRecomputeExposures, 1505 (pointer)(&TwoRegions)); 1506 } 1507 1508 /* 1509 * remove the successfully copied regions of the 1510 * window from its exposed region 1511 */ 1512 1513 if (g == pWin->bitGravity) { 1514 if(gravitate[g]) 1515 REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed, 1516 &pWin->valdata->after.exposed, gravitate[g]); 1517 if(gravitate2[g] && pTree) 1518 REGION_SUBTRACT(pScreen, &pTree->valdata->exposed, 1519 &pTree->valdata->exposed, gravitate2[g]); 1520 } 1521 if(gravitate[g]) { 1522 if (!destClip) 1523 destClip = gravitate[g]; 1524 else { 1525 REGION_UNION(pScreen, destClip, destClip, gravitate[g]); 1526 REGION_DESTROY(pScreen, gravitate[g]); 1527 } 1528 } 1529 if(gravitate2[g]) { 1530 if (!destClip2) 1531 destClip2 = gravitate2[g]; 1532 else { 1533 REGION_UNION(pScreen, destClip2, destClip2, gravitate2[g]); 1534 REGION_DESTROY(pScreen, gravitate2[g]); 1535 } 1536 } 1537 } 1538 1539 REGION_DESTROY(pScreen, pRegion); 1540 REGION_DESTROY(pScreen, oldRegion); 1541 if(doUnderlay) 1542 REGION_DESTROY(pScreen, oldRegion2); 1543 if (destClip) 1544 REGION_DESTROY(pScreen, destClip); 1545 if (destClip2) 1546 REGION_DESTROY(pScreen, destClip2); 1547 if (bsExposed) { 1548 RegionPtr valExposed = NullRegion; 1549 1550 if (pWin->valdata) 1551 valExposed = &pWin->valdata->after.exposed; 1552 (*pScreen->WindowExposures) (pWin, valExposed, bsExposed); 1553 if (valExposed) 1554 REGION_EMPTY(pScreen, valExposed); 1555 REGION_DESTROY(pScreen, bsExposed); 1556 } 1557 (*pScreen->HandleExposures)(pWin->parent); 1558#ifdef DO_SAVE_UNDERS 1559 if (dosave) 1560 (*pScreen->PostChangeSaveUnder)(pWin, pFirstChange); 1561#endif /* DO_SAVE_UNDERS */ 1562 if (pScreen->PostValidateTree) 1563 (*pScreen->PostValidateTree)(pWin->parent, pFirstChange, VTOther); 1564 } 1565 else if (bsExposed) { 1566 (*pScreen->WindowExposures) (pWin, NullRegion, bsExposed); 1567 REGION_DESTROY(pScreen, bsExposed); 1568 } 1569 if (pWin->realized) 1570 WindowsRestructured (); 1571} 1572 1573 1574#ifdef SHAPE 1575static void 1576miOverlaySetShape(WindowPtr pWin) 1577{ 1578 Bool WasViewable = (Bool)(pWin->viewable); 1579 ScreenPtr pScreen = pWin->drawable.pScreen; 1580 RegionPtr pOldClip = NULL, bsExposed; 1581#ifdef DO_SAVE_UNDERS 1582 Bool dosave = FALSE; 1583#endif 1584 1585 if (WasViewable) { 1586 (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL); 1587 1588 if (HasBorder (pWin)) { 1589 RegionPtr borderVisible; 1590 1591 borderVisible = REGION_CREATE(pScreen, NullBox, 1); 1592 REGION_SUBTRACT(pScreen, borderVisible, 1593 &pWin->borderClip, &pWin->winSize); 1594 pWin->valdata->before.borderVisible = borderVisible; 1595 pWin->valdata->before.resized = TRUE; 1596 if(IN_UNDERLAY(pWin)) { 1597 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 1598 RegionPtr borderVisible2; 1599 1600 borderVisible2 = REGION_CREATE(pScreen, NULL, 1); 1601 REGION_SUBTRACT(pScreen, borderVisible2, 1602 &pTree->borderClip, &pWin->winSize); 1603 pTree->valdata->borderVisible = borderVisible2; 1604 } 1605 } 1606 } 1607 1608 SetWinSize (pWin); 1609 SetBorderSize (pWin); 1610 1611 ResizeChildrenWinSize(pWin, 0, 0, 0, 0); 1612 1613 if (WasViewable) { 1614 if (pWin->backStorage) { 1615 pOldClip = REGION_CREATE(pScreen, NullBox, 1); 1616 REGION_COPY(pScreen, pOldClip, &pWin->clipList); 1617 } 1618 1619 (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL); 1620 1621#ifdef DO_SAVE_UNDERS 1622 if (DO_SAVE_UNDERS(pWin)) 1623 dosave = (*pScreen->ChangeSaveUnder)(pWin, pWin); 1624#endif /* DO_SAVE_UNDERS */ 1625 1626 (*pScreen->ValidateTree)(pWin->parent, NullWindow, VTOther); 1627 } 1628 1629 if (pWin->backStorage && ((pWin->backingStore == Always) || WasViewable)) { 1630 if (!WasViewable) 1631 pOldClip = &pWin->clipList; /* a convenient empty region */ 1632 bsExposed = (*pScreen->TranslateBackingStore) 1633 (pWin, 0, 0, pOldClip, 1634 pWin->drawable.x, pWin->drawable.y); 1635 if (WasViewable) 1636 REGION_DESTROY(pScreen, pOldClip); 1637 if (bsExposed) 1638 { 1639 RegionPtr valExposed = NullRegion; 1640 1641 if (pWin->valdata) 1642 valExposed = &pWin->valdata->after.exposed; 1643 (*pScreen->WindowExposures) (pWin, valExposed, bsExposed); 1644 if (valExposed) 1645 REGION_EMPTY(pScreen, valExposed); 1646 REGION_DESTROY(pScreen, bsExposed); 1647 } 1648 } 1649 if (WasViewable) { 1650 (*pScreen->HandleExposures)(pWin->parent); 1651#ifdef DO_SAVE_UNDERS 1652 if (dosave) 1653 (*pScreen->PostChangeSaveUnder)(pWin, pWin); 1654#endif /* DO_SAVE_UNDERS */ 1655 if (pScreen->PostValidateTree) 1656 (*pScreen->PostValidateTree)(pWin->parent, NullWindow, VTOther); 1657 } 1658 if (pWin->realized) 1659 WindowsRestructured (); 1660 CheckCursorConfinement(pWin); 1661} 1662#endif 1663 1664 1665 1666static void 1667miOverlayChangeBorderWidth( 1668 WindowPtr pWin, 1669 unsigned int width 1670){ 1671 int oldwidth; 1672 ScreenPtr pScreen; 1673 Bool WasViewable = (Bool)(pWin->viewable); 1674 Bool HadBorder; 1675#ifdef DO_SAVE_UNDERS 1676 Bool dosave = FALSE; 1677#endif 1678 1679 oldwidth = wBorderWidth (pWin); 1680 if (oldwidth == width) 1681 return; 1682 HadBorder = HasBorder(pWin); 1683 pScreen = pWin->drawable.pScreen; 1684 if (WasViewable && (width < oldwidth)) 1685 (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL); 1686 1687 pWin->borderWidth = width; 1688 SetBorderSize (pWin); 1689 1690 if (WasViewable) { 1691 if (width > oldwidth) { 1692 (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL); 1693 1694 if (HadBorder) { 1695 RegionPtr borderVisible; 1696 borderVisible = REGION_CREATE(pScreen, NULL, 1); 1697 REGION_SUBTRACT(pScreen, borderVisible, 1698 &pWin->borderClip, &pWin->winSize); 1699 pWin->valdata->before.borderVisible = borderVisible; 1700 if(IN_UNDERLAY(pWin)) { 1701 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 1702 RegionPtr borderVisible2; 1703 1704 borderVisible2 = REGION_CREATE(pScreen, NULL, 1); 1705 REGION_SUBTRACT(pScreen, borderVisible2, 1706 &pTree->borderClip, &pWin->winSize); 1707 pTree->valdata->borderVisible = borderVisible2; 1708 } 1709 } 1710 } 1711#ifdef DO_SAVE_UNDERS 1712 if (DO_SAVE_UNDERS(pWin)) 1713 dosave = (*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib); 1714#endif /* DO_SAVE_UNDERS */ 1715 (*pScreen->ValidateTree)(pWin->parent, pWin, VTOther); 1716 (*pScreen->HandleExposures)(pWin->parent); 1717 1718#ifdef DO_SAVE_UNDERS 1719 if (dosave) 1720 (*pScreen->PostChangeSaveUnder)(pWin, pWin->nextSib); 1721#endif /* DO_SAVE_UNDERS */ 1722 if (pScreen->PostValidateTree) 1723 (*pScreen->PostValidateTree)(pWin->parent, pWin, VTOther); 1724 } 1725 if (pWin->realized) 1726 WindowsRestructured (); 1727} 1728 1729/* We need this as an addition since the xf86 common code doesn't 1730 know about the second tree which is static to this file. */ 1731 1732_X_EXPORT void 1733miOverlaySetRootClip(ScreenPtr pScreen, Bool enable) 1734{ 1735 WindowPtr pRoot = WindowTable[pScreen->myNum]; 1736 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pRoot); 1737 1738 MARK_UNDERLAY(pRoot); 1739 1740 if(enable) { 1741 BoxRec box; 1742 1743 box.x1 = 0; 1744 box.y1 = 0; 1745 box.x2 = pScreen->width; 1746 box.y2 = pScreen->height; 1747 1748 REGION_RESET(pScreen, &pTree->borderClip, &box); 1749 } else 1750 REGION_EMPTY(pScreen, &pTree->borderClip); 1751 1752 REGION_BREAK(pScreen, &pTree->clipList); 1753} 1754 1755static void 1756miOverlayClearToBackground( 1757 WindowPtr pWin, 1758 int x, int y, 1759 int w, int h, 1760 Bool generateExposures 1761) 1762{ 1763 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 1764 BoxRec box; 1765 RegionRec reg; 1766 RegionPtr pBSReg = NullRegion; 1767 ScreenPtr pScreen = pWin->drawable.pScreen; 1768 miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen); 1769 RegionPtr clipList; 1770 BoxPtr extents; 1771 int x1, y1, x2, y2; 1772 1773 x1 = pWin->drawable.x + x; 1774 y1 = pWin->drawable.y + y; 1775 if (w) 1776 x2 = x1 + (int) w; 1777 else 1778 x2 = x1 + (int) pWin->drawable.width - (int) x; 1779 if (h) 1780 y2 = y1 + h; 1781 else 1782 y2 = y1 + (int) pWin->drawable.height - (int) y; 1783 1784 clipList = ((*pScreenPriv->InOverlay)(pWin)) ? &pWin->clipList : 1785 &pTree->clipList; 1786 1787 extents = REGION_EXTENTS(pScreen, clipList); 1788 1789 if (x1 < extents->x1) x1 = extents->x1; 1790 if (x2 > extents->x2) x2 = extents->x2; 1791 if (y1 < extents->y1) y1 = extents->y1; 1792 if (y2 > extents->y2) y2 = extents->y2; 1793 1794 if (x2 <= x1 || y2 <= y1) 1795 x2 = x1 = y2 = y1 = 0; 1796 1797 box.x1 = x1; box.x2 = x2; 1798 box.y1 = y1; box.y2 = y2; 1799 1800 REGION_INIT(pScreen, ®, &box, 1); 1801 if (pWin->backStorage) { 1802 pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h, 1803 generateExposures); 1804 } 1805 1806 REGION_INTERSECT(pScreen, ®, ®, clipList); 1807 if (generateExposures) 1808 (*pScreen->WindowExposures)(pWin, ®, pBSReg); 1809 else if (pWin->backgroundState != None) 1810 (*pScreen->PaintWindowBackground)(pWin, ®, PW_BACKGROUND); 1811 REGION_UNINIT(pScreen, ®); 1812 if (pBSReg) 1813 REGION_DESTROY(pScreen, pBSReg); 1814} 1815 1816 1817/****************************************************************/ 1818 1819/* not used */ 1820_X_EXPORT Bool 1821miOverlayGetPrivateClips( 1822 WindowPtr pWin, 1823 RegionPtr *borderClip, 1824 RegionPtr *clipList 1825){ 1826 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 1827 1828 if(pTree) { 1829 *borderClip = &(pTree->borderClip); 1830 *clipList = &(pTree->clipList); 1831 return TRUE; 1832 } 1833 1834 *borderClip = *clipList = NULL; 1835 1836 return FALSE; 1837} 1838 1839_X_EXPORT void 1840miOverlaySetTransFunction ( 1841 ScreenPtr pScreen, 1842 miOverlayTransFunc transFunc 1843){ 1844 MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent = transFunc; 1845} 1846 1847_X_EXPORT Bool 1848miOverlayCopyUnderlay(ScreenPtr pScreen) 1849{ 1850 return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->copyUnderlay; 1851} 1852 1853_X_EXPORT void 1854miOverlayComputeCompositeClip(GCPtr pGC, WindowPtr pWin) 1855{ 1856 ScreenPtr pScreen = pGC->pScreen; 1857 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 1858 RegionPtr pregWin; 1859 Bool freeTmpClip, freeCompClip; 1860 1861 if(!pTree) { 1862 miComputeCompositeClip(pGC, &pWin->drawable); 1863 return; 1864 } 1865 1866 if (pGC->subWindowMode == IncludeInferiors) { 1867 pregWin = REGION_CREATE(pScreen, NullBox, 1); 1868 freeTmpClip = TRUE; 1869 if (pWin->parent || (screenIsSaved != SCREEN_SAVER_ON) || 1870 !HasSaverWindow (pScreen->myNum)) 1871 { 1872 REGION_INTERSECT(pScreen,pregWin,&pTree->borderClip,&pWin->winSize); 1873 } 1874 } else { 1875 pregWin = &pTree->clipList; 1876 freeTmpClip = FALSE; 1877 } 1878 freeCompClip = pGC->freeCompClip; 1879 if (pGC->clientClipType == CT_NONE) { 1880 if (freeCompClip) 1881 REGION_DESTROY(pScreen, pGC->pCompositeClip); 1882 pGC->pCompositeClip = pregWin; 1883 pGC->freeCompClip = freeTmpClip; 1884 } else { 1885 REGION_TRANSLATE(pScreen, pGC->clientClip, 1886 pWin->drawable.x + pGC->clipOrg.x, 1887 pWin->drawable.y + pGC->clipOrg.y); 1888 1889 if (freeCompClip) { 1890 REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip, 1891 pregWin, pGC->clientClip); 1892 if (freeTmpClip) 1893 REGION_DESTROY(pScreen, pregWin); 1894 } else if (freeTmpClip) { 1895 REGION_INTERSECT(pScreen, pregWin, pregWin, pGC->clientClip); 1896 pGC->pCompositeClip = pregWin; 1897 } else { 1898 pGC->pCompositeClip = REGION_CREATE(pScreen, NullBox, 0); 1899 REGION_INTERSECT(pScreen, pGC->pCompositeClip, 1900 pregWin, pGC->clientClip); 1901 } 1902 pGC->freeCompClip = TRUE; 1903 REGION_TRANSLATE(pScreen, pGC->clientClip, 1904 -(pWin->drawable.x + pGC->clipOrg.x), 1905 -(pWin->drawable.y + pGC->clipOrg.y)); 1906 } 1907} 1908 1909_X_EXPORT Bool 1910miOverlayCollectUnderlayRegions( 1911 WindowPtr pWin, 1912 RegionPtr *region 1913){ 1914 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 1915 1916 if(pTree) { 1917 *region = &pTree->borderClip; 1918 return FALSE; 1919 } 1920 1921 *region = REGION_CREATE(pWin->drawable.pScreen, NullBox, 0); 1922 1923 CollectUnderlayChildrenRegions(pWin, *region); 1924 1925 return TRUE; 1926} 1927 1928 1929static miOverlayTreePtr 1930DoLeaf( 1931 WindowPtr pWin, 1932 miOverlayTreePtr parent, 1933 miOverlayTreePtr prevSib 1934){ 1935 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 1936 1937 pTree->parent = parent; 1938 pTree->firstChild = NULL; 1939 pTree->lastChild = NULL; 1940 pTree->prevSib = prevSib; 1941 pTree->nextSib = NULL; 1942 1943 if(prevSib) 1944 prevSib->nextSib = pTree; 1945 1946 if(!parent->firstChild) 1947 parent->firstChild = parent->lastChild = pTree; 1948 else if(parent->lastChild == prevSib) 1949 parent->lastChild = pTree; 1950 1951 return pTree; 1952} 1953 1954static void 1955RebuildTree(WindowPtr pWin) 1956{ 1957 miOverlayTreePtr parent, prevSib, tChild; 1958 WindowPtr pChild; 1959 1960 prevSib = tChild = NULL; 1961 1962 pWin = pWin->parent; 1963 1964 while(IN_OVERLAY(pWin)) 1965 pWin = pWin->parent; 1966 1967 parent = MIOVERLAY_GET_WINDOW_TREE(pWin); 1968 1969 pChild = pWin->firstChild; 1970 parent->firstChild = parent->lastChild = NULL; 1971 1972 while(1) { 1973 if(IN_UNDERLAY(pChild)) 1974 prevSib = tChild = DoLeaf(pChild, parent, prevSib); 1975 1976 if(pChild->firstChild) { 1977 if(IN_UNDERLAY(pChild)) { 1978 parent = tChild; 1979 prevSib = NULL; 1980 } 1981 pChild = pChild->firstChild; 1982 continue; 1983 } 1984 1985 while(!pChild->nextSib) { 1986 pChild = pChild->parent; 1987 if(pChild == pWin) return; 1988 if(IN_UNDERLAY(pChild)) { 1989 prevSib = tChild = MIOVERLAY_GET_WINDOW_TREE(pChild); 1990 parent = tChild->parent; 1991 } 1992 } 1993 1994 pChild = pChild->nextSib; 1995 } 1996} 1997 1998 1999static Bool 2000HasUnderlayChildren(WindowPtr pWin) 2001{ 2002 WindowPtr pChild; 2003 2004 if(!(pChild = pWin->firstChild)) 2005 return FALSE; 2006 2007 while(1) { 2008 if(IN_UNDERLAY(pChild)) 2009 return TRUE; 2010 2011 if(pChild->firstChild) { 2012 pChild = pChild->firstChild; 2013 continue; 2014 } 2015 2016 while(!pChild->nextSib && (pWin != pChild)) 2017 pChild = pChild->parent; 2018 2019 if(pChild == pWin) break; 2020 2021 pChild = pChild->nextSib; 2022 } 2023 2024 return FALSE; 2025} 2026 2027 2028static Bool 2029CollectUnderlayChildrenRegions(WindowPtr pWin, RegionPtr pReg) 2030{ 2031 WindowPtr pChild; 2032 miOverlayTreePtr pTree; 2033 Bool hasUnderlay; 2034 2035 if(!(pChild = pWin->firstChild)) 2036 return FALSE; 2037 2038 hasUnderlay = FALSE; 2039 2040 while(1) { 2041 if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) { 2042 REGION_APPEND(pScreen, pReg, &pTree->borderClip); 2043 hasUnderlay = TRUE; 2044 } else 2045 if(pChild->firstChild) { 2046 pChild = pChild->firstChild; 2047 continue; 2048 } 2049 2050 while(!pChild->nextSib && (pWin != pChild)) 2051 pChild = pChild->parent; 2052 2053 if(pChild == pWin) break; 2054 2055 pChild = pChild->nextSib; 2056 } 2057 2058 if(hasUnderlay) { 2059 Bool overlap; 2060 REGION_VALIDATE(pScreen, pReg, &overlap); 2061 } 2062 2063 return hasUnderlay; 2064} 2065 2066 2067static void 2068MarkUnderlayWindow(WindowPtr pWin) 2069{ 2070 miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin); 2071 2072 if(pTree->valdata) return; 2073 pTree->valdata = (miOverlayValDataPtr)xnfalloc(sizeof(miOverlayValDataRec)); 2074 pTree->valdata->oldAbsCorner.x = pWin->drawable.x; 2075 pTree->valdata->oldAbsCorner.y = pWin->drawable.y; 2076 pTree->valdata->borderVisible = NullRegion; 2077} 2078