/* 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); } }
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); } }