xserver: Branch 'master' - 8 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Feb 27 12:00:12 UTC 2025


 hw/xfree86/sdksyms.sh |    1 
 mi/meson.build        |    2 
 mi/mioverlay.c        | 1862 ++++++++++++++++++++++++++++++++++++++++++++++++++
 mi/mioverlay.h        |   27 
 4 files changed, 1892 insertions(+)

New commits:
commit fe156104cfb18630f349f11b2df5992aa3630551
Author: Enrico Weigelt, metux IT consult <info at metux.net>
Date:   Wed Feb 26 17:57:47 2025 +0100

    Revert "mi: drop obsolete miInitOverlay()"
    
    This reverts commit 12ab2e314b6baef4a1e6155a6ee4f0a0c005e9f0.
    
    Requested by Nvidia - their proprietary driver still needs it.
    
    Signed-off-by: Enrico Weigelt, metux IT consult <info at metux.net>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1843>

diff --git a/mi/mioverlay.c b/mi/mioverlay.c
index 33ed8ed19..820133e10 100644
--- a/mi/mioverlay.c
+++ b/mi/mioverlay.c
@@ -62,9 +62,32 @@ static DevPrivateKeyRec miOverlayScreenKeyRec;
 
 #define miOverlayScreenKey (&miOverlayScreenKeyRec)
 
+static void RebuildTree(WindowPtr);
+static Bool HasUnderlayChildren(WindowPtr);
 static void MarkUnderlayWindow(WindowPtr);
 static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr);
 
+static Bool miOverlayCloseScreen(ScreenPtr);
+static Bool miOverlayCreateWindow(WindowPtr);
+static Bool miOverlayDestroyWindow(WindowPtr);
+static Bool miOverlayUnrealizeWindow(WindowPtr);
+static Bool miOverlayRealizeWindow(WindowPtr);
+static void miOverlayMarkWindow(WindowPtr);
+static void miOverlayReparentWindow(WindowPtr, WindowPtr);
+static void miOverlayRestackWindow(WindowPtr, WindowPtr);
+static Bool miOverlayMarkOverlappedWindows(WindowPtr, WindowPtr, WindowPtr *);
+static void miOverlayMarkUnrealizedWindow(WindowPtr, WindowPtr, Bool);
+static int miOverlayValidateTree(WindowPtr, WindowPtr, VTKind);
+static void miOverlayHandleExposures(WindowPtr);
+static void miOverlayMoveWindow(WindowPtr, int, int, WindowPtr, VTKind);
+static void miOverlayWindowExposures(WindowPtr, RegionPtr);
+static void miOverlayResizeWindow(WindowPtr, int, int, unsigned int,
+                                  unsigned int, WindowPtr);
+static void miOverlayClearToBackground(WindowPtr, int, int, int, int, Bool);
+
+static void miOverlaySetShape(WindowPtr, int);
+static void miOverlayChangeBorderWidth(WindowPtr, unsigned int);
+
 #define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen) ((miOverlayScreenPtr) \
 	dixLookupPrivate(&(pScreen)->devPrivates, miOverlayScreenKey))
 #define MIOVERLAY_GET_WINDOW_PRIVATE(pWin) ((miOverlayWindowPtr) \
@@ -72,8 +95,1440 @@ static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr);
 #define MIOVERLAY_GET_WINDOW_TREE(pWin) \
 	(MIOVERLAY_GET_WINDOW_PRIVATE(pWin)->tree)
 
+#define IN_UNDERLAY(w) MIOVERLAY_GET_WINDOW_TREE(w)
+#define IN_OVERLAY(w) !MIOVERLAY_GET_WINDOW_TREE(w)
+
+#define MARK_OVERLAY(w) miMarkWindow(w)
 #define MARK_UNDERLAY(w) MarkUnderlayWindow(w)
 
