Esempio n. 1
0
int
ProcXFixesSetRegion(ClientPtr client)
{
    int things;
    RegionPtr pRegion, pNew;

    REQUEST(xXFixesSetRegionReq);

    REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq);
    VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);

    things = (client->req_len << 2) - sizeof(xXFixesCreateRegionReq);
    if (things & 4)
        return BadLength;
    things >>= 3;

    pNew = RegionFromRects(things, (xRectangle *) (stuff + 1), CT_UNSORTED);
    if (!pNew)
        return BadAlloc;
    if (!RegionCopy(pRegion, pNew)) {
        RegionDestroy(pNew);
        return BadAlloc;
    }
    RegionDestroy(pNew);
    return Success;
}
Esempio n. 2
0
static Bool
xf86FBCloseScreen(ScreenPtr pScreen)
{
    FBLinkPtr pLink, tmp;
    FBLinearLinkPtr pLinearLink, tmp2;
    FBManagerPtr offman = (FBManagerPtr) dixLookupPrivate(&pScreen->devPrivates,
                                                          xf86FBScreenKey);

    pScreen->CloseScreen = offman->CloseScreen;

    pLink = offman->UsedAreas;
    while (pLink) {
        tmp = pLink;
        pLink = pLink->next;
        free(tmp);
    }

    pLinearLink = offman->LinearAreas;
    while (pLinearLink) {
        tmp2 = pLinearLink;
        pLinearLink = pLinearLink->next;
        free(tmp2);
    }

    RegionDestroy(offman->InitialBoxes);
    RegionDestroy(offman->FreeBoxes);

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

    return (*pScreen->CloseScreen) (pScreen);
}
Esempio n. 3
0
void
miDestroyClip(GCPtr pGC)
{
    if (pGC->clientClip)
        RegionDestroy(pGC->clientClip);
    pGC->clientClip = NULL;
}
/* See Porting Layer Definition - p. 46 */
static void
winDestroyGCNativeGDI (GCPtr pGC)
{
    winGCPriv(pGC);
    winScreenPriv(pGC->pScreen);

    if (pGC->freeCompClip)
        RegionDestroy(pGC->pCompositeClip);

    /* Free the memory DC */
    if (pGCPriv->hdcMem != NULL)
    {
        DeleteDC (pGCPriv->hdcMem);
        pGCPriv->hdcMem = NULL;
    }

    /* Release the screen DC for the display window */
    if (pGCPriv->hdc != NULL)
    {
        ReleaseDC (pScreenPriv->hwndScreen, pGCPriv->hdc);
        pGCPriv->hdc = NULL;
    }

    /* Invalidate the GC privates pointer */
    winSetGCPriv (pGC, NULL);
}
Esempio n. 5
0
int
draw_item_remove(rdpPixmapRec *priv, struct rdp_draw_item *di)
{
    if (di->prev != 0)
    {
        di->prev->next = di->next;
    }

    if (di->next != 0)
    {
        di->next->prev = di->prev;
    }

    if (priv->draw_item_head == di)
    {
        priv->draw_item_head = di->next;
    }

    if (priv->draw_item_tail == di)
    {
        priv->draw_item_tail = di->prev;
    }

    if (di->type == RDI_LINE)
    {
        if (di->u.line.segs != 0)
        {
            g_free(di->u.line.segs);
        }
    }

    RegionDestroy(di->reg);
    g_free(di);
    return 0;
}
Esempio n. 6
0
void
miDestroyPictureClip(PicturePtr pPicture)
{
    if (pPicture->clientClip)
        RegionDestroy(pPicture->clientClip);
    pPicture->clientClip = NULL;
}
Esempio n. 7
0
static int
RegionResFree(void *data, XID id)
{
    RegionPtr pRegion = (RegionPtr) data;

    RegionDestroy(pRegion);
    return Success;
}
Esempio n. 8
0
void
xnestDestroyClipHelper(GCPtr pGC)
{
  switch (pGC->clientClipType)
    {
    default:
    case CT_NONE:
      break;
      
    case CT_REGION:
      RegionDestroy(pGC->clientClip);
      break;
    }
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
Bool
glamor_solid_boxes(PixmapPtr pixmap,
                   BoxPtr box, int nbox, unsigned long fg_pixel)
{
    glamor_pixmap_private *pixmap_priv;
    GLfloat color[4];

    pixmap_priv = glamor_get_pixmap_private(pixmap);

    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
        return FALSE;

    glamor_get_rgba_from_pixel(fg_pixel,
                               &color[0],
                               &color[1],
                               &color[2], &color[3], format_for_pixmap(pixmap));

    if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
        RegionRec region;
        int n_region;
        glamor_pixmap_clipped_regions *clipped_regions;
        int i;

        RegionInitBoxes(&region, box, nbox);
        clipped_regions =
            glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0,
                                           0, 0);
        for (i = 0; i < n_region; i++) {
            BoxPtr inner_box;
            int inner_nbox;

            SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);

            inner_box = RegionRects(clipped_regions[i].region);
            inner_nbox = RegionNumRects(clipped_regions[i].region);
            _glamor_solid_boxes(pixmap, inner_box, inner_nbox, color);
            RegionDestroy(clipped_regions[i].region);
        }
        free(clipped_regions);
        RegionUninit(&region);
    }
    else
        _glamor_solid_boxes(pixmap, box, nbox, color);

    return TRUE;
}
void
miDestroyPictureClip (PicturePtr pPicture)
{
    switch (pPicture->clientClipType) {
    case CT_NONE:
	return;
    case CT_PIXMAP:
	(*pPicture->pDrawable->pScreen->DestroyPixmap) ((PixmapPtr) (pPicture->clientClip));
	break;
    default:
	/*
	 * we know we'll never have a list of rectangles, since ChangeClip
	 * immediately turns them into a region
	 */
	RegionDestroy(pPicture->clientClip);
	break;
    }
    pPicture->clientClip = NULL;
    pPicture->clientClipType = CT_NONE;
}    
Esempio n. 12
0
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 or fully clipped windows */
    if (pDstDrawable->type == DRAWABLE_WINDOW &&
        RegionNil(&((WindowPtr)pDstDrawable)->clipList)) {
        return NULL;
    }

    if (pSrcDrawable->pScreen->SourceValidate) {
        (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn,
                                                  widthSrc, heightSrc,
                                                  pGC->subWindowMode);
    }

    /* Compute source clip region */
    if (pSrcDrawable->type == DRAWABLE_PIXMAP) {
        if ((pSrcDrawable == pDstDrawable) && (!pGC->clientClip))
            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 &&
                RegionNotEmpty(&((WindowPtr) pSrcDrawable)->borderClip)) {
                /*
                 * special case bitblt from root window in
                 * IncludeInferiors mode; just like from a pixmap
                 */
                fastSrc = TRUE;
            }
            else if ((pSrcDrawable == pDstDrawable) && (!pGC->clientClip)) {
                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 (RegionNumRects(cclip) == 1) {
            BoxPtr pBox = RegionRects(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) {
        RegionNull(&rgnDst);
    }
    else {
        BoxRec box;

        box.x1 = box_x1;
        box.y1 = box_y1;
        box.x2 = box_x2;
        box.y2 = box_y2;
        RegionInit(&rgnDst, &box, 1);
    }

    /* Clip against complex source if needed */
    if (!fastSrc) {
        RegionIntersect(&rgnDst, &rgnDst, prgnSrcClip);
        RegionTranslate(&rgnDst, -dx, -dy);
    }

    /* Clip against complex dest if needed */
    if (!fastDst) {
        RegionIntersect(&rgnDst, &rgnDst, miGetCompositeClip(pGC));
    }

    /* Do bit blitting */
    numRects = RegionNumRects(&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);
    RegionUninit(&rgnDst);
    if (freeSrcClip)
        RegionDestroy(prgnSrcClip);
    return prgnExposed;
}
Esempio n. 13
0
static Bool
glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
                                    int h, int stride, void *bits, int pbo,
                                    PictFormatShort pict_format)
{
    ScreenPtr screen = pixmap->drawable.pScreen;
    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
    GLenum format, type;
    int no_alpha, revert, swap_rb;
    glamor_pixmap_private *pixmap_priv;
    Bool force_clip;

    if (glamor_get_tex_format_type_from_pixmap(pixmap,
                                               pict_format,
                                               &format,
                                               &type,
                                               &no_alpha,
                                               &revert, &swap_rb, 1)) {
        glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
        return FALSE;
    }
    if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
        return FALSE;

    pixmap_priv = glamor_get_pixmap_private(pixmap);
    force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
        && !glamor_check_fbo_size(glamor_priv, w, h);

    if (glamor_pixmap_priv_is_large(pixmap_priv) || force_clip) {
        RegionRec region;
        BoxRec box;
        int n_region;
        glamor_pixmap_clipped_regions *clipped_regions;
        void *sub_bits;
        int i, j;

        sub_bits = xallocarray(h, stride);
        if (sub_bits == NULL)
            return FALSE;
        box.x1 = x;
        box.y1 = y;
        box.x2 = x + w;
        box.y2 = y + h;
        RegionInitBoxes(&region, &box, 1);
        if (!force_clip)
            clipped_regions =
                glamor_compute_clipped_regions(pixmap, &region, &n_region,
                                               0, 0, 0);
        else
            clipped_regions =
                glamor_compute_clipped_regions_ext(pixmap, &region,
                                                   &n_region,
                                                   pixmap_priv->block_w,
                                                   pixmap_priv->block_h,
                                                   0,
                                                   0);
        DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
        for (i = 0; i < n_region; i++) {
            BoxPtr boxes;
            int nbox;
            int temp_stride;
            void *temp_bits;

            assert(pbo == 0);

            glamor_set_pixmap_fbo_current(pixmap_priv, clipped_regions[i].block_idx);

            boxes = RegionRects(clipped_regions[i].region);
            nbox = RegionNumRects(clipped_regions[i].region);
            DEBUGF("split to %d boxes\n", nbox);
            for (j = 0; j < nbox; j++) {
                temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
                                            pixmap->drawable.depth);

                if (boxes[j].x1 == x && temp_stride == stride) {
                    temp_bits = (char *) bits + (boxes[j].y1 - y) * stride;
                }
                else {
                    temp_bits = sub_bits;
                    glamor_put_bits(temp_bits, temp_stride, bits, stride,
                                    pixmap->drawable.bitsPerPixel,
                                    boxes[j].x1 - x, boxes[j].y1 - y,
                                    boxes[j].x2 - boxes[j].x1,
                                    boxes[j].y2 - boxes[j].y1);
                }
                DEBUGF("upload x %d y %d w %d h %d temp stride %d \n",
                       boxes[j].x1 - x, boxes[j].y1 - y,
                       boxes[j].x2 - boxes[j].x1,
                       boxes[j].y2 - boxes[j].y1, temp_stride);
                if (_glamor_upload_bits_to_pixmap_texture
                    (pixmap, format, type, no_alpha, revert, swap_rb,
                     boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1,
                     boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits,
                     pbo) == FALSE) {
                    RegionUninit(&region);
                    free(sub_bits);
                    assert(0);
                    return FALSE;
                }
            }
            RegionDestroy(clipped_regions[i].region);
        }
        free(sub_bits);
        free(clipped_regions);
        RegionUninit(&region);
        return TRUE;
    }
    else
        return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type,
                                                     no_alpha, revert, swap_rb,
                                                     x, y, w, h, stride, bits,
                                                     pbo);
}
Esempio n. 14
0
static Bool
_glamor_copy_n_to_n(DrawablePtr src,
		    DrawablePtr dst,
		    GCPtr gc,
		    BoxPtr box,
		    int nbox,
		    int dx,
		    int dy,
		    Bool reverse,
		    Bool upsidedown, Pixel bitplane,
		    void *closure, Bool fallback)
{
	PixmapPtr dst_pixmap, src_pixmap;
	glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
	glamor_screen_private *glamor_priv;
	glamor_gl_dispatch *dispatch;
	BoxPtr extent;
	RegionRec region;
	int src_x_off, src_y_off, dst_x_off, dst_y_off;
	Bool ok = FALSE;
	int force_clip = 0;

	if (nbox == 0)
		return TRUE;
	dst_pixmap = glamor_get_drawable_pixmap(dst);
	dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
	src_pixmap = glamor_get_drawable_pixmap(src);
	src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);

	glamor_priv = glamor_get_screen_private(dst->pScreen);

	DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
		box[0].x1, box[0].y1,
		box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
		dx, dy,
		src_pixmap, dst_pixmap);

	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
		goto fall_back;

	if (gc) {
		if (!glamor_set_planemask(dst_pixmap, gc->planemask))
			goto fall_back;
		dispatch = glamor_get_dispatch(glamor_priv);
		if (!glamor_set_alu(dispatch, gc->alu)) {
			glamor_put_dispatch(glamor_priv);
			goto fail_noregion;
		}
		glamor_put_dispatch(glamor_priv);
	}

	if (!src_pixmap_priv) {
		glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY);
		src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
	}

	glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
				   &src_y_off);
	glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
				   &dst_y_off);

	RegionInitBoxes(&region, box, nbox);
	extent = RegionExtents(&region);

	if (!glamor_check_fbo_size(glamor_priv,
		extent->x2 - extent->x1, extent->y2 - extent->y1)
	   && (src_pixmap_priv->type == GLAMOR_MEMORY
		|| (src_pixmap_priv == dst_pixmap_priv))) {
		force_clip = 1;
	}

	if (force_clip || dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
	    || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
			glamor_pixmap_clipped_regions *clipped_dst_regions;
			int n_dst_region, i, j;
			PixmapPtr temp_source_pixmap;
			glamor_pixmap_private *temp_source_priv = NULL;

			RegionTranslate(&region, dst_x_off, dst_y_off);
			if (!force_clip)
				clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
										     &region, &n_dst_region, 0,
										     reverse, upsidedown);
			else
				clipped_dst_regions = glamor_compute_clipped_regions_ext(dst_pixmap_priv,
										         &region, &n_dst_region,
											 glamor_priv->max_fbo_size,
											 glamor_priv->max_fbo_size,
											 reverse, upsidedown);
			for(i = 0; i < n_dst_region; i++)
			{
				int n_src_region;
				glamor_pixmap_clipped_regions *clipped_src_regions;
				BoxPtr current_boxes;
				int n_current_boxes;

				SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, clipped_dst_regions[i].block_idx);

				temp_source_pixmap = NULL;
				if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
					RegionTranslate(clipped_dst_regions[i].region,
							-dst_x_off + src_x_off + dx, -dst_y_off + src_y_off + dy);
					clipped_src_regions = glamor_compute_clipped_regions(src_pixmap_priv,
											     clipped_dst_regions[i].region,
											     &n_src_region, 0,
											     reverse, upsidedown);
					DEBUGF("Source is large pixmap.\n");
					for (j = 0; j < n_src_region; j++)
					{
						if (src_pixmap_priv != dst_pixmap_priv)
							SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, clipped_src_regions[j].block_idx);
						else if (src_pixmap_priv == dst_pixmap_priv &&
						    clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx) {
							/* source and the dest are the same, but need different block_idx.
							 * we create a empty pixmap and fill the required source fbo and box to
							 * it. It's a little hacky, but avoid extra copy. */
							temp_source_pixmap = glamor_create_pixmap(src->pScreen, 0, 0,
												  src->depth, 0);
							if (!temp_source_pixmap) {
								ok = FALSE;
								goto fail;
							}
							src->pScreen->ModifyPixmapHeader(temp_source_pixmap,
										      src_pixmap->drawable.width,
										      src_pixmap->drawable.height,
										      0, 0, src_pixmap->devKind, NULL);
							temp_source_priv = glamor_get_pixmap_private(temp_source_pixmap);
							*temp_source_priv = *src_pixmap_priv;
							temp_source_priv->large.box = src_pixmap_priv->large.box_array[clipped_src_regions[j].block_idx];
							temp_source_priv->base.fbo = src_pixmap_priv->large.fbo_array[clipped_src_regions[j].block_idx];
							temp_source_priv->base.pixmap = temp_source_pixmap;
						}
						assert(temp_source_pixmap || !(src_pixmap_priv == dst_pixmap_priv
							&& (clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx)));

						RegionTranslate(clipped_src_regions[j].region,
								-src_x_off - dx,
								-src_y_off - dy);
						current_boxes = RegionRects(clipped_src_regions[j].region);
						n_current_boxes = RegionNumRects(clipped_src_regions[j].region);
						DEBUGF("dst pixmap fbo idx %d src pixmap fbo idx %d \n",
							clipped_dst_regions[i].block_idx,
							clipped_src_regions[j].block_idx);
						DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
							current_boxes[0].x1, current_boxes[0].y1,
							current_boxes[0].x2, current_boxes[0].y2,
							dx, dy, src_pixmap, dst_pixmap);
						if (!temp_source_pixmap)
							ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
										  n_current_boxes, dx, dy, reverse,
										  upsidedown, bitplane, closure);
						else {
							ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable,
										  dst, gc, current_boxes,
										  n_current_boxes, dx, dy, reverse,
										  upsidedown, bitplane, closure);
							temp_source_priv->type = GLAMOR_MEMORY;
							temp_source_priv->base.fbo = NULL;
							glamor_destroy_pixmap(temp_source_pixmap);
							temp_source_pixmap = NULL;
						}

						RegionDestroy(clipped_src_regions[j].region);
						if (!ok) {
							assert(0);
							goto fail;
						}
					}

					if (n_src_region == 0)
						ok = TRUE;
					free(clipped_src_regions);
				} else {
					RegionTranslate(clipped_dst_regions[i].region,
							- dst_x_off,
							- dst_y_off);
					current_boxes = RegionRects(clipped_dst_regions[i].region);
					n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);

						DEBUGF("dest pixmap fbo idx %d \n",
							clipped_dst_regions[i].block_idx);
						DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
							current_boxes[0].x1, current_boxes[0].y1,
							current_boxes[0].x2, current_boxes[0].y2,
							dx, dy, src_pixmap, dst_pixmap);

					ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
								  n_current_boxes, dx, dy, reverse,
								  upsidedown, bitplane, closure);

				}
				RegionDestroy(clipped_dst_regions[i].region);
			}
		if (n_dst_region == 0)
			ok = TRUE;
		free(clipped_dst_regions);
	} else {
		ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy,
					  reverse, upsidedown, bitplane,
					  closure);
	}

fail:
	RegionUninit(&region);
fail_noregion:
	dispatch = glamor_get_dispatch(glamor_priv);
	glamor_set_alu(dispatch, GXcopy);
	glamor_put_dispatch(glamor_priv);

	if (ok)
		return TRUE;
fall_back:
	if (!fallback
	    && glamor_ddx_fallback_check_pixmap(src)
	    && glamor_ddx_fallback_check_pixmap(dst))
		goto done;

	if (src_pixmap_priv->type == GLAMOR_DRM_ONLY
	    || dst_pixmap_priv->type == GLAMOR_DRM_ONLY) {
		LogMessage(X_WARNING,
			   "Access a DRM only pixmap is not allowed within glamor.\n");
		return TRUE;
	}
	glamor_report_delayed_fallbacks(src->pScreen);
	glamor_report_delayed_fallbacks(dst->pScreen);

	glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
			glamor_get_drawable_location(src),
			glamor_get_drawable_location(dst));

	if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) &&
	    glamor_prepare_access(src, GLAMOR_ACCESS_RO) &&
	    glamor_prepare_access_gc(gc)) {
		fbCopyNtoN(src, dst, gc, box, nbox,
			   dx, dy, reverse, upsidedown, bitplane, closure);
	}
	glamor_finish_access_gc(gc);
	glamor_finish_access(src);
	glamor_finish_access(dst);
	ok = TRUE;

      done:
	glamor_clear_delayed_fallbacks(src->pScreen);
	glamor_clear_delayed_fallbacks(dst->pScreen);
	return ok;
}
Esempio n. 15
0
static void
XAACopyWindow8_32(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
    DDXPointPtr pptSrc, ppt;
    RegionRec rgnDst;
    BoxPtr pbox;
    int dx, dy, nbox;
    WindowPtr pwinRoot;
    ScreenPtr pScreen = pWin->drawable.pScreen;
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
    Bool doUnderlay = miOverlayCopyUnderlay(pScreen);
    RegionPtr borderClip = &pWin->borderClip;
    Bool freeReg = FALSE;

    if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt ||
        (infoRec->ScreenToScreenBitBltFlags & NO_PLANEMASK)) {
        XAA_SCREEN_PROLOGUE(pScreen, CopyWindow);
        if (infoRec->pScrn->vtSema && infoRec->NeedToSync) {
            (*infoRec->Sync) (infoRec->pScrn);
            infoRec->NeedToSync = FALSE;
        }
        (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
        XAA_SCREEN_EPILOGUE(pScreen, CopyWindow, XAACopyWindow8_32);
        return;
    }

    pwinRoot = pScreen->root;

    if (doUnderlay)
        freeReg = miOverlayCollectUnderlayRegions(pWin, &borderClip);

    RegionNull(&rgnDst);

    dx = ptOldOrg.x - pWin->drawable.x;
    dy = ptOldOrg.y - pWin->drawable.y;
    RegionTranslate(prgnSrc, -dx, -dy);
    RegionIntersect(&rgnDst, borderClip, prgnSrc);

    pbox = RegionRects(&rgnDst);
    nbox = RegionNumRects(&rgnDst);
    if (!nbox || !(pptSrc = (DDXPointPtr) malloc(nbox * sizeof(DDXPointRec)))) {
        RegionUninit(&rgnDst);
        return;
    }
    ppt = pptSrc;

    while (nbox--) {
        ppt->x = pbox->x1 + dx;
        ppt->y = pbox->y1 + dy;
        ppt++;
        pbox++;
    }

    infoRec->ScratchGC.planemask = doUnderlay ? 0x00ffffff : 0xff000000;
    infoRec->ScratchGC.alu = GXcopy;

    XAADoBitBlt((DrawablePtr) pwinRoot, (DrawablePtr) pwinRoot,
                &(infoRec->ScratchGC), &rgnDst, pptSrc);

    free(pptSrc);
    RegionUninit(&rgnDst);
    if (freeReg)
        RegionDestroy(borderClip);
}
Esempio n. 16
0
Bool
glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
            int x, int y, int width, int height,
            unsigned char alu, unsigned long planemask, int tile_x, int tile_y)
{
    ScreenPtr screen = pixmap->drawable.pScreen;
    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
    glamor_pixmap_private *dst_pixmap_priv;
    glamor_pixmap_private *src_pixmap_priv;

    dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
    src_pixmap_priv = glamor_get_pixmap_private(tile);

    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
        return FALSE;

    if (glamor_priv->tile_prog == 0) {
        glamor_fallback("Tiling unsupported\n");
        goto fail;
    }

    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
        /* XXX dynamic uploading candidate. */
        glamor_fallback("Non-texture tile pixmap\n");
        goto fail;
    }

    if (!glamor_set_planemask(pixmap, planemask)) {
        glamor_fallback("unsupported planemask %lx\n", planemask);
        goto fail;
    }

    glamor_make_current(glamor_priv);
    if (!glamor_set_alu(screen, alu)) {
        glamor_fallback("unsupported alu %x\n", alu);
        goto fail;
    }

    if (dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
        || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
        glamor_pixmap_clipped_regions *clipped_dst_regions;
        int n_dst_region, i, j, k;
        BoxRec box;
        RegionRec region;

        box.x1 = x;
        box.y1 = y;
        box.x2 = x + width;
        box.y2 = y + height;
        RegionInitBoxes(&region, &box, 1);
        clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
                                                             &region,
                                                             &n_dst_region, 0,
                                                             0, 0);
        for (i = 0; i < n_dst_region; i++) {
            int n_src_region;
            glamor_pixmap_clipped_regions *clipped_src_regions;
            BoxPtr current_boxes;
            int n_current_boxes;

            SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv,
                                   clipped_dst_regions[i].block_idx);

            if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
                RegionTranslate(clipped_dst_regions[i].region,
                                tile_x - x, tile_y - y);
                DEBUGF("tiled a large src pixmap. %dx%d \n",
                       tile->drawable.width, tile->drawable.height);
                clipped_src_regions =
                    glamor_compute_clipped_regions(src_pixmap_priv,
                                                   clipped_dst_regions[i].
                                                   region, &n_src_region, 1, 0,
                                                   0);
                DEBUGF("got %d src regions %d \n", n_src_region);
                for (j = 0; j < n_src_region; j++) {

                    SET_PIXMAP_FBO_CURRENT(src_pixmap_priv,
                                           clipped_src_regions[j].block_idx);

                    RegionTranslate(clipped_src_regions[j].region,
                                    x - tile_x, y - tile_y);
                    current_boxes = RegionRects(clipped_src_regions[j].region);
                    n_current_boxes =
                        RegionNumRects(clipped_src_regions[j].region);
                    for (k = 0; k < n_current_boxes; k++) {
                        DEBUGF
                            ("Tile on %d %d %d %d dst block id %d tile block id %d tilex %d tiley %d\n",
                             current_boxes[k].x1, current_boxes[k].y1,
                             current_boxes[k].x2 - current_boxes[k].x1,
                             current_boxes[k].y2 - current_boxes[k].y1,
                             clipped_dst_regions[i].block_idx,
                             clipped_src_regions[j].block_idx,
                             (tile_x + (current_boxes[k].x1 - x)),
                             tile_y + (current_boxes[k].y1 - y));

                        _glamor_tile(pixmap, tile,
                                     current_boxes[k].x1, current_boxes[k].y1,
                                     current_boxes[k].x2 - current_boxes[k].x1,
                                     current_boxes[k].y2 - current_boxes[k].y1,
                                     (tile_x + (current_boxes[k].x1 - x)),
                                     (tile_y + (current_boxes[k].y1 - y)));
                    }

                    RegionDestroy(clipped_src_regions[j].region);
                }
                free(clipped_src_regions);
            }
            else {
                current_boxes = RegionRects(clipped_dst_regions[i].region);
                n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
                for (k = 0; k < n_current_boxes; k++) {
                    _glamor_tile(pixmap, tile,
                                 current_boxes[k].x1, current_boxes[k].y1,
                                 current_boxes[k].x2 - current_boxes[k].x1,
                                 current_boxes[k].y2 - current_boxes[k].y1,
                                 (tile_x + (current_boxes[k].x1 - x)),
                                 (tile_y + (current_boxes[k].y1 - y)));
                }
            }
            RegionDestroy(clipped_dst_regions[i].region);
        }
        free(clipped_dst_regions);
        RegionUninit(&region);
    }
    else
        _glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);

    glamor_set_alu(screen, GXcopy);
    return TRUE;
 fail:
    return FALSE;

}
Esempio n. 17
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;
}
Esempio n. 18
0
void
rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{
    RegionRec clip_reg;
    RegionPtr tmpRegion;
    int cd;
    int lw;
    int extra;
    int i;
    int num_clips;
    int got_id;
    int dirty_type;
    int post_process;
    int reset_surface;
    xRectangle *rects;
    BoxRec box;
    struct image_data id;
    WindowPtr pDstWnd;
    PixmapPtr pDstPixmap;
    rdpPixmapRec *pDstPriv;
    rdpPixmapRec *pDirtyPriv;

    LLOGLN(10, ("rdpPolyFillArc:"));

    rects = 0;

    if (narcs > 0)
    {
        rects = (xRectangle *)g_malloc(narcs * sizeof(xRectangle), 0);
        lw = pGC->lineWidth;

        if (lw == 0)
        {
            lw = 1;
        }

        extra = lw / 2;

        for (i = 0; i < narcs; i++)
        {
            rects[i].x = (parcs[i].x - extra) + pDrawable->x;
            rects[i].y = (parcs[i].y - extra) + pDrawable->y;
            rects[i].width = parcs[i].width + lw;
            rects[i].height = parcs[i].height + lw;
        }
    }

    /* do original call */
    rdpPolyFillArcOrg(pDrawable, pGC, narcs, parcs);

    dirty_type = 0;
    pDirtyPriv = 0;
    post_process = 0;
    reset_surface = 0;
    got_id = 0;

    if (pDrawable->type == DRAWABLE_PIXMAP)
    {
        pDstPixmap = (PixmapPtr)pDrawable;
        pDstPriv = GETPIXPRIV(pDstPixmap);

        if (xrdp_is_os(pDstPixmap, pDstPriv))
        {
            post_process = 1;

            if (g_do_dirty_os)
            {
                LLOGLN(10, ("rdpPolyFillArc: getting dirty"));
                pDstPriv->is_dirty = 1;
                pDirtyPriv = pDstPriv;
                dirty_type = RDI_IMGLY;
            }
            else
            {
                rdpup_switch_os_surface(pDstPriv->rdpindex);
                reset_surface = 1;
                rdpup_get_pixmap_image_rect(pDstPixmap, &id);
                got_id = 1;
            }
        }
    }
    else
    {
        if (pDrawable->type == DRAWABLE_WINDOW)
        {
            pDstWnd = (WindowPtr)pDrawable;

            if (pDstWnd->viewable)
            {
                post_process = 1;

                if (g_do_dirty_ons)
                {
                    LLOGLN(10, ("rdpPolyFillArc: getting dirty"));
                    g_screenPriv.is_dirty = 1;
                    pDirtyPriv = &g_screenPriv;
                    dirty_type = RDI_IMGLL;
                }
                else
                {
                    rdpup_get_screen_image_rect(&id);
                    got_id = 1;
                }
            }
        }
    }

    if (!post_process)
    {
        g_free(rects);
        return;
    }

    RegionInit(&clip_reg, NullBox, 0);
    cd = rdp_get_clip(&clip_reg, pDrawable, pGC);

    if (cd == 1)
    {
        if (rects != 0)
        {
            tmpRegion = RegionFromRects(narcs, rects, CT_NONE);
            num_clips = REGION_NUM_RECTS(tmpRegion);

            if (num_clips > 0)
            {
                if (dirty_type != 0)
                {
                    draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type, TAG_POLYFILLARC);
                }
                else if (got_id)
                {
                    rdpup_begin_update();

                    for (i = num_clips - 1; i >= 0; i--)
                    {
                        box = REGION_RECTS(tmpRegion)[i];
                        rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
                                        box.y2 - box.y1);
                    }

                    rdpup_end_update();
                }
            }

            RegionDestroy(tmpRegion);
        }
    }
    else if (cd == 2)
    {
        if (rects != 0)
        {
            tmpRegion = RegionFromRects(narcs, rects, CT_NONE);
            RegionIntersect(tmpRegion, tmpRegion, &clip_reg);
            num_clips = REGION_NUM_RECTS(tmpRegion);

            if (num_clips > 0)
            {
                if (dirty_type != 0)
                {
                    draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type, TAG_POLYFILLARC);
                }
                else if (got_id)
                {
                    rdpup_begin_update();

                    for (i = num_clips - 1; i >= 0; i--)
                    {
                        box = REGION_RECTS(tmpRegion)[i];
                        rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
                                        box.y2 - box.y1);
                    }

                    rdpup_end_update();
                }
            }

            RegionDestroy(tmpRegion);
        }
    }

    RegionUninit(&clip_reg);
    g_free(rects);

    if (reset_surface)
    {
        rdpup_switch_os_surface(-1);
    }
}
Esempio n. 19
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;
}
Esempio n. 20
0
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 */
Esempio n. 21
0
/*
 *-----------------------------------------------------------------------
 * miComputeClips --
 *	Recompute the clipList, borderClip, exposed and borderExposed
 *	regions for pParent and its children. Only viewable windows are
 *	taken into account.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	clipList, borderClip, exposed and borderExposed are altered.
 *	A VisibilityNotify event may be generated on the parent window.
 *
 *-----------------------------------------------------------------------
 */
