Пример #1
0
void
CreatorDoHWBitblt(DrawablePtr pSrc, DrawablePtr pDst, int alu, RegionPtr prgnDst,
		  DDXPointPtr pptSrc, unsigned long planemask)
{
	FFBPtr pFfb = GET_FFB_FROM_SCREEN (pSrc->pScreen);
	ffb_fbcPtr ffb = pFfb->regs;
	BoxPtr pboxTmp;
	DDXPointPtr pptTmp;
	int nbox;
	BoxPtr pboxNext, pboxBase, pbox;

	nbox = REGION_NUM_RECTS(prgnDst);
	pbox = REGION_RECTS(prgnDst);

	FFB_WRITE_ATTRIBUTES(pFfb,
			     FFB_PPC_ACE_DISABLE|FFB_PPC_APE_DISABLE|FFB_PPC_CS_CONST,
			     FFB_PPC_ACE_MASK|FFB_PPC_APE_MASK|FFB_PPC_CS_MASK,
			     planemask,
			     FFB_ROP_NEW,
			     FFB_DRAWOP_BCOPY, pFfb->fg_cache,
			     FFB_FBC_DEFAULT);
	
	/* need to blit rectangles in different orders, depending on the direction of copy
           so that an area isnt overwritten before it is blitted */
	if (pptSrc->y < pbox->y1 && nbox > 1) {
		if (pptSrc->x < pbox->x1) {
			pboxTmp = pbox + nbox;
			pptTmp = pptSrc + nbox;
			while(nbox--) {
				pboxTmp--;
				pptTmp--;
				FFBFifo(pFfb, 6);
				FFB_WRITE64(&ffb->by, pptTmp->y, pptTmp->x);
				FFB_WRITE64_2(&ffb->dy, pboxTmp->y1, pboxTmp->x1);
				FFB_WRITE64_3(&ffb->bh,
					      (pboxTmp->y2 - pboxTmp->y1),
					      (pboxTmp->x2 - pboxTmp->x1));
			}
		} else {
			/* keep ordering in each band, reverse order of bands */
			pboxBase = pboxNext = pbox+nbox-1;
			
			while (pboxBase >= pbox) { /* for each band */
				/* find first box in band */
				while (pboxNext >= pbox && pboxBase->y1 == pboxNext->y1)
					pboxNext--;
		
				pboxTmp = pboxNext + 1;			/* first box in band */
				pptTmp = pptSrc + (pboxTmp - pbox);	/* first point in band */
		
				while (pboxTmp <= pboxBase) { /* for each box in band */
					FFBFifo(pFfb, 6);
					FFB_WRITE64(&ffb->by, pptTmp->y, pptTmp->x);
					FFB_WRITE64_2(&ffb->dy, pboxTmp->y1, pboxTmp->x1);
					FFB_WRITE64_3(&ffb->bh,
						      (pboxTmp->y2 - pboxTmp->y1),
						      (pboxTmp->x2 - pboxTmp->x1));
					++pboxTmp;
					++pptTmp;	
				}
				pboxBase = pboxNext;
			}
		}
	} else {
		if((pptSrc->x < pbox->x1) && (nbox > 1)) {
			pboxBase = pboxNext = pbox;
			while(pboxBase < pbox+nbox) {
				while((pboxNext<pbox+nbox) &&
				      (pboxNext->y1 == pboxBase->y1))
					pboxNext++;
				pboxTmp = pboxNext;
				pptTmp = pptSrc + (pboxTmp - pbox);
				while(pboxTmp != pboxBase) {
					--pboxTmp;
					--pptTmp;
					FFBFifo(pFfb, 6);
					FFB_WRITE64(&ffb->by, pptTmp->y, pptTmp->x);
					FFB_WRITE64_2(&ffb->dy, pboxTmp->y1, pboxTmp->x1);
					FFB_WRITE64_3(&ffb->bh,
						      (pboxTmp->y2 - pboxTmp->y1),
						      (pboxTmp->x2 - pboxTmp->x1));
				}
				pboxBase = pboxNext;
			}
		} else {
			/* dont need to change order of anything */
			pptTmp = pptSrc;
			pboxTmp = pbox;
	    
			while (nbox--) {
				FFBFifo(pFfb, 6);
				FFB_WRITE64(&ffb->by, pptTmp->y, pptTmp->x);
				FFB_WRITE64_2(&ffb->dy, pboxTmp->y1, pboxTmp->x1);
				FFB_WRITE64_3(&ffb->bh,
					      (pboxTmp->y2 - pboxTmp->y1),
					      (pboxTmp->x2 - pboxTmp->x1));
				pboxTmp++;
				pptTmp++;
			}
		}
	}
	pFfb->rp_active = 1;
	FFBSync(pFfb, ffb);
}
Пример #2
0
void
winShadowUpdateDDNL (ScreenPtr pScreen, 
		     shadowBufPtr pBuf)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  RegionPtr		damage = &pBuf->damage;
  HRESULT		ddrval = DD_OK;
  RECT			rcDest, rcSrc;
  POINT			ptOrigin;
  DWORD			dwBox = REGION_NUM_RECTS (damage);
  BoxPtr		pBox = REGION_RECTS (damage);
  HRGN			hrgnTemp = NULL, hrgnCombined = NULL;

  /*
   * Return immediately if the app is not active
   * and we are fullscreen, or if we have a bad display depth
   */
  if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
      || pScreenPriv->fBadDepth) return;

  /* Get the origin of the window in the screen coords */
  ptOrigin.x = pScreenInfo->dwXOffset;
  ptOrigin.y = pScreenInfo->dwYOffset;
  MapWindowPoints (pScreenPriv->hwndScreen,
		   HWND_DESKTOP,
		   (LPPOINT)&ptOrigin, 1);

  /*
   * Handle small regions with multiple blits,
   * handle large regions by creating a clipping region and 
   * doing a single blit constrained to that clipping region.
   */
  if (pScreenInfo->dwClipUpdatesNBoxes == 0
      || dwBox < pScreenInfo->dwClipUpdatesNBoxes)
    {
      /* Loop through all boxes in the damaged region */
      while (dwBox--)
	{
	  /* Assign damage box to source rectangle */
	  rcSrc.left = pBox->x1;
	  rcSrc.top = pBox->y1;
	  rcSrc.right = pBox->x2;
	  rcSrc.bottom = pBox->y2;
	  
	  /* Calculate destination rectangle */
	  rcDest.left = ptOrigin.x + rcSrc.left;
	  rcDest.top = ptOrigin.y + rcSrc.top;
	  rcDest.right = ptOrigin.x + rcSrc.right;
	  rcDest.bottom = ptOrigin.y + rcSrc.bottom;
	  
	  /* Blit the damaged areas */
	  ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4,
					    &rcDest,
					    pScreenPriv->pddsShadow4,
					    &rcSrc,
					    DDBLT_WAIT,
					    NULL);
	  if (FAILED (ddrval))
	    {
	      ErrorF ("winShadowUpdateDDNL - IDirectDrawSurface4_Blt () "
		      "failed: %08x\n",
		      ddrval);
	    }
	  
	  /* Get a pointer to the next box */
	  ++pBox;
	}
    }
  else
    {
      BoxPtr		pBoxExtents = REGION_EXTENTS (pScreen, damage);

      /* Compute a GDI region from the damaged region */
      hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
      dwBox--;
      pBox++;
      while (dwBox--)
	{
	  hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
	  CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
	  DeleteObject (hrgnTemp);
	  pBox++;
	}

      /* Install the GDI region as a clipping region */
      SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined);
      DeleteObject (hrgnCombined);
      hrgnCombined = NULL;

#if CYGDEBUG
      ErrorF ("winShadowUpdateDDNL - be x1 %d y1 %d x2 %d y2 %d\n",
	      pBoxExtents->x1, pBoxExtents->y1,
	      pBoxExtents->x2, pBoxExtents->y2);
