Ejemplo n.º 1
0
static void
miColorRects (PicturePtr    pDst,
	      PicturePtr    pClipPict,
	      xRenderColor  *color,
	      int	    nRect,
	      xRectangle    *rects,
	      int	    xoff,
	      int	    yoff)
{
    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
    CARD32		pixel;
    GCPtr		pGC;
    CARD32		tmpval[5];
    RegionPtr		pClip;
    unsigned long	mask;

    miRenderColorToPixel (pDst->pFormat, color, &pixel);

    pGC = GetScratchGC (pDst->pDrawable->depth, pScreen);
    if (!pGC)
	return;
    tmpval[0] = GXcopy;
    tmpval[1] = pixel;
    tmpval[2] = pDst->subWindowMode;
    mask = GCFunction | GCForeground | GCSubwindowMode;
    if (pClipPict->clientClipType == CT_REGION)
    {
	tmpval[3] = pDst->clipOrigin.x - xoff;
	tmpval[4] = pDst->clipOrigin.y - yoff;
	mask |= GCClipXOrigin|GCClipYOrigin;
	
	pClip = REGION_CREATE (pScreen, NULL, 1);
	REGION_COPY (pScreen, pClip,
		     (RegionPtr) pClipPict->clientClip);
	(*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);
    }

    ChangeGC (pGC, mask, tmpval);
    ValidateGC (pDst->pDrawable, pGC);
    if (xoff || yoff)
    {
	int	i;
	for (i = 0; i < nRect; i++)
	{
	    rects[i].x -= xoff;
	    rects[i].y -= yoff;
	}
    }
    (*pGC->ops->PolyFillRect) (pDst->pDrawable, pGC, nRect, rects);
    if (xoff || yoff)
    {
	int	i;
	for (i = 0; i < nRect; i++)
	{
	    rects[i].x += xoff;
	    rects[i].y += yoff;
	}
    }
    FreeScratchGC (pGC);
}
static void
vivante_dri2_CopyRegion(DrawablePtr drawable, RegionPtr pRegion,
	DRI2BufferPtr dstBuf, DRI2BufferPtr srcBuf)
{
	ScreenPtr screen = drawable->pScreen;
	DrawablePtr src = vivante_dri2_get_drawable(srcBuf, drawable);
	DrawablePtr dst = vivante_dri2_get_drawable(dstBuf, drawable);
	RegionPtr clip;
	GCPtr gc;

	gc = GetScratchGC(dst->depth, screen);
	if (!gc)
		return;

	clip = REGION_CREATE(screen, NULL, 0);
	REGION_COPY(screen, clip, pRegion);
	gc->funcs->ChangeClip(gc, CT_REGION, clip, 0);
	ValidateGC(dst, gc);

	/*
	 * FIXME: wait for scanline to be outside the region to be copied...
	 * that is an interesting problem for Dove/GAL stuff because they're
	 * independent, and there's no way for the GPU to know where the
	 * scan position is.  For now, just do the copy anyway.
	 */
	gc->ops->CopyArea(src, dst, gc, 0, 0,
			  drawable->width, drawable->height, 0, 0);

	FreeScratchGC(gc);
}
Ejemplo n.º 3
0
Archivo: xf86fbman.c Proyecto: aosm/X11
Bool
xf86InitFBManagerRegion(
    ScreenPtr pScreen,  
    RegionPtr FullRegion
){
   FBManagerPtr offman;

   if(REGION_NIL(FullRegion))
	return FALSE;

   if(xf86FBGeneration != serverGeneration) {
	if((xf86FBScreenIndex = AllocateScreenPrivateIndex()) < 0)
		return FALSE;
	xf86FBGeneration = serverGeneration;
   }

   if(!xf86RegisterOffscreenManager(pScreen, &xf86FBManFuncs))
	return FALSE;

   offman = xalloc(sizeof(FBManager));
   if(!offman) return FALSE;

   pScreen->devPrivates[xf86FBScreenIndex].ptr = (pointer)offman;

   offman->CloseScreen = pScreen->CloseScreen;
   pScreen->CloseScreen = xf86FBCloseScreen;

   offman->InitialBoxes = REGION_CREATE(pScreen, NULL, 1);
   offman->FreeBoxes = REGION_CREATE(pScreen, NULL, 1);

   REGION_COPY(pScreen, offman->InitialBoxes, FullRegion);
   REGION_COPY(pScreen, 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;
} 
Ejemplo n.º 4
0
void
miSetShape(WindowPtr pWin)
{
    Bool	WasViewable = (Bool)(pWin->viewable);
    ScreenPtr 	pScreen = pWin->drawable.pScreen;
    Bool	anyMarked = FALSE;
    WindowPtr   pLayerWin;

    if (WasViewable)
    {
	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
						      &pLayerWin);
	if (pWin->valdata)
	{
	    if (HasBorder (pWin))
	    {
		RegionPtr	borderVisible;

		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
		REGION_SUBTRACT(pScreen, borderVisible,
				      &pWin->borderClip, &pWin->winSize);
		pWin->valdata->before.borderVisible = borderVisible;
	    }
	    pWin->valdata->before.resized = TRUE;
	}
    }

    SetWinSize (pWin);
    SetBorderSize (pWin);

    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);

    if (WasViewable)
    {
	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
						NULL);


	if (anyMarked)
	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
    }

    if (WasViewable)
    {
	if (anyMarked)
	    (*pScreen->HandleExposures)(pLayerWin->parent);
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
    CheckCursorConfinement(pWin);
}
Ejemplo n.º 5
0
void
miChangeBorderWidth(WindowPtr pWin, unsigned int width)
{
    int oldwidth;
    Bool anyMarked = FALSE;
    ScreenPtr pScreen;
    Bool WasViewable = (Bool)(pWin->viewable);
    Bool HadBorder;
    WindowPtr  pLayerWin;

    oldwidth = wBorderWidth (pWin);
    if (oldwidth == width)
	return;
    HadBorder = HasBorder(pWin);
    pScreen = pWin->drawable.pScreen;
    if (WasViewable && width < oldwidth)
	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);

    pWin->borderWidth = width;
    SetBorderSize (pWin);

    if (WasViewable)
    {
	if (width > oldwidth)
	{
	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
							  &pLayerWin);
	    /*
	     * save the old border visible region to correctly compute
	     * borderExposed.
	     */
	    if (pWin->valdata && HadBorder)
	    {
		RegionPtr   borderVisible;
		borderVisible = REGION_CREATE(pScreen, NULL, 1);
		REGION_SUBTRACT(pScreen, borderVisible,
				      &pWin->borderClip, &pWin->winSize);
		pWin->valdata->before.borderVisible = borderVisible;
	    }
	}

	if (anyMarked)
	{
	    (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
	    (*pScreen->HandleExposures)(pLayerWin->parent);
	}
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
					  VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
RegionPtr
XFixesRegionCopy (RegionPtr pRegion)
{
    RegionPtr   pNew = REGION_CREATE (0, REGION_EXTENTS(0, pRegion),
				      REGION_NUM_RECTS(pRegion));
    if (!pNew)
	return 0;
    if (!REGION_COPY (0, pNew, pRegion))
    {
	REGION_DESTROY (0, pNew);
	return 0;
    }
    return pNew;
}
Ejemplo n.º 8
0
/* Do ordinary copy */
static void MaliDRI2CopyRegion_copy(DrawablePtr pDraw,
                                    RegionPtr pRegion,
                                    DRI2BufferPtr pDstBuffer,
                                    DRI2BufferPtr pSrcBuffer)
{
    GCPtr pGC;
    RegionPtr copyRegion;
    ScreenPtr pScreen = pDraw->pScreen;
    MaliDRI2BufferPrivatePtr privates;
    PixmapPtr pScratchPixmap;
    privates = (MaliDRI2BufferPrivatePtr)pSrcBuffer->driverPrivate;

//    DebugMsg("Enter MaliDRI2CopyRegion    buf_name:%d\n",pSrcBuffer->name);
/*
#ifdef HAVE_LIBUMP_CACHE_CONTROL
    if (privates->handle != UMP_INVALID_MEMORY_HANDLE) {
//        That's a normal UMP allocation, not a wrapped framebuffer
        ump_cache_operations_control(UMP_CACHE_OP_START);
        ump_switch_hw_usage_secure_id(pSrcBuffer->name, UMP_USED_BY_CPU);
        ump_cache_operations_control(UMP_CACHE_OP_FINISH);
    }
#endif
*/
    pGC = GetScratchGC(pDraw->depth, pScreen);
    pScratchPixmap = GetScratchPixmapHeader(pScreen,
                                            privates->width, privates->height,
                                            privates->depth, pSrcBuffer->cpp * 8,
                                            pSrcBuffer->pitch,
                                            privates->addr + pSrcBuffer->flags);
    copyRegion = REGION_CREATE(pScreen, NULL, 0);
    REGION_COPY(pScreen, copyRegion, pRegion);
    (*pGC->funcs->ChangeClip)(pGC, CT_REGION, copyRegion, 0);
    ValidateGC(pDraw, pGC);
    (*pGC->ops->CopyArea)((DrawablePtr)pScratchPixmap, pDraw, pGC, 0, 0,
                          pDraw->width, pDraw->height, 0, 0);
    FreeScratchPixmapHeader(pScratchPixmap);
    FreeScratchGC(pGC);
/*
#ifdef HAVE_LIBUMP_CACHE_CONTROL
    if (privates->handle != UMP_INVALID_MEMORY_HANDLE) {
//        That's a normal UMP allocation, not a wrapped framebuffer
        ump_cache_operations_control(UMP_CACHE_OP_START);
        ump_switch_hw_usage_secure_id(pSrcBuffer->name, UMP_USED_BY_MALI);
        ump_cache_operations_control(UMP_CACHE_OP_FINISH);
    }
#endif
*/
}
Ejemplo n.º 9
0
static void
LeoCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
	ScreenPtr pScreen = pWin->drawable.pScreen;
	LeoPtr pLeo = LeoGetScreenPrivate (pScreen);
	DDXPointPtr pptSrc;
	DDXPointPtr ppt;
	RegionPtr prgnDst;
	BoxPtr pbox;
	int dx, dy;
	int i, nbox;
	WindowPtr pwinRoot;

	if (pLeo->vtSema)
		return;

	dx = ptOldOrg.x - pWin->drawable.x;
	dy = ptOldOrg.y - pWin->drawable.y;

	pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];

	prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);

	REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
	REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip, prgnSrc);

	pbox = REGION_RECTS(prgnDst);
	nbox = REGION_NUM_RECTS(prgnDst);
	if(!(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec))))
		return;
	ppt = pptSrc;

	for (i = nbox; --i >= 0; ppt++, pbox++) {
		ppt->x = pbox->x1 + dx;
		ppt->y = pbox->y1 + dy;
	}

	LeoDoBitblt ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
		     GXcopy, prgnDst, pptSrc, ~0L);
	DEALLOCATE_LOCAL(pptSrc);
	REGION_DESTROY(pWin->drawable.pScreen, prgnDst);
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
static void MaliDRI2CopyRegion(DrawablePtr   pDraw,
                               RegionPtr     pRegion,
                               DRI2BufferPtr pDstBuffer,
                               DRI2BufferPtr pSrcBuffer)
{
    GCPtr pGC;
    RegionPtr copyRegion;
    ScreenPtr pScreen = pDraw->pScreen;
    MaliDRI2BufferPrivatePtr privates;
    PixmapPtr pScratchPixmap;
    privates = (MaliDRI2BufferPrivatePtr)pSrcBuffer->driverPrivate;

    if (privates->depth != pDraw->depth) {
        ErrorF("MaliDRI2CopyRegion: privates->depth != pDraw->depth (%d vs. %d)\n",
               privates->depth, pDraw->depth);
        return;
    }

    //ErrorF("MaliDRI2CopyRegion dstbuf=%p srcbuf=%p, depth=%d\n", pDstBuffer, pSrcBuffer, privates->depth);

    ump_cache_operations_control(UMP_CACHE_OP_START);
    ump_switch_hw_usage_secure_id(pSrcBuffer->name, UMP_USED_BY_CPU);
    ump_cache_operations_control(UMP_CACHE_OP_FINISH);

    pGC = GetScratchGC(pDraw->depth, pScreen);
    pScratchPixmap = GetScratchPixmapHeader(pScreen, privates->width, privates->height,
                                            privates->depth, pSrcBuffer->cpp * 8,
                                            pSrcBuffer->pitch, privates->addr);
    copyRegion = REGION_CREATE(pScreen, NULL, 0);
    REGION_COPY(pScreen, copyRegion, pRegion);
    (*pGC->funcs->ChangeClip)(pGC, CT_REGION, copyRegion, 0);
    ValidateGC(pDraw, pGC);
    (*pGC->ops->CopyArea)(pScratchPixmap, pDraw, pGC, 0, 0,
                          pDraw->width, pDraw->height, 0, 0);
    FreeScratchPixmapHeader(pScratchPixmap);
    FreeScratchGC(pGC);

    ump_cache_operations_control(UMP_CACHE_OP_START);
    ump_switch_hw_usage_secure_id(pSrcBuffer->name, UMP_USED_BY_MALI);
    ump_cache_operations_control(UMP_CACHE_OP_FINISH);
}
Ejemplo n.º 12
0
Bool
omap_screen_resources_create(struct omap_screen_info *omaps)
{
    PixmapPtr pixmap;

    ENTER();

    /* Set up our damage listener to update the window by hand. */
    omaps->timer_active = 0;
    omaps->empty_updates = 0;
    omaps->damage = DamageCreate(damage_report_hook, damage_destroy_hook,
                                 DamageReportNonEmpty, TRUE,
                                 omaps->screen->pScreen, omaps);
    if (!omaps->damage)
        FatalError("omapCreateDrawResources: couldn't create damage\n");
    pixmap = omaps->screen->pScreen->GetScreenPixmap(omaps->screen->pScreen);
    if (!pixmap)
        FatalError("omapCreateDrawResources: couldn't get screen pixmap\n");
    omaps->pixmap = pixmap;
    reset_damage(omaps);
    DamageRegister(&pixmap->drawable, omaps->damage);

    omaps->pixel_doubled = 0;
    omaps->individual_updates = 0;
#ifdef XSP
    XSPSetEventCallback(omaps->screen->pScreen->myNum, xsp_event, omaps);
#endif

    omaps->tmp_region = REGION_CREATE(omaps->screen->pScreen, NullBox, 0);
    if (!omaps->tmp_region)
        FatalError("omapCreateDrawResources: couldn't create temp region\n");

    LEAVE();

    return TRUE;
}
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);
}
Ejemplo n.º 14
0
void
nouveau_dri2_copy_region2(ScreenPtr pScreen, DrawablePtr pDraw, RegionPtr pRegion,
			 DRI2BufferPtr pDstBuffer, DRI2BufferPtr pSrcBuffer)
{
	struct nouveau_dri2_buffer *src = nouveau_dri2_buffer(pSrcBuffer);
	struct nouveau_dri2_buffer *dst = nouveau_dri2_buffer(pDstBuffer);
	NVPtr pNv = NVPTR(xf86ScreenToScrn(pScreen));
	RegionPtr pCopyClip;
	GCPtr pGC;
	DrawablePtr src_draw, dst_draw;
	Bool translate = FALSE;
	int off_x = 0, off_y = 0;

	src_draw = &src->ppix->drawable;
	dst_draw = &dst->ppix->drawable;
#if 0
	ErrorF("attachments src %d, dst %d, drawable %p %p pDraw %p\n",
	       src->base.attachment, dst->base.attachment,
	       src_draw, dst_draw, pDraw);
#endif
	if (src->base.attachment == DRI2BufferFrontLeft)
		src_draw = pDraw;
	if (dst->base.attachment == DRI2BufferFrontLeft) {
#ifdef NOUVEAU_PIXMAP_SHARING
		if (pDraw->pScreen != pScreen) {
			dst_draw = DRI2UpdatePrime(pDraw, pDstBuffer);
			if (!dst_draw)
				return;
		} 
		else
#endif
			dst_draw = pDraw;
		if (dst_draw != pDraw)
			translate = TRUE;
	}

	if (translate && pDraw->type == DRAWABLE_WINDOW) {
#ifdef COMPOSITE
		PixmapPtr pPix = get_drawable_pixmap(pDraw);
		off_x = -pPix->screen_x;
		off_y = -pPix->screen_y;
#endif
		off_x += pDraw->x;
		off_y += pDraw->y;
	}

	pGC = GetScratchGC(pDraw->depth, pScreen);
	pCopyClip = REGION_CREATE(pScreen, NULL, 0);
	REGION_COPY(pScreen, pCopyClip, pRegion);

	if (translate) {
		REGION_TRANSLATE(pScreen, pCopyClip, off_x, off_y);
	}
	pGC->funcs->ChangeClip(pGC, CT_REGION, pCopyClip, 0);
	ValidateGC(dst_draw, pGC);

	/* If this is a full buffer swap or frontbuffer flush, throttle on
	 * the previous one.
	 */
	if (dst->base.attachment == DRI2BufferFrontLeft &&
	    REGION_NUM_RECTS(pRegion) == 1) {
		BoxPtr extents = REGION_EXTENTS(pScreen, pRegion);
		if (extents->x1 == 0 && extents->y1 == 0 &&
		    extents->x2 == pDraw->width &&
		    extents->y2 == pDraw->height) {
			PixmapPtr fpix = get_drawable_pixmap(dst_draw);
			struct nouveau_bo *bo = nouveau_pixmap_bo(fpix);
			if (bo)
				nouveau_bo_wait(bo, NOUVEAU_BO_RD, pNv->client);
		}
	}

	pGC->ops->CopyArea(src_draw, dst_draw, pGC, 0, 0,
			   pDraw->width, pDraw->height, off_x, off_y);

	FreeScratchGC(pGC);
}
Ejemplo n.º 15
0
Archivo: PclLine.c Proyecto: aosm/X11
void
PclPolySegment(
     DrawablePtr pDrawable,
     GCPtr pGC,
     int nSegments,
     xSegment *pSegments)
{
    FILE *outFile, *dummy;
    char t[80];
    int xoffset, yoffset;
    int nbox, i;
    unsigned long valid;
    BoxPtr pbox;
    xRectangle *drawRects, *r;
    RegionPtr drawRegion, region;
    short fudge;
    XpContextPtr pCon;
    PclContextPrivPtr pConPriv;
    GC cacheGC;


    if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
      return;

    pCon = PclGetContextFromWindow( (WindowPtr) pDrawable );
    pConPriv = (PclContextPrivPtr)
			pCon->devPrivates[PclContextPrivateIndex].ptr;

    /*
     * Allocate the storage for the temporary regions.
     */
    region = REGION_CREATE( pGC->pScreen, NULL, 0 );
    drawRects = (xRectangle *)
      xalloc( nSegments * sizeof( xRectangle ) );

    /*
     * Calculate the fudge factor, based on the line width
     */
    fudge = pGC->lineWidth * 3 + 1;

    /*
     * Turn off line joining.
     */
    SEND_PCL( outFile, "\033%0BLA2,6;\033%0A" );

    /*
     * Generate the PCL code to draw the segments, by defining them as
     * a macro which uses the HP-GL/2 line drawing function.
     *
     * XXX I wonder if this should be implemented using the Encoded
     * XXX Polyline function.  Since I'm only sending it once, it's not
     * XXX necessarily too important.
     */

    MACRO_START( outFile, pConPriv );
    SAVE_PCL( outFile, pConPriv, "\033%0B" );

    xoffset = pDrawable->x;
    yoffset = pDrawable->y;

    for( i = 0, r = drawRects; i < nSegments; i++, r++ )
      {
	  r->x = MIN( pSegments[i].x1, pSegments[i].x2 ) + xoffset;
	  r->y = MIN( pSegments[i].y1, pSegments[i].y2 ) + yoffset;
	  r->width = abs( pSegments[i].x1 - pSegments[i].x2 );
	  r->height = abs( pSegments[i].y1 - pSegments[i].y2 );

	  sprintf( t, "PU%d,%d;PD%d,%d;", pSegments[i].x1 + xoffset,
		  pSegments[i].y1 + yoffset, pSegments[i].x2 +
		  xoffset, pSegments[i].y2 + yoffset );
	  SAVE_PCL( outFile, pConPriv, t );

	  r->x -= fudge;
	  r->y -= fudge;
	  r->width += 2 * fudge;
	  r->height += 2 * fudge;
      }
    SAVE_PCL( outFile, pConPriv, "\033%0A" );
    MACRO_END ( outFile );

    /*
     * Convert the collection of rectangles into a proper region, then
     * intersect it with the clip region.
     */
    drawRegion = RECTS_TO_REGION( pGC->pScreen, nSegments,
				  drawRects, CT_UNSORTED );
    REGION_INTERSECT( pGC->pScreen, region, drawRegion, pGC->pCompositeClip );

    /*
     * For each rectangle in the clip region, set the HP-GL/2 "input
     * window" and render the entire set of segments to it.
     */
    pbox = REGION_RECTS( region );
    nbox = REGION_NUM_RECTS( region );

    PclSendData(outFile, pConPriv, pbox, nbox, 1.0);

    /*
     * Now we need to reset the line join mode to whatever it was at before.
     * The easiest way is to force the cached GC's joinstyle to be different
     * from the current GC's joinstyle, then re-update the GC.  This way, we
     * don't have to duplicate code unnecessarily.
     */
    PclGetDrawablePrivateStuff( pDrawable, &cacheGC, &valid, &dummy );
    cacheGC.joinStyle = !cacheGC.joinStyle;
    PclSetDrawablePrivateGC( pDrawable, cacheGC );
    PclUpdateDrawableGC( pGC, pDrawable, &outFile );

    /*
     * Clean up
     */
    REGION_DESTROY( pGC->pScreen, drawRegion );
    REGION_DESTROY( pGC->pScreen, region );
    xfree( drawRects );
}
Ejemplo n.º 16
0
void
miSlideAndSizeWindow(WindowPtr pWin,
                     int x, int y,
                     unsigned int w, unsigned int h,
                     WindowPtr pSib)
{
    WindowPtr pParent;
    Bool WasViewable = (Bool)(pWin->viewable);
    unsigned short width = pWin->drawable.width,
		   height = pWin->drawable.height;
    short oldx = pWin->drawable.x,
	  oldy = pWin->drawable.y;
    int bw = wBorderWidth (pWin);
    short dw, dh;
    DDXPointRec oldpt;
    RegionPtr oldRegion = NULL;
    Bool anyMarked = FALSE;
    ScreenPtr pScreen;
    WindowPtr pFirstChange;
    WindowPtr pChild;
    RegionPtr	gravitate[StaticGravity + 1];
    unsigned g;
    int		nx, ny;		/* destination x,y */
    int		newx, newy;	/* new inner window position */
    RegionPtr	pRegion = NULL;
    RegionPtr	destClip;	/* portions of destination already written */
    RegionPtr	oldWinClip = NULL;	/* old clip list for window */
    RegionPtr	borderVisible = NullRegion; /* visible area of the border */
    Bool	shrunk = FALSE; /* shrunk in an inner dimension */
    Bool	moved = FALSE;	/* window position changed */
    WindowPtr  pLayerWin;

    /* if this is a root window, can't be resized */
    if (!(pParent = pWin->parent))
	return ;

    pScreen = pWin->drawable.pScreen;
    newx = pParent->drawable.x + x + bw;
    newy = pParent->drawable.y + y + bw;
    if (WasViewable)
    {
	anyMarked = FALSE;
	/*
	 * save the visible region of the window
	 */
	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
	REGION_COPY(pScreen, oldRegion, &pWin->winSize);

	/*
	 * categorize child windows into regions to be moved
	 */
	for (g = 0; g <= StaticGravity; g++)
	    gravitate[g] = (RegionPtr) NULL;
	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
	{
	    g = pChild->winGravity;
	    if (g != UnmapGravity)
	    {
		if (!gravitate[g])
		    gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
		REGION_UNION(pScreen, gravitate[g],
				   gravitate[g], &pChild->borderClip);
	    }
	    else
	    {
		UnmapWindow(pChild, TRUE);
		anyMarked = TRUE;
	    }
	}
	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 
						       &pLayerWin);

	oldWinClip = NULL;
	if (pWin->bitGravity != ForgetGravity)
	{
	    oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
	    REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
	}
	/*
	 * if the window is changing size, borderExposed
	 * can't be computed correctly without some help.
	 */
	if (pWin->drawable.height > h || pWin->drawable.width > w)
	    shrunk = TRUE;

	if (newx != oldx || newy != oldy)
	    moved = TRUE;

	if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
	    HasBorder (pWin))
	{
	    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
	    /* for tiled borders, we punt and draw the whole thing */
	    if (pWin->borderIsPixel || !moved)
	    {
		if (shrunk || moved)
		    REGION_SUBTRACT(pScreen, borderVisible,
					  &pWin->borderClip,
					  &pWin->winSize);
		else
		    REGION_COPY(pScreen, borderVisible,
					    &pWin->borderClip);
	    }
	}
    }
    pWin->origin.x = x + bw;
    pWin->origin.y = y + bw;
    pWin->drawable.height = h;
    pWin->drawable.width = w;

    x = pWin->drawable.x = newx;
    y = pWin->drawable.y = newy;

    SetWinSize (pWin);
    SetBorderSize (pWin);

    dw = (int)w - (int)width;
    dh = (int)h - (int)height;
    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);

    /* let the hardware adjust background and border pixmaps, if any */
    (*pScreen->PositionWindow)(pWin, x, y);

    pFirstChange = MoveWindowInStack(pWin, pSib);

    if (WasViewable)
    {
	pRegion = REGION_CREATE(pScreen, NullBox, 1);

	if (pLayerWin == pWin)
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
						NULL);
	else
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
						NULL);

	if (pWin->valdata)
	{
	    pWin->valdata->before.resized = TRUE;
	    pWin->valdata->before.borderVisible = borderVisible;
	}


	if (anyMarked)
	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
	/*
	 * the entire window is trashed unless bitGravity
	 * recovers portions of it
	 */
	REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
    }

    GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);

    if (WasViewable)
    {
	/* avoid the border */
	if (HasBorder (pWin))
	{
	    int	offx, offy, dx, dy;

	    /* kruft to avoid double translates for each gravity */
	    offx = 0;
	    offy = 0;
	    for (g = 0; g <= StaticGravity; g++)
	    {
		if (!gravitate[g])
		    continue;

		/* align winSize to gravitate[g].
		 * winSize is in new coordinates,
		 * gravitate[g] is still in old coordinates */
		GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
		
		dx = (oldx - nx) - offx;
		dy = (oldy - ny) - offy;
		if (dx || dy)
		{
		    REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
		    offx += dx;
		    offy += dy;
		}
		REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
				 &pWin->winSize);
	    }
	    /* get winSize back where it belongs */
	    if (offx || offy)
		REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
	}
	/*
	 * add screen bits to the appropriate bucket
	 */

	if (oldWinClip)
	{
	    /*
	     * clip to new clipList
	     */
	    REGION_COPY(pScreen, pRegion, oldWinClip);
	    REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
	    REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
	    /*
	     * don't step on any gravity bits which will be copied after this
	     * region.	Note -- this assumes that the regions will be copied
	     * in gravity order.
	     */
	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
	    {
		if (gravitate[g])
		    REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
					gravitate[g]);
	    }
	    REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
	    g = pWin->bitGravity;
	    if (!gravitate[g])
		gravitate[g] = oldWinClip;
	    else
	    {
		REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
		REGION_DESTROY(pScreen, oldWinClip);
	    }
	}

	/*
	 * move the bits on the screen
	 */

	destClip = NULL;

	for (g = 0; g <= StaticGravity; g++)
	{
	    if (!gravitate[g])
		continue;

	    GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);

	    oldpt.x = oldx + (x - nx);
	    oldpt.y = oldy + (y - ny);

	    /* Note that gravitate[g] is *translated* by CopyWindow */

	    /* only copy the remaining useful bits */

	    REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);

	    /* clip to not overwrite already copied areas */

	    if (destClip) {
		REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
		REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
		REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
	    }

	    /* and move those bits */

	    if (oldpt.x != x || oldpt.y != y
#ifdef COMPOSITE
		|| pWin->redirectDraw
#endif
		)
	    {
		(*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
	    }

	    /* remove any overwritten bits from the remaining useful bits */

	    REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);

	    /*
	     * recompute exposed regions of child windows
	     */
	
	    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
	    {
		if (pChild->winGravity != g)
		    continue;
		REGION_INTERSECT(pScreen, pRegion,
				       &pChild->borderClip, gravitate[g]);
		TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
	    }

	    /*
	     * remove the successfully copied regions of the
	     * window from its exposed region
	     */

	    if (g == pWin->bitGravity)
		REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
				     &pWin->valdata->after.exposed, gravitate[g]);
	    if (!destClip)
		destClip = gravitate[g];
	    else
	    {
		REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
		REGION_DESTROY(pScreen, gravitate[g]);
	    }
	}

	REGION_DESTROY(pScreen, oldRegion);
	REGION_DESTROY(pScreen, pRegion);
	if (destClip)
	    REGION_DESTROY(pScreen, destClip);
	if (anyMarked)
	    (*pScreen->HandleExposures)(pLayerWin->parent);
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
					  VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
}
Ejemplo n.º 17
0
static void
xf86SetRootClip (ScreenPtr pScreen, Bool enable)
{
#if XORG < 19
    WindowPtr	pWin = WindowTable[pScreen->myNum];
#else
    WindowPtr	pWin = pScreen->root;
#endif
    WindowPtr	pChild;
    Bool	WasViewable = (Bool)(pWin->viewable);
    Bool	anyMarked = FALSE;
#if XORG < 110
    RegionPtr	pOldClip = NULL, bsExposed;
#ifdef DO_SAVE_UNDERS
    Bool	dosave = FALSE;
#endif
#endif
    WindowPtr   pLayerWin;
    BoxRec	box;

    if (WasViewable)
    {
	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
	{
	    (void) (*pScreen->MarkOverlappedWindows)(pChild,
						     pChild,
						     &pLayerWin);
	}
	(*pScreen->MarkWindow) (pWin);
	anyMarked = TRUE;
	if (pWin->valdata)
	{
	    if (HasBorder (pWin))
	    {
		RegionPtr	borderVisible;

		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
		REGION_SUBTRACT(pScreen, borderVisible,
				&pWin->borderClip, &pWin->winSize);
		pWin->valdata->before.borderVisible = borderVisible;
	    }
	    pWin->valdata->before.resized = TRUE;
	}
    }
    
    /*
     * Use REGION_BREAK to avoid optimizations in ValidateTree
     * that assume the root borderClip can't change well, normally
     * it doesn't...)
     */
    if (enable)
    {
	box.x1 = 0;
	box.y1 = 0;
	box.x2 = pScreen->width;
	box.y2 = pScreen->height;
	REGION_INIT (pScreen, &pWin->winSize, &box, 1);
	REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
	if (WasViewable)
	    REGION_RESET(pScreen, &pWin->borderClip, &box);
	pWin->drawable.width = pScreen->width;
	pWin->drawable.height = pScreen->height;
        REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
    }
    else
    {
	REGION_EMPTY(pScreen, &pWin->borderClip);
	REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
    }
    
    ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
    
    if (WasViewable)
    {
#if XORG < 110
	if (pWin->backStorage)
	{
	    pOldClip = REGION_CREATE(pScreen, NullBox, 1);
	    REGION_COPY(pScreen, pOldClip, &pWin->clipList);
	}
#endif

	if (pWin->firstChild)
	{
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
							   pWin->firstChild,
							   (WindowPtr *)NULL);
	}
	else
	{
	    (*pScreen->MarkWindow) (pWin);
	    anyMarked = TRUE;
	}

#if XORG < 110 && defined(DO_SAVE_UNDERS)
	if (DO_SAVE_UNDERS(pWin))
	{
	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
	}
#endif /* DO_SAVE_UNDERS */

	if (anyMarked)
	    (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
    }

#if XORG < 110
    if (pWin->backStorage &&
	((pWin->backingStore == Always) || WasViewable))
    {
	if (!WasViewable)
	    pOldClip = &pWin->clipList; /* a convenient empty region */
	bsExposed = (*pScreen->TranslateBackingStore)
			     (pWin, 0, 0, pOldClip,
			      pWin->drawable.x, pWin->drawable.y);
	if (WasViewable)
	    REGION_DESTROY(pScreen, pOldClip);
	if (bsExposed)
	{
	    RegionPtr	valExposed = NullRegion;
    
	    if (pWin->valdata)
		valExposed = &pWin->valdata->after.exposed;
	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
	    if (valExposed)
		REGION_EMPTY(pScreen, valExposed);
	    REGION_DESTROY(pScreen, bsExposed);
	}
    }
#endif
    if (WasViewable)
    {
	if (anyMarked)
	    (*pScreen->HandleExposures)(pWin);

#if XORG < 110 && defined(DO_SAVE_UNDERS)
	if (dosave)
	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
#endif /* DO_SAVE_UNDERS */
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
    FlushAllOutput ();
}
Ejemplo n.º 18
0
void
KdSetRootClip (ScreenPtr pScreen, BOOL enable)
{
#ifndef FB_OLD_SCREEN
    WindowPtr	pWin = WindowTable[pScreen->myNum];
    WindowPtr	pChild;
    Bool	WasViewable;
    Bool	anyMarked = FALSE;
    RegionPtr	pOldClip = 0, bsExposed;
#ifdef DO_SAVE_UNDERS
    Bool	dosave = FALSE;
#endif
    WindowPtr   pLayerWin;
    BoxRec	box;

    if (!pWin)
	return;
    WasViewable = (Bool)(pWin->viewable);
    if (WasViewable)
    {
	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
	{
	    (void) (*pScreen->MarkOverlappedWindows)(pChild,
						     pChild,
						     &pLayerWin);
	}
	(*pScreen->MarkWindow) (pWin);
	anyMarked = TRUE;
	if (pWin->valdata)
	{
	    if (HasBorder (pWin))
	    {
		RegionPtr	borderVisible;

		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
		REGION_SUBTRACT(pScreen, borderVisible,
				&pWin->borderClip, &pWin->winSize);
		pWin->valdata->before.borderVisible = borderVisible;
	    }
	    pWin->valdata->before.resized = TRUE;
	}
    }

    if (enable)
    {
	box.x1 = 0;
	box.y1 = 0;
	box.x2 = pScreen->width;
	box.y2 = pScreen->height;
	pWin->drawable.width = pScreen->width;
	pWin->drawable.height = pScreen->height;
	REGION_INIT (pScreen, &pWin->winSize, &box, 1);
	REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
	REGION_RESET(pScreen, &pWin->borderClip, &box);
	REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
    }
    else
    {
	REGION_EMPTY(pScreen, &pWin->borderClip);
	REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
    }
    
    ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
    
    if (WasViewable)
    {
	if (pWin->backStorage)
	{
	    pOldClip = REGION_CREATE(pScreen, NullBox, 1);
	    REGION_COPY(pScreen, pOldClip, &pWin->clipList);
	}

	if (pWin->firstChild)
	{
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
							   pWin->firstChild,
							   (WindowPtr *)NULL);
	}
	else
	{
	    (*pScreen->MarkWindow) (pWin);
	    anyMarked = TRUE;
	}

#ifdef DO_SAVE_UNDERS
	if (DO_SAVE_UNDERS(pWin))
	{
	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
	}
#endif /* DO_SAVE_UNDERS */

	if (anyMarked)
	    (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
    }

    if (pWin->backStorage &&
	((pWin->backingStore == Always) || WasViewable))
    {
	if (!WasViewable)
	    pOldClip = &pWin->clipList; /* a convenient empty region */
	bsExposed = (*pScreen->TranslateBackingStore)
			     (pWin, 0, 0, pOldClip,
			      pWin->drawable.x, pWin->drawable.y);
	if (WasViewable)
	    REGION_DESTROY(pScreen, pOldClip);
	if (bsExposed)
	{
	    RegionPtr	valExposed = NullRegion;
    
	    if (pWin->valdata)
		valExposed = &pWin->valdata->after.exposed;
	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
	    if (valExposed)
		REGION_EMPTY(pScreen, valExposed);
	    REGION_DESTROY(pScreen, bsExposed);
	}
    }
    if (WasViewable)
    {
	if (anyMarked)
	    (*pScreen->HandleExposures)(pWin);
#ifdef DO_SAVE_UNDERS
	if (dosave)
	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
#endif /* DO_SAVE_UNDERS */
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
#endif	/* !FB_OLD_SCREEN */
}
Ejemplo n.º 19
0
void
miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind)
{
    WindowPtr pParent;
    Bool WasViewable = (Bool)(pWin->viewable);
    short bw;
    RegionPtr oldRegion = NULL;
    DDXPointRec oldpt;
    Bool anyMarked = FALSE;
    ScreenPtr pScreen;
    WindowPtr windowToValidate;
    WindowPtr pLayerWin;

    /* if this is a root window, can't be moved */
    if (!(pParent = pWin->parent))
       return ;
    pScreen = pWin->drawable.pScreen;
    bw = wBorderWidth (pWin);

    oldpt.x = pWin->drawable.x;
    oldpt.y = pWin->drawable.y;
    if (WasViewable)
    {
	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
	REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
    }
    pWin->origin.x = x + (int)bw;
    pWin->origin.y = y + (int)bw;
    x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
    y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;

    SetWinSize (pWin);
    SetBorderSize (pWin);

    (*pScreen->PositionWindow)(pWin, x, y);

    windowToValidate = MoveWindowInStack(pWin, pNextSib);

    ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);

    if (WasViewable)
    {
	if (pLayerWin == pWin)
	    anyMarked |= (*pScreen->MarkOverlappedWindows)
				(pWin, windowToValidate, NULL);
	else
	    anyMarked |= (*pScreen->MarkOverlappedWindows)
				(pWin, pLayerWin, NULL);


	if (anyMarked)
	{
	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
	    (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
	    REGION_DESTROY(pScreen, oldRegion);
	    /* XXX need to retile border if ParentRelative origin */
	    (*pScreen->HandleExposures)(pLayerWin->parent);
	}
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
    }
    if (pWin->realized)
	WindowsRestructured ();
}
Ejemplo n.º 20
0
void
miValidatePicture (PicturePtr pPicture,
		   Mask       mask)
{
    DrawablePtr	    pDrawable = pPicture->pDrawable;

    if ((mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)) ||
	(pDrawable->serialNumber != (pPicture->serialNumber & DRAWABLE_SERIAL_BITS)))
    {
	if (pDrawable->type == DRAWABLE_WINDOW)
	{
	    WindowPtr       pWin = (WindowPtr) pDrawable;
	    RegionPtr       pregWin;
	    Bool            freeTmpClip, freeCompClip;

	    if (pPicture->subWindowMode == IncludeInferiors)
	    {
		pregWin = NotClippedByChildren(pWin);
		freeTmpClip = TRUE;
	    }
	    else
	    {
		pregWin = &pWin->clipList;
		freeTmpClip = FALSE;
	    }
	    freeCompClip = pPicture->freeCompClip;

	    /*
	     * if there is no client clip, we can get by with just keeping the
	     * pointer we got, and remembering whether or not should destroy
	     * (or maybe re-use) it later.  this way, we avoid unnecessary
	     * copying of regions.  (this wins especially if many clients clip
	     * by children and have no client clip.)
	     */
	    if (pPicture->clientClipType == CT_NONE)
	    {
		if (freeCompClip)
		    REGION_DESTROY(pScreen, pPicture->pCompositeClip);
		pPicture->pCompositeClip = pregWin;
		pPicture->freeCompClip = freeTmpClip;
	    }
	    else
	    {
		/*
		 * we need one 'real' region to put into the composite clip. if
		 * pregWin the current composite clip are real, we can get rid of
		 * one. if pregWin is real and the current composite clip isn't,
		 * use pregWin for the composite clip. if the current composite
		 * clip is real and pregWin isn't, use the current composite
		 * clip. if neither is real, create a new region.
		 */

		REGION_TRANSLATE(pScreen, pPicture->clientClip,
				 pDrawable->x + pPicture->clipOrigin.x,
				 pDrawable->y + pPicture->clipOrigin.y);

		if (freeCompClip)
		{
		    REGION_INTERSECT(pPicture->pScreen, pPicture->pCompositeClip,
				     pregWin, pPicture->clientClip);
		    if (freeTmpClip)
			REGION_DESTROY(pScreen, pregWin);
		}
		else if (freeTmpClip)
		{
		    REGION_INTERSECT(pScreen, pregWin, pregWin, pPicture->clientClip);
		    pPicture->pCompositeClip = pregWin;
		}
		else
		{
		    pPicture->pCompositeClip = REGION_CREATE(pScreen, NullBox, 0);
		    REGION_INTERSECT(pScreen, pPicture->pCompositeClip,
				     pregWin, pPicture->clientClip);
		}
		pPicture->freeCompClip = TRUE;
		REGION_TRANSLATE(pScreen, pPicture->clientClip,
				 -(pDrawable->x + pPicture->clipOrigin.x),
				 -(pDrawable->y + pPicture->clipOrigin.y));
	    }
	}	/* end of composite clip for a window */
	else
	{
	    BoxRec          pixbounds;

	    /* XXX should we translate by drawable.x/y here ? */
	    /* If you want pixmaps in offscreen memory, yes */
	    pixbounds.x1 = pDrawable->x;
	    pixbounds.y1 = pDrawable->y;
	    pixbounds.x2 = pDrawable->x + pDrawable->width;
	    pixbounds.y2 = pDrawable->y + pDrawable->height;

	    if (pPicture->freeCompClip)
	    {
		REGION_RESET(pScreen, pPicture->pCompositeClip, &pixbounds);
	    }
	    else
	    {
		pPicture->freeCompClip = TRUE;
		pPicture->pCompositeClip = REGION_CREATE(pScreen, &pixbounds, 1);
	    }

	    if (pPicture->clientClipType == CT_REGION)
	    {
		if(pDrawable->x || pDrawable->y) {
		    REGION_TRANSLATE(pScreen, pPicture->clientClip,
				     pDrawable->x + pPicture->clipOrigin.x, 
				     pDrawable->y + pPicture->clipOrigin.y);
		    REGION_INTERSECT(pScreen, pPicture->pCompositeClip,
				     pPicture->pCompositeClip, pPicture->clientClip);
		    REGION_TRANSLATE(pScreen, pPicture->clientClip,
				     -(pDrawable->x + pPicture->clipOrigin.x), 
				     -(pDrawable->y + pPicture->clipOrigin.y));
		} else {
		    REGION_TRANSLATE(pScreen, pPicture->pCompositeClip,
				     -pPicture->clipOrigin.x, -pPicture->clipOrigin.y);
		    REGION_INTERSECT(pScreen, pPicture->pCompositeClip,
				     pPicture->pCompositeClip, pPicture->clientClip);
		    REGION_TRANSLATE(pScreen, pPicture->pCompositeClip,
				     pPicture->clipOrigin.x, pPicture->clipOrigin.y);
		}
	    }
	}	/* end of composite clip for pixmap */
    }
}
Ejemplo n.º 21
0
void
I915DisplayVideoTextured(ScrnInfoPtr scrn,
			 intel_adaptor_private *adaptor_priv, int id,
			 RegionPtr dstRegion,
			 short width, short height, int video_pitch,
			 int video_pitch2,
			 short src_w, short src_h, short drw_w, short drw_h,
			 PixmapPtr pixmap)
{
	intel_screen_private *intel = intel_get_screen_private(scrn);
	uint32_t format, ms3, s5, tiling;
	BoxPtr pbox = REGION_RECTS(dstRegion);
	int nbox_total = REGION_NUM_RECTS(dstRegion);
	int nbox_this_time;
	int dxo, dyo, pix_xoff, pix_yoff;
	PixmapPtr target;

#if 0
	ErrorF("I915DisplayVideo: %dx%d (pitch %d)\n", width, height,
	       video_pitch);
#endif

	dxo = dstRegion->extents.x1;
	dyo = dstRegion->extents.y1;

	if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048 ||
	    !intel_uxa_check_pitch_3d(pixmap)) {
		ScreenPtr screen = pixmap->drawable.pScreen;

		target = screen->CreatePixmap(screen,
					      dstRegion->extents.x2 - dxo,
					      dstRegion->extents.y2 - dyo,
					      pixmap->drawable.depth,
					      CREATE_PIXMAP_USAGE_SCRATCH);
		if (target == NULL)
			return;

		if (intel_uxa_get_pixmap_bo(target) == NULL) {
			screen->DestroyPixmap(target);
			return;
		}

		pix_xoff = -dxo;
		pix_yoff = -dyo;
	} else {
		target = pixmap;

		/* Set up the offset for translating from the given region
		 * (in screen coordinates) to the backing pixmap.
		 */
#ifdef COMPOSITE
		pix_xoff = -target->screen_x + target->drawable.x;
		pix_yoff = -target->screen_y + target->drawable.y;
#else
		pix_xoff = 0;
		pix_yoff = 0;
#endif
	}