static void
miComputeClips (
    WindowPtr	pParent,
    ScreenPtr	pScreen,
    RegionPtr	universe,
    VTKind		kind,
    RegionPtr		exposed ) /* for intermediate calculations */
{
    int			dx,
			dy;
    RegionRec		childUniverse;
    WindowPtr		pChild;
    int     	  	oldVis, newVis;
    BoxRec		borderSize;
    RegionRec		childUnion;
    Bool		overlap;
    RegionPtr		borderVisible;
    /*
     * Figure out the new visibility of this window.
     * The extent of the universe should be the same as the extent of
     * the borderSize region. If the window is unobscured, this rectangle
     * will be completely inside the universe (the universe will cover it
     * completely). If the window is completely obscured, none of the
     * universe will cover the rectangle.
     */
    borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
    borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
    dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent);
    if (dx > 32767)
	dx = 32767;
    borderSize.x2 = dx;
    dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent);
    if (dy > 32767)
	dy = 32767;
    borderSize.y2 = dy;

#ifdef COMPOSITE
    /*
     * In redirected drawing case, reset universe to borderSize
     */
    if (pParent->redirectDraw != RedirectDrawNone)
    {
	if (miSetRedirectBorderClipProc)
	{
	    if (TreatAsTransparent (pParent))
		RegionEmpty(universe);
	    (*miSetRedirectBorderClipProc) (pParent, universe);
	}
	RegionCopy(universe, &pParent->borderSize);
    }