#endif

      /* Calculating a bounding box for the source is easy */
      rcSrc.left = pBoxExtents->x1;
      rcSrc.top = pBoxExtents->y1;
      rcSrc.right = pBoxExtents->x2;
      rcSrc.bottom = pBoxExtents->y2;

      /* Calculating a bounding box for the destination is trickier */
      rcDest.left = ptOrigin.x + rcSrc.left;
      rcDest.top = ptOrigin.y + rcSrc.top;
      rcDest.right = ptOrigin.x + rcSrc.right;
      rcDest.bottom = ptOrigin.y + rcSrc.bottom;

      /* Our Blt should be clipped to the invalidated region */
      ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4,
					&rcDest,
					pScreenPriv->pddsShadow4,
					&rcSrc,
					DDBLT_WAIT,
					NULL);

      /* Reset the clip region */
      SelectClipRgn (pScreenPriv->hdcScreen, NULL);
    }
}
Пример #3
0
void
xglFillSpan (DrawablePtr pDrawable,
	     GCPtr	 pGC,
	     int	 n,
	     DDXPointPtr ppt,
	     int	 *pwidth)
{
    RegionPtr pClip = pGC->pCompositeClip;
    BoxPtr    pClipBox;
    BoxPtr    pExtent = REGION_EXTENTS (pGC->pScreen, pClip);
    BoxRec    part, full;
    BoxPtr    heapBox = NULL;
    BoxRec    stackBox[N_STACK_BOX];
    int       size = N_STACK_BOX;
    BoxPtr    pBox = stackBox;
    int	      nClip, nBox = 0;

    while (n--)
    {
	full.x1 = ppt->x;
	full.y1 = ppt->y;
	full.x2 = full.x1 + *pwidth;
	full.y2 = full.y1 + 1;

	pwidth++;
	ppt++;

	if (full.x1 < pExtent->x1)
	    full.x1 = pExtent->x1;
	if (full.y1 < pExtent->y1)
	    full.y1 = pExtent->y1;
	if (full.x2 > pExtent->x2)
	    full.x2 = pExtent->x2;
	if (full.y2 > pExtent->y2)
	    full.y2 = pExtent->y2;

	if (full.x1 >= full.x2 || full.y1 >= full.y2)
	    continue;

	nClip = REGION_NUM_RECTS (pClip);
	if (nClip == 1)
	{
	    ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
	}
	else
	{
	    pClipBox = REGION_RECTS (pClip);
	    while (nClip--)
	    {
		part = *pClipBox++;

		if (part.x1 < full.x1)
		    part.x1 = full.x1;
		if (part.y1 < full.y1)
		    part.y1 = full.y1;
		if (part.x2 > full.x2)
		    part.x2 = full.x2;
		if (part.y2 > full.y2)
		    part.y2 = full.y2;

		if (part.x1 < part.x2 && part.y1 < part.y2)
		    ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
	    }
	}
    }

    xglFillBox (pDrawable, pGC,
		pExtent->x1, pExtent->y1,
		pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
		(heapBox) ? heapBox : stackBox, nBox);

    if (heapBox)
	xfree (heapBox);
}
Пример #4
0
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 );
      }
}
Пример #5
0
RegionPtr
XAABitBlt(
    DrawablePtr pSrcDrawable,
    DrawablePtr pDstDrawable,
    GC *pGC,
    int srcx, int srcy,
    int width, int height,
    int dstx, int dsty,
    void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr),
    unsigned long bitPlane )
{

    RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
    RegionPtr prgnExposed;
    Bool freeSrcClip = FALSE;
    RegionRec rgnDst;
    DDXPointPtr pptSrc, ppt;
    DDXPointRec origDest;
    BoxPtr pbox;
    BoxRec fastBox;
    int i, dx, dy, numRects;
    xRectangle origSource;
    int fastClip = 0;		/* for fast clipping with pixmap source */
    int fastExpose = 0;		/* for fast exposures with pixmap source */

    origSource.x = srcx;
    origSource.y = srcy;
    origSource.width = width;
    origSource.height = height;
    origDest.x = dstx;
    origDest.y = dsty;

    if((pSrcDrawable != pDstDrawable) && 
			pSrcDrawable->pScreen->SourceValidate) {
	(*pSrcDrawable->pScreen->SourceValidate) (
			pSrcDrawable, srcx, srcy, width, height);
    }

    srcx += pSrcDrawable->x;
    srcy += pSrcDrawable->y;

    /* clip the source */
    if (pSrcDrawable->type == DRAWABLE_PIXMAP) {
	if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
	    prgnSrcClip = pGC->pCompositeClip;
	else
	    fastClip = 1;
    } else {	/* Window */
	if (pGC->subWindowMode == IncludeInferiors) {
	    if (!((WindowPtr) pSrcDrawable)->parent) {
		/*
		 * special case bitblt from root window in
		 * IncludeInferiors mode; just like from a pixmap
		 */
		fastClip = 1;
	    } else if ((pSrcDrawable == pDstDrawable) &&
		(pGC->clientClipType == CT_NONE)) {
		prgnSrcClip = pGC->pCompositeClip;
	    } else {
		prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
		freeSrcClip = TRUE;
	    }
	} else {
	    prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
	}
    }

    fastBox.x1 = srcx;
    fastBox.y1 = srcy;
    fastBox.x2 = srcx + width;
    fastBox.y2 = srcy + height;

    /* Don't create a source region if we are doing a fast clip */
    if (fastClip) {
	fastExpose = 1;
	/*
	 * clip the source; if regions extend beyond the source size,
 	 * make sure exposure events get sent
	 */
	if (fastBox.x1 < pSrcDrawable->x) {
	    fastBox.x1 = pSrcDrawable->x;
	    fastExpose = 0;
	} 
	if (fastBox.y1 < pSrcDrawable->y) {
	    fastBox.y1 = pSrcDrawable->y;
	    fastExpose = 0;
	}
	if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width) {
	    fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
	    fastExpose = 0;
	}
	if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height) {
	    fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
	    fastExpose = 0;
	}
    } else {
	REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
	REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
    }

    dstx += pDstDrawable->x;
    dsty += pDstDrawable->y;

    if (pDstDrawable->type == DRAWABLE_WINDOW) {
	if (!((WindowPtr)pDstDrawable)->realized) {
	    if (!fastClip)
		REGION_UNINIT(pGC->pScreen, &rgnDst);
	    if (freeSrcClip)
		REGION_DESTROY(pGC->pScreen, prgnSrcClip);
	    return NULL;
	}
    }

    dx = srcx - dstx;
    dy = srcy - dsty;

    /* Translate and clip the dst to the destination composite clip */
    if (fastClip) {
	RegionPtr cclip;

        /* Translate the region directly */
        fastBox.x1 -= dx;
        fastBox.x2 -= dx;
        fastBox.y1 -= dy;
        fastBox.y2 -= dy;

	/* If the destination composite clip is one rectangle we can
	   do the clip directly.  Otherwise we have to create a full
	   blown region and call intersect */

	cclip = pGC->pCompositeClip;
        if (REGION_NUM_RECTS(cclip) == 1) {
	    BoxPtr pBox = REGION_RECTS(cclip);

	    if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
	    if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
	    if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
	    if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;

	    /* Check to see if the region is empty */
	    if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) {
		REGION_NULL(pGC->pScreen, &rgnDst);
	    } else {
		REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
	    }
	} else {
	    /* We must turn off fastClip now, since we must create
	       a full blown region.  It is intersected with the
	       composite clip below. */
	    fastClip = 0;
	    REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
	}
    } else {
        REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
    }

    if (!fastClip) {
	REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst,
				 pGC->pCompositeClip);
    }

    /* Do bit blitting */
    numRects = REGION_NUM_RECTS(&rgnDst);
    if (numRects && width && height) {
	if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
						  sizeof(DDXPointRec)))) {
	    REGION_UNINIT(pGC->pScreen, &rgnDst);
	    if (freeSrcClip)
		REGION_DESTROY(pGC->pScreen, prgnSrcClip);
	    return NULL;
	}
	pbox = REGION_RECTS(&rgnDst);
	ppt = pptSrc;
	for (i = numRects; --i >= 0; pbox++, ppt++) {
	    ppt->x = pbox->x1 + dx;
	    ppt->y = pbox->y1 + dy;
	}

	(*doBitBlt) (pSrcDrawable, pDstDrawable, pGC, &rgnDst, pptSrc);
	DEALLOCATE_LOCAL(pptSrc);
    }

    prgnExposed = NULL;
    if (pGC->fExpose) {
        /* Pixmap sources generate a NoExposed (we return NULL to do this) */
        if (!fastExpose)
	    prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
				  origSource.x, origSource.y,
				  (int)origSource.width,
				  (int)origSource.height,
				  origDest.x, origDest.y, bitPlane);
    }
    REGION_UNINIT(pGC->pScreen, &rgnDst);
    if (freeSrcClip)
	REGION_DESTROY(pGC->pScreen, prgnSrcClip);
    return prgnExposed;
}
Пример #6
0
RegionPtr rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
		int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long bitPlane)
{
	RegionPtr rv;
	RegionRec clip_reg;
	RegionRec box_reg;
	int cd;
	int num_clips;
	int j;
	int post_process;
	BoxRec box;
	BoxPtr pbox;
	WindowPtr pDstWnd;
	PixmapPtr pDstPixmap;
	rdpPixmapRec *pDstPriv;

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

	/* do original call */
	rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane);

	post_process = 0;

	if (pDst->type == DRAWABLE_PIXMAP)
	{
		pDstPixmap = (PixmapPtr) pDst;
		pDstPriv = GETPIXPRIV(pDstPixmap);
	}
	else
	{
		if (pDst->type == DRAWABLE_WINDOW)
		{
			pDstWnd = (WindowPtr) pDst;

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

	if (!post_process)
		return rv;

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

	if (cd == 1)
	{
		rdp_send_area_update(pDst->x + dstx, pDst->y + dsty, w, h);
	}
	else if (cd == 2)
	{
		num_clips = REGION_NUM_RECTS(&clip_reg);

		if (num_clips > 0)
		{
			box.x1 = pDst->x + dstx;
			box.y1 = pDst->y + dsty;
			box.x2 = box.x1 + w;
			box.y2 = box.y1 + h;
			RegionInit(&box_reg, &box, 0);
			RegionIntersect(&clip_reg, &clip_reg, &box_reg);
			num_clips = REGION_NUM_RECTS(&clip_reg);

			if (num_clips < 10)
			{
				for (j = num_clips - 1; j >= 0; j--)
				{
					box = REGION_RECTS(&clip_reg)[j];
					rdp_send_area_update(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
				}
			}
			else
			{
				pbox = RegionExtents(&clip_reg);
				rdp_send_area_update(pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
			}

			RegionUninit(&box_reg);
		}
	}

	RegionUninit(&clip_reg);

	return rv;
}
Пример #7
0
void
fbWalkCompositeRegion (CARD8 op,
                       PicturePtr pSrc,
                       PicturePtr pMask,
                       PicturePtr pDst,
                       INT16 xSrc,
                       INT16 ySrc,
                       INT16 xMask,
                       INT16 yMask,
                       INT16 xDst,
                       INT16 yDst,
                       CARD16 width,
                       CARD16 height,
                       Bool srcRepeat,
                       Bool maskRepeat,
                       CompositeFunc compositeRect)
{
    RegionRec	    region;
    int		    n;
    BoxPtr	    pbox;
    int		    w, h, w_this, h_this;
    int		    x_msk, y_msk, x_src, y_src, x_dst, y_dst;

    xDst += pDst->pDrawable->x;
    yDst += pDst->pDrawable->y;
    if (pSrc->pDrawable)
    {
        xSrc += pSrc->pDrawable->x;
        ySrc += pSrc->pDrawable->y;
    }
    if (pMask && pMask->pDrawable)
    {
        xMask += pMask->pDrawable->x;
        yMask += pMask->pDrawable->y;
    }

    if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc, ySrc,
                                   xMask, yMask, xDst, yDst, width, height))
        return;

    n = REGION_NUM_RECTS (&region);
    pbox = REGION_RECTS (&region);
    while (n--)
    {
        h = pbox->y2 - pbox->y1;
        y_src = pbox->y1 - yDst + ySrc;
        y_msk = pbox->y1 - yDst + yMask;
        y_dst = pbox->y1;
        while (h)
        {
            h_this = h;
            w = pbox->x2 - pbox->x1;
            x_src = pbox->x1 - xDst + xSrc;
            x_msk = pbox->x1 - xDst + xMask;
            x_dst = pbox->x1;
            if (maskRepeat)
            {
                y_msk = mod (y_msk - pMask->pDrawable->y, pMask->pDrawable->height);
                if (h_this > pMask->pDrawable->height - y_msk)
                    h_this = pMask->pDrawable->height - y_msk;
                y_msk += pMask->pDrawable->y;
            }
            if (srcRepeat)
            {
                y_src = mod (y_src - pSrc->pDrawable->y, pSrc->pDrawable->height);
                if (h_this > pSrc->pDrawable->height - y_src)
                    h_this = pSrc->pDrawable->height - y_src;
                y_src += pSrc->pDrawable->y;
            }
            while (w)
            {
                w_this = w;
                if (maskRepeat)
                {
                    x_msk = mod (x_msk - pMask->pDrawable->x, pMask->pDrawable->width);
                    if (w_this > pMask->pDrawable->width - x_msk)
                        w_this = pMask->pDrawable->width - x_msk;
                    x_msk += pMask->pDrawable->x;
                }
                if (srcRepeat)
                {
                    x_src = mod (x_src - pSrc->pDrawable->x, pSrc->pDrawable->width);
                    if (w_this > pSrc->pDrawable->width - x_src)
                        w_this = pSrc->pDrawable->width - x_src;
                    x_src += pSrc->pDrawable->x;
                }
                (*compositeRect) (op, pSrc, pMask, pDst,
                                  x_src, y_src, x_msk, y_msk, x_dst, y_dst,
                                  w_this, h_this);
                w -= w_this;
                x_src += w_this;
                x_msk += w_this;
                x_dst += w_this;
            }
            h -= h_this;
            y_src += h_this;
            y_msk += h_this;
            y_dst += h_this;
        }
        pbox++;
    }
    REGION_UNINIT (pDst->pDrawable->pScreen, &region);
}
Пример #8
0
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;
}
Пример #9
0
/* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
 * Based on fbFillRegionTiled(), fbTile().
 */
Bool
uxa_fill_region_tiled(DrawablePtr pDrawable,
		      RegionPtr pRegion,
		      PixmapPtr pTile,
		      DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu)
{
	uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen);
	PixmapPtr pPixmap;
	int xoff, yoff;
	int tileWidth, tileHeight;
	int nbox = REGION_NUM_RECTS(pRegion);
	BoxPtr pBox = REGION_RECTS(pRegion);
	Bool ret = FALSE;

	tileWidth = pTile->drawable.width;
	tileHeight = pTile->drawable.height;

	/* If we're filling with a solid color, grab it out and go to
	 * FillRegionsolid, saving numerous copies.
	 */
	if (tileWidth == 1 && tileHeight == 1)
		return uxa_fill_region_solid(pDrawable, pRegion,
					     uxa_get_pixmap_first_pixel(pTile),
					     planemask, alu);

	pPixmap = uxa_get_offscreen_pixmap(pDrawable, &xoff, &yoff);
	if (!pPixmap || !uxa_pixmap_is_offscreen(pTile))
		goto out;

	if (uxa_screen->info->check_copy &&
	    !uxa_screen->info->check_copy(pTile, pPixmap, alu, planemask))
		return FALSE;

	REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);

	if ((*uxa_screen->info->prepare_copy) (pTile, pPixmap, 1, 1, alu,
					       planemask)) {
		while (nbox--) {
			int height = pBox->y2 - pBox->y1;
			int dstY = pBox->y1;
			int tileY;

			modulus(dstY - yoff - pDrawable->y - pPatOrg->y,
				tileHeight, tileY);

			while (height > 0) {
				int width = pBox->x2 - pBox->x1;
				int dstX = pBox->x1;
				int tileX;
				int h = tileHeight - tileY;

				if (h > height)
					h = height;
				height -= h;

				modulus(dstX - xoff - pDrawable->x - pPatOrg->x,
					tileWidth, tileX);

				while (width > 0) {
					int w = tileWidth - tileX;
					if (w > width)
						w = width;
					width -= w;

					(*uxa_screen->info->copy) (pPixmap,
								   tileX, tileY,
								   dstX, dstY,
								   w, h);
					dstX += w;
					tileX = 0;
				}
				dstY += h;
				tileY = 0;
			}
			pBox++;
		}
		(*uxa_screen->info->done_copy) (pPixmap);

		ret = TRUE;
	}

