1706f2543Smrg 2706f2543Smrg/*********************************************************** 3706f2543Smrg 4706f2543SmrgCopyright 1987, 1998 The Open Group 5706f2543Smrg 6706f2543SmrgPermission to use, copy, modify, distribute, and sell this software and its 7706f2543Smrgdocumentation for any purpose is hereby granted without fee, provided that 8706f2543Smrgthe above copyright notice appear in all copies and that both that 9706f2543Smrgcopyright notice and this permission notice appear in supporting 10706f2543Smrgdocumentation. 11706f2543Smrg 12706f2543SmrgThe above copyright notice and this permission notice shall be included in 13706f2543Smrgall copies or substantial portions of the Software. 14706f2543Smrg 15706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18706f2543SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19706f2543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20706f2543SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21706f2543Smrg 22706f2543SmrgExcept as contained in this notice, the name of The Open Group shall not be 23706f2543Smrgused in advertising or otherwise to promote the sale, use or other dealings 24706f2543Smrgin this Software without prior written authorization from The Open Group. 25706f2543Smrg 26706f2543Smrg 27706f2543SmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 28706f2543Smrg 29706f2543Smrg All Rights Reserved 30706f2543Smrg 31706f2543SmrgPermission to use, copy, modify, and distribute this software and its 32706f2543Smrgdocumentation for any purpose and without fee is hereby granted, 33706f2543Smrgprovided that the above copyright notice appear in all copies and that 34706f2543Smrgboth that copyright notice and this permission notice appear in 35706f2543Smrgsupporting documentation, and that the name of Digital not be 36706f2543Smrgused in advertising or publicity pertaining to distribution of the 37706f2543Smrgsoftware without specific, written prior permission. 38706f2543Smrg 39706f2543SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 40706f2543SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 41706f2543SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 42706f2543SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 43706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 44706f2543SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 45706f2543SmrgSOFTWARE. 46706f2543Smrg 47706f2543Smrg******************************************************************/ 48706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 49706f2543Smrg#include <dix-config.h> 50706f2543Smrg#endif 51706f2543Smrg 52706f2543Smrg#include <X11/X.h> 53706f2543Smrg#include <X11/extensions/shapeconst.h> 54706f2543Smrg#include "regionstr.h" 55706f2543Smrg#include "region.h" 56706f2543Smrg#include "mi.h" 57706f2543Smrg#include "windowstr.h" 58706f2543Smrg#include "scrnintstr.h" 59706f2543Smrg#include "pixmapstr.h" 60706f2543Smrg#include "mivalidate.h" 61706f2543Smrg 62706f2543Smrgvoid 63706f2543SmrgmiClearToBackground(WindowPtr pWin, 64706f2543Smrg int x, int y, int w, int h, 65706f2543Smrg Bool generateExposures) 66706f2543Smrg{ 67706f2543Smrg BoxRec box; 68706f2543Smrg RegionRec reg; 69706f2543Smrg BoxPtr extents; 70706f2543Smrg int x1, y1, x2, y2; 71706f2543Smrg 72706f2543Smrg /* compute everything using ints to avoid overflow */ 73706f2543Smrg 74706f2543Smrg x1 = pWin->drawable.x + x; 75706f2543Smrg y1 = pWin->drawable.y + y; 76706f2543Smrg if (w) 77706f2543Smrg x2 = x1 + (int) w; 78706f2543Smrg else 79706f2543Smrg x2 = x1 + (int) pWin->drawable.width - (int) x; 80706f2543Smrg if (h) 81706f2543Smrg y2 = y1 + h; 82706f2543Smrg else 83706f2543Smrg y2 = y1 + (int) pWin->drawable.height - (int) y; 84706f2543Smrg 85706f2543Smrg extents = &pWin->clipList.extents; 86706f2543Smrg 87706f2543Smrg /* clip the resulting rectangle to the window clipList extents. This 88706f2543Smrg * makes sure that the result will fit in a box, given that the 89706f2543Smrg * screen is < 32768 on a side. 90706f2543Smrg */ 91706f2543Smrg 92706f2543Smrg if (x1 < extents->x1) 93706f2543Smrg x1 = extents->x1; 94706f2543Smrg if (x2 > extents->x2) 95706f2543Smrg x2 = extents->x2; 96706f2543Smrg if (y1 < extents->y1) 97706f2543Smrg y1 = extents->y1; 98706f2543Smrg if (y2 > extents->y2) 99706f2543Smrg y2 = extents->y2; 100706f2543Smrg 101706f2543Smrg if (x2 <= x1 || y2 <= y1) 102706f2543Smrg { 103706f2543Smrg x2 = x1 = 0; 104706f2543Smrg y2 = y1 = 0; 105706f2543Smrg } 106706f2543Smrg 107706f2543Smrg box.x1 = x1; 108706f2543Smrg box.x2 = x2; 109706f2543Smrg box.y1 = y1; 110706f2543Smrg box.y2 = y2; 111706f2543Smrg 112706f2543Smrg RegionInit(®, &box, 1); 113706f2543Smrg 114706f2543Smrg RegionIntersect(®, ®, &pWin->clipList); 115706f2543Smrg if (generateExposures) 116706f2543Smrg (*pWin->drawable.pScreen->WindowExposures)(pWin, ®, NULL); 117706f2543Smrg else if (pWin->backgroundState != None) 118706f2543Smrg miPaintWindow(pWin, ®, PW_BACKGROUND); 119706f2543Smrg RegionUninit(®); 120706f2543Smrg} 121706f2543Smrg 122706f2543Smrgvoid 123706f2543SmrgmiMarkWindow(WindowPtr pWin) 124706f2543Smrg{ 125706f2543Smrg ValidatePtr val; 126706f2543Smrg 127706f2543Smrg if (pWin->valdata) 128706f2543Smrg return; 129706f2543Smrg val = (ValidatePtr)xnfalloc(sizeof(ValidateRec)); 130706f2543Smrg val->before.oldAbsCorner.x = pWin->drawable.x; 131706f2543Smrg val->before.oldAbsCorner.y = pWin->drawable.y; 132706f2543Smrg val->before.borderVisible = NullRegion; 133706f2543Smrg val->before.resized = FALSE; 134706f2543Smrg pWin->valdata = val; 135706f2543Smrg} 136706f2543Smrg 137706f2543SmrgBool 138706f2543SmrgmiMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin) 139706f2543Smrg{ 140706f2543Smrg BoxPtr box; 141706f2543Smrg WindowPtr pChild, pLast; 142706f2543Smrg Bool anyMarked = FALSE; 143706f2543Smrg MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow; 144706f2543Smrg 145706f2543Smrg /* single layered systems are easy */ 146706f2543Smrg if (ppLayerWin) *ppLayerWin = pWin; 147706f2543Smrg 148706f2543Smrg if (pWin == pFirst) 149706f2543Smrg { 150706f2543Smrg /* Blindly mark pWin and all of its inferiors. This is a slight 151706f2543Smrg * overkill if there are mapped windows that outside pWin's border, 152706f2543Smrg * but it's better than wasting time on RectIn checks. 153706f2543Smrg */ 154706f2543Smrg pChild = pWin; 155706f2543Smrg while (1) 156706f2543Smrg { 157706f2543Smrg if (pChild->viewable) 158706f2543Smrg { 159706f2543Smrg if (RegionBroken(&pChild->winSize)) 160706f2543Smrg SetWinSize (pChild); 161706f2543Smrg if (RegionBroken(&pChild->borderSize)) 162706f2543Smrg SetBorderSize (pChild); 163706f2543Smrg (* MarkWindow)(pChild); 164706f2543Smrg if (pChild->firstChild) 165706f2543Smrg { 166706f2543Smrg pChild = pChild->firstChild; 167706f2543Smrg continue; 168706f2543Smrg } 169706f2543Smrg } 170706f2543Smrg while (!pChild->nextSib && (pChild != pWin)) 171706f2543Smrg pChild = pChild->parent; 172706f2543Smrg if (pChild == pWin) 173706f2543Smrg break; 174706f2543Smrg pChild = pChild->nextSib; 175706f2543Smrg } 176706f2543Smrg anyMarked = TRUE; 177706f2543Smrg pFirst = pFirst->nextSib; 178706f2543Smrg } 179706f2543Smrg if ( (pChild = pFirst) ) 180706f2543Smrg { 181706f2543Smrg box = RegionExtents(&pWin->borderSize); 182706f2543Smrg pLast = pChild->parent->lastChild; 183706f2543Smrg while (1) 184706f2543Smrg { 185706f2543Smrg if (pChild->viewable) 186706f2543Smrg { 187706f2543Smrg if (RegionBroken(&pChild->winSize)) 188706f2543Smrg SetWinSize (pChild); 189706f2543Smrg if (RegionBroken(&pChild->borderSize)) 190706f2543Smrg SetBorderSize (pChild); 191706f2543Smrg if (RegionContainsRect(&pChild->borderSize, box)) 192706f2543Smrg { 193706f2543Smrg (* MarkWindow)(pChild); 194706f2543Smrg anyMarked = TRUE; 195706f2543Smrg if (pChild->firstChild) 196706f2543Smrg { 197706f2543Smrg pChild = pChild->firstChild; 198706f2543Smrg continue; 199706f2543Smrg } 200706f2543Smrg } 201706f2543Smrg } 202706f2543Smrg while (!pChild->nextSib && (pChild != pLast)) 203706f2543Smrg pChild = pChild->parent; 204706f2543Smrg if (pChild == pLast) 205706f2543Smrg break; 206706f2543Smrg pChild = pChild->nextSib; 207706f2543Smrg } 208706f2543Smrg } 209706f2543Smrg if (anyMarked) 210706f2543Smrg (* MarkWindow)(pWin->parent); 211706f2543Smrg return anyMarked; 212706f2543Smrg} 213706f2543Smrg 214706f2543Smrg/***** 215706f2543Smrg * miHandleValidateExposures(pWin) 216706f2543Smrg * starting at pWin, draw background in any windows that have exposure 217706f2543Smrg * regions, translate the regions, restore any backing store, 218706f2543Smrg * and then send any regions still exposed to the client 219706f2543Smrg *****/ 220706f2543Smrgvoid 221706f2543SmrgmiHandleValidateExposures(WindowPtr pWin) 222706f2543Smrg{ 223706f2543Smrg WindowPtr pChild; 224706f2543Smrg ValidatePtr val; 225706f2543Smrg WindowExposuresProcPtr WindowExposures; 226706f2543Smrg 227706f2543Smrg pChild = pWin; 228706f2543Smrg WindowExposures = pChild->drawable.pScreen->WindowExposures; 229706f2543Smrg while (1) 230706f2543Smrg { 231706f2543Smrg if ( (val = pChild->valdata) ) 232706f2543Smrg { 233706f2543Smrg if (RegionNotEmpty(&val->after.borderExposed)) 234706f2543Smrg miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER); 235706f2543Smrg RegionUninit(&val->after.borderExposed); 236706f2543Smrg (*WindowExposures)(pChild, &val->after.exposed, NullRegion); 237706f2543Smrg RegionUninit(&val->after.exposed); 238706f2543Smrg free(val); 239706f2543Smrg pChild->valdata = NULL; 240706f2543Smrg if (pChild->firstChild) 241706f2543Smrg { 242706f2543Smrg pChild = pChild->firstChild; 243706f2543Smrg continue; 244706f2543Smrg } 245706f2543Smrg } 246706f2543Smrg while (!pChild->nextSib && (pChild != pWin)) 247706f2543Smrg pChild = pChild->parent; 248706f2543Smrg if (pChild == pWin) 249706f2543Smrg break; 250706f2543Smrg pChild = pChild->nextSib; 251706f2543Smrg } 252706f2543Smrg} 253706f2543Smrg 254706f2543Smrgvoid 255706f2543SmrgmiMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind) 256706f2543Smrg{ 257706f2543Smrg WindowPtr pParent; 258706f2543Smrg Bool WasViewable = (Bool)(pWin->viewable); 259706f2543Smrg short bw; 260706f2543Smrg RegionPtr oldRegion = NULL; 261706f2543Smrg DDXPointRec oldpt; 262706f2543Smrg Bool anyMarked = FALSE; 263706f2543Smrg ScreenPtr pScreen; 264706f2543Smrg WindowPtr windowToValidate; 265706f2543Smrg WindowPtr pLayerWin; 266706f2543Smrg 267706f2543Smrg /* if this is a root window, can't be moved */ 268706f2543Smrg if (!(pParent = pWin->parent)) 269706f2543Smrg return ; 270706f2543Smrg pScreen = pWin->drawable.pScreen; 271706f2543Smrg bw = wBorderWidth (pWin); 272706f2543Smrg 273706f2543Smrg oldpt.x = pWin->drawable.x; 274706f2543Smrg oldpt.y = pWin->drawable.y; 275706f2543Smrg if (WasViewable) 276706f2543Smrg { 277706f2543Smrg oldRegion = RegionCreate(NullBox, 1); 278706f2543Smrg RegionCopy(oldRegion, &pWin->borderClip); 279706f2543Smrg anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin); 280706f2543Smrg } 281706f2543Smrg pWin->origin.x = x + (int)bw; 282706f2543Smrg pWin->origin.y = y + (int)bw; 283706f2543Smrg x = pWin->drawable.x = pParent->drawable.x + x + (int)bw; 284706f2543Smrg y = pWin->drawable.y = pParent->drawable.y + y + (int)bw; 285706f2543Smrg 286706f2543Smrg SetWinSize (pWin); 287706f2543Smrg SetBorderSize (pWin); 288706f2543Smrg 289706f2543Smrg (*pScreen->PositionWindow)(pWin, x, y); 290706f2543Smrg 291706f2543Smrg windowToValidate = MoveWindowInStack(pWin, pNextSib); 292706f2543Smrg 293706f2543Smrg ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0); 294706f2543Smrg 295706f2543Smrg if (WasViewable) 296706f2543Smrg { 297706f2543Smrg if (pLayerWin == pWin) 298706f2543Smrg anyMarked |= (*pScreen->MarkOverlappedWindows) 299706f2543Smrg (pWin, windowToValidate, NULL); 300706f2543Smrg else 301706f2543Smrg anyMarked |= (*pScreen->MarkOverlappedWindows) 302706f2543Smrg (pWin, pLayerWin, NULL); 303706f2543Smrg 304706f2543Smrg 305706f2543Smrg if (anyMarked) 306706f2543Smrg { 307706f2543Smrg (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind); 308706f2543Smrg (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion); 309706f2543Smrg RegionDestroy(oldRegion); 310706f2543Smrg /* XXX need to retile border if ParentRelative origin */ 311706f2543Smrg (*pScreen->HandleExposures)(pLayerWin->parent); 312706f2543Smrg } 313706f2543Smrg if (anyMarked && pScreen->PostValidateTree) 314706f2543Smrg (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind); 315706f2543Smrg } 316706f2543Smrg if (pWin->realized) 317706f2543Smrg WindowsRestructured (); 318706f2543Smrg} 319706f2543Smrg 320706f2543Smrg 321706f2543Smrg/* 322706f2543Smrg * pValid is a region of the screen which has been 323706f2543Smrg * successfully copied -- recomputed exposed regions for affected windows 324706f2543Smrg */ 325706f2543Smrg 326706f2543Smrgstatic int 327706f2543SmrgmiRecomputeExposures ( 328706f2543Smrg WindowPtr pWin, 329706f2543Smrg pointer value) /* must conform to VisitWindowProcPtr */ 330706f2543Smrg{ 331706f2543Smrg RegionPtr pValid = (RegionPtr)value; 332706f2543Smrg 333706f2543Smrg if (pWin->valdata) 334706f2543Smrg { 335706f2543Smrg#ifdef COMPOSITE 336706f2543Smrg /* 337706f2543Smrg * Redirected windows are not affected by parent window 338706f2543Smrg * gravity manipulations, so don't recompute their 339706f2543Smrg * exposed areas here. 340706f2543Smrg */ 341706f2543Smrg if (pWin->redirectDraw != RedirectDrawNone) 342706f2543Smrg return WT_DONTWALKCHILDREN; 343706f2543Smrg#endif 344706f2543Smrg /* 345706f2543Smrg * compute exposed regions of this window 346706f2543Smrg */ 347706f2543Smrg RegionSubtract(&pWin->valdata->after.exposed, 348706f2543Smrg &pWin->clipList, pValid); 349706f2543Smrg /* 350706f2543Smrg * compute exposed regions of the border 351706f2543Smrg */ 352706f2543Smrg RegionSubtract(&pWin->valdata->after.borderExposed, 353706f2543Smrg &pWin->borderClip, &pWin->winSize); 354706f2543Smrg RegionSubtract(&pWin->valdata->after.borderExposed, 355706f2543Smrg &pWin->valdata->after.borderExposed, pValid); 356706f2543Smrg return WT_WALKCHILDREN; 357706f2543Smrg } 358706f2543Smrg return WT_NOMATCH; 359706f2543Smrg} 360706f2543Smrg 361706f2543Smrgvoid 362706f2543SmrgmiSlideAndSizeWindow(WindowPtr pWin, 363706f2543Smrg int x, int y, 364706f2543Smrg unsigned int w, unsigned int h, 365706f2543Smrg WindowPtr pSib) 366706f2543Smrg{ 367706f2543Smrg WindowPtr pParent; 368706f2543Smrg Bool WasViewable = (Bool)(pWin->viewable); 369706f2543Smrg unsigned short width = pWin->drawable.width, 370706f2543Smrg height = pWin->drawable.height; 371706f2543Smrg short oldx = pWin->drawable.x, 372706f2543Smrg oldy = pWin->drawable.y; 373706f2543Smrg int bw = wBorderWidth (pWin); 374706f2543Smrg short dw, dh; 375706f2543Smrg DDXPointRec oldpt; 376706f2543Smrg RegionPtr oldRegion = NULL; 377706f2543Smrg Bool anyMarked = FALSE; 378706f2543Smrg ScreenPtr pScreen; 379706f2543Smrg WindowPtr pFirstChange; 380706f2543Smrg WindowPtr pChild; 381706f2543Smrg RegionPtr gravitate[StaticGravity + 1]; 382706f2543Smrg unsigned g; 383706f2543Smrg int nx, ny; /* destination x,y */ 384706f2543Smrg int newx, newy; /* new inner window position */ 385706f2543Smrg RegionPtr pRegion = NULL; 386706f2543Smrg RegionPtr destClip; /* portions of destination already written */ 387706f2543Smrg RegionPtr oldWinClip = NULL; /* old clip list for window */ 388706f2543Smrg RegionPtr borderVisible = NullRegion; /* visible area of the border */ 389706f2543Smrg Bool shrunk = FALSE; /* shrunk in an inner dimension */ 390706f2543Smrg Bool moved = FALSE; /* window position changed */ 391706f2543Smrg WindowPtr pLayerWin; 392706f2543Smrg 393706f2543Smrg /* if this is a root window, can't be resized */ 394706f2543Smrg if (!(pParent = pWin->parent)) 395706f2543Smrg return ; 396706f2543Smrg 397706f2543Smrg pScreen = pWin->drawable.pScreen; 398706f2543Smrg newx = pParent->drawable.x + x + bw; 399706f2543Smrg newy = pParent->drawable.y + y + bw; 400706f2543Smrg if (WasViewable) 401706f2543Smrg { 402706f2543Smrg anyMarked = FALSE; 403706f2543Smrg /* 404706f2543Smrg * save the visible region of the window 405706f2543Smrg */ 406706f2543Smrg oldRegion = RegionCreate(NullBox, 1); 407706f2543Smrg RegionCopy(oldRegion, &pWin->winSize); 408706f2543Smrg 409706f2543Smrg /* 410706f2543Smrg * categorize child windows into regions to be moved 411706f2543Smrg */ 412706f2543Smrg for (g = 0; g <= StaticGravity; g++) 413706f2543Smrg gravitate[g] = (RegionPtr) NULL; 414706f2543Smrg for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) 415706f2543Smrg { 416706f2543Smrg g = pChild->winGravity; 417706f2543Smrg if (g != UnmapGravity) 418706f2543Smrg { 419706f2543Smrg if (!gravitate[g]) 420706f2543Smrg gravitate[g] = RegionCreate(NullBox, 1); 421706f2543Smrg RegionUnion(gravitate[g], 422706f2543Smrg gravitate[g], &pChild->borderClip); 423706f2543Smrg } 424706f2543Smrg else 425706f2543Smrg { 426706f2543Smrg UnmapWindow(pChild, TRUE); 427706f2543Smrg anyMarked = TRUE; 428706f2543Smrg } 429706f2543Smrg } 430706f2543Smrg anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 431706f2543Smrg &pLayerWin); 432706f2543Smrg 433706f2543Smrg oldWinClip = NULL; 434706f2543Smrg if (pWin->bitGravity != ForgetGravity) 435706f2543Smrg { 436706f2543Smrg oldWinClip = RegionCreate(NullBox, 1); 437706f2543Smrg RegionCopy(oldWinClip, &pWin->clipList); 438706f2543Smrg } 439706f2543Smrg /* 440706f2543Smrg * if the window is changing size, borderExposed 441706f2543Smrg * can't be computed correctly without some help. 442706f2543Smrg */ 443706f2543Smrg if (pWin->drawable.height > h || pWin->drawable.width > w) 444706f2543Smrg shrunk = TRUE; 445706f2543Smrg 446706f2543Smrg if (newx != oldx || newy != oldy) 447706f2543Smrg moved = TRUE; 448706f2543Smrg 449706f2543Smrg if ((pWin->drawable.height != h || pWin->drawable.width != w) && 450706f2543Smrg HasBorder (pWin)) 451706f2543Smrg { 452706f2543Smrg borderVisible = RegionCreate(NullBox, 1); 453706f2543Smrg /* for tiled borders, we punt and draw the whole thing */ 454706f2543Smrg if (pWin->borderIsPixel || !moved) 455706f2543Smrg { 456706f2543Smrg if (shrunk || moved) 457706f2543Smrg RegionSubtract(borderVisible, 458706f2543Smrg &pWin->borderClip, 459706f2543Smrg &pWin->winSize); 460706f2543Smrg else 461706f2543Smrg RegionCopy(borderVisible, 462706f2543Smrg &pWin->borderClip); 463706f2543Smrg } 464706f2543Smrg } 465706f2543Smrg } 466706f2543Smrg pWin->origin.x = x + bw; 467706f2543Smrg pWin->origin.y = y + bw; 468706f2543Smrg pWin->drawable.height = h; 469706f2543Smrg pWin->drawable.width = w; 470706f2543Smrg 471706f2543Smrg x = pWin->drawable.x = newx; 472706f2543Smrg y = pWin->drawable.y = newy; 473706f2543Smrg 474706f2543Smrg SetWinSize (pWin); 475706f2543Smrg SetBorderSize (pWin); 476706f2543Smrg 477706f2543Smrg dw = (int)w - (int)width; 478706f2543Smrg dh = (int)h - (int)height; 479706f2543Smrg ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh); 480706f2543Smrg 481706f2543Smrg /* let the hardware adjust background and border pixmaps, if any */ 482706f2543Smrg (*pScreen->PositionWindow)(pWin, x, y); 483706f2543Smrg 484706f2543Smrg pFirstChange = MoveWindowInStack(pWin, pSib); 485706f2543Smrg 486706f2543Smrg if (WasViewable) 487706f2543Smrg { 488706f2543Smrg pRegion = RegionCreate(NullBox, 1); 489706f2543Smrg 490706f2543Smrg if (pLayerWin == pWin) 491706f2543Smrg anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange, 492706f2543Smrg NULL); 493706f2543Smrg else 494706f2543Smrg anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin, 495706f2543Smrg NULL); 496706f2543Smrg 497706f2543Smrg if (pWin->valdata) 498706f2543Smrg { 499706f2543Smrg pWin->valdata->before.resized = TRUE; 500706f2543Smrg pWin->valdata->before.borderVisible = borderVisible; 501706f2543Smrg } 502706f2543Smrg 503706f2543Smrg 504706f2543Smrg if (anyMarked) 505706f2543Smrg (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther); 506706f2543Smrg /* 507706f2543Smrg * the entire window is trashed unless bitGravity 508706f2543Smrg * recovers portions of it 509706f2543Smrg */ 510706f2543Smrg RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList); 511706f2543Smrg } 512706f2543Smrg 513706f2543Smrg GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny); 514706f2543Smrg 515706f2543Smrg if (WasViewable) 516706f2543Smrg { 517706f2543Smrg /* avoid the border */ 518706f2543Smrg if (HasBorder (pWin)) 519706f2543Smrg { 520706f2543Smrg int offx, offy, dx, dy; 521706f2543Smrg 522706f2543Smrg /* kruft to avoid double translates for each gravity */ 523706f2543Smrg offx = 0; 524706f2543Smrg offy = 0; 525706f2543Smrg for (g = 0; g <= StaticGravity; g++) 526706f2543Smrg { 527706f2543Smrg if (!gravitate[g]) 528706f2543Smrg continue; 529706f2543Smrg 530706f2543Smrg /* align winSize to gravitate[g]. 531706f2543Smrg * winSize is in new coordinates, 532706f2543Smrg * gravitate[g] is still in old coordinates */ 533706f2543Smrg GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny); 534706f2543Smrg 535706f2543Smrg dx = (oldx - nx) - offx; 536706f2543Smrg dy = (oldy - ny) - offy; 537706f2543Smrg if (dx || dy) 538706f2543Smrg { 539706f2543Smrg RegionTranslate(&pWin->winSize, dx, dy); 540706f2543Smrg offx += dx; 541706f2543Smrg offy += dy; 542706f2543Smrg } 543706f2543Smrg RegionIntersect(gravitate[g], gravitate[g], 544706f2543Smrg &pWin->winSize); 545706f2543Smrg } 546706f2543Smrg /* get winSize back where it belongs */ 547706f2543Smrg if (offx || offy) 548706f2543Smrg RegionTranslate(&pWin->winSize, -offx, -offy); 549706f2543Smrg } 550706f2543Smrg /* 551706f2543Smrg * add screen bits to the appropriate bucket 552706f2543Smrg */ 553706f2543Smrg 554706f2543Smrg if (oldWinClip) 555706f2543Smrg { 556706f2543Smrg /* 557706f2543Smrg * clip to new clipList 558706f2543Smrg */ 559706f2543Smrg RegionCopy(pRegion, oldWinClip); 560706f2543Smrg RegionTranslate(pRegion, nx - oldx, ny - oldy); 561706f2543Smrg RegionIntersect(oldWinClip, pRegion, &pWin->clipList); 562706f2543Smrg /* 563706f2543Smrg * don't step on any gravity bits which will be copied after this 564706f2543Smrg * region. Note -- this assumes that the regions will be copied 565706f2543Smrg * in gravity order. 566706f2543Smrg */ 567706f2543Smrg for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) 568706f2543Smrg { 569706f2543Smrg if (gravitate[g]) 570706f2543Smrg RegionSubtract(oldWinClip, oldWinClip, 571706f2543Smrg gravitate[g]); 572706f2543Smrg } 573706f2543Smrg RegionTranslate(oldWinClip, oldx - nx, oldy - ny); 574706f2543Smrg g = pWin->bitGravity; 575706f2543Smrg if (!gravitate[g]) 576706f2543Smrg gravitate[g] = oldWinClip; 577706f2543Smrg else 578706f2543Smrg { 579706f2543Smrg RegionUnion(gravitate[g], gravitate[g], oldWinClip); 580706f2543Smrg RegionDestroy(oldWinClip); 581706f2543Smrg } 582706f2543Smrg } 583706f2543Smrg 584706f2543Smrg /* 585706f2543Smrg * move the bits on the screen 586706f2543Smrg */ 587706f2543Smrg 588706f2543Smrg destClip = NULL; 589706f2543Smrg 590706f2543Smrg for (g = 0; g <= StaticGravity; g++) 591706f2543Smrg { 592706f2543Smrg if (!gravitate[g]) 593706f2543Smrg continue; 594706f2543Smrg 595706f2543Smrg GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny); 596706f2543Smrg 597706f2543Smrg oldpt.x = oldx + (x - nx); 598706f2543Smrg oldpt.y = oldy + (y - ny); 599706f2543Smrg 600706f2543Smrg /* Note that gravitate[g] is *translated* by CopyWindow */ 601706f2543Smrg 602706f2543Smrg /* only copy the remaining useful bits */ 603706f2543Smrg 604706f2543Smrg RegionIntersect(gravitate[g], gravitate[g], oldRegion); 605706f2543Smrg 606706f2543Smrg /* clip to not overwrite already copied areas */ 607706f2543Smrg 608706f2543Smrg if (destClip) { 609706f2543Smrg RegionTranslate(destClip, oldpt.x - x, oldpt.y - y); 610706f2543Smrg RegionSubtract(gravitate[g], gravitate[g], destClip); 611706f2543Smrg RegionTranslate(destClip, x - oldpt.x, y - oldpt.y); 612706f2543Smrg } 613706f2543Smrg 614706f2543Smrg /* and move those bits */ 615706f2543Smrg 616706f2543Smrg if (oldpt.x != x || oldpt.y != y 617706f2543Smrg#ifdef COMPOSITE 618706f2543Smrg || pWin->redirectDraw 619706f2543Smrg#endif 620706f2543Smrg ) 621706f2543Smrg { 622706f2543Smrg (*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]); 623706f2543Smrg } 624706f2543Smrg 625706f2543Smrg /* remove any overwritten bits from the remaining useful bits */ 626706f2543Smrg 627706f2543Smrg RegionSubtract(oldRegion, oldRegion, gravitate[g]); 628706f2543Smrg 629706f2543Smrg /* 630706f2543Smrg * recompute exposed regions of child windows 631706f2543Smrg */ 632706f2543Smrg 633706f2543Smrg for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) 634706f2543Smrg { 635706f2543Smrg if (pChild->winGravity != g) 636706f2543Smrg continue; 637706f2543Smrg RegionIntersect(pRegion, 638706f2543Smrg &pChild->borderClip, gravitate[g]); 639706f2543Smrg TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion); 640706f2543Smrg } 641706f2543Smrg 642706f2543Smrg /* 643706f2543Smrg * remove the successfully copied regions of the 644706f2543Smrg * window from its exposed region 645706f2543Smrg */ 646706f2543Smrg 647706f2543Smrg if (g == pWin->bitGravity) 648706f2543Smrg RegionSubtract(&pWin->valdata->after.exposed, 649706f2543Smrg &pWin->valdata->after.exposed, gravitate[g]); 650706f2543Smrg if (!destClip) 651706f2543Smrg destClip = gravitate[g]; 652706f2543Smrg else 653706f2543Smrg { 654706f2543Smrg RegionUnion(destClip, destClip, gravitate[g]); 655706f2543Smrg RegionDestroy(gravitate[g]); 656706f2543Smrg } 657706f2543Smrg } 658706f2543Smrg 659706f2543Smrg RegionDestroy(oldRegion); 660706f2543Smrg RegionDestroy(pRegion); 661706f2543Smrg if (destClip) 662706f2543Smrg RegionDestroy(destClip); 663706f2543Smrg if (anyMarked) 664706f2543Smrg (*pScreen->HandleExposures)(pLayerWin->parent); 665706f2543Smrg if (anyMarked && pScreen->PostValidateTree) 666706f2543Smrg (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, 667706f2543Smrg VTOther); 668706f2543Smrg } 669706f2543Smrg if (pWin->realized) 670706f2543Smrg WindowsRestructured (); 671706f2543Smrg} 672706f2543Smrg 673706f2543SmrgWindowPtr 674706f2543SmrgmiGetLayerWindow(WindowPtr pWin) 675706f2543Smrg{ 676706f2543Smrg return pWin->firstChild; 677706f2543Smrg} 678706f2543Smrg 679706f2543Smrg/****** 680706f2543Smrg * 681706f2543Smrg * miSetShape 682706f2543Smrg * The border/window shape has changed. Recompute winSize/borderSize 683706f2543Smrg * and send appropriate exposure events 684706f2543Smrg */ 685706f2543Smrg 686706f2543Smrgvoid 687706f2543SmrgmiSetShape(WindowPtr pWin, int kind) 688706f2543Smrg{ 689706f2543Smrg Bool WasViewable = (Bool)(pWin->viewable); 690706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 691706f2543Smrg Bool anyMarked = FALSE; 692706f2543Smrg WindowPtr pLayerWin; 693706f2543Smrg 694706f2543Smrg if (kind != ShapeInput) { 695706f2543Smrg if (WasViewable) 696706f2543Smrg { 697706f2543Smrg anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, 698706f2543Smrg &pLayerWin); 699706f2543Smrg if (pWin->valdata) 700706f2543Smrg { 701706f2543Smrg if (HasBorder (pWin)) 702706f2543Smrg { 703706f2543Smrg RegionPtr borderVisible; 704706f2543Smrg 705706f2543Smrg borderVisible = RegionCreate(NullBox, 1); 706706f2543Smrg RegionSubtract(borderVisible, 707706f2543Smrg &pWin->borderClip, &pWin->winSize); 708706f2543Smrg pWin->valdata->before.borderVisible = borderVisible; 709706f2543Smrg } 710706f2543Smrg pWin->valdata->before.resized = TRUE; 711706f2543Smrg } 712706f2543Smrg } 713706f2543Smrg 714706f2543Smrg SetWinSize (pWin); 715706f2543Smrg SetBorderSize (pWin); 716706f2543Smrg 717706f2543Smrg ResizeChildrenWinSize(pWin, 0, 0, 0, 0); 718706f2543Smrg 719706f2543Smrg if (WasViewable) 720706f2543Smrg { 721706f2543Smrg anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 722706f2543Smrg NULL); 723706f2543Smrg 724706f2543Smrg if (anyMarked) 725706f2543Smrg (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, 726706f2543Smrg VTOther); 727706f2543Smrg } 728706f2543Smrg 729706f2543Smrg if (WasViewable) 730706f2543Smrg { 731706f2543Smrg if (anyMarked) 732706f2543Smrg (*pScreen->HandleExposures)(pLayerWin->parent); 733706f2543Smrg if (anyMarked && pScreen->PostValidateTree) 734706f2543Smrg (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, 735706f2543Smrg VTOther); 736706f2543Smrg } 737706f2543Smrg } 738706f2543Smrg if (pWin->realized) 739706f2543Smrg WindowsRestructured (); 740706f2543Smrg CheckCursorConfinement(pWin); 741706f2543Smrg} 742706f2543Smrg 743706f2543Smrg/* Keeps the same inside(!) origin */ 744706f2543Smrg 745706f2543Smrgvoid 746706f2543SmrgmiChangeBorderWidth(WindowPtr pWin, unsigned int width) 747706f2543Smrg{ 748706f2543Smrg int oldwidth; 749706f2543Smrg Bool anyMarked = FALSE; 750706f2543Smrg ScreenPtr pScreen; 751706f2543Smrg Bool WasViewable = (Bool)(pWin->viewable); 752706f2543Smrg Bool HadBorder; 753706f2543Smrg WindowPtr pLayerWin; 754706f2543Smrg 755706f2543Smrg oldwidth = wBorderWidth (pWin); 756706f2543Smrg if (oldwidth == width) 757706f2543Smrg return; 758706f2543Smrg HadBorder = HasBorder(pWin); 759706f2543Smrg pScreen = pWin->drawable.pScreen; 760706f2543Smrg if (WasViewable && width < oldwidth) 761706f2543Smrg anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin); 762706f2543Smrg 763706f2543Smrg pWin->borderWidth = width; 764706f2543Smrg SetBorderSize (pWin); 765706f2543Smrg 766706f2543Smrg if (WasViewable) 767706f2543Smrg { 768706f2543Smrg if (width > oldwidth) 769706f2543Smrg { 770706f2543Smrg anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, 771706f2543Smrg &pLayerWin); 772706f2543Smrg /* 773706f2543Smrg * save the old border visible region to correctly compute 774706f2543Smrg * borderExposed. 775706f2543Smrg */ 776706f2543Smrg if (pWin->valdata && HadBorder) 777706f2543Smrg { 778706f2543Smrg RegionPtr borderVisible; 779706f2543Smrg borderVisible = RegionCreate(NULL, 1); 780706f2543Smrg RegionSubtract(borderVisible, 781706f2543Smrg &pWin->borderClip, &pWin->winSize); 782706f2543Smrg pWin->valdata->before.borderVisible = borderVisible; 783706f2543Smrg } 784706f2543Smrg } 785706f2543Smrg 786706f2543Smrg if (anyMarked) 787706f2543Smrg { 788706f2543Smrg (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther); 789706f2543Smrg (*pScreen->HandleExposures)(pLayerWin->parent); 790706f2543Smrg } 791706f2543Smrg if (anyMarked && pScreen->PostValidateTree) 792706f2543Smrg (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, 793706f2543Smrg VTOther); 794706f2543Smrg } 795706f2543Smrg if (pWin->realized) 796706f2543Smrg WindowsRestructured (); 797706f2543Smrg} 798706f2543Smrg 799706f2543Smrgvoid 800706f2543SmrgmiMarkUnrealizedWindow(WindowPtr pChild, WindowPtr pWin, Bool fromConfigure) 801706f2543Smrg{ 802706f2543Smrg if ((pChild != pWin) || fromConfigure) 803706f2543Smrg { 804706f2543Smrg RegionEmpty(&pChild->clipList); 805706f2543Smrg if (pChild->drawable.pScreen->ClipNotify) 806706f2543Smrg (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0); 807706f2543Smrg RegionEmpty(&pChild->borderClip); 808706f2543Smrg } 809706f2543Smrg} 810706f2543Smrg 811706f2543Smrgvoid 812706f2543SmrgmiSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth) 813706f2543Smrg{ 814706f2543Smrg WindowPtr pChild; 815706f2543Smrg 816706f2543Smrg for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) 817706f2543Smrg { 818706f2543Smrg if (pChild->drawable.depth == depth) 819706f2543Smrg RegionUnion(pReg, pReg, &pChild->borderClip); 820706f2543Smrg 821706f2543Smrg if (pChild->firstChild) 822706f2543Smrg miSegregateChildren(pChild, pReg, depth); 823706f2543Smrg } 824706f2543Smrg} 825