#define BYTES_FOR_BOXES(n)	((200 + (n) * 20) * 4)
#define BOXES_IN_BYTES(s)	((((s)/4) - 200) / 20)
#define BATCH_BYTES(p)		((p)->batch_bo->size - 16)

	while (nbox_total) {
		nbox_this_time = nbox_total;
		if (BYTES_FOR_BOXES(nbox_this_time) > BATCH_BYTES(intel))
			nbox_this_time = BOXES_IN_BYTES(BATCH_BYTES(intel));
		nbox_total -= nbox_this_time;

		intel_batch_start_atomic(scrn, 200 + 20 * nbox_this_time);

		IntelEmitInvarientState(scrn);
		intel->last_3d = LAST_3D_VIDEO;

		/* draw rect -- just clipping */
		OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
		OUT_BATCH(DRAW_DITHER_OFS_X(pixmap->drawable.x & 3) |
			  DRAW_DITHER_OFS_Y(pixmap->drawable.y & 3));
		OUT_BATCH(0x00000000);	/* ymin, xmin */
		/* ymax, xmax */
		OUT_BATCH((target->drawable.width - 1) |
			  (target->drawable.height - 1) << 16);
		OUT_BATCH(0x00000000);	/* yorigin, xorigin */

		OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
			  I1_LOAD_S(5) | I1_LOAD_S(6) | 2);
		OUT_BATCH(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
			  S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
			  S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) |
			  S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) |
			  S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) |
			  S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) |
			  S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) |
			  S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT));
		s5 = 0x0;
		if (intel->cpp == 2)
			s5 |= S5_COLOR_DITHER_ENABLE;
		OUT_BATCH(s5);	/* S5 - enable bits */
		OUT_BATCH((2 << S6_DEPTH_TEST_FUNC_SHIFT) |
			  (2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
			  (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) |
			  S6_COLOR_WRITE_ENABLE | (2 << S6_TRISTRIP_PV_SHIFT));

		OUT_BATCH(_3DSTATE_CONST_BLEND_COLOR_CMD);
		OUT_BATCH(0x00000000);

		OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
		if (intel->cpp == 2)
			format = COLR_BUF_RGB565;
		else
			format =
			    COLR_BUF_ARGB8888 | DEPTH_FRMT_24_FIXED_8_OTHER;

		OUT_BATCH(LOD_PRECLAMP_OGL |
			  DSTORG_HORT_BIAS(0x8) |
			  DSTORG_VERT_BIAS(0x8) | format);

		/* front buffer, pitch, offset */
		if (intel_uxa_pixmap_tiled(target)) {
			tiling = BUF_3D_TILED_SURFACE;
			if (intel_uxa_get_pixmap_private(target)->tiling == I915_TILING_Y)
				tiling |= BUF_3D_TILE_WALK_Y;
		} else
			tiling = 0;
		OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
		OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling |
			  BUF_3D_PITCH(intel_pixmap_pitch(target)));
		OUT_RELOC_PIXMAP(target, I915_GEM_DOMAIN_RENDER,
				 I915_GEM_DOMAIN_RENDER, 0);

		if (!is_planar_fourcc(id)) {
			FS_LOCALS();

			OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | 4);
			OUT_BATCH(0x0000001);	/* constant 0 */
			/* constant 0: brightness/contrast */
			OUT_BATCH_F(adaptor_priv->brightness / 128.0);
			OUT_BATCH_F(adaptor_priv->contrast / 255.0);
			OUT_BATCH_F(0.0);
			OUT_BATCH_F(0.0);

			OUT_BATCH(_3DSTATE_SAMPLER_STATE | 3);
			OUT_BATCH(0x00000001);
			OUT_BATCH(SS2_COLORSPACE_CONVERSION |
				  (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
				  (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
			OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCX_ADDR_MODE_SHIFT) |
				  (TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCY_ADDR_MODE_SHIFT) |
				  (0 << SS3_TEXTUREMAP_INDEX_SHIFT) |
				  SS3_NORMALIZED_COORDS);
			OUT_BATCH(0x00000000);

			OUT_BATCH(_3DSTATE_MAP_STATE | 3);
			OUT_BATCH(0x00000001);	/* texture map #1 */
			if (adaptor_priv->buf)
				OUT_RELOC(adaptor_priv->buf,
					  I915_GEM_DOMAIN_SAMPLER, 0,
					  adaptor_priv->YBufOffset);
			else
				OUT_BATCH(adaptor_priv->YBufOffset);

			ms3 = MAPSURF_422;
			switch (id) {
			case FOURCC_YUY2:
				ms3 |= MT_422_YCRCB_NORMAL;
				break;
			case FOURCC_UYVY:
				ms3 |= MT_422_YCRCB_SWAPY;
				break;
			}
			ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
			ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
			OUT_BATCH(ms3);
			OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);

			FS_BEGIN();
			i915_fs_dcl(FS_S0);
			i915_fs_dcl(FS_T0);
			i915_fs_texld(FS_OC, FS_S0, FS_T0);
			if (adaptor_priv->brightness != 0) {
				i915_fs_add(FS_OC,
					    i915_fs_operand_reg(FS_OC),
					    i915_fs_operand(FS_C0, X, X, X,
							    ZERO));
			}
			FS_END();
		} else {
			FS_LOCALS();

			/* For the planar formats, we set up three samplers --
			 * one for each plane, in a Y8 format.  Because I
			 * couldn't get the special PLANAR_TO_PACKED
			 * shader setup to work, I did the manual pixel shader:
			 *
			 * y' = y - .0625
			 * u' = u - .5
			 * v' = v - .5;
			 *
			 * r = 1.1643 * y' + 0.0     * u' + 1.5958  * v'
			 * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v'
			 * b = 1.1643 * y' + 2.017   * u' + 0.0     * v'
			 *
			 * register assignment:
			 * r0 = (y',u',v',0)
			 * r1 = (y,y,y,y)
			 * r2 = (u,u,u,u)
			 * r3 = (v,v,v,v)
			 * OC = (r,g,b,1)
			 */
			OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | (22 - 2));
			OUT_BATCH(0x000001f);	/* constants 0-4 */
			/* constant 0: normalization offsets */
			OUT_BATCH_F(-0.0625);
			OUT_BATCH_F(-0.5);
			OUT_BATCH_F(-0.5);
			OUT_BATCH_F(0.0);
			/* constant 1: r coefficients */
			OUT_BATCH_F(1.1643);
			OUT_BATCH_F(0.0);
			OUT_BATCH_F(1.5958);
			OUT_BATCH_F(0.0);
			/* constant 2: g coefficients */
			OUT_BATCH_F(1.1643);
			OUT_BATCH_F(-0.39173);
			OUT_BATCH_F(-0.81290);
			OUT_BATCH_F(0.0);
			/* constant 3: b coefficients */
			OUT_BATCH_F(1.1643);
			OUT_BATCH_F(2.017);
			OUT_BATCH_F(0.0);
			OUT_BATCH_F(0.0);
			/* constant 4: brightness/contrast */
			OUT_BATCH_F(adaptor_priv->brightness / 128.0);
			OUT_BATCH_F(adaptor_priv->contrast / 255.0);
			OUT_BATCH_F(0.0);
			OUT_BATCH_F(0.0);

			OUT_BATCH(_3DSTATE_SAMPLER_STATE | 9);
			OUT_BATCH(0x00000007);
			/* sampler 0 */
			OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
				  (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
			OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCX_ADDR_MODE_SHIFT) |
				  (TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCY_ADDR_MODE_SHIFT) |
				  (0 << SS3_TEXTUREMAP_INDEX_SHIFT) |
				  SS3_NORMALIZED_COORDS);
			OUT_BATCH(0x00000000);
			/* sampler 1 */
			OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
				  (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
			OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCX_ADDR_MODE_SHIFT) |
				  (TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCY_ADDR_MODE_SHIFT) |
				  (1 << SS3_TEXTUREMAP_INDEX_SHIFT) |
				  SS3_NORMALIZED_COORDS);
			OUT_BATCH(0x00000000);
			/* sampler 2 */
			OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
				  (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT));
			OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCX_ADDR_MODE_SHIFT) |
				  (TEXCOORDMODE_CLAMP_EDGE <<
				   SS3_TCY_ADDR_MODE_SHIFT) |
				  (2 << SS3_TEXTUREMAP_INDEX_SHIFT) |
				  SS3_NORMALIZED_COORDS);
			OUT_BATCH(0x00000000);

			OUT_BATCH(_3DSTATE_MAP_STATE | 9);
			OUT_BATCH(0x00000007);

			if (adaptor_priv->buf)
				OUT_RELOC(adaptor_priv->buf,
					  I915_GEM_DOMAIN_SAMPLER, 0,
					  adaptor_priv->YBufOffset);
			else
				OUT_BATCH(adaptor_priv->YBufOffset);

			ms3 = MAPSURF_8BIT | MT_8BIT_I8;
			ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
			ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
			OUT_BATCH(ms3);
			/* check to see if Y has special pitch than normal
			 * double u/v pitch, e.g i915 XvMC hw requires at
			 * least 1K alignment, so Y pitch might
			 * be same as U/V's.*/
			if (video_pitch2)
				OUT_BATCH(((video_pitch2 / 4) -
					   1) << MS4_PITCH_SHIFT);
			else
				OUT_BATCH(((video_pitch * 2 / 4) -
					   1) << MS4_PITCH_SHIFT);

			if (adaptor_priv->buf)
				OUT_RELOC(adaptor_priv->buf,
					  I915_GEM_DOMAIN_SAMPLER, 0,
					  adaptor_priv->UBufOffset);
			else
				OUT_BATCH(adaptor_priv->UBufOffset);

			ms3 = MAPSURF_8BIT | MT_8BIT_I8;
			ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
			ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
			OUT_BATCH(ms3);
			OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);

			if (adaptor_priv->buf)
				OUT_RELOC(adaptor_priv->buf,
					  I915_GEM_DOMAIN_SAMPLER, 0,
					  adaptor_priv->VBufOffset);
			else
				OUT_BATCH(adaptor_priv->VBufOffset);

			ms3 = MAPSURF_8BIT | MT_8BIT_I8;
			ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
			ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
			OUT_BATCH(ms3);
			OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);

			FS_BEGIN();
			/* Declare samplers */
			i915_fs_dcl(FS_S0);	/* Y */
			i915_fs_dcl(FS_S1);	/* U */
			i915_fs_dcl(FS_S2);	/* V */
			i915_fs_dcl(FS_T0);	/* normalized coords */

			/* Load samplers to temporaries. */
			i915_fs_texld(FS_R1, FS_S0, FS_T0);
			i915_fs_texld(FS_R2, FS_S1, FS_T0);
			i915_fs_texld(FS_R3, FS_S2, FS_T0);

			/* Move the sampled YUV data in R[123] to the first
			 * 3 channels of R0.
			 */
			i915_fs_mov_masked(FS_R0, MASK_X,
					   i915_fs_operand_reg(FS_R1));
			i915_fs_mov_masked(FS_R0, MASK_Y,
					   i915_fs_operand_reg(FS_R2));
			i915_fs_mov_masked(FS_R0, MASK_Z,
					   i915_fs_operand_reg(FS_R3));

			/* Normalize the YUV data */
			i915_fs_add(FS_R0, i915_fs_operand_reg(FS_R0),
				    i915_fs_operand_reg(FS_C0));
			/* dot-product the YUV data in R0 by the vectors of
			 * coefficients for calculating R, G, and B, storing
			 * the results in the R, G, or B channels of the output
			 * color.  The OC results are implicitly clamped
			 * at the end of the program.
			 */
			i915_fs_dp3(FS_OC, MASK_X,
				    i915_fs_operand_reg(FS_R0),
				    i915_fs_operand_reg(FS_C1));
			i915_fs_dp3(FS_OC, MASK_Y,
				    i915_fs_operand_reg(FS_R0),
				    i915_fs_operand_reg(FS_C2));
			i915_fs_dp3(FS_OC, MASK_Z,
				    i915_fs_operand_reg(FS_R0),
				    i915_fs_operand_reg(FS_C3));
			/* Set alpha of the output to 1.0, by wiring W to 1
			 * and not actually using the source.
			 */
			i915_fs_mov_masked(FS_OC, MASK_W,
					   i915_fs_operand_one());

			if (adaptor_priv->brightness != 0) {
				i915_fs_add(FS_OC,
					    i915_fs_operand_reg(FS_OC),
					    i915_fs_operand(FS_C4, X, X, X,
							    ZERO));
			}
			FS_END();
		}

		OUT_BATCH(PRIM3D_RECTLIST | (12 * nbox_this_time - 1));
		while (nbox_this_time--) {
			int box_x1 = pbox->x1;
			int box_y1 = pbox->y1;
			int box_x2 = pbox->x2;
			int box_y2 = pbox->y2;
			float src_scale_x, src_scale_y;

			pbox++;

			src_scale_x = ((float)src_w / width) / drw_w;
			src_scale_y = ((float)src_h / height) / drw_h;

			/* vertex data - rect list consists of bottom right,
			 * bottom left, and top left vertices.
			 */

			/* bottom right */
			OUT_BATCH_F(box_x2 + pix_xoff);
			OUT_BATCH_F(box_y2 + pix_yoff);
			OUT_BATCH_F((box_x2 - dxo) * src_scale_x);
			OUT_BATCH_F((box_y2 - dyo) * src_scale_y);

			/* bottom left */
			OUT_BATCH_F(box_x1 + pix_xoff);
			OUT_BATCH_F(box_y2 + pix_yoff);
			OUT_BATCH_F((box_x1 - dxo) * src_scale_x);
			OUT_BATCH_F((box_y2 - dyo) * src_scale_y);

			/* top left */
			OUT_BATCH_F(box_x1 + pix_xoff);
			OUT_BATCH_F(box_y1 + pix_yoff);
			OUT_BATCH_F((box_x1 - dxo) * src_scale_x);
			OUT_BATCH_F((box_y1 - dyo) * src_scale_y);
		}

		intel_batch_end_atomic(scrn);
	}

	if (target != pixmap) {
		GCPtr gc;

		gc = GetScratchGC(pixmap->drawable.depth,
				  pixmap->drawable.pScreen);
		if (gc) {
			gc->subWindowMode = ClipByChildren;

			if (REGION_NUM_RECTS(dstRegion) > 1) {
				RegionPtr tmp;

				tmp = REGION_CREATE(pixmap->drawable.pScreen, NULL, 0);
				if (tmp) {
					REGION_COPY(pixmap->drawable.pScreen, tmp, dstRegion);
					gc->funcs->ChangeClip(gc, CT_REGION, tmp, 0);
				}
			}

			ValidateGC(&pixmap->drawable, gc);
			gc->ops->CopyArea(&target->drawable, &pixmap->drawable, gc,
					  0, 0,
					  target->drawable.width,
					  target->drawable.height,
					  -pix_xoff, -pix_yoff);
			FreeScratchGC(gc);
		}

		target->drawable.pScreen->DestroyPixmap(target);
	}

	intel_uxa_debug_flush(scrn);
}
Ejemplo n.º 22
0
Archivo: PclArc.c Proyecto: aosm/X11
static void
PclDoArc(
     DrawablePtr pDrawable,
     GCPtr pGC,
     int nArcs,
     xArc *pArcs,
     void (*DoIt)(FILE *, PclContextPrivPtr, double, double, xArc))
{
    char t[80];
    FILE *outFile;
    int nbox, i;
    BoxPtr pbox;
    BoxRec r;
    RegionPtr drawRegion, region, transClip;
    short fudge;
    int xoffset, yoffset;
    XpContextPtr pCon;
    PclContextPrivPtr pConPriv;
    xRectangle repro;
    
    if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
      return;
    
    fudge = 3 * pGC->lineWidth;

    pCon = PclGetContextFromWindow( (WindowPtr) pDrawable );
    pConPriv = (PclContextPrivPtr)
			pCon->devPrivates[PclContextPrivateIndex].ptr;
    XpGetReproductionArea( pCon, &repro );
    
    /* 
     * Generate the PCL code to draw the collection of arcs, by
     * defining it as a macro which uses the HP-GL/2 arc drawing
     * function.
     */

    xoffset = pDrawable->x;
    yoffset = pDrawable->y;
    
    for( i = 0; i < nArcs; i++ )
      {
	  xArc Arc = pArcs[i];
	  double b, X, Y, ratio;
	  double angle1;

	  MACRO_START( outFile, pConPriv );
	  SAVE_PCL( outFile, pConPriv, "\033%0B" );

	  /* Calculate the start of the arc */
	  if( ( Arc.angle1 / 64 ) % 360 == 90 )
	    {
		X = 0;
		Y = -Arc.height / 2.0;
	    }
	  else if( ( Arc.angle1 / 64 ) % 360 == 270 )
	    {
		X = 0;
		Y = Arc.height / 2.0;
	    }
	  else
	    {
		/* Convert the angle to radians */
		angle1 = ( Arc.angle1 / 64.0 ) * 3.141592654 / 180.0;
	  
		b = (Arc.height / 2.0);
		X = b * cos( angle1 );
		Y = -b * sin( angle1 );
	    }
	  
	  /* Change the coordinate system to scale the ellipse */
	  ratio = (double)Arc.height / (double)Arc.width;
	  
	  sprintf( t, "SC%.2f,%.2f,%d,%d;", 
		  (repro.x - Arc.width / 2 - xoffset - Arc.x) * ratio,
		  (repro.x - Arc.width / 2 - xoffset - Arc.x +
		   repro.width) * ratio,
		  repro.y - Arc.height / 2 - yoffset - Arc.y + repro.height,
		  repro.y - Arc.height / 2 - yoffset - Arc.y);
	  SAVE_PCL( outFile, pConPriv, t );

	  DoIt( outFile, pConPriv, X, Y, Arc );
	  
	  /* Build the bounding box */
	  r.x1 = -Arc.width / 2 - fudge;
	  r.y1 = -Arc.height / 2 - fudge;
	  r.x2 = Arc.width / 2 + fudge;
	  r.y2 = Arc.height / 2 + fudge;
	  drawRegion = REGION_CREATE( pGC->pScreen, &r, 0 );

	  SAVE_PCL( outFile, pConPriv, "\033%0A" );
	  MACRO_END( outFile );
    
	  /*
	   * Intersect the bounding box with the clip region.
	   */
	  region = REGION_CREATE( pGC->pScreen, NULL, 0 );
    	  transClip = REGION_CREATE( pGC->pScreen, NULL, 0 );
	  REGION_COPY( pGC->pScreen, transClip, pGC->pCompositeClip );
	  REGION_TRANSLATE( pGC->pScreen, transClip,
			    -(xoffset + Arc.x + Arc.width / 2),
			    -(yoffset + Arc.y + Arc.height / 2) );
	  REGION_INTERSECT( pGC->pScreen, region, drawRegion, transClip );

	  /*
	   * For each rectangle in the clip region, set the HP-GL/2 "input
	   * window" and render the collection of arcs to it.
	   */
	  pbox = REGION_RECTS( region );
	  nbox = REGION_NUM_RECTS( region );
    
	  PclSendData(outFile, pConPriv, pbox, nbox, ratio);

	  /*
	   * Restore the coordinate system
	   */
	  sprintf( t, "\033%%0BSC%d,%d,%d,%d;\033%%0A", repro.x, 
		  repro.x + repro.width, repro.y + repro.height, 
		  repro.y );
	  SEND_PCL( outFile, t );
	  
	  /*
	   * Clean up the temporary regions
	   */
	  REGION_DESTROY( pGC->pScreen, drawRegion );
	  REGION_DESTROY( pGC->pScreen, region );
	  REGION_DESTROY( pGC->pScreen, transClip );
      }
}
Ejemplo n.º 23
0
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 = xalloc(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 miRegionCopy() 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  = RECTS_TO_REGION(pScreen, nbox, rects, ordering);
	xfree(rects);

	if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask,
					   pGC->fillStyle, pGC->alu,
					   pGC->clientClipType)) {
	    dstregion = REGION_CREATE(pScreen, NullBox, 0);
	    REGION_COPY(pScreen, dstregion, srcregion);
	    REGION_TRANSLATE(pScreen, 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 (exaPixmapIsOffscreen(pDstPixmap)) {
	/* Normal blitting. */
	if (exaPixmapIsOffscreen(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. */
	} else if (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) {
	REGION_UNINIT(pScreen, dstregion);
	REGION_DESTROY(pScreen, dstregion);
    }
    if (srcregion) {
	REGION_UNINIT(pScreen, srcregion);
	REGION_DESTROY(pScreen, srcregion);
    }

    return ret;
}
Ejemplo n.º 24
0
static void
cwCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
    ScreenPtr pScreen = pWin->drawable.pScreen;

    SCREEN_PROLOGUE(pScreen, CopyWindow);

    if (!cwDrawableIsRedirWindow((DrawablePtr)pWin)) {
	(*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
    } else {
	GCPtr	    pGC;
	BoxPtr	    pExtents;
	int	    x_off, y_off;
	int	    dx, dy;
	PixmapPtr   pBackingPixmap;
	RegionPtr   pClip;
	int	    src_x, src_y, dst_x, dst_y, w, h;

	dx = ptOldOrg.x - pWin->drawable.x;
	dy = ptOldOrg.y - pWin->drawable.y;

	pExtents = REGION_EXTENTS(pScreen, prgnSrc);

	pBackingPixmap = (PixmapPtr) cwGetBackingDrawable((DrawablePtr)pWin,
							  &x_off, &y_off);

	src_x = pExtents->x1 - pBackingPixmap->screen_x;
	src_y = pExtents->y1 - pBackingPixmap->screen_y;
	w = pExtents->x2 - pExtents->x1;
	h = pExtents->y2 - pExtents->y1;
	dst_x = src_x - dx;
	dst_y = src_y - dy;
			       
	/* Translate region (as required by API) */
	REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
	
	pGC = GetScratchGC(pBackingPixmap->drawable.depth, pScreen);
	/*
	 * Copy region to GC as clip, aligning as dest clip
	 */
	pClip = REGION_CREATE (pScreen, NULL, 0);
	REGION_INTERSECT(pScreen, pClip, &pWin->borderClip, prgnSrc);
	REGION_TRANSLATE(pScreen, pClip, 
			 -pBackingPixmap->screen_x,
			 -pBackingPixmap->screen_y);
	
	(*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);

	ValidateGC(&pBackingPixmap->drawable, pGC);

	(*pGC->ops->CopyArea) (&pBackingPixmap->drawable,
			       &pBackingPixmap->drawable, pGC,
			       src_x, src_y, w, h, dst_x, dst_y);

	(*pGC->funcs->DestroyClip) (pGC);

	FreeScratchGC(pGC);
    }
	
    SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow);
}
Ejemplo n.º 25
0
Archivo: PclLine.c Proyecto: aosm/X11
void
PclPolyLine(
     DrawablePtr pDrawable,
     GCPtr pGC,
     int mode,
     int nPoints,
     xPoint *pPoints)
{
    char t[80];
    FILE *outFile;
    int xoffset = 0, yoffset = 0;
    int nbox;
    BoxPtr pbox;
    xRectangle *drawRects, *r;
    RegionPtr drawRegion, region;
    short fudge;
    int i;
    XpContextPtr pCon;
    PclContextPrivPtr pConPriv;

    if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
      return;

    pCon = PclGetContextFromWindow( (WindowPtr) pDrawable );
    pConPriv = (PclContextPrivPtr)
			pCon->devPrivates[PclContextPrivateIndex].ptr;

    /*
     * Allocate the storage required to deal with the clipping
     * regions.
     */
    region = REGION_CREATE( pGC->pScreen, NULL, 0 );
    drawRects = (xRectangle *)
      xalloc( ( nPoints - 1 ) * sizeof( xRectangle ) );

    /*
     * Calculate the "fudge factor" based on the line width.
     * Multiplying by three seems to be a good first guess.
     * XXX I need to think of a way to test this.
     */
    fudge = 3 * pGC->lineWidth + 1;

    /*
     * Generate the PCL code to draw the polyline, by defining it as a
     * macro which uses the HP-GL/2 line drawing function.
     */

    MACRO_START( outFile, pConPriv );
    SAVE_PCL( outFile, pConPriv, "\033%0B" );

    sprintf( t, "PU%d,%dPD\n", pPoints[0].x + pDrawable->x,
	    pPoints[0].y + pDrawable->y );
    SAVE_PCL( outFile, pConPriv, t ); /* Move to the start of the polyline */

    switch( mode )
      {
	case CoordModeOrigin:
	  xoffset = pDrawable->x;
	  yoffset = pDrawable->y;
	  SAVE_PCL( outFile, pConPriv, "PA" );
	  break;
	case CoordModePrevious:
	  xoffset = yoffset = 0;
	  SAVE_PCL( outFile, pConPriv, "PR" );
	  break;
      }

    /*
     * Build the "drawing region" as we build the PCL to draw the
     * line.
     */
    for(i = 1, r = drawRects; i < nPoints; i++, r++ )
      {
	  if( i != 1 )
	    SAVE_PCL( outFile, pConPriv, "," );

	  sprintf( t, "%d,%d", pPoints[i].x + xoffset,
		  pPoints[i].y + yoffset );
	  SAVE_PCL( outFile, pConPriv, t );

	  r->x = MIN( pPoints[i-1].x, pPoints[i].x ) + xoffset - fudge;
	  r->y = MIN( pPoints[i-1].y, pPoints[i].y ) + yoffset - fudge;
	  r->width = abs( pPoints[i-1].x - pPoints[i].x ) + 2 * fudge;
	  r->height = abs( pPoints[i-1].y - pPoints[i].y ) + 2 * fudge;
      }
    SAVE_PCL( outFile, pConPriv, ";\033%0A" ); /* End the macro */
    MACRO_END( outFile );

    /*
     * Convert the collection of rectangles into a proper region, then
     * intersect it with the clip region.
     */
    drawRegion = RECTS_TO_REGION( pGC->pScreen, nPoints - 1,
				  drawRects, CT_UNSORTED );
    if( mode == CoordModePrevious )
      REGION_TRANSLATE( pGC->pScreen, drawRegion, pPoints[0].x, pPoints[0].y );
    REGION_INTERSECT( pGC->pScreen, region, drawRegion, pGC->pCompositeClip );

    /*
     * For each rectangle in the clip region, set the HP-GL/2 "input
     * window" and render the entire polyline to it.
     */
    pbox = REGION_RECTS( region );
    nbox = REGION_NUM_RECTS( region );

    PclSendData(outFile, pConPriv, pbox, nbox, 1.0);

    /*
     * Clean up the temporary regions
     */
    REGION_DESTROY( pGC->pScreen, drawRegion );
    REGION_DESTROY( pGC->pScreen, region );
    xfree( drawRects );
}
Ejemplo n.º 26
0
void
PclFillPolygon(
     DrawablePtr pDrawable,
     GCPtr pGC,
     int shape,
     int mode,
     int nPoints,
     DDXPointPtr pPoints)
{
    char t[80];
    FILE *outFile;
    int nbox, i;
    BoxPtr pbox;
    BoxRec box;
    RegionPtr drawRegion, region;
    int xoffset, yoffset;
    int xtop, xbottom, yleft, yright;
    int fillRule;
    XpContextPtr pCon;
    PclContextPrivPtr pConPriv;
    char *command;

    if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
      return;

    pCon = PclGetContextFromWindow( (WindowPtr) pDrawable );
    pConPriv = (PclContextPrivPtr)
			pCon->devPrivates[PclContextPrivateIndex].ptr;

    /*
     * Generate the PCL code to draw the filled polygon, by defining
     * it as a macro which uses the HP-GL/2 polygon drawing function.
     */
    MACRO_START( outFile, pConPriv );
    SAVE_PCL( outFile, pConPriv, "\033%0B" );

    if( mode == CoordModeOrigin )
      {
	  xoffset = pDrawable->x;
	  yoffset = pDrawable->y;
	  command = "PA";
      }
    else
      {
	  xoffset = yoffset = 0;
	  command = "PR";
      }

    /* Begin the polygon */
    sprintf( t, "PU%d,%d;PM0;%s", pPoints[0].x + xoffset, pPoints[0].y
	    + yoffset, command );
    SAVE_PCL( outFile, pConPriv, t );

    /* Seed the bounding box */
    xtop = xbottom = pPoints[0].x + xoffset;
    yleft = yright = pPoints[0].y + yoffset;

    /* Add the rest of the points to the polygon */
    for( i = 1; i < nPoints; i++ )
      {
	  if( i != 1 )
	    SAVE_PCL( outFile, pConPriv, "," );

	  sprintf( t, "%d,%d", pPoints[i].x + xoffset, pPoints[i].y +
		  yoffset );
	  SAVE_PCL( outFile, pConPriv, t );

	  /* Update the bounding box */
	  xtop = MIN( xtop, pPoints[i].x + xoffset );
	  xbottom = MAX( xbottom, pPoints[i].x + xoffset );
	  yleft = MIN( yleft, pPoints[i].y + yoffset );
	  yright = MAX( yright, pPoints[i].y + yoffset );
      }

    /* Close the polygon and the macro */

    if( pGC->fillRule == EvenOddRule )
      fillRule = 0;
    else
      fillRule = 1;

    sprintf( t, ";PM2;FP%d;\033%%0A", fillRule );
    SAVE_PCL( outFile, pConPriv, t );
    MACRO_END ( outFile );

    /*
     * Build the bounding region from the bounding box of the polygon
     */
    box.x1 = xtop;
    box.y1 = yleft;
    box.x2 = xbottom;
    box.y2 = yright;
    drawRegion = REGION_CREATE( pGC->pScreen, &box, 0 );

    if( mode == CoordModePrevious )
      REGION_TRANSLATE( pGC->pScreen, drawRegion, pPoints[0].x, pPoints[0].y );

    region = REGION_CREATE( pGC->pScreen, NULL, 0 );

    REGION_INTERSECT( pGC->pScreen, region, drawRegion, pGC->pCompositeClip );

    /*
     * For each rectangle in the clip region, set the HP-GL/2 "input
     * window" and render the polygon to it.
     */
    pbox = REGION_RECTS( region );
    nbox = REGION_NUM_RECTS( region );

    PclSendData(outFile, pConPriv, pbox, nbox, 1.0);

    /*
     * Clean up the temporary regions
     */
    REGION_DESTROY( pGC->pScreen, drawRegion );
    REGION_DESTROY( pGC->pScreen, region );
}
Ejemplo n.º 27
0
void
PclPolyRectangle(
     DrawablePtr pDrawable,
     GCPtr pGC,
     int nRects,
     xRectangle *pRects)
{
    char t[80];
    FILE *outFile;
    int nbox, i;
    BoxPtr pbox;
    xRectangle *drawRects, *r;
    RegionPtr drawRegion, region;
    short fudge;
    int xoffset, yoffset;
    XpContextPtr pCon;
    PclContextPrivPtr pConPriv;

    if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
      return;

    pCon = PclGetContextFromWindow( (WindowPtr) pDrawable );
    pConPriv = (PclContextPrivPtr)
			pCon->devPrivates[PclContextPrivateIndex].ptr;

    /*
     * Allocate the storage required to deal with the clipping
     * regions.
     */
    region = REGION_CREATE( pGC->pScreen, NULL, 0 );
    drawRects = (xRectangle *)xalloc( nRects * sizeof( xRectangle ) );

    fudge = 3 * pGC->lineWidth + 1;

    /*
     * Generate the PCL code to draw the rectangles, by defining them
     * as a macro which uses the HP-GL/2 rectangle drawing function.
     */
    MACRO_START( outFile, pConPriv );
    SAVE_PCL( outFile, pConPriv, "\033%0B" );

    xoffset = pDrawable->x;
    yoffset = pDrawable->y;

    for( i = 0, r = drawRects; i < nRects; i++, r++ )
      {
	  xRectangle rect = pRects[i];

	  /* Draw the rectangle */
	  sprintf( t, "PU%d,%d;ER%d,%d;", rect.x + xoffset,
		  rect.y + yoffset, rect.width, rect.height );
	  SAVE_PCL( outFile, pConPriv, t );

	  /* Build the bounding box */
	  r->x = MIN( rect.x, rect.x + rect.width ) + xoffset -
	    fudge;
	  r->y = MIN( rect.y, rect.y + rect.height ) + yoffset -
	    fudge;
	  r->width = rect.width + 2 * fudge;
	  r->height = rect.height + 2 * fudge;
      }
    SAVE_PCL( outFile, pConPriv, ";\033%0A" ); /* End the macro */
    MACRO_END( outFile );

    /*
     * Convert the collection of rectangles to a proper region, then
     * intersect it with the clip region.
     */
    drawRegion = RECTS_TO_REGION( pGC->pScreen, nRects,
				  drawRects, CT_UNSORTED );

    REGION_INTERSECT( pGC->pScreen, region, drawRegion, pGC->pCompositeClip );

    /*
     * For each rectangle in the clip region, set the HP-GL/2 "input
     * window" and render the set of rectangles to it.
     */
    pbox = REGION_RECTS( region );
    nbox = REGION_NUM_RECTS( region );

    PclSendData(outFile, pConPriv, pbox, nbox, 1.0);

    /*
     * Clean up the temporary regions
     */
    REGION_DESTROY( pGC->pScreen, drawRegion );
    REGION_DESTROY( pGC->pScreen, region );
    xfree( drawRects );
}
Ejemplo n.º 28
0
Archivo: winwindow.c Proyecto: aosm/X11
void 
winCopyWindowNativeGDI (WindowPtr pWin,
			DDXPointRec ptOldOrg,
			RegionPtr prgnSrc)
{
  DDXPointPtr		pptSrc;
  DDXPointPtr		ppt;
  RegionPtr		prgnDst;
  BoxPtr		pBox;
  int			dx, dy;
  int			i, nbox;
  WindowPtr		pwinRoot;
  BoxPtr		pBoxDst;
  ScreenPtr		pScreen = pWin->drawable.pScreen;
  winScreenPriv(pScreen);

#if 0
  ErrorF ("winCopyWindow\n");
#endif

  /* Get a pointer to the root window */
  pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];

  /* Create a region for the destination */
  prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);

  /* Calculate the shift from the source to the destination */
  dx = ptOldOrg.x - pWin->drawable.x;
  dy = ptOldOrg.y - pWin->drawable.y;

  /* Translate the region from the destination to the source? */
  REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
  REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip,
		   prgnSrc);

  /* Get a pointer to the first box in the region to be copied */
  pBox = REGION_RECTS(prgnDst);
  
  /* Get the number of boxes in the region */
  nbox = REGION_NUM_RECTS(prgnDst);

  /* Allocate source points for each box */
  if(!(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec))))
    return;

  /* Set an iterator pointer */
  ppt = pptSrc;

  /* Calculate the source point of each box? */
  for (i = nbox; --i >= 0; ppt++, pBox++)
    {
      ppt->x = pBox->x1 + dx;
      ppt->y = pBox->y1 + dy;
    }

  /* Setup loop pointers again */
  pBoxDst = REGION_RECTS(prgnDst);
  ppt = pptSrc;