out:
	REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);

	return ret;
}
Пример #10
0
void
rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
                xRectangle *prectInit)
{
    int j;
    int cd;
    int num_clips;
    RegionRec clip_reg;
    RegionPtr fill_reg;
    BoxRec box;

    int got_id;
    int dirty_type;
    int post_process;
    int reset_surface;

    struct image_data id;
    WindowPtr pDstWnd;
    PixmapPtr pDstPixmap;
    rdpPixmapRec *pDstPriv;
    rdpPixmapRec *pDirtyPriv;

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

    /* make a copy of rects */
    fill_reg = RegionFromRects(nrectFill, prectInit, CT_NONE);

    /* do original call */
    rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit);

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

    if (pDrawable->type == DRAWABLE_PIXMAP)
    {
        pDstPixmap = (PixmapPtr)pDrawable;
        pDstPriv = GETPIXPRIV(pDstPixmap);
        if (pDstPixmap->devPrivate.ptr == g_rdpScreen.pfbMemory)
        {
            /* treat like root window */
            post_process = 1;

            if (g_do_dirty_ons)
            {
                LLOGLN(10, ("rdpPolyFillRect: gettig dirty"));
                g_screenPriv.is_dirty = 1;
                pDirtyPriv = &g_screenPriv;
                dirty_type = RDI_IMGLL;
            }
            else
            {
                rdpup_get_screen_image_rect(&id);
                got_id = 1;
            }
        }
        else if (xrdp_is_os(pDstPixmap, pDstPriv))
        {
            post_process = 1;

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

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

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

    if (!post_process)
    {
        RegionDestroy(fill_reg);
        LLOGLN(10, ("rdpPolyFillRect: out, post_process not set"));
        return;
    }

    RegionTranslate(fill_reg, pDrawable->x, pDrawable->y);
    RegionInit(&clip_reg, NullBox, 0);
    cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
    LLOGLN(10, ("rdpPolyFillRect: cd %d", cd));

    if (cd == 1) /* no clip */
    {
        if (dirty_type != 0)
        {
            if (pGC->fillStyle == 0 && /* solid fill */
                    (pGC->alu == GXclear ||
                     pGC->alu == GXset ||
                     pGC->alu == GXinvert ||
                     pGC->alu == GXnoop ||
                     pGC->alu == GXand ||
                     pGC->alu == GXcopy /*||
                     pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
            {
                draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel,
                                          pGC->alu);
            }
            else
            {
                draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, RDI_IMGLL, 2);
            }
        }
        else if (got_id)
        {
            rdpup_begin_update();

            if (pGC->fillStyle == 0 && /* solid fill */
                    (pGC->alu == GXclear ||
                     pGC->alu == GXset ||
                     pGC->alu == GXinvert ||
                     pGC->alu == GXnoop ||
                     pGC->alu == GXand ||
                     pGC->alu == GXcopy /*||
                     pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
            {
                rdpup_set_fgcolor(pGC->fgPixel);
                rdpup_set_opcode(pGC->alu);

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

                rdpup_set_opcode(GXcopy);
            }
            else /* non solid fill */
            {
                for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
                {
                    box = REGION_RECTS(fill_reg)[j];
                    rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
                                    box.y2 - box.y1);
                }
            }

            rdpup_end_update();
        }
    }
    else if (cd == 2) /* clip */
    {
        RegionIntersect(&clip_reg, &clip_reg, fill_reg);
        num_clips = REGION_NUM_RECTS(&clip_reg);

        if (num_clips > 0)
        {
            if (dirty_type != 0)
            {
                if (pGC->fillStyle == 0 && /* solid fill */
                        (pGC->alu == GXclear ||
                         pGC->alu == GXset ||
                         pGC->alu == GXinvert ||
                         pGC->alu == GXnoop ||
                         pGC->alu == GXand ||
                         pGC->alu == GXcopy /*||
                         pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
                {
                    LLOGLN(10, ("rdpPolyFillRect: 3"));
                    draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
                                              pGC->alu);
                }
                else
                {
                    LLOGLN(10, ("rdpPolyFillRect: 4"));
                    draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, RDI_IMGLL, 2);
                }
            }
            else if (got_id)
            {
                rdpup_begin_update();

                 LLOGLN(10, ("2 %x", pGC->fgPixel));

                if (pGC->fillStyle == 0 && /* solid fill */
                        (pGC->alu == GXclear ||
                         pGC->alu == GXset ||
                         pGC->alu == GXinvert ||
                         pGC->alu == GXnoop ||
                         pGC->alu == GXand ||
                         pGC->alu == GXcopy /*||
                         pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
                {
                    rdpup_set_fgcolor(pGC->fgPixel);
                    rdpup_set_opcode(pGC->alu);

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

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

                rdpup_end_update();
            }
        }
    }

    RegionUninit(&clip_reg);
    RegionDestroy(fill_reg);

    if (reset_surface)
    {
        rdpup_switch_os_surface(-1);
    }
}
Пример #11
0
static FBAreaPtr
AllocateArea(
   FBManagerPtr offman,
   int w, int h,
   int granularity,
   MoveAreaCallbackProcPtr moveCB,
   RemoveAreaCallbackProcPtr removeCB,
   pointer privData
){
   ScreenPtr pScreen = offman->pScreen;
   FBLinkPtr link = NULL;
   FBAreaPtr area = NULL;
   RegionRec NewReg;
   int i, x = 0, num;
   BoxPtr boxp;

   if(granularity <= 1) granularity = 0;

   boxp = REGION_RECTS(offman->FreeBoxes);
   num = REGION_NUM_RECTS(offman->FreeBoxes);

   /* look through the free boxes */
   for(i = 0; i < num; i++, boxp++) {
	x = boxp->x1;
	if(granularity) {
	    int tmp = x % granularity;
	    if(tmp) x += (granularity - tmp);
	}

	if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w))
	   continue;

	link = xalloc(sizeof(FBLink));
	if(!link) return NULL;

        area = &(link->area);
        link->next = offman->UsedAreas;
        offman->UsedAreas = link;
        offman->NumUsedAreas++;
	break;
   }

   /* try to boot a removeable one out if we are not expendable ourselves */
   if(!area && !removeCB) {
	link = offman->UsedAreas;

	while(link) {
	   if(!link->area.RemoveAreaCallback) {
		link = link->next;
		continue;
	   }

	   boxp = &(link->area.box);
	   x = boxp->x1;
 	   if(granularity) {
		int tmp = x % granularity;
		if(tmp) x += (granularity - tmp);
	   }

	   if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w)) {
		link = link->next;
		continue;
	   }

	   /* bye, bye */
	   (*link->area.RemoveAreaCallback)(&link->area);
	   REGION_INIT(pScreen, &NewReg, &(link->area.box), 1); 
	   REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
	   REGION_UNINIT(pScreen, &NewReg); 

           area = &(link->area);
	   break;
	}
   }

   if(area) {
	area->pScreen = pScreen;
	area->granularity = granularity;
	area->box.x1 = x;
	area->box.x2 = x + w;
	area->box.y1 = boxp->y1;
	area->box.y2 = boxp->y1 + h;
	area->MoveAreaCallback = moveCB;
	area->RemoveAreaCallback = removeCB;
	area->devPrivate.ptr = privData;

        REGION_INIT(pScreen, &NewReg, &(area->box), 1);
	REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
	REGION_UNINIT(pScreen, &NewReg);
   }

   return area;
}
Пример #12
0
static void send_update(void)
{
  CL_SLOT *cl = (CL_SLOT *)cur_slot;
  BoxRec fb_rect;
  RegionRec fb_region, clip_region, outer_region;
  CARD8 msg_hdr[4] = {
    0, 0, 0, 1
  };
  CARD8 rect_hdr[12];
  int num_copy_rects, num_pending_rects, num_all_rects;
  int raw_bytes = 0, hextile_bytes = 0;
  int i, idx, rev_order;
  static int counter = 0;

#ifdef NETLOGGER
  aio_set_serial_number(&cl->s, cl->serial_number);
#endif

  counter++;
  vncspuLog(1, "Begin send update %d", counter);

  CRASSERT(vnc_spu.serverBuffer);

  /*crDebug("Enter send_update to %s", cur_slot->name);*/

  /* check if clipping has changed since we got the pixels and update
   * the pending region if needed.
   */
  if (NewClip) {
     /*crDebug("Getting updated cliprects");*/
     vncspuGetScreenRects(&cl->pending_region);
     num_pending_rects = REGION_NUM_RECTS(&cl->pending_region);
     /*crDebug("Now, %d rects", num_pending_rects);*/
     if (num_pending_rects == 0 && cl->enable_frame_sync) {
        /* always need to send _something_ for framesync to work */
        BoxRec b;
        b.x1 = 0;
        b.y1 = 0;
        b.x2 = 1;
        b.y2 = 1;
        REGION_UNINIT(&cl->pending_region);
        REGION_INIT(&cl->pending_region, &b, 1);
     }
     NewClip = 0;
  }
  /*PrintRegion("Sending", &cl->pending_region);*/


  /* Process framebuffer size change. */
  if (cl->newfbsize_pending) {
    /* Update framebuffer size, clear newfbsize_pending flag. */
    cl->fb_width = g_screen_info.width;
    cl->fb_height = g_screen_info.height;
    cl->newfbsize_pending = 0;
    log_write(LL_DEBUG, "Applying new framebuffer size (%dx%d) to %s",
              (int)cl->fb_width, (int)cl->fb_height, cur_slot->name);
    /* In any case, mark all the framebuffer contents as changed. */
    fb_rect.x1 = 0;
    fb_rect.y1 = 0;
    fb_rect.x2 = cl->fb_width;
    fb_rect.y2 = cl->fb_height;
    REGION_INIT(&fb_region, &fb_rect, 1);
    REGION_COPY(&cl->pending_region, &fb_region);
    REGION_UNINIT(&fb_region);
    REGION_EMPTY(&cl->copy_region);
    /* If NewFBSize is supported by the client, send only NewFBSize
       pseudo-rectangle, pixel data will be sent in the next update. */
    if (cl->enable_newfbsize) {
      send_newfbsize();
      vncspuUnlockFrameBuffer();
      return;
    }
  } else {
    /* Exclude CopyRect areas covered by pending_region. */
    REGION_SUBTRACT(&cl->copy_region, &cl->copy_region, &cl->pending_region);
  }

#if 00
  if (cl->enable_cliprects_enc && cl->new_cliprects) {
    send_new_cliprects();
    vncspuUnlockFrameBuffer();
    cl->new_cliprects = 0;
    return;
  }
#endif

  /* Clip regions to the rectangle requested by the client. */
  REGION_INIT(&clip_region, &cl->update_rect, 1);

  REGION_INTERSECT(&cl->pending_region, &cl->pending_region, &clip_region);
  if (REGION_NOTEMPTY(&cl->copy_region)) {
    REGION_INTERSECT(&cl->copy_region, &cl->copy_region, &clip_region);

    REGION_INIT(&outer_region, NullBox, 8);
    REGION_COPY(&outer_region, &cl->copy_region);
    REGION_TRANSLATE(&clip_region, cl->copy_dx, cl->copy_dy);
    REGION_INTERSECT(&cl->copy_region, &cl->copy_region, &clip_region);
    REGION_SUBTRACT(&outer_region, &outer_region, &cl->copy_region);
    REGION_UNION(&cl->pending_region, &cl->pending_region, &outer_region);
    REGION_UNINIT(&outer_region);
  }
  REGION_UNINIT(&clip_region);

  /* Reduce the number of rectangles if possible. */
  if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
    region_pack(&cl->pending_region, 32);
  } else {
    region_pack(&cl->pending_region, 12);
  }

  /* Compute the number of rectangles in regions. */
  num_pending_rects = REGION_NUM_RECTS(&cl->pending_region);
  num_copy_rects = REGION_NUM_RECTS(&cl->copy_region);
  num_all_rects = num_pending_rects + num_copy_rects;
  if (num_all_rects == 0) {
    vncspuUnlockFrameBuffer();
    return;
  }

  log_write(LL_DEBUG, "Sending framebuffer update (min %d rects) to %s",
            num_all_rects, cur_slot->name);

  /* Prepare and send FramebufferUpdate message header. */
  /* FIXME: Enable Tight encoding even if LastRect is not supported. */
  /* FIXME: Do not send LastRect if all the rectangles are CopyRect. */
  if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
    buf_put_CARD16(&msg_hdr[2], 0xFFFF);
  } else {
    buf_put_CARD16(&msg_hdr[2], num_all_rects);
  }
  aio_write(NULL, msg_hdr, 4);

  /* Determine the order in which CopyRect rectangles should be sent. */
  rev_order = (cl->copy_dy > 0 || (cl->copy_dy == 0 && cl->copy_dx > 0));

  /* For each CopyRect rectangle: */
  for (i = 0; i < num_copy_rects; i++) {
    FB_RECT rect;
    AIO_BLOCK *block;
    idx = (rev_order) ? num_copy_rects - i - 1 : i;
    rect.x = REGION_RECTS(&cl->copy_region)[idx].x1;
    rect.y = REGION_RECTS(&cl->copy_region)[idx].y1;
    rect.w = REGION_RECTS(&cl->copy_region)[idx].x2 - rect.x;
    rect.h = REGION_RECTS(&cl->copy_region)[idx].y2 - rect.y;
    rect.src_x = rect.x - cl->copy_dx;
    rect.src_y = rect.y - cl->copy_dy;
    rect.enc = RFB_ENCODING_COPYRECT;
    log_write(LL_DEBUG, "Sending CopyRect rectangle %dx%d at %d,%d to %s",
              (int)rect.w, (int)rect.h, (int)rect.x, (int)rect.y,
              cur_slot->name);

    /* Prepare the CopyRect rectangle. */
    block = rfb_encode_copyrect_block(cl, &rect);

    /* Send the rectangle.
       FIXME: Check for block == NULL? */
    aio_write_nocopy(NULL, block);
  }

  if (cl->enc_prefer == RFB_ENCODING_TIGHT) {
    /* needed for successful caching of zlib-compressed data (tight) */
    rfb_reset_tight_encoder(cl);
  }

  if (num_pending_rects) {
    /* Lock around fb access so other thread doesn't change contents while
     * we're encoding.
     */
#ifdef NETLOGGER
    if (vnc_spu.netlogger_url) {
      NL_info("vncspu", "spu.encode.begin",
              "NODE=s NUMBER=i", vnc_spu.hostname, cl->serial_number);
    }
#endif

    /* For each of the usual pending rectangles: */
    for (i = 0; i < num_pending_rects; i++) {
      FB_RECT rect;
      AIO_BLOCK *block;
			/*
      crDebug("sending rect %d of %d: %d, %d .. %d, %d", i, num_pending_rects,
              REGION_RECTS(&cl->pending_region)[i].x1,
              REGION_RECTS(&cl->pending_region)[i].y1,
              REGION_RECTS(&cl->pending_region)[i].x2,
              REGION_RECTS(&cl->pending_region)[i].y2);
			*/
      rect.x = REGION_RECTS(&cl->pending_region)[i].x1;
      rect.y = REGION_RECTS(&cl->pending_region)[i].y1;
      rect.w = REGION_RECTS(&cl->pending_region)[i].x2 - rect.x;
      rect.h = REGION_RECTS(&cl->pending_region)[i].y2 - rect.y;
      log_write(LL_DEBUG, "Sending rectangle %dx%d at %d,%d to %s enc 0x%x",
                (int)rect.w, (int)rect.h, (int)rect.x, (int)rect.y,
                cur_slot->name, cl->enc_prefer);

      if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
        /* Use Tight encoding */
        rect.enc = RFB_ENCODING_TIGHT;
        /* lock to prevent glReadPixels in other thread changing data */
        rfb_encode_tight(cl, &rect);
        continue;                 /* Important! */
      } else if (cl->enc_prefer == RFB_ENCODING_RAW24) {
        rect.enc = RFB_ENCODING_RAW24;
        block = rfb_encode_raw24_block(cl, &rect);
      } else if ( cl->enc_prefer != RFB_ENCODING_RAW &&
                  cl->enc_enable[RFB_ENCODING_HEXTILE] ) {
        /* Use Hextile encoding */
        rect.enc = RFB_ENCODING_HEXTILE;
        block = rfb_encode_hextile_block(cl, &rect);
        if (block != NULL) {
          hextile_bytes += block->data_size;
          raw_bytes += rect.w * rect.h * (cl->format.bits_pixel / 8);
        }
      } else {
        /* Use Raw encoding */
        rect.enc = RFB_ENCODING_RAW;
        if (vnc_spu.half_rez) {
           block = rfb_encode_raw_block_halfrez(cl, &rect);
        }
        else {
           block = rfb_encode_raw_block(cl, &rect);
        }
      }

      /* Send the rectangle.
         FIXME: Check for block == NULL? */
      aio_write_nocopy(NULL, block);
    }

  } /* if num_pending_rects */


  REGION_EMPTY(&cl->pending_region);
  REGION_EMPTY(&cl->copy_region);

  /* Send LastRect marker. */
  if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
    FB_RECT rect;
    rect.x = rect.y = rect.w = rect.h = 0;
    rect.enc = RFB_ENCODING_LASTRECT;
    put_rect_header(rect_hdr, &rect);
    aio_write(NULL, rect_hdr, 12);
  }

  /* Set the last block's callback function */
  /* All prev blocks had NULL callbacks */
  assert(cur_slot->outqueue_last);
  if (cur_slot->outqueue_last) {
    cur_slot->outqueue_last->func = wf_client_update_finished;
  }

  /* Something has been queued for sending. */
  cl->update_in_progress = 1;
  cl->update_requested = 0;

#ifdef NETLOGGER
  if (vnc_spu.netlogger_url) {
    NL_info("vncspu", "spu.encode.end",
            "NODE=s NUMBER=i", vnc_spu.hostname, cl->serial_number);
  }
  aio_set_serial_number(&cl->s, 0);
#endif

  vncspuUnlockFrameBuffer(); /* encoder done with buffer */

  /*crDebug("Leave send_update");*/

  vncspuLog(1, "End send update %d", counter);
}
Пример #13
0
void
winReshapeMultiWindow (WindowPtr pWin)
{
  int		nRects;
  RegionRec	rrNewShape;
  BoxPtr	pShape, pRects, pEnd;
  HRGN		hRgn, hRgnRect;
  winWindowPriv(pWin);

#if CYGDEBUG
  winDebug ("winReshape ()\n");
#endif
  
  /* 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;

  REGION_NULL(pWin->drawable.pScreen, &rrNewShape);
  REGION_COPY(pWin->drawable.pScreen, &rrNewShape, wBoundingShape(pWin));
  REGION_TRANSLATE(pWin->drawable.pScreen,
		   &rrNewShape,
		   pWin->borderWidth,
                   pWin->borderWidth);
  
  nRects = REGION_NUM_RECTS(&rrNewShape);
  pShape = REGION_RECTS(&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;
    }

  REGION_UNINIT(pWin->drawable.pScreen, &rrNewShape);
  
  return;
}
Пример #14
0
Файл: xaaRect.c Проект: aosm/X11
void
XAAPolyRectangleThinSolid(
    DrawablePtr  pDrawable,
    GCPtr        pGC,    
    int	         nRectsInit,
    xRectangle  *pRectsInit )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    int         nClipRects;     /* number of clip rectangles */
    BoxPtr      pClipRects;     /* points to the list of clip rects */
    int         xOrigin;        /* Drawables x origin */
    int         yOrigin;        /* Drawables x origin */
    xRectangle *pRect;          /* list of rects */
    int         nRects;         /* running count of number of rects */
    int         origX1, origY1; /* original rectangle's U/L corner */
    int         origX2, origY2; /* original rectangle's L/R corner */
    int         clippedX1;      /* clipped rectangle's left x */
    int         clippedY1;      /* clipped rectangle's top y */
    int         clippedX2;      /* clipped rectangle's right x */
    int         clippedY2;      /* clipped rectangle's bottom y */
    int         clipXMin;       /* upper left corner of clip rect */
    int         clipYMin;       /* upper left corner of clip rect */
    int         clipXMax;       /* lower right corner of clip rect */
    int         clipYMax;       /* lower right corner of clip rect */
    int         width, height;  /* width and height of rect */

    nClipRects = REGION_NUM_RECTS(pGC->pCompositeClip);
    pClipRects = REGION_RECTS(pGC->pCompositeClip);

    if(!nClipRects) return;

    xOrigin = pDrawable->x;
    yOrigin = pDrawable->y;


    (*infoRec->SetupForSolidLine)(infoRec->pScrn, 
			pGC->fgPixel, pGC->alu, pGC->planemask);


    for ( ; nClipRects > 0; 
	  nClipRects--, pClipRects++ )
    {
        clipYMin = pClipRects->y1;
        clipYMax = pClipRects->y2 - 1;
        clipXMin = pClipRects->x1;
        clipXMax = pClipRects->x2 - 1;

	for (pRect = pRectsInit, nRects = nRectsInit; 
	     nRects > 0; 
	     nRects--, pRect++ )
        {
	    /* translate rectangle data over to the drawable */
            origX1 = pRect->x + xOrigin; 
	    origY1 = pRect->y + yOrigin;
            origX2 = origX1 + pRect->width; 
	    origY2 = origY1 + pRect->height; 

	    /* reject entire rectangle if completely outside clip rect */
	    if ((origX1 > clipXMax) || (origX2 < clipXMin) ||
		(origY1 > clipYMax) || (origY2 < clipYMin))
	        continue;

	    /* clip the rectangle */
	    clippedX1 = max (origX1, clipXMin);
	    clippedX2 = min (origX2, clipXMax);
	    clippedY1 = max (origY1, clipYMin);
	    clippedY2 = min (origY2, clipYMax);

	    width = clippedX2 - clippedX1 + 1;

	    if (origY1 >= clipYMin) {
		(*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
			clippedX1, clippedY1, width, DEGREES_0);

		/* don't overwrite corner */
		clippedY1++;
	    }

	    if ((origY2 <= clipYMax) && (origY1 != origY2)) {
		(*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
			clippedX1, clippedY2, width, DEGREES_0);

		/* don't overwrite corner */
		clippedY2--; 
	    }

	    if (clippedY2 < clippedY1) continue;

	    height = clippedY2 - clippedY1 + 1;

	    /* draw vertical edges using lines if not clipped out */
            if (origX1 >= clipXMin) 
		(*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
			clippedX1, clippedY1, height, DEGREES_270);

            if ((origX2 <= clipXMax) && (origX2 != origX1))
		(*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
			clippedX2, clippedY1, height, DEGREES_270);
	}
    }

    SET_SYNC_FLAG(infoRec);
} 
Пример #15
0
void
rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
{
  RegionRec clip_reg;
  RegionPtr tmpRegion;
  int cd;
  int lw;
  int extra;
  int i;
  int num_clips;
  int got_id;
  xRectangle* rects;
  BoxRec box;
  struct image_data id;
  WindowPtr pDstWnd;
  PixmapPtr pDstPixmap;
  rdpPixmapRec* pDstPriv;

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

  rects = 0;
  if (narcs > 0)
  {
    rects = (xRectangle*)g_malloc(narcs * sizeof(xRectangle), 0);
    lw = pGC->lineWidth;
    if (lw == 0)
    {
      lw = 1;
    }
    extra = lw / 2;
    for (i = 0; i < narcs; i++)
    {
      rects[i].x = (parcs[i].x - extra) + pDrawable->x;
      rects[i].y = (parcs[i].y - extra) + pDrawable->y;
      rects[i].width = parcs[i].width + lw;
      rects[i].height = parcs[i].height + lw;
    }
  }

  /* do original call */
  rdpPolyArcOrg(pDrawable, pGC, narcs, parcs);

  got_id = 0;
  if (pDrawable->type == DRAWABLE_PIXMAP)
  {
    pDstPixmap = (PixmapPtr)pDrawable;
    pDstPriv = GETPIXPRIV(pDstPixmap);
    if (XRDP_IS_OS(pDstPriv))
    {
      rdpup_switch_os_surface(pDstPriv->rdpindex);
      rdpup_get_pixmap_image_rect(pDstPixmap, &id);
      got_id = 1;
    }
  }
  else
  {
    if (pDrawable->type == DRAWABLE_WINDOW)
    {
      pDstWnd = (WindowPtr)pDrawable;
      if (pDstWnd->viewable)
      {
        rdpup_get_screen_image_rect(&id);
        got_id = 1;
      }
    }
  }
  if (!got_id)
  {
    g_free(rects);
    return;
  }

  RegionInit(&clip_reg, NullBox, 0);
  cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
  if (cd == 1)
  {
    if (rects != 0)
    {
      tmpRegion = RegionFromRects(narcs, rects, CT_NONE);
      num_clips = REGION_NUM_RECTS(tmpRegion);
      if (num_clips > 0)
      {
        rdpup_begin_update();
        for (i = num_clips - 1; i >= 0; i--)
        {
          box = REGION_RECTS(tmpRegion)[i];
          rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
        }
        rdpup_end_update();
      }
      RegionDestroy(tmpRegion);
    }
  }
  else if (cd == 2)
  {
    if (rects != 0)
    {
      tmpRegion = RegionFromRects(narcs, rects, CT_NONE);
      RegionIntersect(tmpRegion, tmpRegion, &clip_reg);
      num_clips = REGION_NUM_RECTS(tmpRegion);
      if (num_clips > 0)
      {
        rdpup_begin_update();
        for (i = num_clips - 1; i >= 0; i--)
        {
          box = REGION_RECTS(tmpRegion)[i];
          rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
        }
        rdpup_end_update();
      }
      RegionDestroy(tmpRegion);
    }
  }
  RegionUninit(&clip_reg);
  g_free(rects);
  rdpup_switch_os_surface(-1);
}
Пример #16
0
static Bool
uxa_do_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
		 int w, int h, int format, char *bits, int src_stride)
{
	uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen);
	PixmapPtr pPix;
	RegionPtr pClip;
	BoxPtr pbox;
	int nbox;
	int xoff, yoff;
	int bpp = pDrawable->bitsPerPixel;

	/* Don't bother with under 8bpp, XYPixmaps. */
	if (format != ZPixmap || bpp < 8)
		return FALSE;

	if (uxa_screen->force_fallback)
		return FALSE;

	if (!uxa_screen->info->put_image)
		return FALSE;

	/* Only accelerate copies: no rop or planemask. */
	if (!UXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
		return FALSE;

	pPix = uxa_get_offscreen_pixmap(pDrawable, &xoff, &yoff);
	if (!pPix)
		return FALSE;

	x += pDrawable->x;
	y += pDrawable->y;

	pClip = fbGetCompositeClip(pGC);
	for (nbox = REGION_NUM_RECTS(pClip),
	     pbox = REGION_RECTS(pClip); nbox--; pbox++) {
		int x1 = x;
		int y1 = y;
		int x2 = x + w;
		int y2 = y + h;
		char *src;
		Bool ok;

		if (x1 < pbox->x1)
			x1 = pbox->x1;
		if (y1 < pbox->y1)
			y1 = pbox->y1;
		if (x2 > pbox->x2)
			x2 = pbox->x2;
		if (y2 > pbox->y2)
			y2 = pbox->y2;
		if (x1 >= x2 || y1 >= y2)
			continue;

		src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
		ok = uxa_screen->info->put_image(pPix, x1 + xoff, y1 + yoff,
						 x2 - x1, y2 - y1, src,
						 src_stride);
		/* If we fail to accelerate the upload, fall back to using
		 * unaccelerated fb calls.
		 */
		if (!ok) {
			FbStip *dst;
			FbStride dst_stride;
			int dstBpp;
			int dstXoff, dstYoff;

			if (!uxa_prepare_access(pDrawable, UXA_ACCESS_RW))
				return FALSE;

			fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp,
					  dstXoff, dstYoff);

			fbBltStip((FbStip *) bits +
				  (y1 - y) * (src_stride / sizeof(FbStip)),
				  src_stride / sizeof(FbStip),
				  (x1 - x) * dstBpp,
				  dst + (y1 + dstYoff) * dst_stride, dst_stride,
				  (x1 + dstXoff) * dstBpp, (x2 - x1) * dstBpp,
				  y2 - y1, GXcopy, FB_ALLONES, dstBpp);

			uxa_finish_access(pDrawable, UXA_ACCESS_RW);
		}
	}


	return TRUE;
}
Пример #17
0
void
rlPolyFillRect(DrawablePtr  pDrawable,
               GCPtr	    pGC,
               int	    nrect,
               xRectangle   *prect)
{
    RegionPtr	    pClip = fbGetCompositeClip(pGC);
    register BoxPtr pbox;
    BoxPtr	    pextent;
    int		    extentX1, extentX2, extentY1, extentY2;
    int		    fullX1, fullX2, fullY1, fullY2;
    int		    partX1, partX2, partY1, partY2;
    int		    xorg, yorg;
    int		    n;

    xorg = pDrawable->x;
    yorg = pDrawable->y;

    pextent = REGION_EXTENTS(pGC->pScreen, pClip);
    extentX1 = pextent->x1;
    extentY1 = pextent->y1;
    extentX2 = pextent->x2;
    extentY2 = pextent->y2;
    while (nrect--)
    {
        fullX1 = prect->x + xorg;
        fullY1 = prect->y + yorg;
        fullX2 = fullX1 + (int) prect->width;
        fullY2 = fullY1 + (int) prect->height;
        prect++;

        if (fullX1 < extentX1)
            fullX1 = extentX1;

        if (fullY1 < extentY1)
            fullY1 = extentY1;

        if (fullX2 > extentX2)
            fullX2 = extentX2;

        if (fullY2 > extentY2)
            fullY2 = extentY2;

        if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
            continue;
        n = REGION_NUM_RECTS (pClip);
        if (n == 1)
        {
            rlFill (pDrawable,
                    pGC,
                    fullX1, fullY1, fullX2-fullX1, fullY2-fullY1);
        }
        else
        {
            pbox = REGION_RECTS(pClip);
            /*
             * clip the rectangle to each box in the clip region
             * this is logically equivalent to calling Intersect()
             */
            while(n--)
            {
                partX1 = pbox->x1;
                if (partX1 < fullX1)
                    partX1 = fullX1;
                partY1 = pbox->y1;
                if (partY1 < fullY1)
                    partY1 = fullY1;
                partX2 = pbox->x2;
                if (partX2 > fullX2)
                    partX2 = fullX2;
                partY2 = pbox->y2;
                if (partY2 > fullY2)
                    partY2 = fullY2;

                pbox++;

                if (partX1 < partX2 && partY1 < partY2)
                    rlFill (pDrawable, pGC,
                            partX1, partY1,
                            partX2 - partX1, partY2 - partY1);
            }
        }
    }
}
Пример #18
0
static void
uxa_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int n,
	       DDXPointPtr ppt, int *pwidth, int fSorted)
{
	ScreenPtr screen = pDrawable->pScreen;
	uxa_screen_t *uxa_screen = uxa_get_screen(screen);
	RegionPtr pClip = fbGetCompositeClip(pGC);
	PixmapPtr dst_pixmap;
	BoxPtr pbox;
	int nbox;
	int x1, x2, y;
	int off_x, off_y;

	if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
		int ok = 0;

		if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) {
			ok = glamor_fill_spans_nf(pDrawable,
						  pGC, n, ppt, pwidth, fSorted);
			uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
		}

		if (!ok)
			goto fallback;

		return;
	}

	if (uxa_screen->force_fallback)
		goto fallback;

	if (pGC->fillStyle != FillSolid)
		goto fallback;

	dst_pixmap = uxa_get_offscreen_pixmap(pDrawable, &off_x, &off_y);
	if (!dst_pixmap)
		goto fallback;

	if (uxa_screen->info->check_solid &&
	    !uxa_screen->info->check_solid(pDrawable, pGC->alu, pGC->planemask))
		goto fallback;

	if (!(*uxa_screen->info->prepare_solid) (dst_pixmap,
						 pGC->alu,
						 pGC->planemask,
						 pGC->fgPixel))
		goto fallback;

	while (n--) {
		x1 = ppt->x;
		y = ppt->y;
		x2 = x1 + (int)*pwidth;
		ppt++;
		pwidth++;

		nbox = REGION_NUM_RECTS(pClip);
		pbox = REGION_RECTS(pClip);
		while (nbox--) {
			int X1 = x1, X2 = x2;
			if (X1 < pbox->x1)
				X1 = pbox->x1;

			if (X2 > pbox->x2)
				X2 = pbox->x2;

			if (X2 > X1 && pbox->y1 <= y && pbox->y2 > y)
				(*uxa_screen->info->solid) (dst_pixmap,
							    X1 + off_x, y + off_y,
							    X2 + off_x, y + 1 + off_y);
			pbox++;
		}
	}
	(*uxa_screen->info->done_solid) (dst_pixmap);

	return;

