예제 #1
0
static void
RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
                  INT16 xSrc, INT16 ySrc, INT16  xMask, INT16  yMask,
                  INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    WindowPtr dstWin;

    dstWin  = (pDst->pDrawable->type  == DRAWABLE_WINDOW) ?
        (WindowPtr)pDst->pDrawable  :  NULL;

    // SCREEN_UNWRAP(ps, Composite);
    ps->Composite = SCREENREC(pScreen)->Composite;

    ps->Composite(op, pSrc, pMask, pDst,
                  xSrc, ySrc, xMask, yMask,
                  xDst, yDst, width, height);

    if (dstWin  && IsFramedWindow(dstWin)) {
        RootlessDamageRect(dstWin, xDst, yDst, width, height);
    }

    ps->Composite = RootlessComposite;
    // SCREEN_WRAP(ps, Composite);
}
예제 #2
0
파일: dmxpict.c 프로젝트: Agnesa/xserver
/** Fill a rectangle on the appropriate screen by combining the color
 *  with the dest picture in the area specified by the list of
 *  rectangles.  For a complete description see the protocol document of
 *  the RENDER library. */
void
dmxCompositeRects(CARD8 op,
                  PicturePtr pDst,
                  xRenderColor * color, int nRect, xRectangle *rects)
{
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pDst);

    DMX_UNWRAP(CompositeRects, dmxScreen, ps);
#if 0
    if (ps->CompositeRects)
        ps->CompositeRects(op, pDst, color, nRect, rects);
#endif

    /* CompositeRects on back-end server */
    if (pPictPriv->pict) {
        XRenderFillRectangles(dmxScreen->beDisplay,
                              op,
                              pPictPriv->pict,
                              (XRenderColor *) color,
                              (XRectangle *) rects, nRect);
        dmxSync(dmxScreen, FALSE);
    }

    DMX_WRAP(CompositeRects, dmxCompositeRects, dmxScreen, ps);
}
예제 #3
0
파일: rdpdraw.c 프로젝트: mehulsbhatt/xrdp
void
rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
          PictFormatPtr maskFormat,
          INT16 xSrc, INT16 ySrc, int nlists, GlyphListPtr lists,
          GlyphPtr* glyphs)
{
  PictureScreenPtr ps;
  int index;

  LLOGLN(10, ("rdpGlyphs:"));
  LLOGLN(10, ("rdpGlyphs: nlists %d len %d", nlists, lists->len));
  rdpup_set_hints(1, 1);
  for (index = 0; index < lists->len; index++)
  {
    LLOGLN(10, ("  index %d size %d refcnt %d width %d height %d",
           index, (int)(glyphs[index]->size), (int)(glyphs[index]->refcnt),
           glyphs[index]->info.width, glyphs[index]->info.height));
  }
  ps = GetPictureScreen(g_pScreen);
  ps->Glyphs = g_rdpScreen.Glyphs;
  ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc,
             nlists, lists, glyphs);
  ps->Glyphs = rdpGlyphs;
  rdpup_set_hints(0, 1);
  LLOGLN(10, ("rdpGlyphs: out"));
}
예제 #4
0
파일: dmxpict.c 프로젝트: Agnesa/xserver
/** Destroy the picture's list of clip rectangles. */
void
dmxDestroyPictureClip(PicturePtr pPicture)
{
    ScreenPtr pScreen = pPicture->pDrawable->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);

    DMX_UNWRAP(DestroyPictureClip, dmxScreen, ps);
#if 1
    if (ps->DestroyPictureClip)
        ps->DestroyPictureClip(pPicture);
#endif

    /* Destroy picture clip rects on back-end server */
    if (pPictPriv->pict) {
        XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
                                        pPictPriv->pict, 0, 0, NULL, 0);
        dmxSync(dmxScreen, FALSE);
    }
    else {
        /* FIXME: Handle destroying clip region when offscreen */
    }

    DMX_WRAP(DestroyPictureClip, dmxDestroyPictureClip, dmxScreen, ps);
}
예제 #5
0
/** Change the picture's list of clip rectangles. */
int dmxChangePictureClip(PicturePtr pPicture, int clipType,
			 pointer value, int n)
{
    ScreenPtr         pScreen   = pPicture->pDrawable->pScreen;
    DMXScreenInfo    *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr  ps        = GetPictureScreen(pScreen);
    dmxPictPrivPtr    pPictPriv = DMX_GET_PICT_PRIV(pPicture);

    DMX_UNWRAP(ChangePictureClip, dmxScreen, ps);
#if 1
    if (ps->ChangePictureClip)
	ps->ChangePictureClip(pPicture, clipType, value, n);
#endif

    /* Change picture clip rects on back-end server */
    if (pPictPriv->pict) {
	/* The clip has already been changed into a region by the mi
	 * routine called above.
	 */
	if (pPicture->clientClip) {
	    RegionPtr   pClip = pPicture->clientClip;
	    BoxPtr      pBox  = REGION_RECTS(pClip);
	    int         nBox  = REGION_NUM_RECTS(pClip);
	    XRectangle *pRects;
	    XRectangle *pRect;
	    int         nRects;

	    nRects = nBox;
	    pRects = pRect = xalloc(nRects * sizeof(*pRect));

	    while (nBox--) {
		pRect->x      = pBox->x1;
		pRect->y      = pBox->y1;
		pRect->width  = pBox->x2 - pBox->x1;
		pRect->height = pBox->y2 - pBox->y1;
		pBox++;
		pRect++;
	    }

	    XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
					    pPictPriv->pict,
					    0, 0,
					    pRects,
					    nRects);
	    xfree(pRects);
	} else {
	    XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
					    pPictPriv->pict,
					    0, 0, NULL, 0);
	}
	dmxSync(dmxScreen, FALSE);
    } else {
	/* FIXME: Handle saving clip region when offscreen */
    }

    DMX_WRAP(ChangePictureClip, dmxChangePictureClip, dmxScreen, ps);
    
    return Success;
}
예제 #6
0
/** Change the attributes of the pictures.  If the picture has not yet
 *  been created due to lazy window creation, save the mask so that it
 *  can be used to appropriately initialize the picture's attributes
 *  when it is created later. */
void dmxChangePicture(PicturePtr pPicture, Mask mask)
{
    ScreenPtr         pScreen   = pPicture->pDrawable->pScreen;
    DMXScreenInfo    *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr  ps        = GetPictureScreen(pScreen);
    dmxPictPrivPtr    pPictPriv = DMX_GET_PICT_PRIV(pPicture);

    DMX_UNWRAP(ChangePicture, dmxScreen, ps);
#if 1
    if (ps->ChangePicture)
	ps->ChangePicture(pPicture, mask);
#endif

    /* Picture attribute changes are handled in ValidatePicture */
    pPictPriv->savedMask |= mask;

    DMX_WRAP(ChangePicture, dmxChangePicture, dmxScreen, ps);
}
예제 #7
0
void
ExaCheckAddTraps(PicturePtr pPicture,
                 INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
{
    ScreenPtr pScreen = pPicture->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);

    EXA_PRE_FALLBACK(pScreen);

    EXA_FALLBACK(("to pict %p (%c)\n",
                  exaDrawableLocation(pPicture->pDrawable)));
    exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
    swap(pExaScr, ps, AddTraps);
    ps->AddTraps(pPicture, x_off, y_off, ntrap, traps);
    swap(pExaScr, ps, AddTraps);
    exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK(pScreen);
}
예제 #8
0
/** Destroy a picture.  This function calls the wrapped function that
 *  frees the resources in the DMX server associated with this
 *  picture. */
void dmxDestroyPicture(PicturePtr pPicture)
{
    ScreenPtr         pScreen   = pPicture->pDrawable->pScreen;
    DMXScreenInfo    *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr  ps        = GetPictureScreen(pScreen);

    DMX_UNWRAP(DestroyPicture, dmxScreen, ps);

    /* Destroy picture on back-end server */
    if (dmxBEFreePicture(pPicture))
	dmxSync(dmxScreen, FALSE);

#if 1
    if (ps->DestroyPicture)
	ps->DestroyPicture(pPicture);
#endif
    DMX_WRAP(DestroyPicture, dmxDestroyPicture, dmxScreen, ps);
}
예제 #9
0
/** Composite a picture on the appropriate screen by combining the
 *  specified rectangle of the transformed src and mask operands with
 *  the specified rectangle of the dst using op as the compositing
 *  operator.  For a complete description see the protocol document of
 *  the RENDER library. */
void dmxComposite(CARD8 op,
		  PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
		  INT16 xSrc, INT16 ySrc,
		  INT16 xMask, INT16 yMask,
		  INT16 xDst, INT16 yDst,
		  CARD16 width, CARD16 height)
{
    ScreenPtr         pScreen   = pDst->pDrawable->pScreen;
    DMXScreenInfo    *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr  ps        = GetPictureScreen(pScreen);
    dmxPictPrivPtr    pSrcPriv  = DMX_GET_PICT_PRIV(pSrc);
    dmxPictPrivPtr    pMaskPriv = NULL;
    dmxPictPrivPtr    pDstPriv  = DMX_GET_PICT_PRIV(pDst);

    if (pMask) pMaskPriv = DMX_GET_PICT_PRIV(pMask);

    DMX_UNWRAP(Composite, dmxScreen, ps);
#if 0
    if (ps->Composite)
	ps->Composite(op, pSrc, pMask, pDst,
		      xSrc, ySrc, xMask, yMask, xDst, yDst,
		      width, height);
#endif

    /* Composite on back-end server */
    if (pSrcPriv->pict && pDstPriv->pict &&
	((pMaskPriv && pMaskPriv->pict) || !pMaskPriv)) {
	XRenderComposite(dmxScreen->beDisplay,
			 op,
			 pSrcPriv->pict,
			 pMaskPriv ? pMaskPriv->pict : None,
			 pDstPriv->pict,
			 xSrc, ySrc,
			 xMask, yMask,
			 xDst, yDst,
			 width, height);
	dmxSync(dmxScreen, FALSE);
    }


    DMX_WRAP(Composite, dmxComposite, dmxScreen, ps);
}
예제 #10
0
static void
rdpCompositeOrg(PictureScreenPtr ps, rdpPtr dev,
                CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
                INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
                INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
    ps->Composite = dev->Composite;
    ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
                  xDst, yDst, width, height);
    ps->Composite = rdpComposite;
}
예제 #11
0
static void
rdpGlyphsOrg(PictureScreenPtr ps, rdpPtr dev,
             CARD8 op, PicturePtr pSrc, PicturePtr pDst,
             PictFormatPtr maskFormat,
             INT16 xSrc, INT16 ySrc, int nlists, GlyphListPtr lists,
             GlyphPtr *glyphs)
{
    ps->Glyphs = dev->Glyphs;
    ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc,
               nlists, lists, glyphs);
    ps->Glyphs = rdpGlyphs;
}
예제 #12
0
static void
RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
               PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
               int nlist, GlyphListPtr list, GlyphPtr *glyphs)
{
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    int x, y;
    int n;
    GlyphPtr glyph;
    WindowPtr dstWin;

    dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
        (WindowPtr)pDst->pDrawable  :  NULL;

    //SCREEN_UNWRAP(ps, Glyphs);
    ps->Glyphs = SCREENREC(pScreen)->Glyphs;
    ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
    ps->Glyphs = RootlessGlyphs;
    //SCREEN_WRAP(ps, Glyphs);

    if (dstWin && IsFramedWindow(dstWin)) {
        x = xSrc;
        y = ySrc;
        while (nlist--) {
            x += list->xOff;
            y += list->yOff;
            n = list->len;
            while (n--) {
                glyph = *glyphs++;
                RootlessDamageRect(dstWin,
                                   x - glyph->info.x, y - glyph->info.y,
                                   glyph->info.width, glyph->info.height);
                x += glyph->info.xOff;
                y += glyph->info.yOff;
            }
            list++;
        }
    }
}
예제 #13
0
/** Composite a triangle fan on the appropriate screen.  For a complete
 *  description see the protocol document of the RENDER library. */
void dmxTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
	       PictFormatPtr maskFormat,
	       INT16 xSrc, INT16 ySrc,
	       int npoint, xPointFixed *points)
{
    ScreenPtr         pScreen   = pDst->pDrawable->pScreen;
    DMXScreenInfo    *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr  ps        = GetPictureScreen(pScreen);
    dmxPictPrivPtr    pSrcPriv  = DMX_GET_PICT_PRIV(pSrc);
    dmxPictPrivPtr    pDstPriv  = DMX_GET_PICT_PRIV(pDst);

    DMX_UNWRAP(TriFan, dmxScreen, ps);
#if 0
    if (ps->TriFan)
	ps->TriFan(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points);
#endif

    /* Draw trapezoids on back-end server */
    if (pDstPriv->pict) {
	XRenderPictFormat *pFormat;

	pFormat = dmxFindFormat(dmxScreen, maskFormat);
	if (!pFormat) {
	    /* FIXME: Error! */
	}

	XRenderCompositeTriFan(dmxScreen->beDisplay,
			       op,
			       pSrcPriv->pict,
			       pDstPriv->pict,
			       pFormat,
			       xSrc, ySrc,
			       (XPointFixed *)points,
			       npoint);
	dmxSync(dmxScreen, FALSE);
    }

    DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps);
}
예제 #14
0
/** Create a picture.  This function handles the CreatePicture
 *  unwrapping/wrapping and calls dmxDoCreatePicture to actually create
 *  the picture on the appropriate screen.  */
