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

📄 mibstore.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $XConsortium: mibstore.c,v 5.63 94/10/21 20:25:08 dpw Exp $ *//***********************************************************Copyright (c) 1987  X ConsortiumPermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THEX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER INAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR INCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.Except as contained in this notice, the name of the X Consortium shall not beused in advertising or otherwise to promote the sale, use or other dealingsin this Software without prior written authorization from the X Consortium.Copyright 1987 by the Regents of the University of California                        All Rights ReservedPermission to use, copy, modify, and distribute this software and itsdocumentation for any purpose and without fee is hereby granted, providedthat the above copyright notice appear in all copies and that both thatcopyright notice and this permission notice appear in supportingdocumentation, and that the name X Consortium not be used in advertising or publicitypertaining to distribution of the software without specific, written priorpermission.  The University of California makes no representations about the suitabilityof this software for any purpose.  It is provided "as is" without express orimplied warranty.******************************************************************/#define NEED_EVENTS#include "X.h"#include "Xmd.h"#include "Xproto.h"#include "misc.h"#include "regionstr.h"#include "scrnintstr.h"#include "gcstruct.h"#include "extnsionst.h"#include "windowstr.h"#include "pixmapstr.h"#include "fontstruct.h"#include "dixfontstr.h"#include "dixstruct.h"		/* For requestingClient */#include "mi.h"#include "mibstorest.h"/* * When the server fails to allocate a backing store pixmap, if you want * it to dynamically retry to allocate backing store on every subsequent * graphics op, you can enable BSEAGER; otherwise, backing store will be * disabled on the window until it is unmapped and then remapped. *//* #define BSEAGER *//*- * NOTES ON USAGE: * * The functions in this file implement a machine-independent backing-store * scheme. To use it, the output library must do the following: *	- Provide a SaveAreas function that takes a destination pixmap, a *	    region of the areas to save (in the pixmap's coordinate system) *	    and the screen origin of the region. It should copy the areas from *	    the screen into the pixmap. *	- Provide a RestoreAreas function that takes a source pixmap, a region *	    of the areas to restore (in the screen's coordinate system) and the *	    origin of the pixmap on the screen. It should copy the areas from *	    the pixmap into the screen. *	- Provide a SetClipmaskRgn function that takes a gc and a region *	    and merges the region into any CT_PIXMAP client clip that *	    is specified in the GC.  This routine is only needed if *	    miValidateBackingStore will see CT_PIXMAP clip lists; not *	    true for any of the sample servers (which convert the PIXMAP *	    clip lists into CT_REGION clip lists; an expensive but simple *	    to code option). *	- The function placed in a window's ClearToBackground vector must call *	    pScreen->ClearBackingStore with the window, followed by *	    the window-relative x and y coordinates, followed by the width and *	    height of the area to be cleared, followed by the generateExposures *	    flag. This has been taken care of in miClearToBackground. *	- Whatever determines GraphicsExpose events for the CopyArea and *	    CopyPlane requests should call pWin->backStorage->ExposeCopy *	    with the source and destination drawables, the GC used, a source- *	    window-relative region of exposed areas, the source and destination *	    coordinates and the bitplane copied, if CopyPlane, or 0, if *	    CopyArea. * * JUSTIFICATION *    This is a cross between saving everything and just saving the * obscued areas (as in Pike's layers.)  This method has the advantage * of only doing each output operation once per pixel, visible or * invisible, and avoids having to do all the crufty storage * management of keeping several separate rectangles.  Since the * ddx layer ouput primitives are required to draw through clipping * rectangles anyway, sending multiple drawing requests for each of * several rectangles isn't necessary.  (Of course, it could be argued * that the ddx routines should just take one rectangle each and * get called multiple times, but that would make taking advantage of * smart hardware harder, and probably be slower as well.) */#define SETUP_BACKING_TERSE(pGC) \    miBSGCPtr	pGCPrivate = (miBSGCPtr)(pGC)->devPrivates[miBSGCIndex].ptr; \    GCFuncs	*oldFuncs = pGC->funcs;#define SETUP_BACKING(pDrawable,pGC) \    miBSWindowPtr pBackingStore = \    	(miBSWindowPtr)((WindowPtr)(pDrawable))->backStorage; \    DrawablePtr	  pBackingDrawable = (DrawablePtr) \        pBackingStore->pBackingPixmap; \    SETUP_BACKING_TERSE(pGC) \    GCPtr	pBackingGC = pGCPrivate->pBackingGC;#define PROLOGUE(pGC) { \    pGC->ops = pGCPrivate->wrapOps;\    pGC->funcs = pGCPrivate->wrapFuncs; \    }#define EPILOGUE(pGC) { \    pGCPrivate->wrapOps = (pGC)->ops; \    (pGC)->ops = &miBSGCOps; \    (pGC)->funcs = oldFuncs; \    }   static void	    miCreateBSPixmap();static void	    miDestroyBSPixmap();static void	    miTileVirtualBS();static void	    miBSAllocate(), miBSFree();static Bool	    miBSCreateGCPrivate	();static void	    miBSClearBackingRegion ();#define MoreCopy0 ;#define MoreCopy2 *dstCopy++ = *srcCopy++; *dstCopy++ = *srcCopy++;#define MoreCopy4 MoreCopy2 MoreCopy2#define copyData(src,dst,n,morecopy) \{ \    register short *srcCopy = (short *)(src); \    register short *dstCopy = (short *)(dst); \    register int i; \    register int bsx = pBackingStore->x; \    register int bsy = pBackingStore->y; \    for (i = n; --i >= 0; ) \    { \	*dstCopy++ = *srcCopy++ - bsx; \	*dstCopy++ = *srcCopy++ - bsy; \	morecopy \    } \}#define copyPoints(src,dst,n,mode) \if (mode == CoordModeOrigin) \{ \    copyData(src,dst,n,MoreCopy0); \} \else \{ \    memmove((char *)(dst), (char *)(src), (n) << 2); \    *((short *)(dst)) -= pBackingStore->x; \    *((short *)(dst) + 1) -= pBackingStore->y; \}/* * wrappers for screen funcs */static int  miBSScreenIndex;static unsigned long miBSGeneration = 0;static Bool	    miBSCloseScreen();static void	    miBSGetImage();static void	    miBSGetSpans();static Bool	    miBSChangeWindowAttributes();static Bool	    miBSCreateGC();static Bool	    miBSDestroyWindow();/* * backing store screen functions */static void	    miBSSaveDoomedAreas();static RegionPtr    miBSRestoreAreas();static void	    miBSExposeCopy();static RegionPtr    miBSTranslateBackingStore(), miBSClearBackingStore();static void	    miBSDrawGuarantee();/* * wrapper vectors for GC funcs and ops */static int  miBSGCIndex;static void miBSValidateGC (),	miBSCopyGC (),	    miBSDestroyGC();static void miBSChangeGC();static void miBSChangeClip(),	miBSDestroyClip(),  miBSCopyClip();static GCFuncs	miBSGCFuncs = {    miBSValidateGC,    miBSChangeGC,    miBSCopyGC,    miBSDestroyGC,    miBSChangeClip,    miBSDestroyClip,    miBSCopyClip,};static void	    miBSFillSpans(),	miBSSetSpans(),	    miBSPutImage();static RegionPtr    miBSCopyArea(),	miBSCopyPlane();static void	    miBSPolyPoint(),	miBSPolylines(),    miBSPolySegment();static void	    miBSPolyRectangle(),miBSPolyArc(),	    miBSFillPolygon();static void	    miBSPolyFillRect(),	miBSPolyFillArc();static int	    miBSPolyText8(),	miBSPolyText16();static void	    miBSImageText8(),	miBSImageText16();static void	    miBSImageGlyphBlt(),miBSPolyGlyphBlt();static void	    miBSPushPixels();#ifdef NEED_LINEHELPERstatic void	    miBSLineHelper();#endifstatic GCOps miBSGCOps = {    miBSFillSpans,	miBSSetSpans,	    miBSPutImage,	    miBSCopyArea,	miBSCopyPlane,	    miBSPolyPoint,    miBSPolylines,	miBSPolySegment,    miBSPolyRectangle,    miBSPolyArc,	miBSFillPolygon,    miBSPolyFillRect,    miBSPolyFillArc,	miBSPolyText8,	    miBSPolyText16,    miBSImageText8,	miBSImageText16,    miBSImageGlyphBlt,    miBSPolyGlyphBlt,	miBSPushPixels#ifdef NEED_LINEHELPER    , miBSLineHelper#endif};#define FUNC_PROLOGUE(pGC, pPriv) \    ((pGC)->funcs = pPriv->wrapFuncs),\    ((pGC)->ops = pPriv->wrapOps)#define FUNC_EPILOGUE(pGC, pPriv) \    ((pGC)->funcs = &miBSGCFuncs),\    ((pGC)->ops = &miBSGCOps)/* * every GC in the server is initially wrapped with these * "cheap" functions.  This allocates no memory and is used * to discover GCs used with windows which have backing * store enabled */static void miBSCheapValidateGC(),  miBSCheapCopyGC(),	miBSCheapDestroyGC();static void miBSCheapChangeGC ();static void miBSCheapChangeClip(),  miBSCheapDestroyClip();static void miBSCheapCopyClip();static GCFuncs miBSCheapGCFuncs = {    miBSCheapValidateGC,    miBSCheapChangeGC,    miBSCheapCopyGC,    miBSCheapDestroyGC,    miBSCheapChangeClip,    miBSCheapDestroyClip,    miBSCheapCopyClip,};#define CHEAP_FUNC_PROLOGUE(pGC) \    ((pGC)->funcs = (GCFuncs *) (pGC)->devPrivates[miBSGCIndex].ptr)#define CHEAP_FUNC_EPILOGUE(pGC) \    ((pGC)->funcs = &miBSCheapGCFuncs)/* * called from device screen initialization proc.  Gets a GCPrivateIndex * and wraps appropriate per-screen functions */voidmiInitializeBackingStore (pScreen, funcs)    ScreenPtr	pScreen;    miBSFuncPtr	funcs;{    miBSScreenPtr    pScreenPriv;    if (miBSGeneration != serverGeneration)    {	miBSScreenIndex = AllocateScreenPrivateIndex ();	if (miBSScreenIndex < 0)	    return;	miBSGCIndex = AllocateGCPrivateIndex ();	miBSGeneration = serverGeneration;    }    if (!AllocateGCPrivate(pScreen, miBSGCIndex, 0))	return;    pScreenPriv = (miBSScreenPtr) xalloc (sizeof (miBSScreenRec));    if (!pScreenPriv)	return;    pScreenPriv->CloseScreen = pScreen->CloseScreen;    pScreenPriv->GetImage = pScreen->GetImage;    pScreenPriv->GetSpans = pScreen->GetSpans;    pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;    pScreenPriv->CreateGC = pScreen->CreateGC;    pScreenPriv->DestroyWindow = pScreen->DestroyWindow;    pScreenPriv->funcs = funcs;    pScreen->CloseScreen = miBSCloseScreen;    pScreen->GetImage = miBSGetImage;    pScreen->GetSpans = miBSGetSpans;    pScreen->ChangeWindowAttributes = miBSChangeWindowAttributes;    pScreen->CreateGC = miBSCreateGC;    pScreen->DestroyWindow = miBSDestroyWindow;    pScreen->SaveDoomedAreas = miBSSaveDoomedAreas;    pScreen->RestoreAreas = miBSRestoreAreas;    pScreen->ExposeCopy = miBSExposeCopy;    pScreen->TranslateBackingStore = miBSTranslateBackingStore;    pScreen->ClearBackingStore = miBSClearBackingStore;    pScreen->DrawGuarantee = miBSDrawGuarantee;    pScreen->devPrivates[miBSScreenIndex].ptr = (pointer) pScreenPriv;}/* * Screen function wrappers */#define SCREEN_PROLOGUE(pScreen, field)\  ((pScreen)->field = \   ((miBSScreenPtr) \    (pScreen)->devPrivates[miBSScreenIndex].ptr)->field)#define SCREEN_EPILOGUE(pScreen, field, wrapper)\    ((pScreen)->field = wrapper)/* * CloseScreen wrapper -- unwrap everything, free the private data * and call the wrapped function */static BoolmiBSCloseScreen (i, pScreen)    int		i;    ScreenPtr	pScreen;{    miBSScreenPtr   pScreenPriv;    pScreenPriv = (miBSScreenPtr) pScreen->devPrivates[miBSScreenIndex].ptr;    pScreen->CloseScreen = pScreenPriv->CloseScreen;    pScreen->GetImage = pScreenPriv->GetImage;    pScreen->GetSpans = pScreenPriv->GetSpans;    pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;    pScreen->CreateGC = pScreenPriv->CreateGC;    xfree ((pointer) pScreenPriv);    return (*pScreen->CloseScreen) (i, pScreen);}static void miBSFillVirtualBits();static voidmiBSGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)    DrawablePtr	    pDrawable;    int		    sx, sy, w, h;    unsigned int    format;    unsigned long   planemask;    char	    *pdstLine;{    ScreenPtr		    pScreen = pDrawable->pScreen;    BoxRec		    bounds;    unsigned char	    depth;        SCREEN_PROLOGUE (pScreen, GetImage);    if (pDrawable->type != DRAWABLE_PIXMAP &&	((WindowPtr) pDrawable)->visibility != VisibilityUnobscured)    {	PixmapPtr	pPixmap;	miBSWindowPtr	pWindowPriv;	GCPtr		pGC;	WindowPtr	pWin, pSrcWin;	int		xoff, yoff;	RegionRec	Remaining;	RegionRec	Border;	RegionRec	Inside;	BoxPtr		pBox;	int		n;	pWin = (WindowPtr) pDrawable;	pPixmap = 0;	depth = pDrawable->depth;	bounds.x1 = sx + pDrawable->x;	bounds.y1 = sy + pDrawable->y;	bounds.x2 = bounds.x1 + w;	bounds.y2 = bounds.y1 + h;	REGION_INIT(pScreen, &Remaining, &bounds, 0);	for (;;) 	{	    bounds.x1 = sx + pDrawable->x - pWin->drawable.x;	    bounds.y1 = sy + pDrawable->y - pWin->drawable.y;	    bounds.x2 = bounds.x1 + w;	    bounds.y2 = bounds.y1 + h;	    if (pWin->viewable && pWin->backStorage &&		pWin->drawable.depth == depth &&	        (RECT_IN_REGION(pScreen, &(pWindowPriv =		    (miBSWindowPtr) pWin->backStorage)->SavedRegion,		    &bounds) != rgnOUT ||		 RECT_IN_REGION(pScreen, &Remaining,		  REGION_EXTENTS(pScreen, &pWin->borderSize)) != rgnOUT))	    {		if (!pPixmap)		{		    XID	subWindowMode = IncludeInferiors;		    int	x, y;		    pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, depth);		    if (!pPixmap)			goto punt;		    pGC = GetScratchGC (depth, pScreen);		    if (!pGC)		    {			(*pScreen->DestroyPixmap) (pPixmap);			goto punt;		    }		    ChangeGC (pGC, GCSubwindowMode, &subWindowMode);		    ValidateGC ((DrawablePtr)pPixmap, pGC);		    REGION_INIT(pScreen, &Border, NullBox, 0);		    REGION_INIT(pScreen, &Inside, NullBox, 0);		    pSrcWin = (WindowPtr) pDrawable;		    x = sx;		    y = sy;		    if (pSrcWin->parent)		    {			x += pSrcWin->origin.x;			y += pSrcWin->origin.y;			pSrcWin = pSrcWin->parent;		    }		    (*pGC->ops->CopyArea) ((DrawablePtr)pSrcWin, 					    (DrawablePtr)pPixmap, pGC,					    x, y, w, h,					    0, 0);		    REGION_SUBTRACT(pScreen, &Remaining, &Remaining,				    &((WindowPtr) pDrawable)->borderClip);		}		REGION_INTERSECT(pScreen, &Inside, &Remaining, &pWin->winSize);		REGION_TRANSLATE(pScreen, &Inside,					     -pWin->drawable.x, 					     -pWin->drawable.y);		REGION_INTERSECT(pScreen, &Inside, &Inside,				 &pWindowPriv->SavedRegion);		/* offset of sub-window in GetImage pixmap */		xoff = pWin->drawable.x - pDrawable->x - sx;		yoff = pWin->drawable.y - pDrawable->y - sy;		if (REGION_NUM_RECTS(&Inside) > 0)		{		    switch (pWindowPriv->status)		    {		    case StatusContents:			pBox = REGION_RECTS(&Inside);			for (n = REGION_NUM_RECTS(&Inside); --n >= 0;)			{			    (*pGC->ops->CopyArea) (				(DrawablePtr)pWindowPriv->pBackingPixmap,						   (DrawablePtr)pPixmap, pGC,						   pBox->x1 - pWindowPriv->x,						   pBox->y1 - pWindowPriv->y,						   pBox->x2 - pBox->x1,						   pBox->y2 - pBox->y1,						   pBox->x1 + xoff,						   pBox->y1 + yoff);			    ++pBox;			}			break;		    case StatusVirtual:		    case StatusVDirty:			if (pWindowPriv->backgroundState == BackgroundPixmap ||			    pWindowPriv->backgroundState == BackgroundPixel)			miBSFillVirtualBits ((DrawablePtr) pPixmap, pGC, &Inside,					    xoff, yoff,					    (int) pWindowPriv->backgroundState,					    pWindowPriv->background, ~0L);			break;		    }

⌨️ 快捷键说明

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