+#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
+                                    HasBorder(w) && \
+                                    (w)->backgroundState == ParentRelative)
+
+Bool
+miInitOverlay(ScreenPtr pScreen,
+              miOverlayInOverlayFunc inOverlayFunc,
+              miOverlayTransFunc transFunc)
+{
+    miOverlayScreenPtr pScreenPriv;
+
+    if (!inOverlayFunc || !transFunc)
+        return FALSE;
+
+    if (!dixRegisterPrivateKey
+        (&miOverlayWindowKeyRec, PRIVATE_WINDOW, sizeof(miOverlayWindowRec)))
+        return FALSE;
+
+    if (!dixRegisterPrivateKey(&miOverlayScreenKeyRec, PRIVATE_SCREEN, 0))
+        return FALSE;
+
+    if (!(pScreenPriv = malloc(sizeof(miOverlayScreenRec))))
+        return FALSE;
+
+    dixSetPrivate(&pScreen->devPrivates, miOverlayScreenKey, pScreenPriv);
+
+    pScreenPriv->InOverlay = inOverlayFunc;
+    pScreenPriv->MakeTransparent = transFunc;
+    pScreenPriv->underlayMarked = FALSE;
+
+    pScreenPriv->CloseScreen = pScreen->CloseScreen;
+    pScreenPriv->CreateWindow = pScreen->CreateWindow;
+    pScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+    pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow;
+    pScreenPriv->RealizeWindow = pScreen->RealizeWindow;
+
+    pScreen->CloseScreen = miOverlayCloseScreen;
+    pScreen->CreateWindow = miOverlayCreateWindow;
+    pScreen->DestroyWindow = miOverlayDestroyWindow;
+    pScreen->UnrealizeWindow = miOverlayUnrealizeWindow;
+    pScreen->RealizeWindow = miOverlayRealizeWindow;
+
+    pScreen->ReparentWindow = miOverlayReparentWindow;
+    pScreen->RestackWindow = miOverlayRestackWindow;
+    pScreen->MarkOverlappedWindows = miOverlayMarkOverlappedWindows;
+    pScreen->MarkUnrealizedWindow = miOverlayMarkUnrealizedWindow;
+    pScreen->ValidateTree = miOverlayValidateTree;
+    pScreen->HandleExposures = miOverlayHandleExposures;
+    pScreen->MoveWindow = miOverlayMoveWindow;
+    pScreen->WindowExposures = miOverlayWindowExposures;
+    pScreen->ResizeWindow = miOverlayResizeWindow;
+    pScreen->MarkWindow = miOverlayMarkWindow;
+    pScreen->ClearToBackground = miOverlayClearToBackground;
+    pScreen->SetShape = miOverlaySetShape;
+    pScreen->ChangeBorderWidth = miOverlayChangeBorderWidth;
+
+    return TRUE;
+}
+
+static Bool
+miOverlayCloseScreen(ScreenPtr pScreen)
+{
+    miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+
+    pScreen->CloseScreen = pScreenPriv->CloseScreen;
+    pScreen->CreateWindow = pScreenPriv->CreateWindow;
+    pScreen->DestroyWindow = pScreenPriv->DestroyWindow;
+    pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow;
+    pScreen->RealizeWindow = pScreenPriv->RealizeWindow;
+
+    free(pScreenPriv);
+
+    return (*pScreen->CloseScreen) (pScreen);
+}
+
+static Bool
+miOverlayCreateWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    miOverlayWindowPtr pWinPriv = MIOVERLAY_GET_WINDOW_PRIVATE(pWin);
+    miOverlayTreePtr pTree = NULL;
+    Bool result = TRUE;
+
+    pWinPriv->tree = NULL;
+
+    if (!pWin->parent || !((*pScreenPriv->InOverlay) (pWin))) {
+        if (!(pTree = (miOverlayTreePtr) calloc(1, sizeof(miOverlayTreeRec))))
+            return FALSE;
+    }
+
+    if (pScreenPriv->CreateWindow) {
+        pScreen->CreateWindow = pScreenPriv->CreateWindow;
+        result = (*pScreen->CreateWindow) (pWin);
+        pScreen->CreateWindow = miOverlayCreateWindow;
+    }
+
+    if (pTree) {
+        if (result) {
+            pTree->pWin = pWin;
+            pTree->visibility = VisibilityNotViewable;
+            pWinPriv->tree = pTree;
+            if (pWin->parent) {
+                RegionNull(&(pTree->borderClip));
+                RegionNull(&(pTree->clipList));
+                RebuildTree(pWin);
+            }
+            else {
+                BoxRec fullBox;
+
+                fullBox.x1 = 0;
+                fullBox.y1 = 0;
+                fullBox.x2 = pScreen->width;
+                fullBox.y2 = pScreen->height;
+                RegionInit(&(pTree->borderClip), &fullBox, 1);
+                RegionInit(&(pTree->clipList), &fullBox, 1);
+            }
+        }
+        else
+            free(pTree);
+    }
+
+    return TRUE;
+}
+
+static Bool
+miOverlayDestroyWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    Bool result = TRUE;
+
+    if (pTree) {
+        if (pTree->prevSib)
+            pTree->prevSib->nextSib = pTree->nextSib;
+        else if (pTree->parent)
+            pTree->parent->firstChild = pTree->nextSib;
+
+        if (pTree->nextSib)
+            pTree->nextSib->prevSib = pTree->prevSib;
+        else if (pTree->parent)
+            pTree->parent->lastChild = pTree->prevSib;
+
+        RegionUninit(&(pTree->borderClip));
+        RegionUninit(&(pTree->clipList));
+        free(pTree);
+    }
+
+    if (pScreenPriv->DestroyWindow) {
+        pScreen->DestroyWindow = pScreenPriv->DestroyWindow;
+        result = (*pScreen->DestroyWindow) (pWin);
+        pScreen->DestroyWindow = miOverlayDestroyWindow;
+    }
+
+    return result;
+}
+
+static Bool
+miOverlayUnrealizeWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    Bool result = TRUE;
+
+    if (pTree)
+        pTree->visibility = VisibilityNotViewable;
+
+    if (pScreenPriv->UnrealizeWindow) {
+        pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow;
+        result = (*pScreen->UnrealizeWindow) (pWin);
+        pScreen->UnrealizeWindow = miOverlayUnrealizeWindow;
+    }
+
+    return result;
+}
+
+static Bool
+miOverlayRealizeWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    Bool result = TRUE;
+
+    if (pScreenPriv->RealizeWindow) {
+        pScreen->RealizeWindow = pScreenPriv->RealizeWindow;
+        result = (*pScreen->RealizeWindow) (pWin);
+        pScreen->RealizeWindow = miOverlayRealizeWindow;
+    }
+
+    /* we only need to catch the root window realization */
+
+    if (result && !pWin->parent && !((*pScreenPriv->InOverlay) (pWin))) {
+        BoxRec box;
+
+        box.x1 = box.y1 = 0;
+        box.x2 = pWin->drawable.width;
+        box.y2 = pWin->drawable.height;
+        (*pScreenPriv->MakeTransparent) (pScreen, 1, &box);
+    }
+
+    return result;
+}
+
+static void
+miOverlayReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
+{
+    if (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) {
+        /* This could probably be more optimal */
+        RebuildTree(pWin->drawable.pScreen->root->firstChild);
+    }
+}
+
+static void
+miOverlayRestackWindow(WindowPtr pWin, WindowPtr oldNextSib)
+{
+    if (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) {
+        /* This could probably be more optimal */
+        RebuildTree(pWin);
+    }
+}
+
+static Bool
+miOverlayMarkOverlappedWindows(WindowPtr pWin,
+                               WindowPtr pFirst, WindowPtr *pLayerWin)
+{
+    WindowPtr pChild, pLast;
+    Bool overMarked, underMarked, doUnderlay, markAll;
+    miOverlayTreePtr pTree = NULL, tLast, tChild;
+    BoxPtr box;
+
+    overMarked = underMarked = markAll = FALSE;
+
+    if (pLayerWin)
+        *pLayerWin = pWin;      /* hah! */
+
+    doUnderlay = (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin));
+
+    box = RegionExtents(&pWin->borderSize);
+
+    if ((pChild = pFirst)) {
+        pLast = pChild->parent->lastChild;
+        while (1) {
+            if (pChild == pWin)
+                markAll = TRUE;
+
+            if (doUnderlay && IN_UNDERLAY(pChild))
+                pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
+
+            if (pChild->viewable) {
+                if (RegionBroken(&pChild->winSize))
+                    SetWinSize(pChild);
+                if (RegionBroken(&pChild->borderSize))
+                    SetBorderSize(pChild);
+
+                if (markAll || RegionContainsRect(&pChild->borderSize, box)) {
+                    MARK_OVERLAY(pChild);
+                    overMarked = TRUE;
+                    if (doUnderlay && IN_UNDERLAY(pChild)) {
+                        MARK_UNDERLAY(pChild);
+                        underMarked = TRUE;
+                    }
+                    if (pChild->firstChild) {
+                        pChild = pChild->firstChild;
+                        continue;
+                    }
+                }
+            }
+            while (!pChild->nextSib && (pChild != pLast)) {
+                pChild = pChild->parent;
+                if (doUnderlay && IN_UNDERLAY(pChild))
+                    pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
+            }
+
+            if (pChild == pWin)
+                markAll = FALSE;
+
+            if (pChild == pLast)
+                break;
+
+            pChild = pChild->nextSib;
+        }
+        if (overMarked)
+            MARK_OVERLAY(pWin->parent);
+    }
+
+    if (doUnderlay && !pTree) {
+        if (!(pTree = MIOVERLAY_GET_WINDOW_TREE(pWin))) {
+            pChild = pWin->lastChild;
+            while (1) {
+                if ((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild)))
+                    break;
+
+                if (pChild->lastChild) {
+                    pChild = pChild->lastChild;
+                    continue;
+                }
+
+                while (!pChild->prevSib)
+                    pChild = pChild->parent;
+
+                pChild = pChild->prevSib;
+            }
+        }
+    }
+
+    if (pTree && pTree->nextSib) {
+        tChild = pTree->parent->lastChild;
+        tLast = pTree->nextSib;
+
+        while (1) {
+            if (tChild->pWin->viewable) {
+                if (RegionBroken(&tChild->pWin->winSize))
+                    SetWinSize(tChild->pWin);
+                if (RegionBroken(&tChild->pWin->borderSize))
+                    SetBorderSize(tChild->pWin);
+
+                if (RegionContainsRect(&(tChild->pWin->borderSize), box)) {
+                    MARK_UNDERLAY(tChild->pWin);
+                    underMarked = TRUE;
+                }
+            }
+
+            if (tChild->lastChild) {
+                tChild = tChild->lastChild;
+                continue;
+            }
+
+            while (!tChild->prevSib && (tChild != tLast))
+                tChild = tChild->parent;
+
+            if (tChild == tLast)
+                break;
+
+            tChild = tChild->prevSib;
+        }
+    }
+
+    if (underMarked) {
+        ScreenPtr pScreen = pWin->drawable.pScreen;
+
+        MARK_UNDERLAY(pTree->parent->pWin);
+        MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->underlayMarked = TRUE;
+    }
+
+    return underMarked || overMarked;
+}
+
+static void
+miOverlayComputeClips(WindowPtr pParent,
+                      RegionPtr universe, VTKind kind, RegionPtr exposed)
+{
+    ScreenPtr pScreen = pParent->drawable.pScreen;
+    int oldVis, newVis, dx, dy;
+    BoxRec borderSize;
+    RegionPtr borderVisible;
+    RegionRec childUniverse, childUnion;
+    miOverlayTreePtr tParent = MIOVERLAY_GET_WINDOW_TREE(pParent);
+    miOverlayTreePtr tChild;
+    Bool overlap;
+
+    borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
+    borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
+    dx = (int) pParent->drawable.x + (int) pParent->drawable.width +
+        wBorderWidth(pParent);
+    if (dx > 32767)
+        dx = 32767;
+    borderSize.x2 = dx;
+    dy = (int) pParent->drawable.y + (int) pParent->drawable.height +
+        wBorderWidth(pParent);
+    if (dy > 32767)
+        dy = 32767;
+    borderSize.y2 = dy;
+
+    oldVis = tParent->visibility;
+    switch (RegionContainsRect(universe, &borderSize)) {
+    case rgnIN:
+        newVis = VisibilityUnobscured;
+        break;
+    case rgnPART:
+        newVis = VisibilityPartiallyObscured;
+        {
+            RegionPtr pBounding;
+
+            if ((pBounding = wBoundingShape(pParent))) {
+                switch (miShapedWindowIn(universe, pBounding,
+                                         &borderSize,
+                                         pParent->drawable.x,
+                                         pParent->drawable.y)) {
+                case rgnIN:
+                    newVis = VisibilityUnobscured;
+                    break;
+                case rgnOUT:
+                    newVis = VisibilityFullyObscured;
+                    break;
+                }
+            }
+        }
+        break;
+    default:
+        newVis = VisibilityFullyObscured;
+        break;
+    }
+    tParent->visibility = newVis;
+
+    dx = pParent->drawable.x - tParent->valdata->oldAbsCorner.x;
+    dy = pParent->drawable.y - tParent->valdata->oldAbsCorner.y;
+
+    switch (kind) {
+    case VTMap:
+    case VTStack:
+    case VTUnmap:
+        break;
+    case VTMove:
+        if ((oldVis == newVis) &&
+            ((oldVis == VisibilityFullyObscured) ||
+             (oldVis == VisibilityUnobscured))) {
+            tChild = tParent;
+            while (1) {
+                if (tChild->pWin->viewable) {
+                    if (tChild->visibility != VisibilityFullyObscured) {
+                        RegionTranslate(&tChild->borderClip, dx, dy);
+                        RegionTranslate(&tChild->clipList, dx, dy);
+
+                        tChild->pWin->drawable.serialNumber =
+                            NEXT_SERIAL_NUMBER;
+                        if (pScreen->ClipNotify)
+                            (*pScreen->ClipNotify) (tChild->pWin, dx, dy);
+                    }
+                    if (tChild->valdata) {
+                        RegionNull(&tChild->valdata->borderExposed);
+                        if (HasParentRelativeBorder(tChild->pWin)) {
+                            RegionSubtract(&tChild->valdata->borderExposed,
+                                           &tChild->borderClip,
+                                           &tChild->pWin->winSize);
+                        }
+                        RegionNull(&tChild->valdata->exposed);
+                    }
+                    if (tChild->firstChild) {
+                        tChild = tChild->firstChild;
+                        continue;
+                    }
+                }
+                while (!tChild->nextSib && (tChild != tParent))
+                    tChild = tChild->parent;
+                if (tChild == tParent)
+                    break;
+                tChild = tChild->nextSib;
+            }
+            return;
+        }
+        /* fall through */
+    default:
+        if (dx || dy) {
+            RegionTranslate(&tParent->borderClip, dx, dy);
+            RegionTranslate(&tParent->clipList, dx, dy);
+        }
+        break;
+    case VTBroken:
+        RegionEmpty(&tParent->borderClip);
+        RegionEmpty(&tParent->clipList);
+        break;
+    }
+
+    borderVisible = tParent->valdata->borderVisible;
+    RegionNull(&tParent->valdata->borderExposed);
+    RegionNull(&tParent->valdata->exposed);
+
+    if (HasBorder(pParent)) {
+        if (borderVisible) {
+            RegionSubtract(exposed, universe, borderVisible);
+            RegionDestroy(borderVisible);
+        }
+        else
+            RegionSubtract(exposed, universe, &tParent->borderClip);
+
+        if (HasParentRelativeBorder(pParent) && (dx || dy))
+            RegionSubtract(&tParent->valdata->borderExposed,
+                           universe, &pParent->winSize);
+        else
+            RegionSubtract(&tParent->valdata->borderExposed,
+                           exposed, &pParent->winSize);
+
+        RegionCopy(&tParent->borderClip, universe);
+        RegionIntersect(universe, universe, &pParent->winSize);
+    }
+    else
+        RegionCopy(&tParent->borderClip, universe);
+
+    if ((tChild = tParent->firstChild) && pParent->mapped) {
+        RegionNull(&childUniverse);
+        RegionNull(&childUnion);
+
+        for (; tChild; tChild = tChild->nextSib) {
+            if (tChild->pWin->viewable)
+                RegionAppend(&childUnion, &tChild->pWin->borderSize);
+        }
+
+        RegionValidate(&childUnion, &overlap);
+
+        for (tChild = tParent->firstChild; tChild; tChild = tChild->nextSib) {
+            if (tChild->pWin->viewable) {
+                if (tChild->valdata) {
+                    RegionIntersect(&childUniverse, universe,
+                                    &tChild->pWin->borderSize);
+                    miOverlayComputeClips(tChild->pWin, &childUniverse,
+                                          kind, exposed);
+                }
+                if (overlap)
+                    RegionSubtract(universe, universe,
+                                   &tChild->pWin->borderSize);
+            }
+        }
+        if (!overlap)
+            RegionSubtract(universe, universe, &childUnion);
+        RegionUninit(&childUnion);
+        RegionUninit(&childUniverse);
+    }
+
+    if (oldVis == VisibilityFullyObscured || oldVis == VisibilityNotViewable) {
+        RegionCopy(&tParent->valdata->exposed, universe);
+    }
+    else if (newVis != VisibilityFullyObscured &&
+             newVis != VisibilityNotViewable) {
+        RegionSubtract(&tParent->valdata->exposed,
+                       universe, &tParent->clipList);
+    }
+
+    /* HACK ALERT - copying contents of regions, instead of regions */
+    {
+        RegionRec tmp;
+
+        tmp = tParent->clipList;
+        tParent->clipList = *universe;
+        *universe = tmp;
+    }
+
+    pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    if (pScreen->ClipNotify)
+        (*pScreen->ClipNotify) (pParent, dx, dy);
+}
+
+static void
+miOverlayMarkWindow(WindowPtr pWin)
+{
+    miOverlayTreePtr pTree = NULL;
+    WindowPtr pChild, pGrandChild;
+
+    miMarkWindow(pWin);
+
+    /* look for UnmapValdata among immediate children */
+
+    if (!(pChild = pWin->firstChild))
+        return;
+
+    for (; pChild; pChild = pChild->nextSib) {
+        if (pChild->valdata == UnmapValData) {
+            if (IN_UNDERLAY(pChild)) {
+                pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
+                pTree->valdata = (miOverlayValDataPtr) UnmapValData;
+                continue;
+            }
+            else {
+                if (!(pGrandChild = pChild->firstChild))
+                    continue;
+
+                while (1) {
+                    if (IN_UNDERLAY(pGrandChild)) {
+                        pTree = MIOVERLAY_GET_WINDOW_TREE(pGrandChild);
+                        pTree->valdata = (miOverlayValDataPtr) UnmapValData;
+                    }
+                    else if (pGrandChild->firstChild) {
+                        pGrandChild = pGrandChild->firstChild;
+                        continue;
+                    }
+
+                    while (!pGrandChild->nextSib && (pGrandChild != pChild))
+                        pGrandChild = pGrandChild->parent;
+
+                    if (pChild == pGrandChild)
+                        break;
+
+                    pGrandChild = pGrandChild->nextSib;
+                }
+            }
+        }
+    }
+
+    if (pTree) {
+        MARK_UNDERLAY(pTree->parent->pWin);
+        MIOVERLAY_GET_SCREEN_PRIVATE(pWin->drawable.pScreen)->underlayMarked =
+            TRUE;
+    }
+}
+
+static void
+miOverlayMarkUnrealizedWindow(WindowPtr pChild,
+                              WindowPtr pWin, Bool fromConfigure)
+{
+    if ((pChild != pWin) || fromConfigure) {
+        miOverlayTreePtr pTree;
+
+        RegionEmpty(&pChild->clipList);
+        if (pChild->drawable.pScreen->ClipNotify)
+            (*pChild->drawable.pScreen->ClipNotify) (pChild, 0, 0);
+        RegionEmpty(&pChild->borderClip);
+        if ((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
+            if (pTree->valdata != (miOverlayValDataPtr) UnmapValData) {
+                RegionEmpty(&pTree->clipList);
+                RegionEmpty(&pTree->borderClip);
+            }
+        }
+    }
+}
+
+static int
+miOverlayValidateTree(WindowPtr pParent, WindowPtr pChild,      /* first child effected */
+                      VTKind kind)
+{
+    ScreenPtr pScreen = pParent->drawable.pScreen;
+    miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    RegionRec totalClip, childClip, exposed;
+    miOverlayTreePtr tParent, tChild, tWin;
+    Bool overlap;
+    WindowPtr newParent;
+
+    if (!pPriv->underlayMarked)
+        goto SKIP_UNDERLAY;
+
+    if (!pChild)
+        pChild = pParent->firstChild;
+
+    RegionNull(&totalClip);
+    RegionNull(&childClip);
+    RegionNull(&exposed);
+
+    newParent = pParent;
+
+    while (IN_OVERLAY(newParent))
+        newParent = newParent->parent;
+
+    tParent = MIOVERLAY_GET_WINDOW_TREE(newParent);
+
+    if (IN_UNDERLAY(pChild))
+        tChild = MIOVERLAY_GET_WINDOW_TREE(pChild);
+    else
+        tChild = tParent->firstChild;
+
+    if (RegionBroken(&tParent->clipList) && !RegionBroken(&tParent->borderClip)) {
+        kind = VTBroken;
+        RegionCopy(&totalClip, &tParent->borderClip);
+        RegionIntersect(&totalClip, &totalClip, &tParent->pWin->winSize);
+
+        for (tWin = tParent->firstChild; tWin != tChild; tWin = tWin->nextSib) {
+            if (tWin->pWin->viewable)
+                RegionSubtract(&totalClip, &totalClip, &tWin->pWin->borderSize);
+        }
+        RegionEmpty(&tParent->clipList);
+    }
+    else {
+        for (tWin = tChild; tWin; tWin = tWin->nextSib) {
+            if (tWin->valdata)
+                RegionAppend(&totalClip, &tWin->borderClip);
+        }
+        RegionValidate(&totalClip, &overlap);
+    }
+
+    if (kind != VTStack)
+        RegionUnion(&totalClip, &totalClip, &tParent->clipList);
+
+    for (tWin = tChild; tWin; tWin = tWin->nextSib) {
+        if (tWin->valdata) {
+            if (tWin->pWin->viewable) {
+                RegionIntersect(&childClip, &totalClip,
+                                &tWin->pWin->borderSize);
+                miOverlayComputeClips(tWin->pWin, &childClip, kind, &exposed);
+                RegionSubtract(&totalClip, &totalClip, &tWin->pWin->borderSize);
+            }
+            else {              /* Means we are unmapping */
+                RegionEmpty(&tWin->clipList);
+                RegionEmpty(&tWin->borderClip);
+                tWin->valdata = NULL;
+            }
+        }
+    }
+
+    RegionUninit(&childClip);
+
+    if (!((*pPriv->InOverlay) (newParent))) {
+        RegionNull(&tParent->valdata->exposed);
+        RegionNull(&tParent->valdata->borderExposed);
+    }
+
+    switch (kind) {
+    case VTStack:
+        break;
+    default:
+        if (!((*pPriv->InOverlay) (newParent)))
+            RegionSubtract(&tParent->valdata->exposed, &totalClip,
+                           &tParent->clipList);
+        /* fall through */
+    case VTMap:
+        RegionCopy(&tParent->clipList, &totalClip);
+        if (!((*pPriv->InOverlay) (newParent)))
+            newParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+        break;
+    }
+
+    RegionUninit(&totalClip);
+    RegionUninit(&exposed);
+
+ SKIP_UNDERLAY:
+
+    miValidateTree(pParent, pChild, kind);
+
+    return 1;
+}
+
+static void
+miOverlayHandleExposures(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    WindowPtr pChild;
+    ValidatePtr val;
+    WindowExposuresProcPtr WindowExposures;
+
+    WindowExposures = pWin->drawable.pScreen->WindowExposures;
+    if (pPriv->underlayMarked) {
+        miOverlayTreePtr pTree;
+        miOverlayValDataPtr mival;
+
+        pChild = pWin;
+        while (IN_OVERLAY(pChild))
+            pChild = pChild->parent;
+
+        pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
+
+        while (1) {
+            if ((mival = pTree->valdata)) {
+                if (!((*pPriv->InOverlay) (pTree->pWin))) {
+                    if (RegionNotEmpty(&mival->borderExposed)) {
+                        pScreen->PaintWindow(pTree->pWin, &mival->borderExposed,
+                                             PW_BORDER);
+                    }
+                    RegionUninit(&mival->borderExposed);
+
+                    (*WindowExposures) (pTree->pWin, &mival->exposed);
+                    RegionUninit(&mival->exposed);
+                }
+                free(mival);
+                pTree->valdata = NULL;
+                if (pTree->firstChild) {
+                    pTree = pTree->firstChild;
+                    continue;
+                }
+            }
+            while (!pTree->nextSib && (pTree->pWin != pChild))
+                pTree = pTree->parent;
+            if (pTree->pWin == pChild)
+                break;
+            pTree = pTree->nextSib;
+        }
+        pPriv->underlayMarked = FALSE;
+    }
+
+    pChild = pWin;
+    while (1) {
+        if ((val = pChild->valdata)) {
+            if (!((*pPriv->InOverlay) (pChild))) {
+                RegionUnion(&val->after.exposed, &val->after.exposed,
+                            &val->after.borderExposed);
+
+                if (RegionNotEmpty(&val->after.exposed)) {
+                    (*(MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent))
+                        (pScreen, RegionNumRects(&val->after.exposed),
+                         RegionRects(&val->after.exposed));
+                }
+            }
+            else {
+                if (RegionNotEmpty(&val->after.borderExposed)) {
+                    pScreen->PaintWindow(pChild, &val->after.borderExposed,
+                                         PW_BORDER);
+                }
+                (*WindowExposures) (pChild, &val->after.exposed);
+            }
+            RegionUninit(&val->after.borderExposed);
+            RegionUninit(&val->after.exposed);
+            free(val);
+            pChild->valdata = NULL;
+            if (pChild->firstChild) {
+                pChild = pChild->firstChild;
+                continue;
+            }
+        }
+        while (!pChild->nextSib && (pChild != pWin))
+            pChild = pChild->parent;
+        if (pChild == pWin)
+            break;
+        pChild = pChild->nextSib;
+    }
+}
+
+static void
+miOverlayMoveWindow(WindowPtr pWin,
+                    int x, int y, WindowPtr pNextSib, VTKind kind)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    WindowPtr pParent, windowToValidate;
+    Bool WasViewable = (Bool) (pWin->viewable);
+    short bw;
+    RegionRec overReg, underReg;
+    DDXPointRec oldpt;
+
+    if (!(pParent = pWin->parent))
+        return;
+    bw = wBorderWidth(pWin);
+
+    oldpt.x = pWin->drawable.x;
+    oldpt.y = pWin->drawable.y;
+    if (WasViewable) {
+        RegionNull(&overReg);
+        RegionNull(&underReg);
+        if (pTree) {
+            RegionCopy(&overReg, &pWin->borderClip);
+            RegionCopy(&underReg, &pTree->borderClip);
+        }
+        else {
+            RegionCopy(&overReg, &pWin->borderClip);
+            CollectUnderlayChildrenRegions(pWin, &underReg);
+        }
+        (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
+    }
+    pWin->origin.x = x + (int) bw;
+    pWin->origin.y = y + (int) bw;
+    x = pWin->drawable.x = pParent->drawable.x + x + (int) bw;
+    y = pWin->drawable.y = pParent->drawable.y + y + (int) bw;
+
+    SetWinSize(pWin);
+    SetBorderSize(pWin);
+
+    (*pScreen->PositionWindow) (pWin, x, y);
+
+    windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+    ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+    if (WasViewable) {
+        miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+
+        (*pScreen->MarkOverlappedWindows) (pWin, windowToValidate, NULL);
+
+        (*pScreen->ValidateTree) (pWin->parent, NullWindow, kind);
+        if (RegionNotEmpty(&underReg)) {
+            pPriv->copyUnderlay = TRUE;
+            (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, &underReg);
+        }
+        RegionUninit(&underReg);
+        if (RegionNotEmpty(&overReg)) {
+            pPriv->copyUnderlay = FALSE;
+            (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, &overReg);
+        }
+        RegionUninit(&overReg);
+        (*pScreen->HandleExposures) (pWin->parent);
+
+        if (pScreen->PostValidateTree)
+            (*pScreen->PostValidateTree) (pWin->parent, NullWindow, kind);
+    }
+    if (pWin->realized)
+        WindowsRestructured();
+}
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25
+#endif
+
+static void
+miOverlayWindowExposures(WindowPtr pWin, RegionPtr prgn)
+{
+    RegionPtr exposures = prgn;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    if (prgn && !RegionNil(prgn)) {
+        RegionRec expRec;
+        int clientInterested =
+            (pWin->eventMask | wOtherEventMasks(pWin)) & ExposureMask;
+        if (clientInterested && (RegionNumRects(prgn) > RECTLIMIT)) {
+            miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+            BoxRec box;
+
+            box = *RegionExtents(prgn);
+            exposures = &expRec;
+            RegionInit(exposures, &box, 1);
+            RegionReset(prgn, &box);
+            /* This is the only reason why we are replacing mi's version
+               of this file */
+
+            if (!((*pPriv->InOverlay) (pWin))) {
+                miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+                RegionIntersect(prgn, prgn, &pTree->clipList);
+            }
+            else
+                RegionIntersect(prgn, prgn, &pWin->clipList);
+        }
+        pScreen->PaintWindow(pWin, prgn, PW_BACKGROUND);
+        if (clientInterested)
+            miSendExposures(pWin, exposures,
+                            pWin->drawable.x, pWin->drawable.y);
+        if (exposures == &expRec)
+            RegionUninit(exposures);
+        RegionEmpty(prgn);
+    }
+}
+
+typedef struct {
+    RegionPtr over;
+    RegionPtr under;
+} miOverlayTwoRegions;
+
+static int
+miOverlayRecomputeExposures(WindowPtr pWin, void *value)
+{
+    miOverlayTwoRegions *pValid = (miOverlayTwoRegions *) value;
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+    if (pWin->valdata) {
+        /*
+         * compute exposed regions of this window
+         */
+        RegionSubtract(&pWin->valdata->after.exposed,
+                       &pWin->clipList, pValid->over);
+        /*
+         * compute exposed regions of the border
+         */
+        RegionSubtract(&pWin->valdata->after.borderExposed,
+                       &pWin->borderClip, &pWin->winSize);
+        RegionSubtract(&pWin->valdata->after.borderExposed,
+                       &pWin->valdata->after.borderExposed, pValid->over);
+    }
+
+    if (pTree && pTree->valdata) {
+        RegionSubtract(&pTree->valdata->exposed,
+                       &pTree->clipList, pValid->under);
+        RegionSubtract(&pTree->valdata->borderExposed,
+                       &pTree->borderClip, &pWin->winSize);
+        RegionSubtract(&pTree->valdata->borderExposed,
+                       &pTree->valdata->borderExposed, pValid->under);
+    }
+    else if (!pWin->valdata)
+        return WT_NOMATCH;
+
+    return WT_WALKCHILDREN;
+}
+
+static void
+miOverlayResizeWindow(WindowPtr pWin,
+                      int x, int y,
+                      unsigned int w, unsigned int h, WindowPtr pSib)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    WindowPtr pParent;
+    miOverlayTreePtr tChild, pTree;
+    Bool WasViewable = (Bool) (pWin->viewable);
+    unsigned short width = pWin->drawable.width;
+    unsigned short height = pWin->drawable.height;
+    short oldx = pWin->drawable.x;
+    short oldy = pWin->drawable.y;
+    int bw = wBorderWidth(pWin);
+    short dw, dh;
+    DDXPointRec oldpt;
+    RegionPtr oldRegion = NULL, oldRegion2 = NULL;
+    WindowPtr pFirstChange;
+    WindowPtr pChild;
+    RegionPtr gravitate[StaticGravity + 1];
+    RegionPtr gravitate2[StaticGravity + 1];
+    unsigned g;
+    int nx, ny;                 /* destination x,y */
+    int newx, newy;             /* new inner window position */
+    RegionPtr pRegion = NULL;
+    RegionPtr destClip, destClip2;
+    RegionPtr oldWinClip = NULL, oldWinClip2 = NULL;
+    RegionPtr borderVisible = NullRegion;
+    RegionPtr borderVisible2 = NullRegion;
+    Bool shrunk = FALSE;        /* shrunk in an inner dimension */
+    Bool moved = FALSE;         /* window position changed */
+    Bool doUnderlay;
+
+    /* if this is a root window, can't be resized */
+    if (!(pParent = pWin->parent))
+        return;
+
+    pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    doUnderlay = ((pTree) || HasUnderlayChildren(pWin));
+    newx = pParent->drawable.x + x + bw;
+    newy = pParent->drawable.y + y + bw;
+    if (WasViewable) {
+        /*
+         * save the visible region of the window
+         */
+        oldRegion = RegionCreate(NullBox, 1);
+        RegionCopy(oldRegion, &pWin->winSize);
+        if (doUnderlay) {
+            oldRegion2 = RegionCreate(NullBox, 1);
+            RegionCopy(oldRegion2, &pWin->winSize);
+        }
+
+        /*
+         * categorize child windows into regions to be moved
+         */
+        for (g = 0; g <= StaticGravity; g++)
+            gravitate[g] = gravitate2[g] = NULL;
+        for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
+            g = pChild->winGravity;
+            if (g != UnmapGravity) {
+                if (!gravitate[g])
+                    gravitate[g] = RegionCreate(NullBox, 1);
+                RegionUnion(gravitate[g], gravitate[g], &pChild->borderClip);
+
+                if (doUnderlay) {
+                    if (!gravitate2[g])
+                        gravitate2[g] = RegionCreate(NullBox, 0);
+
+                    if ((tChild = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
+                        RegionUnion(gravitate2[g],
+                                    gravitate2[g], &tChild->borderClip);
+                    }
+                    else
+                        CollectUnderlayChildrenRegions(pChild, gravitate2[g]);
+                }
+            }
+            else {
+                UnmapWindow(pChild, TRUE);
+            }
+        }
+        (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
+
+        oldWinClip = oldWinClip2 = NULL;
+        if (pWin->bitGravity != ForgetGravity) {
+            oldWinClip = RegionCreate(NullBox, 1);
+            RegionCopy(oldWinClip, &pWin->clipList);
+            if (pTree) {
+                oldWinClip2 = RegionCreate(NullBox, 1);
+                RegionCopy(oldWinClip2, &pTree->clipList);
+            }
+        }
+        /*
+         * if the window is changing size, borderExposed
+         * can't be computed correctly without some help.
+         */
+        if (pWin->drawable.height > h || pWin->drawable.width > w)
+            shrunk = TRUE;
+
+        if (newx != oldx || newy != oldy)
+            moved = TRUE;
+
+        if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+            HasBorder(pWin)) {
+            borderVisible = RegionCreate(NullBox, 1);
+            if (pTree)
+                borderVisible2 = RegionCreate(NullBox, 1);
+            /* for tiled borders, we punt and draw the whole thing */
+            if (pWin->borderIsPixel || !moved) {
+                if (shrunk || moved)
+                    RegionSubtract(borderVisible,
+                                   &pWin->borderClip, &pWin->winSize);
+                else
+                    RegionCopy(borderVisible, &pWin->borderClip);
+                if (pTree) {
+                    if (shrunk || moved)
+                        RegionSubtract(borderVisible,
+                                       &pTree->borderClip, &pWin->winSize);
+                    else
+                        RegionCopy(borderVisible, &pTree->borderClip);
+                }
+            }
+        }
+    }
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.height = h;
+    pWin->drawable.width = w;
+
+    x = pWin->drawable.x = newx;
+    y = pWin->drawable.y = newy;
+
+    SetWinSize(pWin);
+    SetBorderSize(pWin);
+
+    dw = (int) w - (int) width;
+    dh = (int) h - (int) height;
+    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+    /* let the hardware adjust background and border pixmaps, if any */
+    (*pScreen->PositionWindow) (pWin, x, y);
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable) {
+        pRegion = RegionCreate(NullBox, 1);
+
+        (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange, NULL);
+
+        pWin->valdata->before.resized = TRUE;
+        pWin->valdata->before.borderVisible = borderVisible;
+        if (pTree)
+            pTree->valdata->borderVisible = borderVisible2;
+
+        (*pScreen->ValidateTree) (pWin->parent, pFirstChange, VTOther);
+        /*
+         * the entire window is trashed unless bitGravity
+         * recovers portions of it
+         */
+        RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList);
+        if (pTree)
+            RegionCopy(&pTree->valdata->exposed, &pTree->clipList);
+    }
+
+    GravityTranslate(x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+    if (WasViewable) {
+        miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+        miOverlayTwoRegions TwoRegions;
+
+        /* avoid the border */
+        if (HasBorder(pWin)) {
+            int offx, offy, dx, dy;
+
+            /* kruft to avoid double translates for each gravity */
+            offx = 0;
+            offy = 0;
+            for (g = 0; g <= StaticGravity; g++) {
+                if (!gravitate[g] && !gravitate2[g])
+                    continue;
+
+                /* align winSize to gravitate[g].
+                 * winSize is in new coordinates,
+                 * gravitate[g] is still in old coordinates */
+                GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+                dx = (oldx - nx) - offx;
+                dy = (oldy - ny) - offy;
+                if (dx || dy) {
+                    RegionTranslate(&pWin->winSize, dx, dy);
+                    offx += dx;
+                    offy += dy;
+                }
+                if (gravitate[g])
+                    RegionIntersect(gravitate[g], gravitate[g], &pWin->winSize);
+                if (gravitate2[g])
+                    RegionIntersect(gravitate2[g], gravitate2[g],
+                                    &pWin->winSize);
+            }
+            /* get winSize back where it belongs */
+            if (offx || offy)
+                RegionTranslate(&pWin->winSize, -offx, -offy);
+        }
+        /*
+         * add screen bits to the appropriate bucket
+         */
+
+        if (oldWinClip2) {
+            RegionCopy(pRegion, oldWinClip2);
+            RegionTranslate(pRegion, nx - oldx, ny - oldy);
+            RegionIntersect(oldWinClip2, pRegion, &pTree->clipList);
+
+            for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
+                if (gravitate2[g])
+                    RegionSubtract(oldWinClip2, oldWinClip2, gravitate2[g]);
+            }
+            RegionTranslate(oldWinClip2, oldx - nx, oldy - ny);
+            g = pWin->bitGravity;
+            if (!gravitate2[g])
+                gravitate2[g] = oldWinClip2;
+            else {
+                RegionUnion(gravitate2[g], gravitate2[g], oldWinClip2);
+                RegionDestroy(oldWinClip2);
+            }
+        }
+
+        if (oldWinClip) {
+            /*
+             * clip to new clipList
+             */
+            RegionCopy(pRegion, oldWinClip);
+            RegionTranslate(pRegion, nx - oldx, ny - oldy);
+            RegionIntersect(oldWinClip, pRegion, &pWin->clipList);
+            /*
+             * don't step on any gravity bits which will be copied after this
+             * region.  Note -- this assumes that the regions will be copied
+             * in gravity order.
+             */
+            for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
+                if (gravitate[g])
+                    RegionSubtract(oldWinClip, oldWinClip, gravitate[g]);
+            }
+            RegionTranslate(oldWinClip, oldx - nx, oldy - ny);
+            g = pWin->bitGravity;
+            if (!gravitate[g])
+                gravitate[g] = oldWinClip;
+            else {
+                RegionUnion(gravitate[g], gravitate[g], oldWinClip);
+                RegionDestroy(oldWinClip);
+            }
+        }
+
+        /*
+         * move the bits on the screen
+         */
+
+        destClip = destClip2 = NULL;
+
+        for (g = 0; g <= StaticGravity; g++) {
+            if (!gravitate[g] && !gravitate2[g])
+                continue;
+
+            GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+            oldpt.x = oldx + (x - nx);
+            oldpt.y = oldy + (y - ny);
+
+            /* Note that gravitate[g] is *translated* by CopyWindow */
+
+            /* only copy the remaining useful bits */
+
+            if (gravitate[g])
+                RegionIntersect(gravitate[g], gravitate[g], oldRegion);
+            if (gravitate2[g])
+                RegionIntersect(gravitate2[g], gravitate2[g], oldRegion2);
+
+            /* clip to not overwrite already copied areas */
+
+            if (destClip && gravitate[g]) {
+                RegionTranslate(destClip, oldpt.x - x, oldpt.y - y);
+                RegionSubtract(gravitate[g], gravitate[g], destClip);
+                RegionTranslate(destClip, x - oldpt.x, y - oldpt.y);
+            }
+            if (destClip2 && gravitate2[g]) {
+                RegionTranslate(destClip2, oldpt.x - x, oldpt.y - y);
+                RegionSubtract(gravitate2[g], gravitate2[g], destClip2);
+                RegionTranslate(destClip2, x - oldpt.x, y - oldpt.y);
+            }
+
+            /* and move those bits */
+
+            if (oldpt.x != x || oldpt.y != y) {
+                if (gravitate2[g]) {
+                    pPriv->copyUnderlay = TRUE;
+                    (*pScreen->CopyWindow) (pWin, oldpt, gravitate2[g]);
+                }
+                if (gravitate[g]) {
+                    pPriv->copyUnderlay = FALSE;
+                    (*pScreen->CopyWindow) (pWin, oldpt, gravitate[g]);
+                }
+            }
+
+            /* remove any overwritten bits from the remaining useful bits */
+
+            if (gravitate[g])
+                RegionSubtract(oldRegion, oldRegion, gravitate[g]);
+            if (gravitate2[g])
+                RegionSubtract(oldRegion2, oldRegion2, gravitate2[g]);
+
+            /*
+             * recompute exposed regions of child windows
+             */
+
+            for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
+                if (pChild->winGravity != g)
+                    continue;
+
+                TwoRegions.over = gravitate[g];
+                TwoRegions.under = gravitate2[g];
+
+                TraverseTree(pChild, miOverlayRecomputeExposures,
+                             (void *) (&TwoRegions));
+            }
+
+            /*
+             * remove the successfully copied regions of the
+             * window from its exposed region
+             */
+
+            if (g == pWin->bitGravity) {
+                if (gravitate[g])
+                    RegionSubtract(&pWin->valdata->after.exposed,
+                                   &pWin->valdata->after.exposed, gravitate[g]);
+                if (gravitate2[g] && pTree)
+                    RegionSubtract(&pTree->valdata->exposed,
+                                   &pTree->valdata->exposed, gravitate2[g]);
+            }
+            if (gravitate[g]) {
+                if (!destClip)
+                    destClip = gravitate[g];
+                else {
+                    RegionUnion(destClip, destClip, gravitate[g]);
+                    RegionDestroy(gravitate[g]);
+                }
+            }
+            if (gravitate2[g]) {
+                if (!destClip2)
+                    destClip2 = gravitate2[g];
+                else {
+                    RegionUnion(destClip2, destClip2, gravitate2[g]);
+                    RegionDestroy(gravitate2[g]);
+                }
+            }
+        }
+
+        RegionDestroy(pRegion);
+        RegionDestroy(oldRegion);
+        if (doUnderlay)
+            RegionDestroy(oldRegion2);
+        if (destClip)
+            RegionDestroy(destClip);
+        if (destClip2)
+            RegionDestroy(destClip2);
+        (*pScreen->HandleExposures) (pWin->parent);
+        if (pScreen->PostValidateTree)
+            (*pScreen->PostValidateTree) (pWin->parent, pFirstChange, VTOther);
+    }
+    if (pWin->realized)
+        WindowsRestructured();
+}
+
+static void
+miOverlaySetShape(WindowPtr pWin, int kind)
+{
+    Bool WasViewable = (Bool) (pWin->viewable);
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    if (kind != ShapeInput) {
+        if (WasViewable) {
+            (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
+
+            if (HasBorder(pWin)) {
+                RegionPtr borderVisible;
+
+                borderVisible = RegionCreate(NullBox, 1);
+                RegionSubtract(borderVisible,
+                               &pWin->borderClip, &pWin->winSize);
+                pWin->valdata->before.borderVisible = borderVisible;
+                pWin->valdata->before.resized = TRUE;
+                if (IN_UNDERLAY(pWin)) {
+                    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+                    RegionPtr borderVisible2;
+
+                    borderVisible2 = RegionCreate(NULL, 1);
+                    RegionSubtract(borderVisible2,
+                                   &pTree->borderClip, &pWin->winSize);
+                    pTree->valdata->borderVisible = borderVisible2;
+                }
+            }
+        }
+
+        SetWinSize(pWin);
+        SetBorderSize(pWin);
+
+        ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+        if (WasViewable) {
+            (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
+            (*pScreen->ValidateTree) (pWin->parent, NullWindow, VTOther);
+            (*pScreen->HandleExposures) (pWin->parent);
+            if (pScreen->PostValidateTree)
+                (*pScreen->PostValidateTree) (pWin->parent, NullWindow,
+                                              VTOther);
+        }
+    }
+    if (pWin->realized)
+        WindowsRestructured();
+    CheckCursorConfinement(pWin);
+}
+
+static void
+miOverlayChangeBorderWidth(WindowPtr pWin, unsigned int width)
+{
+    int oldwidth;
+    ScreenPtr pScreen;
+    Bool WasViewable = (Bool) (pWin->viewable);
+    Bool HadBorder;
+
+    oldwidth = wBorderWidth(pWin);
+    if (oldwidth == width)
+        return;
+    HadBorder = HasBorder(pWin);
+    pScreen = pWin->drawable.pScreen;
+    if (WasViewable && (width < oldwidth))
+        (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
+
+    pWin->borderWidth = width;
+    SetBorderSize(pWin);
+
+    if (WasViewable) {
+        if (width > oldwidth) {
+            (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);
+
+            if (HadBorder) {
+                RegionPtr borderVisible;
+
+                borderVisible = RegionCreate(NULL, 1);
+                RegionSubtract(borderVisible,
+                               &pWin->borderClip, &pWin->winSize);
+                pWin->valdata->before.borderVisible = borderVisible;
+                if (IN_UNDERLAY(pWin)) {
+                    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+                    RegionPtr borderVisible2;
+
+                    borderVisible2 = RegionCreate(NULL, 1);
+                    RegionSubtract(borderVisible2,
+                                   &pTree->borderClip, &pWin->winSize);
+                    pTree->valdata->borderVisible = borderVisible2;
+                }
+            }
+        }
+        (*pScreen->ValidateTree) (pWin->parent, pWin, VTOther);
+        (*pScreen->HandleExposures) (pWin->parent);
+
+        if (pScreen->PostValidateTree)
+            (*pScreen->PostValidateTree) (pWin->parent, pWin, VTOther);
+    }
+    if (pWin->realized)
+        WindowsRestructured();
+}
+
 /*  We need this as an addition since the xf86 common code doesn't
     know about the second tree which is static to this file.  */
 
@@ -101,6 +1556,62 @@ miOverlaySetRootClip(ScreenPtr pScreen, Bool enable)
     RegionBreak(&pTree->clipList);
 }
 
+static void
+miOverlayClearToBackground(WindowPtr pWin,
+                           int x, int y, int w, int h, Bool generateExposures)
+{
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    BoxRec box;
+    RegionRec reg;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+    RegionPtr clipList;
+    BoxPtr extents;
+    int x1, y1, x2, y2;
+
+    x1 = pWin->drawable.x + x;
+    y1 = pWin->drawable.y + y;
+    if (w)
+        x2 = x1 + (int) w;
+    else
+        x2 = x1 + (int) pWin->drawable.width - (int) x;
+    if (h)
+        y2 = y1 + h;
+    else
+        y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+    clipList = ((*pScreenPriv->InOverlay) (pWin)) ? &pWin->clipList :
+        &pTree->clipList;
+
+    extents = RegionExtents(clipList);
+
+    if (x1 < extents->x1)
+        x1 = extents->x1;
+    if (x2 > extents->x2)
+        x2 = extents->x2;
+    if (y1 < extents->y1)
+        y1 = extents->y1;
+    if (y2 > extents->y2)
+        y2 = extents->y2;
+
+    if (x2 <= x1 || y2 <= y1)
+        x2 = x1 = y2 = y1 = 0;
+
+    box.x1 = x1;
+    box.x2 = x2;
+    box.y1 = y1;
+    box.y2 = y2;
+
+    RegionInit(&reg, &box, 1);
+
+    RegionIntersect(&reg, &reg, clipList);
+    if (generateExposures)
+        (*pScreen->WindowExposures) (pWin, &reg);
+    else if (pWin->backgroundState != None)
+        pScreen->PaintWindow(pWin, &reg, PW_BACKGROUND);
+    RegionUninit(&reg);
+}
+
 /****************************************************************/
 
 /* not used */
@@ -200,6 +1711,102 @@ miOverlayCollectUnderlayRegions(WindowPtr pWin, RegionPtr *region)
     return TRUE;
 }
 
+static miOverlayTreePtr
+DoLeaf(WindowPtr pWin, miOverlayTreePtr parent, miOverlayTreePtr prevSib)
+{
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+    pTree->parent = parent;
+    pTree->firstChild = NULL;
+    pTree->lastChild = NULL;
+    pTree->prevSib = prevSib;
+    pTree->nextSib = NULL;
+
+    if (prevSib)
+        prevSib->nextSib = pTree;
+
+    if (!parent->firstChild)
+        parent->firstChild = parent->lastChild = pTree;
+    else if (parent->lastChild == prevSib)
+        parent->lastChild = pTree;
+
+    return pTree;
+}
+
+static void
+RebuildTree(WindowPtr pWin)
+{
+    miOverlayTreePtr parent, prevSib, tChild;
+    WindowPtr pChild;
+
+    prevSib = tChild = NULL;
+
+    pWin = pWin->parent;
+
+    while (IN_OVERLAY(pWin))
+        pWin = pWin->parent;
+
+    parent = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+    pChild = pWin->firstChild;
+    parent->firstChild = parent->lastChild = NULL;
+
+    while (1) {
+        if (IN_UNDERLAY(pChild))
+            prevSib = tChild = DoLeaf(pChild, parent, prevSib);
+
+        if (pChild->firstChild) {
+            if (IN_UNDERLAY(pChild)) {
+                parent = tChild;
+                prevSib = NULL;
+            }
+            pChild = pChild->firstChild;
+            continue;
+        }
+
+        while (!pChild->nextSib) {
+            pChild = pChild->parent;
+            if (pChild == pWin)
+                return;
+            if (IN_UNDERLAY(pChild)) {
+                prevSib = tChild = MIOVERLAY_GET_WINDOW_TREE(pChild);
+                parent = tChild->parent;
+            }
+        }
+
+        pChild = pChild->nextSib;
+    }
+}
+
+static Bool
+HasUnderlayChildren(WindowPtr pWin)
+{
+    WindowPtr pChild;
+
+    if (!(pChild = pWin->firstChild))
+        return FALSE;
+
+    while (1) {
+        if (IN_UNDERLAY(pChild))
+            return TRUE;
+
+        if (pChild->firstChild) {
+            pChild = pChild->firstChild;
+            continue;
+        }
+
+        while (!pChild->nextSib && (pWin != pChild))
+            pChild = pChild->parent;
+
+        if (pChild == pWin)
+            break;
+
+        pChild = pChild->nextSib;
+    }
+
+    return FALSE;
+}
+
 static Bool
 CollectUnderlayChildrenRegions(WindowPtr pWin, RegionPtr pReg)
 {
diff --git a/mi/mioverlay.h b/mi/mioverlay.h
index f99888300..420a846c2 100644
--- a/mi/mioverlay.h
+++ b/mi/mioverlay.h
@@ -11,6 +11,11 @@ typedef Bool (*miOverlayInOverlayFunc) (WindowPtr);
 
 extern _X_EXPORT Bool
 
+miInitOverlay(ScreenPtr pScreen,
+              miOverlayInOverlayFunc inOverlay, miOverlayTransFunc trans);
+
+extern _X_EXPORT Bool
+
 miOverlayGetPrivateClips(WindowPtr pWin,
                          RegionPtr *borderClip, RegionPtr *clipList);
 
commit 41a75f01cc5b02c015d10699f3666c06fab3accd
Author: Enrico Weigelt, metux IT consult <info at metux.net>
Date:   Wed Feb 26 17:57:26 2025 +0100

    Revert "mi: drop obsolete miOverlayGetPrivateClips()"
    
    This reverts commit 2c21824ee96daf3db8025c8bbe1210050dd67a13.
    
    Requested by Nvidia - their proprietary driver still needs it.
    
    Signed-off-by: Enrico Weigelt, metux IT consult <info at metux.net>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1843>

diff --git a/mi/mioverlay.c b/mi/mioverlay.c
index 38c57ecaf..33ed8ed19 100644
--- a/mi/mioverlay.c
+++ b/mi/mioverlay.c
@@ -103,6 +103,24 @@ miOverlaySetRootClip(ScreenPtr pScreen, Bool enable)
 
 /****************************************************************/
 
+/* not used */
+Bool
+miOverlayGetPrivateClips(WindowPtr pWin,
+                         RegionPtr *borderClip, RegionPtr *clipList)
+{
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+    if (pTree) {
+        *borderClip = &(pTree->borderClip);
+        *clipList = &(pTree->clipList);
+        return TRUE;
+    }
+
+    *borderClip = *clipList = NULL;
+
+    return FALSE;
+}
+
 Bool
 miOverlayCopyUnderlay(ScreenPtr pScreen)
 {
diff --git a/mi/mioverlay.h b/mi/mioverlay.h
index 2bd9d90cb..f99888300 100644
--- a/mi/mioverlay.h
+++ b/mi/mioverlay.h
@@ -9,6 +9,11 @@
 typedef void (*miOverlayTransFunc) (ScreenPtr, int, BoxPtr);
 typedef Bool (*miOverlayInOverlayFunc) (WindowPtr);
 
+extern _X_EXPORT Bool
+
+miOverlayGetPrivateClips(WindowPtr pWin,
+                         RegionPtr *borderClip, RegionPtr *clipList);
+
 extern _X_EXPORT Bool miOverlayCollectUnderlayRegions(WindowPtr, RegionPtr *);
 extern _X_EXPORT void miOverlayComputeCompositeClip(GCPtr, WindowPtr);
 extern _X_EXPORT Bool miOverlayCopyUnderlay(ScreenPtr);
commit ab95b569e1a390ea57fe8d2acd058b00767b8053
Author: Enrico Weigelt, metux IT consult <info at metux.net>
Date:   Wed Feb 26 17:56:57 2025 +0100

    Revert "mi: drop obsolete miOverlayCollectUnderlayRegions()"
    
    This reverts commit a860ce2c9f032a3ec54bde014d183db76715d23d.
    
    Requested by Nvidia - their proprietary driver still needs it.
    
    Signed-off-by: Enrico Weigelt, metux IT consult <info at metux.net>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1843>

diff --git a/mi/mioverlay.c b/mi/mioverlay.c
index 83a4949a3..38c57ecaf 100644
--- a/mi/mioverlay.c
+++ b/mi/mioverlay.c
@@ -63,6 +63,7 @@ static DevPrivateKeyRec miOverlayScreenKeyRec;
 #define miOverlayScreenKey (&miOverlayScreenKeyRec)
 
 static void MarkUnderlayWindow(WindowPtr);
+static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr);
 
 #define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen) ((miOverlayScreenPtr) \
 	dixLookupPrivate(&(pScreen)->devPrivates, miOverlayScreenKey))
@@ -164,6 +165,63 @@ miOverlayComputeCompositeClip(GCPtr pGC, WindowPtr pWin)
     }
 }
 
