示例#1
0
文件: rdpdraw.c 项目: piccolo/xrdp
int
draw_item_add_line_region(rdpPixmapRec *priv, RegionPtr reg, int color,
                          int opcode, int width, xSegment *segs, int nseg,
                          int is_segment)
{
    struct rdp_draw_item *di;

    LLOGLN(10, ("draw_item_add_line_region:"));
    di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1);
    di->type = RDI_LINE;
    di->u.line.fg_color = color;
    di->u.line.opcode = opcode;
    di->u.line.width = width;
    di->u.line.segs = (xSegment *)g_malloc(sizeof(xSegment) * nseg, 1);
    memcpy(di->u.line.segs, segs, sizeof(xSegment) * nseg);
    di->u.line.nseg = nseg;

    if (is_segment)
    {
        di->u.line.flags = 1;
    }

    di->reg = RegionCreate(NullBox, 0);
    di->flags |= 1;
    RegionCopy(di->reg, reg);
    draw_item_add(priv, di);
    return 0;
}
示例#2
0
RegionPtr
CreateClipShape(WindowPtr pWin)
{
    BoxRec extents;

    extents.x1 = 0;
    extents.y1 = 0;
    extents.x2 = pWin->drawable.width;
    extents.y2 = pWin->drawable.height;
    return RegionCreate(&extents, 1);
}
示例#3
0
文件: migc.c 项目: mirror/xserver
void
miCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
{
    if (pgcSrc->clientClip) {
        RegionPtr prgnNew = RegionCreate(NULL, 1);
        RegionCopy(prgnNew, (RegionPtr) (pgcSrc->clientClip));
        (*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, prgnNew, 0);
    } else {
        (*pgcDst->funcs->ChangeClip) (pgcDst, CT_NONE, NULL, 0);
    }
}
示例#4
0
RegionPtr
CreateBoundingShape(WindowPtr pWin)
{
    BoxRec extents;

    extents.x1 = -wBorderWidth(pWin);
    extents.y1 = -wBorderWidth(pWin);
    extents.x2 = pWin->drawable.width + wBorderWidth(pWin);
    extents.y2 = pWin->drawable.height + wBorderWidth(pWin);
    return RegionCreate(&extents, 1);
}
示例#5
0
Bool
xf86InitFBManagerRegion(ScreenPtr pScreen, RegionPtr FullRegion)
{
    FBManagerPtr offman;

    if (RegionNil(FullRegion))
        return FALSE;

    if (!dixRegisterPrivateKey(&xf86FBScreenKeyRec, PRIVATE_SCREEN, 0))
        return FALSE;

    if (!xf86RegisterOffscreenManager(pScreen, &xf86FBManFuncs))
        return FALSE;

    offman = malloc(sizeof(FBManager));
    if (!offman)
        return FALSE;

    dixSetPrivate(&pScreen->devPrivates, xf86FBScreenKey, offman);

    offman->CloseScreen = pScreen->CloseScreen;
    pScreen->CloseScreen = xf86FBCloseScreen;

    offman->InitialBoxes = RegionCreate(NULL, 1);
    offman->FreeBoxes = RegionCreate(NULL, 1);

    RegionCopy(offman->InitialBoxes, FullRegion);
    RegionCopy(offman->FreeBoxes, FullRegion);

    offman->pScreen = pScreen;
    offman->UsedAreas = NULL;
    offman->LinearAreas = NULL;
    offman->NumUsedAreas = 0;
    offman->NumCallbacks = 0;
    offman->FreeBoxesUpdateCallback = NULL;
    offman->devPrivates = NULL;

    return TRUE;
}
示例#6
0
void
miSetShape(WindowPtr pWin, int kind)
{
    Bool WasViewable = (Bool) (pWin->viewable);
    ScreenPtr pScreen = pWin->drawable.pScreen;
    Bool anyMarked = FALSE;
    WindowPtr pLayerWin;

    if (kind != ShapeInput) {
        if (WasViewable) {
            anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin,
                                                           &pLayerWin);
            if (pWin->valdata) {
                if (HasBorder(pWin)) {
                    RegionPtr borderVisible;

                    borderVisible = RegionCreate(NullBox, 1);
                    RegionSubtract(borderVisible,
                                   &pWin->borderClip, &pWin->winSize);
                    pWin->valdata->before.borderVisible = borderVisible;
                }
                pWin->valdata->before.resized = TRUE;
            }
        }

        SetWinSize(pWin);
        SetBorderSize(pWin);

        ResizeChildrenWinSize(pWin, 0, 0, 0, 0);

        if (WasViewable) {
            anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL);

            if (anyMarked)
                (*pScreen->ValidateTree) (pLayerWin->parent, NullWindow,
                                          VTOther);
        }

        if (WasViewable) {
            if (anyMarked)
                (*pScreen->HandleExposures) (pLayerWin->parent);
            if (anyMarked && pScreen->PostValidateTree)
                (*pScreen->PostValidateTree) (pLayerWin->parent, NullWindow,
                                              VTOther);
        }
    }
    if (pWin->realized)
        WindowsRestructured();
    CheckCursorConfinement(pWin);
}
示例#7
0
文件: rdpdraw.c 项目: piccolo/xrdp
int
draw_item_add_img_region(rdpPixmapRec *priv, RegionPtr reg, int opcode,
                         int type)
{
    struct rdp_draw_item *di;

    di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1);
    di->type = type;
    di->reg = RegionCreate(NullBox, 0);
    RegionCopy(di->reg, reg);
    di->u.img.opcode = opcode;
    draw_item_add(priv, di);
    return 0;
}
示例#8
0
文件: region.c 项目: mirror/xserver
RegionPtr
XFixesRegionCopy(RegionPtr pRegion)
{
    RegionPtr pNew = RegionCreate(RegionExtents(pRegion),
                                  RegionNumRects(pRegion));

    if (!pNew)
        return 0;
    if (!RegionCopy(pNew, pRegion)) {
        RegionDestroy(pNew);
        return 0;
    }
    return pNew;
}
示例#9
0
void
miChangeBorderWidth(WindowPtr pWin, unsigned int width)
{
    int oldwidth;
    Bool anyMarked = FALSE;
    ScreenPtr pScreen;
    Bool WasViewable = (Bool) (pWin->viewable);
    Bool HadBorder;
    WindowPtr pLayerWin;

    oldwidth = wBorderWidth(pWin);
    if (oldwidth == width)
        return;
    HadBorder = HasBorder(pWin);
    pScreen = pWin->drawable.pScreen;
    if (WasViewable && width < oldwidth)
        anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin);

    pWin->borderWidth = width;
    SetBorderSize(pWin);

    if (WasViewable) {
        if (width > oldwidth) {
            anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin,
                                                           &pLayerWin);
            /*
             * save the old border visible region to correctly compute
             * borderExposed.
             */
            if (pWin->valdata && HadBorder) {
                RegionPtr borderVisible;

                borderVisible = RegionCreate(NULL, 1);
                RegionSubtract(borderVisible,
                               &pWin->borderClip, &pWin->winSize);
                pWin->valdata->before.borderVisible = borderVisible;
            }
        }

        if (anyMarked) {
            (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTOther);
            (*pScreen->HandleExposures) (pLayerWin->parent);
        }
        if (anyMarked && pScreen->PostValidateTree)
            (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin,
                                          VTOther);
    }
    if (pWin->realized)
        WindowsRestructured();
}
示例#10
0
文件: rdpdraw.c 项目: piccolo/xrdp
int
draw_item_add_fill_region(rdpPixmapRec *priv, RegionPtr reg, int color,
                          int opcode)
{
    struct rdp_draw_item *di;

    di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1);
    di->type = RDI_FILL;
    di->u.fill.fg_color = color;
    di->u.fill.opcode = opcode;
    di->reg = RegionCreate(NullBox, 0);
    RegionCopy(di->reg, reg);
    draw_item_add(priv, di);
    return 0;
}
void sgx_exa_copy_region(DrawablePtr draw, RegionPtr reg, DrawablePtr src_draw,
			DrawablePtr dst_draw)
{
        ScreenPtr screen = dst_draw->pScreen;
	RegionPtr copy_clip = RegionCreate(NULL, 0);
        GCPtr gc;

        gc = GetScratchGC(dst_draw->depth, screen);
	RegionCopy(copy_clip, reg);
        (*gc->funcs->ChangeClip)(gc, CT_REGION, copy_clip, 0);
        ValidateGC(dst_draw, gc);

        (*gc->ops->CopyArea)(src_draw, dst_draw, gc, 0, 0, draw->width,
                                draw->height, 0, 0);

        FreeScratchGC(gc);
}
示例#12
0
文件: GC.c 项目: 4eremuxa/xserver
void
xnestCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
{
  RegionPtr pRgn;

  switch (pGCSrc->clientClipType)
    {
    default:
    case CT_NONE:
      xnestDestroyClip(pGCDst);
      break;

    case CT_REGION:
      pRgn = RegionCreate(NULL, 1);
      RegionCopy(pRgn, pGCSrc->clientClip);
      xnestChangeClip(pGCDst, CT_REGION, pRgn, 0);
      break;
    }
}
示例#13
0
文件: rdpdraw.c 项目: piccolo/xrdp
int
draw_item_add_srcblt_region(rdpPixmapRec *priv, RegionPtr reg,
                            int srcx, int srcy, int dstx, int dsty,
                            int cx, int cy)
{
    struct rdp_draw_item *di;

    LLOGLN(10, ("draw_item_add_srcblt_region:"));
    di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1);
    di->type = RDI_SCRBLT;
    di->u.scrblt.srcx = srcx;
    di->u.scrblt.srcy = srcy;
    di->u.scrblt.dstx = dstx;
    di->u.scrblt.dsty = dsty;
    di->u.scrblt.cx = cx;
    di->u.scrblt.cy = cy;
    di->reg = RegionCreate(NullBox, 0);
    RegionCopy(di->reg, reg);
    draw_item_add(priv, di);
    return 0;
}
示例#14
0
Bool
exaHWCopyNtoN(DrawablePtr pSrcDrawable,
              DrawablePtr pDstDrawable,
              GCPtr pGC,
              BoxPtr pbox,
              int nbox, int dx, int dy, Bool reverse, Bool upsidedown)
{
    ExaScreenPriv(pDstDrawable->pScreen);
    PixmapPtr pSrcPixmap, pDstPixmap;
    ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap;
    int src_off_x, src_off_y;
    int dst_off_x, dst_off_y;
    RegionPtr srcregion = NULL, dstregion = NULL;
    xRectangle *rects;
    Bool ret = TRUE;

    /* avoid doing copy operations if no boxes */
    if (nbox == 0)
        return TRUE;

    pSrcPixmap = exaGetDrawablePixmap(pSrcDrawable);
    pDstPixmap = exaGetDrawablePixmap(pDstDrawable);

    exaGetDrawableDeltas(pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
    exaGetDrawableDeltas(pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);

    rects = malloc(nbox * sizeof(xRectangle));

    if (rects) {
        int i;
        int ordering;

        for (i = 0; i < nbox; i++) {
            rects[i].x = pbox[i].x1 + dx + src_off_x;
            rects[i].y = pbox[i].y1 + dy + src_off_y;
            rects[i].width = pbox[i].x2 - pbox[i].x1;
            rects[i].height = pbox[i].y2 - pbox[i].y1;
        }

        /* This must match the RegionCopy() logic for reversing rect order */
        if (nbox == 1 || (dx > 0 && dy > 0) ||
            (pDstDrawable != pSrcDrawable &&
             (pDstDrawable->type != DRAWABLE_WINDOW ||
              pSrcDrawable->type != DRAWABLE_WINDOW)))
            ordering = CT_YXBANDED;
        else
            ordering = CT_UNSORTED;

        srcregion = RegionFromRects(nbox, rects, ordering);
        free(rects);

        if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask,
                                           pGC->fillStyle, pGC->alu,
                                           pGC->clientClip != NULL)) {
            dstregion = RegionCreate(NullBox, 0);
            RegionCopy(dstregion, srcregion);
            RegionTranslate(dstregion, dst_off_x - dx - src_off_x,
                            dst_off_y - dy - src_off_y);
        }
    }

    pSrcExaPixmap = ExaGetPixmapPriv(pSrcPixmap);
    pDstExaPixmap = ExaGetPixmapPriv(pDstPixmap);

    /* Check whether the accelerator can use this pixmap.
     * If the pitch of the pixmaps is out of range, there's nothing
     * we can do but fall back to software rendering.
     */
    if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH ||
        pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH)
        goto fallback;

    /* If the width or the height of either of the pixmaps
     * is out of range, check whether the boxes are actually out of the
     * addressable range as well. If they aren't, we can still do
     * the copying in hardware.
     */
    if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) {
        int i;

        for (i = 0; i < nbox; i++) {
            /* src */
            if ((pbox[i].x2 + dx + src_off_x) >= pExaScr->info->maxX ||
                (pbox[i].y2 + dy + src_off_y) >= pExaScr->info->maxY)
                goto fallback;

            /* dst */
            if ((pbox[i].x2 + dst_off_x) >= pExaScr->info->maxX ||
                (pbox[i].y2 + dst_off_y) >= pExaScr->info->maxY)
                goto fallback;
        }
    }

    if (pExaScr->do_migration) {
        ExaMigrationRec pixmaps[2];

        pixmaps[0].as_dst = TRUE;
        pixmaps[0].as_src = FALSE;
        pixmaps[0].pPix = pDstPixmap;
        pixmaps[0].pReg = dstregion;
        pixmaps[1].as_dst = FALSE;
        pixmaps[1].as_src = TRUE;
        pixmaps[1].pPix = pSrcPixmap;
        pixmaps[1].pReg = srcregion;

        exaDoMigration(pixmaps, 2, TRUE);
    }

    /* Mixed directions must be handled specially if the card is lame */
    if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
        reverse != upsidedown) {
        if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
                              dx, dy))
            goto out;
        goto fallback;
    }

    if (exaPixmapHasGpuCopy(pDstPixmap)) {
        /* Normal blitting. */
        if (exaPixmapHasGpuCopy(pSrcPixmap)) {
            if (!(*pExaScr->info->PrepareCopy)
                (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, upsidedown ? -1 : 1,
                 pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) {
                goto fallback;
            }

            while (nbox--) {
                (*pExaScr->info->Copy) (pDstPixmap,
                                        pbox->x1 + dx + src_off_x,
                                        pbox->y1 + dy + src_off_y,
                                        pbox->x1 + dst_off_x,
                                        pbox->y1 + dst_off_y,
                                        pbox->x2 - pbox->x1,
                                        pbox->y2 - pbox->y1);
                pbox++;
            }

            (*pExaScr->info->DoneCopy) (pDstPixmap);
            exaMarkSync(pDstDrawable->pScreen);
            /* UTS: mainly for SHM PutImage's secondary path.
             *
             * Only taking this path for directly accessible pixmaps.
             */
        }
        else if (!pDstExaPixmap->pDamage && pSrcExaPixmap->sys_ptr) {
            int bpp = pSrcDrawable->bitsPerPixel;
            int src_stride = exaGetPixmapPitch(pSrcPixmap);
            CARD8 *src = NULL;

            if (!pExaScr->info->UploadToScreen)
                goto fallback;

            if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
                goto fallback;

            if (pSrcDrawable->bitsPerPixel < 8)
                goto fallback;

            if (pGC &&
                !(pGC->alu == GXcopy &&
                  EXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask)))
                goto fallback;

            while (nbox--) {
                src =
                    pSrcExaPixmap->sys_ptr + (pbox->y1 + dy +
                                              src_off_y) * src_stride +
                    (pbox->x1 + dx + src_off_x) * (bpp / 8);
                if (!pExaScr->info->
                    UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x,
                                   pbox->y1 + dst_off_y, pbox->x2 - pbox->x1,
                                   pbox->y2 - pbox->y1, (char *) src,
                                   src_stride))
                    goto fallback;

                pbox++;
            }
        }
        else
            goto fallback;
    }
    else
        goto fallback;

    goto out;

 fallback:
    ret = FALSE;

 out:
    if (dstregion) {
        RegionUninit(dstregion);
        RegionDestroy(dstregion);
    }
    if (srcregion) {
        RegionUninit(srcregion);
        RegionDestroy(srcregion);
    }

    return ret;
}
示例#15
0
/** Transfer \a pBits image to back-end server associated with \a
 *  pDrawable's screen.  If primitive subdivision optimization is
 *  enabled, then only transfer the sections of \a pBits that are
 *  visible (i.e., not-clipped) to the back-end server. */