#if 0
  ErrorF ("winCopyWindow - x1\tx2\ty1\ty2\tx\ty\n");
#endif

  /* BitBlt each source to the destination point */
  for (i = nbox; --i >= 0; pBoxDst++, ppt++)
    {
#if 0
      ErrorF ("winCopyWindow - %d\t%d\t%d\t%d\t%d\t%d\n",
	      pBoxDst->x1, pBoxDst->x2, pBoxDst->y1, pBoxDst->y2,
	      ppt->x, ppt->y);
#endif

      BitBlt (pScreenPriv->hdcScreen,
	      pBoxDst->x1, pBoxDst->y1,
	      pBoxDst->x2 - pBoxDst->x1, pBoxDst->y2 - pBoxDst->y1,
	      pScreenPriv->hdcScreen,
	      ppt->x, ppt->y,
	      SRCCOPY);
    }

  /* Cleanup the regions, etc. */
  DEALLOCATE_LOCAL(pptSrc);
  REGION_DESTROY(pWin->drawable.pScreen, prgnDst);
}
Ejemplo n.º 29
0
Archivo: xf86fbman.c Proyecto: aosm/X11
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 = pScreen->devPrivates[xf86FBScreenIndex].ptr;

    if(severity < 0) severity = 0;
    if(severity > 2) severity = 2;

    switch(severity) {
    case 2:
	if(offman->NumUsedAreas) {
	    FBLinkPtr pLink;
	    RegionRec tmpRegion;
	    newRegion = REGION_CREATE(pScreen, NULL, 1);
	    REGION_COPY(pScreen, newRegion, offman->InitialBoxes);
	    pLink = offman->UsedAreas;

	    while(pLink) {
		if(!pLink->area.RemoveAreaCallback) {
		    REGION_INIT(pScreen, &tmpRegion, &(pLink->area.box), 1);
		    REGION_SUBTRACT(pScreen, newRegion, newRegion, &tmpRegion);
		    REGION_UNINIT(pScreen, &tmpRegion);
		}
		pLink = pLink->next;
	    }

	    nbox = REGION_NUM_RECTS(newRegion);
	    pbox = REGION_RECTS(newRegion);
	    break;
	}
    case 1:
	if(offman->NumUsedAreas) {
	    FBLinkPtr pLink;
	    RegionRec tmpRegion;
	    newRegion = REGION_CREATE(pScreen, NULL, 1);
	    REGION_COPY(pScreen, newRegion, offman->FreeBoxes);
	    pLink = offman->UsedAreas;

	    while(pLink) {
		if(pLink->area.RemoveAreaCallback) {
		    REGION_INIT(pScreen, &tmpRegion, &(pLink->area.box), 1);
		    REGION_APPEND(pScreen, newRegion, &tmpRegion);
		    REGION_UNINIT(pScreen, &tmpRegion);
		}
		pLink = pLink->next;
	    }

	    nbox = REGION_NUM_RECTS(newRegion);
	    pbox = REGION_RECTS(newRegion);
	    break;
	}
    default:
	nbox = REGION_NUM_RECTS(offman->FreeBoxes);
	pbox = REGION_RECTS(offman->FreeBoxes);
	break;
    }

    while(nbox--) {
	x = pbox->x1;
	if(granularity) {
	   int tmp = x % granularity;
	   if(tmp) x += (granularity - tmp);
        }

	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)
	REGION_DESTROY(pScreen, newRegion);

    return TRUE;
}
Ejemplo n.º 30
0
static void
cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
{
    GCPtr   	  	pBackingGC;
    cwGCPtr		pPriv;
    DrawablePtr		pBackingDrawable;
    int			x_off, y_off;

    pPriv = (cwGCPtr) getCwGC (pGC);

    FUNC_PROLOGUE(pGC, pPriv);

    /*
     * Must call ValidateGC to ensure pGC->pCompositeClip is valid
     */
    (*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);

    if (!cwDrawableIsRedirWindow(pDrawable)) {
	cwDestroyBackingGC(pGC);
	FUNC_EPILOGUE(pGC, pPriv);
	return;
    } else {
	if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) {
	    FUNC_EPILOGUE(pGC, pPriv);
	    return;
	}
    }

    pBackingGC = pPriv->pBackingGC;
    pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);

    pPriv->stateChanges |= stateChanges;

    /*
     * Copy the composite clip into the backing GC if either
     * the drawable clip list has changed or the client has changed
     * the client clip data
     */
    if (pDrawable->serialNumber != pPriv->serialNumber ||
	(pPriv->stateChanges & (GCClipXOrigin|GCClipYOrigin|GCClipMask)))
    {
	XID vals[2];
	RegionPtr   pCompositeClip;

	pCompositeClip = REGION_CREATE (pScreen, NULL, 0);
	REGION_COPY (pScreen, pCompositeClip, pGC->pCompositeClip);

	/* Either the drawable has changed, or the clip list in the drawable has
	 * changed.  Copy the new clip list over and set the new translated
	 * offset for it.
	 */
	
	(*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION,
					  (pointer) pCompositeClip, 0);
	
	vals[0] = x_off - pDrawable->x;
	vals[1] = y_off - pDrawable->y;
	dixChangeGC(NullClient, pBackingGC,
		    (GCClipXOrigin | GCClipYOrigin), vals, NULL);

	pPriv->serialNumber = pDrawable->serialNumber;
	/*
	 * Mask off any client clip changes to make sure
	 * the clip list set above remains in effect
	 */
	pPriv->stateChanges &= ~(GCClipXOrigin|GCClipYOrigin|GCClipMask);
    }

    if (pPriv->stateChanges) {
	CopyGC(pGC, pBackingGC, pPriv->stateChanges);
	pPriv->stateChanges = 0;
    }

    if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x ||
	(pGC->patOrg.y + y_off) != pBackingGC->patOrg.y)
    {
	XID vals[2];
	vals[0] = pGC->patOrg.x + x_off;
	vals[1] = pGC->patOrg.y + y_off;
	dixChangeGC(NullClient, pBackingGC,
		    (GCTileStipXOrigin | GCTileStipYOrigin), vals, NULL);
    }

    ValidateGC(pBackingDrawable, pBackingGC);

    FUNC_EPILOGUE(pGC, pPriv);
}