+Bool
+miOverlayCollectUnderlayRegions(WindowPtr pWin, RegionPtr *region)
+{
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+    if (pTree) {
+        *region = &pTree->borderClip;
+        return FALSE;
+    }
+
+    *region = RegionCreate(NullBox, 0);
+
+    CollectUnderlayChildrenRegions(pWin, *region);
+
+    return TRUE;
+}
+
+static Bool
+CollectUnderlayChildrenRegions(WindowPtr pWin, RegionPtr pReg)
+{
+    WindowPtr pChild;
+    miOverlayTreePtr pTree;
+    Bool hasUnderlay;
+
+    if (!(pChild = pWin->firstChild))
+        return FALSE;
+
+    hasUnderlay = FALSE;
+
+    while (1) {
+        if ((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
+            RegionAppend(pReg, &pTree->borderClip);
+            hasUnderlay = TRUE;
+        }
+        else if (pChild->firstChild) {
+            pChild = pChild->firstChild;
+            continue;
+        }
+
+        while (!pChild->nextSib && (pWin != pChild))
+            pChild = pChild->parent;
+
+        if (pChild == pWin)
+            break;
+
+        pChild = pChild->nextSib;
+    }
+
+    if (hasUnderlay) {
+        Bool overlap;
+
+        RegionValidate(pReg, &overlap);
+    }
+
+    return hasUnderlay;
+}
+
 static void
 MarkUnderlayWindow(WindowPtr pWin)
 {
diff --git a/mi/mioverlay.h b/mi/mioverlay.h
index 5463a293c..2bd9d90cb 100644
--- a/mi/mioverlay.h
+++ b/mi/mioverlay.h
@@ -9,6 +9,7 @@
 typedef void (*miOverlayTransFunc) (ScreenPtr, int, BoxPtr);
 typedef Bool (*miOverlayInOverlayFunc) (WindowPtr);
 
+extern _X_EXPORT Bool miOverlayCollectUnderlayRegions(WindowPtr, RegionPtr *);
 extern _X_EXPORT void miOverlayComputeCompositeClip(GCPtr, WindowPtr);
 extern _X_EXPORT Bool miOverlayCopyUnderlay(ScreenPtr);
 extern _X_EXPORT void miOverlaySetRootClip(ScreenPtr, Bool);
commit 4cdc184c13ed43cc30ff5b76389e56ea8425ee7a
Author: Enrico Weigelt, metux IT consult <info at metux.net>
Date:   Wed Feb 26 17:56:41 2025 +0100

    Revert "mi: drop obsolete miOverlayComputeCompositeClip()"
    
    This reverts commit bfb69b7316c4d4dabc5fc1744cc8d8e5ecd83347.
    
    Requested by Nvidia - their proprietary driver still needs it.
    
    Signed-off-by: Enrico Weigelt, metux IT consult <info at metux.net>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1843>

diff --git a/mi/mioverlay.c b/mi/mioverlay.c
index 6dd99d89a..83a4949a3 100644
--- a/mi/mioverlay.c
+++ b/mi/mioverlay.c
@@ -108,6 +108,62 @@ miOverlayCopyUnderlay(ScreenPtr pScreen)
     return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->copyUnderlay;
 }
 
+void
+miOverlayComputeCompositeClip(GCPtr pGC, WindowPtr pWin)
+{
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+    RegionPtr pregWin;
+    Bool freeTmpClip, freeCompClip;
+
+    if (!pTree) {
+        miComputeCompositeClip(pGC, &pWin->drawable);
+        return;
+    }
+
+    if (pGC->subWindowMode == IncludeInferiors) {
+        pregWin = RegionCreate(NullBox, 1);
+        freeTmpClip = TRUE;
+        if (pWin->parent || (screenIsSaved != SCREEN_SAVER_ON) ||
+            !HasSaverWindow(pGC->pScreen)) {
+            RegionIntersect(pregWin, &pTree->borderClip, &pWin->winSize);
+        }
+    }
+    else {
+        pregWin = &pTree->clipList;
+        freeTmpClip = FALSE;
+    }
+    freeCompClip = pGC->freeCompClip;
+    if (!pGC->clientClip) {
+        if (freeCompClip)
+            RegionDestroy(pGC->pCompositeClip);
+        pGC->pCompositeClip = pregWin;
+        pGC->freeCompClip = freeTmpClip;
+    }
+    else {
+        RegionTranslate(pGC->clientClip,
+                        pWin->drawable.x + pGC->clipOrg.x,
+                        pWin->drawable.y + pGC->clipOrg.y);
+
+        if (freeCompClip) {
+            RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip);
+            if (freeTmpClip)
+                RegionDestroy(pregWin);
+        }
+        else if (freeTmpClip) {
+            RegionIntersect(pregWin, pregWin, pGC->clientClip);
+            pGC->pCompositeClip = pregWin;
+        }
+        else {
+            pGC->pCompositeClip = RegionCreate(NullBox, 0);
+            RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip);
+        }
+        pGC->freeCompClip = TRUE;
+        RegionTranslate(pGC->clientClip,
+                        -(pWin->drawable.x + pGC->clipOrg.x),
+                        -(pWin->drawable.y + pGC->clipOrg.y));
+    }
+}
+
 static void
 MarkUnderlayWindow(WindowPtr pWin)
 {
diff --git a/mi/mioverlay.h b/mi/mioverlay.h
index ca4c06db5..5463a293c 100644
--- a/mi/mioverlay.h
+++ b/mi/mioverlay.h
@@ -9,6 +9,7 @@
 typedef void (*miOverlayTransFunc) (ScreenPtr, int, BoxPtr);
 typedef Bool (*miOverlayInOverlayFunc) (WindowPtr);
 
+extern _X_EXPORT void miOverlayComputeCompositeClip(GCPtr, WindowPtr);
 extern _X_EXPORT Bool miOverlayCopyUnderlay(ScreenPtr);
 extern _X_EXPORT void miOverlaySetRootClip(ScreenPtr, Bool);
 
commit 9d88cc5f119ea69a9a9e5a8544c5fd8e966e4a7e
Author: Enrico Weigelt, metux IT consult <info at metux.net>
Date:   Wed Feb 26 17:56:15 2025 +0100

    Revert "mi: drop obsolete miOverlayCopyUnderlay()"
    
    This reverts commit be6985948d6d79c60a08a11f578346f62ab7a448.
    
    Requested by Nvidia - their proprietary driver still needs it.
    
    Signed-off-by: Enrico Weigelt, metux IT consult <info at metux.net>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1843>

diff --git a/mi/mioverlay.c b/mi/mioverlay.c
index 0c1d79d70..6dd99d89a 100644
--- a/mi/mioverlay.c
+++ b/mi/mioverlay.c
@@ -58,9 +58,14 @@ typedef struct {
 static DevPrivateKeyRec miOverlayWindowKeyRec;
 
 #define miOverlayWindowKey (&miOverlayWindowKeyRec)
+static DevPrivateKeyRec miOverlayScreenKeyRec;
+
+#define miOverlayScreenKey (&miOverlayScreenKeyRec)
 
 static void MarkUnderlayWindow(WindowPtr);
 
+#define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen) ((miOverlayScreenPtr) \
+	dixLookupPrivate(&(pScreen)->devPrivates, miOverlayScreenKey))
 #define MIOVERLAY_GET_WINDOW_PRIVATE(pWin) ((miOverlayWindowPtr) \
 	dixLookupPrivate(&(pWin)->devPrivates, miOverlayWindowKey))
 #define MIOVERLAY_GET_WINDOW_TREE(pWin) \