void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC,
		 int depth, int x, int y, int w, int h,
		 int leftPad, int format, char *pBits)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
    XImage        *img;

    if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;

    img = XCreateImage(dmxScreen->beDisplay,
		       dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
		       depth, format, leftPad, pBits, w, h,
		       BitmapPad(dmxScreen->beDisplay),
		       (format == ZPixmap) ?
		       PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad));

    if (img) {
	Drawable draw;

	DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);

	if (dmxSubdividePrimitives && pGC->pCompositeClip) {
	    RegionPtr  pSubImages;
	    RegionPtr  pClip;
	    BoxRec     box;
	    BoxPtr     pBox;
	    int        nBox;

	    box.x1 = x;
	    box.y1 = y;
	    box.x2 = x + w;
	    box.y2 = y + h;
	    pSubImages = RegionCreate(&box, 1);

	    pClip = RegionCreate(NullBox, 1);
	    RegionCopy(pClip, pGC->pCompositeClip);
	    RegionTranslate(pClip,
			     -pDrawable->x, -pDrawable->y);
	    RegionIntersect(pSubImages, pSubImages, pClip);

	    nBox = RegionNumRects(pSubImages);
	    pBox = RegionRects(pSubImages);

	    while (nBox--) {
		XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img,
			  pBox->x1 - box.x1,
			  pBox->y1 - box.y1,
			  pBox->x1,
			  pBox->y1,
			  pBox->x2 - pBox->x1,
			  pBox->y2 - pBox->y1);
		pBox++;
	    }
            RegionDestroy(pClip);
            RegionDestroy(pSubImages);
	} else {
	    XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc,
		      img, 0, 0, x, y, w, h);
	}
	XFree(img);             /* Use XFree instead of XDestroyImage
                                 * because pBits is passed in from the
                                 * caller. */

	dmxSync(dmxScreen, FALSE);
    } else {
	/* Error -- this should not happen! */
    }
}
示例#16
0
文件: cw.c 项目: 4eremuxa/xserver
static void
cwCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
    ScreenPtr pScreen = pWin->drawable.pScreen;

    SCREEN_PROLOGUE(pScreen, CopyWindow);

    if (!cwDrawableIsRedirWindow((DrawablePtr)pWin)) {
	(*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
    } else {
	GCPtr	    pGC;
	BoxPtr	    pExtents;
	int	    x_off, y_off;
	int	    dx, dy;
	PixmapPtr   pBackingPixmap;
	RegionPtr   pClip;
	int	    src_x, src_y, dst_x, dst_y, w, h;

	dx = ptOldOrg.x - pWin->drawable.x;
	dy = ptOldOrg.y - pWin->drawable.y;

	pExtents = RegionExtents(prgnSrc);

	pBackingPixmap = (PixmapPtr) cwGetBackingDrawable((DrawablePtr)pWin,
							  &x_off, &y_off);

	src_x = pExtents->x1 - pBackingPixmap->screen_x;
	src_y = pExtents->y1 - pBackingPixmap->screen_y;
	w = pExtents->x2 - pExtents->x1;
	h = pExtents->y2 - pExtents->y1;
	dst_x = src_x - dx;
	dst_y = src_y - dy;
			       
	/* Translate region (as required by API) */
	RegionTranslate(prgnSrc, -dx, -dy);
	
	pGC = GetScratchGC(pBackingPixmap->drawable.depth, pScreen);
	/*
	 * Copy region to GC as clip, aligning as dest clip
	 */
	pClip = RegionCreate(NULL, 0);
	RegionIntersect(pClip, &pWin->borderClip, prgnSrc);
	RegionTranslate(pClip,
			 -pBackingPixmap->screen_x,
			 -pBackingPixmap->screen_y);
	
	(*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);

	ValidateGC(&pBackingPixmap->drawable, pGC);

	(*pGC->ops->CopyArea) (&pBackingPixmap->drawable,
			       &pBackingPixmap->drawable, pGC,
			       src_x, src_y, w, h, dst_x, dst_y);

	(*pGC->funcs->DestroyClip) (pGC);

	FreeScratchGC(pGC);
    }
	
    SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow);
}
void
miValidatePicture (PicturePtr pPicture,
		   Mask       mask)
{
    DrawablePtr	    pDrawable = pPicture->pDrawable;

    if ((mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)) ||
	(pDrawable->serialNumber != (pPicture->serialNumber & DRAWABLE_SERIAL_BITS)))
    {
	if (pDrawable->type == DRAWABLE_WINDOW)
	{
	    WindowPtr       pWin = (WindowPtr) pDrawable;
	    RegionPtr       pregWin;
	    Bool            freeTmpClip, freeCompClip;

	    if (pPicture->subWindowMode == IncludeInferiors)
	    {
		pregWin = NotClippedByChildren(pWin);
		freeTmpClip = TRUE;
	    }
	    else
	    {
		pregWin = &pWin->clipList;
		freeTmpClip = FALSE;
	    }
	    freeCompClip = pPicture->freeCompClip;

	    /*
	     * if there is no client clip, we can get by with just keeping the
	     * pointer we got, and remembering whether or not should destroy
	     * (or maybe re-use) it later.  this way, we avoid unnecessary
	     * copying of regions.  (this wins especially if many clients clip
	     * by children and have no client clip.)
	     */
	    if (pPicture->clientClipType == CT_NONE)
	    {
		if (freeCompClip)
		    RegionDestroy(pPicture->pCompositeClip);
		pPicture->pCompositeClip = pregWin;
		pPicture->freeCompClip = freeTmpClip;
	    }
	    else
	    {
		/*
		 * we need one 'real' region to put into the composite clip. if
		 * pregWin the current composite clip are real, we can get rid of
		 * one. if pregWin is real and the current composite clip isn't,
		 * use pregWin for the composite clip. if the current composite
		 * clip is real and pregWin isn't, use the current composite
		 * clip. if neither is real, create a new region.
		 */

		RegionTranslate(pPicture->clientClip,
				 pDrawable->x + pPicture->clipOrigin.x,
				 pDrawable->y + pPicture->clipOrigin.y);

		if (freeCompClip)
		{
		    RegionIntersect(pPicture->pCompositeClip,
				     pregWin, pPicture->clientClip);
		    if (freeTmpClip)
			RegionDestroy(pregWin);
		}
		else if (freeTmpClip)
		{
		    RegionIntersect(pregWin, pregWin, pPicture->clientClip);
		    pPicture->pCompositeClip = pregWin;
		}
		else
		{
		    pPicture->pCompositeClip = RegionCreate(NullBox, 0);
		    RegionIntersect(pPicture->pCompositeClip,
				     pregWin, pPicture->clientClip);
		}
		pPicture->freeCompClip = TRUE;
		RegionTranslate(pPicture->clientClip,
				 -(pDrawable->x + pPicture->clipOrigin.x),
				 -(pDrawable->y + pPicture->clipOrigin.y));
	    }
	}	/* end of composite clip for a window */
	else
	{
	    BoxRec          pixbounds;

	    /* XXX should we translate by drawable.x/y here ? */
	    /* If you want pixmaps in offscreen memory, yes */
	    pixbounds.x1 = pDrawable->x;
	    pixbounds.y1 = pDrawable->y;
	    pixbounds.x2 = pDrawable->x + pDrawable->width;
	    pixbounds.y2 = pDrawable->y + pDrawable->height;

	    if (pPicture->freeCompClip)
	    {
		RegionReset(pPicture->pCompositeClip, &pixbounds);
	    }
	    else
	    {
		pPicture->freeCompClip = TRUE;
		pPicture->pCompositeClip = RegionCreate(&pixbounds, 1);
	    }

	    if (pPicture->clientClipType == CT_REGION)
	    {
		if(pDrawable->x || pDrawable->y) {
		    RegionTranslate(pPicture->clientClip,
				     pDrawable->x + pPicture->clipOrigin.x, 
				     pDrawable->y + pPicture->clipOrigin.y);
		    RegionIntersect(pPicture->pCompositeClip,
				     pPicture->pCompositeClip, pPicture->clientClip);
		    RegionTranslate(pPicture->clientClip,
				     -(pDrawable->x + pPicture->clipOrigin.x), 
				     -(pDrawable->y + pPicture->clipOrigin.y));
		} else {
		    RegionTranslate(pPicture->pCompositeClip,
				     -pPicture->clipOrigin.x, -pPicture->clipOrigin.y);
		    RegionIntersect(pPicture->pCompositeClip,
				     pPicture->pCompositeClip, pPicture->clientClip);
		    RegionTranslate(pPicture->pCompositeClip,
				     pPicture->clipOrigin.x, pPicture->clipOrigin.y);
		}
	    }
	}	/* end of composite clip for pixmap */
    }
}
示例#18
0
static Bool
localQueryLargestOffscreenArea(ScreenPtr pScreen,
                               int *width, int *height,
                               int granularity, int preferences, int severity)
{
    FBManagerPtr offman;
    RegionPtr newRegion = NULL;
    BoxPtr pbox;
    int nbox;
    int x, w, h, area, oldArea;

    *width = *height = oldArea = 0;

    if (granularity <= 1)
        granularity = 0;

    if ((preferences < 0) || (preferences > 3))
        return FALSE;

    offman = (FBManagerPtr) dixLookupPrivate(&pScreen->devPrivates,
                                             xf86FBScreenKey);
    if (severity < 0)
        severity = 0;
    if (severity > 2)
        severity = 2;

    switch (severity) {
    case 2:
        if (offman->NumUsedAreas) {
            FBLinkPtr pLink;
            RegionRec tmpRegion;

            newRegion = RegionCreate(NULL, 1);
            RegionCopy(newRegion, offman->InitialBoxes);
            pLink = offman->UsedAreas;

            while (pLink) {
                if (!pLink->area.RemoveAreaCallback) {
                    RegionInit(&tmpRegion, &(pLink->area.box), 1);
                    RegionSubtract(newRegion, newRegion, &tmpRegion);
                    RegionUninit(&tmpRegion);
                }
                pLink = pLink->next;
            }

            nbox = RegionNumRects(newRegion);
            pbox = RegionRects(newRegion);
            break;
        }
    case 1:
        if (offman->NumUsedAreas) {
            FBLinkPtr pLink;
            RegionRec tmpRegion;

            newRegion = RegionCreate(NULL, 1);
            RegionCopy(newRegion, offman->FreeBoxes);
            pLink = offman->UsedAreas;

            while (pLink) {
                if (pLink->area.RemoveAreaCallback) {
                    RegionInit(&tmpRegion, &(pLink->area.box), 1);
                    RegionAppend(newRegion, &tmpRegion);
                    RegionUninit(&tmpRegion);
                }
                pLink = pLink->next;
            }

            nbox = RegionNumRects(newRegion);
            pbox = RegionRects(newRegion);
            break;
        }
    default:
        nbox = RegionNumRects(offman->FreeBoxes);
        pbox = RegionRects(offman->FreeBoxes);
        break;
    }

    while (nbox--) {
        x = pbox->x1;
        if (granularity > 1)
            x = ((x + granularity - 1) / granularity) * granularity;

        w = pbox->x2 - x;
        h = pbox->y2 - pbox->y1;
        area = w * h;

        if (w > 0) {
            Bool gotIt = FALSE;

            switch (preferences) {
            case FAVOR_AREA_THEN_WIDTH:
                if ((area > oldArea) || ((area == oldArea) && (w > *width)))
                    gotIt = TRUE;
                break;
            case FAVOR_AREA_THEN_HEIGHT:
                if ((area > oldArea) || ((area == oldArea) && (h > *height)))
                    gotIt = TRUE;
                break;
            case FAVOR_WIDTH_THEN_AREA:
                if ((w > *width) || ((w == *width) && (area > oldArea)))
                    gotIt = TRUE;
                break;
            case FAVOR_HEIGHT_THEN_AREA:
                if ((h > *height) || ((h == *height) && (area > oldArea)))
                    gotIt = TRUE;
                break;
            }
            if (gotIt) {
                *width = w;
                *height = h;
                oldArea = area;
            }
        }
        pbox++;
    }

    if (newRegion)
        RegionDestroy(newRegion);

    return TRUE;
}
示例#19
0
文件: migc.c 项目: mirror/xserver
void
miComputeCompositeClip(GCPtr pGC, DrawablePtr pDrawable)
{
    if (pDrawable->type == DRAWABLE_WINDOW) {
        WindowPtr pWin = (WindowPtr) pDrawable;
        RegionPtr pregWin;
        Bool freeTmpClip, freeCompClip;

        if (pGC->subWindowMode == IncludeInferiors) {
            pregWin = NotClippedByChildren(pWin);
            freeTmpClip = TRUE;
        }
        else {
            pregWin = &pWin->clipList;
            freeTmpClip = FALSE;
        }
        freeCompClip = pGC->freeCompClip;

        /*
         * if there is no client clip, we can get by with just keeping the
         * pointer we got, and remembering whether or not should destroy (or
         * maybe re-use) it later.  this way, we avoid unnecessary copying of
         * regions.  (this wins especially if many clients clip by children
         * and have no client clip.)
         */
        if (!pGC->clientClip) {
            if (freeCompClip)
                RegionDestroy(pGC->pCompositeClip);
            pGC->pCompositeClip = pregWin;
            pGC->freeCompClip = freeTmpClip;
        }
        else {
            /*
             * we need one 'real' region to put into the composite clip. if
             * pregWin the current composite clip are real, we can get rid of
             * one. if pregWin is real and the current composite clip isn't,
             * use pregWin for the composite clip. if the current composite
             * clip is real and pregWin isn't, use the current composite
             * clip. if neither is real, create a new region.
             */

            RegionTranslate(pGC->clientClip,
                            pDrawable->x + pGC->clipOrg.x,
                            pDrawable->y + pGC->clipOrg.y);

            if (freeCompClip) {
                RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip);
                if (freeTmpClip)
                    RegionDestroy(pregWin);
            }
            else if (freeTmpClip) {
                RegionIntersect(pregWin, pregWin, pGC->clientClip);
                pGC->pCompositeClip = pregWin;
            }
            else {
                pGC->pCompositeClip = RegionCreate(NullBox, 0);
                RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip);
            }
            pGC->freeCompClip = TRUE;
            RegionTranslate(pGC->clientClip,
                            -(pDrawable->x + pGC->clipOrg.x),
                            -(pDrawable->y + pGC->clipOrg.y));
        }
    }                           /* end of composite clip for a window */
    else {
        BoxRec pixbounds;

        /* XXX should we translate by drawable.x/y here ? */
        /* If you want pixmaps in offscreen memory, yes */
        pixbounds.x1 = pDrawable->x;
        pixbounds.y1 = pDrawable->y;
        pixbounds.x2 = pDrawable->x + pDrawable->width;
        pixbounds.y2 = pDrawable->y + pDrawable->height;

        if (pGC->freeCompClip) {
            RegionReset(pGC->pCompositeClip, &pixbounds);
        }
        else {
            pGC->freeCompClip = TRUE;
            pGC->pCompositeClip = RegionCreate(&pixbounds, 1);
        }

        if (pGC->clientClip) {
            if (pDrawable->x || pDrawable->y) {
                RegionTranslate(pGC->clientClip,
                                pDrawable->x + pGC->clipOrg.x,
                                pDrawable->y + pGC->clipOrg.y);
                RegionIntersect(pGC->pCompositeClip,
                                pGC->pCompositeClip, pGC->clientClip);
                RegionTranslate(pGC->clientClip,
                                -(pDrawable->x + pGC->clipOrg.x),
                                -(pDrawable->y + pGC->clipOrg.y));
            }
            else {
                RegionTranslate(pGC->pCompositeClip,
                                -pGC->clipOrg.x, -pGC->clipOrg.y);
                RegionIntersect(pGC->pCompositeClip,
                                pGC->pCompositeClip, pGC->clientClip);
                RegionTranslate(pGC->pCompositeClip,
                                pGC->clipOrg.x, pGC->clipOrg.y);
            }
        }
    }                           /* end of composite clip for pixmap */
}                               /* end miComputeCompositeClip */
示例#20
0
void
winCopyWindowNativeGDI(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
    DDXPointPtr pptSrc;
    DDXPointPtr ppt;
    RegionPtr prgnDst;
    BoxPtr pBox;
    int dx, dy;
    int i, nbox;
    WindowPtr pwinRoot;
    BoxPtr pBoxDst;
    ScreenPtr pScreen = pWin->drawable.pScreen;

    winScreenPriv(pScreen);

    /* Get a pointer to the root window */
    pwinRoot = pWin->drawable.pScreen->root;

    /* Create a region for the destination */
    prgnDst = RegionCreate(NULL, 1);

    /* Calculate the shift from the source to the destination */
    dx = ptOldOrg.x - pWin->drawable.x;
    dy = ptOldOrg.y - pWin->drawable.y;

    /* Translate the region from the destination to the source? */
    RegionTranslate(prgnSrc, -dx, -dy);
    RegionIntersect(prgnDst, &pWin->borderClip, prgnSrc);

    /* Get a pointer to the first box in the region to be copied */
    pBox = RegionRects(prgnDst);

    /* Get the number of boxes in the region */
    nbox = RegionNumRects(prgnDst);

    /* Allocate source points for each box */
    if (!(pptSrc = (DDXPointPtr) malloc(nbox * sizeof(DDXPointRec))))
        return;

    /* Set an iterator pointer */
    ppt = pptSrc;

    /* Calculate the source point of each box? */
    for (i = nbox; --i >= 0; ppt++, pBox++) {
        ppt->x = pBox->x1 + dx;
        ppt->y = pBox->y1 + dy;
    }

    /* Setup loop pointers again */
    pBoxDst = RegionRects(prgnDst);
    ppt = pptSrc;

    /* BitBlt each source to the destination point */
    for (i = nbox; --i >= 0; pBoxDst++, ppt++) {
        BitBlt(pScreenPriv->hdcScreen,
               pBoxDst->x1, pBoxDst->y1,
               pBoxDst->x2 - pBoxDst->x1, pBoxDst->y2 - pBoxDst->y1,
               pScreenPriv->hdcScreen, ppt->x, ppt->y, SRCCOPY);
    }

    /* Cleanup the regions, etc. */
    free(pptSrc);
    RegionDestroy(prgnDst);
}
示例#21
0
void
miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind)
{
    WindowPtr pParent;
    Bool WasViewable = (Bool) (pWin->viewable);
    short bw;
    RegionPtr oldRegion = NULL;
    DDXPointRec oldpt;
    Bool anyMarked = FALSE;
    ScreenPtr pScreen;
    WindowPtr windowToValidate;
    WindowPtr pLayerWin;

    /* if this is a root window, can't be moved */
    if (!(pParent = pWin->parent))
        return;
    pScreen = pWin->drawable.pScreen;
    bw = wBorderWidth(pWin);

    oldpt.x = pWin->drawable.x;
    oldpt.y = pWin->drawable.y;
    if (WasViewable) {
        oldRegion = RegionCreate(NullBox, 1);
        RegionCopy(oldRegion, &pWin->borderClip);
        anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin);
    }
    pWin->origin.x = x + (int) bw;
    pWin->origin.y = y + (int) bw;
    x = pWin->drawable.x = pParent->drawable.x + x + (int) bw;
    y = pWin->drawable.y = pParent->drawable.y + y + (int) bw;

    SetWinSize(pWin);
    SetBorderSize(pWin);

    (*pScreen->PositionWindow) (pWin, x, y);

    windowToValidate = MoveWindowInStack(pWin, pNextSib);

    ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);

    if (WasViewable) {
        if (pLayerWin == pWin)
            anyMarked |= (*pScreen->MarkOverlappedWindows)
                (pWin, windowToValidate, NULL);
        else
            anyMarked |= (*pScreen->MarkOverlappedWindows)
                (pWin, pLayerWin, NULL);

        if (anyMarked) {
            (*pScreen->ValidateTree) (pLayerWin->parent, NullWindow, kind);
            (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, oldRegion);
            RegionDestroy(oldRegion);
            /* XXX need to retile border if ParentRelative origin */
            (*pScreen->HandleExposures) (pLayerWin->parent);
        }
        if (anyMarked && pScreen->PostValidateTree)
            (*pScreen->PostValidateTree) (pLayerWin->parent, NullWindow, kind);
    }
    if (pWin->realized)
        WindowsRestructured();
}
示例#22
0
static int
RegionOperate(ClientPtr client,
              WindowPtr pWin,
              int kind,
              RegionPtr *destRgnp,
              RegionPtr srcRgn, int op, int xoff, int yoff, CreateDftPtr create)
{
    if (srcRgn && (xoff || yoff))
        RegionTranslate(srcRgn, xoff, yoff);
    if (!pWin->parent) {
        if (srcRgn)
            RegionDestroy(srcRgn);
        return Success;
    }

    /* May/30/2001:
     * The shape.PS specs say if src is None, existing shape is to be
     * removed (and so the op-code has no meaning in such removal);
     * see shape.PS, page 3, ShapeMask.
     */
    if (srcRgn == NULL) {
        if (*destRgnp != NULL) {
            RegionDestroy(*destRgnp);
            *destRgnp = 0;
            /* go on to remove shape and generate ShapeNotify */
        }
        else {
            /* May/30/2001:
             * The target currently has no shape in effect, so nothing to
             * do here.  The specs say that ShapeNotify is generated whenever
             * the client region is "modified"; since no modification is done
             * here, we do not generate that event.  The specs does not say
             * "it is an error to request removal when there is no shape in
             * effect", so we return good status.
             */
            return Success;
        }
    }
    else
        switch (op) {
        case ShapeSet:
            if (*destRgnp)
                RegionDestroy(*destRgnp);
            *destRgnp = srcRgn;
            srcRgn = 0;
            break;
        case ShapeUnion:
            if (*destRgnp)
                RegionUnion(*destRgnp, *destRgnp, srcRgn);
            break;
        case ShapeIntersect:
            if (*destRgnp)
                RegionIntersect(*destRgnp, *destRgnp, srcRgn);
            else {
                *destRgnp = srcRgn;
                srcRgn = 0;
            }
            break;
        case ShapeSubtract:
            if (!*destRgnp)
                *destRgnp = (*create) (pWin);
            RegionSubtract(*destRgnp, *destRgnp, srcRgn);
            break;
        case ShapeInvert:
            if (!*destRgnp)
                *destRgnp = RegionCreate((BoxPtr) 0, 0);
            else
                RegionSubtract(*destRgnp, srcRgn, *destRgnp);
            break;
        default:
            client->errorValue = op;
            return BadValue;
        }
    if (srcRgn)
        RegionDestroy(srcRgn);
    (*pWin->drawable.pScreen->SetShape) (pWin, kind);
    SendShapeNotify(pWin, kind);
    return Success;
}
示例#23
0
static int
ProcShapeCombine(ClientPtr client)
{
    WindowPtr pSrcWin, pDestWin;

    REQUEST(xShapeCombineReq);
    RegionPtr srcRgn;
    RegionPtr *destRgn;
    CreateDftPtr createDefault;
    CreateDftPtr createSrc;
    RegionPtr tmp;
    int rc;

    REQUEST_SIZE_MATCH(xShapeCombineReq);
    UpdateCurrentTime();
    rc = dixLookupWindow(&pDestWin, stuff->dest, client, DixSetAttrAccess);
    if (rc != Success)
        return rc;
    if (!pDestWin->optional)
        MakeWindowOptional(pDestWin);
    switch (stuff->destKind) {
    case ShapeBounding:
        createDefault = CreateBoundingShape;
        break;
    case ShapeClip:
        createDefault = CreateClipShape;
        break;
    case ShapeInput:
        createDefault = CreateBoundingShape;
        break;
    default:
        client->errorValue = stuff->destKind;
        return BadValue;
    }

    rc = dixLookupWindow(&pSrcWin, stuff->src, client, DixGetAttrAccess);
    if (rc != Success)
        return rc;
    switch (stuff->srcKind) {
    case ShapeBounding:
        srcRgn = wBoundingShape(pSrcWin);
        createSrc = CreateBoundingShape;
        break;
    case ShapeClip:
        srcRgn = wClipShape(pSrcWin);
        createSrc = CreateClipShape;
        break;
    case ShapeInput:
        srcRgn = wInputShape(pSrcWin);
        createSrc = CreateBoundingShape;
        break;
    default:
        client->errorValue = stuff->srcKind;
        return BadValue;
    }
    if (pSrcWin->drawable.pScreen != pDestWin->drawable.pScreen) {
        return BadMatch;
    }

    if (srcRgn) {
        tmp = RegionCreate((BoxPtr) 0, 0);
        RegionCopy(tmp, srcRgn);
        srcRgn = tmp;
    }
    else
        srcRgn = (*createSrc) (pSrcWin);

    if (!pDestWin->optional)
        MakeWindowOptional(pDestWin);
    switch (stuff->destKind) {
    case ShapeBounding:
        destRgn = &pDestWin->optional->boundingShape;
        break;
    case ShapeClip:
        destRgn = &pDestWin->optional->clipShape;
        break;
    case ShapeInput:
        destRgn = &pDestWin->optional->inputShape;
        break;
    default:
        return BadValue;
    }

    return RegionOperate(client, pDestWin, (int) stuff->destKind,
                         destRgn, srcRgn, (int) stuff->op,
                         stuff->xOff, stuff->yOff, createDefault);
}
示例#24
0
void
miSlideAndSizeWindow(WindowPtr pWin,
                     int x, int y,
                     unsigned int w, unsigned int h, WindowPtr pSib)
{
    WindowPtr pParent;
    Bool WasViewable = (Bool) (pWin->viewable);
    unsigned short width = pWin->drawable.width, height = pWin->drawable.height;
    short oldx = pWin->drawable.x, oldy = pWin->drawable.y;
    int bw = wBorderWidth(pWin);
    short dw, dh;
    DDXPointRec oldpt;
    RegionPtr oldRegion = NULL;
    Bool anyMarked = FALSE;
    ScreenPtr pScreen;
    WindowPtr pFirstChange;
    WindowPtr pChild;
    RegionPtr gravitate[StaticGravity + 1];
    unsigned g;
    int nx, ny;                 /* destination x,y */
    int newx, newy;             /* new inner window position */
    RegionPtr pRegion = NULL;
    RegionPtr destClip;         /* portions of destination already written */
    RegionPtr oldWinClip = NULL;        /* old clip list for window */
    RegionPtr borderVisible = NullRegion;       /* visible area of the border */
    Bool shrunk = FALSE;        /* shrunk in an inner dimension */
    Bool moved = FALSE;         /* window position changed */
    WindowPtr pLayerWin;

    /* if this is a root window, can't be resized */
    if (!(pParent = pWin->parent))
        return;

    pScreen = pWin->drawable.pScreen;
    newx = pParent->drawable.x + x + bw;
    newy = pParent->drawable.y + y + bw;
    if (WasViewable) {
        anyMarked = FALSE;
        /*
         * save the visible region of the window
         */
        oldRegion = RegionCreate(NullBox, 1);
        RegionCopy(oldRegion, &pWin->winSize);

        /*
         * categorize child windows into regions to be moved
         */
        for (g = 0; g <= StaticGravity; g++)
            gravitate[g] = (RegionPtr) NULL;
        for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
            g = pChild->winGravity;
            if (g != UnmapGravity) {
                if (!gravitate[g])
                    gravitate[g] = RegionCreate(NullBox, 1);
                RegionUnion(gravitate[g], gravitate[g], &pChild->borderClip);
            }
            else {
                UnmapWindow(pChild, TRUE);
                anyMarked = TRUE;
            }
        }
        anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin);

        oldWinClip = NULL;
        if (pWin->bitGravity != ForgetGravity) {
            oldWinClip = RegionCreate(NullBox, 1);
            RegionCopy(oldWinClip, &pWin->clipList);
        }
        /*
         * if the window is changing size, borderExposed
         * can't be computed correctly without some help.
         */
        if (pWin->drawable.height > h || pWin->drawable.width > w)
            shrunk = TRUE;

        if (newx != oldx || newy != oldy)
            moved = TRUE;

        if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
            HasBorder(pWin)) {
            borderVisible = RegionCreate(NullBox, 1);
            /* for tiled borders, we punt and draw the whole thing */
            if (pWin->borderIsPixel || !moved) {
                if (shrunk || moved)
                    RegionSubtract(borderVisible,
                                   &pWin->borderClip, &pWin->winSize);
                else
                    RegionCopy(borderVisible, &pWin->borderClip);
            }
        }
    }
    pWin->origin.x = x + bw;
    pWin->origin.y = y + bw;
    pWin->drawable.height = h;
    pWin->drawable.width = w;

    x = pWin->drawable.x = newx;
    y = pWin->drawable.y = newy;

    SetWinSize(pWin);
    SetBorderSize(pWin);

    dw = (int) w - (int) width;
    dh = (int) h - (int) height;
    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);

    /* let the hardware adjust background and border pixmaps, if any */
    (*pScreen->PositionWindow) (pWin, x, y);

    pFirstChange = MoveWindowInStack(pWin, pSib);

    if (WasViewable) {
        pRegion = RegionCreate(NullBox, 1);

        if (pLayerWin == pWin)
            anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange,
                                                            NULL);
        else
            anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin,
                                                            NULL);

        if (pWin->valdata) {
            pWin->valdata->before.resized = TRUE;
            pWin->valdata->before.borderVisible = borderVisible;
        }

        if (anyMarked)
            (*pScreen->ValidateTree) (pLayerWin->parent, pFirstChange, VTOther);
        /*
         * the entire window is trashed unless bitGravity
         * recovers portions of it
         */
        RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList);
    }

    GravityTranslate(x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);

    if (WasViewable) {
        /* avoid the border */
        if (HasBorder(pWin)) {
            int offx, offy, dx, dy;

            /* kruft to avoid double translates for each gravity */
            offx = 0;
            offy = 0;
            for (g = 0; g <= StaticGravity; g++) {
                if (!gravitate[g])
                    continue;

                /* align winSize to gravitate[g].
                 * winSize is in new coordinates,
                 * gravitate[g] is still in old coordinates */
                GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny);

                dx = (oldx - nx) - offx;
                dy = (oldy - ny) - offy;
                if (dx || dy) {
                    RegionTranslate(&pWin->winSize, dx, dy);
                    offx += dx;
                    offy += dy;
                }
                RegionIntersect(gravitate[g], gravitate[g], &pWin->winSize);
            }
            /* get winSize back where it belongs */
            if (offx || offy)
                RegionTranslate(&pWin->winSize, -offx, -offy);
        }
        /*
         * add screen bits to the appropriate bucket
         */

        if (oldWinClip) {
            /*
             * clip to new clipList
             */
            RegionCopy(pRegion, oldWinClip);
            RegionTranslate(pRegion, nx - oldx, ny - oldy);
            RegionIntersect(oldWinClip, pRegion, &pWin->clipList);
            /*
             * don't step on any gravity bits which will be copied after this
             * region.  Note -- this assumes that the regions will be copied
             * in gravity order.
             */
            for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
                if (gravitate[g])
                    RegionSubtract(oldWinClip, oldWinClip, gravitate[g]);
            }
            RegionTranslate(oldWinClip, oldx - nx, oldy - ny);
            g = pWin->bitGravity;
            if (!gravitate[g])
                gravitate[g] = oldWinClip;
            else {
                RegionUnion(gravitate[g], gravitate[g], oldWinClip);
                RegionDestroy(oldWinClip);
            }
        }

        /*
         * move the bits on the screen
         */

        destClip = NULL;

        for (g = 0; g <= StaticGravity; g++) {
            if (!gravitate[g])
                continue;

            GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny);

            oldpt.x = oldx + (x - nx);
            oldpt.y = oldy + (y - ny);

            /* Note that gravitate[g] is *translated* by CopyWindow */

            /* only copy the remaining useful bits */

            RegionIntersect(gravitate[g], gravitate[g], oldRegion);

            /* clip to not overwrite already copied areas */

            if (destClip) {
                RegionTranslate(destClip, oldpt.x - x, oldpt.y - y);
                RegionSubtract(gravitate[g], gravitate[g], destClip);
                RegionTranslate(destClip, x - oldpt.x, y - oldpt.y);
            }

            /* and move those bits */

            if (oldpt.x != x || oldpt.y != y
#ifdef COMPOSITE
                || pWin->redirectDraw
#endif
                ) {
                (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt,
                                                       gravitate[g]);
            }

            /* remove any overwritten bits from the remaining useful bits */

            RegionSubtract(oldRegion, oldRegion, gravitate[g]);

            /*
             * recompute exposed regions of child windows
             */

            for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
                if (pChild->winGravity != g)
                    continue;
                RegionIntersect(pRegion, &pChild->borderClip, gravitate[g]);
                TraverseTree(pChild, miRecomputeExposures, (void *) pRegion);
            }

            /*
             * remove the successfully copied regions of the
             * window from its exposed region
             */

            if (g == pWin->bitGravity)
                RegionSubtract(&pWin->valdata->after.exposed,
                               &pWin->valdata->after.exposed, gravitate[g]);
            if (!destClip)
                destClip = gravitate[g];
            else {
                RegionUnion(destClip, destClip, gravitate[g]);
                RegionDestroy(gravitate[g]);
            }
        }

        RegionDestroy(oldRegion);
        RegionDestroy(pRegion);
        if (destClip)
            RegionDestroy(destClip);
        if (anyMarked)
            (*pScreen->HandleExposures) (pLayerWin->parent);
        if (anyMarked && pScreen->PostValidateTree)
            (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstChange,
                                          VTOther);
    }
    if (pWin->realized)
        WindowsRestructured();
}
示例#25
0
文件: cw.c 项目: 4eremuxa/xserver
static void
cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
{
    GCPtr   	  	pBackingGC;
    cwGCPtr		pPriv;
    DrawablePtr		pBackingDrawable;
    int			x_off, y_off;

    pPriv = (cwGCPtr) getCwGC (pGC);

    FUNC_PROLOGUE(pGC, pPriv);

    /*
     * Must call ValidateGC to ensure pGC->pCompositeClip is valid
     */
    (*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);

    if (!cwDrawableIsRedirWindow(pDrawable)) {
	cwDestroyBackingGC(pGC);
	FUNC_EPILOGUE(pGC, pPriv);
	return;
    } else {
	if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) {
	    FUNC_EPILOGUE(pGC, pPriv);
	    return;
	}
    }

    pBackingGC = pPriv->pBackingGC;
    pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);

    pPriv->stateChanges |= stateChanges;

    /*
     * Copy the composite clip into the backing GC if either
     * the drawable clip list has changed or the client has changed
     * the client clip data
     */
    if (pDrawable->serialNumber != pPriv->serialNumber ||
	(pPriv->stateChanges & (GCClipXOrigin|GCClipYOrigin|GCClipMask)))
    {
	ChangeGCVal vals[2];
	RegionPtr   pCompositeClip;

	pCompositeClip = RegionCreate(NULL, 0);
	RegionCopy(pCompositeClip, pGC->pCompositeClip);

	/* Either the drawable has changed, or the clip list in the drawable has
	 * changed.  Copy the new clip list over and set the new translated
	 * offset for it.
	 */
	
	(*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION,
					  (pointer) pCompositeClip, 0);
	
	vals[0].val = x_off - pDrawable->x;
	vals[1].val = y_off - pDrawable->y;
	ChangeGC(NullClient, pBackingGC,
		    (GCClipXOrigin | GCClipYOrigin), vals);

	pPriv->serialNumber = pDrawable->serialNumber;
	/*
	 * Mask off any client clip changes to make sure
	 * the clip list set above remains in effect
	 */
	pPriv->stateChanges &= ~(GCClipXOrigin|GCClipYOrigin|GCClipMask);
    }

    if (pPriv->stateChanges) {
	CopyGC(pGC, pBackingGC, pPriv->stateChanges);
	pPriv->stateChanges = 0;
    }

    if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x ||
	(pGC->patOrg.y + y_off) != pBackingGC->patOrg.y)
    {
	ChangeGCVal vals[2];
	vals[0].val = pGC->patOrg.x + x_off;
	vals[1].val = pGC->patOrg.y + y_off;
	ChangeGC(NullClient, pBackingGC,
		    (GCTileStipXOrigin | GCTileStipYOrigin), vals);
    }

    ValidateGC(pBackingDrawable, pBackingGC);

    FUNC_EPILOGUE(pGC, pPriv);
}
示例#26
0
文件: miexpose.c 项目: mirror/xserver
RegionPtr
miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
                  GCPtr pGC, int srcx, int srcy, int width, int height,
                  int dstx, int dsty)
{
    RegionPtr prgnSrcClip;      /* drawable-relative source clip */
    RegionRec rgnSrcRec;
    RegionPtr prgnDstClip;      /* drawable-relative dest clip */
    RegionRec rgnDstRec;
    BoxRec srcBox;              /* unclipped source */
    RegionRec rgnExposed;       /* exposed region, calculated source-
                                   relative, made dst relative to
                                   intersect with visible parts of
                                   dest and send events to client,
                                   and then screen relative to paint
                                   the window background
                                 */
    WindowPtr pSrcWin;
    BoxRec expBox = { 0, };
    Bool extents;

    /* avoid work if we can */
    if (!pGC->graphicsExposures && pDstDrawable->type == DRAWABLE_PIXMAP)
        return NULL;

    srcBox.x1 = srcx;
    srcBox.y1 = srcy;
    srcBox.x2 = srcx + width;
    srcBox.y2 = srcy + height;

    if (pSrcDrawable->type != DRAWABLE_PIXMAP) {
        BoxRec TsrcBox;

        TsrcBox.x1 = srcx + pSrcDrawable->x;
        TsrcBox.y1 = srcy + pSrcDrawable->y;
        TsrcBox.x2 = TsrcBox.x1 + width;
        TsrcBox.y2 = TsrcBox.y1 + height;
        pSrcWin = (WindowPtr) pSrcDrawable;
        if (pGC->subWindowMode == IncludeInferiors) {
            prgnSrcClip = NotClippedByChildren(pSrcWin);
            if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) {
                RegionDestroy(prgnSrcClip);
                return NULL;
            }
        }
        else {
            if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN)
                return NULL;
            prgnSrcClip = &rgnSrcRec;
            RegionNull(prgnSrcClip);
            RegionCopy(prgnSrcClip, &pSrcWin->clipList);
        }
        RegionTranslate(prgnSrcClip, -pSrcDrawable->x, -pSrcDrawable->y);
    }
    else {
        BoxRec box;

        if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
            (srcBox.x2 <= pSrcDrawable->width) &&
            (srcBox.y2 <= pSrcDrawable->height))
            return NULL;

        box.x1 = 0;
        box.y1 = 0;
        box.x2 = pSrcDrawable->width;
        box.y2 = pSrcDrawable->height;
        prgnSrcClip = &rgnSrcRec;
        RegionInit(prgnSrcClip, &box, 1);
        pSrcWin = NULL;
    }

    if (pDstDrawable == pSrcDrawable) {
        prgnDstClip = prgnSrcClip;
    }
    else if (pDstDrawable->type != DRAWABLE_PIXMAP) {
        if (pGC->subWindowMode == IncludeInferiors) {
            prgnDstClip = NotClippedByChildren((WindowPtr) pDstDrawable);
        }
        else {
            prgnDstClip = &rgnDstRec;
            RegionNull(prgnDstClip);
            RegionCopy(prgnDstClip, &((WindowPtr) pDstDrawable)->clipList);
        }
        RegionTranslate(prgnDstClip, -pDstDrawable->x, -pDstDrawable->y);
    }
    else {
        BoxRec box;

        box.x1 = 0;
        box.y1 = 0;
        box.x2 = pDstDrawable->width;
        box.y2 = pDstDrawable->height;
        prgnDstClip = &rgnDstRec;
        RegionInit(prgnDstClip, &box, 1);
    }

    /* drawable-relative source region */
    RegionInit(&rgnExposed, &srcBox, 1);

    /* now get the hidden parts of the source box */
    RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip);

    /* move them over the destination */
    RegionTranslate(&rgnExposed, dstx - srcx, dsty - srcy);

    /* intersect with visible areas of dest */
    RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip);

    /* intersect with client clip region. */
    if (pGC->clientClip)
        RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip);

    /*
     * If we have LOTS of rectangles, we decide to take the extents
     * and force an exposure on that.  This should require much less
     * work overall, on both client and server.  This is cheating, but
     * isn't prohibited by the protocol ("spontaneous combustion" :-)
     * for windows.
     */
    extents = pGC->graphicsExposures &&
        (RegionNumRects(&rgnExposed) > RECTLIMIT) &&
        (pDstDrawable->type != DRAWABLE_PIXMAP);
    if (pSrcWin) {
        RegionPtr region;

        if (!(region = wClipShape(pSrcWin)))
            region = wBoundingShape(pSrcWin);
        /*
         * If you try to CopyArea the extents of a shaped window, compacting the
         * exposed region will undo all our work!
         */
        if (extents && pSrcWin && region &&
            (RegionContainsRect(region, &srcBox) != rgnIN))
            extents = FALSE;
    }
    if (extents) {
        expBox = *RegionExtents(&rgnExposed);
        RegionReset(&rgnExposed, &expBox);
    }
    if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
        (((WindowPtr) pDstDrawable)->backgroundState != None)) {
        WindowPtr pWin = (WindowPtr) pDstDrawable;

        /* make the exposed area screen-relative */
        RegionTranslate(&rgnExposed, pDstDrawable->x, pDstDrawable->y);

        if (extents) {
            /* PaintWindow doesn't clip, so we have to */
            RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList);
        }
        pDstDrawable->pScreen->PaintWindow((WindowPtr) pDstDrawable,
                                           &rgnExposed, PW_BACKGROUND);

        if (extents) {
            RegionReset(&rgnExposed, &expBox);
        }
        else
            RegionTranslate(&rgnExposed, -pDstDrawable->x, -pDstDrawable->y);
    }
    if (prgnDstClip == &rgnDstRec) {
        RegionUninit(prgnDstClip);
    }
    else if (prgnDstClip != prgnSrcClip) {
        RegionDestroy(prgnDstClip);
    }

    if (prgnSrcClip == &rgnSrcRec) {
        RegionUninit(prgnSrcClip);
    }
    else {
        RegionDestroy(prgnSrcClip);
    }

    if (pGC->graphicsExposures) {
        /* don't look */
        RegionPtr exposed = RegionCreate(NullBox, 0);

        *exposed = rgnExposed;
        return exposed;
    }
    else {
        RegionUninit(&rgnExposed);
        return NULL;
    }
}