From 2e76958d304a3c4080d62f32449724eeb9b95d93 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Wed, 4 Feb 2009 19:48:03 +0100 Subject: [PATCH] fb: move some code to mi --- exa/exa_accel.c | 4 +- fb/fb.h | 37 ----- fb/fbcopy.c | 331 +------------------------------------------- fb/fboverlay.c | 2 +- fb/fboverlay.h | 2 +- fb/fbwindow.c | 2 +- mi/Makefile.am | 1 + mi/mi.h | 42 ++++++ mi/micopy.c | 354 ++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 406 insertions(+), 369 deletions(-) create mode 100644 mi/micopy.c diff --git a/exa/exa_accel.c b/exa/exa_accel.c index 02858f1fc..cc5dd18f2 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -524,7 +524,7 @@ exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, srcx, srcy, width, height, dstx, dsty); } - return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, + return miDoCopy (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, exaCopyNtoN, 0, NULL); } @@ -879,7 +879,7 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) -pPixmap->screen_x, -pPixmap->screen_y); #endif - fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable, + miCopyRegion (&pPixmap->drawable, &pPixmap->drawable, NULL, &rgnDst, dx, dy, exaCopyNtoN, 0, NULL); diff --git a/fb/fb.h b/fb/fb.h index 83843155e..cadb9a0c7 100644 --- a/fb/fb.h +++ b/fb/fb.h @@ -1306,18 +1306,6 @@ fbInitVisuals (VisualPtr *visualp, * fbcopy.c */ -typedef void (*fbCopyProc) (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pDstBox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure); - extern _X_EXPORT void fbCopyNtoN (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, @@ -1357,31 +1345,6 @@ fbCopyNto1 (DrawablePtr pSrcDrawable, Pixel bitplane, void *closure); -extern _X_EXPORT void -fbCopyRegion (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - RegionPtr pDstRegion, - int dx, - int dy, - fbCopyProc copyProc, - Pixel bitPlane, - void *closure); - -extern _X_EXPORT RegionPtr -fbDoCopy (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - int xIn, - int yIn, - int widthSrc, - int heightSrc, - int xOut, - int yOut, - fbCopyProc copyProc, - Pixel bitplane, - void *closure); - extern _X_EXPORT RegionPtr fbCopyArea (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, diff --git a/fb/fbcopy.c b/fb/fbcopy.c index b8b0b6a8c..fed87a599 100644 --- a/fb/fbcopy.c +++ b/fb/fbcopy.c @@ -289,329 +289,6 @@ fbCopyNto1 (DrawablePtr pSrcDrawable, } } -void -fbCopyRegion (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - RegionPtr pDstRegion, - int dx, - int dy, - fbCopyProc copyProc, - Pixel bitPlane, - void *closure) -{ - int careful; - Bool reverse; - Bool upsidedown; - BoxPtr pbox; - int nbox; - BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp; - - pbox = REGION_RECTS(pDstRegion); - nbox = REGION_NUM_RECTS(pDstRegion); - - /* XXX we have to err on the side of safety when both are windows, - * because we don't know if IncludeInferiors is being used. - */ - careful = ((pSrcDrawable == pDstDrawable) || - ((pSrcDrawable->type == DRAWABLE_WINDOW) && - (pDstDrawable->type == DRAWABLE_WINDOW))); - - pboxNew1 = NULL; - pboxNew2 = NULL; - if (careful && dy < 0) - { - upsidedown = TRUE; - - if (nbox > 1) - { - /* keep ordering in each band, reverse order of bands */ - pboxNew1 = (BoxPtr)xalloc(sizeof(BoxRec) * nbox); - if(!pboxNew1) - return; - pboxBase = pboxNext = pbox+nbox-1; - while (pboxBase >= pbox) - { - while ((pboxNext >= pbox) && - (pboxBase->y1 == pboxNext->y1)) - pboxNext--; - pboxTmp = pboxNext+1; - while (pboxTmp <= pboxBase) - { - *pboxNew1++ = *pboxTmp++; - } - pboxBase = pboxNext; - } - pboxNew1 -= nbox; - pbox = pboxNew1; - } - } - else - { - /* walk source top to bottom */ - upsidedown = FALSE; - } - - if (careful && dx < 0) - { - /* walk source right to left */ - if (dy <= 0) - reverse = TRUE; - else - reverse = FALSE; - - if (nbox > 1) - { - /* reverse order of rects in each band */ - pboxNew2 = (BoxPtr)xalloc(sizeof(BoxRec) * nbox); - if(!pboxNew2) - { - if (pboxNew1) - xfree(pboxNew1); - return; - } - pboxBase = pboxNext = pbox; - while (pboxBase < pbox+nbox) - { - while ((pboxNext < pbox+nbox) && - (pboxNext->y1 == pboxBase->y1)) - pboxNext++; - pboxTmp = pboxNext; - while (pboxTmp != pboxBase) - { - *pboxNew2++ = *--pboxTmp; - } - pboxBase = pboxNext; - } - pboxNew2 -= nbox; - pbox = pboxNew2; - } - } - else - { - /* walk source left to right */ - reverse = FALSE; - } - - (*copyProc) (pSrcDrawable, - pDstDrawable, - pGC, - pbox, - nbox, - dx, dy, - reverse, upsidedown, bitPlane, closure); - - if (pboxNew1) - xfree (pboxNew1); - if (pboxNew2) - xfree (pboxNew2); -} - -RegionPtr -fbDoCopy (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - int xIn, - int yIn, - int widthSrc, - int heightSrc, - int xOut, - int yOut, - fbCopyProc copyProc, - Pixel bitPlane, - void *closure) -{ - RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ - Bool freeSrcClip = FALSE; - RegionPtr prgnExposed = NULL; - RegionRec rgnDst; - int dx; - int dy; - int numRects; - int box_x1; - int box_y1; - int box_x2; - int box_y2; - Bool fastSrc = FALSE; /* for fast clipping with pixmap source */ - Bool fastDst = FALSE; /* for fast clipping with one rect dest */ - Bool fastExpose = FALSE; /* for fast exposures with pixmap source */ - - /* Short cut for unmapped windows */ - - if (pDstDrawable->type == DRAWABLE_WINDOW && - !((WindowPtr)pDstDrawable)->realized) - { - return NULL; - } - - if ((pSrcDrawable != pDstDrawable) && - pSrcDrawable->pScreen->SourceValidate) - { - (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, widthSrc, heightSrc); - } - - /* Compute source clip region */ - if (pSrcDrawable->type == DRAWABLE_PIXMAP) - { - if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) - prgnSrcClip = fbGetCompositeClip(pGC); - else - fastSrc = TRUE; - } - else - { - if (pGC->subWindowMode == IncludeInferiors) - { - /* - * XFree86 DDX empties the border clip when the - * VT is inactive, make sure the region isn't empty - */ - if (!((WindowPtr) pSrcDrawable)->parent && - REGION_NOTEMPTY (pSrcDrawable->pScreen, - &((WindowPtr) pSrcDrawable)->borderClip)) - { - /* - * special case bitblt from root window in - * IncludeInferiors mode; just like from a pixmap - */ - fastSrc = TRUE; - } - else if ((pSrcDrawable == pDstDrawable) && - (pGC->clientClipType == CT_NONE)) - { - prgnSrcClip = fbGetCompositeClip(pGC); - } - else - { - prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable); - freeSrcClip = TRUE; - } - } - else - { - prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList; - } - } - - xIn += pSrcDrawable->x; - yIn += pSrcDrawable->y; - - xOut += pDstDrawable->x; - yOut += pDstDrawable->y; - - box_x1 = xIn; - box_y1 = yIn; - box_x2 = xIn + widthSrc; - box_y2 = yIn + heightSrc; - - dx = xIn - xOut; - dy = yIn - yOut; - - /* Don't create a source region if we are doing a fast clip */ - if (fastSrc) - { - RegionPtr cclip; - - fastExpose = TRUE; - /* - * clip the source; if regions extend beyond the source size, - * make sure exposure events get sent - */ - if (box_x1 < pSrcDrawable->x) - { - box_x1 = pSrcDrawable->x; - fastExpose = FALSE; - } - if (box_y1 < pSrcDrawable->y) - { - box_y1 = pSrcDrawable->y; - fastExpose = FALSE; - } - if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width) - { - box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width; - fastExpose = FALSE; - } - if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height) - { - box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height; - fastExpose = FALSE; - } - - /* Translate and clip the dst to the destination composite clip */ - box_x1 -= dx; - box_x2 -= dx; - box_y1 -= dy; - box_y2 -= dy; - - /* If the destination composite clip is one rectangle we can - do the clip directly. Otherwise we have to create a full - blown region and call intersect */ - - cclip = fbGetCompositeClip(pGC); - if (REGION_NUM_RECTS(cclip) == 1) - { - BoxPtr pBox = REGION_RECTS(cclip); - - if (box_x1 < pBox->x1) box_x1 = pBox->x1; - if (box_x2 > pBox->x2) box_x2 = pBox->x2; - if (box_y1 < pBox->y1) box_y1 = pBox->y1; - if (box_y2 > pBox->y2) box_y2 = pBox->y2; - fastDst = TRUE; - } - } - - /* Check to see if the region is empty */ - if (box_x1 >= box_x2 || box_y1 >= box_y2) - { - REGION_NULL(pGC->pScreen, &rgnDst); - } - else - { - BoxRec box; - box.x1 = box_x1; - box.y1 = box_y1; - box.x2 = box_x2; - box.y2 = box_y2; - REGION_INIT(pGC->pScreen, &rgnDst, &box, 1); - } - - /* Clip against complex source if needed */ - if (!fastSrc) - { - REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip); - REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy); - } - - /* Clip against complex dest if needed */ - if (!fastDst) - { - REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, - fbGetCompositeClip(pGC)); - } - - /* Do bit blitting */ - numRects = REGION_NUM_RECTS(&rgnDst); - if (numRects && widthSrc && heightSrc) - fbCopyRegion (pSrcDrawable, pDstDrawable, pGC, - &rgnDst, dx, dy, copyProc, bitPlane, closure); - - /* Pixmap sources generate a NoExposed (we return NULL to do this) */ - if (!fastExpose && pGC->fExpose) - prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, - xIn - pSrcDrawable->x, - yIn - pSrcDrawable->y, - widthSrc, heightSrc, - xOut - pDstDrawable->x, - yOut - pDstDrawable->y, - (unsigned long) bitPlane); - REGION_UNINIT(pGC->pScreen, &rgnDst); - if (freeSrcClip) - REGION_DESTROY(pGC->pScreen, prgnSrcClip); - fbValidateDrawable (pDstDrawable); - return prgnExposed; -} - RegionPtr fbCopyArea (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, @@ -623,7 +300,7 @@ fbCopyArea (DrawablePtr pSrcDrawable, int xOut, int yOut) { - fbCopyProc copy; + miCopyProc copy; #ifdef FB_24_32BIT if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel) @@ -631,7 +308,7 @@ fbCopyArea (DrawablePtr pSrcDrawable, else #endif copy = fbCopyNtoN; - return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, + return miDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut, copy, 0, 0); } @@ -648,11 +325,11 @@ fbCopyPlane (DrawablePtr pSrcDrawable, unsigned long bitplane) { if (pSrcDrawable->bitsPerPixel > 1) - return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, + return miDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0); else if (bitplane & 1) - return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, + return miDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut, fbCopy1toN, (Pixel) bitplane, 0); else diff --git a/fb/fboverlay.c b/fb/fboverlay.c index 1432cb6f0..99939e8bf 100644 --- a/fb/fboverlay.c +++ b/fb/fboverlay.c @@ -248,7 +248,7 @@ fbOverlayCopyWindow(WindowPtr pWin, { REGION_TRANSLATE(pScreen, &layerRgn[i], -dx, -dy); pPixmap = pScrPriv->layer[i].u.run.pixmap; - fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable, + miCopyRegion (&pPixmap->drawable, &pPixmap->drawable, 0, &layerRgn[i], dx, dy, pScrPriv->CopyWindow, 0, (void *)(long) i); diff --git a/fb/fboverlay.h b/fb/fboverlay.h index ed355afad..b626a7702 100644 --- a/fb/fboverlay.h +++ b/fb/fboverlay.h @@ -53,7 +53,7 @@ typedef struct _fbOverlayLayer { typedef struct _fbOverlayScrPriv { int nlayers; fbOverlayPaintKeyProc PaintKey; - fbCopyProc CopyWindow; + miCopyProc CopyWindow; FbOverlayLayer layer[FB_OVERLAY_MAX]; } FbOverlayScrPrivRec, *FbOverlayScrPrivPtr; diff --git a/fb/fbwindow.c b/fb/fbwindow.c index 022a16f1b..46c033448 100644 --- a/fb/fbwindow.c +++ b/fb/fbwindow.c @@ -140,7 +140,7 @@ fbCopyWindow(WindowPtr pWin, -pPixmap->screen_x, -pPixmap->screen_y); #endif - fbCopyRegion (pDrawable, pDrawable, + miCopyRegion (pDrawable, pDrawable, 0, &rgnDst, dx, dy, fbCopyWindowProc, 0, 0); diff --git a/mi/Makefile.am b/mi/Makefile.am index e6a4e600b..979cc3980 100644 --- a/mi/Makefile.am +++ b/mi/Makefile.am @@ -20,6 +20,7 @@ libmi_la_SOURCES = \ micmap.c \ micmap.h \ micoord.h \ + micopy.c \ micursor.c \ midash.c \ midispcur.c \ diff --git a/mi/mi.h b/mi/mi.h index 23f9abb09..c44ff0650 100644 --- a/mi/mi.h +++ b/mi/mi.h @@ -56,6 +56,7 @@ SOFTWARE. #include "input.h" #include "cursor.h" #include "privates.h" +#include "colormap.h" #define MiBits CARD32 @@ -123,6 +124,47 @@ extern _X_EXPORT void miPutImage( char * /*pImage*/ ); +/* micopy.c */ + +#define miGetCompositeClip(pGC) ((pGC)->pCompositeClip) + +typedef void (*miCopyProc) (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pDstBox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +extern _X_EXPORT void +miCopyRegion (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + RegionPtr pDstRegion, + int dx, + int dy, + miCopyProc copyProc, + Pixel bitPlane, + void *closure); + +extern _X_EXPORT RegionPtr +miDoCopy (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut, + miCopyProc copyProc, + Pixel bitplane, + void *closure); + /* micursor.c */ extern _X_EXPORT void miRecolorCursor( diff --git a/mi/micopy.c b/mi/micopy.c new file mode 100644 index 000000000..3719f4646 --- /dev/null +++ b/mi/micopy.c @@ -0,0 +1,354 @@ +/* + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "mi.h" +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmap.h" +#include "pixmapstr.h" +#include "windowstr.h" + +void +miCopyRegion (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + RegionPtr pDstRegion, + int dx, + int dy, + miCopyProc copyProc, + Pixel bitPlane, + void *closure) +{ + int careful; + Bool reverse; + Bool upsidedown; + BoxPtr pbox; + int nbox; + BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp; + + pbox = REGION_RECTS(pDstRegion); + nbox = REGION_NUM_RECTS(pDstRegion); + + /* XXX we have to err on the side of safety when both are windows, + * because we don't know if IncludeInferiors is being used. + */ + careful = ((pSrcDrawable == pDstDrawable) || + ((pSrcDrawable->type == DRAWABLE_WINDOW) && + (pDstDrawable->type == DRAWABLE_WINDOW))); + + pboxNew1 = NULL; + pboxNew2 = NULL; + if (careful && dy < 0) + { + upsidedown = TRUE; + + if (nbox > 1) + { + /* keep ordering in each band, reverse order of bands */ + pboxNew1 = (BoxPtr)xalloc(sizeof(BoxRec) * nbox); + if(!pboxNew1) + return; + pboxBase = pboxNext = pbox+nbox-1; + while (pboxBase >= pbox) + { + while ((pboxNext >= pbox) && + (pboxBase->y1 == pboxNext->y1)) + pboxNext--; + pboxTmp = pboxNext+1; + while (pboxTmp <= pboxBase) + { + *pboxNew1++ = *pboxTmp++; + } + pboxBase = pboxNext; + } + pboxNew1 -= nbox; + pbox = pboxNew1; + } + } + else + { + /* walk source top to bottom */ + upsidedown = FALSE; + } + + if (careful && dx < 0) + { + /* walk source right to left */ + if (dy <= 0) + reverse = TRUE; + else + reverse = FALSE; + + if (nbox > 1) + { + /* reverse order of rects in each band */ + pboxNew2 = (BoxPtr)xalloc(sizeof(BoxRec) * nbox); + if(!pboxNew2) + { + if (pboxNew1) + xfree(pboxNew1); + return; + } + pboxBase = pboxNext = pbox; + while (pboxBase < pbox+nbox) + { + while ((pboxNext < pbox+nbox) && + (pboxNext->y1 == pboxBase->y1)) + pboxNext++; + pboxTmp = pboxNext; + while (pboxTmp != pboxBase) + { + *pboxNew2++ = *--pboxTmp; + } + pboxBase = pboxNext; + } + pboxNew2 -= nbox; + pbox = pboxNew2; + } + } + else + { + /* walk source left to right */ + reverse = FALSE; + } + + (*copyProc) (pSrcDrawable, + pDstDrawable, + pGC, + pbox, + nbox, + dx, dy, + reverse, upsidedown, bitPlane, closure); + + if (pboxNew1) + xfree (pboxNew1); + if (pboxNew2) + xfree (pboxNew2); +} + +RegionPtr +miDoCopy (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut, + miCopyProc copyProc, + Pixel bitPlane, + void *closure) +{ + RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ + Bool freeSrcClip = FALSE; + RegionPtr prgnExposed = NULL; + RegionRec rgnDst; + int dx; + int dy; + int numRects; + int box_x1; + int box_y1; + int box_x2; + int box_y2; + Bool fastSrc = FALSE; /* for fast clipping with pixmap source */ + Bool fastDst = FALSE; /* for fast clipping with one rect dest */ + Bool fastExpose = FALSE; /* for fast exposures with pixmap source */ + + /* Short cut for unmapped windows */ + + if (pDstDrawable->type == DRAWABLE_WINDOW && + !((WindowPtr)pDstDrawable)->realized) + { + return NULL; + } + + if ((pSrcDrawable != pDstDrawable) && + pSrcDrawable->pScreen->SourceValidate) + { + (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, widthSrc, heightSrc); + } + + /* Compute source clip region */ + if (pSrcDrawable->type == DRAWABLE_PIXMAP) + { + if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) + prgnSrcClip = miGetCompositeClip(pGC); + else + fastSrc = TRUE; + } + else + { + if (pGC->subWindowMode == IncludeInferiors) + { + /* + * XFree86 DDX empties the border clip when the + * VT is inactive, make sure the region isn't empty + */ + if (!((WindowPtr) pSrcDrawable)->parent && + REGION_NOTEMPTY (pSrcDrawable->pScreen, + &((WindowPtr) pSrcDrawable)->borderClip)) + { + /* + * special case bitblt from root window in + * IncludeInferiors mode; just like from a pixmap + */ + fastSrc = TRUE; + } + else if ((pSrcDrawable == pDstDrawable) && + (pGC->clientClipType == CT_NONE)) + { + prgnSrcClip = miGetCompositeClip(pGC); + } + else + { + prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable); + freeSrcClip = TRUE; + } + } + else + { + prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList; + } + } + + xIn += pSrcDrawable->x; + yIn += pSrcDrawable->y; + + xOut += pDstDrawable->x; + yOut += pDstDrawable->y; + + box_x1 = xIn; + box_y1 = yIn; + box_x2 = xIn + widthSrc; + box_y2 = yIn + heightSrc; + + dx = xIn - xOut; + dy = yIn - yOut; + + /* Don't create a source region if we are doing a fast clip */ + if (fastSrc) + { + RegionPtr cclip; + + fastExpose = TRUE; + /* + * clip the source; if regions extend beyond the source size, + * make sure exposure events get sent + */ + if (box_x1 < pSrcDrawable->x) + { + box_x1 = pSrcDrawable->x; + fastExpose = FALSE; + } + if (box_y1 < pSrcDrawable->y) + { + box_y1 = pSrcDrawable->y; + fastExpose = FALSE; + } + if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width) + { + box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width; + fastExpose = FALSE; + } + if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height) + { + box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height; + fastExpose = FALSE; + } + + /* Translate and clip the dst to the destination composite clip */ + box_x1 -= dx; + box_x2 -= dx; + box_y1 -= dy; + box_y2 -= dy; + + /* If the destination composite clip is one rectangle we can + do the clip directly. Otherwise we have to create a full + blown region and call intersect */ + + cclip = miGetCompositeClip(pGC); + if (REGION_NUM_RECTS(cclip) == 1) + { + BoxPtr pBox = REGION_RECTS(cclip); + + if (box_x1 < pBox->x1) box_x1 = pBox->x1; + if (box_x2 > pBox->x2) box_x2 = pBox->x2; + if (box_y1 < pBox->y1) box_y1 = pBox->y1; + if (box_y2 > pBox->y2) box_y2 = pBox->y2; + fastDst = TRUE; + } + } + + /* Check to see if the region is empty */ + if (box_x1 >= box_x2 || box_y1 >= box_y2) + { + REGION_NULL(pGC->pScreen, &rgnDst); + } + else + { + BoxRec box; + box.x1 = box_x1; + box.y1 = box_y1; + box.x2 = box_x2; + box.y2 = box_y2; + REGION_INIT(pGC->pScreen, &rgnDst, &box, 1); + } + + /* Clip against complex source if needed */ + if (!fastSrc) + { + REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip); + REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy); + } + + /* Clip against complex dest if needed */ + if (!fastDst) + { + REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, + miGetCompositeClip(pGC)); + } + + /* Do bit blitting */ + numRects = REGION_NUM_RECTS(&rgnDst); + if (numRects && widthSrc && heightSrc) + miCopyRegion (pSrcDrawable, pDstDrawable, pGC, + &rgnDst, dx, dy, copyProc, bitPlane, closure); + + /* Pixmap sources generate a NoExposed (we return NULL to do this) */ + if (!fastExpose && pGC->fExpose) + prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, + xIn - pSrcDrawable->x, + yIn - pSrcDrawable->y, + widthSrc, heightSrc, + xOut - pDstDrawable->x, + yOut - pDstDrawable->y, + (unsigned long) bitPlane); + REGION_UNINIT(pGC->pScreen, &rgnDst); + if (freeSrcClip) + REGION_DESTROY(pGC->pScreen, prgnSrcClip); + return prgnExposed; +}