@@ -97,6 +102,12 @@ miOverlaySetRootClip(ScreenPtr pScreen, Bool enable)
 
 /****************************************************************/
 
+Bool
+miOverlayCopyUnderlay(ScreenPtr pScreen)
+{
+    return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->copyUnderlay;
+}
+
 static void
 MarkUnderlayWindow(WindowPtr pWin)
 {
diff --git a/mi/mioverlay.h b/mi/mioverlay.h
index 68a88260a..ca4c06db5 100644
--- a/mi/mioverlay.h
+++ b/mi/mioverlay.h
@@ -9,6 +9,7 @@
 typedef void (*miOverlayTransFunc) (ScreenPtr, int, BoxPtr);
 typedef Bool (*miOverlayInOverlayFunc) (WindowPtr);
 
+extern _X_EXPORT Bool miOverlayCopyUnderlay(ScreenPtr);
 extern _X_EXPORT void miOverlaySetRootClip(ScreenPtr, Bool);
 
 #endif                          /* __MIOVERLAY_H */
commit d4f92a56883bf894636c3edd7a6b5379cc05efb6
Author: Enrico Weigelt, metux IT consult <info at metux.net>
Date:   Wed Feb 26 17:53:30 2025 +0100

    Revert "mi: drop obsolete miOverlaySetRootClip()"
    
    This reverts commit 00796cbf8cf8e2f613aaa8b2400b5c63cddd0e5e.
    
    Requested by Nvidia - their proprietary driver still needs it.
    
    Signed-off-by: Enrico Weigelt, metux IT consult <info at metux.net>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1843>

diff --git a/mi/mioverlay.c b/mi/mioverlay.c
index 23cc2b366..0c1d79d70 100644
--- a/mi/mioverlay.c
+++ b/mi/mioverlay.c
@@ -54,3 +54,59 @@ typedef struct {
     Bool underlayMarked;
     Bool copyUnderlay;
 } miOverlayScreenRec, *miOverlayScreenPtr;
+
+static DevPrivateKeyRec miOverlayWindowKeyRec;
+
+#define miOverlayWindowKey (&miOverlayWindowKeyRec)
+
+static void MarkUnderlayWindow(WindowPtr);
+
+#define MIOVERLAY_GET_WINDOW_PRIVATE(pWin) ((miOverlayWindowPtr) \
+	dixLookupPrivate(&(pWin)->devPrivates, miOverlayWindowKey))
+#define MIOVERLAY_GET_WINDOW_TREE(pWin) \
+	(MIOVERLAY_GET_WINDOW_PRIVATE(pWin)->tree)
+
+#define MARK_UNDERLAY(w) MarkUnderlayWindow(w)
+
+/*  We need this as an addition since the xf86 common code doesn't
+    know about the second tree which is static to this file.  */
+
+void
+miOverlaySetRootClip(ScreenPtr pScreen, Bool enable)
+{
+    WindowPtr pRoot = pScreen->root;
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pRoot);
+
+    MARK_UNDERLAY(pRoot);
+
+    if (enable) {
+        BoxRec box;
+
+        box.x1 = 0;
+        box.y1 = 0;
+        box.x2 = pScreen->width;
+        box.y2 = pScreen->height;
+
+        RegionReset(&pTree->borderClip, &box);
+    }
+    else
+        RegionEmpty(&pTree->borderClip);
+
+    RegionBreak(&pTree->clipList);
+}
+
+/****************************************************************/
+
+static void
+MarkUnderlayWindow(WindowPtr pWin)
+{
+    miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+    if (pTree->valdata)
+        return;
+    pTree->valdata =
+        (miOverlayValDataPtr) XNFalloc(sizeof(miOverlayValDataRec));
+    pTree->valdata->oldAbsCorner.x = pWin->drawable.x;
+    pTree->valdata->oldAbsCorner.y = pWin->drawable.y;
+    pTree->valdata->borderVisible = NullRegion;
+}
diff --git a/mi/mioverlay.h b/mi/mioverlay.h
index 857491dd3..68a88260a 100644
--- a/mi/mioverlay.h
+++ b/mi/mioverlay.h
@@ -9,4 +9,6 @@
 typedef void (*miOverlayTransFunc) (ScreenPtr, int, BoxPtr);
 typedef Bool (*miOverlayInOverlayFunc) (WindowPtr);
 