int dmxCreatePicture(PicturePtr pPicture)
{
    ScreenPtr         pScreen   = pPicture->pDrawable->pScreen;
    DMXScreenInfo    *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr  ps        = GetPictureScreen(pScreen);
    dmxPictPrivPtr    pPictPriv = DMX_GET_PICT_PRIV(pPicture);
    int               ret       = Success;

    DMX_UNWRAP(CreatePicture, dmxScreen, ps);
#if 1
    if (ps->CreatePicture)
	ret = ps->CreatePicture(pPicture);
#endif

    /* Create picture on back-end server */
    pPictPriv->pict      = dmxDoCreatePicture(pPicture);
    pPictPriv->savedMask = 0;

    DMX_WRAP(CreatePicture, dmxCreatePicture, dmxScreen, ps);

    return ret;
}
예제 #15
0
파일: rdpdraw.c 프로젝트: mehulsbhatt/xrdp
/* it looks like all the antialias draws go through here */
void
rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
             INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
             INT16 yDst, CARD16 width, CARD16 height)
{
  BoxRec box;
  PictureScreenPtr ps;
  RegionRec reg1;
  RegionRec reg2;
  DrawablePtr p;
  int j;
  int num_clips;
  int got_id;
  WindowPtr pDstWnd;
  PixmapPtr pDstPixmap;
  rdpPixmapRec* pDstPriv;
  struct image_data id;

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

  p = pDst->pDrawable;

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

  if (pDst->clientClipType == CT_REGION)
  {
    box.x1 = p->x + xDst;
    box.y1 = p->y + yDst;
    box.x2 = box.x1 + width;
    box.y2 = box.y1 + height;
    RegionInit(&reg1, &box, 0);
    RegionInit(&reg2, NullBox, 0);
    RegionCopy(&reg2, pDst->clientClip);
    RegionTranslate(&reg2, p->x + pDst->clipOrigin.x,
                      p->y + pDst->clipOrigin.y);
    RegionIntersect(&reg1, &reg1, &reg2);
    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;
    rdpup_begin_update();
    rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
    rdpup_end_update();
  }
  rdpup_switch_os_surface(-1);
}
예제 #16
0
파일: dmxpict.c 프로젝트: Agnesa/xserver
/** Validate the picture's attributes before rendering to it.  Update
 *  any picture attributes that have been changed by one of the higher
 *  layers. */
void
dmxValidatePicture(PicturePtr pPicture, Mask mask)
{
    ScreenPtr pScreen = pPicture->pDrawable->pScreen;
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);

    DMX_UNWRAP(ValidatePicture, dmxScreen, ps);

    /* Change picture attributes on back-end server */
    if (pPictPriv->pict) {
        XRenderPictureAttributes attribs;

        if (mask & CPRepeat) {
            attribs.repeat = pPicture->repeatType;
        }
        if (mask & CPAlphaMap) {
            if (pPicture->alphaMap) {
                dmxPictPrivPtr pAlphaPriv;

                pAlphaPriv = DMX_GET_PICT_PRIV(pPicture->alphaMap);
                if (pAlphaPriv->pict) {
                    attribs.alpha_map = pAlphaPriv->pict;
                }
                else {
                    /* FIXME: alpha picture drawable has not been created?? */
                    return;     /* or should this be: attribs.alpha_map = None; */
                }
            }
            else {
                attribs.alpha_map = None;
            }
        }
        if (mask & CPAlphaXOrigin)
            attribs.alpha_x_origin = pPicture->alphaOrigin.x;
        if (mask & CPAlphaYOrigin)
            attribs.alpha_y_origin = pPicture->alphaOrigin.y;
        if (mask & CPClipXOrigin)
            attribs.clip_x_origin = pPicture->clipOrigin.x;
        if (mask & CPClipYOrigin)
            attribs.clip_y_origin = pPicture->clipOrigin.y;
        if (mask & CPClipMask)
            mask &= ~CPClipMask;        /* Handled in ChangePictureClip */
        if (mask & CPGraphicsExposure)
            attribs.graphics_exposures = pPicture->graphicsExposures;
        if (mask & CPSubwindowMode)
            attribs.subwindow_mode = pPicture->subWindowMode;
        if (mask & CPPolyEdge)
            attribs.poly_edge = pPicture->polyEdge;
        if (mask & CPPolyMode)
            attribs.poly_mode = pPicture->polyMode;
        if (mask & CPComponentAlpha)
            attribs.component_alpha = pPicture->componentAlpha;

        XRenderChangePicture(dmxScreen->beDisplay, pPictPriv->pict,
                             mask, &attribs);
        dmxSync(dmxScreen, FALSE);
    }
    else {
        pPictPriv->savedMask |= mask;
    }