fallback:
	uxa_check_fill_spans(pDrawable, pGC, n, ppt, pwidth, fSorted);
}
Пример #19
0
/* tested with pGC->lineWidth = 0, 1, 2, 4 and opcodes 3 and 6 */
void
rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
                 xRectangle *rects)
{
    RegionRec clip_reg;
    RegionPtr fill_reg;
    int num_clips;
    int cd;
    int lw;
    int i;
    int j;
    int up;
    int down;
    int got_id;
    int dirty_type;
    int post_process;
    int reset_surface;
    xRectangle *regRects;
    xRectangle *r;
    xRectangle *rect1;
    BoxRec box;
    struct image_data id;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                    rdpup_end_update();
                }
            }

            RegionDestroy(fill_reg);
        }
    }

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

    if (reset_surface)
    {
        rdpup_switch_os_surface(-1);
    }
}
Пример #20
0
static void
uxa_poly_fill_rect(DrawablePtr pDrawable,
		   GCPtr pGC, int nrect, xRectangle * prect)
{
	uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen);
	RegionPtr pClip = fbGetCompositeClip(pGC);
	PixmapPtr pPixmap;
	RegionPtr pReg;
	BoxPtr pbox;
	int fullX1, fullX2, fullY1, fullY2;
	int xoff, yoff;
	int xorg, yorg;
	int n;

	if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
		int ok = 0;

		if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) {
			ok = glamor_poly_fill_rect_nf(pDrawable, pGC, nrect, prect);
			uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
		}

		if (!ok)
			uxa_check_poly_fill_rect(pDrawable, pGC, nrect, prect);

		return;
	}

	/* Compute intersection of rects and clip region */
	pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED);
	REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y);
	REGION_INTERSECT(pScreen, pReg, pClip, pReg);

	if (!REGION_NUM_RECTS(pReg))
		goto out;

	if (uxa_screen->force_fallback)
		goto fallback;

	pPixmap = uxa_get_offscreen_pixmap (pDrawable, &xoff, &yoff);
	if (!pPixmap)
		goto fallback;

	/* For ROPs where overlaps don't matter, convert rectangles to region
	 * and call uxa_fill_region_{solid,tiled}.
	 */
	if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) &&
	    (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear ||
	     pGC->alu == GXnoop || pGC->alu == GXcopyInverted ||
	     pGC->alu == GXset)) {
		if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
		     uxa_fill_region_solid(pDrawable, pReg,
					   pGC->fillStyle ==
					   FillSolid ? pGC->fgPixel : pGC->tile.
					   pixel, pGC->planemask, pGC->alu))
		    || (pGC->fillStyle == FillTiled && !pGC->tileIsPixel
			&& uxa_fill_region_tiled(pDrawable, pReg,
						 pGC->tile.pixmap, &pGC->patOrg,
						 pGC->planemask, pGC->alu))) {
			goto out;
		}
	}

	if (pGC->fillStyle != FillSolid &&
	    !(pGC->tileIsPixel && pGC->fillStyle == FillTiled)) {
		goto fallback;
	}

	if (uxa_screen->info->check_solid &&
	    !uxa_screen->info->check_solid(pDrawable, pGC->alu, pGC->planemask)) {
		goto fallback;
	}

	if (!(*uxa_screen->info->prepare_solid) (pPixmap,
						 pGC->alu,
						 pGC->planemask,
						 pGC->fgPixel)) {
fallback:
		uxa_check_poly_fill_rect(pDrawable, pGC, nrect, prect);
		goto out;
	}

	xorg = pDrawable->x;
	yorg = pDrawable->y;

	while (nrect--) {
		fullX1 = prect->x + xorg;
		fullY1 = prect->y + yorg;
		fullX2 = fullX1 + (int)prect->width;
		fullY2 = fullY1 + (int)prect->height;
		prect++;

		n = REGION_NUM_RECTS(pClip);
		pbox = REGION_RECTS(pClip);
		/*
		 * clip the rectangle to each box in the clip region
		 * this is logically equivalent to calling Intersect(),
		 * but rectangles may overlap each other here.
		 */
		while (n--) {
			int x1 = fullX1;
			int x2 = fullX2;
			int y1 = fullY1;
			int y2 = fullY2;

			if (pbox->x1 > x1)
				x1 = pbox->x1;
			if (pbox->x2 < x2)
				x2 = pbox->x2;
			if (pbox->y1 > y1)
				y1 = pbox->y1;
			if (pbox->y2 < y2)
				y2 = pbox->y2;
			pbox++;

			if (x1 >= x2 || y1 >= y2)
				continue;

			(*uxa_screen->info->solid) (pPixmap,
						    x1 + xoff,
						    y1 + yoff,
						    x2 + xoff,
						    y2 + yoff);
		}
	}
	(*uxa_screen->info->done_solid) (pPixmap);

