From 57a879849643e79d9674198a3a77c59532fb79b4 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Thu, 28 Apr 2011 07:58:00 +0000
Subject: xserver xkeyboard-config mesa git update 28 Apr 2011

---
 xorg-server/miext/rootless/rootlessScreen.c  | 1509 +++++++++++++-------------
 xorg-server/miext/rootless/rootlessValTree.c | 1244 +++++++++++----------
 2 files changed, 1375 insertions(+), 1378 deletions(-)

(limited to 'xorg-server/miext')

diff --git a/xorg-server/miext/rootless/rootlessScreen.c b/xorg-server/miext/rootless/rootlessScreen.c
index ca4f00c3e..0801e7206 100644
--- a/xorg-server/miext/rootless/rootlessScreen.c
+++ b/xorg-server/miext/rootless/rootlessScreen.c
@@ -1,755 +1,754 @@
-/*
- * Screen routines for generic rootless X server
- */
-/*
- * Copyright (c) 2001 Greg Parker. All Rights Reserved.
- * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "mi.h"
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "propertyst.h"
-#include "mivalidate.h"
-#include "picturestr.h"
-#include "colormapst.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "rootlessCommon.h"
-#include "rootlessWindow.h"
-
-/* In milliseconds */
-#ifndef ROOTLESS_REDISPLAY_DELAY
-#define ROOTLESS_REDISPLAY_DELAY 10
-#endif
-
-extern int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild,
-                                  VTKind kind);
-extern Bool RootlessCreateGC(GCPtr pGC);
-
-// Initialize globals
-DevPrivateKeyRec rootlessGCPrivateKeyRec;
-DevPrivateKeyRec rootlessScreenPrivateKeyRec;
-DevPrivateKeyRec rootlessWindowPrivateKeyRec;
-DevPrivateKeyRec rootlessWindowOldPixmapPrivateKeyRec;
-
-/*
- * RootlessUpdateScreenPixmap
- *  miCreateScreenResources does not like a null framebuffer pointer,
- *  it leaves the screen pixmap with an uninitialized data pointer.
- *  Thus, rootless implementations typically set the framebuffer width
- *  to zero so that miCreateScreenResources does not allocate a screen
- *  pixmap for us. We allocate our own screen pixmap here since we need
- *  the screen pixmap to be valid (e.g. CopyArea from the root window).
- */
-void
-RootlessUpdateScreenPixmap(ScreenPtr pScreen)
-{
-    RootlessScreenRec *s = SCREENREC(pScreen);
-    PixmapPtr pPix;
-    unsigned int rowbytes;
-
-    pPix = (*pScreen->GetScreenPixmap)(pScreen);
-    if (pPix == NULL) {
-        pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
-        (*pScreen->SetScreenPixmap)(pPix);
-    }
-
-    rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth);
-
-    if (s->pixmap_data_size < rowbytes) {
-        free(s->pixmap_data);
-
-        s->pixmap_data_size = rowbytes;
-        s->pixmap_data = malloc(s->pixmap_data_size);
-        if (s->pixmap_data == NULL)
-            return;
-
-        memset(s->pixmap_data, 0xFF, s->pixmap_data_size);
-
-        pScreen->ModifyPixmapHeader(pPix, pScreen->width, pScreen->height,
-                                    pScreen->rootDepth,
-                                    BitsPerPixel(pScreen->rootDepth),
-                                    0, s->pixmap_data);
-        /* ModifyPixmapHeader ignores zero arguments, so install rowbytes
-           by hand. */
-        pPix->devKind = 0;
-    }
-}
-
-
-/*
- * RootlessCreateScreenResources
- *  Rootless implementations typically set a null framebuffer pointer, which
- *  causes problems with miCreateScreenResources. We fix things up here.
- */
-static Bool
-RootlessCreateScreenResources(ScreenPtr pScreen)
-{
-    Bool ret = TRUE;
-
-    SCREEN_UNWRAP(pScreen, CreateScreenResources);
-
-    if (pScreen->CreateScreenResources != NULL)
-        ret = (*pScreen->CreateScreenResources)(pScreen);
-
-    SCREEN_WRAP(pScreen, CreateScreenResources);
-
-    if (!ret)
-        return ret;
-
-    /* Make sure we have a valid screen pixmap. */
-
-    RootlessUpdateScreenPixmap(pScreen);
-
-    return ret;
-}
-
-
-static Bool
-RootlessCloseScreen(int i, ScreenPtr pScreen)
-{
-    RootlessScreenRec *s;
-
-    s = SCREENREC(pScreen);
-
-    // fixme unwrap everything that was wrapped?
-    pScreen->CloseScreen = s->CloseScreen;
-
-    if (s->pixmap_data != NULL) {
-        free(s->pixmap_data);
-        s->pixmap_data = NULL;
-        s->pixmap_data_size = 0;
-    }
-
-    free(s);
-    return pScreen->CloseScreen(i, pScreen);
-}
-
-
-static void
-RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
-                 unsigned int format, unsigned long planeMask, char *pdstLine)
-{
-    ScreenPtr pScreen = pDrawable->pScreen;
-    SCREEN_UNWRAP(pScreen, GetImage);
-
-    if (pDrawable->type == DRAWABLE_WINDOW) {
-        int x0, y0, x1, y1;
-        RootlessWindowRec *winRec;
-
-        // Many apps use GetImage to sync with the visible frame buffer
-        // FIXME: entire screen or just window or all screens?
-        RootlessRedisplayScreen(pScreen);
-
-        // RedisplayScreen stops drawing, so we need to start it again
-        RootlessStartDrawing((WindowPtr)pDrawable);
-
-        /* Check that we have some place to read from. */
-        winRec = WINREC(TopLevelParent((WindowPtr) pDrawable));
-        if (winRec == NULL)
-            goto out;
-
-        /* Clip to top-level window bounds. */
-        /* FIXME: fbGetImage uses the width parameter to calculate the
-           stride of the destination pixmap. If w is clipped, the data
-           returned will be garbage, although we will not crash. */
-
-        x0 = pDrawable->x + sx;
-        y0 = pDrawable->y + sy;
-        x1 = x0 + w;
-        y1 = y0 + h;
-
-        x0 = max (x0, winRec->x);
-        y0 = max (y0, winRec->y);
-        x1 = min (x1, winRec->x + winRec->width);
-        y1 = min (y1, winRec->y + winRec->height);
-
-        sx = x0 - pDrawable->x;
-        sy = y0 - pDrawable->y;
-        w = x1 - x0;
-        h = y1 - y0;
-
-        if (w <= 0 || h <= 0)
-            goto out;
-    }
-
-    pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
-
-out:
-    SCREEN_WRAP(pScreen, GetImage);
-}
-
-
-/*
- * RootlessSourceValidate
- *  CopyArea and CopyPlane use a GC tied to the destination drawable.
- *  StartDrawing/StopDrawing wrappers won't be called if source is
- *  a visible window but the destination isn't. So, we call StartDrawing
- *  here and leave StopDrawing for the block handler.
- */
-static void
-RootlessSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h,
-                       unsigned int subWindowMode)
-{
-    SCREEN_UNWRAP(pDrawable->pScreen, SourceValidate);
-    if (pDrawable->type == DRAWABLE_WINDOW) {
-        WindowPtr pWin = (WindowPtr)pDrawable;
-        RootlessStartDrawing(pWin);
-    }
-    if (pDrawable->pScreen->SourceValidate) {
-        pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h, subWindowMode);
-    }
-    SCREEN_WRAP(pDrawable->pScreen, SourceValidate);
-}
-
-static void
-RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
-                  INT16 xSrc, INT16 ySrc, INT16  xMask, INT16  yMask,
-                  INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
-{
-    ScreenPtr pScreen = pDst->pDrawable->pScreen;
-    PictureScreenPtr ps = GetPictureScreen(pScreen);
-    WindowPtr srcWin, dstWin, maskWin = NULL;
-
-    if (pMask) {                        // pMask can be NULL
-        maskWin = (pMask->pDrawable->type == DRAWABLE_WINDOW) ?
-                  (WindowPtr)pMask->pDrawable :  NULL;
-    }
-    srcWin  = (pSrc->pDrawable && pSrc->pDrawable->type  == DRAWABLE_WINDOW) ?
-              (WindowPtr)pSrc->pDrawable  :  NULL;
-    dstWin  = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
-              (WindowPtr)pDst->pDrawable  :  NULL;
-
-    // SCREEN_UNWRAP(ps, Composite);
-    ps->Composite = SCREENREC(pScreen)->Composite;
-
-    if (srcWin  && IsFramedWindow(srcWin))
-        RootlessStartDrawing(srcWin);
-    if (maskWin && IsFramedWindow(maskWin))
-        RootlessStartDrawing(maskWin);
-    if (dstWin  && IsFramedWindow(dstWin))
-        RootlessStartDrawing(dstWin);
-
-    ps->Composite(op, pSrc, pMask, pDst,
-                  xSrc, ySrc, xMask, yMask,
-                  xDst, yDst, width, height);
-
-    if (dstWin  && IsFramedWindow(dstWin)) {
-        RootlessDamageRect(dstWin, xDst, yDst, width, height);
-    }
-
-    ps->Composite = RootlessComposite;
-    // SCREEN_WRAP(ps, Composite);
-}
-
-
-static void
-RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
-               PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
-               int nlist, GlyphListPtr list, GlyphPtr *glyphs)
-{
-    ScreenPtr pScreen = pDst->pDrawable->pScreen;
-    PictureScreenPtr ps = GetPictureScreen(pScreen);
-    int x, y;
-    int n;
-    GlyphPtr glyph;
-    WindowPtr srcWin, dstWin;
-
-    srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
-             (WindowPtr)pSrc->pDrawable  :  NULL;
-    dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
-             (WindowPtr)pDst->pDrawable  :  NULL;
-
-    if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin);
-    if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin);
-
-    //SCREEN_UNWRAP(ps, Glyphs);
-    ps->Glyphs = SCREENREC(pScreen)->Glyphs;
-    ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
-    ps->Glyphs = RootlessGlyphs;
-    //SCREEN_WRAP(ps, Glyphs);
-
-    if (dstWin && IsFramedWindow(dstWin)) {
-        x = xSrc;
-        y = ySrc;
-
-        while (nlist--) {
-            x += list->xOff;
-            y += list->yOff;
-            n = list->len;
-
-            /* Calling DamageRect for the bounding box of each glyph is
-               inefficient. So compute the union of all glyphs in a list
-               and damage that. */
-
-            if (n > 0) {
-                BoxRec box;
-
-                glyph = *glyphs++;
-
-                box.x1 = x - glyph->info.x;
-                box.y1 = y - glyph->info.y;
-                box.x2 = box.x1 + glyph->info.width;
-                box.y2 = box.y2 + glyph->info.height;
-
-                x += glyph->info.xOff;
-                y += glyph->info.yOff;
-
-                while (--n > 0) {
-                    short x1, y1, x2, y2;
-
-                    glyph = *glyphs++;
-
-                    x1 = x - glyph->info.x;
-                    y1 = y - glyph->info.y;
-                    x2 = x1 + glyph->info.width;
-                    y2 = y1 + glyph->info.height;
-
-                    box.x1 = max (box.x1, x1);
-                    box.y1 = max (box.y1, y1);
-                    box.x2 = max (box.x2, x2);
-                    box.y2 = max (box.y2, y2);
-
-                    x += glyph->info.xOff;
-                    y += glyph->info.yOff;
-                }
-
-                RootlessDamageBox(dstWin, &box);
-            }
-            list++;
-        }
-    }
-}
-
-
-/*
- * RootlessValidateTree
- *  ValidateTree is modified in two ways:
- *   - top-level windows don't clip each other
- *   - windows aren't clipped against root.
- *  These only matter when validating from the root.
- */
-static int
-RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
-{
-    int result;
-    RegionRec saveRoot;
-    ScreenPtr pScreen = pParent->drawable.pScreen;
-
-    SCREEN_UNWRAP(pScreen, ValidateTree);
-    RL_DEBUG_MSG("VALIDATETREE start ");
-
-    // Use our custom version to validate from root
-    if (IsRoot(pParent)) {
-        RL_DEBUG_MSG("custom ");
-        result = RootlessMiValidateTree(pParent, pChild, kind);
-    } else {
-        HUGE_ROOT(pParent);
-        result = pScreen->ValidateTree(pParent, pChild, kind);
-        NORMAL_ROOT(pParent);
-    }
-
-    SCREEN_WRAP(pScreen, ValidateTree);
-    RL_DEBUG_MSG("VALIDATETREE end\n");
-
-    return result;
-}
-
-
-/*
- * RootlessMarkOverlappedWindows
- *  MarkOverlappedWindows is modified to ignore overlapping
- *  top-level windows.
- */
-static Bool
-RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
-                              WindowPtr *ppLayerWin)
-{
-    RegionRec saveRoot;
-    Bool result;
-    ScreenPtr pScreen = pWin->drawable.pScreen;
-    SCREEN_UNWRAP(pScreen, MarkOverlappedWindows);
-    RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start ");
-
-    HUGE_ROOT(pWin);
-    if (IsRoot(pWin)) {
-        // root - mark nothing
-        RL_DEBUG_MSG("is root not marking ");
-        result = FALSE;
-    }
-    else if (! IsTopLevel(pWin)) {
-        // not top-level window - mark normally
-        result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin);
-    }
-    else {
-        //top-level window - mark children ONLY - NO overlaps with sibs (?)
-        // This code copied from miMarkOverlappedWindows()
-
-        register WindowPtr pChild;
-        Bool anyMarked = FALSE;
-        MarkWindowProcPtr MarkWindow = pScreen->MarkWindow;
-
-        RL_DEBUG_MSG("is top level! ");
-        /* single layered systems are easy */
-        if (ppLayerWin) *ppLayerWin = pWin;
-
-        if (pWin == pFirst) {
-            /* Blindly mark pWin and all of its inferiors.   This is a slight
-             * overkill if there are mapped windows that outside pWin's border,
-             * but it's better than wasting time on RectIn checks.
-             */
-            pChild = pWin;
-            while (1) {
-                if (pChild->viewable) {
-                    if (RegionBroken(&pChild->winSize))
-                        SetWinSize (pChild);
-                    if (RegionBroken(&pChild->borderSize))
-                        SetBorderSize (pChild);
-                    (* MarkWindow)(pChild);
-                    if (pChild->firstChild) {
-                        pChild = pChild->firstChild;
-                        continue;
-                    }
-                }
-                while (!pChild->nextSib && (pChild != pWin))
-                    pChild = pChild->parent;
-                if (pChild == pWin)
-                    break;
-                pChild = pChild->nextSib;
-            }
-            anyMarked = TRUE;
-            pFirst = pFirst->nextSib;
-        }
-        if (anyMarked)
-            (* MarkWindow)(pWin->parent);
-        result = anyMarked;
-    }
-    NORMAL_ROOT(pWin);
-    SCREEN_WRAP(pScreen, MarkOverlappedWindows);
-    RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n");
-
-    return result;
-}
-
-static void expose_1 (WindowPtr pWin) {
-    WindowPtr pChild;
-    
-    if (!pWin->realized)
-        return;
-    
-    miPaintWindow(pWin, &pWin->borderClip, PW_BACKGROUND);
-    
-    /* FIXME: comments in windowstr.h indicate that borderClip doesn't
-     include subwindow visibility. But I'm not so sure.. so we may
-     be exposing too much.. */
-    
-    miSendExposures (pWin, &pWin->borderClip,
-                     pWin->drawable.x, pWin->drawable.y);
-    
-    for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib)
-        expose_1 (pChild);
-}
-
-void
-RootlessScreenExpose (ScreenPtr pScreen)
-{
-    expose_1 (pScreen->root);
-}
-
-
-ColormapPtr
-RootlessGetColormap (ScreenPtr pScreen)
-{
-  RootlessScreenRec *s = SCREENREC (pScreen);
-
-  return s->colormap;
-}
-
-static void
-RootlessInstallColormap (ColormapPtr pMap)
-{
-  ScreenPtr pScreen = pMap->pScreen;
-  RootlessScreenRec *s = SCREENREC (pScreen);
-
-  SCREEN_UNWRAP(pScreen, InstallColormap);
-
-  if (s->colormap != pMap) {
-    s->colormap = pMap;
-    s->colormap_changed = TRUE;
-    RootlessQueueRedisplay (pScreen);
-  }
-
-  pScreen->InstallColormap (pMap);
-
-  SCREEN_WRAP (pScreen, InstallColormap);
-}
-
-static void
-RootlessUninstallColormap (ColormapPtr pMap)
-{
-  ScreenPtr pScreen = pMap->pScreen;
-  RootlessScreenRec *s = SCREENREC (pScreen);
-
-  SCREEN_UNWRAP(pScreen, UninstallColormap);
-
-  if (s->colormap == pMap)
-    s->colormap = NULL;
-
-  pScreen->UninstallColormap (pMap);
-
-  SCREEN_WRAP(pScreen, UninstallColormap);
-}
-
-static void
-RootlessStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef)
-{
-  ScreenPtr pScreen = pMap->pScreen;
-  RootlessScreenRec *s = SCREENREC (pScreen);
-
-  SCREEN_UNWRAP(pScreen, StoreColors);
-
-  if (s->colormap == pMap && ndef > 0) {
-    s->colormap_changed = TRUE;
-    RootlessQueueRedisplay (pScreen);
-  }
-
-  pScreen->StoreColors (pMap, ndef, pdef);
-
-  SCREEN_WRAP(pScreen, StoreColors);
-}
-
-
-static CARD32
-RootlessRedisplayCallback(OsTimerPtr timer, CARD32 time, void *arg)
-{
-    RootlessScreenRec *screenRec = arg;
-
-    if (!screenRec->redisplay_queued) {
-        /* No update needed. Stop the timer. */
-
-        screenRec->redisplay_timer_set = FALSE;
-        return 0;
-    }
-
-    screenRec->redisplay_queued = FALSE;
-
-    /* Mark that we should redisplay before waiting for I/O next time */
-    screenRec->redisplay_expired = TRUE;
-
-    /* Reinstall the timer immediately, so we get as close to our
-       redisplay interval as possible. */
-
-    return ROOTLESS_REDISPLAY_DELAY;
-}
-
-
-/*
- * RootlessQueueRedisplay
- *  Queue a redisplay after a timer delay to ensure we do not redisplay
- *  too frequently.
- */
-void
-RootlessQueueRedisplay(ScreenPtr pScreen)
-{
-    RootlessScreenRec *screenRec = SCREENREC(pScreen);
-
-    screenRec->redisplay_queued = TRUE;
-
-    if (screenRec->redisplay_timer_set)
-        return;
-
-    screenRec->redisplay_timer = TimerSet(screenRec->redisplay_timer,
-                                          0, ROOTLESS_REDISPLAY_DELAY,
-                                          RootlessRedisplayCallback,
-                                          screenRec);
-    screenRec->redisplay_timer_set = TRUE;
-}
-
-
-/*
- * RootlessBlockHandler
- *  If the redisplay timer has expired, flush drawing before blocking
- *  on select().
- */
-static void
-RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask)
-{
-    ScreenPtr pScreen = pbdata;
-    RootlessScreenRec *screenRec = SCREENREC(pScreen);
-
-    if (screenRec->redisplay_expired) {
-        screenRec->redisplay_expired = FALSE;
-
-        RootlessRedisplayScreen(pScreen);
-    }
-}
-
-
-static void
-RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask)
-{
-    // nothing here
-}
-
-
-static Bool
-RootlessAllocatePrivates(ScreenPtr pScreen)
-{
-    RootlessScreenRec *s;
-
-    if (!dixRegisterPrivateKey(&rootlessGCPrivateKeyRec, PRIVATE_GC, sizeof(RootlessGCRec)))
-        return FALSE;
-    if (!dixRegisterPrivateKey(&rootlessScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
-        return FALSE;
-    if (!dixRegisterPrivateKey(&rootlessWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
-        return FALSE;
-    if (!dixRegisterPrivateKey(&rootlessWindowOldPixmapPrivateKeyRec, PRIVATE_WINDOW, 0))
-        return FALSE;
-
-    s = malloc(sizeof(RootlessScreenRec));
-    if (! s) return FALSE;
-    SETSCREENREC(pScreen, s);
-
-    s->pixmap_data = NULL;
-    s->pixmap_data_size = 0;
-
-    s->redisplay_timer = NULL;
-    s->redisplay_timer_set = FALSE;
-
-    return TRUE;
-}
-
-
-static void
-RootlessWrap(ScreenPtr pScreen)
-{
-    RootlessScreenRec *s = SCREENREC(pScreen);
-
-#define WRAP(a) \
-    if (pScreen->a) { \
-        s->a = pScreen->a; \
-    } else { \
-        RL_DEBUG_MSG("null screen fn " #a "\n"); \
-        s->a = NULL; \
-    } \
-    pScreen->a = Rootless##a
-
-    WRAP(CreateScreenResources);
-    WRAP(CloseScreen);
-    WRAP(CreateGC);
-    WRAP(CopyWindow);
-    WRAP(GetImage);
-    WRAP(SourceValidate);
-    WRAP(CreateWindow);
-    WRAP(DestroyWindow);
-    WRAP(RealizeWindow);
-    WRAP(UnrealizeWindow);
-    WRAP(MoveWindow);
-    WRAP(PositionWindow);
-    WRAP(ResizeWindow);
-    WRAP(RestackWindow);
-    WRAP(ReparentWindow);
-    WRAP(ChangeBorderWidth);
-    WRAP(MarkOverlappedWindows);
-    WRAP(ValidateTree);
-    WRAP(ChangeWindowAttributes);
-    WRAP(InstallColormap);
-    WRAP(UninstallColormap);
-    WRAP(StoreColors);
-
-    WRAP(SetShape);
-
-    {
-        // Composite and Glyphs don't use normal screen wrapping
-        PictureScreenPtr ps = GetPictureScreen(pScreen);
-        s->Composite = ps->Composite;
-        ps->Composite = RootlessComposite;
-        s->Glyphs = ps->Glyphs;
-        ps->Glyphs = RootlessGlyphs;
-    }
-
-    // WRAP(ClearToBackground); fixme put this back? useful for shaped wins?
-
-#undef WRAP
-}
-
-
-/*
- * RootlessInit
- *  Called by the rootless implementation to initialize the rootless layer.
- *  Rootless wraps lots of stuff and needs a bunch of devPrivates.
- */
-Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs)
-{
-    RootlessScreenRec *s;
-
-    if (!RootlessAllocatePrivates(pScreen))
-        return FALSE;
-
-    s = SCREENREC(pScreen);
-
-    s->imp = procs;
-    s->colormap = NULL;
-    s->redisplay_expired = FALSE;
-
-    RootlessWrap(pScreen);
-
-    if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler,
-                                        RootlessWakeupHandler,
-                                        (pointer) pScreen))
-    {
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-void RootlessUpdateRooted (Bool state) {
-    int i;
-    
-    if (!state)
-    {
-        for (i = 0; i < screenInfo.numScreens; i++)
-            RootlessDisableRoot (screenInfo.screens[i]);
-    }
-    else
-    {
-        for (i = 0; i < screenInfo.numScreens; i++)
-            RootlessEnableRoot (screenInfo.screens[i]);
-    }
-}
+/*
+ * Screen routines for generic rootless X server
+ */
+/*
+ * Copyright (c) 2001 Greg Parker. All Rights Reserved.
+ * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "mi.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "mivalidate.h"
+#include "picturestr.h"
+#include "colormapst.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "rootlessCommon.h"
+#include "rootlessWindow.h"
+
+/* In milliseconds */
+#ifndef ROOTLESS_REDISPLAY_DELAY
+#define ROOTLESS_REDISPLAY_DELAY 10
+#endif
+
+extern int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild,
+                                  VTKind kind);
+extern Bool RootlessCreateGC(GCPtr pGC);
+
+// Initialize globals
+DevPrivateKeyRec rootlessGCPrivateKeyRec;
+DevPrivateKeyRec rootlessScreenPrivateKeyRec;
+DevPrivateKeyRec rootlessWindowPrivateKeyRec;
+DevPrivateKeyRec rootlessWindowOldPixmapPrivateKeyRec;
+
+/*
+ * RootlessUpdateScreenPixmap
+ *  miCreateScreenResources does not like a null framebuffer pointer,
+ *  it leaves the screen pixmap with an uninitialized data pointer.
+ *  Thus, rootless implementations typically set the framebuffer width
+ *  to zero so that miCreateScreenResources does not allocate a screen
+ *  pixmap for us. We allocate our own screen pixmap here since we need
+ *  the screen pixmap to be valid (e.g. CopyArea from the root window).
+ */
+void
+RootlessUpdateScreenPixmap(ScreenPtr pScreen)
+{
+    RootlessScreenRec *s = SCREENREC(pScreen);
+    PixmapPtr pPix;
+    unsigned int rowbytes;
+
+    pPix = (*pScreen->GetScreenPixmap)(pScreen);
+    if (pPix == NULL) {
+        pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
+        (*pScreen->SetScreenPixmap)(pPix);
+    }
+
+    rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth);
+
+    if (s->pixmap_data_size < rowbytes) {
+        free(s->pixmap_data);
+
+        s->pixmap_data_size = rowbytes;
+        s->pixmap_data = malloc(s->pixmap_data_size);
+        if (s->pixmap_data == NULL)
+            return;
+
+        memset(s->pixmap_data, 0xFF, s->pixmap_data_size);
+
+        pScreen->ModifyPixmapHeader(pPix, pScreen->width, pScreen->height,
+                                    pScreen->rootDepth,
+                                    BitsPerPixel(pScreen->rootDepth),
+                                    0, s->pixmap_data);
+        /* ModifyPixmapHeader ignores zero arguments, so install rowbytes
+           by hand. */
+        pPix->devKind = 0;
+    }
+}
+
+
+/*
+ * RootlessCreateScreenResources
+ *  Rootless implementations typically set a null framebuffer pointer, which
+ *  causes problems with miCreateScreenResources. We fix things up here.
+ */
+static Bool
+RootlessCreateScreenResources(ScreenPtr pScreen)
+{
+    Bool ret = TRUE;
+
+    SCREEN_UNWRAP(pScreen, CreateScreenResources);
+
+    if (pScreen->CreateScreenResources != NULL)
+        ret = (*pScreen->CreateScreenResources)(pScreen);
+
+    SCREEN_WRAP(pScreen, CreateScreenResources);
+
+    if (!ret)
+        return ret;
+
+    /* Make sure we have a valid screen pixmap. */
+
+    RootlessUpdateScreenPixmap(pScreen);
+
+    return ret;
+}
+
+
+static Bool
+RootlessCloseScreen(int i, ScreenPtr pScreen)
+{
+    RootlessScreenRec *s;
+
+    s = SCREENREC(pScreen);
+
+    // fixme unwrap everything that was wrapped?
+    pScreen->CloseScreen = s->CloseScreen;
+
+    if (s->pixmap_data != NULL) {
+        free(s->pixmap_data);
+        s->pixmap_data = NULL;
+        s->pixmap_data_size = 0;
+    }
+
+    free(s);
+    return pScreen->CloseScreen(i, pScreen);
+}
+
+
+static void
+RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
+                 unsigned int format, unsigned long planeMask, char *pdstLine)
+{
+    ScreenPtr pScreen = pDrawable->pScreen;
+    SCREEN_UNWRAP(pScreen, GetImage);
+
+    if (pDrawable->type == DRAWABLE_WINDOW) {
+        int x0, y0, x1, y1;
+        RootlessWindowRec *winRec;
+
+        // Many apps use GetImage to sync with the visible frame buffer
+        // FIXME: entire screen or just window or all screens?
+        RootlessRedisplayScreen(pScreen);
+
+        // RedisplayScreen stops drawing, so we need to start it again
+        RootlessStartDrawing((WindowPtr)pDrawable);
+
+        /* Check that we have some place to read from. */
+        winRec = WINREC(TopLevelParent((WindowPtr) pDrawable));
+        if (winRec == NULL)
+            goto out;
+
+        /* Clip to top-level window bounds. */
+        /* FIXME: fbGetImage uses the width parameter to calculate the
+           stride of the destination pixmap. If w is clipped, the data
+           returned will be garbage, although we will not crash. */
+
+        x0 = pDrawable->x + sx;
+        y0 = pDrawable->y + sy;
+        x1 = x0 + w;
+        y1 = y0 + h;
+
+        x0 = max (x0, winRec->x);
+        y0 = max (y0, winRec->y);
+        x1 = min (x1, winRec->x + winRec->width);
+        y1 = min (y1, winRec->y + winRec->height);
+
+        sx = x0 - pDrawable->x;
+        sy = y0 - pDrawable->y;
+        w = x1 - x0;
+        h = y1 - y0;
+
+        if (w <= 0 || h <= 0)
+            goto out;
+    }
+
+    pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
+
+out:
+    SCREEN_WRAP(pScreen, GetImage);
+}
+
+
+/*
+ * RootlessSourceValidate
+ *  CopyArea and CopyPlane use a GC tied to the destination drawable.
+ *  StartDrawing/StopDrawing wrappers won't be called if source is
+ *  a visible window but the destination isn't. So, we call StartDrawing
+ *  here and leave StopDrawing for the block handler.
+ */
+static void
+RootlessSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h,
+                       unsigned int subWindowMode)
+{
+    SCREEN_UNWRAP(pDrawable->pScreen, SourceValidate);
+    if (pDrawable->type == DRAWABLE_WINDOW) {
+        WindowPtr pWin = (WindowPtr)pDrawable;
+        RootlessStartDrawing(pWin);
+    }
+    if (pDrawable->pScreen->SourceValidate) {
+        pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h, subWindowMode);
+    }
+    SCREEN_WRAP(pDrawable->pScreen, SourceValidate);
+}
+
+static void
+RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+                  INT16 xSrc, INT16 ySrc, INT16  xMask, INT16  yMask,
+                  INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
+{
+    ScreenPtr pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr ps = GetPictureScreen(pScreen);
+    WindowPtr srcWin, dstWin, maskWin = NULL;
+
+    if (pMask) {                        // pMask can be NULL
+        maskWin = (pMask->pDrawable->type == DRAWABLE_WINDOW) ?
+                  (WindowPtr)pMask->pDrawable :  NULL;
+    }
+    srcWin  = (pSrc->pDrawable && pSrc->pDrawable->type  == DRAWABLE_WINDOW) ?
+              (WindowPtr)pSrc->pDrawable  :  NULL;
+    dstWin  = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
+              (WindowPtr)pDst->pDrawable  :  NULL;
+
+    // SCREEN_UNWRAP(ps, Composite);
+    ps->Composite = SCREENREC(pScreen)->Composite;
+
+    if (srcWin  && IsFramedWindow(srcWin))
+        RootlessStartDrawing(srcWin);
+    if (maskWin && IsFramedWindow(maskWin))
+        RootlessStartDrawing(maskWin);
+    if (dstWin  && IsFramedWindow(dstWin))
+        RootlessStartDrawing(dstWin);
+
+    ps->Composite(op, pSrc, pMask, pDst,
+                  xSrc, ySrc, xMask, yMask,
+                  xDst, yDst, width, height);
+
+    if (dstWin  && IsFramedWindow(dstWin)) {
+        RootlessDamageRect(dstWin, xDst, yDst, width, height);
+    }
+
+    ps->Composite = RootlessComposite;
+    // SCREEN_WRAP(ps, Composite);
+}
+
+
+static void
+RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+               PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+               int nlist, GlyphListPtr list, GlyphPtr *glyphs)
+{
+    ScreenPtr pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr ps = GetPictureScreen(pScreen);
+    int x, y;
+    int n;
+    GlyphPtr glyph;
+    WindowPtr srcWin, dstWin;
+
+    srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
+             (WindowPtr)pSrc->pDrawable  :  NULL;
+    dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
+             (WindowPtr)pDst->pDrawable  :  NULL;
+
+    if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin);
+    if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin);
+
+    //SCREEN_UNWRAP(ps, Glyphs);
+    ps->Glyphs = SCREENREC(pScreen)->Glyphs;
+    ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+    ps->Glyphs = RootlessGlyphs;
+    //SCREEN_WRAP(ps, Glyphs);
+
+    if (dstWin && IsFramedWindow(dstWin)) {
+        x = xSrc;
+        y = ySrc;
+
+        while (nlist--) {
+            x += list->xOff;
+            y += list->yOff;
+            n = list->len;
+
+            /* Calling DamageRect for the bounding box of each glyph is
+               inefficient. So compute the union of all glyphs in a list
+               and damage that. */
+
+            if (n > 0) {
+                BoxRec box;
+
+                glyph = *glyphs++;
+
+                box.x1 = x - glyph->info.x;
+                box.y1 = y - glyph->info.y;
+                box.x2 = box.x1 + glyph->info.width;
+                box.y2 = box.y1 + glyph->info.height;
+
+                x += glyph->info.xOff;
+                y += glyph->info.yOff;
+
+                while (--n > 0) {
+                    short x1, y1, x2, y2;
+
+                    glyph = *glyphs++;
+
+                    x1 = x - glyph->info.x;
+                    y1 = y - glyph->info.y;
+                    x2 = x1 + glyph->info.width;
+                    y2 = y1 + glyph->info.height;
+
+                    box.x1 = max (box.x1, x1);
+                    box.y1 = max (box.y1, y1);
+                    box.x2 = max (box.x2, x2);
+                    box.y2 = max (box.y2, y2);
+
+                    x += glyph->info.xOff;
+                    y += glyph->info.yOff;
+                }
+
+                RootlessDamageBox(dstWin, &box);
+            }
+            list++;
+        }
+    }
+}
+
+
+/*
+ * RootlessValidateTree
+ *  ValidateTree is modified in two ways:
+ *   - top-level windows don't clip each other
+ *   - windows aren't clipped against root.
+ *  These only matter when validating from the root.
+ */
+static int
+RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
+{
+    int result;
+    RegionRec saveRoot;
+    ScreenPtr pScreen = pParent->drawable.pScreen;
+
+    SCREEN_UNWRAP(pScreen, ValidateTree);
+    RL_DEBUG_MSG("VALIDATETREE start ");
+
+    // Use our custom version to validate from root
+    if (IsRoot(pParent)) {
+        RL_DEBUG_MSG("custom ");
+        result = RootlessMiValidateTree(pParent, pChild, kind);
+    } else {
+        HUGE_ROOT(pParent);
+        result = pScreen->ValidateTree(pParent, pChild, kind);
+        NORMAL_ROOT(pParent);
+    }
+
+    SCREEN_WRAP(pScreen, ValidateTree);
+    RL_DEBUG_MSG("VALIDATETREE end\n");
+
+    return result;
+}
+
+
+/*
+ * RootlessMarkOverlappedWindows
+ *  MarkOverlappedWindows is modified to ignore overlapping
+ *  top-level windows.
+ */
+static Bool
+RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
+                              WindowPtr *ppLayerWin)
+{
+    RegionRec saveRoot;
+    Bool result;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    SCREEN_UNWRAP(pScreen, MarkOverlappedWindows);
+    RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start ");
+
+    HUGE_ROOT(pWin);
+    if (IsRoot(pWin)) {
+        // root - mark nothing
+        RL_DEBUG_MSG("is root not marking ");
+        result = FALSE;
+    }
+    else if (! IsTopLevel(pWin)) {
+        // not top-level window - mark normally
+        result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin);
+    }
+    else {
+        //top-level window - mark children ONLY - NO overlaps with sibs (?)
+        // This code copied from miMarkOverlappedWindows()
+
+        register WindowPtr pChild;
+        Bool anyMarked = FALSE;
+        MarkWindowProcPtr MarkWindow = pScreen->MarkWindow;
+
+        RL_DEBUG_MSG("is top level! ");
+        /* single layered systems are easy */
+        if (ppLayerWin) *ppLayerWin = pWin;
+
+        if (pWin == pFirst) {
+            /* Blindly mark pWin and all of its inferiors.   This is a slight
+             * overkill if there are mapped windows that outside pWin's border,
+             * but it's better than wasting time on RectIn checks.
+             */
+            pChild = pWin;
+            while (1) {
+                if (pChild->viewable) {
+                    if (RegionBroken(&pChild->winSize))
+                        SetWinSize (pChild);
+                    if (RegionBroken(&pChild->borderSize))
+                        SetBorderSize (pChild);
+                    (* MarkWindow)(pChild);
+                    if (pChild->firstChild) {
+                        pChild = pChild->firstChild;
+                        continue;
+                    }
+                }
+                while (!pChild->nextSib && (pChild != pWin))
+                    pChild = pChild->parent;
+                if (pChild == pWin)
+                    break;
+                pChild = pChild->nextSib;
+            }
+            anyMarked = TRUE;
+        }
+        if (anyMarked)
+            (* MarkWindow)(pWin->parent);
+        result = anyMarked;
+    }
+    NORMAL_ROOT(pWin);
+    SCREEN_WRAP(pScreen, MarkOverlappedWindows);
+    RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n");
+
+    return result;
+}
+
+static void expose_1 (WindowPtr pWin) {
+    WindowPtr pChild;
+    
+    if (!pWin->realized)
+        return;
+    
+    miPaintWindow(pWin, &pWin->borderClip, PW_BACKGROUND);
+    
+    /* FIXME: comments in windowstr.h indicate that borderClip doesn't
+     include subwindow visibility. But I'm not so sure.. so we may
+     be exposing too much.. */
+    
+    miSendExposures (pWin, &pWin->borderClip,
+                     pWin->drawable.x, pWin->drawable.y);
+    
+    for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib)
+        expose_1 (pChild);
+}
+
+void
+RootlessScreenExpose (ScreenPtr pScreen)
+{
+    expose_1 (pScreen->root);
+}
+
+
+ColormapPtr
+RootlessGetColormap (ScreenPtr pScreen)
+{
+  RootlessScreenRec *s = SCREENREC (pScreen);
+
+  return s->colormap;
+}
+
+static void
+RootlessInstallColormap (ColormapPtr pMap)
+{
+  ScreenPtr pScreen = pMap->pScreen;
+  RootlessScreenRec *s = SCREENREC (pScreen);
+
+  SCREEN_UNWRAP(pScreen, InstallColormap);
+
+  if (s->colormap != pMap) {
+    s->colormap = pMap;
+    s->colormap_changed = TRUE;
+    RootlessQueueRedisplay (pScreen);
+  }
+
+  pScreen->InstallColormap (pMap);
+
+  SCREEN_WRAP (pScreen, InstallColormap);
+}
+
+static void
+RootlessUninstallColormap (ColormapPtr pMap)
+{
+  ScreenPtr pScreen = pMap->pScreen;
+  RootlessScreenRec *s = SCREENREC (pScreen);
+
+  SCREEN_UNWRAP(pScreen, UninstallColormap);
+
+  if (s->colormap == pMap)
+    s->colormap = NULL;
+
+  pScreen->UninstallColormap (pMap);
+
+  SCREEN_WRAP(pScreen, UninstallColormap);
+}
+
+static void
+RootlessStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef)
+{
+  ScreenPtr pScreen = pMap->pScreen;
+  RootlessScreenRec *s = SCREENREC (pScreen);
+
+  SCREEN_UNWRAP(pScreen, StoreColors);
+
+  if (s->colormap == pMap && ndef > 0) {
+    s->colormap_changed = TRUE;
+    RootlessQueueRedisplay (pScreen);
+  }
+
+  pScreen->StoreColors (pMap, ndef, pdef);
+
+  SCREEN_WRAP(pScreen, StoreColors);
+}
+
+
+static CARD32
+RootlessRedisplayCallback(OsTimerPtr timer, CARD32 time, void *arg)
+{
+    RootlessScreenRec *screenRec = arg;
+
+    if (!screenRec->redisplay_queued) {
+        /* No update needed. Stop the timer. */
+
+        screenRec->redisplay_timer_set = FALSE;
+        return 0;
+    }
+
+    screenRec->redisplay_queued = FALSE;
+
+    /* Mark that we should redisplay before waiting for I/O next time */
+    screenRec->redisplay_expired = TRUE;
+
+    /* Reinstall the timer immediately, so we get as close to our
+       redisplay interval as possible. */
+
+    return ROOTLESS_REDISPLAY_DELAY;
+}
+
+
+/*
+ * RootlessQueueRedisplay
+ *  Queue a redisplay after a timer delay to ensure we do not redisplay
+ *  too frequently.
+ */
+void
+RootlessQueueRedisplay(ScreenPtr pScreen)
+{
+    RootlessScreenRec *screenRec = SCREENREC(pScreen);
+
+    screenRec->redisplay_queued = TRUE;
+
+    if (screenRec->redisplay_timer_set)
+        return;
+
+    screenRec->redisplay_timer = TimerSet(screenRec->redisplay_timer,
+                                          0, ROOTLESS_REDISPLAY_DELAY,
+                                          RootlessRedisplayCallback,
+                                          screenRec);
+    screenRec->redisplay_timer_set = TRUE;
+}
+
+
+/*
+ * RootlessBlockHandler
+ *  If the redisplay timer has expired, flush drawing before blocking
+ *  on select().
+ */
+static void
+RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask)
+{
+    ScreenPtr pScreen = pbdata;
+    RootlessScreenRec *screenRec = SCREENREC(pScreen);
+
+    if (screenRec->redisplay_expired) {
+        screenRec->redisplay_expired = FALSE;
+
+        RootlessRedisplayScreen(pScreen);
+    }
+}
+
+
+static void
+RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask)
+{
+    // nothing here
+}
+
+
+static Bool
+RootlessAllocatePrivates(ScreenPtr pScreen)
+{
+    RootlessScreenRec *s;
+
+    if (!dixRegisterPrivateKey(&rootlessGCPrivateKeyRec, PRIVATE_GC, sizeof(RootlessGCRec)))
+        return FALSE;
+    if (!dixRegisterPrivateKey(&rootlessScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
+        return FALSE;
+    if (!dixRegisterPrivateKey(&rootlessWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
+        return FALSE;
+    if (!dixRegisterPrivateKey(&rootlessWindowOldPixmapPrivateKeyRec, PRIVATE_WINDOW, 0))
+        return FALSE;
+
+    s = malloc(sizeof(RootlessScreenRec));
+    if (! s) return FALSE;
+    SETSCREENREC(pScreen, s);
+
+    s->pixmap_data = NULL;
+    s->pixmap_data_size = 0;
+
+    s->redisplay_timer = NULL;
+    s->redisplay_timer_set = FALSE;
+
+    return TRUE;
+}
+
+
+static void
+RootlessWrap(ScreenPtr pScreen)
+{
+    RootlessScreenRec *s = SCREENREC(pScreen);
+
+#define WRAP(a) \
+    if (pScreen->a) { \
+        s->a = pScreen->a; \
+    } else { \
+        RL_DEBUG_MSG("null screen fn " #a "\n"); \
+        s->a = NULL; \
+    } \
+    pScreen->a = Rootless##a
+
+    WRAP(CreateScreenResources);
+    WRAP(CloseScreen);
+    WRAP(CreateGC);
+    WRAP(CopyWindow);
+    WRAP(GetImage);
+    WRAP(SourceValidate);
+    WRAP(CreateWindow);
+    WRAP(DestroyWindow);
+    WRAP(RealizeWindow);
+    WRAP(UnrealizeWindow);
+    WRAP(MoveWindow);
+    WRAP(PositionWindow);
+    WRAP(ResizeWindow);
+    WRAP(RestackWindow);
+    WRAP(ReparentWindow);
+    WRAP(ChangeBorderWidth);
+    WRAP(MarkOverlappedWindows);
+    WRAP(ValidateTree);
+    WRAP(ChangeWindowAttributes);
+    WRAP(InstallColormap);
+    WRAP(UninstallColormap);
+    WRAP(StoreColors);
+
+    WRAP(SetShape);
+
+    {
+        // Composite and Glyphs don't use normal screen wrapping
+        PictureScreenPtr ps = GetPictureScreen(pScreen);
+        s->Composite = ps->Composite;
+        ps->Composite = RootlessComposite;
+        s->Glyphs = ps->Glyphs;
+        ps->Glyphs = RootlessGlyphs;
+    }
+
+    // WRAP(ClearToBackground); fixme put this back? useful for shaped wins?
+
+#undef WRAP
+}
+
+
+/*
+ * RootlessInit
+ *  Called by the rootless implementation to initialize the rootless layer.
+ *  Rootless wraps lots of stuff and needs a bunch of devPrivates.
+ */
+Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs)
+{
+    RootlessScreenRec *s;
+
+    if (!RootlessAllocatePrivates(pScreen))
+        return FALSE;
+
+    s = SCREENREC(pScreen);
+
+    s->imp = procs;
+    s->colormap = NULL;
+    s->redisplay_expired = FALSE;
+
+    RootlessWrap(pScreen);
+
+    if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler,
+                                        RootlessWakeupHandler,
+                                        (pointer) pScreen))
+    {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+void RootlessUpdateRooted (Bool state) {
+    int i;
+    
+    if (!state)
+    {
+        for (i = 0; i < screenInfo.numScreens; i++)
+            RootlessDisableRoot (screenInfo.screens[i]);
+    }
+    else
+    {
+        for (i = 0; i < screenInfo.numScreens; i++)
+            RootlessEnableRoot (screenInfo.screens[i]);
+    }
+}
diff --git a/xorg-server/miext/rootless/rootlessValTree.c b/xorg-server/miext/rootless/rootlessValTree.c
index 23527ff2e..9aa881423 100644
--- a/xorg-server/miext/rootless/rootlessValTree.c
+++ b/xorg-server/miext/rootless/rootlessValTree.c
@@ -1,623 +1,621 @@
-/*
- * Calculate window clip lists for rootless mode
- *
- * This file is very closely based on mivaltree.c.
- */
-
-/*
- * mivaltree.c --
- *	Functions for recalculating window clip lists. Main function
- *	is miValidateTree.
- *
-
-Copyright 1987, 1988, 1989, 1998  The Open Group
-
-All Rights Reserved.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
- *
- * Copyright 1987, 1988, 1989 by 
- * Digital Equipment Corporation, Maynard, Massachusetts,
- * 
- *                         All Rights Reserved
- * 
- * Permission to use, copy, modify, and distribute this software and its 
- * documentation for any purpose and without fee is hereby granted, 
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in 
- * supporting documentation, and that the name of Digital not be
- * used in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.  
- * 
- * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * 
- ******************************************************************/
-
-/* The panoramix components contained the following notice */
-/*****************************************************************
-
-Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
-BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of Digital Equipment Corporation
-shall not be used in advertising or otherwise to promote the sale, use or other
-dealings in this Software without prior written authorization from Digital
-Equipment Corporation.
-
-******************************************************************/
- /* 
-  * Aug '86: Susan Angebranndt -- original code
-  * July '87: Adam de Boor -- substantially modified and commented
-  * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
-  *             In particular, much improved code for window mapping and
-  *             circulating.
-  *		Bob Scheifler -- avoid miComputeClips for unmapped windows,
-  *				 valdata changes
-  */
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stddef.h> /* For NULL */
-#include    <X11/X.h>
-#include    "scrnintstr.h"
-#include    "validate.h"
-#include    "windowstr.h"
-#include    "mi.h"
-#include    "regionstr.h"
-#include    "mivalidate.h"
-
-#include    "globals.h"
-
-int RootlessMiValidateTree (WindowPtr pRoot, WindowPtr pChild, VTKind kind);
-
-/*
- * Compute the visibility of a shaped window
- */
-static int
-RootlessShapedWindowIn (RegionPtr universe,
-			RegionPtr bounding, BoxPtr rect, int x, int y)
-{
-    BoxRec  box;
-    register BoxPtr  boundBox;
-    int	    nbox;
-    Bool    someIn, someOut;
-    register int t, x1, y1, x2, y2;
-
-    nbox = RegionNumRects (bounding);
-    boundBox = RegionRects (bounding);
-    someIn = someOut = FALSE;
-    x1 = rect->x1;
-    y1 = rect->y1;
-    x2 = rect->x2;
-    y2 = rect->y2;
-    while (nbox--)
-    {
-	if ((t = boundBox->x1 + x) < x1)
-	    t = x1;
-	box.x1 = t;
-	if ((t = boundBox->y1 + y) < y1)
-	    t = y1;
-	box.y1 = t;
-	if ((t = boundBox->x2 + x) > x2)
-	    t = x2;
-	box.x2 = t;
-	if ((t = boundBox->y2 + y) > y2)
-	    t = y2;
-	box.y2 = t;
-	if (box.x1 > box.x2)
-	    box.x2 = box.x1;
-	if (box.y1 > box.y2)
-	    box.y2 = box.y1;
-	switch (RegionContainsRect(universe, &box))
-	{
-	case rgnIN:
-	    if (someOut)
-		return rgnPART;
-	    someIn = TRUE;
-	    break;
-	case rgnOUT:
-	    if (someIn)
-		return rgnPART;
-	    someOut = TRUE;
-	    break;
-	default:
-	    return rgnPART;
-	}
-	boundBox++;
-    }
-    if (someIn)
-	return rgnIN;
-    return rgnOUT;
-}
-
-#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
-				    HasBorder(w) && \
-				    (w)->backgroundState == ParentRelative)
-
-
-/*
- *-----------------------------------------------------------------------
- * RootlessComputeClips --
- *	Recompute the clipList, borderClip, exposed and borderExposed
- *	regions for pParent and its children. Only viewable windows are
- *	taken into account.
- *
- * Results:
- *	None.
- *
- * Side Effects:
- *	clipList, borderClip, exposed and borderExposed are altered.
- *	A VisibilityNotify event may be generated on the parent window.
- *
- *-----------------------------------------------------------------------
- */
-static void
-RootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen, 
-		      RegionPtr universe, VTKind kind, RegionPtr exposed)
-{
-    int			dx,
-			dy;
-    RegionRec		childUniverse;
-    register WindowPtr	pChild;
-    int     	  	oldVis, newVis;
-    BoxRec		borderSize;
-    RegionRec		childUnion;
-    Bool		overlap;
-    RegionPtr		borderVisible;
-    Bool		resized;
-    /*
-     * Figure out the new visibility of this window.
-     * The extent of the universe should be the same as the extent of
-     * the borderSize region. If the window is unobscured, this rectangle
-     * will be completely inside the universe (the universe will cover it
-     * completely). If the window is completely obscured, none of the
-     * universe will cover the rectangle.
-     */
-    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 = pParent->visibility;
-    switch (RegionContainsRect(universe, &borderSize))
-    {
-    case rgnIN:
-	    newVis = VisibilityUnobscured;
-	    break;
-	case rgnPART:
-	    newVis = VisibilityPartiallyObscured;
-	    {
-		RegionPtr   pBounding;
-
-		if ((pBounding = wBoundingShape (pParent)))
-		{
-		    switch (RootlessShapedWindowIn (universe,
-						    pBounding, &borderSize,
-						    pParent->drawable.x,
-						    pParent->drawable.y))
-		    {
-		    case rgnIN:
-			newVis = VisibilityUnobscured;
-			break;
-		    case rgnOUT:
-			newVis = VisibilityFullyObscured;
-			break;
-		    }
-		}
-	    }
-	    break;
-	default:
-	    newVis = VisibilityFullyObscured;
-	    break;
-    }
-
-    pParent->visibility = newVis;
-    if (oldVis != newVis &&
-	((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
-	SendVisibilityNotify(pParent);
-
-    dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
-    dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
-
-    /*
-     * avoid computations when dealing with simple operations
-     */
-
-    switch (kind) {
-    case VTMap:
-    case VTStack:
-    case VTUnmap:
-	break;
-    case VTMove:
-	if ((oldVis == newVis) &&
-	    ((oldVis == VisibilityFullyObscured) ||
-	     (oldVis == VisibilityUnobscured)))
-	{
-	    pChild = pParent;
-	    while (1)
-	    {
-		if (pChild->viewable)
-		{
-		    if (pChild->visibility != VisibilityFullyObscured)
-		    {
-			RegionTranslate(&pChild->borderClip,
-						      dx, dy);
-			RegionTranslate(&pChild->clipList,
-						      dx, dy);
-			pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
-			if (pScreen->ClipNotify)
-			    (* pScreen->ClipNotify) (pChild, dx, dy);
-
-		    }
-		    if (pChild->valdata)
-		    {
-			RegionNull(&pChild->valdata->after.borderExposed);
-			if (HasParentRelativeBorder(pChild))
-			  {
-			    RegionSubtract(&pChild->valdata->after.borderExposed,
-					   &pChild->borderClip,
-					   &pChild->winSize);
-			}
-			RegionNull(&pChild->valdata->after.exposed);
-		    }
-		    if (pChild->firstChild)
-		    {
-			pChild = pChild->firstChild;
-			continue;
-		    }
-		}
-		while (!pChild->nextSib && (pChild != pParent))
-		    pChild = pChild->parent;
-		if (pChild == pParent)
-		    break;
-		pChild = pChild->nextSib;
-	    }
-	    return;
-	}
-	/* fall through */
-    default:
-    	/*
-     	 * To calculate exposures correctly, we have to translate the old
-     	 * borderClip and clipList regions to the window's new location so there
-     	 * is a correspondence between pieces of the new and old clipping regions.
-     	 */
-    	if (dx || dy) 
-    	{
-	    /*
-	     * We translate the old clipList because that will be exposed or copied
-	     * if gravity is right.
-	     */
-	    RegionTranslate(&pParent->borderClip, dx, dy);
-	    RegionTranslate(&pParent->clipList, dx, dy);
-    	} 
-	break;
-    case VTBroken:
-	RegionEmpty(&pParent->borderClip);
-	RegionEmpty(&pParent->clipList);
-	break;
-    }
-
-    borderVisible = pParent->valdata->before.borderVisible;
-    resized = pParent->valdata->before.resized;
-    RegionNull(&pParent->valdata->after.borderExposed);
-    RegionNull(&pParent->valdata->after.exposed);
-
-    /*
-     * Since the borderClip must not be clipped by the children, we do
-     * the border exposure first...
-     *
-     * 'universe' is the window's borderClip. To figure the exposures, remove
-     * the area that used to be exposed from the new.
-     * This leaves a region of pieces that weren't exposed before.
-     */
-
-    if (HasBorder (pParent))
-    {
-    	if (borderVisible)
-    	{
-	    /*
-	     * when the border changes shape, the old visible portions
-	     * of the border will be saved by DIX in borderVisible --
-	     * use that region and destroy it
-	     */
-	    RegionSubtract(exposed, universe, borderVisible);
-	    RegionDestroy(borderVisible);
-    	}
-    	else
-    	{
-	    RegionSubtract(exposed, universe, &pParent->borderClip);
-    	}
-	if (HasParentRelativeBorder(pParent) && (dx || dy)) {
-	    RegionSubtract(&pParent->valdata->after.borderExposed,
-				  universe,
-				  &pParent->winSize);
-	} else {
-	    RegionSubtract(&pParent->valdata->after.borderExposed,
-			       exposed, &pParent->winSize);
-	}
-
-	RegionCopy(&pParent->borderClip, universe);
-    
-    	/*
-     	 * To get the right clipList for the parent, and to make doubly sure
-     	 * that no child overlaps the parent's border, we remove the parent's
-     	 * border from the universe before proceeding.
-     	 */
-    
-	RegionIntersect(universe, universe, &pParent->winSize);
-    }
-    else
-	RegionCopy(&pParent->borderClip, universe);
-    
-    if ((pChild = pParent->firstChild) && pParent->mapped)
-    {
-	RegionNull(&childUniverse);
-	RegionNull(&childUnion);
-	if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
-	    ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
-	     (pChild->drawable.x < pParent->lastChild->drawable.x)))
-	{
-	    for (; pChild; pChild = pChild->nextSib)
-	    {
-		if (pChild->viewable)
-		    RegionAppend(&childUnion, &pChild->borderSize);
-	    }
-	}
-	else
-	{
-	    for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
-	    {
-		if (pChild->viewable)
-		    RegionAppend(&childUnion, &pChild->borderSize);
-	    }
-	}
-	RegionValidate(&childUnion, &overlap);
-
-	for (pChild = pParent->firstChild;
-	     pChild;
-	     pChild = pChild->nextSib)
- 	{
-	    if (pChild->viewable) {
-		/*
-		 * If the child is viewable, we want to remove its extents
-		 * from the current universe, but we only re-clip it if
-		 * it's been marked.
-		 */
-		if (pChild->valdata) {
-		    /*
-		     * Figure out the new universe from the child's
-		     * perspective and recurse.
-		     */
-		    RegionIntersect(&childUniverse,
-					    universe,
-					    &pChild->borderSize);
-		    RootlessComputeClips (pChild, pScreen, &childUniverse, 
-					  kind, exposed);
-		}
-		/*
-		 * Once the child has been processed, we remove its extents
-		 * from the current universe, thus denying its space to any
-		 * other sibling.
-		 */
-		if (overlap)
-		    RegionSubtract(universe, universe,
-					  &pChild->borderSize);
-	    }
-	}
-	if (!overlap)
-	    RegionSubtract(universe, universe, &childUnion);
-	RegionUninit(&childUnion);
-	RegionUninit(&childUniverse);
-    } /* if any children */
-
-    /*
-     * 'universe' now contains the new clipList for the parent window.
-     *
-     * To figure the exposure of the window we subtract the old clip from the
-     * new, just as for the border.
-     */
-
-    if (oldVis == VisibilityFullyObscured ||
-	oldVis == VisibilityNotViewable)
-    {
-	RegionCopy(&pParent->valdata->after.exposed, universe);
-    }
-    else if (newVis != VisibilityFullyObscured &&
-	     newVis != VisibilityNotViewable)
-    {
-	RegionSubtract(&pParent->valdata->after.exposed,
-			       universe, &pParent->clipList);
-    }
-
-    /* HACK ALERT - copying contents of regions, instead of regions */
-    {
-	RegionRec   tmp;
-
-	tmp = pParent->clipList;
-	pParent->clipList = *universe;
-	*universe = tmp;
-    }
-
-#ifdef NOTDEF
-    RegionCopy(&pParent->clipList, universe);
-#endif
-
-    pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
-
-    if (pScreen->ClipNotify)
-	(* pScreen->ClipNotify) (pParent, dx, dy);
-}
-
-static void
-RootlessTreeObscured(WindowPtr pParent)
-{
-    register WindowPtr pChild;
-    register int    oldVis;
-
-    pChild = pParent;
-    while (1)
-    {
-	if (pChild->viewable)
-	{
-	    oldVis = pChild->visibility;
-	    if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
-		((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
-		SendVisibilityNotify(pChild);
-	    if (pChild->firstChild)
-	    {
-		pChild = pChild->firstChild;
-		continue;
-	    }
-	}
-	while (!pChild->nextSib && (pChild != pParent))
-	    pChild = pChild->parent;
-	if (pChild == pParent)
-	    break;
-	pChild = pChild->nextSib;
-    }
-}
-
-/*
- *-----------------------------------------------------------------------
- * RootlessMiValidateTree --
- *	Recomputes the clip list for pParent and all its inferiors.
- *
- * Results:
- *	Always returns 1.
- *
- * Side Effects:
- *	The clipList, borderClip, exposed, and borderExposed regions for
- *	each marked window are altered.
- *
- * Notes:
- *	This routine assumes that all affected windows have been marked
- *	(valdata created) and their winSize and borderSize regions
- *	adjusted to correspond to their new positions. The borderClip and
- *	clipList regions should not have been touched.
- *
- *	The top-most level is treated differently from all lower levels
- *	because pParent is unchanged. For the top level, we merge the
- *	regions taken up by the marked children back into the clipList
- *	for pParent, thus forming a region from which the marked children
- *	can claim their areas. For lower levels, where the old clipList
- *	and borderClip are invalid, we can't do this and have to do the
- *	extra operations done in miComputeClips, but this is much faster
- *	e.g. when only one child has moved...
- *
- *-----------------------------------------------------------------------
- */
-/* 
-   Quartz version: used for validate from root in rootless mode.
-   We need to make sure top-level windows don't clip each other, 
-   and that top-level windows aren't clipped to the root window.
-*/
-/*ARGSUSED*/
-// fixme this is ugly
-// Xprint/ValTree.c doesn't work, but maybe that method can?
-int
-RootlessMiValidateTree (WindowPtr pRoot, /* Parent to validate */
-			WindowPtr pChild, /* First child of pRoot that was
-					   * affected */
-			VTKind kind /* What kind of configuration caused call */)
-{
-    RegionRec	  	childClip;  /* The new borderClip for the current
-				     * child */
-    RegionRec		exposed;    /* For intermediate calculations */
-    register ScreenPtr	pScreen;
-    register WindowPtr	pWin;
-
-    pScreen = pRoot->drawable.pScreen;
-    if (pChild == NullWindow)
-	pChild = pRoot->firstChild;
-
-    RegionNull(&childClip);
-    RegionNull(&exposed);
-
-    if (RegionBroken(&pRoot->clipList) &&
-	!RegionBroken(&pRoot->borderClip))
-    {
-        // fixme this might not work, but hopefully doesn't happen anyway.
-        kind = VTBroken;
-        RegionEmpty(&pRoot->clipList);
-        ErrorF("ValidateTree: BUSTED!\n");
-    }
-
-    /* 
-     * Recursively compute the clips for all children of the root. 
-     * They don't clip against each other or the root itself, so 
-     * childClip is always reset to that child's size.
-     */
-
-    for (pWin = pChild;
-	 pWin != NullWindow;
-	 pWin = pWin->nextSib)
-    {
-        if (pWin->viewable) {
-            if (pWin->valdata) {
-                RegionCopy(&childClip, &pWin->borderSize);
-                RootlessComputeClips (pWin, pScreen, &childClip, kind, &exposed);
-            } else if (pWin->visibility == VisibilityNotViewable) {
-                RootlessTreeObscured(pWin);
-            }
-        } else {
-            if (pWin->valdata) {
-                RegionEmpty(&pWin->clipList);
-                if (pScreen->ClipNotify)
-                    (* pScreen->ClipNotify) (pWin, 0, 0);
-                RegionEmpty(&pWin->borderClip);
-                pWin->valdata = NULL;
-            }
-        }
-    }
-
-    RegionUninit(&childClip);
-
-    /* The root is never clipped by its children, so nothing on the root 
-       is ever exposed by moving or mapping its children. */
-    RegionNull(&pRoot->valdata->after.exposed);
-    RegionNull(&pRoot->valdata->after.borderExposed);
-
-    return 1;
-}
+/*
+ * Calculate window clip lists for rootless mode
+ *
+ * This file is very closely based on mivaltree.c.
+ */
+
+/*
+ * mivaltree.c --
+ *	Functions for recalculating window clip lists. Main function
+ *	is miValidateTree.
+ *
+
+Copyright 1987, 1988, 1989, 1998  The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ *
+ * Copyright 1987, 1988, 1989 by 
+ * Digital Equipment Corporation, Maynard, Massachusetts,
+ * 
+ *                         All Rights Reserved
+ * 
+ * Permission to use, copy, modify, and distribute this software and its 
+ * documentation for any purpose and without fee is hereby granted, 
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in 
+ * supporting documentation, and that the name of Digital not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.  
+ * 
+ * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * 
+ ******************************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+ /* 
+  * Aug '86: Susan Angebranndt -- original code
+  * July '87: Adam de Boor -- substantially modified and commented
+  * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
+  *             In particular, much improved code for window mapping and
+  *             circulating.
+  *		Bob Scheifler -- avoid miComputeClips for unmapped windows,
+  *				 valdata changes
+  */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stddef.h> /* For NULL */
+#include    <X11/X.h>
+#include    "scrnintstr.h"
+#include    "validate.h"
+#include    "windowstr.h"
+#include    "mi.h"
+#include    "regionstr.h"
+#include    "mivalidate.h"
+
+#include    "globals.h"
+
+int RootlessMiValidateTree (WindowPtr pRoot, WindowPtr pChild, VTKind kind);
+
+/*
+ * Compute the visibility of a shaped window
+ */
+static int
+RootlessShapedWindowIn (RegionPtr universe,
+			RegionPtr bounding, BoxPtr rect, int x, int y)
+{
+    BoxRec  box;
+    register BoxPtr  boundBox;
+    int	    nbox;
+    Bool    someIn, someOut;
+    register int t, x1, y1, x2, y2;
+
+    nbox = RegionNumRects (bounding);
+    boundBox = RegionRects (bounding);
+    someIn = someOut = FALSE;
+    x1 = rect->x1;
+    y1 = rect->y1;
+    x2 = rect->x2;
+    y2 = rect->y2;
+    while (nbox--)
+    {
+	if ((t = boundBox->x1 + x) < x1)
+	    t = x1;
+	box.x1 = t;
+	if ((t = boundBox->y1 + y) < y1)
+	    t = y1;
+	box.y1 = t;
+	if ((t = boundBox->x2 + x) > x2)
+	    t = x2;
+	box.x2 = t;
+	if ((t = boundBox->y2 + y) > y2)
+	    t = y2;
+	box.y2 = t;
+	if (box.x1 > box.x2)
+	    box.x2 = box.x1;
+	if (box.y1 > box.y2)
+	    box.y2 = box.y1;
+	switch (RegionContainsRect(universe, &box))
+	{
+	case rgnIN:
+	    if (someOut)
+		return rgnPART;
+	    someIn = TRUE;
+	    break;
+	case rgnOUT:
+	    if (someIn)
+		return rgnPART;
+	    someOut = TRUE;
+	    break;
+	default:
+	    return rgnPART;
+	}
+	boundBox++;
+    }
+    if (someIn)
+	return rgnIN;
+    return rgnOUT;
+}
+
+#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
+				    HasBorder(w) && \
+				    (w)->backgroundState == ParentRelative)
+
+
+/*
+ *-----------------------------------------------------------------------
+ * RootlessComputeClips --
+ *	Recompute the clipList, borderClip, exposed and borderExposed
+ *	regions for pParent and its children. Only viewable windows are
+ *	taken into account.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	clipList, borderClip, exposed and borderExposed are altered.
+ *	A VisibilityNotify event may be generated on the parent window.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+RootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen, 
+		      RegionPtr universe, VTKind kind, RegionPtr exposed)
+{
+    int			dx,
+			dy;
+    RegionRec		childUniverse;
+    register WindowPtr	pChild;
+    int     	  	oldVis, newVis;
+    BoxRec		borderSize;
+    RegionRec		childUnion;
+    Bool		overlap;
+    RegionPtr		borderVisible;
+    /*
+     * Figure out the new visibility of this window.
+     * The extent of the universe should be the same as the extent of
+     * the borderSize region. If the window is unobscured, this rectangle
+     * will be completely inside the universe (the universe will cover it
+     * completely). If the window is completely obscured, none of the
+     * universe will cover the rectangle.
+     */
+    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 = pParent->visibility;
+    switch (RegionContainsRect(universe, &borderSize))
+    {
+    case rgnIN:
+	    newVis = VisibilityUnobscured;
+	    break;
+	case rgnPART:
+	    newVis = VisibilityPartiallyObscured;
+	    {
+		RegionPtr   pBounding;
+
+		if ((pBounding = wBoundingShape (pParent)))
+		{
+		    switch (RootlessShapedWindowIn (universe,
+						    pBounding, &borderSize,
+						    pParent->drawable.x,
+						    pParent->drawable.y))
+		    {
+		    case rgnIN:
+			newVis = VisibilityUnobscured;
+			break;
+		    case rgnOUT:
+			newVis = VisibilityFullyObscured;
+			break;
+		    }
+		}
+	    }
+	    break;
+	default:
+	    newVis = VisibilityFullyObscured;
+	    break;
+    }
+
+    pParent->visibility = newVis;
+    if (oldVis != newVis &&
+	((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
+	SendVisibilityNotify(pParent);
+
+    dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
+    dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
+
+    /*
+     * avoid computations when dealing with simple operations
+     */
+
+    switch (kind) {
+    case VTMap:
+    case VTStack:
+    case VTUnmap:
+	break;
+    case VTMove:
+	if ((oldVis == newVis) &&
+	    ((oldVis == VisibilityFullyObscured) ||
+	     (oldVis == VisibilityUnobscured)))
+	{
+	    pChild = pParent;
+	    while (1)
+	    {
+		if (pChild->viewable)
+		{
+		    if (pChild->visibility != VisibilityFullyObscured)
+		    {
+			RegionTranslate(&pChild->borderClip,
+						      dx, dy);
+			RegionTranslate(&pChild->clipList,
+						      dx, dy);
+			pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+			if (pScreen->ClipNotify)
+			    (* pScreen->ClipNotify) (pChild, dx, dy);
+
+		    }
+		    if (pChild->valdata)
+		    {
+			RegionNull(&pChild->valdata->after.borderExposed);
+			if (HasParentRelativeBorder(pChild))
+			  {
+			    RegionSubtract(&pChild->valdata->after.borderExposed,
+					   &pChild->borderClip,
+					   &pChild->winSize);
+			}
+			RegionNull(&pChild->valdata->after.exposed);
+		    }
+		    if (pChild->firstChild)
+		    {
+			pChild = pChild->firstChild;
+			continue;
+		    }
+		}
+		while (!pChild->nextSib && (pChild != pParent))
+		    pChild = pChild->parent;
+		if (pChild == pParent)
+		    break;
+		pChild = pChild->nextSib;
+	    }
+	    return;
+	}
+	/* fall through */
+    default:
+    	/*
+     	 * To calculate exposures correctly, we have to translate the old
+     	 * borderClip and clipList regions to the window's new location so there
+     	 * is a correspondence between pieces of the new and old clipping regions.
+     	 */
+    	if (dx || dy) 
+    	{
+	    /*
+	     * We translate the old clipList because that will be exposed or copied
+	     * if gravity is right.
+	     */
+	    RegionTranslate(&pParent->borderClip, dx, dy);
+	    RegionTranslate(&pParent->clipList, dx, dy);
+    	} 
+	break;
+    case VTBroken:
+	RegionEmpty(&pParent->borderClip);
+	RegionEmpty(&pParent->clipList);
+	break;
+    }
+
+    borderVisible = pParent->valdata->before.borderVisible;
+    RegionNull(&pParent->valdata->after.borderExposed);
+    RegionNull(&pParent->valdata->after.exposed);
+
+    /*
+     * Since the borderClip must not be clipped by the children, we do
+     * the border exposure first...
+     *
+     * 'universe' is the window's borderClip. To figure the exposures, remove
+     * the area that used to be exposed from the new.
+     * This leaves a region of pieces that weren't exposed before.
+     */
+
+    if (HasBorder (pParent))
+    {
+    	if (borderVisible)
+    	{
+	    /*
+	     * when the border changes shape, the old visible portions
+	     * of the border will be saved by DIX in borderVisible --
+	     * use that region and destroy it
+	     */
+	    RegionSubtract(exposed, universe, borderVisible);
+	    RegionDestroy(borderVisible);
+    	}
+    	else
+    	{
+	    RegionSubtract(exposed, universe, &pParent->borderClip);
+    	}
+	if (HasParentRelativeBorder(pParent) && (dx || dy)) {
+	    RegionSubtract(&pParent->valdata->after.borderExposed,
+				  universe,
+				  &pParent->winSize);
+	} else {
+	    RegionSubtract(&pParent->valdata->after.borderExposed,
+			       exposed, &pParent->winSize);
+	}
+
+	RegionCopy(&pParent->borderClip, universe);
+    
+    	/*
+     	 * To get the right clipList for the parent, and to make doubly sure
+     	 * that no child overlaps the parent's border, we remove the parent's
+     	 * border from the universe before proceeding.
+     	 */
+    
+	RegionIntersect(universe, universe, &pParent->winSize);
+    }
+    else
+	RegionCopy(&pParent->borderClip, universe);
+    
+    if ((pChild = pParent->firstChild) && pParent->mapped)
+    {
+	RegionNull(&childUniverse);
+	RegionNull(&childUnion);
+	if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
+	    ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
+	     (pChild->drawable.x < pParent->lastChild->drawable.x)))
+	{
+	    for (; pChild; pChild = pChild->nextSib)
+	    {
+		if (pChild->viewable)
+		    RegionAppend(&childUnion, &pChild->borderSize);
+	    }
+	}
+	else
+	{
+	    for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
+	    {
+		if (pChild->viewable)
+		    RegionAppend(&childUnion, &pChild->borderSize);
+	    }
+	}
+	RegionValidate(&childUnion, &overlap);
+
+	for (pChild = pParent->firstChild;
+	     pChild;
+	     pChild = pChild->nextSib)
+ 	{
+	    if (pChild->viewable) {
+		/*
+		 * If the child is viewable, we want to remove its extents
+		 * from the current universe, but we only re-clip it if
+		 * it's been marked.
+		 */
+		if (pChild->valdata) {
+		    /*
+		     * Figure out the new universe from the child's
+		     * perspective and recurse.
+		     */
+		    RegionIntersect(&childUniverse,
+					    universe,
+					    &pChild->borderSize);
+		    RootlessComputeClips (pChild, pScreen, &childUniverse, 
+					  kind, exposed);
+		}
+		/*
+		 * Once the child has been processed, we remove its extents
+		 * from the current universe, thus denying its space to any
+		 * other sibling.
+		 */
+		if (overlap)
+		    RegionSubtract(universe, universe,
+					  &pChild->borderSize);
+	    }
+	}
+	if (!overlap)
+	    RegionSubtract(universe, universe, &childUnion);
+	RegionUninit(&childUnion);
+	RegionUninit(&childUniverse);
+    } /* if any children */
+
+    /*
+     * 'universe' now contains the new clipList for the parent window.
+     *
+     * To figure the exposure of the window we subtract the old clip from the
+     * new, just as for the border.
+     */
+
+    if (oldVis == VisibilityFullyObscured ||
+	oldVis == VisibilityNotViewable)
+    {
+	RegionCopy(&pParent->valdata->after.exposed, universe);
+    }
+    else if (newVis != VisibilityFullyObscured &&
+	     newVis != VisibilityNotViewable)
+    {
+	RegionSubtract(&pParent->valdata->after.exposed,
+			       universe, &pParent->clipList);
+    }
+
+    /* HACK ALERT - copying contents of regions, instead of regions */
+    {
+	RegionRec   tmp;
+
+	tmp = pParent->clipList;
+	pParent->clipList = *universe;
+	*universe = tmp;
+    }
+
+#ifdef NOTDEF
+    RegionCopy(&pParent->clipList, universe);
+#endif
+
+    pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    if (pScreen->ClipNotify)
+	(* pScreen->ClipNotify) (pParent, dx, dy);
+}
+
+static void
+RootlessTreeObscured(WindowPtr pParent)
+{
+    register WindowPtr pChild;
+    register int    oldVis;
+
+    pChild = pParent;
+    while (1)
+    {
+	if (pChild->viewable)
+	{
+	    oldVis = pChild->visibility;
+	    if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
+		((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
+		SendVisibilityNotify(pChild);
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pParent))
+	    pChild = pChild->parent;
+	if (pChild == pParent)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * RootlessMiValidateTree --
+ *	Recomputes the clip list for pParent and all its inferiors.
+ *
+ * Results:
+ *	Always returns 1.
+ *
+ * Side Effects:
+ *	The clipList, borderClip, exposed, and borderExposed regions for
+ *	each marked window are altered.
+ *
+ * Notes:
+ *	This routine assumes that all affected windows have been marked
+ *	(valdata created) and their winSize and borderSize regions
+ *	adjusted to correspond to their new positions. The borderClip and
+ *	clipList regions should not have been touched.
+ *
+ *	The top-most level is treated differently from all lower levels
+ *	because pParent is unchanged. For the top level, we merge the
+ *	regions taken up by the marked children back into the clipList
+ *	for pParent, thus forming a region from which the marked children
+ *	can claim their areas. For lower levels, where the old clipList
+ *	and borderClip are invalid, we can't do this and have to do the
+ *	extra operations done in miComputeClips, but this is much faster
+ *	e.g. when only one child has moved...
+ *
+ *-----------------------------------------------------------------------
+ */
+/* 
+   Quartz version: used for validate from root in rootless mode.
+   We need to make sure top-level windows don't clip each other, 
+   and that top-level windows aren't clipped to the root window.
+*/
+/*ARGSUSED*/
+// fixme this is ugly
+// Xprint/ValTree.c doesn't work, but maybe that method can?
+int
+RootlessMiValidateTree (WindowPtr pRoot, /* Parent to validate */
+			WindowPtr pChild, /* First child of pRoot that was
+					   * affected */
+			VTKind kind /* What kind of configuration caused call */)
+{
+    RegionRec	  	childClip;  /* The new borderClip for the current
+				     * child */
+    RegionRec		exposed;    /* For intermediate calculations */
+    register ScreenPtr	pScreen;
+    register WindowPtr	pWin;
+
+    pScreen = pRoot->drawable.pScreen;
+    if (pChild == NullWindow)
+	pChild = pRoot->firstChild;
+
+    RegionNull(&childClip);
+    RegionNull(&exposed);
+
+    if (RegionBroken(&pRoot->clipList) &&
+	!RegionBroken(&pRoot->borderClip))
+    {
+        // fixme this might not work, but hopefully doesn't happen anyway.
+        kind = VTBroken;
+        RegionEmpty(&pRoot->clipList);
+        ErrorF("ValidateTree: BUSTED!\n");
+    }
+
+    /* 
+     * Recursively compute the clips for all children of the root. 
+     * They don't clip against each other or the root itself, so 
+     * childClip is always reset to that child's size.
+     */
+
+    for (pWin = pChild;
+	 pWin != NullWindow;
+	 pWin = pWin->nextSib)
+    {
+        if (pWin->viewable) {
+            if (pWin->valdata) {
+                RegionCopy(&childClip, &pWin->borderSize);
+                RootlessComputeClips (pWin, pScreen, &childClip, kind, &exposed);
+            } else if (pWin->visibility == VisibilityNotViewable) {
+                RootlessTreeObscured(pWin);
+            }
+        } else {
+            if (pWin->valdata) {
+                RegionEmpty(&pWin->clipList);
+                if (pScreen->ClipNotify)
+                    (* pScreen->ClipNotify) (pWin, 0, 0);
+                RegionEmpty(&pWin->borderClip);
+                pWin->valdata = NULL;
+            }
+        }
+    }
+
+    RegionUninit(&childClip);
+
+    /* The root is never clipped by its children, so nothing on the root 
+       is ever exposed by moving or mapping its children. */
+    RegionNull(&pRoot->valdata->after.exposed);
+    RegionNull(&pRoot->valdata->after.borderExposed);
+
+    return 1;
+}
-- 
cgit v1.2.3