#if 1
    if (ps->ValidatePicture)
        ps->ValidatePicture(pPicture, mask);
#endif

    DMX_WRAP(ValidatePicture, dmxValidatePicture, dmxScreen, ps);
}
예제 #17
0
void
ExaCheckComposite(CARD8 op,
                  PicturePtr pSrc,
                  PicturePtr pMask,
                  PicturePtr pDst,
                  INT16 xSrc,
                  INT16 ySrc,
                  INT16 xMask,
                  INT16 yMask,
                  INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);

    EXA_PRE_FALLBACK(pScreen);

    if (pExaScr->prepare_access_reg) {
        if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc,
                                    ySrc, xMask, yMask, xDst, yDst, width,
                                    height))
            goto out_no_clip;
    }
    else {

        /* We need to prepare access to any separate alpha maps first,
         * in case the driver doesn't support EXA_PREPARE_AUX*,
         * in which case EXA_PREPARE_SRC may be used for moving them out.
         */

        if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
            exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
        if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
            exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
        if (pDst->alphaMap && pDst->alphaMap->pDrawable)
            exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);

        exaPrepareAccess(pDst->pDrawable, EXA_PREPARE_DEST);

        EXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst));

        if (pSrc->pDrawable != NULL)
            exaPrepareAccess(pSrc->pDrawable, EXA_PREPARE_SRC);
        if (pMask && pMask->pDrawable != NULL)
            exaPrepareAccess(pMask->pDrawable, EXA_PREPARE_MASK);
    }

    swap(pExaScr, ps, Composite);
    ps->Composite(op,
                  pSrc,
                  pMask,
                  pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
    swap(pExaScr, ps, Composite);
    if (pMask && pMask->pDrawable != NULL)
        exaFinishAccess(pMask->pDrawable, EXA_PREPARE_MASK);
    if (pSrc->pDrawable != NULL)
        exaFinishAccess(pSrc->pDrawable, EXA_PREPARE_SRC);
    exaFinishAccess(pDst->pDrawable, EXA_PREPARE_DEST);
    if (pDst->alphaMap && pDst->alphaMap->pDrawable)
        exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
    if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
        exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
    if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
        exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);

 out_no_clip:
    EXA_POST_FALLBACK(pScreen);
}
예제 #18
0
static void
RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
               PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
               int nlist, GlyphListPtr list, GlyphPtr *glyphs)
{
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    int x, y;
    int n;
    GlyphPtr glyph;
    WindowPtr srcWin, dstWin;

    srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
             (WindowPtr)pSrc->pDrawable  :  NULL;
    dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
             (WindowPtr)pDst->pDrawable  :  NULL;

    if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin);
    if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin);

    //SCREEN_UNWRAP(ps, Glyphs);
    ps->Glyphs = SCREENREC(pScreen)->Glyphs;
    ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
    ps->Glyphs = RootlessGlyphs;
    //SCREEN_WRAP(ps, Glyphs);

    if (dstWin && IsFramedWindow(dstWin)) {
        x = xSrc;
        y = ySrc;

        while (nlist--) {
            x += list->xOff;
            y += list->yOff;
            n = list->len;

            /* Calling DamageRect for the bounding box of each glyph is
               inefficient. So compute the union of all glyphs in a list
               and damage that. */

            if (n > 0) {
                BoxRec box;

                glyph = *glyphs++;

                box.x1 = x - glyph->info.x;
                box.y1 = y - glyph->info.y;
                box.x2 = box.x1 + glyph->info.width;
                box.y2 = box.y1 + glyph->info.height;

                x += glyph->info.xOff;
                y += glyph->info.yOff;

                while (--n > 0) {
                    short x1, y1, x2, y2;

                    glyph = *glyphs++;

                    x1 = x - glyph->info.x;
                    y1 = y - glyph->info.y;
                    x2 = x1 + glyph->info.width;
                    y2 = y1 + glyph->info.height;

                    box.x1 = max (box.x1, x1);
                    box.y1 = max (box.y1, y1);
                    box.x2 = max (box.x2, x2);
                    box.y2 = max (box.y2, y2);

                    x += glyph->info.xOff;
                    y += glyph->info.yOff;
                }

                RootlessDamageBox(dstWin, &box);
            }
            list++;
        }
    }
}
예제 #19
0
파일: rdpdraw.c 프로젝트: piccolo/xrdp
/* 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);
    }
}