out:
	REGION_UNINIT(pScreen, pReg);
	REGION_DESTROY(pScreen, pReg);
}
Пример #21
0
void rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSegs)
{
	RegionRec clip_reg;
	int cd;
	int i;
	int j;
	int got_id;
	int dirty_type;
	int post_process;
	int reset_surface;
	xSegment *segs;
	BoxRec box;
	struct image_data id;
	WindowPtr pDstWnd;
	PixmapPtr pDstPixmap;
	rdpPixmapRec *pDstPriv;
	rdpPixmapRec *pDirtyPriv;

	LLOGLN(10, ("rdpPolySegment:"));
	LLOGLN(10, ("  nseg %d", nseg));

	segs = 0;

	if (nseg) /* get the rects */
	{
		segs = (xSegment *)g_malloc(nseg * sizeof(xSegment), 0);

		for (i = 0; i < nseg; i++)
		{
			segs[i].x1 = pSegs[i].x1 + pDrawable->x;
			segs[i].y1 = pSegs[i].y1 + pDrawable->y;
			segs[i].x2 = pSegs[i].x2 + pDrawable->x;
			segs[i].y2 = pSegs[i].y2 + pDrawable->y;
		}
	}

	/* do original call */
	rdpPolySegmentOrg(pDrawable, pGC, nseg, pSegs);

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

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

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

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

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

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

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

	RegionInit(&clip_reg, NullBox, 0);
	cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
	LLOGLN(10, ("rdpPolySegment: cd %d", cd));

	if (cd == 1) /* no clip */
	{
		if (segs != 0)
		{
			if (dirty_type != 0)
			{
				RegionUninit(&clip_reg);
				RegionInit(&clip_reg, NullBox, 0);
				RegionAroundSegs(&clip_reg, segs, nseg);
				draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
						pGC->alu, pGC->lineWidth, segs, nseg, 1);
			}
			else if (got_id)
			{
				rdpup_begin_update();
				rdpup_set_fgcolor(pGC->fgPixel);
				rdpup_set_opcode(pGC->alu);
				rdpup_set_pen(0, pGC->lineWidth);

				for (i = 0; i < nseg; i++)
				{
					rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
				}

				rdpup_set_opcode(GXcopy);
				rdpup_end_update();
			}
		}
	}
	else if (cd == 2) /* clip */
	{
		if (segs != 0)
		{
			if (dirty_type != 0)
			{
				draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
						pGC->alu, pGC->lineWidth, segs, nseg, 1);
			}
			else if (got_id)
			{
				rdpup_begin_update();
				rdpup_set_fgcolor(pGC->fgPixel);
				rdpup_set_opcode(pGC->alu);
				rdpup_set_pen(0, pGC->lineWidth);

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

					for (i = 0; i < nseg; i++)
					{
						rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
						LLOGLN(10, ("  %d %d %d %d", segs[i].x1, segs[i].y1,
								segs[i].x2, segs[i].y2));
					}
				}

				rdpup_reset_clip();
				rdpup_set_opcode(GXcopy);
				rdpup_end_update();
			}
		}
	}

	g_free(segs);
	RegionUninit(&clip_reg);

	if (reset_surface)
	{
		rdpup_switch_os_surface(-1);
	}
}
Пример #22
0
void
rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
            int w, int h, int leftPad, int format, char *pBits)
{
    RegionRec clip_reg;
    int cd;
    int j;
    int reset_surface;
    int post_process;
    int got_id;
    int dirty_type;
    BoxRec box;
    struct image_data id;

    WindowPtr pDstWnd;
    PixmapPtr pDstPixmap;
    rdpPixmapRec *pDstPriv;
    rdpPixmapRec *pDirtyPriv;
    RegionRec reg1;
    RegionRec reg2;

    LLOGLN(10, ("rdpPutImage:"));
    LLOGLN(10, ("rdpPutImage: drawable id 0x%x", (int)(pDst->id)));
    LLOGLN(10, ("rdpPutImage: x %d y %d w %d h %d is_window %d", x, y, w, h,
           pDst->type == DRAWABLE_WINDOW));

    /* do original call */
    rdpPutImageOrg(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits);

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

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

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

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

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

                if (g_do_dirty_ons)
                {
                    LLOGLN(10, ("rdpPutImage: getting dirty"));
                    g_screenPriv.is_dirty = 1;
                    pDirtyPriv = &g_screenPriv;
                    dirty_type = RDI_IMGLY;
                }
                else
                {
                    rdpup_get_screen_image_rect(&id);
                    got_id = 1;
                }
            }
        }
    }

    if (!post_process)
    {
        return;
    }

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

    if (cd == 1)
    {
        if (dirty_type != 0)
        {
            box.x1 = pDst->x + x;
            box.y1 = pDst->y + y;
            box.x2 = box.x1 + w;
            box.y2 = box.y1 + h;
            RegionInit(&reg1, &box, 0);
            draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_PUTIMAGE);
            RegionUninit(&reg1);
        }
        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(&reg1, &box, 0);
            RegionInit(&reg2, NullBox, 0);
            RegionCopy(&reg2, &clip_reg);
            RegionIntersect(&reg1, &reg1, &reg2);
            draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type, TAG_PUTIMAGE);
            RegionUninit(&reg1);
            RegionUninit(&reg2);
        }
        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);
    }
}
Пример #23
0
RegionPtr
rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
             GCPtr pGC, int srcx, int srcy, int w, int h,
             int dstx, int dsty, unsigned long bitPlane)
{
    RegionPtr rv;
    RegionRec clip_reg;
    RegionRec box_reg;
    RegionRec reg1;
    RegionRec reg2;
    int cd;
    int num_clips;
    int j;
    int got_id;
    int dirty_type;
    int post_process;
    int reset_surface;
    BoxRec box;
    BoxPtr pbox;
    struct image_data id;
    WindowPtr pDstWnd;
    PixmapPtr pDstPixmap;
    rdpPixmapRec *pDstPriv;
    rdpPixmapRec *pDirtyPriv;

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

    /* do original call */
    rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h,
                         dstx, dsty, bitPlane);

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

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

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

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

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

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

    if (!post_process)
    {
        return rv;
    }

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

    if (cd == 1)
    {
        if (dirty_type != 0)
        {
            box.x1 = pDst->x + dstx;
            box.y1 = pDst->y + dsty;
            box.x2 = box.x1 + w;
            box.y2 = box.y1 + h;
            RegionInit(&reg1, &box, 0);
            draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
            RegionUninit(&reg1);
        }
        else if (got_id)
        {
            rdpup_begin_update();
            rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h);
            rdpup_end_update();
        }
    }
    else if (cd == 2)
    {
        num_clips = REGION_NUM_RECTS(&clip_reg);

        if (num_clips > 0)
        {
            if (dirty_type != 0)
            {
                box.x1 = pDst->x + dstx;
                box.y1 = pDst->y + dsty;
                box.x2 = box.x1 + w;
                box.y2 = box.y1 + h;
                RegionInit(&reg1, &box, 0);
                RegionInit(&reg2, NullBox, 0);
                RegionCopy(&reg2, &clip_reg);
                RegionIntersect(&reg1, &reg1, &reg2);
                draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
                RegionUninit(&reg1);
                RegionUninit(&reg2);
            }
            else if (got_id)
            {
                rdpup_begin_update();
                box.x1 = pDst->x + dstx;
                box.y1 = pDst->y + dsty;
                box.x2 = box.x1 + w;
                box.y2 = box.y1 + h;
                RegionInit(&box_reg, &box, 0);
                RegionIntersect(&clip_reg, &clip_reg, &box_reg);
                num_clips = REGION_NUM_RECTS(&clip_reg);

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

                RegionUninit(&box_reg);
                rdpup_end_update();
            }
        }
    }

    RegionUninit(&clip_reg);

    if (reset_surface)
    {
        rdpup_switch_os_surface(-1);
    }

    return rv;
}
Пример #24
0
/*
 * This function is largely ripped from miPaintWindow, but modified so
 * that the background is not painted to the root window, and so that
 * the backing store is not referenced.
 */
