Esempio n. 1
0
/* tested with pGC->lineWidth = 0, 1, 2, 4 and opcodes 3 and 6 */
void rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
		xRectangle *rects)
{
	RegionRec clip_reg;
	RegionPtr fill_reg;
	int num_clips;
	int cd;
	int lw;
	int i;
	int j;
	int up;
	int down;
	int got_id;
	int dirty_type;
	int post_process;
	int reset_surface;
	xRectangle *regRects;
	xRectangle *r;
	xRectangle *rect1;
	BoxRec box;
	struct image_data id;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

					rdpup_end_update();
				}
			}

			RegionDestroy(fill_reg);
		}
	}

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

	if (reset_surface)
	{
		rdpup_switch_os_surface(-1);
	}
}
Esempio n. 2
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);
    }
}