]> git.sesse.net Git - rdpsrv/blobdiff - Xserver/programs/Xserver/hw/vnc/draw.c
Removed Xserver/ directory, it does nothing useful ATM.
[rdpsrv] / Xserver / programs / Xserver / hw / vnc / draw.c
diff --git a/Xserver/programs/Xserver/hw/vnc/draw.c b/Xserver/programs/Xserver/hw/vnc/draw.c
deleted file mode 100644 (file)
index 599e313..0000000
+++ /dev/null
@@ -1,1998 +0,0 @@
-/*
- * draw.c - drawing routines for the RFB X server.  This is a set of
- * wrappers around the standard MI/MFB/CFB drawing routines which work out
- * to a fair approximation the region of the screen being modified by the
- * drawing.  If the RFB client is ready then the modified region of the screen
- * is sent to the client, otherwise the modified region will simply grow with
- * each drawing request until the client is ready.
- */
-
-/*
- *  Copyright (C) 2002-2003 RealVNC Ltd.
- *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
- *
- *  This is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This software is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this software; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- *  USA.
- */
-
-/*
-
-Copyright (c) 1989  X Consortium
-
-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
-X CONSORTIUM 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 X Consortium 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 X Consortium.
-*/
-
-#include <stdio.h>
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "windowstr.h"
-#include "regionstr.h"
-#include "dixfontstr.h"
-#include "rfb.h"
-#include "mfb.h"
-
-extern WindowPtr *WindowTable; /* Why isn't this in a header file? */
-
-int rfbDeferUpdateTime = 40; /* ms */
-
-/* MAX_RECTS_PER_OP is the maximum number of rectangles we generate from
-   operations like Polylines and PolySegment.  If the operation is more complex
-   than this, we simply use the bounding box.  Ideally it would be a
-   command-line option, but that would involve an extra malloc each time, so we
-   fix it here. */
-#define MAX_RECTS_PER_OP 5
-
-
-/****************************************************************************/
-/*
- * Macro definitions
- */
-/****************************************************************************/
-
-/* SLIGHTLY DIRTY HACK - use Composite Clip region calculated by mfb */
-
-#define WINDOW_CLIP_REGION(_w, _gc) \
-  (((mfbPrivGCPtr)((_gc)->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip)
-
-#define TRC(x) if (rfbTrace) rfbLog x
-
-/* ADD_TO_MODIFIED_REGION adds the given region to the modified region for each
-   client */
-
-#define ADD_TO_MODIFIED_REGION(pScreen,reg)                                   \
-  {                                                                           \
-      rfbClientPtr cl;                                                        \
-      for (cl = rfbClientHead; cl; cl = cl->next) {                           \
-          if (REGION_NUM_RECTS(&cl->modifiedRegion) > rfbMaxRects) {          \
-              BoxRec boundingBox = *(REGION_EXTENTS((pScreen),                \
-                                                    &cl->modifiedRegion));    \
-              REGION_RESET((pScreen), &cl->modifiedRegion, &boundingBox);     \
-          }                                                                   \
-                                                                              \
-         REGION_UNION((pScreen),&cl->modifiedRegion,&cl->modifiedRegion,reg);\
-      }                                                                       \
-  }
-
-/* SCHEDULE_FB_UPDATE is used at the end of each drawing routine to schedule an
-   update to be sent to each client if there is one pending and the client is
-   ready for it.  */
-
-#define SCHEDULE_FB_UPDATE(pScreen,prfb)                               \
-  if (!prfb->dontSendFramebufferUpdate) {                              \
-      rfbClientPtr cl, nextCl;                                         \
-      for (cl = rfbClientHead; cl; cl = nextCl) {                      \
-         nextCl = cl->next;                                            \
-         if (!cl->deferredUpdateScheduled && FB_UPDATE_PENDING(cl) &&  \
-             REGION_NOTEMPTY(pScreen,&cl->requestedRegion))            \
-         {                                                             \
-             rfbScheduleDeferredUpdate(cl);                            \
-         }                                                             \
-      }                                                                        \
-  }
-
-/* function prototypes */
-
-static void rfbCopyRegion(ScreenPtr pScreen, rfbClientPtr cl,
-                         RegionPtr src, RegionPtr dst, int dx, int dy);
-
-/* GC funcs */
-
-static void rfbValidateGC(GCPtr, unsigned long /*changes*/, DrawablePtr);
-static void rfbChangeGC(GCPtr, unsigned long /*mask*/);
-static void rfbCopyGC(GCPtr /*src*/, unsigned long /*mask*/, GCPtr /*dst*/);
-static void rfbDestroyGC(GCPtr);
-static void rfbChangeClip(GCPtr, int /*type*/, pointer /*pValue*/,
-                         int /*nrects*/);
-static void rfbDestroyClip(GCPtr);
-static void rfbCopyClip(GCPtr /*dst*/, GCPtr /*src*/);
-
-/* GC ops */
-
-static void rfbFillSpans();
-static void rfbSetSpans();
-static void rfbPutImage();
-static RegionPtr rfbCopyArea();
-static RegionPtr rfbCopyPlane();
-static void rfbPolyPoint();
-static void rfbPolylines();
-static void rfbPolySegment();
-static void rfbPolyRectangle();
-static void rfbPolyArc();
-static void rfbFillPolygon();
-static void rfbPolyFillRect();
-static void rfbPolyFillArc();
-static int rfbPolyText8();
-static int rfbPolyText16();
-static void rfbImageText8();
-static void rfbImageText16();
-static void rfbImageGlyphBlt();
-static void rfbPolyGlyphBlt();
-static void rfbPushPixels();
-
-
-static GCFuncs rfbGCFuncs = {
-    rfbValidateGC,
-    rfbChangeGC,
-    rfbCopyGC,
-    rfbDestroyGC,
-    rfbChangeClip,
-    rfbDestroyClip,
-    rfbCopyClip,
-};
-
-
-static GCOps rfbGCOps = {
-    rfbFillSpans,      rfbSetSpans,    rfbPutImage,    
-    rfbCopyArea,       rfbCopyPlane,   rfbPolyPoint,
-    rfbPolylines,      rfbPolySegment, rfbPolyRectangle,
-    rfbPolyArc,                rfbFillPolygon, rfbPolyFillRect,
-    rfbPolyFillArc,    rfbPolyText8,   rfbPolyText16,
-    rfbImageText8,     rfbImageText16, rfbImageGlyphBlt,
-    rfbPolyGlyphBlt,   rfbPushPixels
-};
-
-
-
-/****************************************************************************/
-/*
- * Screen functions wrapper stuff
- */
-/****************************************************************************/
-
-#define SCREEN_PROLOGUE(scrn, field)           \
-    ScreenPtr pScreen = scrn;                  \
-    rfbScreenInfoPtr prfb = &rfbScreen;                \
-    pScreen->field = prfb->field;
-
-#define SCREEN_EPILOGUE(field, wrapper) \
-    pScreen->field = wrapper;
-
-
-/*
- * CloseScreen wrapper -- unwrap everything, free the private data
- * and call the wrapped CloseScreen function.
- */
-
-Bool
-rfbCloseScreen (i, pScreen)
-    int i;
-    ScreenPtr  pScreen;
-{
-    rfbScreenInfoPtr prfb = &rfbScreen;
-
-    pScreen->CloseScreen = prfb->CloseScreen;
-    pScreen->CreateGC = prfb->CreateGC;
-    pScreen->PaintWindowBackground = prfb->PaintWindowBackground;
-    pScreen->PaintWindowBorder = prfb->PaintWindowBorder;
-    pScreen->CopyWindow = prfb->CopyWindow;
-    pScreen->ClearToBackground = prfb->ClearToBackground;
-    pScreen->RestoreAreas = prfb->RestoreAreas;
-
-    TRC(("Unwrapped screen functions\n"));
-
-    return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-/*
- * CreateGC - wrap the GC funcs (the GC ops will be wrapped when the GC
- * func "ValidateGC" is called).
- */
-
-Bool
-rfbCreateGC (pGC)
-    GCPtr   pGC;
-{
-    Bool ret;
-    rfbGCPtr pGCPriv;
-
-    SCREEN_PROLOGUE(pGC->pScreen,CreateGC);
-    
-    pGCPriv = (rfbGCPtr)pGC->devPrivates[rfbGCIndex].ptr;
-
-    ret = (*pScreen->CreateGC) (pGC);
-
-    TRC(("rfbCreateGC called\n"));
-
-    pGCPriv->wrapOps = NULL;
-    pGCPriv->wrapFuncs = pGC->funcs;
-    pGC->funcs = &rfbGCFuncs;
-
-    SCREEN_EPILOGUE(CreateGC,rfbCreateGC);
-
-    return ret;
-}
-
-/*
- * PaintWindowBackground - the region being modified is just the given region.
- */
-
-void
-rfbPaintWindowBackground (pWin, pRegion, what)
-    WindowPtr  pWin;
-    RegionPtr  pRegion;
-    int                what;
-{
-    SCREEN_PROLOGUE(pWin->drawable.pScreen,PaintWindowBackground);
-
-    TRC(("rfbPaintWindowBackground called\n"));
-
-    ADD_TO_MODIFIED_REGION(pScreen,pRegion);
-
-    (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
-
-    SCHEDULE_FB_UPDATE(pScreen, prfb);
-
-    SCREEN_EPILOGUE(PaintWindowBackground,rfbPaintWindowBackground);
-}
-
-/*
- * PaintWindowBorder - the region being modified is just the given region.
- */
-
-void
-rfbPaintWindowBorder (pWin, pRegion, what)
-    WindowPtr  pWin;
-    RegionPtr  pRegion;
-    int                what;
-{
-    SCREEN_PROLOGUE(pWin->drawable.pScreen,PaintWindowBorder);
-
-    TRC(("rfbPaintWindowBorder called\n"));
-
-    ADD_TO_MODIFIED_REGION(pScreen,pRegion);
-
-    (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
-
-    SCHEDULE_FB_UPDATE(pScreen, prfb);
-
-    SCREEN_EPILOGUE(PaintWindowBorder,rfbPaintWindowBorder);
-}
-
-/*
- * CopyWindow - the region being modified is the translation of the old
- * region, clipped to the border clip region of the window.  Note that any
- * parts of the window which have become newly-visible will not be affected by
- * this call - a separate PaintWindowBackground/Border will be called to do
- * that.  If the client will accept CopyRect messages then use rfbCopyRegion to
- * optimise the pending screen changes into a single "copy region" plus the
- * ordinary modified region.
- */
-
-void
-rfbCopyWindow (pWin, ptOldOrg, pOldRegion)
-    WindowPtr  pWin;
-    DDXPointRec        ptOldOrg;
-    RegionPtr  pOldRegion;
-{
-    rfbClientPtr cl;
-    RegionRec srcRegion, dstRegion;
-    SCREEN_PROLOGUE(pWin->drawable.pScreen,CopyWindow);
-
-    TRC(("rfbCopyWindow called\n"));
-
-    REGION_INIT(pScreen,&dstRegion,NullBox,0);
-    REGION_COPY(pScreen,&dstRegion,pOldRegion);
-    REGION_TRANSLATE(pWin->drawable.pScreen, &dstRegion,
-                    pWin->drawable.x - ptOldOrg.x,
-                    pWin->drawable.y - ptOldOrg.y);
-    REGION_INTERSECT(pWin->drawable.pScreen, &dstRegion, &dstRegion,
-                    &pWin->borderClip);
-
-    for (cl = rfbClientHead; cl; cl = cl->next) {
-       if (cl->useCopyRect) {
-           REGION_INIT(pScreen,&srcRegion,NullBox,0);
-           REGION_COPY(pScreen,&srcRegion,pOldRegion);
-
-           rfbCopyRegion(pScreen, cl, &srcRegion, &dstRegion,
-                         pWin->drawable.x - ptOldOrg.x,
-                         pWin->drawable.y - ptOldOrg.y);
-
-           REGION_UNINIT(pSrc->pScreen, &srcRegion);
-
-       } else {
-
-           REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
-                        &dstRegion);
-       }
-    }
-
-    REGION_UNINIT(pSrc->pScreen, &dstRegion);
-
-    (*pScreen->CopyWindow) (pWin, ptOldOrg, pOldRegion);
-
-    SCHEDULE_FB_UPDATE(pScreen, prfb);
-
-    SCREEN_EPILOGUE(CopyWindow,rfbCopyWindow);
-}
-
-/*
- * ClearToBackground - when generateExposures is false, the region being
- * modified is the given rectangle (clipped to the "window clip region").
- */
-
-void
-rfbClearToBackground (pWin, x, y, w, h, generateExposures)
-    WindowPtr pWin;
-    int x,y,w,h;
-    Bool generateExposures;
-{
-    RegionRec tmpRegion;
-    BoxRec box;
-    SCREEN_PROLOGUE(pWin->drawable.pScreen,ClearToBackground);
-
-    TRC(("rfbClearToBackground called\n"));
-
-    if (!generateExposures) {
-       box.x1 = x + pWin->drawable.x;
-       box.y1 = y + pWin->drawable.y;
-       box.x2 = w ? (box.x1 + w) : (pWin->drawable.x + pWin->drawable.width);
-       box.y2 = h ? (box.y1 + h) : (pWin->drawable.y + pWin->drawable.height);
-
-       SAFE_REGION_INIT(pScreen, &tmpRegion, &box, 0);
-
-       REGION_INTERSECT(pScreen, &tmpRegion, &tmpRegion, &pWin->clipList);
-
-       ADD_TO_MODIFIED_REGION(pScreen, &tmpRegion);
-
-       REGION_UNINIT(pScreen, &tmpRegion);
-    }
-
-    (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
-
-    if (!generateExposures) {
-       SCHEDULE_FB_UPDATE(pScreen, prfb);
-    }
-
-    SCREEN_EPILOGUE(ClearToBackground,rfbClearToBackground);
-}
-
-/*
- * RestoreAreas - just be safe here - the region being modified is the whole
- * exposed region.
- */
-
-RegionPtr
-rfbRestoreAreas (pWin, prgnExposed)
-    WindowPtr  pWin;
-    RegionPtr  prgnExposed;
-{
-    RegionPtr result;
-    SCREEN_PROLOGUE(pWin->drawable.pScreen,RestoreAreas);
-
-    TRC(("rfbRestoreAreas called\n"));
-
-    ADD_TO_MODIFIED_REGION(pScreen, prgnExposed);
-
-    result = (*pScreen->RestoreAreas) (pWin, prgnExposed);
-
-    SCHEDULE_FB_UPDATE(pScreen, prfb);
-
-    SCREEN_EPILOGUE(RestoreAreas,rfbRestoreAreas);
-
-    return result;
-}
-
-
-
-/****************************************************************************/
-/*
- * GC funcs wrapper stuff
- *
- * We only really want to wrap the GC ops, but to do this we need to wrap
- * ValidateGC and so all the other GC funcs must be wrapped as well.
- */
-/****************************************************************************/
-
-#define GC_FUNC_PROLOGUE(pGC)                                          \
-    rfbGCPtr pGCPriv = (rfbGCPtr) (pGC)->devPrivates[rfbGCIndex].ptr;  \
-    (pGC)->funcs = pGCPriv->wrapFuncs;                                 \
-    if (pGCPriv->wrapOps)                                              \
-       (pGC)->ops = pGCPriv->wrapOps;
-
-#define GC_FUNC_EPILOGUE(pGC)          \
-    pGCPriv->wrapFuncs = (pGC)->funcs; \
-    (pGC)->funcs = &rfbGCFuncs;                \
-    if (pGCPriv->wrapOps) {            \
-       pGCPriv->wrapOps = (pGC)->ops;  \
-       (pGC)->ops = &rfbGCOps;         \
-    }
-
-
-/*
- * ValidateGC - call the wrapped ValidateGC, then wrap the resulting GC ops if
- * the drawing will be to a viewable window.
- */
-
-static void
-rfbValidateGC (pGC, changes, pDrawable)
-    GCPtr      pGC;
-    unsigned long changes;
-    DrawablePtr        pDrawable;
-{
-    GC_FUNC_PROLOGUE(pGC);
-
-    TRC(("rfbValidateGC called\n"));
-
-    (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
-    
-    pGCPriv->wrapOps = NULL;
-    if (pDrawable->type == DRAWABLE_WINDOW && ((WindowPtr)pDrawable)->viewable)
-    {
-       WindowPtr   pWin = (WindowPtr) pDrawable;
-       RegionPtr   pRegion = &pWin->clipList;
-
-       if (pGC->subWindowMode == IncludeInferiors)
-           pRegion = &pWin->borderClip;
-       if (REGION_NOTEMPTY(pDrawable->pScreen, pRegion)) {
-           pGCPriv->wrapOps = pGC->ops;
-           TRC(("rfbValidateGC: wrapped GC ops\n"));
-       }
-    }
-
-    GC_FUNC_EPILOGUE(pGC);
-}
-
-/*
- * All other GC funcs simply unwrap the GC funcs and ops, call the wrapped
- * function and then rewrap the funcs and ops.
- */
-
-static void
-rfbChangeGC (pGC, mask)
-    GCPtr          pGC;
-    unsigned long   mask;
-{
-    GC_FUNC_PROLOGUE(pGC);
-    (*pGC->funcs->ChangeGC) (pGC, mask);
-    GC_FUNC_EPILOGUE(pGC);
-}
-
-static void
-rfbCopyGC (pGCSrc, mask, pGCDst)
-    GCPtr          pGCSrc, pGCDst;
-    unsigned long   mask;
-{
-    GC_FUNC_PROLOGUE(pGCDst);
-    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-    GC_FUNC_EPILOGUE(pGCDst);
-}
-
-static void
-rfbDestroyGC (pGC)
-    GCPtr   pGC;
-{
-    GC_FUNC_PROLOGUE(pGC);
-    (*pGC->funcs->DestroyGC) (pGC);
-    GC_FUNC_EPILOGUE(pGC);
-}
-
-static void
-rfbChangeClip (pGC, type, pvalue, nrects)
-    GCPtr   pGC;
-    int                type;
-    pointer    pvalue;
-    int                nrects;
-{
-    GC_FUNC_PROLOGUE(pGC);
-    (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
-    GC_FUNC_EPILOGUE(pGC);
-}
-
-static void
-rfbDestroyClip(pGC)
-    GCPtr      pGC;
-{
-    GC_FUNC_PROLOGUE(pGC);
-    (* pGC->funcs->DestroyClip)(pGC);
-    GC_FUNC_EPILOGUE(pGC);
-}
-
-static void
-rfbCopyClip(pgcDst, pgcSrc)
-    GCPtr pgcDst, pgcSrc;
-{
-    GC_FUNC_PROLOGUE(pgcDst);
-    (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
-    GC_FUNC_EPILOGUE(pgcDst);
-}
-
-
-/****************************************************************************/
-/*
- * GC ops wrapper stuff
- *
- * Note that these routines will only have been wrapped for drawing to
- * viewable windows so we don't need to check each time that the drawable
- * is a viewable window.
- */
-/****************************************************************************/
-
-#define GC_OP_PROLOGUE(pDrawable,pGC) \
-    rfbScreenInfoPtr prfb = &rfbScreen; \
-    rfbGCPtr pGCPrivate = (rfbGCPtr) (pGC)->devPrivates[rfbGCIndex].ptr; \
-    GCFuncs *oldFuncs = pGC->funcs; \
-    (pGC)->funcs = pGCPrivate->wrapFuncs; \
-    (pGC)->ops = pGCPrivate->wrapOps;
-
-#define GC_OP_EPILOGUE(pGC) \
-    pGCPrivate->wrapOps = (pGC)->ops; \
-    (pGC)->funcs = oldFuncs; \
-    (pGC)->ops = &rfbGCOps;
-
-
-/*
- * FillSpans - being very safe - the region being modified is the border clip
- * region of the window.
- */
-
-static void
-rfbFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
-    DrawablePtr pDrawable;
-    GCPtr      pGC;
-    int                nInit;                  /* number of spans to fill */
-    DDXPointPtr pptInit;               /* pointer to list of start points */
-    int                *pwidthInit;            /* pointer to list of n widths */
-    int        fSorted;
-{
-    GC_OP_PROLOGUE(pDrawable,pGC);
-
-    TRC(("rfbFillSpans called\n"));
-
-    ADD_TO_MODIFIED_REGION(pDrawable->pScreen,
-                          &((WindowPtr)pDrawable)->borderClip);
-
-    (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit,pwidthInit,fSorted);
-
-    SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * SetSpans - being very safe - the region being modified is the border clip
- * region of the window.
- */
-
-static void
-rfbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted)
-    DrawablePtr                pDrawable;
-    GCPtr              pGC;
-    char               *psrc;
-    register DDXPointPtr ppt;
-    int                        *pwidth;
-    int                        nspans;
-    int                        fSorted;
-{
-    GC_OP_PROLOGUE(pDrawable,pGC);
-
-    TRC(("rfbSetSpans called\n"));
-
-    ADD_TO_MODIFIED_REGION(pDrawable->pScreen,
-                          &((WindowPtr)pDrawable)->borderClip);
-
-    (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
-
-    SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * PutImage - the region being modified is the rectangle of the
- * PutImage (clipped to the window clip region).
- */
-
-static void
-rfbPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits)
-    DrawablePtr          pDrawable;
-    GCPtr        pGC;
-    int                  depth;
-    int                  x;
-    int                  y;
-    int                  w;
-    int                  h;
-    int                  leftPad;
-    int                  format;
-    char         *pBits;
-{
-    RegionRec tmpRegion;
-    BoxRec box;
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbPutImage called\n"));
-
-    box.x1 = x + pDrawable->x;
-    box.y1 = y + pDrawable->y;
-    box.x2 = box.x1 + w;
-    box.y2 = box.y1 + h;
-
-    SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
-
-    REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
-                    WINDOW_CLIP_REGION((WindowPtr)pDrawable,pGC));
-
-    ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
-
-    REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
-
-    (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h,
-                          leftPad, format, pBits);
-
-    SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * CopyArea - the region being modified is the destination rectangle (clipped
- * to the window clip region).
- * If the client will accept CopyRect messages then use rfbCopyRegion
- * to optimise the pending screen changes into a single "copy region" plus
- * the ordinary modified region.
- */
-
-static RegionPtr
-rfbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty)
-    DrawablePtr          pSrc;
-    DrawablePtr          pDst;
-    GCPtr        pGC;
-    int                  srcx;
-    int                  srcy;
-    int                  w;
-    int                  h;
-    int                  dstx;
-    int                  dsty;
-{
-    rfbClientPtr cl;
-    RegionPtr rgn;
-    RegionRec srcRegion, dstRegion;
-    BoxRec box;
-    GC_OP_PROLOGUE(pDst, pGC);
-
-    TRC(("rfbCopyArea called\n"));
-
-    box.x1 = dstx + pDst->x;
-    box.y1 = dsty + pDst->y;
-    box.x2 = box.x1 + w;
-    box.y2 = box.y1 + h;
-
-    SAFE_REGION_INIT(pDst->pScreen, &dstRegion, &box, 0);
-    REGION_INTERSECT(pDst->pScreen, &dstRegion, &dstRegion,
-                    WINDOW_CLIP_REGION((WindowPtr)pDst,pGC));
-
-    if ((pSrc->type == DRAWABLE_WINDOW) && (pSrc->pScreen == pDst->pScreen)) {
-       box.x1 = srcx + pSrc->x;
-       box.y1 = srcy + pSrc->y;
-       box.x2 = box.x1 + w;
-       box.y2 = box.y1 + h;
-
-       for (cl = rfbClientHead; cl; cl = cl->next) {
-           if (cl->useCopyRect) {
-               SAFE_REGION_INIT(pSrc->pScreen, &srcRegion, &box, 0);
-               REGION_INTERSECT(pSrc->pScreen, &srcRegion, &srcRegion,
-                                &((WindowPtr)pSrc)->clipList);
-
-               rfbCopyRegion(pSrc->pScreen, cl, &srcRegion, &dstRegion,
-                             dstx + pDst->x - srcx - pSrc->x,
-                             dsty + pDst->y - srcy - pSrc->y);
-
-               REGION_UNINIT(pSrc->pScreen, &srcRegion);
-
-           } else {
-
-               REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
-                            &dstRegion);
-           }
-       }
-
-    } else {
-
-       ADD_TO_MODIFIED_REGION(pDst->pScreen, &dstRegion);
-    }
-
-    REGION_UNINIT(pDst->pScreen, &dstRegion);
-
-    rgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h,
-                                dstx, dsty);
-
-    SCHEDULE_FB_UPDATE(pDst->pScreen, prfb);
-
-    GC_OP_EPILOGUE(pGC);
-
-    return rgn;
-}
-
-
-/*
- * CopyPlane - the region being modified is the destination rectangle (clipped
- * to the window clip region).
- */
-
-static RegionPtr
-rfbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
-    DrawablePtr          pSrc;
-    DrawablePtr          pDst;
-    register GCPtr pGC;
-    int          srcx,
-                 srcy;
-    int          w,
-                 h;
-    int          dstx,
-                 dsty;
-    unsigned long  plane;
-{
-    RegionPtr rgn;
-    RegionRec tmpRegion;
-    BoxRec box;
-    GC_OP_PROLOGUE(pDst, pGC);
-
-    TRC(("rfbCopyPlane called\n"));
-
-    box.x1 = dstx + pDst->x;
-    box.y1 = dsty + pDst->y;
-    box.x2 = box.x1 + w;
-    box.y2 = box.y1 + h;
-
-    SAFE_REGION_INIT(pDst->pScreen, &tmpRegion, &box, 0);
-
-    REGION_INTERSECT(pDst->pScreen, &tmpRegion, &tmpRegion,
-                    WINDOW_CLIP_REGION((WindowPtr)pDst,pGC));
-
-    ADD_TO_MODIFIED_REGION(pDst->pScreen, &tmpRegion);
-
-    REGION_UNINIT(pDst->pScreen, &tmpRegion);
-
-    rgn = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
-                                 dstx, dsty, plane);
-
-    SCHEDULE_FB_UPDATE(pDst->pScreen, prfb);
-
-    GC_OP_EPILOGUE(pGC);
-
-    return rgn;
-}
-
-/*
- * PolyPoint - find the smallest rectangle which encloses the points drawn
- * (and clip).
- */
-
-static void
-rfbPolyPoint (pDrawable, pGC, mode, npt, pts)
-    DrawablePtr pDrawable;
-    GCPtr      pGC;
-    int                mode;           /* Origin or Previous */
-    int                npt;
-    xPoint     *pts;
-{
-    int i;
-    RegionRec tmpRegion;
-    BoxRec box;
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbPolyPoint called: %d points\n",npt));
-
-    if (npt) {
-       int minX = pts[0].x, maxX = pts[0].x;
-       int minY = pts[0].y, maxY = pts[0].y;
-
-       if (mode == CoordModePrevious)
-       {
-           int x = pts[0].x, y = pts[0].y;
-
-           for (i = 1; i < npt; i++) {
-               x += pts[i].x;
-               y += pts[i].y;
-               if (x < minX) minX = x;
-               if (x > maxX) maxX = x;
-               if (y < minY) minY = y;
-               if (y > maxY) maxY = y;
-           }
-       }
-       else
-       {
-           for (i = 1; i < npt; i++) {
-               if (pts[i].x < minX) minX = pts[i].x;
-               if (pts[i].x > maxX) maxX = pts[i].x;
-               if (pts[i].y < minY) minY = pts[i].y;
-               if (pts[i].y > maxY) maxY = pts[i].y;
-           }
-       }
-
-       box.x1 = minX + pDrawable->x;
-       box.y1 = minY + pDrawable->y;
-       box.x2 = maxX + 1 + pDrawable->x;
-       box.y2 = maxY + 1 + pDrawable->y;
-
-       SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
-
-       REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
-                        WINDOW_CLIP_REGION(((WindowPtr)pDrawable),pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
-
-       REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
-    }
-
-    (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pts);
-
-    if (npt) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * PolyLines - take the union of bounding boxes around each line (and clip).
- */
-
-static void
-rfbPolylines (pDrawable, pGC, mode, npt, ppts)
-    DrawablePtr          pDrawable;
-    GCPtr        pGC;
-    int                  mode;
-    int                  npt;
-    DDXPointPtr          ppts;
-{
-    RegionPtr tmpRegion;
-    xRectangle regRects[MAX_RECTS_PER_OP];
-    int i, extra, nregRects, lw;
-    int prevX, prevY, curX, curY;
-    int rectX1, rectY1, rectX2, rectY2;
-    int minX, minY, maxX, maxY;
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbPolylines called: %d points\n",npt));
-
-    if (npt) {
-       lw = pGC->lineWidth;
-       if (lw == 0)
-           lw = 1;
-
-       if (npt == 1)
-       {
-           nregRects = 1;
-           regRects[0].x = ppts[0].x - lw + pDrawable->x; /* being safe */
-           regRects[0].y = ppts[0].y - lw + pDrawable->y;
-           regRects[0].width = 2*lw;
-           regRects[0].height = 2*lw;
-       }
-       else
-       {
-           nregRects = npt - 1;
-
-           /*
-            * mitered joins can project quite a way from
-            * the line end; the 11 degree miter limit limits
-            * this extension to lw / (2 * tan(11/2)), rounded up
-            * and converted to int yields 6 * lw
-            */
-
-           if (pGC->joinStyle == JoinMiter) {
-               extra = 6 * lw;
-           } else {
-               extra = lw / 2;
-           }
-
-           prevX = ppts[0].x + pDrawable->x;
-           prevY = ppts[0].y + pDrawable->y;
-            minX = maxX = prevX;
-            minY = maxY = prevY;
-
-           for (i = 0; i < nregRects; i++) {
-               if (mode == CoordModeOrigin) {
-                   curX = pDrawable->x + ppts[i+1].x;
-                   curY = pDrawable->y + ppts[i+1].y;
-               } else {
-                   curX = prevX + ppts[i+1].x;
-                   curY = prevY + ppts[i+1].y;
-               }
-
-               if (prevX > curX) {
-                    rectX1 = curX - extra;
-                    rectX2 = prevX + extra + 1;
-               } else {
-                    rectX1 = prevX - extra;
-                    rectX2 = curX + extra + 1;
-               }
-
-               if (prevY > curY) {
-                    rectY1 = curY - extra;
-                    rectY2 = prevY + extra + 1;
-               } else {
-                    rectY1 = prevY - extra;
-                    rectY2 = curY + extra + 1;
-               }
-
-                if (nregRects <= MAX_RECTS_PER_OP) {
-                   regRects[i].x = rectX1;
-                   regRects[i].y = rectY1;
-                   regRects[i].width = rectX2 - rectX1;
-                   regRects[i].height = rectY2 - rectY1;
-                } else {
-                    if (rectX1 < minX) minX = rectX1;
-                    if (rectY1 < minY) minY = rectY1;
-                    if (rectX2 > maxX) maxX = rectX2;
-                    if (rectY2 > maxY) maxY = rectY2;
-                }
-
-               prevX = curX;
-               prevY = curY;
-           }
-
-            if (nregRects > MAX_RECTS_PER_OP) {
-                regRects[0].x = minX;
-                regRects[0].y = minY;
-                regRects[0].width = maxX - minX;
-                regRects[0].height = maxY - minY;
-                nregRects = 1;
-            }
-       }
-
-       tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nregRects, regRects,
-                                    CT_NONE);
-       REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion,
-                        WINDOW_CLIP_REGION((WindowPtr)pDrawable,pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion);
-
-       REGION_DESTROY(pDrawable->pScreen, tmpRegion);
-    }
-
-    (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppts);
-
-    if (npt) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * PolySegment - take the union of bounding boxes around each segment (and
- * clip).
- */
-
-static void
-rfbPolySegment(pDrawable, pGC, nseg, segs)
-    DrawablePtr pDrawable;
-    GCPtr      pGC;
-    int                nseg;
-    xSegment   *segs;
-{
-    RegionPtr tmpRegion;
-    xRectangle regRects[MAX_RECTS_PER_OP];
-    int i, extra, lw, nregRects;
-    int rectX1, rectY1, rectX2, rectY2;
-    int minX, minY, maxX, maxY;
-
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbPolySegment called: %d segments\n",nseg));
-
-    if (nseg) {
-        nregRects = nseg;
-       lw = pGC->lineWidth;
-       extra = lw / 2;
-
-        minX = maxX = segs[0].x1;
-        minY = maxY = segs[0].y1;
-
-       for (i = 0; i < nseg; i++)
-       {
-           if (segs[i].x1 > segs[i].x2) {
-                rectX1 = pDrawable->x + segs[i].x2 - extra;
-                rectX2 = pDrawable->x + segs[i].x1 + extra + 1;
-           } else {
-                rectX1 = pDrawable->x + segs[i].x1 - extra;
-                rectX2 = pDrawable->x + segs[i].x2 + extra + 1;
-           }
-
-           if (segs[i].y1 > segs[i].y2) {
-                rectY1 = pDrawable->y + segs[i].y2 - extra;
-                rectY2 = pDrawable->y + segs[i].y1 + extra + 1;
-           } else {
-                rectY1 = pDrawable->y + segs[i].y1 - extra;
-                rectY2 = pDrawable->y + segs[i].y2 + extra + 1;
-           }
-
-            if (nseg <= MAX_RECTS_PER_OP) {
-                regRects[i].x = rectX1;
-                regRects[i].y = rectY1;
-                regRects[i].width = rectX2 - rectX1;
-                regRects[i].height = rectY2 - rectY1;
-            } else {
-                if (rectX1 < minX) minX = rectX1;
-                if (rectY1 < minY) minY = rectY1;
-                if (rectX2 > maxX) maxX = rectX2;
-                if (rectY2 > maxY) maxY = rectY2;
-            }
-       }
-
-        if (nseg > MAX_RECTS_PER_OP) {
-            regRects[0].x = minX;
-            regRects[0].y = minY;
-            regRects[0].width = maxX - minX;
-            regRects[0].height = maxY - minY;
-            nregRects = 1;
-        }
-
-       tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nregRects, regRects,
-                                    CT_NONE);
-       REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion,
-                        WINDOW_CLIP_REGION((WindowPtr)pDrawable,pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion);
-
-       REGION_DESTROY(pDrawable->pScreen, tmpRegion);
-    }
-
-    (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, segs);
-
-    if (nseg) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * PolyRectangle (rectangle outlines) - take the union of bounding boxes
- * around each line (and clip).
- */
-
-static void
-rfbPolyRectangle(pDrawable, pGC, nrects, rects)
-    DrawablePtr        pDrawable;
-    GCPtr      pGC;
-    int                nrects;
-    xRectangle *rects;
-{
-    int i, extra, lw, nregRects;
-    int rectX1, rectY1, rectX2, rectY2;
-    int minX, minY, maxX, maxY;
-    RegionPtr tmpRegion;
-    xRectangle regRects[MAX_RECTS_PER_OP*4];
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbPolyRectangle called: %d rects\n",nrects));
-
-    if (nrects) {
-        nregRects = nrects * 4;
-       lw = pGC->lineWidth;
-       extra = lw / 2;
-
-        minX = maxX = rects[0].x;
-        minY = maxY = rects[0].y;
-
-       for (i = 0; i < nrects; i++)
-       {
-            if (nrects <= MAX_RECTS_PER_OP) {
-                regRects[i*4].x = rects[i].x - extra + pDrawable->x;
-                regRects[i*4].y = rects[i].y - extra + pDrawable->y;
-                regRects[i*4].width = rects[i].width + 1 + 2 * extra;
-                regRects[i*4].height = 1 + 2 * extra;
-
-                regRects[i*4+1].x = rects[i].x - extra + pDrawable->x;
-                regRects[i*4+1].y = rects[i].y - extra + pDrawable->y;
-                regRects[i*4+1].width = 1 + 2 * extra;
-                regRects[i*4+1].height = rects[i].height + 1 + 2 * extra;
-
-                regRects[i*4+2].x
-                    = rects[i].x + rects[i].width - extra + pDrawable->x;
-                regRects[i*4+2].y = rects[i].y - extra + pDrawable->y;
-                regRects[i*4+2].width = 1 + 2 * extra;
-                regRects[i*4+2].height = rects[i].height + 1 + 2 * extra;
-
-                regRects[i*4+3].x = rects[i].x - extra + pDrawable->x;
-                regRects[i*4+3].y
-                    = rects[i].y + rects[i].height - extra + pDrawable->y;
-                regRects[i*4+3].width = rects[i].width + 1 + 2 * extra;
-                regRects[i*4+3].height = 1 + 2 * extra;
-            } else {
-                rectX1 = pDrawable->x + rects[i].x - extra;
-                rectY1 = pDrawable->y + rects[i].y - extra;
-                rectX2 = pDrawable->x + rects[i].x + rects[i].width + extra+1;
-                rectY2 = pDrawable->y + rects[i].y + rects[i].height + extra+1;
-                if (rectX1 < minX) minX = rectX1;
-                if (rectY1 < minY) minY = rectY1;
-                if (rectX2 > maxX) maxX = rectX2;
-                if (rectY2 > maxY) maxY = rectY2;
-            }
-       }
-
-        if (nrects > MAX_RECTS_PER_OP) {
-            regRects[0].x = minX;
-            regRects[0].y = minY;
-            regRects[0].width = maxX - minX;
-            regRects[0].height = maxY - minY;
-            nregRects = 1;
-        }
-
-       tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nregRects,
-                                   regRects, CT_NONE);
-       REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion,
-                        WINDOW_CLIP_REGION((WindowPtr)pDrawable,pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion);
-
-       REGION_DESTROY(pDrawable->pScreen, tmpRegion);
-    }
-
-    (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, rects);
-
-    if (nrects) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * PolyArc - take the union of bounding boxes around each arc (and clip).
- * Bounding boxes assume each is a full circle / ellipse.
- */
-
-static void
-rfbPolyArc(pDrawable, pGC, narcs, arcs)
-    DrawablePtr        pDrawable;
-    register GCPtr     pGC;
-    int                narcs;
-    xArc       *arcs;
-{
-    int i, extra, lw, nregRects;
-    int rectX1, rectY1, rectX2, rectY2;
-    int minX, minY, maxX, maxY;
-    RegionPtr tmpRegion;
-    xRectangle regRects[MAX_RECTS_PER_OP];
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbPolyArc called: %d arcs\n",narcs));
-
-    if (narcs) {
-        nregRects = narcs;
-       lw = pGC->lineWidth;
-       if (lw == 0)
-           lw = 1;
-       extra = lw / 2;
-
-        minX = maxX = arcs[0].x;
-        minY = maxY = arcs[0].y;
-
-       for (i = 0; i < narcs; i++)
-       {
-            if (narcs <= MAX_RECTS_PER_OP) {
-                regRects[i].x = arcs[i].x - extra + pDrawable->x;
-                regRects[i].y = arcs[i].y - extra + pDrawable->y;
-                regRects[i].width = arcs[i].width + lw;
-                regRects[i].height = arcs[i].height + lw;
-            } else {
-                rectX1 = pDrawable->x + arcs[i].x - extra;
-                rectY1 = pDrawable->y + arcs[i].y - extra;
-                rectX2 = pDrawable->x + arcs[i].x + arcs[i].width + lw;
-                rectY2 = pDrawable->y + arcs[i].y + arcs[i].height + lw;
-                if (rectX1 < minX) minX = rectX1;
-                if (rectY1 < minY) minY = rectY1;
-                if (rectX2 > maxX) maxX = rectX2;
-                if (rectY2 > maxY) maxY = rectY2;
-            }
-       }
-
-        if (narcs > MAX_RECTS_PER_OP) {
-            regRects[0].x = minX;
-            regRects[0].y = minY;
-            regRects[0].width = maxX - minX;
-            regRects[0].height = maxY - minY;
-            nregRects = 1;
-        }
-
-       tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nregRects, regRects,
-                                    CT_NONE);
-       REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion,
-                        WINDOW_CLIP_REGION((WindowPtr)pDrawable,pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion);
-
-       REGION_DESTROY(pDrawable->pScreen, tmpRegion);
-    }
-
-    (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, arcs);
-
-    if (narcs) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * FillPolygon - take bounding box around polygon (and clip).
- */
-
-static void
-rfbFillPolygon(pDrawable, pGC, shape, mode, count, pts)
-    register DrawablePtr pDrawable;
-    register GCPtr     pGC;
-    int                        shape, mode;
-    int                        count;
-    DDXPointPtr                pts;
-{
-    int i;
-    RegionRec tmpRegion;
-    BoxRec box;
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbFillPolygon called\n"));
-
-    if (count) {
-       int minX = pts[0].x, maxX = pts[0].x;
-       int minY = pts[0].y, maxY = pts[0].y;
-
-       if (mode == CoordModePrevious)
-       {
-           int x = pts[0].x, y = pts[0].y;
-
-           for (i = 1; i < count; i++) {
-               x += pts[i].x;
-               y += pts[i].y;
-               if (x < minX) minX = x;
-               if (x > maxX) maxX = x;
-               if (y < minY) minY = y;
-               if (y > maxY) maxY = y;
-           }
-       }
-       else
-       {
-           for (i = 1; i < count; i++) {
-               if (pts[i].x < minX) minX = pts[i].x;
-               if (pts[i].x > maxX) maxX = pts[i].x;
-               if (pts[i].y < minY) minY = pts[i].y;
-               if (pts[i].y > maxY) maxY = pts[i].y;
-           }
-       }
-
-       box.x1 = minX + pDrawable->x;
-       box.y1 = minY + pDrawable->y;
-       box.x2 = maxX + 1 + pDrawable->x;
-       box.y2 = maxY + 1 + pDrawable->y;
-
-       SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
-
-       REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
-                        WINDOW_CLIP_REGION(((WindowPtr)pDrawable),pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
-
-       REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
-    }
-
-    (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pts);
-
-    if (count) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * PolyFillRect - take the union of the given rectangles (and clip).
- */
-
-static void
-rfbPolyFillRect(pDrawable, pGC, nrects, rects)
-    DrawablePtr pDrawable;
-    GCPtr      pGC;
-    int                nrects;
-    xRectangle *rects;
-{
-    RegionPtr tmpRegion;
-    xRectangle regRects[MAX_RECTS_PER_OP];
-    int i, nregRects;
-    int rectX1, rectY1, rectX2, rectY2;
-    int minX, minY, maxX, maxY;
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbPolyFillRect called: %d rects\n",nrects));
-
-    if (nrects) {
-        nregRects = nrects;
-
-        minX = maxX = rects[0].x;
-        minY = maxY = rects[0].y;
-
-       for (i = 0; i < nrects; i++) {
-            if (nrects <= MAX_RECTS_PER_OP) {
-                regRects[i].x = rects[i].x + pDrawable->x;
-                regRects[i].y = rects[i].y + pDrawable->y;
-                regRects[i].width = rects[i].width;
-                regRects[i].height = rects[i].height;
-            } else {
-                rectX1 = pDrawable->x + rects[i].x;
-                rectY1 = pDrawable->y + rects[i].y;
-                rectX2 = pDrawable->x + rects[i].x + rects[i].width;
-                rectY2 = pDrawable->y + rects[i].y + rects[i].height;
-                if (rectX1 < minX) minX = rectX1;
-                if (rectY1 < minY) minY = rectY1;
-                if (rectX2 > maxX) maxX = rectX2;
-                if (rectY2 > maxY) maxY = rectY2;
-            }
-       }
-
-        if (nrects > MAX_RECTS_PER_OP) {
-            regRects[0].x = minX;
-            regRects[0].y = minY;
-            regRects[0].width = maxX - minX;
-            regRects[0].height = maxY - minY;
-            nregRects = 1;
-        }
-
-       tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nregRects, regRects,
-                                   CT_NONE);
-       REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion,
-                        WINDOW_CLIP_REGION((WindowPtr)pDrawable,pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion);
-
-       REGION_DESTROY(pDrawable->pScreen, tmpRegion);
-    }
-
-    (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrects, rects);
-
-    if (nrects) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * PolyFillArc - take the union of bounding boxes around each arc (and clip).
- * Bounding boxes assume each is a full circle / ellipse.
- */
-
-static void
-rfbPolyFillArc(pDrawable, pGC, narcs, arcs)
-    DrawablePtr        pDrawable;
-    GCPtr      pGC;
-    int                narcs;
-    xArc       *arcs;
-{
-    int i, extra, lw, nregRects;
-    int rectX1, rectY1, rectX2, rectY2;
-    int minX, minY, maxX, maxY;
-    RegionPtr tmpRegion;
-    xRectangle regRects[MAX_RECTS_PER_OP];
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbPolyFillArc called: %d arcs\n",narcs));
-
-    if (narcs) {
-        nregRects = narcs;
-       lw = pGC->lineWidth;
-       if (lw == 0)
-           lw = 1;
-       extra = lw / 2;
-
-        minX = maxX = arcs[0].x;
-        minY = maxY = arcs[0].y;
-
-       for (i = 0; i < narcs; i++)
-       {
-            if (narcs <= MAX_RECTS_PER_OP) {
-                regRects[i].x = arcs[i].x - extra + pDrawable->x;
-                regRects[i].y = arcs[i].y - extra + pDrawable->y;
-                regRects[i].width = arcs[i].width + lw;
-                regRects[i].height = arcs[i].height + lw;
-            } else {
-                rectX1 = pDrawable->x + arcs[i].x - extra;
-                rectY1 = pDrawable->y + arcs[i].y - extra;
-                rectX2 = pDrawable->x + arcs[i].x + arcs[i].width + lw;
-                rectY2 = pDrawable->y + arcs[i].y + arcs[i].height + lw;
-                if (rectX1 < minX) minX = rectX1;
-                if (rectY1 < minY) minY = rectY1;
-                if (rectX2 > maxX) maxX = rectX2;
-                if (rectY2 > maxY) maxY = rectY2;
-            }
-       }
-
-        if (narcs > MAX_RECTS_PER_OP) {
-            regRects[0].x = minX;
-            regRects[0].y = minY;
-            regRects[0].width = maxX - minX;
-            regRects[0].height = maxY - minY;
-            nregRects = 1;
-        }
-
-       tmpRegion = RECTS_TO_REGION(pDrawable->pScreen, nregRects, regRects,
-                                    CT_NONE);
-       REGION_INTERSECT(pDrawable->pScreen, tmpRegion, tmpRegion,
-                        WINDOW_CLIP_REGION((WindowPtr)pDrawable,pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, tmpRegion);
-
-       REGION_DESTROY(pDrawable->pScreen, tmpRegion);
-    }
-
-    (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, arcs);
-
-    if (narcs) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * Get a rough bounding box around n characters of the given font.
- */
-
-static void GetTextBoundingBox(pDrawable, font, x, y, n, pbox)
-    DrawablePtr pDrawable;
-    FontPtr font;
-    int x, y, n;
-    BoxPtr pbox;
-{
-    int maxAscent, maxDescent, maxCharWidth;
-
-    if (FONTASCENT(font) > FONTMAXBOUNDS(font,ascent))
-       maxAscent = FONTASCENT(font);
-    else
-       maxAscent = FONTMAXBOUNDS(font,ascent);
-
-    if (FONTDESCENT(font) > FONTMAXBOUNDS(font,descent))
-       maxDescent = FONTDESCENT(font);
-    else
-       maxDescent = FONTMAXBOUNDS(font,descent);
-
-    if (FONTMAXBOUNDS(font,rightSideBearing) > FONTMAXBOUNDS(font,characterWidth))
-       maxCharWidth = FONTMAXBOUNDS(font,rightSideBearing);
-    else
-       maxCharWidth = FONTMAXBOUNDS(font,characterWidth);
-
-    pbox->x1 = pDrawable->x + x;
-    pbox->y1 = pDrawable->y + y - maxAscent;
-    pbox->x2 = pbox->x1 + maxCharWidth * n;
-    pbox->y2 = pbox->y1 + maxAscent + maxDescent;
-
-    if (FONTMINBOUNDS(font,leftSideBearing) < 0) {
-       pbox->x1 += FONTMINBOUNDS(font,leftSideBearing);
-    }
-}
-
-
-/*
- * PolyText8 - use rough bounding box.
- */
-
-static int
-rfbPolyText8(pDrawable, pGC, x, y, count, chars)
-    DrawablePtr pDrawable;
-    GCPtr      pGC;
-    int                x, y;
-    int        count;
-    char       *chars;
-{
-    int        ret;
-    RegionRec tmpRegion;
-    BoxRec box;
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbPolyText8 called '%.*s'\n",count,chars));
-
-    if (count) {
-       GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
-
-       SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
-
-       REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
-                        WINDOW_CLIP_REGION(((WindowPtr)pDrawable),pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
-
-       REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
-    }
-
-    ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars);
-
-    if (count) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-    return ret;
-}
-
-/*
- * PolyText16 - use rough bounding box.
- */
-
-static int
-rfbPolyText16(pDrawable, pGC, x, y, count, chars)
-    DrawablePtr pDrawable;
-    GCPtr      pGC;
-    int                x, y;
-    int                count;
-    unsigned short *chars;
-{
-    int        ret;
-    RegionRec tmpRegion;
-    BoxRec box;
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbPolyText16 called\n"));
-
-    if (count) {
-       GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
-
-       SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
-
-       REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
-                        WINDOW_CLIP_REGION(((WindowPtr)pDrawable),pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
-
-       REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
-    }
-
-    ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars);
-
-    if (count) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-    return ret;
-}
-
-/*
- * ImageText8 - use rough bounding box.
- */
-
-static void
-rfbImageText8(pDrawable, pGC, x, y, count, chars)
-    DrawablePtr pDrawable;
-    GCPtr      pGC;
-    int                x, y;
-    int                count;
-    char       *chars;
-{
-    RegionRec tmpRegion;
-    BoxRec box;
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbImageText8 called '%.*s'\n",count,chars));
-
-    if (count) {
-       GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
-
-       SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
-
-       REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
-                        WINDOW_CLIP_REGION(((WindowPtr)pDrawable),pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
-
-       REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
-    }
-
-    (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars);
-
-    if (count) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * ImageText16 - use rough bounding box.
- */
-
-static void
-rfbImageText16(pDrawable, pGC, x, y, count, chars)
-    DrawablePtr pDrawable;
-    GCPtr      pGC;
-    int                x, y;
-    int                count;
-    unsigned short *chars;
-{
-    RegionRec tmpRegion;
-    BoxRec box;
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbImageText16 called\n"));
-
-    if (count) {
-       GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
-
-       SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
-
-       REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
-                        WINDOW_CLIP_REGION(((WindowPtr)pDrawable),pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
-
-       REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
-    }
-
-    (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars);
-
-    if (count) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * ImageGlyphBlt - use rough bounding box.
- */
-
-static void
-rfbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
-    DrawablePtr pDrawable;
-    GCPtr      pGC;
-    int        x, y;
-    unsigned int nglyph;
-    CharInfoPtr *ppci;         /* array of character info */
-    pointer    pglyphBase;     /* start of array of glyphs */
-{
-    RegionRec tmpRegion;
-    BoxRec box;
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbImageGlyphBlt called\n"));
-
-    if (nglyph) {
-       GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box);
-
-       SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
-
-       REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
-                        WINDOW_CLIP_REGION(((WindowPtr)pDrawable),pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
-
-       REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
-    }
-
-    (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci,pglyphBase);
-
-    if (nglyph) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * PolyGlyphBlt - use rough bounding box.
- */
-
-static void
-rfbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
-    DrawablePtr pDrawable;
-    GCPtr      pGC;
-    int        x, y;
-    unsigned int nglyph;
-    CharInfoPtr *ppci;         /* array of character info */
-    pointer    pglyphBase;     /* start of array of glyphs */
-{
-    RegionRec tmpRegion;
-    BoxRec box;
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbPolyGlyphBlt called\n"));
-
-    if (nglyph) {
-       GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box);
-
-       SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
-
-       REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
-                        WINDOW_CLIP_REGION(((WindowPtr)pDrawable),pGC));
-
-       ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
-
-       REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
-    }
-
-    (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
-
-    if (nglyph) {
-       SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-    }
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-/*
- * PushPixels - be fairly safe - region modified is intersection of the given
- * rectangle with the window clip region.
- */
-
-static void
-rfbPushPixels(pGC, pBitMap, pDrawable, w, h, x, y)
-    GCPtr      pGC;
-    PixmapPtr  pBitMap;
-    DrawablePtr pDrawable;
-    int                w, h, x, y;
-{
-    RegionRec tmpRegion;
-    BoxRec box;
-    GC_OP_PROLOGUE(pDrawable, pGC);
-
-    TRC(("rfbPushPixels called\n"));
-
-    box.x1 = x + pDrawable->x;
-    box.y1 = y + pDrawable->y;
-    box.x2 = box.x1 + w;
-    box.y2 = box.y1 + h;
-
-    SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0);
-
-    REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion,
-                    WINDOW_CLIP_REGION(((WindowPtr)pDrawable),pGC));
-
-    ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion);
-
-    REGION_UNINIT(pDrawable->pScreen, &tmpRegion);
-
-    (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y);
-
-    SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb);
-
-    GC_OP_EPILOGUE(pGC);
-}
-
-
-
-/****************************************************************************/
-/*
- * Other functions
- */
-/****************************************************************************/
-
-/*
- * rfbCopyRegion.  Args are src and dst regions plus a translation (dx,dy).
- * Takes these args together with the existing modified region and possibly an
- * existing copy region and translation.  Produces a combined modified region
- * plus copy region and translation.  Note that the copy region is the
- * destination of the copy.
- *
- * First we trim parts of src which are invalid (ie in the modified region).
- * Then we see if there is any overlap between the src and the existing copy
- * region.  If not then the two copies cannot be combined, so we choose
- * whichever is bigger to form the basis of a new copy, while the other copy is
- * just done the hard way by being added to the modified region.  So if the
- * existing copy is bigger then we simply add the destination of the new copy
- * to the modified region and we're done.  If the new copy is bigger, we add
- * the old copy region to the modified region and behave as though there is no
- * existing copy region.
- * 
- * At this stage we now know that either the two copies can be combined, or
- * that there is no existing copy.  We temporarily add both the existing copy
- * region and dst to the modified region (this is the entire area of the screen
- * affected in any way).  Finally we calculate the new copy region, and remove
- * it from the modified region.
- *
- * Note:
- *   1. The src region is modified by this routine.
- *   2. When the copy region is empty, copyDX and copyDY MUST be set to zero.
- */
-
-static void
-rfbCopyRegion(pScreen, cl, src, dst, dx, dy)
-    ScreenPtr pScreen;
-    rfbClientPtr cl;
-    RegionPtr src;
-    RegionPtr dst;
-    int dx, dy;
-{
-    RegionRec tmp;
-
-    /* src = src - modifiedRegion */
-
-    REGION_SUBTRACT(pScreen, src, src, &cl->modifiedRegion);
-
-    if (REGION_NOTEMPTY(pScreen, &cl->copyRegion)) {
-
-       REGION_INIT(pScreen, &tmp, NullBox, 0);
-       REGION_INTERSECT(pScreen, &tmp, src, &cl->copyRegion);
-
-       if (REGION_NOTEMPTY(pScreen, &tmp)) {
-
-           /* if src and copyRegion overlap:
-                src = src intersect copyRegion */
-
-           REGION_COPY(pScreen, src, &tmp);
-
-       } else {
-
-           /* if no overlap, find bigger region */
-
-           int newArea = (((REGION_EXTENTS(pScreen,src))->x2
-                           - (REGION_EXTENTS(pScreen,src))->x1)
-                          * ((REGION_EXTENTS(pScreen,src))->y2
-                             - (REGION_EXTENTS(pScreen,src))->y1));
-
-           int oldArea = (((REGION_EXTENTS(pScreen,&cl->copyRegion))->x2
-                           - (REGION_EXTENTS(pScreen,&cl->copyRegion))->x1)
-                          * ((REGION_EXTENTS(pScreen,&cl->copyRegion))->y2
-                            - (REGION_EXTENTS(pScreen,&cl->copyRegion))->y1));
-
-           if (oldArea > newArea) {
-
-               /* existing copy is bigger:
-                    modifiedRegion = modifiedRegion union dst
-                    copyRegion = copyRegion - dst
-                    return */
-
-               REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
-                            dst);
-               REGION_SUBTRACT(pScreen, &cl->copyRegion, &cl->copyRegion,
-                               dst);
-               if (!REGION_NOTEMPTY(pScreen, &cl->copyRegion)) {
-                   cl->copyDX = 0;
-                   cl->copyDY = 0;
-               }
-               return;
-           }
-
-           /* new copy is bigger:
-                modifiedRegion = modifiedRegion union copyRegion
-                copyRegion = empty */
-
-           REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
-                        &cl->copyRegion);
-           REGION_EMPTY(pScreen, &cl->copyRegion);
-           cl->copyDX = cl->copyDY = 0;
-       }
-    }
-
-
-    /* modifiedRegion = modifiedRegion union dst union copyRegion */
-
-    REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, dst);
-    REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
-                &cl->copyRegion);
-
-    /* copyRegion = T(src) intersect dst */
-
-    REGION_TRANSLATE(pScreen, src, dx, dy);
-    REGION_INTERSECT(pScreen, &cl->copyRegion, src, dst);
-
-    /* modifiedRegion = modifiedRegion - copyRegion */
-
-    REGION_SUBTRACT(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
-                   &cl->copyRegion);
-
-    /* combine new translation T with existing translation */
-
-    if (REGION_NOTEMPTY(pScreen, &cl->copyRegion)) {
-       cl->copyDX += dx;
-       cl->copyDY += dy;
-    } else {
-       cl->copyDX = 0;
-       cl->copyDY = 0;
-    }
-}
-
-
-/*
- * rfbDeferredUpdateCallback() is called when a client's deferredUpdateTimer
- * goes off.
- */
-
-static CARD32
-rfbDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
-{
-  rfbClientPtr cl = (rfbClientPtr)arg;
-
-  rfbSendFramebufferUpdate(cl);
-
-  cl->deferredUpdateScheduled = FALSE;
-  return 0;
-}
-
-
-/*
- * rfbScheduleDeferredUpdate() is called from the SCHEDULE_FB_UPDATE macro
- * to schedule an update.
- */
-
-void
-rfbScheduleDeferredUpdate(rfbClientPtr cl)
-{
-    if (rfbDeferUpdateTime != 0) {
-       cl->deferredUpdateTimer = TimerSet(cl->deferredUpdateTimer, 0,
-                                          rfbDeferUpdateTime,
-                                          rfbDeferredUpdateCallback, cl);
-       cl->deferredUpdateScheduled = TRUE;
-    } else {
-       rfbSendFramebufferUpdate(cl);
-    }
-}
-
-
-/*
- * PrintRegion is useful for debugging.
- */
-
-#if 0
-static void
-PrintRegion(pScreen,reg)
-    ScreenPtr pScreen;
-    RegionPtr reg;
-{
-    int nrects = REGION_NUM_RECTS(reg);
-    int i;
-
-    rfbLog("Region num rects %d extents %d,%d %d,%d\n",nrects,
-          (REGION_EXTENTS(pScreen,reg))->x1,
-          (REGION_EXTENTS(pScreen,reg))->y1,
-          (REGION_EXTENTS(pScreen,reg))->x2,
-          (REGION_EXTENTS(pScreen,reg))->y2);
-
-    for (i = 0; i < nrects; i++) {
-       rfbLog("    rect %d,%d %dx%d\n",
-              REGION_RECTS(reg)[i].x1,
-              REGION_RECTS(reg)[i].y1,
-              REGION_RECTS(reg)[i].x2-REGION_RECTS(reg)[i].x1,
-              REGION_RECTS(reg)[i].y2-REGION_RECTS(reg)[i].y1);
-    }
-}
-#endif