Ejemplo n.º 1
0
RegionPtr
rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
            int srcx, int srcy, int w, int h, int dstx, int dsty)
{
    RegionPtr rv;
    RegionRec clip_reg;
    RegionRec box_reg;
    RegionRec reg1;
    int num_clips;
    int cd;
    int j;
    int can_do_screen_blt;
    int got_id;
    int dirty_type;
    int post_process;
    int reset_surface;
    struct image_data id;
    BoxRec box;
    BoxPtr pbox;
    PixmapPtr pSrcPixmap;
    PixmapPtr pDstPixmap;
    rdpPixmapRec *pSrcPriv;
    rdpPixmapRec *pDstPriv;
    rdpPixmapRec *pDirtyPriv;
    WindowPtr pDstWnd;
    WindowPtr pSrcWnd;

    LLOGLN(10, ("rdpCopyArea: x %d y %d w %d h %d", dstx, dsty, w, h));

    if (pSrc->type == DRAWABLE_WINDOW)
    {
        pSrcWnd = (WindowPtr)pSrc;

        if (pSrcWnd->viewable)
        {
            rdpup_check_dirty_screen(&g_screenPriv);

            if (pDst->type == DRAWABLE_WINDOW)
            {
                pDstWnd = (WindowPtr)pDst;

                if (pDstWnd->viewable)
                {
                    can_do_screen_blt = pGC->alu == GXcopy;

                    if (can_do_screen_blt)
                    {
                        return rdpCopyAreaWndToWnd(pSrcWnd, pDstWnd, pGC,
                                                   srcx, srcy, w, h, dstx, dsty);
                    }
                }
            }
            else if (pDst->type == DRAWABLE_PIXMAP)
            {
                pDstPixmap = (PixmapPtr)pDst;
                pDstPriv = GETPIXPRIV(pDstPixmap);

                if (xrdp_is_os(pDstPixmap, pDstPriv))
                {
                    can_do_screen_blt = pGC->alu == GXcopy;

                    if (can_do_screen_blt)
                    {
                        rdpup_check_dirty(pDstPixmap, pDstPriv);
                        return rdpCopyAreaWndToPixmap(pSrcWnd, pDstPixmap, pDstPriv, pGC,
                                                      srcx, srcy, w, h, dstx, dsty);
                    }
                }
                else
                {
                    LLOGLN(10, ("rdpCopyArea: 1"));
                }
            }
        }
    }

    if (pSrc->type == DRAWABLE_PIXMAP)
    {
        pSrcPixmap = (PixmapPtr)pSrc;
        pSrcPriv = GETPIXPRIV(pSrcPixmap);

        if (xrdp_is_os(pSrcPixmap, pSrcPriv))
        {
            if (pDst->type == DRAWABLE_WINDOW)
            {
                pDstWnd = (WindowPtr)pDst;

                if (pDstWnd->viewable)
                {
                    rdpup_check_dirty_screen(&g_screenPriv);
                    rdpup_check_dirty(pSrcPixmap, pSrcPriv);
                    return rdpCopyAreaPixmapToWnd(pSrcPixmap, pSrcPriv, pDstWnd, pGC,
                                                  srcx, srcy, w, h, dstx, dsty);
                }
            }
            else if (pDst->type == DRAWABLE_PIXMAP)
            {
                pDstPixmap = (PixmapPtr)pDst;
                pDstPriv = GETPIXPRIV(pDstPixmap);

                if (xrdp_is_os(pDstPixmap, pDstPriv))
                {
                    if (g_can_do_pix_to_pix)
                    {
                        rdpup_check_dirty(pSrcPixmap, pSrcPriv);
                        rdpup_check_dirty(pDstPixmap, pDstPriv);
                        return rdpCopyAreaPixmapToPixmap(pSrcPixmap, pSrcPriv,
                                                         pDstPixmap, pDstPriv,
                                                         pGC, srcx, srcy, w, h,
                                                         dstx, dsty);
                    }
                }
                else
                {
                    LLOGLN(10, ("rdpCopyArea: 4"));
                }
            }
        }
        else
        {
            LLOGLN(10, ("rdpCopyArea: 2"));
        }
    }

    LLOGLN(10, ("rdpCopyArea: fallback"));
    
    /* do original call */
    rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);

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

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

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

            if (g_do_dirty_os)
            {
                LLOGLN(10, ("rdpCopyArea: 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
        {
            LLOGLN(10, ("rdpCopyArea: 3"));
        }
    }
    else
    {
        if (pDst->type == DRAWABLE_WINDOW)
        {
            pDstWnd = (WindowPtr)pDst;

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

                if (g_do_dirty_ons)
                {
                    LLOGLN(10, ("rdpCopyArea: 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)
    {
        return rv;
    }

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

    if (cd == 1)
    {
        if (dirty_type != 0)
        {
            box.x1 = pDst->x + dstx;
            box.y1 = pDst->y + dsty;
            box.x2 = box.x1 + w;
            box.y2 = box.y1 + h;
            RegionInit(&reg1, &box, 0);
            draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_COPYAREA);
            RegionUninit(&reg1);
        }
        else if (got_id)
        {
            rdpup_begin_update();
            rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h);
            rdpup_end_update();
        }
    }
    else if (cd == 2)
    {
        num_clips = REGION_NUM_RECTS(&clip_reg);

        if (num_clips > 0)
        {
            if (dirty_type != 0)
            {
                box.x1 = pDst->x + dstx;
                box.y1 = pDst->y + dsty;
                box.x2 = box.x1 + w;
                box.y2 = box.y1 + h;
                RegionInit(&box_reg, &box, 0);
                RegionIntersect(&clip_reg, &clip_reg, &box_reg);
                draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type, TAG_COPYAREA);
                RegionUninit(&box_reg);
            }
            else if (got_id)
            {
                rdpup_begin_update();
                box.x1 = pDst->x + dstx;
                box.y1 = pDst->y + dsty;
                box.x2 = box.x1 + w;
                box.y2 = box.y1 + h;
                RegionInit(&box_reg, &box, 0);
                RegionIntersect(&clip_reg, &clip_reg, &box_reg);
                num_clips = REGION_NUM_RECTS(&clip_reg);

                if (num_clips < 10)
                {
                    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);
                    }
                }
                else
                {
                    pbox = RegionExtents(&clip_reg);
                    rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
                                    pbox->y2 - pbox->y1);
                }

                RegionUninit(&box_reg);
                rdpup_end_update();
            }
        }
    }

    RegionUninit(&clip_reg);

    if (reset_surface)
    {
        rdpup_switch_os_surface(-1);
    }

    return rv;
}
Ejemplo n.º 2
0
void rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit)
{
	RegionRec clip_reg;
	int num_clips;
	int cd;
	int i;
	int j;
	int post_process;
	BoxRec box;
	xSegment *segs;
	int nseg;
	WindowPtr pDstWnd;
	PixmapPtr pDstPixmap;
	rdpPixmapRec *pDstPriv;

	LLOGLN(10, ("rdpPolylines:"));
	LLOGLN(10, ("  npt %d mode %d x %d y %d", npt, mode,
			pDrawable->x, pDrawable->y));

	/* convert lines to line segments */
	nseg = npt - 1;
	segs = 0;

	if (npt > 1)
	{
		segs = (xSegment*) g_malloc(sizeof(xSegment) * nseg, 0);
		segs[0].x1 = pptInit[0].x + pDrawable->x;
		segs[0].y1 = pptInit[0].y + pDrawable->y;

		if (mode == CoordModeOrigin)
		{
			segs[0].x2 = pptInit[1].x + pDrawable->x;
			segs[0].y2 = pptInit[1].y + pDrawable->y;

			for (i = 2; i < npt; i++)
			{
				segs[i - 1].x1 = segs[i - 2].x2;
				segs[i - 1].y1 = segs[i - 2].y2;
				segs[i - 1].x2 = pptInit[i].x + pDrawable->x;
				segs[i - 1].y2 = pptInit[i].y + pDrawable->y;
			}
		}
		else
		{
			segs[0].x2 = segs[0].x1 + pptInit[1].x;
			segs[0].y2 = segs[0].y1 + pptInit[1].y;

			for (i = 2; i < npt; i++)
			{
				segs[i - 1].x1 = segs[i - 2].x2;
				segs[i - 1].y1 = segs[i - 2].y2;
				segs[i - 1].x2 = segs[i - 1].x1 + pptInit[i].x;
				segs[i - 1].y2 = segs[i - 1].y1 + pptInit[i].y;
			}
		}
	}
	else
	{
		LLOGLN(0, ("rdpPolylines: weird npt [%d]", npt));
	}

	/* do original call */
	rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit);

	post_process = 0;

	if (pDrawable->type == DRAWABLE_PIXMAP)
	{
		pDstPixmap = (PixmapPtr) pDrawable;
		pDstPriv = GETPIXPRIV(pDstPixmap);
	}
	else
	{
		if (pDrawable->type == DRAWABLE_WINDOW)
		{
			pDstWnd = (WindowPtr) pDrawable;

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

	if (!post_process)
	{
		free(segs);
		return;
	}

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

	if (cd == 1)
	{
		if (segs != 0)
		{
			XRDP_MSG_LINE_TO msg;

			rdpup_begin_update();

			msg.bRop2 = rdpup_convert_opcode(pGC->alu);
			msg.penColor = rdpup_convert_color(pGC->fgPixel);
			msg.penWidth = pGC->lineWidth;
			msg.penStyle = 0;

			for (i = 0; i < nseg; i++)
			{
				msg.nXStart = segs[i].x1;
				msg.nYStart = segs[i].y1;
				msg.nXEnd = segs[i].x2;
				msg.nYEnd = segs[i].y2;

				rdpup_draw_line(&msg);
			}

			rdpup_end_update();
		}
	}
	else if (cd == 2)
	{
		num_clips = REGION_NUM_RECTS(&clip_reg);

		if (nseg != 0 && num_clips > 0)
		{
			XRDP_MSG_LINE_TO msg;

			rdpup_begin_update();

			msg.bRop2 = rdpup_convert_opcode(pGC->alu);
			msg.penColor = rdpup_convert_color(pGC->fgPixel);
			msg.penWidth = pGC->lineWidth;
			msg.penStyle = 0;

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

				for (i = 0; i < nseg; i++)
				{
					msg.nXStart = segs[i].x1;
					msg.nYStart = segs[i].y1;
					msg.nXEnd = segs[i].x2;
					msg.nYEnd = segs[i].y2;

					rdpup_draw_line(&msg);
				}
			}

			rdpup_reset_clip();
			rdpup_end_update();
		}
	}

	free(segs);
	RegionUninit(&clip_reg);
}
Ejemplo n.º 3
0
/* draw from an off screen pixmap to an off screen pixmap */
static RegionPtr
rdpCopyAreaPixmapToPixmap(PixmapPtr pSrcPixmap, rdpPixmapRec *pSrcPriv,
                          PixmapPtr pDstPixmap, rdpPixmapRec *pDstPriv,
                          GCPtr pGC, int srcx, int srcy, int w, int h,
                          int dstx, int dsty)
{
    int lsrcx;
    int lsrcy;
    int ldstx;
    int ldsty;
    int cd;
    int j;
    int num_clips;
    int dx;
    int dy;
    RegionPtr rv;
    RegionRec clip_reg;
    BoxRec box;

    LLOGLN(10, ("rdpCopyAreaPixmapToPixmap:"));
    RegionInit(&clip_reg, NullBox, 0);
    cd = rdp_get_clip(&clip_reg, &(pDstPixmap->drawable), pGC);
    LLOGLN(10, ("rdpCopyAreaPixmapToPixmap: cd %d", cd));
    ldstx = pDstPixmap->drawable.x + dstx;
    ldsty = pDstPixmap->drawable.y + dsty;
    lsrcx = pSrcPixmap->drawable.x + srcx;
    lsrcy = pSrcPixmap->drawable.y + srcy;

    if (cd == 1)
    {
        rdpup_switch_os_surface(pDstPriv->rdpindex);
        rdpup_begin_update();
        rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy);
        LLOGLN(10, ("%d %d %d %d %d %d", ldstx, ldsty, w, h, lsrcx, lsrcy));
        rdpup_end_update();
        rdpup_switch_os_surface(-1);
    }
    else if (cd == 2)
    {
        num_clips = REGION_NUM_RECTS(&clip_reg);

        if (num_clips > 0)
        {
            rdpup_switch_os_surface(pDstPriv->rdpindex);
            rdpup_begin_update();
            dx = ldstx - lsrcx;
            dy = ldsty - lsrcy;

            LLOGLN(10, ("rdpCopyAreaPixmapToPixmap: num_clips %d", num_clips));

            if ((dy < 0) || ((dy == 0) && (dx < 0)))
            {
                for (j = 0; j < num_clips; j++)
                {
                    box = REGION_RECTS(&clip_reg)[j];
                    rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
                    rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy);
                    LLOGLN(10, ("%d %d %d %d %d %d", ldstx, ldsty, w, h, lsrcx, lsrcy));
                }
            }
            else
            {
                for (j = num_clips - 1; j >= 0; j--)
                {
                    box = REGION_RECTS(&clip_reg)[j];
                    rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
                    rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy);
                    LLOGLN(10, ("%d %d %d %d %d %d", ldstx, ldsty, w, h, lsrcx, lsrcy));
                }
            }

            rdpup_reset_clip();
            rdpup_end_update();
            rdpup_switch_os_surface(-1);
        }
    }

    RegionUninit(&clip_reg);
    rv = rdpCopyAreaOrg(&(pSrcPixmap->drawable), &(pDstPixmap->drawable),
                        pGC, srcx, srcy, w, h, dstx, dsty);
    return rv;
}
Ejemplo n.º 4
0
void
rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
                xRectangle *prectInit)
{
    int j;
    int cd;
    int num_clips;
    RegionRec clip_reg;
    RegionPtr fill_reg;
    BoxRec box;

    int got_id;
    int dirty_type;
    int post_process;
    int reset_surface;

    struct image_data id;
    WindowPtr pDstWnd;
    PixmapPtr pDstPixmap;
    rdpPixmapRec *pDstPriv;
    rdpPixmapRec *pDirtyPriv;

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

    /* make a copy of rects */
    fill_reg = RegionFromRects(nrectFill, prectInit, CT_NONE);

    /* do original call */
    rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit);

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

    if (pDrawable->type == DRAWABLE_PIXMAP)
    {
        pDstPixmap = (PixmapPtr)pDrawable;
        pDstPriv = GETPIXPRIV(pDstPixmap);
        if (pDstPixmap->devPrivate.ptr == g_rdpScreen.pfbMemory)
        {
            /* treat like root window */
            post_process = 1;

            if (g_do_dirty_ons)
            {
                LLOGLN(10, ("rdpPolyFillRect: gettig dirty"));
                g_screenPriv.is_dirty = 1;
                pDirtyPriv = &g_screenPriv;
                dirty_type = RDI_IMGLL;
            }
            else
            {
                rdpup_get_screen_image_rect(&id);
                got_id = 1;
            }
        }
        else if (xrdp_is_os(pDstPixmap, pDstPriv))
        {
            post_process = 1;

            if (g_do_dirty_os)
            {
                LLOGLN(10, ("rdpPolyFillRect: gettig dirty"));
                pDstPriv->is_dirty = 1;
                pDirtyPriv = pDstPriv;
                dirty_type = RDI_FILL;
            }
            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, ("rdpPolyFillRect: 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)
    {
        RegionDestroy(fill_reg);
        LLOGLN(10, ("rdpPolyFillRect: out, post_process not set"));
        return;
    }

    RegionTranslate(fill_reg, pDrawable->x, pDrawable->y);
    RegionInit(&clip_reg, NullBox, 0);
    cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
    LLOGLN(10, ("rdpPolyFillRect: cd %d", cd));

    if (cd == 1) /* no clip */
    {
        if (dirty_type != 0)
        {
            if (pGC->fillStyle == 0 && /* solid fill */
                    (pGC->alu == GXclear ||
                     pGC->alu == GXset ||
                     pGC->alu == GXinvert ||
                     pGC->alu == GXnoop ||
                     pGC->alu == GXand ||
                     pGC->alu == GXcopy /*||
                     pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
            {
                draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel,
                                          pGC->alu);
            }
            else
            {
                draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, RDI_IMGLL, 2);
            }
        }
        else if (got_id)
        {
            rdpup_begin_update();

            if (pGC->fillStyle == 0 && /* solid fill */
                    (pGC->alu == GXclear ||
                     pGC->alu == GXset ||
                     pGC->alu == GXinvert ||
                     pGC->alu == GXnoop ||
                     pGC->alu == GXand ||
                     pGC->alu == GXcopy /*||
                     pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
            {
                rdpup_set_fgcolor(pGC->fgPixel);
                rdpup_set_opcode(pGC->alu);

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

                rdpup_set_opcode(GXcopy);
            }
            else /* non solid fill */
            {
                for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
                {
                    box = REGION_RECTS(fill_reg)[j];
                    rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
                                    box.y2 - box.y1);
                }
            }

            rdpup_end_update();
        }
    }
    else if (cd == 2) /* clip */
    {
        RegionIntersect(&clip_reg, &clip_reg, fill_reg);
        num_clips = REGION_NUM_RECTS(&clip_reg);

        if (num_clips > 0)
        {
            if (dirty_type != 0)
            {
                if (pGC->fillStyle == 0 && /* solid fill */
                        (pGC->alu == GXclear ||
                         pGC->alu == GXset ||
                         pGC->alu == GXinvert ||
                         pGC->alu == GXnoop ||
                         pGC->alu == GXand ||
                         pGC->alu == GXcopy /*||
                         pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
                {
                    LLOGLN(10, ("rdpPolyFillRect: 3"));
                    draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
                                              pGC->alu);
                }
                else
                {
                    LLOGLN(10, ("rdpPolyFillRect: 4"));
                    draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, RDI_IMGLL, 2);
                }
            }
            else if (got_id)
            {
                rdpup_begin_update();

                 LLOGLN(10, ("2 %x", pGC->fgPixel));

                if (pGC->fillStyle == 0 && /* solid fill */
                        (pGC->alu == GXclear ||
                         pGC->alu == GXset ||
                         pGC->alu == GXinvert ||
                         pGC->alu == GXnoop ||
                         pGC->alu == GXand ||
                         pGC->alu == GXcopy /*||
                         pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
                {
                    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 /* non solid fill */
                {
                    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();
            }
        }
    }

    RegionUninit(&clip_reg);
    RegionDestroy(fill_reg);

    if (reset_surface)
    {
        rdpup_switch_os_surface(-1);
    }
}
Ejemplo n.º 5
0
RegionPtr
rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
            int srcx, int srcy, int w, int h, int dstx, int dsty)
{
  RegionPtr rv;
  RegionRec clip_reg;
  RegionRec box_reg;
  int num_clips;
  int cd;
  int j;
  int can_do_screen_blt;
  int got_id;
  struct image_data id;
  BoxRec box;
  BoxPtr pbox;
  PixmapPtr pSrcPixmap;
  PixmapPtr pDstPixmap;
  rdpPixmapRec* pSrcPriv;
  rdpPixmapRec* pDstPriv;
  WindowPtr pDstWnd;
  WindowPtr pSrcWnd;

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

  if (pSrc->type == DRAWABLE_WINDOW)
  {
    pSrcWnd = (WindowPtr)pSrc;
    if (pSrcWnd->viewable)
    {
      if (pDst->type == DRAWABLE_WINDOW)
      {
        pDstWnd = (WindowPtr)pDst;
        if (pDstWnd->viewable)
        {
          can_do_screen_blt = pGC->alu == GXcopy;
          if (can_do_screen_blt)
          {
            return rdpCopyAreaWndToWnd(pSrcWnd, pDstWnd, pGC,
                                       srcx, srcy, w, h, dstx, dsty);
          }
        }
      }
      else if (pDst->type == DRAWABLE_PIXMAP)
      {
        pDstPixmap = (PixmapPtr)pDst;
        pDstPriv = GETPIXPRIV(pDstPixmap);
        if (XRDP_IS_OS(pDstPriv))
        {
          can_do_screen_blt = pGC->alu == GXcopy;
          if (can_do_screen_blt)
          {
            return rdpCopyAreaWndToPixmap(pSrcWnd, pDstPixmap, pDstPriv, pGC,
                                          srcx, srcy, w, h, dstx, dsty);
          }
        }
      }
    }
  }
  if (pSrc->type == DRAWABLE_PIXMAP)
  {
    pSrcPixmap = (PixmapPtr)pSrc;
    pSrcPriv = GETPIXPRIV(pSrcPixmap);
    if (XRDP_IS_OS(pSrcPriv))
    {
      if (pDst->type == DRAWABLE_WINDOW)
      {
        pDstWnd = (WindowPtr)pDst;
        if (pDstWnd->viewable)
        {
          return rdpCopyAreaPixmapToWnd(pSrcPixmap, pSrcPriv, pDstWnd, pGC,
                                        srcx, srcy, w, h, dstx, dsty);
        }
      }
      else if (pDst->type == DRAWABLE_PIXMAP)
      {
        pDstPixmap = (PixmapPtr)pDst;
        pDstPriv = GETPIXPRIV(pDstPixmap);
        if (XRDP_IS_OS(pDstPriv))
        {
          return rdpCopyAreaPixmapToPixmap(pSrcPixmap, pSrcPriv,
                                           pDstPixmap, pDstPriv,
                                           pGC, srcx, srcy, w, h,
                                           dstx, dsty);
        }
      }
    }
  }

  /* do original call */
  rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);

  got_id = 0;
  if (pDst->type == DRAWABLE_PIXMAP)
  {
    pDstPixmap = (PixmapPtr)pDst;
    pDstPriv = GETPIXPRIV(pDstPixmap);
    if (XRDP_IS_OS(pDstPriv))
    {
      rdpup_switch_os_surface(pDstPriv->rdpindex);
      rdpup_get_pixmap_image_rect(pDstPixmap, &id);
      got_id = 1;
    }
  }
  else
  {
    if (pDst->type == DRAWABLE_WINDOW)
    {
      pDstWnd = (WindowPtr)pDst;
      if (pDstWnd->viewable)
      {
        rdpup_get_screen_image_rect(&id);
        got_id = 1;
      }
    }
  }
  if (!got_id)
  {
    return rv;
  }

  RegionInit(&clip_reg, NullBox, 0);
  cd = rdp_get_clip(&clip_reg, pDst, pGC);
  if (cd == 1)
  {
    rdpup_begin_update();
    rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h);
    rdpup_end_update();
  }
  else if (cd == 2)
  {
    num_clips = REGION_NUM_RECTS(&clip_reg);
    if (num_clips > 0)
    {
      rdpup_begin_update();
      box.x1 = pDst->x + dstx;
      box.y1 = pDst->y + dsty;
      box.x2 = box.x1 + w;
      box.y2 = box.y1 + h;
      RegionInit(&box_reg, &box, 0);
      RegionIntersect(&clip_reg, &clip_reg, &box_reg);
      num_clips = REGION_NUM_RECTS(&clip_reg);
      if (num_clips < 10)
      {
        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);
        }
      }
      else
      {
        pbox = RegionExtents(&clip_reg);
        rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
                        pbox->y2 - pbox->y1);
      }
      RegionUninit(&box_reg);
      rdpup_end_update();
    }
  }
  RegionUninit(&clip_reg);
  rdpup_switch_os_surface(-1);
  return rv;
}
Ejemplo n.º 6
0
void
rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion)
{
  RegionRec reg;
  RegionRec clip;
  int dx;
  int dy;
  int i;
  int j;
  int num_clip_rects;
  int num_reg_rects;
  BoxRec box1;
  BoxRec box2;

  DEBUG_OUT_OPS(("in rdpCopyWindow\n"));
  RegionInit(&reg, NullBox, 0);
  RegionCopy(&reg, pOldRegion);
  g_pScreen->CopyWindow = g_rdpScreen.CopyWindow;
  g_pScreen->CopyWindow(pWin, ptOldOrg, pOldRegion);
  RegionInit(&clip, NullBox, 0);
  RegionCopy(&clip, &pWin->borderClip);
  dx = pWin->drawable.x - ptOldOrg.x;
  dy = pWin->drawable.y - ptOldOrg.y;
  rdpup_begin_update();
  num_clip_rects = REGION_NUM_RECTS(&clip);
  num_reg_rects = REGION_NUM_RECTS(&reg);
  /* should maybe sort the rects instead of checking dy < 0 */
  /* If we can depend on the rects going from top to bottom, left
     to right we are ok */
  if (dy < 0 || (dy == 0 && dx < 0))
  {
    for (j = 0; j < num_clip_rects; j++)
    {
      box1 = REGION_RECTS(&clip)[j];
      rdpup_set_clip(box1.x1, box1.y1, box1.x2 - box1.x1, box1.y2 - box1.y1);
      for (i = 0; i < num_reg_rects; i++)
      {
        box2 = REGION_RECTS(&reg)[i];
        rdpup_screen_blt(box2.x1 + dx, box2.y1 + dy, box2.x2 - box2.x1,
                         box2.y2 - box2.y1, box2.x1, box2.y1);
      }
    }
  }
  else
  {
    for (j = num_clip_rects - 1; j >= 0; j--)
    {
      box1 = REGION_RECTS(&clip)[j];
      rdpup_set_clip(box1.x1, box1.y1, box1.x2 - box1.x1, box1.y2 - box1.y1);
      for (i = num_reg_rects - 1; i >= 0; i--)
      {
        box2 = REGION_RECTS(&reg)[i];
        rdpup_screen_blt(box2.x1 + dx, box2.y1 + dy, box2.x2 - box2.x1,
                         box2.y2 - box2.y1, box2.x1, box2.y1);
      }
    }
  }
  rdpup_reset_clip();
  rdpup_end_update();
  RegionUninit(&reg);
  RegionUninit(&clip);
  g_pScreen->CopyWindow = rdpCopyWindow;
}
Ejemplo n.º 7
0
int
rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
              int x, int y, int count, unsigned short *chars)
{
    RegionRec reg;
    RegionRec reg1;
    int num_clips;
    int cd;
    int j;
    int rv;
    int got_id;
    int dirty_type;
    int post_process;
    int reset_surface;
    BoxRec box;
    struct image_data id;
    WindowPtr pDstWnd;
    PixmapPtr pDstPixmap;
    rdpPixmapRec *pDstPriv;
    rdpPixmapRec *pDirtyPriv;

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

    if (count != 0)
    {
        GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
    }

    /* do original call */
    rv = rdpPolyText16Org(pDrawable, pGC, x, y, count, chars);

    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, ("rdpPolyText16: gettig 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(0, ("rdpPolyText16: 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)
    {
        return rv;
    }

    RegionInit(&reg, NullBox, 0);

    if (count == 0)
    {
        cd = 0;
    }
    else
    {
        cd = rdp_get_clip(&reg, pDrawable, pGC);
    }

    if (cd == 1)
    {
        if (dirty_type != 0)
        {
            RegionInit(&reg1, &box, 0);
            draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, 11);
            RegionUninit(&reg1);
        }
        else if (got_id)
        {
            rdpup_begin_update();
            rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
            rdpup_end_update();
        }
    }
    else if (cd == 2)
    {
        RegionInit(&reg1, &box, 0);
        RegionIntersect(&reg, &reg, &reg1);
        num_clips = REGION_NUM_RECTS(&reg);

        if (num_clips > 0)
        {
            if (dirty_type != 0)
            {
                draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type, 11);
            }
            else if (got_id)
            {
                rdpup_begin_update();

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

                rdpup_end_update();
            }
        }

        RegionUninit(&reg1);
    }

    RegionUninit(&reg);

    if (reset_surface)
    {
        rdpup_switch_os_surface(-1);
    }

    return rv;
}
Ejemplo n.º 8
0
void rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSegs)
{
	RegionRec clip_reg;
	int cd;
	int i;
	int j;
	int got_id;
	int dirty_type;
	int post_process;
	int reset_surface;
	xSegment *segs;
	BoxRec box;
	struct image_data id;
	WindowPtr pDstWnd;
	PixmapPtr pDstPixmap;
	rdpPixmapRec *pDstPriv;
	rdpPixmapRec *pDirtyPriv;

	LLOGLN(10, ("rdpPolySegment:"));
	LLOGLN(10, ("  nseg %d", nseg));

	segs = 0;

	if (nseg) /* get the rects */
	{
		segs = (xSegment *)g_malloc(nseg * sizeof(xSegment), 0);

		for (i = 0; i < nseg; i++)
		{
			segs[i].x1 = pSegs[i].x1 + pDrawable->x;
			segs[i].y1 = pSegs[i].y1 + pDrawable->y;
			segs[i].x2 = pSegs[i].x2 + pDrawable->x;
			segs[i].y2 = pSegs[i].y2 + pDrawable->y;
		}
	}

	/* do original call */
	rdpPolySegmentOrg(pDrawable, pGC, nseg, pSegs);

	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, ("rdpPolySegment: 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, ("rdpPolySegment: 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(segs);
		return;
	}

	RegionInit(&clip_reg, NullBox, 0);
	cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
	LLOGLN(10, ("rdpPolySegment: cd %d", cd));

	if (cd == 1) /* no clip */
	{
		if (segs != 0)
		{
			if (dirty_type != 0)
			{
				RegionUninit(&clip_reg);
				RegionInit(&clip_reg, NullBox, 0);
				RegionAroundSegs(&clip_reg, segs, nseg);
				draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
						pGC->alu, pGC->lineWidth, segs, nseg, 1);
			}
			else if (got_id)
			{
				rdpup_begin_update();
				rdpup_set_fgcolor(pGC->fgPixel);
				rdpup_set_opcode(pGC->alu);
				rdpup_set_pen(0, pGC->lineWidth);

				for (i = 0; i < nseg; i++)
				{
					rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
				}

				rdpup_set_opcode(GXcopy);
				rdpup_end_update();
			}
		}
	}
	else if (cd == 2) /* clip */
	{
		if (segs != 0)
		{
			if (dirty_type != 0)
			{
				draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
						pGC->alu, pGC->lineWidth, segs, nseg, 1);
			}
			else if (got_id)
			{
				rdpup_begin_update();
				rdpup_set_fgcolor(pGC->fgPixel);
				rdpup_set_opcode(pGC->alu);
				rdpup_set_pen(0, pGC->lineWidth);

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

					for (i = 0; i < nseg; i++)
					{
						rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
						LLOGLN(10, ("  %d %d %d %d", segs[i].x1, segs[i].y1,
								segs[i].x2, segs[i].y2));
					}
				}

				rdpup_reset_clip();
				rdpup_set_opcode(GXcopy);
				rdpup_end_update();
			}
		}
	}

	g_free(segs);
	RegionUninit(&clip_reg);

	if (reset_surface)
	{
		rdpup_switch_os_surface(-1);
	}
}
Ejemplo n.º 9
0
RegionPtr
rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
             GCPtr pGC, int srcx, int srcy, int w, int h,
             int dstx, int dsty, unsigned long bitPlane)
{
    RegionPtr rv;
    RegionRec clip_reg;
    RegionRec box_reg;
    RegionRec reg1;
    RegionRec reg2;
    int cd;
    int num_clips;
    int j;
    int got_id;
    int dirty_type;
    int post_process;
    int reset_surface;
    BoxRec box;
    BoxPtr pbox;
    struct image_data id;
    WindowPtr pDstWnd;
    PixmapPtr pDstPixmap;
    rdpPixmapRec *pDstPriv;
    rdpPixmapRec *pDirtyPriv;

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

    /* do original call */
    rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h,
                         dstx, dsty, bitPlane);

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

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

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

            if (g_do_dirty_os)
            {
                LLOGLN(10, ("rdpCopyPlane: 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 (pDst->type == DRAWABLE_WINDOW)
        {
            pDstWnd = (WindowPtr)pDst;

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

                if (g_do_dirty_ons)
                {
                    LLOGLN(0, ("rdpCopyPlane: 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)
    {
        return rv;
    }

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

    if (cd == 1)
    {
        if (dirty_type != 0)
        {
            box.x1 = pDst->x + dstx;
            box.y1 = pDst->y + dsty;
            box.x2 = box.x1 + w;
            box.y2 = box.y1 + h;
            RegionInit(&reg1, &box, 0);
            draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
            RegionUninit(&reg1);
        }
        else if (got_id)
        {
            rdpup_begin_update();
            rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h);
            rdpup_end_update();
        }
    }
    else if (cd == 2)
    {
        num_clips = REGION_NUM_RECTS(&clip_reg);

        if (num_clips > 0)
        {
            if (dirty_type != 0)
            {
                box.x1 = pDst->x + dstx;
                box.y1 = pDst->y + dsty;
                box.x2 = box.x1 + w;
                box.y2 = box.y1 + h;
                RegionInit(&reg1, &box, 0);
                RegionInit(&reg2, NullBox, 0);
                RegionCopy(&reg2, &clip_reg);
                RegionIntersect(&reg1, &reg1, &reg2);
                draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
                RegionUninit(&reg1);
                RegionUninit(&reg2);
            }
            else if (got_id)
            {
                rdpup_begin_update();
                box.x1 = pDst->x + dstx;
                box.y1 = pDst->y + dsty;
                box.x2 = box.x1 + w;
                box.y2 = box.y1 + h;
                RegionInit(&box_reg, &box, 0);
                RegionIntersect(&clip_reg, &clip_reg, &box_reg);
                num_clips = REGION_NUM_RECTS(&clip_reg);

                if (num_clips < 10)
                {
                    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);
                    }
                }
                else
                {
                    pbox = RegionExtents(&clip_reg);
                    rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
                                    pbox->y2 - pbox->y1);
                }

                RegionUninit(&box_reg);
                rdpup_end_update();
            }
        }
    }

    RegionUninit(&clip_reg);

    if (reset_surface)
    {
        rdpup_switch_os_surface(-1);
    }

    return rv;
}
Ejemplo n.º 10
0
RegionPtr rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
		int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long bitPlane)
{
	RegionPtr rv;
	RegionRec clip_reg;
	RegionRec box_reg;
	int cd;
	int num_clips;
	int j;
	int post_process;
	BoxRec box;
	BoxPtr pbox;
	WindowPtr pDstWnd;
	PixmapPtr pDstPixmap;
	rdpPixmapRec *pDstPriv;

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

	/* do original call */
	rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane);

	post_process = 0;

	if (pDst->type == DRAWABLE_PIXMAP)
	{
		pDstPixmap = (PixmapPtr) pDst;
		pDstPriv = GETPIXPRIV(pDstPixmap);
	}
	else
	{
		if (pDst->type == DRAWABLE_WINDOW)
		{
			pDstWnd = (WindowPtr) pDst;

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

	if (!post_process)
		return rv;

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

	if (cd == 1)
	{
		rdp_send_area_update(pDst->x + dstx, pDst->y + dsty, w, h);
	}
	else if (cd == 2)
	{
		num_clips = REGION_NUM_RECTS(&clip_reg);

		if (num_clips > 0)
		{
			box.x1 = pDst->x + dstx;
			box.y1 = pDst->y + dsty;
			box.x2 = box.x1 + w;
			box.y2 = box.y1 + h;
			RegionInit(&box_reg, &box, 0);
			RegionIntersect(&clip_reg, &clip_reg, &box_reg);
			num_clips = REGION_NUM_RECTS(&clip_reg);

			if (num_clips < 10)
			{
				for (j = num_clips - 1; j >= 0; j--)
				{
					box = REGION_RECTS(&clip_reg)[j];
					rdp_send_area_update(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
				}
			}
			else
			{
				pbox = RegionExtents(&clip_reg);
				rdp_send_area_update(pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
			}

			RegionUninit(&box_reg);
		}
	}

	RegionUninit(&clip_reg);

	return rv;
}
Ejemplo n.º 11
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);
    }
}
Ejemplo n.º 12
0
/* XaceCensorImage
 *
 * Called after pScreen->GetImage to prevent pieces or trusted windows from
 * being returned in image data from an untrusted window.
 *
 * Arguments:
 *	client is the client doing the GetImage.
 *      pVisibleRegion is the visible region of the window.
 *	widthBytesLine is the width in bytes of one horizontal line in pBuf.
 *	pDraw is the source window.
 *	x, y, w, h is the rectangle of image data from pDraw in pBuf.
 *	format is the format of the image data in pBuf: ZPixmap or XYPixmap.
 *	pBuf is the image data.
 *
 * Returns: nothing.
 *
 * Side Effects:
 *	Any part of the rectangle (x, y, w, h) that is outside the visible
 *	region of the window will be destroyed (overwritten) in pBuf.
 */
void
XaceCensorImage(ClientPtr client,
                RegionPtr pVisibleRegion,
                long widthBytesLine,
                DrawablePtr pDraw,
                int x, int y, int w, int h, unsigned int format, char *pBuf)
{
    RegionRec imageRegion;      /* region representing x,y,w,h */
    RegionRec censorRegion;     /* region to obliterate */
    BoxRec imageBox;
    int nRects;

    imageBox.x1 = pDraw->x + x;
    imageBox.y1 = pDraw->y + y;
    imageBox.x2 = pDraw->x + x + w;
    imageBox.y2 = pDraw->y + y + h;
    RegionInit(&imageRegion, &imageBox, 1);
    RegionNull(&censorRegion);

    /* censorRegion = imageRegion - visibleRegion */
    RegionSubtract(&censorRegion, &imageRegion, pVisibleRegion);
    nRects = RegionNumRects(&censorRegion);
    if (nRects > 0) {           /* we have something to censor */
        GCPtr pScratchGC = NULL;
        PixmapPtr pPix = NULL;
        xRectangle *pRects = NULL;
        Bool failed = FALSE;
        int depth = 1;
        int bitsPerPixel = 1;
        int i;
        BoxPtr pBox;

        /* convert region to list-of-rectangles for PolyFillRect */

        pRects = malloc(nRects * sizeof(xRectangle));
        if (!pRects) {
            failed = TRUE;
            goto failSafe;
        }
        for (pBox = RegionRects(&censorRegion), i = 0; i < nRects; i++, pBox++) {
            pRects[i].x = pBox->x1 - imageBox.x1;
            pRects[i].y = pBox->y1 - imageBox.y1;
            pRects[i].width = pBox->x2 - pBox->x1;
            pRects[i].height = pBox->y2 - pBox->y1;
        }

        /* use pBuf as a fake pixmap */

        if (format == ZPixmap) {
            depth = pDraw->depth;
            bitsPerPixel = pDraw->bitsPerPixel;
        }

        pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h,
                                      depth, bitsPerPixel,
                                      widthBytesLine, (void *) pBuf);
        if (!pPix) {
            failed = TRUE;
            goto failSafe;
        }

        pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen);
        if (!pScratchGC) {
            failed = TRUE;
            goto failSafe;
        }

        ValidateGC(&pPix->drawable, pScratchGC);
        (*pScratchGC->ops->PolyFillRect) (&pPix->drawable,
                                          pScratchGC, nRects, pRects);

 failSafe:
        if (failed) {
            /* Censoring was not completed above.  To be safe, wipe out
             * all the image data so that nothing trusted gets out.
             */
            memset(pBuf, 0, (int) (widthBytesLine * h));
        }
        free(pRects);
        if (pScratchGC)
            FreeScratchGC(pScratchGC);
        if (pPix)
            FreeScratchPixmapHeader(pPix);
    }
    RegionUninit(&imageRegion);
    RegionUninit(&censorRegion);
}                               /* XaceCensorImage */
Ejemplo n.º 13
0
/* it looks like all the antialias draws go through here */
void
rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
             INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
             INT16 yDst, CARD16 width, CARD16 height)
{
    BoxRec box;
    PictureScreenPtr ps;
    RegionRec reg1;
    RegionRec reg2;
    DrawablePtr p;
    int dirty_type;
    int j;
    int num_clips;
    int post_process;
    int reset_surface;
    int got_id;
    int lx;
    int ly;
    WindowPtr pDstWnd;
    PixmapPtr pDstPixmap;
    rdpPixmapRec *pDstPriv;
    rdpPixmapRec *pDirtyPriv;
    struct image_data id;

    LLOGLN(10, ("rdpComposite:"));
    ps = GetPictureScreen(g_pScreen);
    ps->Composite = g_rdpScreen.Composite;
    ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc,
                  xMask, yMask, xDst, yDst, width, height);
    ps->Composite = rdpComposite;

    p = pDst->pDrawable;

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

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

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

            if (g_do_dirty_os)
            {
                LLOGLN(10, ("rdpComposite: gettig dirty"));
                pDstPriv->is_dirty = 1;
                dirty_type = g_doing_font ? RDI_IMGLL : RDI_IMGLY;
                pDirtyPriv = pDstPriv;

            }
            else
            {
                rdpup_switch_os_surface(pDstPriv->rdpindex);
                reset_surface = 1;
                rdpup_get_pixmap_image_rect(pDstPixmap, &id);
                got_id = 1;
                LLOGLN(10, ("rdpComposite: offscreen"));
            }
        }
    }
    else
    {
        if (p->type == DRAWABLE_WINDOW)
        {
            pDstWnd = (WindowPtr)p;

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

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

    if (!post_process)
    {
        return;
    }

    if (pDst->clientClipType == CT_REGION)
    {
        box.x1 = p->x + xDst;
        box.y1 = p->y + yDst;
        box.x2 = box.x1 + width;
        box.y2 = box.y1 + height;
        RegionInit(&reg1, &box, 0);
        RegionInit(&reg2, NullBox, 0);
        RegionCopy(&reg2, pDst->clientClip);
        lx = p->x + pDst->clipOrigin.x;
        ly = p->y + pDst->clipOrigin.y;
        RegionTranslate(&reg2, lx, ly);
        RegionIntersect(&reg1, &reg1, &reg2);

        if (dirty_type != 0)
        {
            draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
        }
        else if (got_id)
        {
            num_clips = REGION_NUM_RECTS(&reg1);

            if (num_clips > 0)
            {
                rdpup_begin_update();

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

                rdpup_end_update();
            }
        }

        RegionUninit(&reg1);
        RegionUninit(&reg2);
    }
    else
    {
        box.x1 = p->x + xDst;
        box.y1 = p->y + yDst;
        box.x2 = box.x1 + width;
        box.y2 = box.y1 + height;

        if (dirty_type != 0)
        {
            RegionInit(&reg1, &box, 0);
            draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
            RegionUninit(&reg1);
        }
        else if (got_id)
        {
            rdpup_begin_update();
            rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
            rdpup_end_update();
        }
    }

    if (reset_surface)
    {
        rdpup_switch_os_surface(-1);
    }
}
Ejemplo n.º 14
0
void
rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
            int w, int h, int leftPad, int format, char *pBits)
{
    RegionRec clip_reg;
    int cd;
    int j;
    int reset_surface;
    int post_process;
    int got_id;
    int dirty_type;
    BoxRec box;
    struct image_data id;

    WindowPtr pDstWnd;
    PixmapPtr pDstPixmap;
    rdpPixmapRec *pDstPriv;
    rdpPixmapRec *pDirtyPriv;
    RegionRec reg1;
    RegionRec reg2;

    LLOGLN(10, ("rdpPutImage:"));
    LLOGLN(10, ("rdpPutImage: drawable id 0x%x", (int)(pDst->id)));
    LLOGLN(10, ("rdpPutImage: x %d y %d w %d h %d is_window %d", x, y, w, h,
           pDst->type == DRAWABLE_WINDOW));

    /* do original call */
    rdpPutImageOrg(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits);

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

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

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

            if (g_do_dirty_os)
            {
                LLOGLN(10, ("rdpPutImage: 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 (pDst->type == DRAWABLE_WINDOW)
        {
            pDstWnd = (WindowPtr)pDst;

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

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

    if (!post_process)
    {
        return;
    }

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

    if (cd == 1)
    {
        if (dirty_type != 0)
        {
            box.x1 = pDst->x + x;
            box.y1 = pDst->y + y;
            box.x2 = box.x1 + w;
            box.y2 = box.y1 + h;
            RegionInit(&reg1, &box, 0);
            draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_PUTIMAGE);
            RegionUninit(&reg1);
        }
        else if (got_id)
        {
            rdpup_begin_update();
            rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h);
            rdpup_end_update();
        }
    }
    else if (cd == 2)
    {
        if (dirty_type != 0)
        {
            box.x1 = pDst->x + x;
            box.y1 = pDst->y + y;
            box.x2 = box.x1 + w;
            box.y2 = box.y1 + h;
            RegionInit(&reg1, &box, 0);
            RegionInit(&reg2, NullBox, 0);
            RegionCopy(&reg2, &clip_reg);
            RegionIntersect(&reg1, &reg1, &reg2);
            draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_PUTIMAGE);
            RegionUninit(&reg1);
            RegionUninit(&reg2);
        }
        else if (got_id)
        {
            rdpup_begin_update();

            for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
            {
                box = REGION_RECTS(&clip_reg)[j];
                rdpup_set_clip(box.x1, box.y1, (box.x2 - box.x1), (box.y2 - box.y1));
                rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h);
            }

            rdpup_reset_clip();
            rdpup_end_update();
        }
    }

    RegionUninit(&clip_reg);

    if (reset_surface)
    {
        rdpup_switch_os_surface(-1);
    }
}
Ejemplo n.º 15
0
static RegionPtr
rdpCopyAreaWndToWnd(WindowPtr pSrcWnd, WindowPtr pDstWnd, GCPtr pGC,
                    int srcx, int srcy, int w, int h,
                    int dstx, int dsty)
{
    int cd;
    int lsrcx;
    int lsrcy;
    int ldstx;
    int ldsty;
    int num_clips;
    int dx;
    int dy;
    int j;
    BoxRec box;
    RegionPtr rv;
    RegionRec clip_reg;

    LLOGLN(10, ("rdpCopyAreaWndToWnd:"));
    RegionInit(&clip_reg, NullBox, 0);
    cd = rdp_get_clip(&clip_reg, &(pDstWnd->drawable), pGC);
    lsrcx = pSrcWnd->drawable.x + srcx;
    lsrcy = pSrcWnd->drawable.y + srcy;
    ldstx = pDstWnd->drawable.x + dstx;
    ldsty = pDstWnd->drawable.y + dsty;

    if (cd == 1)
    {
        rdpup_begin_update();
        rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy);
        rdpup_end_update();
    }
    else if (cd == 2)
    {
        num_clips = REGION_NUM_RECTS(&clip_reg);

        if (num_clips > 0)
        {
            rdpup_begin_update();
            dx = ldstx - lsrcx;
            dy = ldsty - lsrcy;

            if ((dy < 0) || ((dy == 0) && (dx < 0)))
            {
                for (j = 0; j < num_clips; j++)
                {
                    box = REGION_RECTS(&clip_reg)[j];
                    LLOGLN(10, ("  index %d x1 %d y1 %d x2 %d y2 %d", j,
                           box.x1, box.y1, box.x2, box.y2));
                    rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
                    rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy);
                }
            }
            else
            {
                for (j = num_clips - 1; j >= 0; j--)
                {
                    box = REGION_RECTS(&clip_reg)[j];
                    LLOGLN(10, ("  index %d x1 %d y1 %d x2 %d y2 %d", j,
                           box.x1, box.y1, box.x2, box.y2));
                    rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
                    rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy);
                }
            }

            rdpup_reset_clip();
            rdpup_end_update();
        }
    }

    RegionUninit(&clip_reg);
    rv = rdpCopyAreaOrg(&(pSrcWnd->drawable), &(pDstWnd->drawable),
                        pGC, srcx, srcy, w, h, dstx, dsty);
    return rv;
}
Ejemplo n.º 16
0
void
rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
                xRectangle* prectInit)
{
  int j;
  int cd;
  int num_clips;
  RegionRec clip_reg;
  RegionPtr fill_reg;
  BoxRec box;

  int got_id;
  struct image_data id;
  WindowPtr pDstWnd;
  PixmapPtr pDstPixmap;
  rdpPixmapRec* pDstPriv;

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

  /* make a copy of rects */
  fill_reg = RegionFromRects(nrectFill, prectInit, CT_NONE);

  /* do original call */
  rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit);

  got_id = 0;
  if (pDrawable->type == DRAWABLE_PIXMAP)
  {
    pDstPixmap = (PixmapPtr)pDrawable;
    pDstPriv = GETPIXPRIV(pDstPixmap);
    if (XRDP_IS_OS(pDstPriv))
    {
      rdpup_switch_os_surface(pDstPriv->rdpindex);
      rdpup_get_pixmap_image_rect(pDstPixmap, &id);
      got_id = 1;
    }
  }
  else
  {
    if (pDrawable->type == DRAWABLE_WINDOW)
    {
      pDstWnd = (WindowPtr)pDrawable;
      if (pDstWnd->viewable)
      {
        rdpup_get_screen_image_rect(&id);
        got_id = 1;
      }
    }
  }
  if (!got_id)
  {
    RegionDestroy(fill_reg);
    return;
  }
  RegionTranslate(fill_reg, pDrawable->x, pDrawable->y);
  RegionInit(&clip_reg, NullBox, 0);
  cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
  if (cd == 1) /* no clip */
  {
    rdpup_begin_update();
    if (pGC->fillStyle == 0 && /* solid fill */
        (pGC->alu == GXclear ||
         pGC->alu == GXset ||
         pGC->alu == GXinvert ||
         pGC->alu == GXnoop ||
         pGC->alu == GXand ||
         pGC->alu == GXcopy /*||
         pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
    {
      rdpup_set_fgcolor(pGC->fgPixel);
      rdpup_set_opcode(pGC->alu);
      for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
      {
        box = REGION_RECTS(fill_reg)[j];
        rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
      }
      rdpup_set_opcode(GXcopy);
    }
    else /* non solid fill */
    {
      for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
      {
        box = REGION_RECTS(fill_reg)[j];
        rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
      }
    }
    rdpup_end_update();
  }
  else if (cd == 2) /* clip */
  {
    RegionIntersect(&clip_reg, &clip_reg, fill_reg);
    num_clips = REGION_NUM_RECTS(&clip_reg);
    if (num_clips > 0)
    {
      rdpup_begin_update();
      if (pGC->fillStyle == 0 && /* solid fill */
          (pGC->alu == GXclear ||
           pGC->alu == GXset ||
           pGC->alu == GXinvert ||
           pGC->alu == GXnoop ||
           pGC->alu == GXand ||
           pGC->alu == GXcopy /*||
           pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
      {
        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 /* non solid fill */
      {
        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();
    }
  }
  RegionUninit(&clip_reg);
  RegionDestroy(fill_reg);
  rdpup_switch_os_surface(-1);
}
Ejemplo n.º 17
0
void
rdpPolyArc(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, ("rdpPolyArc:"));

    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 */
    rdpPolyArcOrg(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, ("rdpPolyArc: 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, ("rdpPolyArc: 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(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_POLYARC);
                }
                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_POLYARC);
                }
                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);
    }
}
Ejemplo n.º 18
0
void
miWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr other_exposed)
{
    RegionPtr exposures = prgn;

    if ((prgn && !RegionNil(prgn)) ||
        (exposures && !RegionNil(exposures)) || other_exposed) {
        RegionRec expRec;
        int clientInterested;

        /*
         * Restore from backing-store FIRST.
         */
        clientInterested =
            (pWin->eventMask | wOtherEventMasks(pWin)) & ExposureMask;
        if (other_exposed) {
            if (exposures) {
                RegionUnion(other_exposed, exposures, other_exposed);
                if (exposures != prgn)
                    RegionDestroy(exposures);
            }
            exposures = other_exposed;
        }
        if (clientInterested && exposures &&
            (RegionNumRects(exposures) > RECTLIMIT)) {
            /*
             * 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" :-).
             */
            BoxRec box;

            box = *RegionExtents(exposures);
            if (exposures == prgn) {
                exposures = &expRec;
                RegionInit(exposures, &box, 1);
                RegionReset(prgn, &box);
            }
            else {
                RegionReset(exposures, &box);
                RegionUnion(prgn, prgn, exposures);
            }
            /* miPaintWindow doesn't clip, so we have to */
            RegionIntersect(prgn, prgn, &pWin->clipList);
        }
        if (prgn && !RegionNil(prgn))
            miPaintWindow(pWin, prgn, PW_BACKGROUND);
        if (clientInterested && exposures && !RegionNil(exposures))
            miSendExposures(pWin, exposures,
                            pWin->drawable.x, pWin->drawable.y);
        if (exposures == &expRec) {
            RegionUninit(exposures);
        }
        else if (exposures && exposures != prgn && exposures != other_exposed)
            RegionDestroy(exposures);
        if (prgn)
            RegionEmpty(prgn);
    }
    else if (exposures && exposures != prgn)
        RegionDestroy(exposures);
}
Ejemplo n.º 19
0
/* it looks like all the antialias draws go through here */
void
rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
             INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
             INT16 yDst, CARD16 width, CARD16 height)
{
  BoxRec box;
  PictureScreenPtr ps;
  RegionRec reg1;
  RegionRec reg2;
  DrawablePtr p;
  int j;
  int num_clips;
  int got_id;
  WindowPtr pDstWnd;
  PixmapPtr pDstPixmap;
  rdpPixmapRec* pDstPriv;
  struct image_data id;

  LLOGLN(10, ("rdpComposite:"));
  ps = GetPictureScreen(g_pScreen);
  ps->Composite = g_rdpScreen.Composite;
  ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc,
                xMask, yMask, xDst, yDst, width, height);
  ps->Composite = rdpComposite;

  p = pDst->pDrawable;

  got_id = 0;
  if (p->type == DRAWABLE_PIXMAP)
  {
    pDstPixmap = (PixmapPtr)p;
    pDstPriv = GETPIXPRIV(pDstPixmap);
    if (XRDP_IS_OS(pDstPriv))
    {
      rdpup_switch_os_surface(pDstPriv->rdpindex);
      rdpup_get_pixmap_image_rect(pDstPixmap, &id);
      got_id = 1;
    }
  }
  else
  {
    if (p->type == DRAWABLE_WINDOW)
    {
      pDstWnd = (WindowPtr)p;
      if (pDstWnd->viewable)
      {
        rdpup_get_screen_image_rect(&id);
        got_id = 1;
      }
    }
  }
  if (!got_id)
  {
    return;
  }

  if (pDst->clientClipType == CT_REGION)
  {
    box.x1 = p->x + xDst;
    box.y1 = p->y + yDst;
    box.x2 = box.x1 + width;
    box.y2 = box.y1 + height;
    RegionInit(&reg1, &box, 0);
    RegionInit(&reg2, NullBox, 0);
    RegionCopy(&reg2, pDst->clientClip);
    RegionTranslate(&reg2, p->x + pDst->clipOrigin.x,
                      p->y + pDst->clipOrigin.y);
    RegionIntersect(&reg1, &reg1, &reg2);
    num_clips = REGION_NUM_RECTS(&reg1);
    if (num_clips > 0)
    {
      rdpup_begin_update();
      for (j = num_clips - 1; j >= 0; j--)
      {
        box = REGION_RECTS(&reg1)[j];
        rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
      }
      rdpup_end_update();
    }
    RegionUninit(&reg1);
    RegionUninit(&reg2);
  }
  else
  {
    box.x1 = p->x + xDst;
    box.y1 = p->y + yDst;
    box.x2 = box.x1 + width;
    box.y2 = box.y1 + height;
    rdpup_begin_update();
    rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
    rdpup_end_update();
  }
  rdpup_switch_os_surface(-1);
}
Ejemplo n.º 20
0
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;
    }
}
Ejemplo n.º 21
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;
}
Ejemplo n.º 22
0
void
rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
             int npt, DDXPointPtr pptInit)
{
    RegionRec clip_reg;
    int num_clips;
    int cd;
    int i;
    int j;
    int got_id;
    int dirty_type;
    int post_process;
    int reset_surface;
    BoxRec box;
    xSegment *segs;
    int nseg;
    struct image_data id;
    WindowPtr pDstWnd;
    PixmapPtr pDstPixmap;
    rdpPixmapRec *pDstPriv;
    rdpPixmapRec *pDirtyPriv;

    LLOGLN(10, ("rdpPolylines:"));
    LLOGLN(10, ("  npt %d mode %d x %d y %d", npt, mode,
                pDrawable->x, pDrawable->y));
#if 0
    LLOGLN(0, ("  points"));

    for (i = 0; i < npt; i++)
    {
        LLOGLN(0, ("    %d %d", pptInit[i].x, pptInit[i].y));
    }

#endif
    /* convert lines to line segments */
    nseg = npt - 1;
    segs = 0;

    if (npt > 1)
    {
        segs = (xSegment *)g_malloc(sizeof(xSegment) * nseg, 0);
        segs[0].x1 = pptInit[0].x + pDrawable->x;
        segs[0].y1 = pptInit[0].y + pDrawable->y;

        if (mode == CoordModeOrigin)
        {
            segs[0].x2 = pptInit[1].x + pDrawable->x;
            segs[0].y2 = pptInit[1].y + pDrawable->y;

            for (i = 2; i < npt; i++)
            {
                segs[i - 1].x1 = segs[i - 2].x2;
                segs[i - 1].y1 = segs[i - 2].y2;
                segs[i - 1].x2 = pptInit[i].x + pDrawable->x;
                segs[i - 1].y2 = pptInit[i].y + pDrawable->y;
            }
        }
        else
        {
            segs[0].x2 = segs[0].x1 + pptInit[1].x;
            segs[0].y2 = segs[0].y1 + pptInit[1].y;

            for (i = 2; i < npt; i++)
            {
                segs[i - 1].x1 = segs[i - 2].x2;
                segs[i - 1].y1 = segs[i - 2].y2;
                segs[i - 1].x2 = segs[i - 1].x1 + pptInit[i].x;
                segs[i - 1].y2 = segs[i - 1].y1 + pptInit[i].y;
            }
        }
    }
    else
    {
        LLOGLN(0, ("rdpPolylines: weird npt [%d]", npt));
    }

#if 0
    LLOGLN(0, ("  segments"));

    for (i = 0; i < nseg; i++)
    {
        LLOGLN(0, ("    %d %d %d %d", segs[i].x1, segs[i].y1,
                   segs[i].x2, segs[i].y2));
    }

#endif

    /* do original call */
    rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit);

    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, ("rdpPolylines: 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, ("rdpPolylines: 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(segs);
        return;
    }

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

    if (cd == 1)
    {
        if (segs != 0)
        {
            if (dirty_type != 0)
            {
                RegionUninit(&clip_reg);
                RegionInit(&clip_reg, NullBox, 0);
                RegionAroundSegs(&clip_reg, segs, nseg);
                draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
                                          pGC->alu, pGC->lineWidth, segs, nseg, 0);
            }
            else if (got_id)
            {
                rdpup_begin_update();
                rdpup_set_fgcolor(pGC->fgPixel);
                rdpup_set_opcode(pGC->alu);
                rdpup_set_pen(0, pGC->lineWidth);

                for (i = 0; i < nseg; i++)
                {
                    rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
                }

                rdpup_set_opcode(GXcopy);
                rdpup_end_update();
            }
        }
    }
    else if (cd == 2)
    {
        num_clips = REGION_NUM_RECTS(&clip_reg);

        if (nseg != 0 && num_clips > 0)
        {
            if (dirty_type != 0)
            {
                draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
                                          pGC->alu, pGC->lineWidth, segs, nseg, 0);
            }
            else if (got_id)
            {
                rdpup_begin_update();
                rdpup_set_fgcolor(pGC->fgPixel);
                rdpup_set_opcode(pGC->alu);
                rdpup_set_pen(0, pGC->lineWidth);

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

                    for (i = 0; i < nseg; i++)
                    {
                        rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
                    }
                }

                rdpup_reset_clip();
                rdpup_set_opcode(GXcopy);
                rdpup_end_update();
            }
        }
    }

    g_free(segs);
    RegionUninit(&clip_reg);

    if (reset_surface)
    {
        rdpup_switch_os_surface(-1);
    }
}