void
PclPaintWindow(
    WindowPtr	pWin,
    RegionPtr	pRegion,
    int		what)
{
    int	status;
    WindowPtr pRoot;
	
#define FUNCTION	0
#define FOREGROUND	1
#define TILE		2
#define FILLSTYLE	3
#define ABSX		4
#define ABSY		5
#define CLIPMASK	6
#define SUBWINDOW	7
#define COUNT_BITS	8

    pointer gcval[7];
    pointer newValues [COUNT_BITS];

    BITS32 gcmask, index, mask;
    RegionRec prgnWin;
    DDXPointRec oldCorner;
    BoxRec box;
    WindowPtr	pBgWin;
    GCPtr pGC;
    register int i;
    register BoxPtr pbox;
    register ScreenPtr pScreen = pWin->drawable.pScreen;
    register xRectangle *prect;
    int numRects;

    gcmask = 0;

    /*
     * We don't want to paint a window that has no place to put the
     * PCL output.
     */
    if( PclGetContextFromWindow( pWin ) == (XpContextPtr)NULL )
      return;
    
    if (what == PW_BACKGROUND)
    {
	switch (pWin->backgroundState) {
	case None:
	    return;
	case ParentRelative:
	    (*pWin->parent->drawable.pScreen->PaintWindowBackground)
	      (pWin->parent, pRegion, what);
	    return;
	case BackgroundPixel:
	    newValues[FOREGROUND] = (pointer)pWin->background.pixel;
	    newValues[FILLSTYLE] = (pointer)FillSolid;
	    gcmask |= GCForeground | GCFillStyle;
	    break;
	case BackgroundPixmap:
	    newValues[TILE] = (pointer)pWin->background.pixmap;
	    newValues[FILLSTYLE] = (pointer)FillTiled;
	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | 
	      GCTileStipYOrigin;
	    break;
	}
    }
    else
    {
	if (pWin->borderIsPixel)
	{
	    newValues[FOREGROUND] = (pointer)pWin->border.pixel;
	    newValues[FILLSTYLE] = (pointer)FillSolid;
	    gcmask |= GCForeground | GCFillStyle;
	}
	else
	{
	    newValues[TILE] = (pointer)pWin->border.pixmap;
	    newValues[FILLSTYLE] = (pointer)FillTiled;
	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin
	      | GCTileStipYOrigin;
	}
    }

    prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(pRegion) *
					 sizeof(xRectangle));
    if (!prect)
	return;

    newValues[FUNCTION] = (pointer)GXcopy;
    gcmask |= GCFunction | GCClipMask;

    i = pScreen->myNum;
    pRoot = WindowTable[i];

    pBgWin = pWin;
    if (what == PW_BORDER)
    {
	while (pBgWin->backgroundState == ParentRelative)
	    pBgWin = pBgWin->parent;
    }

    pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
    if (!pGC)
      {
	  DEALLOCATE_LOCAL(prect);
	  return;
      }
    /*
     * mash the clip list so we can paint the border by
     * mangling the window in place, pretending it
     * spans the entire screen
     */
    if (what == PW_BORDER)
      {
	  prgnWin = pWin->clipList;
	  oldCorner.x = pWin->drawable.x;
	  oldCorner.y = pWin->drawable.y;
	  pWin->drawable.x = pWin->drawable.y = 0;
	  box.x1 = 0;
	  box.y1 = 0;
	  box.x2 = pScreen->width;
	  box.y2 = pScreen->height;
	  REGION_INIT(pScreen, &pWin->clipList, &box, 1);
	  pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
	  newValues[ABSX] = (pointer)(long)pBgWin->drawable.x;
	  newValues[ABSY] = (pointer)(long)pBgWin->drawable.y;
      }
    else
      {
	  newValues[ABSX] = (pointer)0;
	  newValues[ABSY] = (pointer)0;
      }

/*
 * XXX Backing store is turned off for the PCL driver    

    if (pWin->backStorage)
	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC,
	GuaranteeVisBack);
 */

    mask = gcmask;
    gcmask = 0;
    i = 0;
    while (mask) {
    	index = lowbit (mask);
	mask &= ~index;
	switch (index) {
	case GCFunction:
	    if ((pointer)(long) pGC->alu != newValues[FUNCTION]) {
		gcmask |= index;
		gcval[i++] = newValues[FUNCTION];
	    }
	    break;
	case GCTileStipXOrigin:
	    if ((pointer)(long) pGC->patOrg.x != newValues[ABSX]) {
		gcmask |= index;
		gcval[i++] = newValues[ABSX];
	    }
	    break;
	case GCTileStipYOrigin:
	    if ((pointer)(long) pGC->patOrg.y != newValues[ABSY]) {
		gcmask |= index;
		gcval[i++] = newValues[ABSY];
	    }
	    break;
	case GCClipMask:
	    if ((pointer) pGC->clientClipType != (pointer)CT_NONE) {
		gcmask |= index;
		gcval[i++] = (pointer)CT_NONE;
	    }
	    break;
	case GCSubwindowMode:
	    if ((pointer) pGC->subWindowMode != newValues[SUBWINDOW]) {
		gcmask |= index;
		gcval[i++] = newValues[SUBWINDOW];
	    }
	    break;
	case GCTile:
	    if (pGC->tileIsPixel || 
		(pointer) pGC->tile.pixmap != newValues[TILE])
 	    {
		gcmask |= index;
		gcval[i++] = newValues[TILE];
	    }
	    break;
	case GCFillStyle:
	    if ((pointer) pGC->fillStyle != newValues[FILLSTYLE]) {
		gcmask |= index;
		gcval[i++] = newValues[FILLSTYLE];
	    }
	    break;
	case GCForeground:
	    if ((pointer) pGC->fgPixel != newValues[FOREGROUND]) {
		gcmask |= index;
		gcval[i++] = newValues[FOREGROUND];
	    }
	    break;
	}
    }

    if (gcmask)
        DoChangeGC(pGC, gcmask, (XID *)gcval, 1);

    if (pWin->drawable.serialNumber != pGC->serialNumber)
	ValidateGC((DrawablePtr)pWin, pGC);

    numRects = REGION_NUM_RECTS(pRegion);
    pbox = REGION_RECTS(pRegion);
    for (i= numRects; --i >= 0; pbox++, prect++)
    {
	prect->x = pbox->x1 - pWin->drawable.x;
	prect->y = pbox->y1 - pWin->drawable.y;
	prect->width = pbox->x2 - pbox->x1;
	prect->height = pbox->y2 - pbox->y1;
    }
    prect -= numRects;
    (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
    DEALLOCATE_LOCAL(prect);

/*
 * XXX Backing store is turned off for the PCL driver

    if (pWin->backStorage)
	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC,
	GuaranteeNothing);
 */

    if (what == PW_BORDER)
      {
	  REGION_UNINIT(pScreen, &pWin->clipList);
	  pWin->clipList = prgnWin;
	  pWin->drawable.x = oldCorner.x;
	  pWin->drawable.y = oldCorner.y;
	  pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
      }
    FreeScratchGC(pGC);

}
Пример #25
0
/*
 * Create and display a new frame.
 */
