RegionPtr rdpRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed) { RegionRec reg; RegionPtr rv; int j; BoxRec box; LLOGLN(0, ("in rdpRestoreAreas")); RegionInit(®, NullBox, 0); RegionCopy(®, prgnExposed); g_pScreen->RestoreAreas = g_rdpScreen.RestoreAreas; rv = g_pScreen->RestoreAreas(pWin, prgnExposed); if (g_do_dirty_ons) { draw_item_add_img_region(&g_screenPriv, ®, GXcopy, RDI_IMGLL); } else { rdpup_begin_update(); for (j = REGION_NUM_RECTS(®) - 1; j >= 0; j--) { box = REGION_RECTS(®)[j]; rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); } rdpup_end_update(); } RegionUninit(®); g_pScreen->RestoreAreas = rdpRestoreAreas; return rv; }
Bool compAllocPixmap(WindowPtr pWin) { int bw = (int) pWin->borderWidth; int x = pWin->drawable.x - bw; int y = pWin->drawable.y - bw; int w = pWin->drawable.width + (bw << 1); int h = pWin->drawable.height + (bw << 1); PixmapPtr pPixmap = compNewPixmap(pWin, x, y, w, h); CompWindowPtr cw = GetCompWindow(pWin); if (!pPixmap) return FALSE; if (cw->update == CompositeRedirectAutomatic) pWin->redirectDraw = RedirectDrawAutomatic; else pWin->redirectDraw = RedirectDrawManual; compSetPixmap(pWin, pPixmap); cw->oldx = COMP_ORIGIN_INVALID; cw->oldy = COMP_ORIGIN_INVALID; cw->damageRegistered = FALSE; if (cw->update == CompositeRedirectAutomatic) { DamageRegister(&pWin->drawable, cw->damage); cw->damageRegistered = TRUE; } /* Make sure our borderClip is up to date */ RegionUninit(&cw->borderClip); RegionCopy(&cw->borderClip, &pWin->borderClip); cw->borderClipX = pWin->drawable.x; cw->borderClipY = pWin->drawable.y; return TRUE; }
void compFreePixmap (WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; PixmapPtr pRedirectPixmap, pParentPixmap; CompWindowPtr cw = GetCompWindow (pWin); if (cw->damageRegistered) { DamageUnregister (&pWin->drawable, cw->damage); cw->damageRegistered = FALSE; DamageEmpty (cw->damage); } /* * Move the parent-constrained border clip region back into * the window so that ValidateTree will handle the unmap * case correctly. Unmap adds the window borderClip to the * parent exposed area; regions beyond the parent cause crashes */ RegionCopy(&pWin->borderClip, &cw->borderClip); pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin); pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent); pWin->redirectDraw = RedirectDrawNone; compSetPixmap (pWin, pParentPixmap); (*pScreen->DestroyPixmap) (pRedirectPixmap); }
static void ShadowCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgn) { ScreenPtr pScreen = pWin->drawable.pScreen; ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen); int num = 0; RegionRec rgnDst; if (pPriv->vtSema) { RegionNull(&rgnDst); RegionCopy(&rgnDst, prgn); RegionTranslate(&rgnDst, pWin->drawable.x - ptOldOrg.x, pWin->drawable.y - ptOldOrg.y); RegionIntersect(&rgnDst, &pWin->borderClip, &rgnDst); if ((num = RegionNumRects(&rgnDst))) { if (pPriv->preRefresh) (*pPriv->preRefresh) (pPriv->pScrn, num, RegionRects(&rgnDst)); } else { RegionUninit(&rgnDst); } } pScreen->CopyWindow = pPriv->CopyWindow; (*pScreen->CopyWindow) (pWin, ptOldOrg, prgn); pScreen->CopyWindow = ShadowCopyWindow; if (num) { if (pPriv->postRefresh) (*pPriv->postRefresh) (pPriv->pScrn, num, RegionRects(&rgnDst)); RegionUninit(&rgnDst); } }
static int ProcDamageSubtract (ClientPtr client) { REQUEST(xDamageSubtractReq); DamageExtPtr pDamageExt; RegionPtr pRepair; RegionPtr pParts; REQUEST_SIZE_MATCH(xDamageSubtractReq); VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess); VERIFY_REGION_OR_NONE(pRepair, stuff->repair, client, DixWriteAccess); VERIFY_REGION_OR_NONE(pParts, stuff->parts, client, DixWriteAccess); if (pDamageExt->level != DamageReportRawRegion) { DamagePtr pDamage = pDamageExt->pDamage; if (pRepair) { if (pParts) RegionIntersect(pParts, DamageRegion (pDamage), pRepair); if (DamageSubtract (pDamage, pRepair)) DamageExtReport (pDamage, DamageRegion (pDamage), (void *) pDamageExt); } else { if (pParts) RegionCopy(pParts, DamageRegion (pDamage)); DamageEmpty (pDamage); } } return Success; }
int ProcXFixesSetRegion(ClientPtr client) { int things; RegionPtr pRegion, pNew; REQUEST(xXFixesSetRegionReq); REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq); VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); things = (client->req_len << 2) - sizeof(xXFixesCreateRegionReq); if (things & 4) return BadLength; things >>= 3; pNew = RegionFromRects(things, (xRectangle *) (stuff + 1), CT_UNSORTED); if (!pNew) return BadAlloc; if (!RegionCopy(pRegion, pNew)) { RegionDestroy(pNew); return BadAlloc; } RegionDestroy(pNew); return Success; }
int draw_item_add_line_region(rdpPixmapRec *priv, RegionPtr reg, int color, int opcode, int width, xSegment *segs, int nseg, int is_segment) { struct rdp_draw_item *di; LLOGLN(10, ("draw_item_add_line_region:")); di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1); di->type = RDI_LINE; di->u.line.fg_color = color; di->u.line.opcode = opcode; di->u.line.width = width; di->u.line.segs = (xSegment *)g_malloc(sizeof(xSegment) * nseg, 1); memcpy(di->u.line.segs, segs, sizeof(xSegment) * nseg); di->u.line.nseg = nseg; if (is_segment) { di->u.line.flags = 1; } di->reg = RegionCreate(NullBox, 0); di->flags |= 1; RegionCopy(di->reg, reg); draw_item_add(priv, di); return 0; }
void miCopyClip(GCPtr pgcDst, GCPtr pgcSrc) { if (pgcSrc->clientClip) { RegionPtr prgnNew = RegionCreate(NULL, 1); RegionCopy(prgnNew, (RegionPtr) (pgcSrc->clientClip)); (*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, prgnNew, 0); } else { (*pgcDst->funcs->ChangeClip) (pgcDst, CT_NONE, NULL, 0); } }
Bool xf86InitFBManagerRegion(ScreenPtr pScreen, RegionPtr FullRegion) { FBManagerPtr offman; if (RegionNil(FullRegion)) return FALSE; if (!dixRegisterPrivateKey(&xf86FBScreenKeyRec, PRIVATE_SCREEN, 0)) return FALSE; if (!xf86RegisterOffscreenManager(pScreen, &xf86FBManFuncs)) return FALSE; offman = malloc(sizeof(FBManager)); if (!offman) return FALSE; dixSetPrivate(&pScreen->devPrivates, xf86FBScreenKey, offman); offman->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = xf86FBCloseScreen; offman->InitialBoxes = RegionCreate(NULL, 1); offman->FreeBoxes = RegionCreate(NULL, 1); RegionCopy(offman->InitialBoxes, FullRegion); RegionCopy(offman->FreeBoxes, FullRegion); offman->pScreen = pScreen; offman->UsedAreas = NULL; offman->LinearAreas = NULL; offman->NumUsedAreas = 0; offman->NumCallbacks = 0; offman->FreeBoxesUpdateCallback = NULL; offman->devPrivates = NULL; return TRUE; }
static void MSMDRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, DRI2BufferPtr pDstBuffer, DRI2BufferPtr pSrcBuffer) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); DrawablePtr pSrcDraw = dri2draw(pDraw, pSrcBuffer); DrawablePtr pDstDraw = dri2draw(pDraw, pDstBuffer); RegionPtr pCopyClip; GCPtr pGC; DEBUG_MSG("pDraw=%p, pDstBuffer=%p (%p), pSrcBuffer=%p (%p)", pDraw, pDstBuffer, pSrcDraw, pSrcBuffer, pDstDraw); /* hack.. since we don't have proper fencing / kernel synchronization * we can get in a scenario where we get many frames ahead of the gpu, * with queued up cmd sequence like: render -> blit -> render -> blit .. * This hack makes sure the previous blit has completed. */ { MSMPtr pMsm = MSMPTR(pScrn); MSMDRI2BufferPtr buf = MSMBUF(pDstBuffer); pMsm->pExa->PrepareAccess(buf->pPixmap, 0); pMsm->pExa->FinishAccess(buf->pPixmap, 0); } pGC = GetScratchGC(pDstDraw->depth, pScreen); if (!pGC) { return; } pCopyClip = REGION_CREATE(pScreen, NULL, 0); RegionCopy(pCopyClip, pRegion); (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pCopyClip, 0); ValidateGC(pDstDraw, pGC); /* If the dst is the framebuffer, and we had a way to * schedule a deferred blit synchronized w/ vsync, that * would be a nice thing to do utilize here to avoid * tearing.. when we have sync object support for GEM * buffers, I think we could do something more clever * here. */ pGC->ops->CopyArea(pSrcDraw, pDstDraw, pGC, 0, 0, pDraw->width, pDraw->height, 0, 0); FreeScratchGC(pGC); MSMFlushAccel(pScreen); }
int ProcXFixesCopyRegion (ClientPtr client) { RegionPtr pSource, pDestination; REQUEST (xXFixesCopyRegionReq); VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); if (!RegionCopy(pDestination, pSource)) return BadAlloc; return Success; }
RegionPtr XFixesRegionCopy(RegionPtr pRegion) { RegionPtr pNew = RegionCreate(RegionExtents(pRegion), RegionNumRects(pRegion)); if (!pNew) return 0; if (!RegionCopy(pNew, pRegion)) { RegionDestroy(pNew); return 0; } return pNew; }
int draw_item_add_img_region(rdpPixmapRec *priv, RegionPtr reg, int opcode, int type) { struct rdp_draw_item *di; di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1); di->type = type; di->reg = RegionCreate(NullBox, 0); RegionCopy(di->reg, reg); di->u.img.opcode = opcode; draw_item_add(priv, di); return 0; }
int draw_item_add_fill_region(rdpPixmapRec *priv, RegionPtr reg, int color, int opcode) { struct rdp_draw_item *di; di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1); di->type = RDI_FILL; di->u.fill.fg_color = color; di->u.fill.opcode = opcode; di->reg = RegionCreate(NullBox, 0); RegionCopy(di->reg, reg); draw_item_add(priv, di); return 0; }
/** * find if the remote window denoted by a_remote * is paired with an internal Window within the Xephyr server. * If the remove window is paired with an internal window, send an * expose event to the client insterested in the internal window expose event. * * Pairing happens when a drawable inside Xephyr is associated with * a GL surface in a DRI environment. * Look at the function ProcXF86DRICreateDrawable in ephyrdriext.c to * know a paired window is created. * * This is useful to make GL drawables (only windows for now) handle * expose events and send those events to clients. */ static void ephyrExposePairedWindow(int a_remote) { EphyrWindowPair *pair = NULL; RegionRec reg; ScreenPtr screen; if (!findWindowPairFromRemote(a_remote, &pair)) { EPHYR_LOG("did not find a pair for this window\n"); return; } screen = pair->local->drawable.pScreen; RegionNull(®); RegionCopy(®, &pair->local->clipList); screen->WindowExposures(pair->local, ®); RegionUninit(®); }
static void shadowReportFunc(DamagePtr pDamage, RegionPtr pRegion, void *closure) { ScreenPtr pScreen = closure; shadowBufPtr pBuf = (shadowBufPtr) dixLookupPrivate(&pScreen->devPrivates, shadowScrPrivateKey); /* Register the damaged region, use DamageReportNone below when we * want to break BC below... */ RegionUnion(&pDamage->damage, &pDamage->damage, pRegion); /* * BC hack. In 7.0 and earlier several drivers would inspect the * 'damage' member directly, so we have to keep it existing. */ RegionCopy(&pBuf->damage, pRegion); }
void sgx_exa_copy_region(DrawablePtr draw, RegionPtr reg, DrawablePtr src_draw, DrawablePtr dst_draw) { ScreenPtr screen = dst_draw->pScreen; RegionPtr copy_clip = RegionCreate(NULL, 0); GCPtr gc; gc = GetScratchGC(dst_draw->depth, screen); RegionCopy(copy_clip, reg); (*gc->funcs->ChangeClip)(gc, CT_REGION, copy_clip, 0); ValidateGC(dst_draw, gc); (*gc->ops->CopyArea)(src_draw, dst_draw, gc, 0, 0, draw->width, draw->height, 0, 0); FreeScratchGC(gc); }
void xnestCopyClip(GCPtr pGCDst, GCPtr pGCSrc) { RegionPtr pRgn; switch (pGCSrc->clientClipType) { default: case CT_NONE: xnestDestroyClip(pGCDst); break; case CT_REGION: pRgn = RegionCreate(NULL, 1); RegionCopy(pRgn, pGCSrc->clientClip); xnestChangeClip(pGCDst, CT_REGION, pRgn, 0); break; } }
static void ARMSOCDRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, DRI2BufferPtr pDstBuffer, DRI2BufferPtr pSrcBuffer) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); RegionPtr pCopyClip; GCPtr pGC; PixmapPtr pScratchPixmap; struct ARMSOCDRI2BufferRec *src = ARMSOCBUF(pSrcBuffer); DEBUG_MSG("pDraw=%p, pDstBuffer=%p pSrcBuffer=%p", pDraw, pDstBuffer, pSrcBuffer); pGC = GetScratchGC(pDraw->depth, pScreen); if (!pGC) return; pCopyClip = REGION_CREATE(pScreen, NULL, 0); RegionCopy(pCopyClip, pRegion); (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pCopyClip, 0); ValidateGC(pDraw, pGC); /* If the dst is the framebuffer, and we had a way to * schedule a deferred blit synchronized w/ vsync, that * would be a nice thing to do utilize here to avoid * tearing.. when we have sync object support for GEM * buffers, I think we could do something more clever * here. */ pScratchPixmap = GetScratchPixmapHeader(pScreen, armsoc_bo_width(src->bo), armsoc_bo_height(src->bo), armsoc_bo_depth(src->bo), armsoc_bo_bpp(src->bo), armsoc_bo_pitch(src->bo), armsoc_bo_map(src->bo)); pGC->ops->CopyArea((DrawablePtr) pScratchPixmap, pDraw, pGC, 0, 0, pDraw->width, pDraw->height, 0, 0); FreeScratchPixmapHeader(pScratchPixmap); FreeScratchGC(pGC); }
int draw_item_add_srcblt_region(rdpPixmapRec *priv, RegionPtr reg, int srcx, int srcy, int dstx, int dsty, int cx, int cy) { struct rdp_draw_item *di; LLOGLN(10, ("draw_item_add_srcblt_region:")); di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1); di->type = RDI_SCRBLT; di->u.scrblt.srcx = srcx; di->u.scrblt.srcy = srcy; di->u.scrblt.dstx = dstx; di->u.scrblt.dsty = dsty; di->u.scrblt.cx = cx; di->u.scrblt.cy = cy; di->reg = RegionCreate(NullBox, 0); RegionCopy(di->reg, reg); draw_item_add(priv, di); return 0; }
RegionPtr rdpRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed) { RegionRec reg; RegionPtr rv; int j; BoxRec box; DEBUG_OUT_OPS(("in rdpRestoreAreas\n")); RegionInit(®, NullBox, 0); RegionCopy(®, prgnExposed); g_pScreen->RestoreAreas = g_rdpScreen.RestoreAreas; rv = g_pScreen->RestoreAreas(pWin, prgnExposed); rdpup_begin_update(); for (j = REGION_NUM_RECTS(®) - 1; j >= 0; j--) { box = REGION_RECTS(®)[j]; rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); } rdpup_end_update(); RegionUninit(®); g_pScreen->RestoreAreas = rdpRestoreAreas; return rv; }
static void ARMSOCDRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, DRI2BufferPtr pDstBuffer, DRI2BufferPtr pSrcBuffer) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); DrawablePtr pSrcDraw = dri2draw(pDraw, pSrcBuffer); DrawablePtr pDstDraw = dri2draw(pDraw, pDstBuffer); RegionPtr pCopyClip; GCPtr pGC; DEBUG_MSG("pDraw=%p, pDstBuffer=%p (%p), pSrcBuffer=%p (%p)", pDraw, pDstBuffer, pSrcDraw, pSrcBuffer, pDstDraw); pGC = GetScratchGC(pDstDraw->depth, pScreen); if (!pGC) return; pCopyClip = REGION_CREATE(pScreen, NULL, 0); RegionCopy(pCopyClip, pRegion); (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pCopyClip, 0); ValidateGC(pDstDraw, pGC); /* If the dst is the framebuffer, and we had a way to * schedule a deferred blit synchronized w/ vsync, that * would be a nice thing to do utilize here to avoid * tearing.. when we have sync object support for GEM * buffers, I think we could do something more clever * here. */ pGC->ops->CopyArea(pSrcDraw, pDstDraw, pGC, 0, 0, pDraw->width, pDraw->height, 0, 0); FreeScratchGC(pGC); }
/* return 2, draw using clip */ int rdpDrawGetClip(rdpPtr dev, RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC) { WindowPtr pWindow; RegionPtr temp; BoxRec box; int rv; rv = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { if (is_clientClip_region(pGC)) { miComputeCompositeClip(pGC, pDrawable); RegionCopy(pRegion, pGC->pCompositeClip); rv = 2; } else { rv = 1; } if (rv == 2) /* check if the clip is the entire pixmap */ { box.x1 = 0; box.y1 = 0; box.x2 = pDrawable->width; box.y2 = pDrawable->height; if (rdpRegionContainsRect(pRegion, &box) == rgnIN) { rv = 1; } } } else if (pDrawable->type == DRAWABLE_WINDOW) { pWindow = (WindowPtr)pDrawable; if (pWindow->viewable) { if (pGC->subWindowMode == IncludeInferiors) { temp = &pWindow->borderClip; } else { temp = &pWindow->clipList; } if (rdpRegionNotEmpty(temp)) { if (is_clientClip_region(pGC)) { rdpRegionCopy(pRegion, pGC->clientClip); rdpRegionTranslate(pRegion, pDrawable->x + pGC->clipOrg.x, pDrawable->y + pGC->clipOrg.y); rdpRegionIntersect(pRegion, pRegion, temp); rv = 2; } else { rdpRegionCopy(pRegion, temp); rv = 2; } if (rv == 2) /* check if the clip is the entire screen */ { box.x1 = 0; box.y1 = 0; box.x2 = dev->width; box.y2 = dev->height; if (rdpRegionContainsRect(pRegion, &box) == rgnIN) { rv = 1; } } } } } return rv; }
Bool exaHWCopyNtoN(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown) { ExaScreenPriv(pDstDrawable->pScreen); PixmapPtr pSrcPixmap, pDstPixmap; ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap; int src_off_x, src_off_y; int dst_off_x, dst_off_y; RegionPtr srcregion = NULL, dstregion = NULL; xRectangle *rects; Bool ret = TRUE; /* avoid doing copy operations if no boxes */ if (nbox == 0) return TRUE; pSrcPixmap = exaGetDrawablePixmap(pSrcDrawable); pDstPixmap = exaGetDrawablePixmap(pDstDrawable); exaGetDrawableDeltas(pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y); exaGetDrawableDeltas(pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y); rects = malloc(nbox * sizeof(xRectangle)); if (rects) { int i; int ordering; for (i = 0; i < nbox; i++) { rects[i].x = pbox[i].x1 + dx + src_off_x; rects[i].y = pbox[i].y1 + dy + src_off_y; rects[i].width = pbox[i].x2 - pbox[i].x1; rects[i].height = pbox[i].y2 - pbox[i].y1; } /* This must match the RegionCopy() logic for reversing rect order */ if (nbox == 1 || (dx > 0 && dy > 0) || (pDstDrawable != pSrcDrawable && (pDstDrawable->type != DRAWABLE_WINDOW || pSrcDrawable->type != DRAWABLE_WINDOW))) ordering = CT_YXBANDED; else ordering = CT_UNSORTED; srcregion = RegionFromRects(nbox, rects, ordering); free(rects); if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask, pGC->fillStyle, pGC->alu, pGC->clientClip != NULL)) { dstregion = RegionCreate(NullBox, 0); RegionCopy(dstregion, srcregion); RegionTranslate(dstregion, dst_off_x - dx - src_off_x, dst_off_y - dy - src_off_y); } } pSrcExaPixmap = ExaGetPixmapPriv(pSrcPixmap); pDstExaPixmap = ExaGetPixmapPriv(pDstPixmap); /* Check whether the accelerator can use this pixmap. * If the pitch of the pixmaps is out of range, there's nothing * we can do but fall back to software rendering. */ if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH || pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH) goto fallback; /* If the width or the height of either of the pixmaps * is out of range, check whether the boxes are actually out of the * addressable range as well. If they aren't, we can still do * the copying in hardware. */ if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) { int i; for (i = 0; i < nbox; i++) { /* src */ if ((pbox[i].x2 + dx + src_off_x) >= pExaScr->info->maxX || (pbox[i].y2 + dy + src_off_y) >= pExaScr->info->maxY) goto fallback; /* dst */ if ((pbox[i].x2 + dst_off_x) >= pExaScr->info->maxX || (pbox[i].y2 + dst_off_y) >= pExaScr->info->maxY) goto fallback; } } if (pExaScr->do_migration) { ExaMigrationRec pixmaps[2]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pDstPixmap; pixmaps[0].pReg = dstregion; pixmaps[1].as_dst = FALSE; pixmaps[1].as_src = TRUE; pixmaps[1].pPix = pSrcPixmap; pixmaps[1].pReg = srcregion; exaDoMigration(pixmaps, 2, TRUE); } /* Mixed directions must be handled specially if the card is lame */ if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) && reverse != upsidedown) { if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy)) goto out; goto fallback; } if (exaPixmapHasGpuCopy(pDstPixmap)) { /* Normal blitting. */ if (exaPixmapHasGpuCopy(pSrcPixmap)) { if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, upsidedown ? -1 : 1, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) { goto fallback; } while (nbox--) { (*pExaScr->info->Copy) (pDstPixmap, pbox->x1 + dx + src_off_x, pbox->y1 + dy + src_off_y, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } (*pExaScr->info->DoneCopy) (pDstPixmap); exaMarkSync(pDstDrawable->pScreen); /* UTS: mainly for SHM PutImage's secondary path. * * Only taking this path for directly accessible pixmaps. */ } else if (!pDstExaPixmap->pDamage && pSrcExaPixmap->sys_ptr) { int bpp = pSrcDrawable->bitsPerPixel; int src_stride = exaGetPixmapPitch(pSrcPixmap); CARD8 *src = NULL; if (!pExaScr->info->UploadToScreen) goto fallback; if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel) goto fallback; if (pSrcDrawable->bitsPerPixel < 8) goto fallback; if (pGC && !(pGC->alu == GXcopy && EXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask))) goto fallback; while (nbox--) { src = pSrcExaPixmap->sys_ptr + (pbox->y1 + dy + src_off_y) * src_stride + (pbox->x1 + dx + src_off_x) * (bpp / 8); if (!pExaScr->info-> UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, (char *) src, src_stride)) goto fallback; pbox++; } } else goto fallback; } else goto fallback; goto out; fallback: ret = FALSE; out: if (dstregion) { RegionUninit(dstregion); RegionDestroy(dstregion); } if (srcregion) { RegionUninit(srcregion); RegionDestroy(srcregion); } return ret; }
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: 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 (pDst->type == DRAWABLE_WINDOW) { pDstWnd = (WindowPtr)pDst; if (pDstWnd->viewable) { post_process = 1; if (g_do_dirty_ons) { LLOGLN(10, ("rdpPutImage: 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; } 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); } }
/** Transfer \a pBits image to back-end server associated with \a * pDrawable's screen. If primitive subdivision optimization is * enabled, then only transfer the sections of \a pBits that are * visible (i.e., not-clipped) to the back-end server. */ void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pBits) { DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); XImage *img; if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; img = XCreateImage(dmxScreen->beDisplay, dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual, depth, format, leftPad, pBits, w, h, BitmapPad(dmxScreen->beDisplay), (format == ZPixmap) ? PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad)); if (img) { Drawable draw; DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); if (dmxSubdividePrimitives && pGC->pCompositeClip) { RegionPtr pSubImages; RegionPtr pClip; BoxRec box; BoxPtr pBox; int nBox; box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; pSubImages = RegionCreate(&box, 1); pClip = RegionCreate(NullBox, 1); RegionCopy(pClip, pGC->pCompositeClip); RegionTranslate(pClip, -pDrawable->x, -pDrawable->y); RegionIntersect(pSubImages, pSubImages, pClip); nBox = RegionNumRects(pSubImages); pBox = RegionRects(pSubImages); while (nBox--) { XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img, pBox->x1 - box.x1, pBox->y1 - box.y1, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1); pBox++; } RegionDestroy(pClip); RegionDestroy(pSubImages); } else { XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img, 0, 0, x, y, w, h); } XFree(img); /* Use XFree instead of XDestroyImage * because pBits is passed in from the * caller. */ dmxSync(dmxScreen, FALSE); } else { /* Error -- this should not happen! */ } }
/* * Redirect one window for one client */ int compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update) { CompWindowPtr cw = GetCompWindow (pWin); CompClientWindowPtr ccw; CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen); WindowPtr pLayerWin; Bool anyMarked = FALSE; if (pWin == cs->pOverlayWin) { return Success; } if (!pWin->parent) return BadMatch; /* * Only one Manual update is allowed */ if (cw && update == CompositeRedirectManual) for (ccw = cw->clients; ccw; ccw = ccw->next) if (ccw->update == CompositeRedirectManual) return BadAccess; /* * Allocate per-client per-window structure * The client *could* allocate multiple, but while supported, * it is not expected to be common */ ccw = malloc(sizeof (CompClientWindowRec)); if (!ccw) return BadAlloc; ccw->id = FakeClientID (pClient->index); ccw->update = update; /* * Now make sure there's a per-window structure to hang this from */ if (!cw) { cw = malloc(sizeof (CompWindowRec)); if (!cw) { free(ccw); return BadAlloc; } cw->damage = DamageCreate (compReportDamage, compDestroyDamage, DamageReportNonEmpty, FALSE, pWin->drawable.pScreen, pWin); if (!cw->damage) { free(ccw); free(cw); return BadAlloc; } anyMarked = compMarkWindows (pWin, &pLayerWin); /* Make sure our borderClip is correct for ValidateTree */ RegionNull(&cw->borderClip); RegionCopy(&cw->borderClip, &pWin->borderClip); cw->borderClipX = pWin->drawable.x; cw->borderClipY = pWin->drawable.y; cw->update = CompositeRedirectAutomatic; cw->clients = 0; cw->oldx = COMP_ORIGIN_INVALID; cw->oldy = COMP_ORIGIN_INVALID; cw->damageRegistered = FALSE; cw->damaged = FALSE; cw->pOldPixmap = NullPixmap; dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, cw); } ccw->next = cw->clients; cw->clients = ccw; if (!AddResource (ccw->id, CompositeClientWindowType, pWin)) return BadAlloc; if (ccw->update == CompositeRedirectManual) { if (!anyMarked) anyMarked = compMarkWindows (pWin, &pLayerWin); if (cw->damageRegistered) { DamageUnregister (&pWin->drawable, cw->damage); cw->damageRegistered = FALSE; } cw->update = CompositeRedirectManual; } else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered) { if (!anyMarked) anyMarked = compMarkWindows (pWin, &pLayerWin); } if (!compCheckRedirect (pWin)) { FreeResource (ccw->id, RT_NONE); return BadAlloc; } if (anyMarked) compHandleMarkedWindows (pWin, pLayerWin); return Success; }
static Bool localQueryLargestOffscreenArea(ScreenPtr pScreen, int *width, int *height, int granularity, int preferences, int severity) { FBManagerPtr offman; RegionPtr newRegion = NULL; BoxPtr pbox; int nbox; int x, w, h, area, oldArea; *width = *height = oldArea = 0; if (granularity <= 1) granularity = 0; if ((preferences < 0) || (preferences > 3)) return FALSE; offman = (FBManagerPtr) dixLookupPrivate(&pScreen->devPrivates, xf86FBScreenKey); if (severity < 0) severity = 0; if (severity > 2) severity = 2; switch (severity) { case 2: if (offman->NumUsedAreas) { FBLinkPtr pLink; RegionRec tmpRegion; newRegion = RegionCreate(NULL, 1); RegionCopy(newRegion, offman->InitialBoxes); pLink = offman->UsedAreas; while (pLink) { if (!pLink->area.RemoveAreaCallback) { RegionInit(&tmpRegion, &(pLink->area.box), 1); RegionSubtract(newRegion, newRegion, &tmpRegion); RegionUninit(&tmpRegion); } pLink = pLink->next; } nbox = RegionNumRects(newRegion); pbox = RegionRects(newRegion); break; } case 1: if (offman->NumUsedAreas) { FBLinkPtr pLink; RegionRec tmpRegion; newRegion = RegionCreate(NULL, 1); RegionCopy(newRegion, offman->FreeBoxes); pLink = offman->UsedAreas; while (pLink) { if (pLink->area.RemoveAreaCallback) { RegionInit(&tmpRegion, &(pLink->area.box), 1); RegionAppend(newRegion, &tmpRegion); RegionUninit(&tmpRegion); } pLink = pLink->next; } nbox = RegionNumRects(newRegion); pbox = RegionRects(newRegion); break; } default: nbox = RegionNumRects(offman->FreeBoxes); pbox = RegionRects(offman->FreeBoxes); break; } while (nbox--) { x = pbox->x1; if (granularity > 1) x = ((x + granularity - 1) / granularity) * granularity; w = pbox->x2 - x; h = pbox->y2 - pbox->y1; area = w * h; if (w > 0) { Bool gotIt = FALSE; switch (preferences) { case FAVOR_AREA_THEN_WIDTH: if ((area > oldArea) || ((area == oldArea) && (w > *width))) gotIt = TRUE; break; case FAVOR_AREA_THEN_HEIGHT: if ((area > oldArea) || ((area == oldArea) && (h > *height))) gotIt = TRUE; break; case FAVOR_WIDTH_THEN_AREA: if ((w > *width) || ((w == *width) && (area > oldArea))) gotIt = TRUE; break; case FAVOR_HEIGHT_THEN_AREA: if ((h > *height) || ((h == *height) && (area > oldArea))) gotIt = TRUE; break; } if (gotIt) { *width = w; *height = h; oldArea = area; } } pbox++; } if (newRegion) RegionDestroy(newRegion); return TRUE; }
void winReshapeMultiWindow(WindowPtr pWin) { int nRects; RegionRec rrNewShape; BoxPtr pShape, pRects, pEnd; HRGN hRgn, hRgnRect; winWindowPriv(pWin); winDebug("winReshape ()\n"); /* Bail if the window is the root window */ if (pWin->parent == NULL) return; /* Bail if the window is not top level */ if (pWin->parent->parent != NULL) return; /* Bail if Windows window handle is invalid */ if (pWinPriv->hWnd == NULL) return; /* Free any existing window region stored in the window privates */ if (pWinPriv->hRgn != NULL) { DeleteObject(pWinPriv->hRgn); pWinPriv->hRgn = NULL; } /* Bail if the window has no bounding region defined */ if (!wBoundingShape(pWin)) return; RegionNull(&rrNewShape); RegionCopy(&rrNewShape, wBoundingShape(pWin)); RegionTranslate(&rrNewShape, pWin->borderWidth, pWin->borderWidth); nRects = RegionNumRects(&rrNewShape); pShape = RegionRects(&rrNewShape); /* Don't do anything if there are no rectangles in the region */ if (nRects > 0) { RECT rcClient; RECT rcWindow; int iOffsetX, iOffsetY; /* Get client rectangle */ if (!GetClientRect(pWinPriv->hWnd, &rcClient)) { ErrorF("winReshape - GetClientRect failed, bailing: %d\n", (int) GetLastError()); return; } /* Translate client rectangle coords to screen coords */ /* NOTE: Only transforms top and left members */ ClientToScreen(pWinPriv->hWnd, (LPPOINT) &rcClient); /* Get window rectangle */ if (!GetWindowRect(pWinPriv->hWnd, &rcWindow)) { ErrorF("winReshape - GetWindowRect failed, bailing: %d\n", (int) GetLastError()); return; } /* Calculate offset from window upper-left to client upper-left */ iOffsetX = rcClient.left - rcWindow.left; iOffsetY = rcClient.top - rcWindow.top; /* Create initial Windows region for title bar */ /* FIXME: Mean, nasty, ugly hack!!! */ hRgn = CreateRectRgn(0, 0, rcWindow.right, iOffsetY); if (hRgn == NULL) { ErrorF("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " "failed: %d\n", 0, 0, (int) rcWindow.right, iOffsetY, (int) GetLastError()); } /* Loop through all rectangles in the X region */ for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) { /* Create a Windows region for the X rectangle */ hRgnRect = CreateRectRgn(pRects->x1 + iOffsetX, pRects->y1 + iOffsetY, pRects->x2 + iOffsetX, pRects->y2 + iOffsetY); if (hRgnRect == NULL) { ErrorF("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " "failed: %d\n" "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n", pRects->x1 + iOffsetX, pRects->y1 + iOffsetY, pRects->x2 + iOffsetX, pRects->y2 + iOffsetY, (int) GetLastError(), pRects->x1, pRects->x2, iOffsetX, pRects->y1, pRects->y2, iOffsetY); } /* Merge the Windows region with the accumulated region */ if (CombineRgn(hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) { ErrorF("winReshape - CombineRgn () failed: %d\n", (int) GetLastError()); } /* Delete the temporary Windows region */ DeleteObject(hRgnRect); } /* Save a handle to the composite region in the window privates */ pWinPriv->hRgn = hRgn; } RegionUninit(&rrNewShape); return; }
static int ProcWindowsWMFrameDraw(ClientPtr client) { REQUEST(xWindowsWMFrameDrawReq); WindowPtr pWin; win32RootlessWindowPtr pRLWinPriv; RECT rcNew; int nCmdShow, rc; RegionRec newShape; REQUEST_SIZE_MATCH(xWindowsWMFrameDrawReq); #if CYGMULTIWINDOW_DEBUG ErrorF("ProcWindowsWMFrameDraw\n"); #endif rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); if (rc != Success) return rc; #if CYGMULTIWINDOW_DEBUG ErrorF("ProcWindowsWMFrameDraw - Window found\n"); #endif pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow(pWin, TRUE); if (pRLWinPriv == 0) return BadWindow; #if CYGMULTIWINDOW_DEBUG ErrorF("ProcWindowsWMFrameDraw - HWND %p 0x%08x 0x%08x\n", pRLWinPriv->hWnd, (int) stuff->frame_style, (int) stuff->frame_style_ex); ErrorF("ProcWindowsWMFrameDraw - %d %d %d %d\n", stuff->ix, stuff->iy, stuff->iw, stuff->ih); #endif /* Store the origin, height, and width in a rectangle structure */ SetRect(&rcNew, stuff->ix, stuff->iy, stuff->ix + stuff->iw, stuff->iy + stuff->ih); /* * Calculate the required size of the Windows window rectangle, * given the size of the Windows window client area. */ AdjustWindowRectEx(&rcNew, stuff->frame_style, FALSE, stuff->frame_style_ex); /* Set the window extended style flags */ if (!SetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE, stuff->frame_style_ex)) { return BadValue; } /* Set the window standard style flags */ if (!SetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE, stuff->frame_style)) { return BadValue; } /* Flush the window style */ if (!SetWindowPos(pRLWinPriv->hWnd, NULL, rcNew.left, rcNew.top, rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE)) { return BadValue; } if (!IsWindowVisible(pRLWinPriv->hWnd)) nCmdShow = SW_HIDE; else nCmdShow = SW_SHOWNA; ShowWindow(pRLWinPriv->hWnd, nCmdShow); if (wBoundingShape(pWin) != NULL) { /* wBoundingShape is relative to *inner* origin of window. Translate by borderWidth to get the outside-relative position. */ RegionNull(&newShape); RegionCopy(&newShape, wBoundingShape(pWin)); RegionTranslate(&newShape, pWin->borderWidth, pWin->borderWidth); winMWExtWMReshapeFrame(pRLWinPriv, &newShape); RegionUninit(&newShape); } #if CYGMULTIWINDOW_DEBUG ErrorF("ProcWindowsWMFrameDraw - done\n"); #endif return Success; }