diff options
Diffstat (limited to 'xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.c')
-rw-r--r-- | xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.c | 753 |
1 files changed, 753 insertions, 0 deletions
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.c b/xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.c new file mode 100644 index 000000000..56418c351 --- /dev/null +++ b/xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.c @@ -0,0 +1,753 @@ +/* + * Rootless window management + * + * Greg Parker gparker@cs.stanford.edu + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.c,v 1.4 2001/08/01 05:34:06 torrey Exp $ */ + +#include "rootlessCommon.h" +#include "rootlessWindow.h" + +#include "fb.h" + +// PanoramiX/Xinerama creates a copy of every window, one per screen. +// Windows in rootless mode really can cross screens, so we only want to +// work with one copy of each. +#ifdef PANORAMIX +#include "../Xext/panoramiX.h" +#include "../Xext/panoramiXsrv.h" +// LookupIDByType doesn't find root window, but root windows are "real" here. +// LookupIDByType doesn't find anything when panoramix is off +#define IS_FAKE_WINDOW(w) \ + (!noPanoramiXExtension && \ + pWin->parent && \ + !LookupIDByType(w->drawable.id, XRT_WINDOW)) +#else +#define IS_FAKE_WINDOW(w) (0) +#endif + + +// RootlessCreateWindow +// For now, don't create a frame until the window is realized. +// Do reset the window size so it's not clipped by the root window. +Bool +RootlessCreateWindow(WindowPtr pWin) +{ + Bool result; + RegionRec saveRoot; + + WINREC(pWin) = NULL; + SCREEN_UNWRAP(pWin->drawable.pScreen, CreateWindow); + if (!IsRoot(pWin)) { + // win/border size set by DIX, not by wrapped CreateWindow, so + // correct it here. + // Don't HUGE_ROOT when pWin is the root! + HUGE_ROOT(pWin); + SetWinSize(pWin); + SetBorderSize(pWin); + } + result = pWin->drawable.pScreen->CreateWindow(pWin); + if (pWin->parent) { + NORMAL_ROOT(pWin); + } + SCREEN_WRAP(pWin->drawable.pScreen, CreateWindow); + return result; +} + + +// RootlessDestroyWindow +// For now, all window destruction takes place in UnrealizeWindow +Bool +RootlessDestroyWindow(WindowPtr pWin) +{ + Bool result; + + SCREEN_UNWRAP(pWin->drawable.pScreen, DestroyWindow); + result = pWin->drawable.pScreen->DestroyWindow(pWin); + SCREEN_WRAP(pWin->drawable.pScreen, DestroyWindow); + return result; +} + + +#ifdef SHAPE + +// fixme reimplement shape + +// boundingShape = outside border (like borderClip) +// clipShape = inside border (like clipList) +// Both are in window-local coordinates +// We only care about boundingShape (fixme true?) + +// RootlessReallySetShape is used in several places other than SetShape. +// Most importantly, SetShape is often called on unmapped windows, so we +// have to wait until the window is mapped to reshape the frame. +static void RootlessReallySetShape(WindowPtr pWin) +{ + RootlessWindowRec *winRec = WINREC(pWin); + ScreenPtr pScreen = pWin->drawable.pScreen; + RegionRec newShape; + + // fixme reimplement shape + return; + + if (IsRoot(pWin)) return; + if (!IsTopLevel(pWin)) return; + if (!winRec) return; + + if (wBoundingShape(pWin)) { + // wBoundingShape is relative to *inner* origin of window. + // Translate by borderWidth to get the outside-relative position. + REGION_INIT(pScreen, &newShape, NullBox, 0); + REGION_COPY(pScreen, &newShape, wBoundingShape(pWin)); + REGION_TRANSLATE(pScreen, &newShape, pWin->borderWidth, + pWin->borderWidth); + } else { + newShape.data = NULL; + newShape.extents.x1 = 0; + newShape.extents.y1 = 0; + newShape.extents.x2 = winRec->frame.w; + newShape.extents.y2 = winRec->frame.h; + } + RL_DEBUG_MSG("reshaping..."); + RL_DEBUG_MSG("numrects %d, extents %d %d %d %d ", + REGION_NUM_RECTS(&newShape), + newShape.extents.x1, newShape.extents.y1, + newShape.extents.x2, newShape.extents.y2); + CallFrameProc(pScreen, ReshapeFrame,(pScreen, &winRec->frame, &newShape)); + REGION_UNINIT(pScreen, &newShape); +} + + +void +RootlessSetShape(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + RootlessReallySetShape(pWin); + SCREEN_UNWRAP(pScreen, SetShape); + pScreen->SetShape(pWin); + SCREEN_WRAP(pScreen, SetShape); +} + +#endif // SHAPE + + +// Disallow ParentRelative background on top-level windows +// because the root window doesn't really have the right background +// and cfb will try to draw on the root instead of on the window. +// fixme what about fb? +// fixme implement ParentRelative with real transparency? +// ParentRelative prevention is also in RealizeWindow() +Bool +RootlessChangeWindowAttributes(WindowPtr pWin, unsigned long vmask) +{ + Bool result; + ScreenPtr pScreen = pWin->drawable.pScreen; + + RL_DEBUG_MSG("change window attributes start "); + + SCREEN_UNWRAP(pScreen, ChangeWindowAttributes); + result = pScreen->ChangeWindowAttributes(pWin, vmask); + SCREEN_WRAP(pScreen, ChangeWindowAttributes); + + if (WINREC(pWin)) { + // disallow ParentRelative background state + if (pWin->backgroundState == ParentRelative) { + XID pixel = 0; + ChangeWindowAttributes(pWin, CWBackPixel, &pixel, serverClient); + } + } + + RL_DEBUG_MSG("change window attributes end\n"); + return result; +} + + +// Update the frame position now. +// (x, y) are *inside* position! +// After this, mi and fb are expecting the pixmap to be at the new location. +Bool +RootlessPositionWindow(WindowPtr pWin, int x, int y) +{ + RootlessWindowRec *winRec = WINREC(pWin); + ScreenPtr pScreen = pWin->drawable.pScreen; + Bool result; + + RL_DEBUG_MSG("positionwindow start\n"); + if (winRec) { + winRec->frame.x = x - pWin->borderWidth; + winRec->frame.y = y - pWin->borderWidth; + } + + UpdatePixmap(pWin); + + SCREEN_UNWRAP(pScreen, PositionWindow); + result = pScreen->PositionWindow(pWin, x, y); + SCREEN_WRAP(pScreen, PositionWindow); + + RL_DEBUG_MSG("positionwindow end\n"); + return result; +} + + +// RootlessRealizeWindow +// The frame is created here and not in CreateWindow. +// fixme change this? probably not - would be faster, but eat more memory +Bool +RootlessRealizeWindow(WindowPtr pWin) +{ + Bool result = FALSE; + RegionRec saveRoot; + ScreenPtr pScreen = pWin->drawable.pScreen; + + if (IS_FAKE_WINDOW(pWin)) { + // Don't map fake windows + // They won't get a frame or take time to draw (fixme true?) + RL_DEBUG_MSG("realize window: skipping fake window\n"); + pWin->mapped = FALSE; + pWin->realized = FALSE; + pWin->viewable = FALSE; + return Success; + } + + RL_DEBUG_MSG("realizewindow start "); + + if (IsTopLevel(pWin) || IsRoot(pWin)) { + DrawablePtr d = &pWin->drawable; + RootlessWindowRec *winRec = xalloc(sizeof(RootlessWindowRec)); + + if (! winRec) goto windowcreatebad; + + winRec->frame.isRoot = (pWin == WindowTable[pScreen->myNum]); + winRec->frame.x = d->x - pWin->borderWidth; + winRec->frame.y = d->y - pWin->borderWidth; + winRec->frame.w = d->width + 2*pWin->borderWidth; + winRec->frame.h = d->height + 2*pWin->borderWidth; + winRec->frame.win = pWin; + winRec->frame.devPrivate = NULL; + + REGION_INIT(pScreen, &winRec->damage, NullBox, 0); + winRec->borderWidth = pWin->borderWidth; + + winRec->pixmap = NULL; + // UpdatePixmap() called below + + WINREC(pWin) = winRec; + + RL_DEBUG_MSG("creating frame "); + CallFrameProc(pScreen, CreateFrame, + (pScreen, &WINREC(pWin)->frame, + pWin->prevSib ? &WINREC(pWin->prevSib)->frame : NULL)); + + // fixme implement ParentRelative with transparency? + // need non-interfering fb first + // Disallow ParentRelative background state + // This might have been set before the window was mapped + if (pWin->backgroundState == ParentRelative) { + XID pixel = 0; + ChangeWindowAttributes(pWin, CWBackPixel, &pixel, serverClient); + } + +#ifdef SHAPE + // Shape is usually set before the window is mapped, but + // (for now) we don't keep track of frames before they're mapped. + // RootlessReallySetShape(pWin); + // fixme reimplement shape +#endif + } + + UpdatePixmap(pWin); + + if (!IsRoot(pWin)) HUGE_ROOT(pWin); + SCREEN_UNWRAP(pScreen, RealizeWindow); + result = pScreen->RealizeWindow(pWin); + SCREEN_WRAP(pScreen, RealizeWindow); + if (!IsRoot(pWin)) NORMAL_ROOT(pWin); + + RL_DEBUG_MSG("realizewindow end\n"); + return result; + +windowcreatebad: + RL_DEBUG_MSG("window create bad! "); + RL_DEBUG_MSG("realizewindow end\n"); + return NULL; +} + + +Bool +RootlessUnrealizeWindow(WindowPtr pWin) +{ + Bool result; + ScreenPtr pScreen = pWin->drawable.pScreen; + + RL_DEBUG_MSG("unrealizewindow start "); + + if (IsTopLevel(pWin) || IsRoot(pWin)) { + RootlessWindowRec *winRec = WINREC(pWin); + + RootlessRedisplay(pWin); + CallFrameProc(pScreen, DestroyFrame, (pScreen, &winRec->frame)); + + REGION_UNINIT(pScreen, &winRec->damage); + + xfree(winRec); + WINREC(pWin) = NULL; + } + + SCREEN_UNWRAP(pScreen, UnrealizeWindow); + result = pScreen->UnrealizeWindow(pWin); + SCREEN_WRAP(pScreen, UnrealizeWindow); + RL_DEBUG_MSG("unrealizewindow end\n"); + return result; +} + + +void +RootlessRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib) +{ + RegionRec saveRoot; + RootlessWindowRec *winRec = WINREC(pWin); + ScreenPtr pScreen = pWin->drawable.pScreen; + + RL_DEBUG_MSG("restackwindow start "); + if (winRec) RL_DEBUG_MSG("restack top level \n"); + + HUGE_ROOT(pWin); + SCREEN_UNWRAP(pScreen, RestackWindow); + if (pScreen->RestackWindow) pScreen->RestackWindow(pWin, pOldNextSib); + SCREEN_WRAP(pScreen, RestackWindow); + NORMAL_ROOT(pWin); + + if (winRec) { + // fixme simplify the following + + WindowPtr oldNextW, newNextW, oldPrevW, newPrevW; + RootlessFramePtr oldNext, newNext, oldPrev, newPrev; + + oldNextW = pOldNextSib; + while (oldNextW && ! WINREC(oldNextW)) oldNextW = oldNextW->nextSib; + oldNext = oldNextW ? &WINREC(oldNextW)->frame : NULL; + + newNextW = pWin->nextSib; + while (newNextW && ! WINREC(newNextW)) newNextW = newNextW->nextSib; + newNext = newNextW ? &WINREC(newNextW)->frame : NULL; + + oldPrevW= pOldNextSib ? pOldNextSib->prevSib : pWin->parent->lastChild; + while (oldPrevW && ! WINREC(oldPrevW)) oldPrevW = oldPrevW->prevSib; + oldPrev = oldPrevW ? &WINREC(oldPrevW)->frame : NULL; + + newPrevW = pWin->prevSib; + while (newPrevW && ! WINREC(newPrevW)) newPrevW = newPrevW->prevSib; + newPrev = newPrevW ? &WINREC(newPrevW)->frame : NULL; + + if (pWin->prevSib) { + WindowPtr w = pWin->prevSib; + while (w) { + RL_DEBUG_MSG("w 0x%x\n", w); + w = w->parent; + } + } + + CallFrameProc(pScreen, RestackFrame, + (pScreen, &winRec->frame, oldPrev, newPrev)); + } + + RL_DEBUG_MSG("restackwindow end\n"); +} + + +/* + * Specialized window copy procedures + */ + +// Globals needed during window resize and move. +static PixmapPtr gResizeDeathPix = NULL; +static pointer gResizeDeathBits = NULL; +static PixmapPtr gResizeCopyWindowSource = NULL; +static CopyWindowProcPtr gResizeOldCopyWindowProc = NULL; + +// CopyWindow() that doesn't do anything. +// For MoveWindow() of top-level windows. +static void +RootlessNoCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, + RegionPtr prgnSrc) +{ + // some code expects the region to be translated + int dx = ptOldOrg.x - pWin->drawable.x; + int dy = ptOldOrg.y - pWin->drawable.y; + RL_DEBUG_MSG("ROOTLESSNOCOPYWINDOW "); + + REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); +} + + +// CopyWindow used during ResizeWindow for gravity moves. +// Cloned from fbCopyWindow +// The original always draws on the root pixmap (which we don't have). +// Instead, draw on the parent window's pixmap. +// Resize version: the old location's pixels are in gResizeCopyWindowSource +static void +RootlessResizeCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, + RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + SCREEN_UNWRAP(pScreen, CopyWindow); + RL_DEBUG_MSG("resizecopywindowFB start (win 0x%x) ", pWin); + + { + RegionRec rgnDst; + int dx, dy; + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy); + REGION_INIT (pScreen, &rgnDst, NullBox, 0); + REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc); + + fbCopyRegion (&gResizeCopyWindowSource->drawable, + &pScreen->GetWindowPixmap(pWin)->drawable, + 0, + &rgnDst, dx, dy, fbCopyWindowProc, 0, 0); + + // don't update - resize will update everything + // fixme DO update? + REGION_UNINIT(pScreen, &rgnDst); + fbValidateDrawable (&pWin->drawable); + } + + SCREEN_WRAP(pScreen, CopyWindow); + RL_DEBUG_MSG("resizecopywindowFB end\n"); +} + + +/* Update *new* location of window. Old location is redrawn with + * PaintWindowBackground/Border. + * Cloned from fbCopyWindow + * The original always draws on the root pixmap (which we don't have). + * Instead, draw on the parent window's pixmap. + */ +void +RootlessCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + SCREEN_UNWRAP(pScreen, CopyWindow); + RL_DEBUG_MSG("copywindowFB start (win 0x%x) ", pWin); + + { + RegionRec rgnDst; + int dx, dy; + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy); + + REGION_INIT(pScreen, &rgnDst, NullBox, 0); + REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc); + + fbCopyRegion ((DrawablePtr)pWin, (DrawablePtr)pWin, + 0, + &rgnDst, dx, dy, fbCopyWindowProc, 0, 0); + + // prgnSrc has been translated to dst position + RootlessDamageRegion(pWin, prgnSrc); + REGION_UNINIT(pScreen, &rgnDst); + fbValidateDrawable (&pWin->drawable); + } + + SCREEN_WRAP(pScreen, CopyWindow); + RL_DEBUG_MSG("copywindowFB end\n"); +} + + +/* + * Window resize procedures + */ + +// Prepare to resize a window. +// The old window's pixels are saved and the implementation is told +// to change the window size. +// (x,y,w,h) is outer frame of window (outside border) +static void +StartFrameResize(WindowPtr pWin, Bool gravity, + int oldX, int oldY, + unsigned int oldW, unsigned int oldH, unsigned int oldBW, + int newX, int newY, + unsigned int newW, unsigned int newH, unsigned int newBW) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + RootlessWindowRec *winRec = WINREC(pWin); + + RL_DEBUG_MSG("RESIZE TOPLEVEL WINDOW "); + RL_DEBUG_MSG("%d %d %d %d %d %d %d %d %d %d ", + oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW); + + RootlessRedisplay(pWin); + +/* +#ifdef SHAPE + // make the frame shape a rect + // fixme reimplement shape + if (wBoundingShape(pWin)) { + RegionPtr saveShape = wBoundingShape(pWin); + + pWin->optional->boundingShape = NULL; + RL_DEBUG_MSG("RootlessReallySetShape from resize "); + RootlessReallySetShape(pWin); + pWin->optional->boundingShape = saveShape; + } +#endif // SHAPE +*/ + + // Make a copy of the current pixmap and all its data. + // The original will go away when we ask the frame manager to + // allocate the new pixmap. + + gResizeDeathBits = xalloc(winRec->frame.bytesPerRow * winRec->frame.h); + memcpy(gResizeDeathBits, winRec->frame.pixelData, + winRec->frame.bytesPerRow * winRec->frame.h); + gResizeDeathPix = + GetScratchPixmapHeader(pScreen, winRec->frame.w, winRec->frame.h, + winRec->frame.depth, winRec->frame.bitsPerPixel, + winRec->frame.bytesPerRow, gResizeDeathBits); + SetPixmapBaseToScreen(gResizeDeathPix, winRec->frame.x, winRec->frame.y); + + winRec->frame.x = newX; + winRec->frame.y = newY; + winRec->frame.w = newW; + winRec->frame.h = newH; + winRec->borderWidth = newBW; + + CallFrameProc(pScreen, StartResizeFrame, + (pScreen, &winRec->frame, oldX, oldY, oldW, oldH)); + UpdatePixmap(pWin); + + // Use custom CopyWindow when moving gravity bits around + // ResizeWindow assumes the old window contents are in the same + // pixmap, but here they're in deathPix instead. + if (gravity) { + gResizeCopyWindowSource = gResizeDeathPix; + gResizeOldCopyWindowProc = pScreen->CopyWindow; + pScreen->CopyWindow = RootlessResizeCopyWindow; + } + + // Copy pixels in intersection from src to dst. + // ResizeWindow assumes these pixels are already present when + // making gravity adjustments. + // pWin currently has new-sized pixmap but is in old position + // fixme border width change! + { + RegionRec r; + DrawablePtr src = &gResizeDeathPix->drawable; + DrawablePtr dst = &pScreen->GetWindowPixmap(pWin)->drawable; + + r.data = NULL; + r.extents.x1 = max(oldX, newX); + r.extents.y1 = max(oldY, newY); + r.extents.x2 = min(oldX + oldW, newX + newW); + r.extents.y2 = min(oldY + oldH, newY + newH); + + // r is now intersection of of old location and new location + if (r.extents.x2 > r.extents.x1 && r.extents.y2 > r.extents.y1) { +#if 0 + DDXPointRec srcPt = {r.extents.x1, r.extents.y1}; + // Correct for border width change + // fixme need to correct for border width change + int dx = newX - oldX; + int dy = newY - oldY; + REGION_TRANSLATE(pScreen, &r, dx, dy); +#endif + fbCopyRegion(src, dst, NULL, &r, 0, 0, fbCopyWindowProc, 0, 0); + } + REGION_UNINIT(pScreen, &r); + } +} + + +static void +FinishFrameResize(WindowPtr pWin, Bool gravity, + int oldX, int oldY, + unsigned int oldW, unsigned int oldH, unsigned int oldBW, + int newX, int newY, + unsigned int newW, unsigned int newH, unsigned int newBW) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + RootlessWindowRec *winRec = WINREC(pWin); + + CallFrameProc(pScreen, FinishResizeFrame, + (pScreen, &winRec->frame, oldX, oldY, oldW, oldH)); + + // Destroy temp pixmap + FreeScratchPixmapHeader(gResizeDeathPix); + xfree(gResizeDeathBits); + gResizeDeathPix = gResizeDeathBits = NULL; + + if (gravity) { + pScreen->CopyWindow = gResizeOldCopyWindowProc; + gResizeCopyWindowSource = NULL; + } +} + + +// If kind==VTOther, window border is resizing (and borderWidth is +// already changed!!@#$) This case works like window resize, not move. +void +RootlessMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind) +{ + CopyWindowProcPtr oldCopyWindowProc = NULL; + RegionRec saveRoot; + RootlessWindowRec *winRec = WINREC(pWin); + ScreenPtr pScreen = pWin->drawable.pScreen; + int oldX = 0, oldY = 0, newX = 0, newY = 0; + unsigned int oldW = 0, oldH = 0, oldBW = 0, newW = 0, newH = 0, newBW = 0; + + RL_DEBUG_MSG("movewindow start \n"); + + if (winRec) { + if (kind == VTMove) { + oldX = winRec->frame.x; + oldY = winRec->frame.y; + RootlessRedisplay(pWin); + } else { + RL_DEBUG_MSG("movewindow border resizing "); + oldBW = winRec->borderWidth; + oldX = winRec->frame.x; + oldY = winRec->frame.y; + oldW = winRec->frame.w; + oldH = winRec->frame.h; + newBW = pWin->borderWidth; + newX = x; + newY = y; + newW = pWin->drawable.width + 2*newBW; + newH = pWin->drawable.height + 2*newBW; + StartFrameResize(pWin, FALSE, oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW); + } + } + + HUGE_ROOT(pWin); + SCREEN_UNWRAP(pScreen, MoveWindow); + if (winRec) { + oldCopyWindowProc = pScreen->CopyWindow; + pScreen->CopyWindow = RootlessNoCopyWindow; + } + pScreen->MoveWindow(pWin, x, y, pSib, kind); + if (winRec) { + pScreen->CopyWindow = oldCopyWindowProc; + } + NORMAL_ROOT(pWin); + SCREEN_WRAP(pScreen, MoveWindow); + + if (winRec) { + if (kind == VTMove) { + // PositionWindow has already set the new frame position. + CallFrameProc(pScreen, MoveFrame, + (pScreen, &winRec->frame, oldX, oldY)); + } else { + FinishFrameResize(pWin, FALSE, oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW); + } + } + + RL_DEBUG_MSG("movewindow end\n"); +} + + +// Note: (x, y, w, h) as passed to this procedure don't match +// the frame definition. +// (x,y) is corner of very outer edge, *outside* border +// w,h is width and height *inside8 border, *ignoring* border width +// The rect (x, y, w, h) doesn't mean anything. +// (x, y, w+2*bw, h+2*bw) is total rect +// (x+bw, y+bw, w, h) is inner rect + +void +RootlessResizeWindow(WindowPtr pWin, int x, int y, + unsigned int w, unsigned int h, WindowPtr pSib) +{ + RegionRec saveRoot; + RootlessWindowRec *winRec = WINREC(pWin); + ScreenPtr pScreen = pWin->drawable.pScreen; + int oldX = 0, oldY = 0, newX = 0, newY = 0; + unsigned int oldW = 0, oldH = 0, oldBW = 0, newW = 0, newH = 0, newBW = 0; + + RL_DEBUG_MSG("resizewindow start (win 0x%x) ", pWin); + + if (winRec) { + oldBW = winRec->borderWidth; + oldX = winRec->frame.x; + oldY = winRec->frame.y; + oldW = winRec->frame.w; + oldH = winRec->frame.h; + + newBW = oldBW; + newX = x; + newY = y; + newW = w + 2*newBW; + newH = h + 2*newBW; + + StartFrameResize(pWin, TRUE, oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW); + } + + HUGE_ROOT(pWin); + SCREEN_UNWRAP(pScreen, ResizeWindow); + pScreen->ResizeWindow(pWin, x, y, w, h, pSib); + SCREEN_WRAP(pScreen, ResizeWindow); + NORMAL_ROOT(pWin); + + if (winRec) { + FinishFrameResize(pWin, TRUE, oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW); + } + + RL_DEBUG_MSG("resizewindow end\n"); +} + + +// fixme untested! +// pWin inside corner stays the same +// pWin->drawable.[xy] stays the same +// frame moves and resizes +void +RootlessChangeBorderWidth(WindowPtr pWin, unsigned int width) +{ + RegionRec saveRoot; + + RL_DEBUG_MSG("change border width "); + if (width != pWin->borderWidth) { + RootlessWindowRec *winRec = WINREC(pWin); + int oldX = 0, oldY = 0, newX = 0, newY = 0; + unsigned int oldW = 0, oldH = 0, oldBW = 0; + unsigned int newW = 0, newH = 0, newBW = 0; + + if (winRec) { + oldBW = winRec->borderWidth; + oldX = winRec->frame.x; + oldY = winRec->frame.y; + oldW = winRec->frame.w; + oldH = winRec->frame.h; + + newBW = width; + newX = pWin->drawable.x - newBW; + newY = pWin->drawable.y - newBW; + newW = pWin->drawable.width + 2*newBW; + newH = pWin->drawable.height + 2*newBW; + + StartFrameResize(pWin, FALSE, oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW); + } + + HUGE_ROOT(pWin); + SCREEN_UNWRAP(pWin->drawable.pScreen, ChangeBorderWidth); + pWin->drawable.pScreen->ChangeBorderWidth(pWin, width); + SCREEN_WRAP(pWin->drawable.pScreen, ChangeBorderWidth); + NORMAL_ROOT(pWin); + + if (winRec) { + FinishFrameResize(pWin, FALSE, oldX, oldY, oldW, oldH, oldBW, + newX, newY, newW, newH, newBW); + } + } + RL_DEBUG_MSG("change border width end\n"); +} |