⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mibstore.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 5 页
字号:
 *	Perform a PutImage, routing output to backing-store as needed. * * Results: *	None. * * Side Effects: * *----------------------------------------------------------------------- */static voidmiBSPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits)    DrawablePtr	  pDrawable;    GCPtr   	  pGC;    int		  depth;    int	    	  x;    int	    	  y;    int	    	  w;    int	    	  h;    int		  leftPad;    int	    	  format;    char    	  *pBits;{    SETUP_BACKING (pDrawable, pGC);    PROLOGUE(pGC);    (*pGC->ops->PutImage)(pDrawable, pGC,		     depth, x, y, w, h, leftPad, format, pBits);    (*pBackingGC->ops->PutImage)(pBackingDrawable, pBackingGC,		     depth, x - pBackingStore->x, y - pBackingStore->y,		     w, h, leftPad, format, pBits);    EPILOGUE (pGC);}/*- *----------------------------------------------------------------------- * miBSDoCopy -- *	Perform a CopyArea or CopyPlane within a window that has backing *	store enabled. * * Results: *	TRUE if the copy was performed or FALSE if a regular one should *	be done. * * Side Effects: *	Things are copied (no s***!) * * Notes: *	The idea here is to form two regions that cover the source box. *	One contains the exposed rectangles while the other contains *	the obscured ones. An array of <box, drawable> pairs is then *	formed where the <box> indicates the area to be copied and the *	<drawable> indicates from where it is to be copied (exposed regions *	come from the screen while obscured ones come from the backing *	pixmap). The array 'sequence' is then filled with the indices of *	the pairs in the order in which they should be copied to prevent *	things from getting screwed up. A call is also made through the *	backingGC to take care of any copying into the backing pixmap. * *----------------------------------------------------------------------- */static BoolmiBSDoCopy(pWin, pGC, srcx, srcy, w, h, dstx, dsty, plane, copyProc, ppRgn)    WindowPtr	  pWin;	    	    /* Window being scrolled */    GCPtr   	  pGC;	    	    /* GC we're called through */    int	    	  srcx;	    	    /* X of source rectangle */    int	    	  srcy;	    	    /* Y of source rectangle */    int	    	  w;	    	    /* Width of source rectangle */    int	    	  h;	    	    /* Height of source rectangle */    int	    	  dstx;	    	    /* X of destination rectangle */    int	    	  dsty;	    	    /* Y of destination rectangle */    unsigned long plane;    	    /* Plane to copy (0 for CopyArea) */    RegionPtr  	  (*copyProc)();    /* Procedure to call to perform the copy */    RegionPtr	  *ppRgn;	    /* resultant Graphics Expose region */{    RegionPtr 	    	pRgnExp;    /* Exposed region */    RegionPtr	  	pRgnObs;    /* Obscured region */    BoxRec	  	box;	    /* Source box (screen coord) */    struct BoxDraw {	BoxPtr	  	pBox;	    	/* Source box */	enum {	    win, pix	}   	  	source;	    	/* Place from which to copy */    }	    	  	*boxes;	    /* Array of box/drawable pairs covering				     * source box. */    int  	  	*sequence;  /* Sequence of boxes to move */    register int  	i, j, k, l, y;    register BoxPtr	pBox;    int	    	  	dx, dy, nrects;    Bool    	  	graphicsExposures;    RegionPtr	  	(*pixCopyProc)();    int			numRectsExp, numRectsObs;    BoxPtr		pBoxExp, pBoxObs;    SETUP_BACKING (pWin, pGC);    /*     * Create a region of exposed boxes in pRgnExp.     */    box.x1 = srcx + pWin->drawable.x;    box.x2 = box.x1 + w;    box.y1 = srcy + pWin->drawable.y;    box.y2 = box.y1 + h;        pRgnExp = REGION_CREATE(pGC->pScreen, &box, 1);    REGION_INTERSECT(pGC->pScreen, pRgnExp, pRgnExp, &pWin->clipList);    pRgnObs = REGION_CREATE(pGC->pScreen, NULL, 1);    REGION_INVERSE( pGC->pScreen, pRgnObs, pRgnExp, &box);    /*     * Translate regions into window coordinates for proper calls     * to the copyProc, then make sure none of the obscured region sticks     * into invalid areas of the backing pixmap.     */    REGION_TRANSLATE(pGC->pScreen, pRgnExp,				      -pWin->drawable.x,				      -pWin->drawable.y);    REGION_TRANSLATE(pGC->pScreen, pRgnObs,				      -pWin->drawable.x,				      -pWin->drawable.y);    REGION_INTERSECT(pGC->pScreen, pRgnObs, pRgnObs, &pBackingStore->SavedRegion);    /*     * If the obscured region is empty, there's no point being fancy.     */    if (!REGION_NOTEMPTY(pGC->pScreen, pRgnObs))    {	REGION_DESTROY(pGC->pScreen, pRgnExp);	REGION_DESTROY(pGC->pScreen, pRgnObs);	return (FALSE);    }    numRectsExp = REGION_NUM_RECTS(pRgnExp);    pBoxExp = REGION_RECTS(pRgnExp);    pBoxObs = REGION_RECTS(pRgnObs);    numRectsObs = REGION_NUM_RECTS(pRgnObs);    nrects = numRectsExp + numRectsObs;        boxes = (struct BoxDraw *)ALLOCATE_LOCAL(nrects * sizeof(struct BoxDraw));    sequence = (int *) ALLOCATE_LOCAL(nrects * sizeof(int));    *ppRgn = NULL;    if (!boxes || !sequence)    {	if (sequence) DEALLOCATE_LOCAL(sequence);	if (boxes) DEALLOCATE_LOCAL(boxes);	REGION_DESTROY(pGC->pScreen, pRgnExp);	REGION_DESTROY(pGC->pScreen, pRgnObs);	return(TRUE);    }    /*     * Order the boxes in the two regions so we know from which drawable     * to copy which box, storing the result in the boxes array     */    for (i = 0, j = 0, k = 0;	 (i < numRectsExp) && (j < numRectsObs);	 k++)    {	if (pBoxExp[i].y1 < pBoxObs[j].y1)	{	    boxes[k].pBox = &pBoxExp[i];	    boxes[k].source = win;	    i++;	}	else if ((pBoxObs[j].y1 < pBoxExp[i].y1) ||		 (pBoxObs[j].x1 < pBoxExp[i].x1))	{	    boxes[k].pBox = &pBoxObs[j];	    boxes[k].source = pix;	    j++;	}	else	{	    boxes[k].pBox = &pBoxExp[i];	    boxes[k].source = win;	    i++;	}    }    /*     * Catch any leftover boxes from either region (note that only     * one can have leftover boxes...)     */    if (i != numRectsExp)    {	do	{	    boxes[k].pBox = &pBoxExp[i];	    boxes[k].source = win;	    i++;	    k++;	} while (i < numRectsExp);    }    else    {	do	{	    boxes[k].pBox = &pBoxObs[j];	    boxes[k].source = pix;	    j++;	    k++;	} while (j < numRectsObs);    }        if (dsty <= srcy)    {	/*	 * Scroll up or vertically stationary, so vertical order is ok.	 */	if (dstx <= srcx)	{	    /*	     * Scroll left or horizontally stationary, so horizontal order	     * is ok as well.	     */	    for (i = 0; i < nrects; i++)	    {		sequence[i] = i;	    }	}	else	{	    /*	     * Scroll right. Need to reverse the rectangles within each	     * band.	     */	    for (i = 0, j = 1, k = 0;		 i < nrects;		 j = i + 1, k = i)	    {		y = boxes[i].pBox->y1;		while ((j < nrects) && (boxes[j].pBox->y1 == y))		{		    j++;		}		for (j--; j >= k; j--, i++)		{		    sequence[i] = j;		}	    }	}    }    else    {	/*	 * Scroll down. Must reverse vertical banding, at least.	 */	if (dstx < srcx)	{	    /*	     * Scroll left. Horizontal order is ok.	     */	    for (i = nrects - 1, j = i - 1, k = i, l = 0;		 i >= 0;		 j = i - 1, k = i)	    {		/*		 * Find extent of current horizontal band, then reverse		 * the order of the whole band.		 */		y = boxes[i].pBox->y1;		while ((j >= 0) && (boxes[j].pBox->y1 == y))		{		    j--;		}		for (j++; j <= k; j++, i--, l++)		{		    sequence[l] = j;		}	    }	}	else	{	    /*	     * Scroll right or horizontal stationary.	     * Reverse horizontal order as well (if stationary, horizontal	     * order can be swapped without penalty and this is faster             * to compute).	     */	    for (i = 0, j = nrects - 1; i < nrects; i++, j--)	    {		sequence[i] = j;	    }	}    }	        /*     * XXX: To avoid getting multiple NoExpose events from this operation,     * we turn OFF graphicsExposures in the gc and deal with any uncopied     * areas later, if there's something not in backing-store.     */    graphicsExposures = pGC->graphicsExposures;    pGC->graphicsExposures = FALSE;        dx = dstx - srcx;    dy = dsty - srcy;    /*     * Figure out which copy procedure to use from the backing GC. Note we     * must do this because some implementations (sun's, e.g.) have     * pBackingGC a fake GC with the real one below it, thus the devPriv for     * pBackingGC won't be what the output library expects.     */    if (plane != 0)    {	pixCopyProc = pBackingGC->ops->CopyPlane;    }    else    {	pixCopyProc = pBackingGC->ops->CopyArea;    }        for (i = 0; i < nrects; i++)    {	pBox = boxes[sequence[i]].pBox;		/*	 * If we're copying from the pixmap, we need to place its contents	 * onto the screen before scrolling the pixmap itself. If we're copying	 * from the window, we need to copy its contents into the pixmap before	 * we scroll the window itself.	 */	if (boxes[sequence[i]].source == pix)	{	    (void) (* copyProc) (pBackingDrawable, pWin, pGC,			  pBox->x1 - pBackingStore->x,			  pBox->y1 - pBackingStore->y,			  pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,			  pBox->x1 + dx, pBox->y1 + dy, plane);	    (void) (* pixCopyProc) (pBackingDrawable, pBackingDrawable, pBackingGC,			     pBox->x1 - pBackingStore->x,			     pBox->y1 - pBackingStore->y,			     pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,			     pBox->x1 + dx - pBackingStore->x,			     pBox->y1 + dy - pBackingStore->y, plane);	}	else	{	    (void) (* pixCopyProc) (pWin, pBackingDrawable, pBackingGC,			     pBox->x1, pBox->y1,			     pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,			     pBox->x1 + dx - pBackingStore->x,			     pBox->y1 + dy - pBackingStore->y, plane);	    (void) (* copyProc) (pWin, pWin, pGC,			  pBox->x1, pBox->y1,			  pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,			  pBox->x1 + dx, pBox->y1 + dy, plane);	}    }    DEALLOCATE_LOCAL(sequence);    DEALLOCATE_LOCAL(boxes);    pGC->graphicsExposures = graphicsExposures;    /*     * Form union of rgnExp and rgnObs and see if covers entire area     * to be copied.  Store the resultant region for miBSCopyArea     * to return to dispatch which will send the appropriate expose     * events.     */    REGION_UNION(pGC->pScreen, pRgnExp, pRgnExp, pRgnObs);    box.x1 = srcx;    box.x2 = srcx + w;    box.y1 = srcy;    box.y2 = srcy + h;    if (RECT_IN_REGION(pGC->pScreen, pRgnExp, &box) == rgnIN)    {	REGION_EMPTY(pGC->pScreen, pRgnExp);    }    else    {	REGION_INVERSE( pGC->pScreen, pRgnExp, pRgnExp, &box);	REGION_TRANSLATE( pGC->pScreen, pRgnExp,					   dx + pWin->drawable.x, 					   dy + pWin->drawable.y);	REGION_INTERSECT( pGC->pScreen, pRgnObs, pRgnExp, &pWin->clipList);	(*pWin->drawable.pScreen->PaintWindowBackground) (pWin,						pRgnObs, PW_BACKGROUND);	REGION_TRANSLATE( pGC->pScreen, pRgnExp,					   -pWin->drawable.x, 					   -pWin->drawable.y);	miBSClearBackingRegion (pWin, pRgnExp);    }    if (graphicsExposures)	*ppRgn = pRgnExp;    else	REGION_DESTROY(pGC->pScreen, pRgnExp);    REGION_DESTROY(pGC->pScreen, pRgnObs);    return (TRUE);}/*- *----------------------------------------------------------------------- * miBSCopyArea -- *	Perform a CopyArea from the source to the destination, extracting *	from the source's backing-store and storing into the destination's *	backing-store without messing anything up. If the source and *	destination are different, there's not too much to worry about: *	we can just issue several calls to the regular CopyArea function. * * Results: *	None. * * Side Effects: * *----------------------------------------------------------------------- */static RegionPtrmiBSCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty)    DrawablePtr	  pSrc;    DrawablePtr	  pDst;    GCPtr   	  pGC;    int	    	  srcx;    int	    	  srcy;    int	    	  w;    int	    	  h;    int	    	  dstx;    int	    	  dsty;{    BoxPtr	pExtents;    long	dx, dy;    int		bsrcx, bsrcy, bw, bh, bdstx, bdsty;    RegionPtr	pixExposed = 0, winExposed = 0;    SETUP_BACKING(pDst, pGC);    PROLOGUE(pGC);    if ((pSrc != pDst) ||	(!miBSDoCopy((WindowPtr)pSrc, pGC, srcx, srcy, w, h, dstx, dsty,		     (unsigned long) 0, pGC->ops->CopyArea, &winExposed)))    {	/*	 * always copy to the backing store first, miBSDoCopy	 * returns FALSE if the *source* region is disjoint	 * from the backing store saved region.  So, copying	 * *to* the backing store is always safe	 */	if (pGC->clientClipType != CT_PIXMAP)	{	    /*	     * adjust srcx, srcy, w, h, dstx, dsty to be clipped to	     * the backing store.  An unnecessary optimisation,	     * but a useful one when GetSpans is slow.	     */	    pExtents = REGION_EXTENTS(pDst->pScreen,				      (RegionPtr)pBackingGC->clientClip);	    bsrcx = srcx;	    bsrcy = srcy;	    bw = w;	    bh = h;	    bdstx = dstx;	    bdsty = dsty;	    dx = pExtents->x1 - bdstx;	    if (dx > 0)	    {		bsrcx += dx;		bdstx += dx;		bw -= dx;	    }	    dy = pExtents->y1 - bdsty;	    if (dy > 0)	    {		bsrcy += dy;		bdsty += dy;		bh -= dy;	    }	    dx = (bdstx + bw) - pExtents->x2;	    if (dx > 0)		bw -= dx;	    dy = (bdsty + bh) - pExtents->y2;	    if (dy > 0)		bh -= dy;	    if (bw > 0 && bh > 0)		pixExposed = (* pBackingGC->ops->CopyArea) (pSrc, 			    pBackingDrawable, pBackingGC, 			    bsrcx, bsrcy, bw, bh, bdstx - pBackingStore->x,			    bdsty - pBackingStore->y);	}	else	    pixExposed = (* pBackingGC->ops->CopyArea) (pSrc, 			    pBackingDrawable, pBackingGC,			    srcx, srcy, w, h,			    dstx - pBackingStore->x, dsty - pBackingStore->y);	winExposed = (* pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);    }    /*     * compute the composite graphics exposure region     */    if (winExposed)    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -