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(®1, &box, 0); draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type, TAG_COPYAREA); RegionUninit(®1); } 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; }
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); }
/* 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; }
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); } }
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; }
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(®, NullBox, 0); RegionCopy(®, 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(®); /* 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(®)[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(®)[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(®); RegionUninit(&clip); g_pScreen->CopyWindow = rdpCopyWindow; }
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(®, NullBox, 0); if (count == 0) { cd = 0; } else { cd = rdp_get_clip(®, pDrawable, pGC); } if (cd == 1) { if (dirty_type != 0) { RegionInit(®1, &box, 0); draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type, 11); RegionUninit(®1); } 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(®1, &box, 0); RegionIntersect(®, ®, ®1); num_clips = REGION_NUM_RECTS(®); if (num_clips > 0) { if (dirty_type != 0) { draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type, 11); } else if (got_id) { rdpup_begin_update(); for (j = num_clips - 1; j >= 0; j--) { box = REGION_RECTS(®)[j]; rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); } rdpup_end_update(); } } RegionUninit(®1); } RegionUninit(®); if (reset_surface) { rdpup_switch_os_surface(-1); } return rv; }
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); } }
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(®1, &box, 0); draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } 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(®1, &box, 0); RegionInit(®2, NullBox, 0); RegionCopy(®2, &clip_reg); RegionIntersect(®1, ®1, ®2); draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); RegionUninit(®2); } 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; }
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; }
/* 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); } }
/* 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 */
/* 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(®1, &box, 0); RegionInit(®2, NullBox, 0); RegionCopy(®2, pDst->clientClip); lx = p->x + pDst->clipOrigin.x; ly = p->y + pDst->clipOrigin.y; RegionTranslate(®2, lx, ly); RegionIntersect(®1, ®1, ®2); if (dirty_type != 0) { draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); } else if (got_id) { num_clips = REGION_NUM_RECTS(®1); if (num_clips > 0) { rdpup_begin_update(); for (j = num_clips - 1; j >= 0; j--) { box = REGION_RECTS(®1)[j]; rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); } rdpup_end_update(); } } RegionUninit(®1); RegionUninit(®2); } 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(®1, &box, 0); draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } 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); } }
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(®1, &box, 0); draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type, TAG_PUTIMAGE); RegionUninit(®1); } 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(®1, &box, 0); RegionInit(®2, NullBox, 0); RegionCopy(®2, &clip_reg); RegionIntersect(®1, ®1, ®2); draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type, TAG_PUTIMAGE); RegionUninit(®1); RegionUninit(®2); } 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); } }
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; }
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); }
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); } }
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); }
/* 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(®1, &box, 0); RegionInit(®2, NullBox, 0); RegionCopy(®2, pDst->clientClip); RegionTranslate(®2, p->x + pDst->clipOrigin.x, p->y + pDst->clipOrigin.y); RegionIntersect(®1, ®1, ®2); num_clips = REGION_NUM_RECTS(®1); if (num_clips > 0) { rdpup_begin_update(); for (j = num_clips - 1; j >= 0; j--) { box = REGION_RECTS(®1)[j]; rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); } rdpup_end_update(); } RegionUninit(®1); RegionUninit(®2); } 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); }
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; } }
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; }
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); } }