+extern _X_EXPORT void miOverlaySetRootClip(ScreenPtr, Bool);
+
 #endif                          /* __MIOVERLAY_H */
commit 0463d7aaaa8fcdff84c3e1ca1c8e5beb497c8220
Author: Enrico Weigelt, metux IT consult <info at metux.net>
Date:   Wed Feb 26 17:53:11 2025 +0100

    Revert "mi: drop now obsolete mioverlay.c"
    
    This reverts commit 65b738ed60689dbd0abe67879e3cfae462c4a3f0.
    
    Requested by Nvidia - their proprietary driver still needs it.
    
    Signed-off-by: Enrico Weigelt, metux IT consult <info at metux.net>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1843>

diff --git a/mi/meson.build b/mi/meson.build
index 74595494e..cccdb06eb 100644
--- a/mi/meson.build
+++ b/mi/meson.build
@@ -9,6 +9,7 @@ srcs_mi = [
     'mifillarc.c',
     'migc.c',
     'miglblt.c',
+    'mioverlay.c',
     'mipointer.c',
     'mipoly.c',
     'mipolypnt.c',
diff --git a/mi/mioverlay.c b/mi/mioverlay.c
new file mode 100644
index 000000000..23cc2b366
--- /dev/null
+++ b/mi/mioverlay.c
@@ -0,0 +1,56 @@
+
+#include <dix-config.h>
+
+#include <X11/X.h>
+
+#include "dix/cursor_priv.h"
+#include "mi/mi_priv.h"
+
+#include "scrnintstr.h"
+#include <X11/extensions/shapeproto.h>
+#include "validate.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "regionstr.h"
+#include "privates.h"
+#include "mivalidate.h"
+#include "mioverlay.h"
+#include "migc.h"
+
+#include "globals.h"
+
+typedef struct {
+    RegionRec exposed;
+    RegionRec borderExposed;
+    RegionPtr borderVisible;
+    DDXPointRec oldAbsCorner;
+} miOverlayValDataRec, *miOverlayValDataPtr;
+
+typedef struct _TreeRec {
+    WindowPtr pWin;
+    struct _TreeRec *parent;
+    struct _TreeRec *firstChild;
+    struct _TreeRec *lastChild;
+    struct _TreeRec *prevSib;
+    struct _TreeRec *nextSib;
+    RegionRec borderClip;
+    RegionRec clipList;
+    unsigned visibility;
+    miOverlayValDataPtr valdata;
+} miOverlayTreeRec, *miOverlayTreePtr;
+
+typedef struct {
+    miOverlayTreePtr tree;
+} miOverlayWindowRec, *miOverlayWindowPtr;
+
+typedef struct {
+    CloseScreenProcPtr CloseScreen;
+    CreateWindowProcPtr CreateWindow;
+    DestroyWindowProcPtr DestroyWindow;
+    UnrealizeWindowProcPtr UnrealizeWindow;
+    RealizeWindowProcPtr RealizeWindow;
+    miOverlayTransFunc MakeTransparent;
+    miOverlayInOverlayFunc InOverlay;
+    Bool underlayMarked;
+    Bool copyUnderlay;
+} miOverlayScreenRec, *miOverlayScreenPtr;
commit f1d87a38aee6e85ed2210ce4739ea16257e04342
Author: Enrico Weigelt, metux IT consult <info at metux.net>
Date:   Wed Feb 26 17:52:30 2025 +0100

    Revert "mi: drop now obsolete mioverlay.h"
    
    This reverts commit 6825f89cd23e1595ecb016834b38683d2a617d3d.
    
    Requested by Nvidia - their proprietary driver still needs it.
    
    Signed-off-by: Enrico Weigelt, metux IT consult <info at metux.net>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1843>

diff --git a/hw/xfree86/sdksyms.sh b/hw/xfree86/sdksyms.sh
index 74ffd8994..43c45698b 100755
--- a/hw/xfree86/sdksyms.sh
+++ b/hw/xfree86/sdksyms.sh
@@ -199,6 +199,7 @@ cat > sdksyms.c << EOF
 #include "mizerarc.h"
 #include "micoord.h"
 #include "mistruct.h"
+#include "mioverlay.h"
 
 
 /* randr/Makefile.am */
diff --git a/mi/meson.build b/mi/meson.build
index 47615b699..74595494e 100644
--- a/mi/meson.build
+++ b/mi/meson.build
@@ -32,6 +32,7 @@ hdrs_mi = [
   'migc.h',
   'mi.h',
   'miline.h',
+  'mioverlay.h',
   'mipointer.h',
   'mipointrst.h',
   'mistruct.h',
diff --git a/mi/mioverlay.h b/mi/mioverlay.h
new file mode 100644
index 000000000..857491dd3
--- /dev/null
+++ b/mi/mioverlay.h
@@ -0,0 +1,12 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef __MIOVERLAY_H
+#define __MIOVERLAY_H
+
+typedef void (*miOverlayTransFunc) (ScreenPtr, int, BoxPtr);
+typedef Bool (*miOverlayInOverlayFunc) (WindowPtr);
+
+#endif                          /* __MIOVERLAY_H */


More information about the xorg-commit mailing list