Bool
xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
               int newX, int newY, RegionPtr pShape)
{
    WindowPtr pWin = pFrame->win;
    xp_window_changes wc;
    unsigned int mask = 0;
    xp_error err;

    wc.x = newX;
    wc.y = newY;
    wc.width = pFrame->width;
    wc.height = pFrame->height;
    wc.bit_gravity = XP_GRAVITY_NONE;
    mask |= XP_BOUNDS;

    if (pWin->drawable.depth == 8)
    {
        wc.depth = XP_DEPTH_INDEX8;
#if 0
        wc.colormap = xprColormapCallback;
        wc.colormap_data = pScreen;
        mask |= XP_COLORMAP;
#endif
    }
    else if (pWin->drawable.depth == 15)
        wc.depth = XP_DEPTH_RGB555;
    else if (pWin->drawable.depth == 24)
        wc.depth = XP_DEPTH_ARGB8888;
    else
        wc.depth = XP_DEPTH_NIL;
    mask |= XP_DEPTH;

    if (pShape != NULL)
    {
        wc.shape_nrects = REGION_NUM_RECTS(pShape);
        wc.shape_rects = REGION_RECTS(pShape);
        wc.shape_tx = wc.shape_ty = 0;
        mask |= XP_SHAPE;
    }

    err = xp_create_window(mask, &wc, (xp_window_id *) &pFrame->wid);

    if (err != Success)
    {
        return FALSE;
    }

    if (window_hash == NULL)
    {
        window_hash = x_hash_table_new(NULL, NULL, NULL, NULL);
        pthread_mutex_init(&window_hash_mutex, NULL);
    }

    pthread_mutex_lock(&window_hash_mutex);
    x_hash_table_insert(window_hash, pFrame->wid, pFrame);
    pthread_mutex_unlock(&window_hash_mutex);

    xprSetNativeProperty(pFrame);

    return TRUE;
}
Пример #26
0
/* it looks like all the antialias draws go through here */
void
rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
             INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
             INT16 yDst, CARD16 width, CARD16 height)
{
    BoxRec box;
    PictureScreenPtr ps;
    RegionRec reg1;
    RegionRec reg2;
    DrawablePtr p;
    int dirty_type;
    int j;
    int num_clips;
    int post_process;
    int reset_surface;
    int got_id;
    int lx;
    int ly;
    WindowPtr pDstWnd;
    PixmapPtr pDstPixmap;
    rdpPixmapRec *pDstPriv;
    rdpPixmapRec *pDirtyPriv;
    struct image_data id;

    LLOGLN(10, ("rdpComposite:"));
    ps = GetPictureScreen(g_pScreen);
    ps->Composite = g_rdpScreen.Composite;
    ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc,
                  xMask, yMask, xDst, yDst, width, height);
    ps->Composite = rdpComposite;

    p = pDst->pDrawable;

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

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

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

            if (g_do_dirty_os)
            {
                LLOGLN(10, ("rdpComposite: gettig dirty"));
                pDstPriv->is_dirty = 1;
                dirty_type = g_doing_font ? RDI_IMGLL : RDI_IMGLY;
                pDirtyPriv = pDstPriv;

            }
            else
            {
                rdpup_switch_os_surface(pDstPriv->rdpindex);
                reset_surface = 1;
                rdpup_get_pixmap_image_rect(pDstPixmap, &id);
                got_id = 1;
                LLOGLN(10, ("rdpComposite: offscreen"));
            }
        }
    }
    else
    {
        if (p->type == DRAWABLE_WINDOW)
        {
            pDstWnd = (WindowPtr)p;

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

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

    if (!post_process)
    {
        return;
    }

    if (pDst->clientClipType == CT_REGION)
    {
        box.x1 = p->x + xDst;
        box.y1 = p->y + yDst;
        box.x2 = box.x1 + width;
        box.y2 = box.y1 + height;
        RegionInit(&reg1, &box, 0);
        RegionInit(&reg2, NullBox, 0);
        RegionCopy(&reg2, pDst->clientClip);
        lx = p->x + pDst->clipOrigin.x;
        ly = p->y + pDst->clipOrigin.y;
        RegionTranslate(&reg2, lx, ly);
        RegionIntersect(&reg1, &reg1, &reg2);

        if (dirty_type != 0)
        {
            draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
        }
        else if (got_id)
        {
            num_clips = REGION_NUM_RECTS(&reg1);

            if (num_clips > 0)
            {
                rdpup_begin_update();

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

                rdpup_end_update();
            }
        }

        RegionUninit(&reg1);
        RegionUninit(&reg2);
    }
    else
    {
        box.x1 = p->x + xDst;
        box.y1 = p->y + yDst;
        box.x2 = box.x1 + width;
        box.y2 = box.y1 + height;

        if (dirty_type != 0)
        {
            RegionInit(&reg1, &box, 0);
            draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
            RegionUninit(&reg1);
        }
        else if (got_id)
        {
            rdpup_begin_update();
            rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
            rdpup_end_update();
        }
    }

    if (reset_surface)
    {
        rdpup_switch_os_surface(-1);
    }
}
Пример #27
0
void
rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
                xRectangle* prectInit)
{
  int j;
  int cd;
  int num_clips;
  RegionRec clip_reg;
  RegionPtr fill_reg;
  BoxRec box;

  int got_id;
  struct image_data id;
  WindowPtr pDstWnd;
  PixmapPtr pDstPixmap;
  rdpPixmapRec* pDstPriv;

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

  /* make a copy of rects */
  fill_reg = RegionFromRects(nrectFill, prectInit, CT_NONE);

  /* do original call */
  rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit);

  got_id = 0;
  if (pDrawable->type == DRAWABLE_PIXMAP)
  {
    pDstPixmap = (PixmapPtr)pDrawable;
    pDstPriv = GETPIXPRIV(pDstPixmap);
    if (XRDP_IS_OS(pDstPriv))
    {
      rdpup_switch_os_surface(pDstPriv->rdpindex);
      rdpup_get_pixmap_image_rect(pDstPixmap, &id);
      got_id = 1;
    }
  }
  else
  {
    if (pDrawable->type == DRAWABLE_WINDOW)
    {
      pDstWnd = (WindowPtr)pDrawable;
      if (pDstWnd->viewable)
      {
        rdpup_get_screen_image_rect(&id);
        got_id = 1;
      }
    }
  }
  if (!got_id)
  {
    RegionDestroy(fill_reg);
    return;
  }
  RegionTranslate(fill_reg, pDrawable->x, pDrawable->y);
  RegionInit(&clip_reg, NullBox, 0);
  cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
  if (cd == 1) /* no clip */
  {
    rdpup_begin_update();
    if (pGC->fillStyle == 0 && /* solid fill */
        (pGC->alu == GXclear ||
         pGC->alu == GXset ||
         pGC->alu == GXinvert ||
         pGC->alu == GXnoop ||
         pGC->alu == GXand ||
         pGC->alu == GXcopy /*||
         pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
    {
      rdpup_set_fgcolor(pGC->fgPixel);
      rdpup_set_opcode(pGC->alu);
      for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
      {
        box = REGION_RECTS(fill_reg)[j];
        rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
      }
      rdpup_set_opcode(GXcopy);
    }
    else /* non solid fill */
    {
      for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
      {
        box = REGION_RECTS(fill_reg)[j];
        rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
      }
    }
    rdpup_end_update();
  }
  else if (cd == 2) /* clip */
  {
    RegionIntersect(&clip_reg, &clip_reg, fill_reg);
    num_clips = REGION_NUM_RECTS(&clip_reg);
    if (num_clips > 0)
    {
      rdpup_begin_update();
      if (pGC->fillStyle == 0 && /* solid fill */
          (pGC->alu == GXclear ||
           pGC->alu == GXset ||
           pGC->alu == GXinvert ||
           pGC->alu == GXnoop ||
           pGC->alu == GXand ||
           pGC->alu == GXcopy /*||
           pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
      {
        rdpup_set_fgcolor(pGC->fgPixel);
        rdpup_set_opcode(pGC->alu);
        for (j = num_clips - 1; j >= 0; j--)
        {
          box = REGION_RECTS(&clip_reg)[j];
          rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
        }
        rdpup_set_opcode(GXcopy);
      }
      else /* non solid fill */
      {
        for (j = num_clips - 1; j >= 0; j--)
        {
          box = REGION_RECTS(&clip_reg)[j];
          rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
        }
      }
      rdpup_end_update();
    }
  }
  RegionUninit(&clip_reg);
  RegionDestroy(fill_reg);
  rdpup_switch_os_surface(-1);
}
Пример #28
0
void
rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion)
{
    RegionRec reg;
    RegionRec clip;
    int dx;
    int dy;
    int i;
    int j;
    int num_clip_rects;
    int num_reg_rects;
    BoxRec box1;
    BoxRec box2;

    LLOGLN(10, ("in rdpCopyWindow"));
    RegionInit(&reg, NullBox, 0);
    RegionCopy(&reg, pOldRegion);
    g_pScreen->CopyWindow = g_rdpScreen.CopyWindow;
    g_pScreen->CopyWindow(pWin, ptOldOrg, pOldRegion);
    RegionInit(&clip, NullBox, 0);
    RegionCopy(&clip, &pWin->borderClip);
    dx = pWin->drawable.x - ptOldOrg.x;
    dy = pWin->drawable.y - ptOldOrg.y;

    if (g_do_dirty_ons)
    {
        LLOGLN(0, ("rdpCopyWindow: gettig dirty TODO"));
        //draw_item_add_srcblt_region
    }
    else
    {
        rdpup_begin_update();
        num_clip_rects = REGION_NUM_RECTS(&clip);
        num_reg_rects = REGION_NUM_RECTS(&reg);

        /* should maybe sort the rects instead of checking dy < 0 */
        /* If we can depend on the rects going from top to bottom, left
           to right we are ok */
        if (dy < 0 || (dy == 0 && dx < 0))
        {
            for (j = 0; j < num_clip_rects; j++)
            {
                box1 = REGION_RECTS(&clip)[j];
                rdpup_set_clip(box1.x1, box1.y1, box1.x2 - box1.x1, box1.y2 - box1.y1);

                for (i = 0; i < num_reg_rects; i++)
                {
                    box2 = REGION_RECTS(&reg)[i];
                    rdpup_screen_blt(box2.x1 + dx, box2.y1 + dy, box2.x2 - box2.x1,
                                     box2.y2 - box2.y1, box2.x1, box2.y1);
                }
            }
        }
        else
        {
            for (j = num_clip_rects - 1; j >= 0; j--)
            {
                box1 = REGION_RECTS(&clip)[j];
                rdpup_set_clip(box1.x1, box1.y1, box1.x2 - box1.x1, box1.y2 - box1.y1);

                for (i = num_reg_rects - 1; i >= 0; i--)
                {
                    box2 = REGION_RECTS(&reg)[i];
                    rdpup_screen_blt(box2.x1 + dx, box2.y1 + dy, box2.x2 - box2.x1,
                                     box2.y2 - box2.y1, box2.x1, box2.y1);
                }
            }
        }

        rdpup_reset_clip();
        rdpup_end_update();
    }

    RegionUninit(&reg);
    RegionUninit(&clip);
    g_pScreen->CopyWindow = rdpCopyWindow;
}
Пример #29
0
Bool
xglFillLine (DrawablePtr pDrawable,
	     GCPtr       pGC,
	     int	 mode,
	     int	 npt,
	     DDXPointPtr ppt)
{
    RegionPtr	   pClip = pGC->pCompositeClip;
    BoxPtr	   pExtent = REGION_EXTENTS (pGC->pScreen, pClip);
    Bool	   coincidentEndpoints = FALSE;
    Bool	   horizontalAndVertical = TRUE;
    DDXPointPtr    pptTmp;
    int		   nptTmp;
    DDXPointRec    pt;
    xglGeometryPtr pGeometry;

    XGL_SCREEN_PRIV (pGC->pScreen);

    if (npt < 2)
	return TRUE;

    pt = *ppt;

    nptTmp = npt - 1;
    pptTmp = ppt + 1;

    if (mode == CoordModePrevious)
    {
	while (nptTmp--)
	{
	    if (pptTmp->x && pptTmp->y)
		horizontalAndVertical = FALSE;

	    pt.x += pptTmp->x;
	    pt.y += pptTmp->y;

	    pptTmp++;
	}

	if (pt.x == ppt->x && pt.y == ppt->y)
	    coincidentEndpoints = TRUE;
    }
    else
    {
	while (nptTmp--)
	{
	    if (pptTmp->x != pt.x && pptTmp->y != pt.y)
	    {
		horizontalAndVertical = FALSE;
		break;
	    }

	    pt = *pptTmp++;
	}

	if (ppt[npt - 1].x == ppt->x && ppt[npt - 1].y == ppt->y)
	    coincidentEndpoints = TRUE;
    }

    if (horizontalAndVertical)
    {
	BoxPtr pClipBox;
	BoxRec part, full;
	BoxPtr heapBox = NULL;
	BoxRec stackBox[N_STACK_BOX];
	int    size = N_STACK_BOX;
	BoxPtr pBox = stackBox;
	int    nClip, nBox = 0;
	int    dx, dy;

	pt = *ppt;

	ppt++;
	npt--;

	while (npt--)
	{
	    if (mode == CoordModePrevious)
	    {
		dx = ppt->x;
		dy = ppt->y;
	    }
	    else
	    {
		dx = ppt->x - pt.x;
		dy = ppt->y - pt.y;
	    }

	    if (dx)
	    {
		if (dx > 0)
		{
		    full.x1 = pt.x + pDrawable->x;

		    if (npt || coincidentEndpoints)
			full.x2 = full.x1 + dx;
		    else
			full.x2 = full.x1 + dx + 1;
		}
		else
		{
		    full.x2 = pt.x + pDrawable->x + 1;

		    if (npt || coincidentEndpoints)
			full.x1 = full.x2 + dx;
		    else
			full.x1 = full.x2 + dx - 1;
		}

		full.y1 = pt.y + pDrawable->y;
		full.y2 = full.y1 + 1;
	    }
	    else
	    {
		if (dy > 0)
		{
		    full.y1 = pt.y + pDrawable->y;

		    if (npt || coincidentEndpoints)
			full.y2 = full.y1 + dy;
		    else
			full.y2 = full.y1 + dy + 1;
		}
		else
		{
		    full.y2 = pt.y + pDrawable->y + 1;

		    if (npt || coincidentEndpoints)
			full.y1 = full.y2 + dy;
		    else
			full.y1 = full.y2 + dy - 1;
		}

		full.x1 = pt.x + pDrawable->x;
		full.x2 = full.x1 + 1;
	    }

	    pt.x += dx;
	    pt.y += dy;

	    ppt++;

	    if (full.x1 < pExtent->x1)
		full.x1 = pExtent->x1;
	    if (full.y1 < pExtent->y1)
		full.y1 = pExtent->y1;
	    if (full.x2 > pExtent->x2)
		full.x2 = pExtent->x2;
	    if (full.y2 > pExtent->y2)
		full.y2 = pExtent->y2;

	    if (full.x1 >= full.x2 || full.y1 >= full.y2)
		continue;

	    nClip = REGION_NUM_RECTS (pClip);
	    if (nClip == 1)
	    {
		ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
	    }
	    else
	    {
		pClipBox = REGION_RECTS (pClip);
		while (nClip--)
		{
		    part = *pClipBox++;

		    if (part.x1 < full.x1)
			part.x1 = full.x1;
		    if (part.y1 < full.y1)
			part.y1 = full.y1;
		    if (part.x2 > full.x2)
			part.x2 = full.x2;
		    if (part.y2 > full.y2)
			part.y2 = full.y2;

		    if (part.x1 < part.x2 && part.y1 < part.y2)
			ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
		}
	    }
	}

	xglFillBox (pDrawable, pGC,
		    pExtent->x1, pExtent->y1,
		    pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
		    (heapBox) ? heapBox : stackBox, nBox);

	if (heapBox)
	    xfree (heapBox);

	return TRUE;
    }

    if (!pScreenPriv->lines)
	return FALSE;

    if (coincidentEndpoints)
	npt--;

    pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, npt);

    GEOMETRY_ADD_LINE (pGC->pScreen, pGeometry,
		       coincidentEndpoints, mode, npt, ppt);

    if (coincidentEndpoints)
	GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINE_LOOP);
    else
	GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINE_STRIP);

    /* Lines need a 0.5 translate */
    GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);

    GEOMETRY_TRANSLATE (pGeometry, pDrawable->x, pDrawable->y);

    pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);

    if (xglFill (pDrawable, pGC, pGeometry,
		 pExtent->x1, pExtent->y1,
		 pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
		 REGION_RECTS (pGC->pCompositeClip),
		 REGION_NUM_RECTS (pGC->pCompositeClip)))
    {
	xglAddCurrentBitDamage (pDrawable);
	return TRUE;
    }

    return FALSE;
}
Пример #30
0
/* The hw attributes have been set by someone higher up in the call
 * chain.
 */
