Remove ancient trunk folder from svn repository
[synfig.git] / synfig-osx / trunk / launcher / rootless-gc.c
diff --git a/synfig-osx/trunk/launcher/rootless-gc.c b/synfig-osx/trunk/launcher/rootless-gc.c
deleted file mode 100644 (file)
index dea17e9..0000000
+++ /dev/null
@@ -1,1526 +0,0 @@
-/*
- * Graphics Context support for Mac OS X rootless X server
- */
-/*
- * Copyright (c) 2001 Greg Parker. All Rights Reserved.
- * Copyright (c) 2002 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.
- */
-/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/rootlessGC.c,v 1.3 2002/07/24 05:58:33 torrey Exp $ */
-
-#include "mi.h"
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "dixfontstr.h"
-#include "mivalidate.h"
-#include "fb.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "rootless-common.h"
-
-
-// GC functions
-static void 
-RootlessValidateGC(GCPtr pGC, unsigned long changes,
-                               DrawablePtr pDrawable);
-static void RootlessChangeGC(GCPtr pGC, unsigned long mask);
-static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
-static void RootlessDestroyGC(GCPtr pGC);
-static void RootlessChangeClip(GCPtr pGC, int type, pointer pvalue,
-                               int nrects);
-static void RootlessDestroyClip(GCPtr pGC);
-static void RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
-
-GCFuncs rootlessGCFuncs = {
-    RootlessValidateGC,
-    RootlessChangeGC,
-    RootlessCopyGC,
-    RootlessDestroyGC,
-    RootlessChangeClip,
-    RootlessDestroyClip,
-    RootlessCopyClip,
-};
-
-// GC operations
-static void RootlessFillSpans();
-static void RootlessSetSpans();
-static void RootlessPutImage();
-static RegionPtr RootlessCopyArea();
-static RegionPtr RootlessCopyPlane();
-static void RootlessPolyPoint();
-static void RootlessPolylines();
-static void RootlessPolySegment();
-static void RootlessPolyRectangle();
-static void RootlessPolyArc();
-static void RootlessFillPolygon();
-static void RootlessPolyFillRect();
-static void RootlessPolyFillArc();
-static int RootlessPolyText8();
-static int RootlessPolyText16();
-static void RootlessImageText8();
-static void RootlessImageText16();
-static void RootlessImageGlyphBlt();
-static void RootlessPolyGlyphBlt();
-static void RootlessPushPixels();
-
-static GCOps rootlessGCOps = {
-    RootlessFillSpans,
-    RootlessSetSpans,
-    RootlessPutImage,
-    RootlessCopyArea,
-    RootlessCopyPlane,
-    RootlessPolyPoint,
-    RootlessPolylines,
-    RootlessPolySegment,
-    RootlessPolyRectangle,
-    RootlessPolyArc,
-    RootlessFillPolygon,
-    RootlessPolyFillRect,
-    RootlessPolyFillArc,
-    RootlessPolyText8,
-    RootlessPolyText16,
-    RootlessImageText8,
-    RootlessImageText16,
-    RootlessImageGlyphBlt,
-    RootlessPolyGlyphBlt,
-    RootlessPushPixels
-#ifdef NEED_LINEHELPER
-    , NULL
-#endif
-};
-
-
-Bool
-RootlessCreateGC(GCPtr pGC)
-{
-    RootlessGCRec *gcrec;
-    RootlessScreenRec *s;
-    Bool result;
-
-    SCREEN_UNWRAP(pGC->pScreen, CreateGC);
-    s = (RootlessScreenRec *) pGC->pScreen->
-            devPrivates[rootlessScreenPrivateIndex].ptr;
-    result = s->CreateGC(pGC);
-    gcrec = (RootlessGCRec *) pGC->devPrivates[rootlessGCPrivateIndex].ptr;
-    gcrec->originalOps = NULL; // don't wrap ops yet
-    gcrec->originalFuncs = pGC->funcs;
-    pGC->funcs = &rootlessGCFuncs;
-
-    SCREEN_WRAP(pGC->pScreen, CreateGC);
-    return result;
-}
-
-
-// GC func wrapping
-// ValidateGC wraps gcOps iff dest is viewable. All others just unwrap&call.
-
-// GCFUN_UNRAP assumes funcs have been wrapped and 
-// does not assume ops have been wrapped
-#define GCFUNC_UNWRAP(pGC) \
-    RootlessGCRec *gcrec = (RootlessGCRec *) \
-        (pGC)->devPrivates[rootlessGCPrivateIndex].ptr; \
-    (pGC)->funcs = gcrec->originalFuncs; \
-    if (gcrec->originalOps) { \
-        (pGC)->ops = gcrec->originalOps; \
-}
-
-#define GCFUNC_WRAP(pGC) \
-    gcrec->originalFuncs = (pGC)->funcs; \
-    (pGC)->funcs = &rootlessGCFuncs; \
-    if (gcrec->originalOps) { \
-        gcrec->originalOps = (pGC)->ops; \
-        (pGC)->ops = &rootlessGCOps; \
-}
-
-/* Turn drawing on the root into a no-op */
-#define GC_IS_ROOT(pDst) ((pDst)->type == DRAWABLE_WINDOW \
-                         && IsRoot ((WindowPtr) (pDst)) \
-                         && WINREC ((WindowPtr) (pDst)) == NULL)
-
-#define GC_SKIP_ROOT(pDst)     \
-    do {                       \
-       if (GC_IS_ROOT (pDst))  \
-           return;             \
-    } while (0)
-       
-/* Our main problem when drawing is that we have to make sure that
-   the alpha channel of the windows we're drawing in is always opaque.
-
-   fb makes this harder than it would otherwise be by noticing that a
-   planemask of 0x00ffffff includes all bits when depth=24, and so
-   "optimizes" the pm to 0xffffffff. We work around that by temporarily
-   setting depth=bpp while changing the GC.
-
-   Anyway, so the normal situation (in 32 bit mode) is that the
-   planemask is 0x00ffffff and thus fb leaves the alpha channel alone
-   (and it's opaque initially, so things work out).
-
-   But there's a problem with drawing with a planemask that doesn't
-   have all bits set - it normally causes fb to fall off its fastest
-   paths when blitting and filling.
-
-   So my solution to that is to try to recognize when we can relax the
-   planemask back to ~0, and do that for the duration of the drawing
-   operation, setting the alpha channel in fg/bg pixels to opaque at
-   the same time. We can do this when drawing op is GXcopy. We can also
-   do it when copying from another window (since its alpha channel must
-   also be opaque).
-
-   Note that even when we can't set planemask to all ones, fbBlt may
-   still choose altivec'd code if it's GXcopy and a forwards copy. This
-   is mainly intended for copying from pixmaps to windows. The copy
-   operation used sets alpha to opaque.
-
-   The three macros below are used to implement this, drawing ops look
-   something like this:
-
-   OP {
-       GC_SAVE (gc);
-       GCFUNC_UNWRAP (gc);
-
-       ...
-
-       if (can_accel_xxx (..) && otherwise-suitable)
-          GC_UNSET_PM (gc, dst);
-
-       gc->funcs->OP (gc, ...);
-
-       GC_RESTORE (gc, dst);
-       GCFUNC_WRAP (gc);
-   }
-
-   */
-
-#define GC_SAVE(pGC)                           \
-    unsigned long _save_fg = (pGC)->fgPixel;   \
-    unsigned long _save_bg = (pGC)->bgPixel;   \
-    unsigned long _save_pm = (pGC)->planemask; \
-    Bool _changed = FALSE
-
-#define GC_RESTORE(pGC, pDraw)                                 \
-    do {                                                       \
-       if (_changed) {                                         \
-           unsigned int depth = (pDraw)->depth;                \
-           (pGC)->fgPixel = _save_fg;                          \
-           (pGC)->bgPixel = _save_bg;                          \
-           (pGC)->planemask = _save_pm;                        \
-           (pDraw)->depth = (pDraw)->bitsPerPixel;             \
-           validate_gc (pGC, GCForeground | GCBackground       \
-                        | GCPlaneMask, pDraw);                 \
-           (pDraw)->depth = depth;                             \
-       }                                                       \
-    } while (0)
-
-#define GC_UNSET_PM(pGC, pDraw)                                                \
-    do {                                                               \
-       unsigned int mask = RootlessAlphaMask ((pDraw)->bitsPerPixel);  \
-       if (((pGC)->planemask & mask) != mask) {                        \
-           unsigned int depth = (pDraw)->depth;                        \
-           (pGC)->fgPixel |= mask;                                     \
-           (pGC)->bgPixel |= mask;                                     \
-           (pGC)->planemask |= mask;                                   \
-           (pDraw)->depth = (pDraw)->bitsPerPixel;                     \
-           validate_gc (pGC, GCForeground                              \
-                        | GCBackground | GCPlaneMask, pDraw);          \
-           (pDraw)->depth = depth;                                     \
-           _changed = TRUE;                                            \
-       }                                                               \
-    } while (0)
-
-static void
-validate_gc (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
-{
-    RootlessGCRec *gcrec = (RootlessGCRec *)
-        (pGC)->devPrivates[rootlessGCPrivateIndex].ptr;
-
-    pGC->funcs->ValidateGC(pGC, changes, pDrawable);
-
-    if (((WindowPtr) pDrawable)->viewable)
-    {
-       gcrec->originalOps = pGC->ops;
-    }
-}
-
-static RootlessWindowRec *
-can_accel_blit (DrawablePtr pDraw, GCPtr pGC)
-{
-    WindowPtr pTop;
-    RootlessWindowRec *winRec;
-    unsigned int pm;
-
-    if (pGC->alu != GXcopy)
-       return NULL;
-
-    if (pDraw->type != DRAWABLE_WINDOW)
-       return NULL;
-
-    pm = ~RootlessAlphaMask (pDraw->bitsPerPixel);
-    if ((pGC->planemask & pm) != pm)
-       return NULL;
-
-    pTop = TopLevelParent ((WindowPtr) pDraw);
-    if (pTop == NULL)
-       return NULL;
-
-    winRec = WINREC(pTop);
-    if (winRec == NULL)
-       return NULL;
-
-    return winRec;
-}
-
-static inline RootlessWindowRec *
-can_accel_fill (DrawablePtr pDraw, GCPtr pGC)
-{
-    if (pGC->fillStyle != FillSolid)
-       return NULL;
-
-    return can_accel_blit (pDraw, pGC);
-}
-
-static unsigned int
-box_bytes (DrawablePtr pDraw, BoxRec *box)
-{
-    unsigned int pixels;
-
-    pixels = (box->x2 - box->x1) * (box->y2 - box->y1);
-
-    return pixels * (pDraw->bitsPerPixel >> 3);
-}
-
-static void
-RootlessValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
-{
-    GCFUNC_UNWRAP(pGC);
-
-    gcrec->originalOps = NULL;
-
-    if (pDrawable->type == DRAWABLE_WINDOW)
-    {
-       /* Prevent fb relaxing planemask by telling it we use all
-          bits temporarily. */
-
-       unsigned int depth = pDrawable->depth;
-       pDrawable->depth = pDrawable->bitsPerPixel;
-       pGC->planemask &= ~RootlessAlphaMask (pDrawable->bitsPerPixel);
-       validate_gc (pGC, changes | GCPlaneMask, pDrawable);
-       pDrawable->depth = depth;
-    }
-    else
-        pGC->funcs->ValidateGC(pGC, changes, pDrawable);
-
-    GCFUNC_WRAP(pGC);
-}
-
-static void RootlessChangeGC(GCPtr pGC, unsigned long mask)
-{
-    GCFUNC_UNWRAP(pGC);
-    pGC->funcs->ChangeGC(pGC, mask);
-    GCFUNC_WRAP(pGC);
-}
-
-static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
-{
-    GCFUNC_UNWRAP(pGCDst);
-    pGCDst->funcs->CopyGC(pGCSrc, mask, pGCDst);
-    GCFUNC_WRAP(pGCDst);
-}
-
-static void RootlessDestroyGC(GCPtr pGC)
-{
-    GCFUNC_UNWRAP(pGC);
-    pGC->funcs->DestroyGC(pGC);
-    GCFUNC_WRAP(pGC);
-}
-
-static void RootlessChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
-{
-    GCFUNC_UNWRAP(pGC);
-    pGC->funcs->ChangeClip(pGC, type, pvalue, nrects);
-    GCFUNC_WRAP(pGC);
-}
-
-static void RootlessDestroyClip(GCPtr pGC)
-{
-    GCFUNC_UNWRAP(pGC);
-    pGC->funcs->DestroyClip(pGC);
-    GCFUNC_WRAP(pGC);
-}
-
-static void RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
-{
-    GCFUNC_UNWRAP(pgcDst);
-    pgcDst->funcs->CopyClip(pgcDst, pgcSrc);
-    GCFUNC_WRAP(pgcDst);
-}
-
-
-// GC ops
-// We can't use shadowfb because shadowfb assumes one pixmap
-// and our root window is a special case.
-// So much of this code is copied from shadowfb.
-
-// assumes both funcs and ops are wrapped
-#define GCOP_UNWRAP(pGC) \
-    RootlessGCRec *gcrec = (RootlessGCRec *) \
-        (pGC)->devPrivates[rootlessGCPrivateIndex].ptr; \
-    GCFuncs *saveFuncs = pGC->funcs; \
-    (pGC)->funcs = gcrec->originalFuncs; \
-    (pGC)->ops = gcrec->originalOps;
-
-#define GCOP_WRAP(pGC) \
-    gcrec->originalOps = (pGC)->ops; \
-    (pGC)->funcs = saveFuncs; \
-    (pGC)->ops = &rootlessGCOps;
-
-
-static void
-RootlessFillSpans(DrawablePtr dst, GCPtr pGC, int nInit,
-                  DDXPointPtr pptInit, int *pwidthInit, int sorted)
-{
-    GC_SAVE (pGC);
-
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("fill spans start\n");
-
-    if (nInit <= 0) {
-        pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted);
-    } else {
-        DDXPointPtr ppt = pptInit;
-        int *pwidth = pwidthInit;
-        int i = nInit;
-        BoxRec box;
-
-        box.x1 = ppt->x;
-        box.x2 = box.x1 + *pwidth;
-        box.y2 = box.y1 = ppt->y;
-
-        while(--i) {
-            ppt++;
-            pwidthInit++;
-            if(box.x1 > ppt->x)
-                box.x1 = ppt->x;
-            if(box.x2 < (ppt->x + *pwidth))
-                box.x2 = ppt->x + *pwidth;
-            if(box.y1 > ppt->y)
-                box.y1 = ppt->y;
-            else if(box.y2 < ppt->y)
-                box.y2 = ppt->y;
-        }
-
-        box.y2++;
-
-        RootlessStartDrawing((WindowPtr) dst);
-
-       if (can_accel_fill (dst, pGC)
-           && box_bytes (dst, &box) >= xp_fill_bytes_threshold)
-       {
-           GC_UNSET_PM (pGC, dst);
-       }
-
-        pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted);
-
-        TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-
-       RootlessFinishedDrawing ((WindowPtr) dst);
-    }
-
-    GC_RESTORE (pGC, dst);
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("fill spans end\n");
-}
-
-static void
-RootlessSetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc,
-                 DDXPointPtr pptInit, int *pwidthInit,
-                 int nspans, int sorted)
-{
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("set spans start\n");
-
-    if (nspans <= 0) {
-        pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit,
-                           nspans, sorted);
-    } else {
-        DDXPointPtr ppt = pptInit;
-        int *pwidth = pwidthInit;
-        int i = nspans;
-        BoxRec box;
-
-        box.x1 = ppt->x;
-        box.x2 = box.x1 + *pwidth;
-        box.y2 = box.y1 = ppt->y;
-
-        while(--i) {
-            ppt++;
-            pwidth++;
-            if(box.x1 > ppt->x)
-                box.x1 = ppt->x;
-            if(box.x2 < (ppt->x + *pwidth))
-                box.x2 = ppt->x + *pwidth;
-            if(box.y1 > ppt->y)
-                box.y1 = ppt->y;
-            else if(box.y2 < ppt->y)
-                box.y2 = ppt->y;
-        }
-
-        box.y2++;
-
-        RootlessStartDrawing((WindowPtr) dst);
-        pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit,
-                           nspans, sorted);
-
-        TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-
-       RootlessFinishedDrawing ((WindowPtr) dst);
-    }
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("set spans end\n");
-}
-
-static void
-RootlessPutImage(DrawablePtr dst, GCPtr pGC,
-                 int depth, int x, int y, int w, int h,
-                 int leftPad, int format, char *pBits)
-{
-    BoxRec box;
-
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("put image start\n");
-
-    RootlessStartDrawing((WindowPtr) dst);
-    pGC->ops->PutImage(dst, pGC, depth, x,y,w,h, leftPad, format, pBits);
-
-    box.x1 = x + dst->x;
-    box.x2 = box.x1 + w;
-    box.y1 = y + dst->y;
-    box.y2 = box.y1 + h;
-
-    TRIM_BOX(box, pGC);
-    if(BOX_NOT_EMPTY(box))
-        RootlessDamageBox ((WindowPtr) dst, &box);
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("put image end\n");
-}
-
-/* changed area is *dest* rect */
-static RegionPtr
-RootlessCopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC,
-                 int srcx, int srcy, int w, int h,
-                 int dstx, int dsty)
-{
-    RegionPtr result;
-    BoxRec box;
-    GC_SAVE (pGC);
-    Bool src_drawing = FALSE;
-
-    if (GC_IS_ROOT (dst) || GC_IS_ROOT (pSrc))
-       return NULL;                    /* nothing exposed */
-
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("copy area start (src 0x%x, dst 0x%x)\n", pSrc, dst);
-
-    if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr)pSrc))
-    {
-       unsigned int bytes;
-
-       /* If both source and dest are windows, and we're doing
-          a simple copy operation, we can remove the alpha-protecting
-          planemask (since source has opaque alpha as well) */
-
-       bytes = w * h * (pSrc->depth >> 3);
-
-       if (bytes >= xp_copy_bytes_threshold && can_accel_blit (pSrc, pGC))
-       {
-           GC_UNSET_PM (pGC, dst);
-       }
-
-        RootlessStartDrawing((WindowPtr) pSrc);
-       src_drawing = TRUE;
-    }
-    RootlessStartDrawing((WindowPtr) dst);
-    result = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty);
-
-    box.x1 = dstx + dst->x;
-    box.x2 = box.x1 + w;
-    box.y1 = dsty + dst->y;
-    box.y2 = box.y1 + h;
-
-    TRIM_BOX(box, pGC);
-    if(BOX_NOT_EMPTY(box))
-        RootlessDamageBox ((WindowPtr) dst, &box);
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-    if (src_drawing)
-       RootlessFinishedDrawing ((WindowPtr) pSrc);
-
-    GC_RESTORE (pGC, dst);
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("copy area end\n");
-    return result;
-}
-
-/* changed area is *dest* rect */
-static RegionPtr RootlessCopyPlane(DrawablePtr pSrc, DrawablePtr dst,
-                                   GCPtr pGC, int srcx, int srcy,
-                                   int w, int h, int dstx, int dsty,
-                                   unsigned long plane)
-{
-    RegionPtr result;
-    BoxRec box;
-    Bool src_drawing = FALSE;
-
-    if (GC_IS_ROOT (dst) || GC_IS_ROOT (pSrc))
-       return NULL;                    /* nothing exposed */
-
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("copy plane start\n");
-
-    if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr)pSrc)) {
-        RootlessStartDrawing((WindowPtr) pSrc);
-       src_drawing = TRUE;
-    }
-    RootlessStartDrawing((WindowPtr) dst);
-    result = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h,
-                                 dstx, dsty, plane);
-
-    box.x1 = dstx + dst->x;
-    box.x2 = box.x1 + w;
-    box.y1 = dsty + dst->y;
-    box.y2 = box.y1 + h;
-
-    TRIM_BOX(box, pGC);
-    if(BOX_NOT_EMPTY(box))
-        RootlessDamageBox ((WindowPtr) dst, &box);
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-    if (src_drawing)
-       RootlessFinishedDrawing ((WindowPtr) pSrc);
-
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("copy plane end\n");
-    return result;
-}
-
-// Options for size of changed area:
-//  0 = box per point
-//  1 = big box around all points
-//  2 = accumulate point in 20 pixel radius
-#define ROOTLESS_CHANGED_AREA 1
-#define abs(a) ((a) > 0 ? (a) : -(a))
-
-/* changed area is box around all points */
-static void RootlessPolyPoint(DrawablePtr dst, GCPtr pGC,
-                              int mode, int npt, DDXPointPtr pptInit)
-{
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("polypoint start\n");
-
-    RootlessStartDrawing((WindowPtr) dst);
-    pGC->ops->PolyPoint(dst, pGC, mode, npt, pptInit);
-
-    if (npt > 0) {
-#if ROOTLESS_CHANGED_AREA==0
-        // box per point
-        BoxRec box;
-
-        while (npt) {
-            box.x1 = pptInit->x;
-            box.y1 = pptInit->y;
-            box.x2 = box.x1 + 1;
-            box.y2 = box.y1 + 1;
-
-            TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-            if(BOX_NOT_EMPTY(box))
-                RootlessDamageBox ((WindowPtr) dst, &box);
-
-            npt--;
-            pptInit++;
-        }
-
-#elif ROOTLESS_CHANGED_AREA==1
-        // one big box
-        BoxRec box;
-
-        box.x2 = box.x1 = pptInit->x;
-        box.y2 = box.y1 = pptInit->y;
-        while(--npt) {
-            pptInit++;
-            if(box.x1 > pptInit->x)
-                box.x1 = pptInit->x;
-            else if(box.x2 < pptInit->x)
-                box.x2 = pptInit->x;
-            if(box.y1 > pptInit->y)
-                box.y1 = pptInit->y;
-            else if(box.y2 < pptInit->y)
-                box.y2 = pptInit->y;
-        }
-
-        box.x2++;
-        box.y2++;
-
-        TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-
-#elif ROOTLESS_CHANGED_AREA==2
-        // clever(?) method: accumulate point in 20-pixel radius
-        BoxRec box;
-        int firstx, firsty;
-
-        box.x2 = box.x1 = firstx = pptInit->x;
-        box.y2 = box.y1 = firsty = pptInit->y;
-        while(--npt) {
-            pptInit++;
-            if (abs(pptInit->x - firstx) > 20 ||
-                abs(pptInit->y - firsty) > 20) {
-                box.x2++;
-                box.y2++;
-                TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-                if(BOX_NOT_EMPTY(box))
-                    RootlessDamageBox ((WindowPtr) dst, &box);
-                box.x2 = box.x1 = firstx = pptInit->x;
-                box.y2 = box.y1 = firsty = pptInit->y;
-            } else {
-                if (box.x1 > pptInit->x) box.x1 = pptInit->x;
-                else if (box.x2 < pptInit->x) box.x2 = pptInit->x;
-                if (box.y1 > pptInit->y) box.y1 = pptInit->y;
-                else if (box.y2 < pptInit->y) box.y2 = pptInit->y;
-            }
-        }
-        box.x2++;
-        box.y2++;
-        TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-#endif  /* ROOTLESS_CHANGED_AREA */
-    }
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("polypoint end\n");
-}
-
-#undef ROOTLESS_CHANGED_AREA
-
-/* changed area is box around each line */
-static void RootlessPolylines(DrawablePtr dst, GCPtr pGC,
-                              int mode, int npt, DDXPointPtr pptInit)
-{
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("poly lines start\n");
-
-    RootlessStartDrawing((WindowPtr) dst);
-    pGC->ops->Polylines(dst, pGC, mode, npt, pptInit);
-
-    if (npt > 0) {
-        BoxRec box;
-        int extra = pGC->lineWidth >> 1;
-
-        box.x2 = box.x1 = pptInit->x;
-        box.y2 = box.y1 = pptInit->y;
-
-        if(npt > 1) {
-            if(pGC->joinStyle == JoinMiter)
-                extra = 6 * pGC->lineWidth;
-            else if(pGC->capStyle == CapProjecting)
-                extra = pGC->lineWidth;
-        }
-
-        if(mode == CoordModePrevious) {
-            int x = box.x1;
-            int y = box.y1;
-
-            while(--npt) {
-                pptInit++;
-                x += pptInit->x;
-                y += pptInit->y;
-                if(box.x1 > x)
-                    box.x1 = x;
-                else if(box.x2 < x)
-                    box.x2 = x;
-                if(box.y1 > y)
-                    box.y1 = y;
-                else if(box.y2 < y)
-                    box.y2 = y;
-            }
-        } else {
-            while(--npt) {
-                pptInit++;
-                if(box.x1 > pptInit->x)
-                    box.x1 = pptInit->x;
-                else if(box.x2 < pptInit->x)
-                    box.x2 = pptInit->x;
-                if(box.y1 > pptInit->y)
-                    box.y1 = pptInit->y;
-                else if(box.y2 < pptInit->y)
-                    box.y2 = pptInit->y;
-            }
-        }
-
-        box.x2++;
-        box.y2++;
-
-        if(extra) {
-            box.x1 -= extra;
-            box.x2 += extra;
-            box.y1 -= extra;
-            box.y2 += extra;
-        }
-
-        TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-    }
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("poly lines end\n");
-}
-
-/* changed area is box around each line segment */
-static void RootlessPolySegment(DrawablePtr dst, GCPtr pGC,
-                                int nseg, xSegment *pSeg)
-{
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("poly segment start (win 0x%x)\n", dst);
-
-    RootlessStartDrawing((WindowPtr) dst);
-    pGC->ops->PolySegment(dst, pGC, nseg, pSeg);
-
-    if (nseg > 0) {
-        BoxRec box;
-        int extra = pGC->lineWidth;
-
-        if(pGC->capStyle != CapProjecting)
-        extra >>= 1;
-
-        if(pSeg->x2 > pSeg->x1) {
-            box.x1 = pSeg->x1;
-            box.x2 = pSeg->x2;
-        } else {
-            box.x2 = pSeg->x1;
-            box.x1 = pSeg->x2;
-        }
-
-        if(pSeg->y2 > pSeg->y1) {
-            box.y1 = pSeg->y1;
-            box.y2 = pSeg->y2;
-        } else {
-            box.y2 = pSeg->y1;
-            box.y1 = pSeg->y2;
-        }
-
-        while(--nseg) {
-            pSeg++;
-            if(pSeg->x2 > pSeg->x1) {
-                if(pSeg->x1 < box.x1) box.x1 = pSeg->x1;
-                if(pSeg->x2 > box.x2) box.x2 = pSeg->x2;
-            } else {
-                if(pSeg->x2 < box.x1) box.x1 = pSeg->x2;
-                if(pSeg->x1 > box.x2) box.x2 = pSeg->x1;
-            }
-            if(pSeg->y2 > pSeg->y1) {
-                if(pSeg->y1 < box.y1) box.y1 = pSeg->y1;
-                if(pSeg->y2 > box.y2) box.y2 = pSeg->y2;
-            } else {
-                if(pSeg->y2 < box.y1) box.y1 = pSeg->y2;
-                if(pSeg->y1 > box.y2) box.y2 = pSeg->y1;
-            }
-        }
-
-        box.x2++;
-        box.y2++;
-
-        if(extra) {
-            box.x1 -= extra;
-            box.x2 += extra;
-            box.y1 -= extra;
-            box.y2 += extra;
-        }
-
-        TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-    }
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("poly segment end\n");
-}
-
-/* changed area is box around each line (not entire rects) */
-static void RootlessPolyRectangle(DrawablePtr dst, GCPtr pGC,
-                                 int nRects, xRectangle *pRects)
-{
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("poly rectangle start\n");
-
-    RootlessStartDrawing((WindowPtr) dst);
-    pGC->ops->PolyRectangle(dst, pGC, nRects, pRects);
-
-    if (nRects > 0) {
-        BoxRec box;
-        int offset1, offset2, offset3;
-
-        offset2 = pGC->lineWidth;
-        if(!offset2) offset2 = 1;
-        offset1 = offset2 >> 1;
-        offset3 = offset2 - offset1;
-
-        while(nRects--) {
-            box.x1 = pRects->x - offset1;
-            box.y1 = pRects->y - offset1;
-            box.x2 = box.x1 + pRects->width + offset2;
-            box.y2 = box.y1 + offset2;         
-            TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-            if(BOX_NOT_EMPTY(box))
-                RootlessDamageBox ((WindowPtr) dst, &box);
-
-            box.x1 = pRects->x - offset1;
-            box.y1 = pRects->y + offset3;
-            box.x2 = box.x1 + offset2;
-            box.y2 = box.y1 + pRects->height - offset2;                
-            TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-            if(BOX_NOT_EMPTY(box))
-                RootlessDamageBox ((WindowPtr) dst, &box);
-
-            box.x1 = pRects->x + pRects->width - offset1;
-            box.y1 = pRects->y + offset3;
-            box.x2 = box.x1 + offset2;
-            box.y2 = box.y1 + pRects->height - offset2;                
-            TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-            if(BOX_NOT_EMPTY(box))
-                RootlessDamageBox ((WindowPtr) dst, &box);
-
-            box.x1 = pRects->x - offset1;
-            box.y1 = pRects->y + pRects->height - offset1;
-            box.x2 = box.x1 + pRects->width + offset2;
-            box.y2 = box.y1 + offset2;         
-            TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-            if(BOX_NOT_EMPTY(box))
-                RootlessDamageBox ((WindowPtr) dst, &box);
-
-            pRects++;
-        }
-    }
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("poly rectangle end\n");
-}
-
-
-/* changed area is box around each arc (assumes all arcs are 360 degrees) */
-static void RootlessPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc *parcs)
-{
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("poly arc start\n");
-
-    RootlessStartDrawing((WindowPtr) dst);
-    pGC->ops->PolyArc(dst, pGC, narcs, parcs);
-
-    if (narcs > 0) {
-        int extra = pGC->lineWidth >> 1;
-        BoxRec box;
-
-        box.x1 = parcs->x;
-        box.x2 = box.x1 + parcs->width;
-        box.y1 = parcs->y;
-        box.y2 = box.y1 + parcs->height;
-
-        /* should I break these up instead ? */
-
-        while(--narcs) {
-            parcs++;
-            if(box.x1 > parcs->x)
-                box.x1 = parcs->x;
-            if(box.x2 < (parcs->x + parcs->width))
-                box.x2 = parcs->x + parcs->width;
-            if(box.y1 > parcs->y)
-                box.y1 = parcs->y;
-            if(box.y2 < (parcs->y + parcs->height))
-                box.y2 = parcs->y + parcs->height;
-        }
-
-        if(extra) {
-            box.x1 -= extra;
-            box.x2 += extra;
-            box.y1 -= extra;
-            box.y2 += extra;
-        }
-
-        box.x2++;
-        box.y2++;
-
-        TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-    }
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("poly arc end\n");
-}
-
-
-/* changed area is box around each poly */
-static void RootlessFillPolygon(DrawablePtr dst, GCPtr pGC,
-                               int shape, int mode, int count,
-                               DDXPointPtr pptInit)
-{
-    GC_SAVE (pGC);
-
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("fill poly start (win 0x%x, fillStyle 0x%x)\n", dst,
-                 pGC->fillStyle);
-
-    if (count <= 2) {
-        pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit);
-    } else {
-        DDXPointPtr ppt = pptInit;
-        int i = count;
-        BoxRec box;
-
-        box.x2 = box.x1 = ppt->x;
-        box.y2 = box.y1 = ppt->y;
-
-        if(mode != CoordModeOrigin) {
-            int x = box.x1;
-            int y = box.y1;
-
-            while(--i) {
-                ppt++;
-                x += ppt->x;
-                y += ppt->y;
-                if(box.x1 > x)
-                    box.x1 = x;
-                else if(box.x2 < x)
-                    box.x2 = x;
-                if(box.y1 > y)
-                    box.y1 = y;
-                else if(box.y2 < y)
-                    box.y2 = y;
-            }
-        } else {
-            while(--i) {
-                ppt++;
-                if(box.x1 > ppt->x)
-                    box.x1 = ppt->x;
-                else if(box.x2 < ppt->x)
-                    box.x2 = ppt->x;
-                if(box.y1 > ppt->y)
-                    box.y1 = ppt->y;
-                else if(box.y2 < ppt->y)
-                    box.y2 = ppt->y;
-            }
-        }
-
-        box.x2++;
-        box.y2++;
-
-        RootlessStartDrawing((WindowPtr) dst);
-
-       if (can_accel_fill (dst, pGC)
-           && box_bytes (dst, &box) >= xp_fill_bytes_threshold)
-       {
-           GC_UNSET_PM (pGC, dst);
-       }
-
-       pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit);
-
-        TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-
-       RootlessFinishedDrawing ((WindowPtr) dst);
-    }
-
-    GC_RESTORE (pGC, dst);
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("fill poly end\n");
-}
-
-/* changed area is the rects */
-static void RootlessPolyFillRect(DrawablePtr dst, GCPtr pGC,
-                                int nRectsInit, xRectangle *pRectsInit)
-{
-    GC_SAVE (pGC);
-
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("fill rect start (win 0x%x, fillStyle 0x%x)\n", dst,
-                 pGC->fillStyle);
-
-    if (nRectsInit <= 0) {
-        pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit);
-    } else {
-        BoxRec box;
-        xRectangle *pRects = pRectsInit;
-        int nRects = nRectsInit;
-
-        box.x1 = pRects->x;
-        box.x2 = box.x1 + pRects->width;
-        box.y1 = pRects->y;
-        box.y2 = box.y1 + pRects->height;
-
-        while(--nRects) {
-            pRects++;
-            if(box.x1 > pRects->x)
-                box.x1 = pRects->x;
-            if(box.x2 < (pRects->x + pRects->width))
-                box.x2 = pRects->x + pRects->width;
-            if(box.y1 > pRects->y)
-                box.y1 = pRects->y;
-            if(box.y2 < (pRects->y + pRects->height))
-                box.y2 = pRects->y + pRects->height;
-        }
-
-        /* cfb messes with the pRectsInit so we have to do our
-          calculations first */
-
-       RootlessStartDrawing((WindowPtr) dst);
-
-       if (can_accel_fill (dst, pGC)
-           && box_bytes (dst, &box) >= xp_fill_bytes_threshold)
-       {
-           GC_UNSET_PM (pGC, dst);
-       }
-
-       pGC->ops->PolyFillRect (dst, pGC, nRectsInit, pRectsInit);
-
-        TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-
-       RootlessFinishedDrawing ((WindowPtr) dst);
-    }
-
-    GC_RESTORE (pGC, dst);
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("fill rect end\n");
-}
-
-
-/* changed area is box around each arc (assuming arcs are all 360 degrees) */
-static void RootlessPolyFillArc(DrawablePtr dst, GCPtr pGC,
-                               int narcs, xArc *parcs)
-{
-    GC_SAVE (pGC);
-
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("fill arc start\n");
-
-    if (narcs > 0) {
-        BoxRec box;
-       int i;
-
-        box.x1 = parcs->x;
-        box.x2 = box.x1 + parcs->width;
-        box.y1 = parcs->y;
-        box.y2 = box.y1 + parcs->height;
-
-        /* should I break these up instead ? */
-
-       for (i = 0; i < narcs; i++)
-       {
-            if(box.x1 > parcs[i].x)
-                box.x1 = parcs[i].x;
-            if(box.x2 < (parcs[i].x + parcs[i].width))
-                box.x2 = parcs[i].x + parcs[i].width;
-            if(box.y1 > parcs[i].y)
-                box.y1 = parcs[i].y;
-            if(box.y2 < (parcs[i].y + parcs[i].height))
-                box.y2 = parcs[i].y + parcs[i].height;
-        }
-
-       RootlessStartDrawing((WindowPtr) dst);
-
-       if (can_accel_fill (dst, pGC)
-           && box_bytes (dst, &box) >= xp_fill_bytes_threshold)
-       {
-           GC_UNSET_PM (pGC, dst);
-       }
-
-       pGC->ops->PolyFillArc(dst, pGC, narcs, parcs);
-
-        TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-
-       RootlessFinishedDrawing ((WindowPtr) dst);
-    }
-    else
-       pGC->ops->PolyFillArc(dst, pGC, narcs, parcs);
-
-    GC_RESTORE (pGC, dst);
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("fill arc end\n");
-}
-
-
-static void RootlessImageText8(DrawablePtr dst, GCPtr pGC,
-                              int x, int y, int count, char *chars)
-{
-    GC_SAVE (pGC);
-
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("imagetext8 start\n");
-
-    RootlessStartDrawing((WindowPtr) dst);
-
-    if (count > 0) {
-        int top, bot, Min, Max;
-        BoxRec box;
-
-        top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
-        bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
-
-        Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
-        if(Min > 0) Min = 0;
-        Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);        
-        if(Max < 0) Max = 0;
-
-        /* ugh */
-        box.x1 = dst->x + x + Min +
-        FONTMINBOUNDS(pGC->font, leftSideBearing);
-        box.x2 = dst->x + x + Max +
-        FONTMAXBOUNDS(pGC->font, rightSideBearing);
-
-        box.y1 = dst->y + y - top;
-        box.y2 = dst->y + y + bot;
-
-       if (can_accel_fill (dst, pGC)
-           && box_bytes (dst, &box) >= xp_fill_bytes_threshold)
-       {
-           GC_UNSET_PM (pGC, dst);
-       }
-
-       pGC->ops->ImageText8(dst, pGC, x, y, count, chars);
-
-        TRIM_BOX(box, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-    }
-    else
-       pGC->ops->ImageText8(dst, pGC, x, y, count, chars);
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-
-    GC_RESTORE (pGC, dst);
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("imagetext8 end\n");
-}
-
-static int RootlessPolyText8(DrawablePtr dst, GCPtr pGC,
-                             int x, int y, int count, char *chars)
-{
-    int width; // the result, sorta
-
-    if (GC_IS_ROOT (dst))
-       return 0;                       /* FIXME: ok? */
-
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("polytext8 start\n");
-
-    RootlessStartDrawing((WindowPtr) dst);
-    width = pGC->ops->PolyText8(dst, pGC, x, y, count, chars);
-    width -= x;
-
-    if(width > 0) {
-        BoxRec box;
-
-        /* ugh */
-        box.x1 = dst->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing);
-        box.x2 = dst->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing);
-
-        if(count > 1) {
-            if(width > 0) box.x2 += width;
-            else box.x1 += width;
-        }
-
-        box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent);
-        box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent);
-
-        TRIM_BOX(box, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-    }
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("polytext8 end\n");
-    return (width + x);
-}
-
-static void RootlessImageText16(DrawablePtr dst, GCPtr pGC,
-                                int x, int y, int count, unsigned short *chars)
-{
-    GC_SAVE (pGC);
-
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("imagetext16 start\n");
-
-    if (count > 0) {
-        int top, bot, Min, Max;
-        BoxRec box;
-
-        top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
-        bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
-
-        Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
-        if(Min > 0) Min = 0;
-        Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
-        if(Max < 0) Max = 0;
-
-        /* ugh */
-        box.x1 = dst->x + x + Min +
-            FONTMINBOUNDS(pGC->font, leftSideBearing);
-        box.x2 = dst->x + x + Max +
-            FONTMAXBOUNDS(pGC->font, rightSideBearing);
-
-        box.y1 = dst->y + y - top;
-        box.y2 = dst->y + y + bot;
-
-       RootlessStartDrawing((WindowPtr) dst);
-
-       if (can_accel_fill (dst, pGC)
-           && box_bytes (dst, &box) >= xp_fill_bytes_threshold)
-       {
-           GC_UNSET_PM (pGC, dst);
-       }
-
-       pGC->ops->ImageText16(dst, pGC, x, y, count, chars);
-
-        TRIM_BOX(box, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-
-       RootlessFinishedDrawing ((WindowPtr) dst);
-    }
-    else
-       pGC->ops->ImageText16(dst, pGC, x, y, count, chars);
-
-    GC_RESTORE (pGC, dst);
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("imagetext16 end\n");
-}
-
-static int RootlessPolyText16(DrawablePtr dst, GCPtr pGC,
-                            int x, int y, int count, unsigned short *chars)
-{
-    int width; // the result, sorta
-
-    if (GC_IS_ROOT (dst))
-       return 0;                       /* FIXME: ok? */
-
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("polytext16 start\n");
-
-    RootlessStartDrawing((WindowPtr) dst);
-    width = pGC->ops->PolyText16(dst, pGC, x, y, count, chars);
-    width -= x;
-
-    if (width > 0) {
-        BoxRec box;
-
-        /* ugh */
-        box.x1 = dst->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing);
-        box.x2 = dst->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing);
-
-        if(count > 1) {
-            if(width > 0) box.x2 += width;
-            else box.x1 += width;
-        }
-
-        box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent);
-        box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent);
-
-        TRIM_BOX(box, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-    }
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("polytext16 end\n");
-    return width + x;
-}
-
-static void RootlessImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
-                                  int x, int y, unsigned int nglyph,
-                                  CharInfoPtr *ppci, pointer unused)
-{
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("imageglyph start\n");
-
-    RootlessStartDrawing((WindowPtr) dst);
-    pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyph, ppci, unused);
-
-    if (nglyph > 0) {
-        int top, bot, width = 0;
-        BoxRec box;
-
-        top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
-        bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
-
-        box.x1 = ppci[0]->metrics.leftSideBearing;
-        if(box.x1 > 0) box.x1 = 0;
-        box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing -
-            ppci[nglyph - 1]->metrics.characterWidth;
-        if(box.x2 < 0) box.x2 = 0;
-
-        box.x2 += dst->x + x;
-        box.x1 += dst->x + x;
-
-        while(nglyph--) {
-            width += (*ppci)->metrics.characterWidth;
-            ppci++;
-        }
-
-        if(width > 0)
-            box.x2 += width;
-        else
-            box.x1 += width;
-
-        box.y1 = dst->y + y - top;
-        box.y2 = dst->y + y + bot;
-
-        TRIM_BOX(box, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-    }
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("imageglyph end\n");
-}
-
-static void RootlessPolyGlyphBlt(DrawablePtr dst, GCPtr pGC,
-                                 int x, int y, unsigned int nglyph,
-                                 CharInfoPtr *ppci, pointer pglyphBase)
-{
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("polyglyph start\n");
-
-    RootlessStartDrawing((WindowPtr) dst);
-    pGC->ops->PolyGlyphBlt(dst, pGC, x, y, nglyph, ppci, pglyphBase);
-
-    if (nglyph > 0) {
-        BoxRec box;
-
-        /* ugh */
-        box.x1 = dst->x + x + ppci[0]->metrics.leftSideBearing;
-        box.x2 = dst->x + x + ppci[nglyph - 1]->metrics.rightSideBearing;
-
-        if(nglyph > 1) {
-            int width = 0;
-
-            while(--nglyph) {
-                width += (*ppci)->metrics.characterWidth;
-                ppci++;
-            }
-
-            if(width > 0) box.x2 += width;
-            else box.x1 += width;
-        }
-
-        box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent);
-        box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent);
-
-        TRIM_BOX(box, pGC);
-        if(BOX_NOT_EMPTY(box))
-            RootlessDamageBox ((WindowPtr) dst, &box);
-    }
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("polyglyph end\n");
-}
-
-
-/* changed area is in dest */
-static void
-RootlessPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst,
-                   int dx, int dy, int xOrg, int yOrg)
-{
-    BoxRec box;
-
-    GC_SKIP_ROOT (dst);
-    GCOP_UNWRAP(pGC);
-    RL_DEBUG_MSG("push pixels start\n");
-
-    RootlessStartDrawing((WindowPtr) dst);
-    pGC->ops->PushPixels(pGC, pBitMap, dst, dx, dy, xOrg, yOrg);
-
-    box.x1 = xOrg + dst->x;
-    box.x2 = box.x1 + dx;
-    box.y1 = yOrg + dst->y;
-    box.y2 = box.y1 + dy;
-
-    TRIM_BOX(box, pGC);
-    if(BOX_NOT_EMPTY(box))
-        RootlessDamageBox ((WindowPtr) dst, &box);
-
-    RootlessFinishedDrawing ((WindowPtr) dst);
-
-    GCOP_WRAP(pGC);
-    RL_DEBUG_MSG("push pixels end\n");
-}