Blame synfig-osx/launcher/rootless-gc.c

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