void
CreatorDoBitblt(DrawablePtr pSrc, DrawablePtr pDst, int alu, RegionPtr prgnDst,
		DDXPointPtr pptSrc, unsigned long planemask)
{
	FFBPtr pFfb = GET_FFB_FROM_SCREEN (pDst->pScreen);
	BoxPtr pboxTmp, pboxNext, pboxBase, pbox;
	DDXPointPtr pptTmp;
	unsigned char *psrcBase, *pdstBase;
	int nbox, widthSrc, widthDst, careful, use_prefetch;
	int psz_shift;

	cfbGetByteWidthAndPointer (pSrc, widthSrc, psrcBase)
	cfbGetByteWidthAndPointer (pDst, widthDst, pdstBase)
	
	careful = ((pSrc == pDst) ||
		  ((pSrc->type == DRAWABLE_WINDOW) &&
		   (pDst->type == DRAWABLE_WINDOW)));
	use_prefetch = (pFfb->use_blkread_prefetch &&
			(psrcBase == (unsigned char *)pFfb->sfb32 ||
			 psrcBase == (unsigned char *)pFfb->sfb8r));

	pbox = REGION_RECTS(prgnDst);
	nbox = REGION_NUM_RECTS(prgnDst);

	pptTmp = pptSrc;
	pboxTmp = pbox;

	FFBLOG(("GCOPY(%d): ", nbox));

	if (pSrc->bitsPerPixel == 8)
		psz_shift = 0;
	else
		psz_shift = 2;

	if (careful && pptSrc->y < pbox->y1) {
		if (pptSrc->x < pbox->x1) {
			/* reverse order of bands and rects in each band */
			pboxTmp=pbox+nbox;
                        pptTmp=pptSrc+nbox;

			while (nbox--){
				pboxTmp--;
				pptTmp--;
				FFBLOG(("[%08x:%08x:%08x:%08x:%08x:%08x] ",
					pptTmp->x, pptTmp->y, pboxTmp->x1, pboxTmp->y1,
					pboxTmp->x2, pboxTmp->y2));
				if (pptTmp->x < pbox->x2) {
					if (use_prefetch) {
						FFBFifo(pFfb, 1);
						pFfb->regs->mer = FFB_MER_EDRA;
						pFfb->rp_active = 1;
						FFBWait(pFfb, pFfb->regs);
					}
					VISmoveImageRL ((psrcBase +
							 ((pptTmp->y + pboxTmp->y2 - pboxTmp->y1 - 1) *
							  widthSrc) +
							 (pptTmp->x << psz_shift)),
				        	        (pdstBase +
							 ((pboxTmp->y2 - 1) * widthDst) +
							 (pboxTmp->x1 << psz_shift)),
					                (pboxTmp->x2 - pboxTmp->x1) << psz_shift,
				        	        (pboxTmp->y2 - pboxTmp->y1),
					                -widthSrc, -widthDst);
				} else {
					if (use_prefetch) {
						FFBFifo(pFfb, 1);
						pFfb->regs->mer = FFB_MER_EIRA;
						pFfb->rp_active = 1;
						FFBWait(pFfb, pFfb->regs);
					}
					VISmoveImageLR ((psrcBase +
							 ((pptTmp->y + pboxTmp->y2 - pboxTmp->y1 - 1) *
							  widthSrc) +
							 (pptTmp->x << psz_shift)),
				        	        (pdstBase +
							 ((pboxTmp->y2 - 1) * widthDst) +
							 (pboxTmp->x1 << psz_shift)),
					                (pboxTmp->x2 - pboxTmp->x1) << psz_shift,
				        	        (pboxTmp->y2 - pboxTmp->y1),
					                -widthSrc, -widthDst);
				}
			}
		} else {
			/* keep ordering in each band, reverse order of bands */
			pboxBase = pboxNext = pbox+nbox-1;

			while (pboxBase >= pbox) {			/* for each band */

				/* find first box in band */
				while (pboxNext >= pbox &&
				       pboxBase->y1 == pboxNext->y1)
					pboxNext--;
		
				pboxTmp = pboxNext+1;			/* first box in band */
				pptTmp = pptSrc + (pboxTmp - pbox);	/* first point in band */
		
				FFBLOG(("[%08x:%08x:%08x:%08x:%08x:%08x] ",
					pptTmp->x, pptTmp->y, pboxTmp->x1, pboxTmp->y1,
					pboxTmp->x2, pboxTmp->y2));
				while (pboxTmp <= pboxBase) {		/* for each box in band */
					if (use_prefetch) {
						FFBFifo(pFfb, 1);
						pFfb->regs->mer = FFB_MER_EIRA;
						pFfb->rp_active = 1;
						FFBWait(pFfb, pFfb->regs);
					}
					VISmoveImageLR ((psrcBase +
							 ((pptTmp->y + pboxTmp->y2 - pboxTmp->y1 - 1) *
							  widthSrc) +
							 (pptTmp->x << psz_shift)),
				        	        (pdstBase +
							 ((pboxTmp->y2 - 1) * widthDst) +
							 (pboxTmp->x1 << psz_shift)),
					                (pboxTmp->x2 - pboxTmp->x1) << psz_shift,
				        	        (pboxTmp->y2 - pboxTmp->y1),
					                -widthSrc, -widthDst);
					++pboxTmp;
					++pptTmp;	
				}
				pboxBase = pboxNext;
			
			}
		}
	} else {
		if (careful && pptSrc->x < pbox->x1) {
			/* reverse order of rects in each band */

			pboxBase = pboxNext = pbox;

			while (pboxBase < pbox+nbox) { /* for each band */

				/* find last box in band */
				while (pboxNext < pbox+nbox &&
				       pboxNext->y1 == pboxBase->y1)
					pboxNext++;

				pboxTmp = pboxNext;			/* last box in band */
				pptTmp = pptSrc + (pboxTmp - pbox);	/* last point in band */

				while (pboxTmp != pboxBase) {		/* for each box in band */
					--pboxTmp;
					--pptTmp;
					FFBLOG(("[%08x:%08x:%08x:%08x:%08x:%08x] ",
						pptTmp->x, pptTmp->y, pboxTmp->x1, pboxTmp->y1,
						pboxTmp->x2, pboxTmp->y2));
					if (pptTmp->x < pbox->x2) {
						if (use_prefetch) {
							FFBFifo(pFfb, 1);
							pFfb->regs->mer = FFB_MER_EDRA;
							pFfb->regs->mer = FFB_MER_EIRA;
							pFfb->rp_active = 1;
						}
						VISmoveImageRL ((psrcBase +
								 (pptTmp->y * widthSrc) +
								 (pptTmp->x << psz_shift)),
						                (pdstBase +
								 (pboxTmp->y1 * widthDst) +
								 (pboxTmp->x1 << psz_shift)),
						                (pboxTmp->x2 - pboxTmp->x1) << psz_shift,
			        	        		(pboxTmp->y2 - pboxTmp->y1),
						                widthSrc, widthDst);
					} else {
						if (use_prefetch) {
							FFBFifo(pFfb, 1);
							pFfb->regs->mer = FFB_MER_EIRA;
							pFfb->rp_active = 1;
							FFBWait(pFfb, pFfb->regs);
						}
						VISmoveImageLR ((psrcBase +
								 (pptTmp->y * widthSrc) +
								 (pptTmp->x << psz_shift)),
						                (pdstBase +
								 (pboxTmp->y1 * widthDst) +
								 (pboxTmp->x1 << psz_shift)),
				                		(pboxTmp->x2 - pboxTmp->x1) << psz_shift,
					        	        (pboxTmp->y2 - pboxTmp->y1),
						                widthSrc, widthDst);
					}
				}
				pboxBase = pboxNext;
			}
		} else {
			while (nbox--) {
				FFBLOG(("[%08x:%08x:%08x:%08x:%08x:%08x] ",
					pptTmp->x, pptTmp->y, pboxTmp->x1, pboxTmp->y1,
					pboxTmp->x2, pboxTmp->y2));
				if (use_prefetch) {
					FFBFifo(pFfb, 1);
					pFfb->regs->mer = FFB_MER_EIRA;
					pFfb->rp_active = 1;
					FFBWait(pFfb, pFfb->regs);
				}
				VISmoveImageLR ((psrcBase +
						 (pptTmp->y * widthSrc) +
						 (pptTmp->x << psz_shift)),
				                (pdstBase +
						 (pboxTmp->y1 * widthDst) +
						 (pboxTmp->x1 << psz_shift)),
				                (pboxTmp->x2 - pboxTmp->x1) << psz_shift,
			        	        (pboxTmp->y2 - pboxTmp->y1),
				                widthSrc, widthDst);
				pboxTmp++;
				pptTmp++;
			}
		}
	}
	if (use_prefetch) {
		FFBFifo(pFfb, 1);
		pFfb->regs->mer = FFB_MER_DRA;
		pFfb->rp_active = 1;
		FFBWait(pFfb, pFfb->regs);
	}
	FFBLOG(("done\n"));
}