#endif

    oldVis = pParent->visibility;
    switch (RegionContainsRect(universe, &borderSize))
    {
	case rgnIN:
	    newVis = VisibilityUnobscured;
	    break;
	case rgnPART:
	    newVis = VisibilityPartiallyObscured;
	    {
		RegionPtr   pBounding;

		if ((pBounding = wBoundingShape (pParent)))
		{
		    switch (miShapedWindowIn (universe, pBounding,
					      &borderSize,
					      pParent->drawable.x,
 					      pParent->drawable.y))
		    {
		    case rgnIN:
			newVis = VisibilityUnobscured;
			break;
		    case rgnOUT:
			newVis = VisibilityFullyObscured;
			break;
		    }
		}
	    }
	    break;
	default:
	    newVis = VisibilityFullyObscured;
	    break;
    }
    pParent->visibility = newVis;
    if (oldVis != newVis &&
	((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
	SendVisibilityNotify(pParent);

    dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
    dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;

    /*
     * avoid computations when dealing with simple operations
     */

    switch (kind) {
    case VTMap:
    case VTStack:
    case VTUnmap:
	break;
    case VTMove:
	if ((oldVis == newVis) &&
	    ((oldVis == VisibilityFullyObscured) ||
	     (oldVis == VisibilityUnobscured)))
	{
	    pChild = pParent;
	    while (1)
	    {
		if (pChild->viewable)
		{
		    if (pChild->visibility != VisibilityFullyObscured)
		    {
			RegionTranslate(&pChild->borderClip,
						      dx, dy);
			RegionTranslate(&pChild->clipList,
						      dx, dy);
			pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
			if (pScreen->ClipNotify)
			    (* pScreen->ClipNotify) (pChild, dx, dy);

		    }
		    if (pChild->valdata)
		    {
			RegionNull(&pChild->valdata->after.borderExposed);
			if (HasParentRelativeBorder(pChild))
			{
			    RegionSubtract(&pChild->valdata->after.borderExposed,
					   &pChild->borderClip,
					   &pChild->winSize);
			}
			RegionNull(&pChild->valdata->after.exposed);
		    }
		    if (pChild->firstChild)
		    {
			pChild = pChild->firstChild;
			continue;
		    }
		}
		while (!pChild->nextSib && (pChild != pParent))
		    pChild = pChild->parent;
		if (pChild == pParent)
		    break;
		pChild = pChild->nextSib;
	    }
	    return;
	}
	/* fall through */
    default:
    	/*
     	 * To calculate exposures correctly, we have to translate the old
     	 * borderClip and clipList regions to the window's new location so there
     	 * is a correspondence between pieces of the new and old clipping regions.
     	 */
    	if (dx || dy) 
    	{
	    /*
	     * We translate the old clipList because that will be exposed or copied
	     * if gravity is right.
	     */
	    RegionTranslate(&pParent->borderClip, dx, dy);
	    RegionTranslate(&pParent->clipList, dx, dy);
    	} 
	break;
    case VTBroken:
	RegionEmpty(&pParent->borderClip);
	RegionEmpty(&pParent->clipList);
	break;
    }

    borderVisible = pParent->valdata->before.borderVisible;
    RegionNull(&pParent->valdata->after.borderExposed);
    RegionNull(&pParent->valdata->after.exposed);

    /*
     * Since the borderClip must not be clipped by the children, we do
     * the border exposure first...
     *
     * 'universe' is the window's borderClip. To figure the exposures, remove
     * the area that used to be exposed from the new.
     * This leaves a region of pieces that weren't exposed before.
     */

    if (HasBorder (pParent))
    {
    	if (borderVisible)
    	{
	    /*
	     * when the border changes shape, the old visible portions
	     * of the border will be saved by DIX in borderVisible --
	     * use that region and destroy it
	     */
	    RegionSubtract(exposed, universe, borderVisible);
	    RegionDestroy(borderVisible);
    	}
    	else
    	{
	    RegionSubtract(exposed, universe, &pParent->borderClip);
    	}
	if (HasParentRelativeBorder(pParent) && (dx || dy))
	    RegionSubtract(&pParent->valdata->after.borderExposed,
				  universe,
				  &pParent->winSize);
	else
	    RegionSubtract(&pParent->valdata->after.borderExposed,
			       exposed, &pParent->winSize);

	RegionCopy(&pParent->borderClip, universe);
    
    	/*
     	 * To get the right clipList for the parent, and to make doubly sure
     	 * that no child overlaps the parent's border, we remove the parent's
     	 * border from the universe before proceeding.
     	 */
    
	RegionIntersect(universe, universe, &pParent->winSize);
    }
    else
	RegionCopy(&pParent->borderClip, universe);
    
    if ((pChild = pParent->firstChild) && pParent->mapped)
    {
	RegionNull(&childUniverse);
	RegionNull(&childUnion);
	if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
	    ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
	     (pChild->drawable.x < pParent->lastChild->drawable.x)))
	{
	    for (; pChild; pChild = pChild->nextSib)
	    {
		if (pChild->viewable && !TreatAsTransparent(pChild))
		    RegionAppend(&childUnion, &pChild->borderSize);
	    }
	}
	else
	{
	    for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
	    {
		if (pChild->viewable && !TreatAsTransparent(pChild))
		    RegionAppend(&childUnion, &pChild->borderSize);
	    }
	}
	RegionValidate(&childUnion, &overlap);

	for (pChild = pParent->firstChild;
	     pChild;
	     pChild = pChild->nextSib)
 	{
	    if (pChild->viewable) {
		/*
		 * If the child is viewable, we want to remove its extents
		 * from the current universe, but we only re-clip it if
		 * it's been marked.
		 */
		if (pChild->valdata) {
		    /*
		     * Figure out the new universe from the child's
		     * perspective and recurse.
		     */
		    RegionIntersect(&childUniverse,
					    universe,
					    &pChild->borderSize);
		    miComputeClips (pChild, pScreen, &childUniverse, kind,
				    exposed);
		}
		/*
		 * Once the child has been processed, we remove its extents
		 * from the current universe, thus denying its space to any
		 * other sibling.
		 */
		if (overlap && !TreatAsTransparent (pChild))
		    RegionSubtract(universe, universe,
					  &pChild->borderSize);
	    }
	}
	if (!overlap)
	    RegionSubtract(universe, universe, &childUnion);
	RegionUninit(&childUnion);
	RegionUninit(&childUniverse);
    } /* if any children */

    /*
     * 'universe' now contains the new clipList for the parent window.
     *
     * To figure the exposure of the window we subtract the old clip from the
     * new, just as for the border.
     */

    if (oldVis == VisibilityFullyObscured ||
	oldVis == VisibilityNotViewable)
    {
	RegionCopy(&pParent->valdata->after.exposed, universe);
    }
    else if (newVis != VisibilityFullyObscured &&
	     newVis != VisibilityNotViewable)
    {
	RegionSubtract(&pParent->valdata->after.exposed,
			       universe, &pParent->clipList);
    }

    /* HACK ALERT - copying contents of regions, instead of regions */
    {
	RegionRec   tmp;

	tmp = pParent->clipList;
	pParent->clipList = *universe;
	*universe = tmp;
    }

#ifdef NOTDEF
    RegionCopy(&pParent->clipList, universe);
#endif

    pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;

    if (pScreen->ClipNotify)
	(* pScreen->ClipNotify) (pParent, dx, dy);
}
Esempio n. 22
0
void
miDestroyGC(GCPtr pGC)
{
    if (pGC->freeCompClip)
        RegionDestroy(pGC->pCompositeClip);
}
Esempio n. 23
0
int
ProcXFixesSetWindowShapeRegion(ClientPtr client)
{
    WindowPtr pWin;
    RegionPtr pRegion;
    RegionPtr *pDestRegion;
    int rc;

    REQUEST(xXFixesSetWindowShapeRegionReq);

    REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
    rc = dixLookupResourceByType((void **) &pWin, stuff->dest, RT_WINDOW,
                                 client, DixSetAttrAccess);
    if (rc != Success) {
        client->errorValue = stuff->dest;
        return rc;
    }
    VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixWriteAccess);
    switch (stuff->destKind) {
    case ShapeBounding:
    case ShapeClip:
    case ShapeInput:
        break;
    default:
        client->errorValue = stuff->destKind;
        return BadValue;
    }
    if (pRegion) {
        pRegion = XFixesRegionCopy(pRegion);
        if (!pRegion)
            return BadAlloc;
        if (!pWin->optional)
            MakeWindowOptional(pWin);
        switch (stuff->destKind) {
        default:
        case ShapeBounding:
            pDestRegion = &pWin->optional->boundingShape;
            break;
        case ShapeClip:
            pDestRegion = &pWin->optional->clipShape;
            break;
        case ShapeInput:
            pDestRegion = &pWin->optional->inputShape;
            break;
        }
        if (stuff->xOff || stuff->yOff)
            RegionTranslate(pRegion, stuff->xOff, stuff->yOff);
    }
    else {
        if (pWin->optional) {
            switch (stuff->destKind) {
            default:
            case ShapeBounding:
                pDestRegion = &pWin->optional->boundingShape;
                break;
            case ShapeClip:
                pDestRegion = &pWin->optional->clipShape;
                break;
            case ShapeInput:
                pDestRegion = &pWin->optional->inputShape;
                break;
            }
        }
        else
            pDestRegion = &pRegion;     /* a NULL region pointer */
    }
    if (*pDestRegion)
        RegionDestroy(*pDestRegion);
    *pDestRegion = pRegion;
    (*pWin->drawable.pScreen->SetShape) (pWin, stuff->destKind);
    SendShapeNotify(pWin, stuff->destKind);
    return Success;
}
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 */
    }
}
Esempio n. 25
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! */
    }
}
void
miDestroyPicture (PicturePtr pPicture)
{
    if (pPicture->freeCompClip)
	RegionDestroy(pPicture->pCompositeClip);
}
Esempio n. 27
0
/* tested with pGC->lineWidth = 0, 1, 2, 4 and opcodes 3 and 6 */
void rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
		xRectangle *rects)
{
	RegionRec clip_reg;
	RegionPtr fill_reg;
	int num_clips;
	int cd;
	int lw;
	int i;
	int j;
	int up;
	int down;
	int got_id;
	int dirty_type;
	int post_process;
	int reset_surface;
	xRectangle *regRects;
	xRectangle *r;
	xRectangle *rect1;
	BoxRec box;
	struct image_data id;

	WindowPtr pDstWnd;
	PixmapPtr pDstPixmap;
	rdpPixmapRec *pDstPriv;
	rdpPixmapRec *pDirtyPriv;

	LLOGLN(10, ("rdpPolyRectangle:"));

	/* make a copy of rects */
	rect1 = (xRectangle *)g_malloc(sizeof(xRectangle) * nrects, 0);

	for (i = 0; i < nrects; i++)
	{
		rect1[i] = rects[i];
	}

	/* do original call */
	rdpPolyRectangleOrg(pDrawable, pGC, nrects, rects);

	dirty_type = 0;
	pDirtyPriv = 0;
	post_process = 0;
	reset_surface = 0;
	got_id = 0;

	if (pDrawable->type == DRAWABLE_PIXMAP)
	{
		pDstPixmap = (PixmapPtr)pDrawable;
		pDstPriv = GETPIXPRIV(pDstPixmap);

		if (xrdp_is_os(pDstPixmap, pDstPriv))
		{
			post_process = 1;

			if (g_do_dirty_os)
			{
				LLOGLN(10, ("rdpPolyRectangle: gettig dirty"));
				pDstPriv->is_dirty = 1;
				pDirtyPriv = pDstPriv;
				dirty_type = RDI_IMGLL;
			}
			else
			{
				rdpup_switch_os_surface(pDstPriv->rdpindex);
				reset_surface = 1;
				rdpup_get_pixmap_image_rect(pDstPixmap, &id);
				got_id = 1;
			}
		}
	}
	else
	{
		if (pDrawable->type == DRAWABLE_WINDOW)
		{
			pDstWnd = (WindowPtr)pDrawable;

			if (pDstWnd->viewable)
			{
				post_process = 1;

				if (g_do_dirty_ons)
				{
					LLOGLN(0, ("rdpPolyRectangle: gettig dirty"));
					g_screenPriv.is_dirty = 1;
					pDirtyPriv = &g_screenPriv;
					dirty_type = RDI_IMGLL;
				}
				else
				{
					rdpup_get_screen_image_rect(&id);
					got_id = 1;
				}
			}
		}
	}

	if (!post_process)
	{
		g_free(rect1);
		return;
	}

	RegionInit(&clip_reg, NullBox, 0);
	cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
	regRects = 0;

	if ((cd != 0) && (nrects > 0))
	{
		regRects = (xRectangle *)g_malloc(nrects * 4 * sizeof(xRectangle), 0);
		lw = pGC->lineWidth;

		if (lw < 1)
		{
			lw = 1;
		}

		up = lw / 2;
		down = 1 + (lw - 1) / 2;

		for (i = 0; i < nrects; i++)
		{
			r = regRects + i * 4;
			r->x = (rect1[i].x + pDrawable->x) - up;
			r->y = (rect1[i].y + pDrawable->y) - up;
			r->width = rect1[i].width + up + down;
			r->height = lw;
			r++;
			r->x = (rect1[i].x + pDrawable->x) - up;
			r->y = (rect1[i].y + pDrawable->y) + down;
			r->width = lw;
			r->height = MAX(rect1[i].height - (up + down), 0);
			r++;
			r->x = ((rect1[i].x + rect1[i].width) + pDrawable->x) - up;
			r->y = (rect1[i].y + pDrawable->y) + down;
			r->width = lw;
			r->height = MAX(rect1[i].height - (up + down), 0);
			r++;
			r->x = (rect1[i].x + pDrawable->x) - up;
			r->y = ((rect1[i].y + rect1[i].height) + pDrawable->y) - up;
			r->width = rect1[i].width + up + down;
			r->height = lw;
		}
	}

	if (cd == 1)
	{
		if (regRects != 0)
		{
			if (dirty_type != 0)
			{
				fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE);

				if (pGC->lineStyle == LineSolid)
				{
					draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel,
							pGC->alu);
				}
				else
				{
					draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, dirty_type);
				}

				RegionDestroy(fill_reg);
			}
			else if (got_id)
			{
				rdpup_begin_update();

				if (pGC->lineStyle == LineSolid)
				{
					rdpup_set_fgcolor(pGC->fgPixel);
					rdpup_set_opcode(pGC->alu);

					for (i = 0; i < nrects * 4; i++)
					{
						r = regRects + i;
						rdpup_fill_rect(r->x, r->y, r->width, r->height);
					}

					rdpup_set_opcode(GXcopy);
				}
				else
				{
					for (i = 0; i < nrects * 4; i++)
					{
						r = regRects + i;
						rdpup_send_area(&id, r->x, r->y, r->width, r->height);
					}
				}

				rdpup_end_update();
			}
		}
	}
	else if (cd == 2)
	{
		if (regRects != 0)
		{
			fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE);
			RegionIntersect(&clip_reg, &clip_reg, fill_reg);
			num_clips = REGION_NUM_RECTS(&clip_reg);

			if (num_clips > 0)
			{
				if (dirty_type != 0)
				{
					if (pGC->lineStyle == LineSolid)
					{
						draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
								pGC->alu);
					}
					else
					{
						draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type);
					}
				}
				else if (got_id)
				{
					rdpup_begin_update();

					if (pGC->lineStyle == LineSolid)
					{
						rdpup_set_fgcolor(pGC->fgPixel);
						rdpup_set_opcode(pGC->alu);

						for (j = num_clips - 1; j >= 0; j--)
						{
							box = REGION_RECTS(&clip_reg)[j];
							rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
						}

						rdpup_set_opcode(GXcopy);
					}
					else
					{
						for (j = num_clips - 1; j >= 0; j--)
						{
							box = REGION_RECTS(&clip_reg)[j];
							rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
						}
					}

					rdpup_end_update();
				}
			}

			RegionDestroy(fill_reg);
		}
	}

	RegionUninit(&clip_reg);
	g_free(regRects);
	g_free(rect1);

	if (reset_surface)
	{
		rdpup_switch_os_surface(-1);
	}
}
Esempio n. 28
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);
}
Esempio n. 29
0
static void
exaPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle *prect)
{
    ExaScreenPriv(pDrawable->pScreen);
    RegionPtr pClip = fbGetCompositeClip(pGC);
    PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);

    ExaPixmapPriv(pPixmap);
    register BoxPtr pbox;
    BoxPtr pextent;
    int extentX1, extentX2, extentY1, extentY2;
    int fullX1, fullX2, fullY1, fullY2;
    int partX1, partX2, partY1, partY2;
    int xoff, yoff;
    int xorg, yorg;
    int n;
    RegionPtr pReg = RegionFromRects(nrect, prect, CT_UNSORTED);

    /* Compute intersection of rects and clip region */
    RegionTranslate(pReg, pDrawable->x, pDrawable->y);
    RegionIntersect(pReg, pClip, pReg);

    if (!RegionNumRects(pReg)) {
        goto out;
    }

    exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);

    if (pExaScr->fallback_counter || pExaScr->swappedOut ||
        pExaPixmap->accel_blocked) {
        goto fallback;
    }

    /* For ROPs where overlaps don't matter, convert rectangles to region and
     * call exaFillRegion{Solid,Tiled}.
     */
    if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) &&
        (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear ||
         pGC->alu == GXnoop || pGC->alu == GXcopyInverted ||
         pGC->alu == GXset)) {
        if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
             exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ?
                                pGC->fgPixel : pGC->tile.pixel, pGC->planemask,
                                pGC->alu, pGC->clientClip != NULL)) ||
            (pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
             exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
                                pGC->planemask, pGC->alu,
                                pGC->clientClip != NULL))) {
            goto out;
        }
    }

    if (pGC->fillStyle != FillSolid &&
        !(pGC->tileIsPixel && pGC->fillStyle == FillTiled)) {
        goto fallback;
    }

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

        pixmaps[0].as_dst = TRUE;
        pixmaps[0].as_src = FALSE;
        pixmaps[0].pPix = pPixmap;
        pixmaps[0].pReg = NULL;

        exaDoMigration(pixmaps, 1, TRUE);
    }

    if (!exaPixmapHasGpuCopy(pPixmap) ||
        !(*pExaScr->info->PrepareSolid) (pPixmap,
                                         pGC->alu,
                                         pGC->planemask, pGC->fgPixel)) {
 fallback:
        ExaCheckPolyFillRect(pDrawable, pGC, nrect, prect);
        goto out;
    }

    xorg = pDrawable->x;
    yorg = pDrawable->y;

    pextent = RegionExtents(pClip);
    extentX1 = pextent->x1;
    extentY1 = pextent->y1;
    extentX2 = pextent->x2;
    extentY2 = pextent->y2;
    while (nrect--) {
        fullX1 = prect->x + xorg;
        fullY1 = prect->y + yorg;
        fullX2 = fullX1 + (int) prect->width;
        fullY2 = fullY1 + (int) prect->height;
        prect++;

        if (fullX1 < extentX1)
            fullX1 = extentX1;

        if (fullY1 < extentY1)
            fullY1 = extentY1;

        if (fullX2 > extentX2)
            fullX2 = extentX2;

        if (fullY2 > extentY2)
            fullY2 = extentY2;

        if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
            continue;
        n = RegionNumRects(pClip);
        if (n == 1) {
            (*pExaScr->info->Solid) (pPixmap,
                                     fullX1 + xoff, fullY1 + yoff,
                                     fullX2 + xoff, fullY2 + yoff);
        }
        else {
            pbox = RegionRects(pClip);
            /*
             * clip the rectangle to each box in the clip region
             * this is logically equivalent to calling Intersect(),
             * but rectangles may overlap each other here.
             */
            while (n--) {
                partX1 = pbox->x1;
                if (partX1 < fullX1)
                    partX1 = fullX1;
                partY1 = pbox->y1;
                if (partY1 < fullY1)
                    partY1 = fullY1;
                partX2 = pbox->x2;
                if (partX2 > fullX2)
                    partX2 = fullX2;
                partY2 = pbox->y2;
                if (partY2 > fullY2)
                    partY2 = fullY2;

                pbox++;

                if (partX1 < partX2 && partY1 < partY2) {
                    (*pExaScr->info->Solid) (pPixmap,
                                             partX1 + xoff, partY1 + yoff,
                                             partX2 + xoff, partY2 + yoff);
                }
            }
        }
    }
    (*pExaScr->info->DoneSolid) (pPixmap);
    exaMarkSync(pDrawable->pScreen);

 out:
    RegionUninit(pReg);
    RegionDestroy(pReg);
}
Esempio n. 30
0
Bool
xf86InitFBManagerArea(ScreenPtr pScreen, int PixelArea, int Verbosity)
{
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    xRectangle Rect[3];
    RegionPtr pRegion, pScreenRegion;
    int nRect;
    Bool ret = FALSE;

    if (PixelArea < (pScrn->displayWidth * pScrn->virtualY))
        return FALSE;

    Rect[0].x = Rect[0].y = 0;
    Rect[0].width = pScrn->displayWidth;
    Rect[0].height = PixelArea / pScrn->displayWidth;
    nRect = 1;

    /* Add a possible partial scanline */
    if ((Rect[1].height = Rect[1].width = PixelArea % pScrn->displayWidth)) {
        Rect[1].x = 0;
        Rect[1].y = Rect[0].height;
        Rect[1].height = 1;
        nRect++;
    }

    /* Factor out virtual resolution */
    pRegion = RegionFromRects(nRect, Rect, 0);
    if (pRegion) {
        if (!RegionNar(pRegion)) {
            Rect[2].x = Rect[2].y = 0;
            Rect[2].width = pScrn->virtualX;
            Rect[2].height = pScrn->virtualY;

            pScreenRegion = RegionFromRects(1, &Rect[2], 0);
            if (pScreenRegion) {
                if (!RegionNar(pScreenRegion)) {
                    RegionSubtract(pRegion, pRegion, pScreenRegion);

                    ret = xf86InitFBManagerRegion(pScreen, pRegion);

                    if (ret && xf86GetVerbosity() >= Verbosity) {
                        int scrnIndex = pScrn->scrnIndex;

                        xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
                                       "Largest offscreen areas (with overlaps):\n");

                        if (Rect[2].width < Rect[0].width) {
                            xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
                                           "\t%d x %d rectangle at %d,0\n",
                                           Rect[0].width - Rect[2].width,
                                           Rect[0].height, Rect[2].width);
                        }
                        if (Rect[2].width < Rect[1].width) {
                            xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
                                           "\t%d x %d rectangle at %d,0\n",
                                           Rect[1].width - Rect[2].width,
                                           Rect[0].height + Rect[1].height,
                                           Rect[2].width);
                        }
                        if (Rect[2].height < Rect[0].height) {
                            xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
                                           "\t%d x %d rectangle at 0,%d\n",
                                           Rect[0].width,
                                           Rect[0].height - Rect[2].height,
                                           Rect[2].height);
                        }
                        if (Rect[1].height) {
                            xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
                                           "\t%d x %d rectangle at 0,%d\n",
                                           Rect[1].width,
                                           Rect[0].height - Rect[2].height +
                                           Rect[1].height, Rect[2].height);
                        }
                    }
                }

                RegionDestroy(pScreenRegion);
            }
        }

        RegionDestroy(pRegion);
    }

    return ret;
}