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

📄 colormap.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 5 页
字号:
        return (TRUE);    }    else if (planes > dplanes)    {	return (FALSE);    }    /* General case count pixels * 2 ^ planes cells to be allocated */    /* make room for new pixels */    ent = pentFirst;    /* first try for contiguous planes, since it's fastest */    for (mask = (((Pixel)1) << planes) - 1, base = 1, dplanes -= (planes - 1);         --dplanes >= 0;         mask += mask, base += base)    {        ppix = pixels;        found = 0;        pixel = 0;        entries = pmap->pVisual->ColormapEntries - mask;        while (pixel < entries)	{    	    save = pixel;    	    maxp = pixel + mask + base;    	    /* check if all are free */    	    while (pixel != maxp && ent[pixel].refcnt == 0)    	        pixel += base;	    if (pixel == maxp)		{		    /* this one works */		    *ppix++ = save;		    found++;		    if (found == count)		    {			/* found enough, allocate them all */			while (--count >= 0)			{			    pixel = pixels[count];			    maxp = pixel + mask;			    while (1)			    {				ent[pixel].refcnt = AllocPrivate;				ent[pixel].fShared = FALSE;				if (pixel == maxp)				    break;				pixel += base;				*ppix++ = pixel;			    }			}			*pMask = mask;			return (TRUE);		    }		}    	    pixel = save + 1;    	    if (pixel & mask)    	        pixel += mask;        }    }    dplanes = pmap->pVisual->nplanes;    if (contig || planes == 1 || dplanes < 3)	return (FALSE);    /* this will be very slow for large maps, need a better algorithm */    /*       we can generate the smallest and largest numbers that fits in dplanes       bits and contain exactly planes bits set as follows. First, we need to       check that it is possible to generate such a mask at all.       (Non-contiguous masks need one more bit than contiguous masks). Then       the smallest such mask consists of the rightmost planes-1 bits set, then       a zero, then a one in position planes + 1. The formula is         (3 << (planes-1)) -1       The largest such masks consists of the leftmost planes-1 bits set, then       a zero, then a one bit in position dplanes-planes-1. If dplanes is       smaller than 32 (the number of bits in a word) then the formula is:         (1<<dplanes) - (1<<(dplanes-planes+1) + (1<<dplanes-planes-1)       If dplanes = 32, then we can't calculate (1<<dplanes) and we have       to use:         ( (1<<(planes-1)) - 1) << (dplanes-planes+1) + (1<<(dplanes-planes-1))	  	  << Thank you, Loretta>>>    */    finalmask =        (((((Pixel)1)<<(planes-1)) - 1) << (dplanes-planes+1)) +	  (((Pixel)1)<<(dplanes-planes-1));    for (mask = (((Pixel)3) << (planes -1)) - 1; mask <= finalmask; mask++)    {        /* next 3 magic statements count number of ones (HAKMEM #169) */        pixel = (mask >> 1) & 033333333333;        pixel = mask - pixel - ((pixel >> 1) & 033333333333);        if ((((pixel + (pixel >> 3)) & 030707070707) % 077) != planes)    	    continue;        ppix = pixels;        found = 0;        entries = pmap->pVisual->ColormapEntries - mask;        base = lowbit (mask);        for (pixel = 0; pixel < entries; pixel++)	{	    if (pixel & mask)	        continue;	    maxp = 0;	    /* check if all are free */	    while (ent[pixel + maxp].refcnt == 0)	    {		GetNextBitsOrBreak(maxp, mask, base);	    }	    if ((maxp < mask) || (ent[pixel + mask].refcnt != 0))		continue;	    /* this one works */	    *ppix++ = pixel;	    found++;	    if (found < count)		continue;	    /* found enough, allocate them all */	    while (--count >= 0)	    {		pixel = (pixels)[count];		maxp = 0;		while (1)		{		    ent[pixel + maxp].refcnt = AllocPrivate;		    ent[pixel + maxp].fShared = FALSE;		    GetNextBitsOrBreak(maxp, mask, base);		    *ppix++ = pixel + maxp;		}	    }	    *pMask = mask;	    return (TRUE);	}    }    return (FALSE);}static BoolAllocShared (pmap, ppix, c, r, g, b, rmask, gmask, bmask, ppixFirst)    ColormapPtr	pmap;    Pixel	*ppix;    int		c, r, g, b;    Pixel	rmask, gmask, bmask;    Pixel	*ppixFirst;	/* First of the client's new pixels */{    Pixel	*pptr, *cptr;    int		npix, z, npixClientNew, npixShared;    Pixel	basemask, base, bits, common;    SHAREDCOLOR *pshared, **ppshared, **psharedList;    npixClientNew = c << (r + g + b);    npixShared = (c << r) + (c << g) + (c << b);    psharedList = (SHAREDCOLOR **)ALLOCATE_LOCAL(npixShared *						 sizeof(SHAREDCOLOR *));    if (!psharedList)	return FALSE;    ppshared = psharedList;    for (z = npixShared; --z >= 0; )    {	if (!(ppshared[z] = (SHAREDCOLOR *)xalloc(sizeof(SHAREDCOLOR))))	{	    for (z++ ; z < npixShared; z++)		xfree(ppshared[z]);	    return FALSE;	}    }    for(pptr = ppix, npix = c; --npix >= 0; pptr++)    {	basemask = ~(gmask | bmask);	common = *pptr & basemask;	if (rmask)	{	    bits = 0;	    base = lowbit (rmask);	    while(1)	    {		pshared = *ppshared++;		pshared->refcnt = 1 << (g + b);		for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)		{		    if ((*cptr & basemask) == (common | bits))		    {			pmap->red[*cptr].fShared = TRUE;			pmap->red[*cptr].co.shco.red = pshared;		    }		}		GetNextBitsOrBreak(bits, rmask, base);	    }	}	else	{	    pshared = *ppshared++;	    pshared->refcnt = 1 << (g + b);	    for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)	    {		if ((*cptr & basemask) == common)		{		    pmap->red[*cptr].fShared = TRUE;		    pmap->red[*cptr].co.shco.red = pshared;		}	    }	}	basemask = ~(rmask | bmask);	common = *pptr & basemask;	if (gmask)	{	    bits = 0;	    base = lowbit (gmask);	    while(1)	    {		pshared = *ppshared++;		pshared->refcnt = 1 << (r + b);		for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)		{		    if ((*cptr & basemask) == (common | bits))		    {			pmap->red[*cptr].co.shco.green = pshared;		    }		}		GetNextBitsOrBreak(bits, gmask, base);	    }	}	else	{	    pshared = *ppshared++;	    pshared->refcnt = 1 << (g + b);	    for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)	    {		if ((*cptr & basemask) == common)		{		    pmap->red[*cptr].co.shco.green = pshared;		}	    }	}	basemask = ~(rmask | gmask);	common = *pptr & basemask;	if (bmask)	{	    bits = 0;	    base = lowbit (bmask);	    while(1)	    {		pshared = *ppshared++;		pshared->refcnt = 1 << (r + g);		for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)		{		    if ((*cptr & basemask) == (common | bits))		    {			pmap->red[*cptr].co.shco.blue = pshared;		    }		}		GetNextBitsOrBreak(bits, bmask, base);	    }	}	else	{	    pshared = *ppshared++;	    pshared->refcnt = 1 << (g + b);	    for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)	    {		if ((*cptr & basemask) == common)		{		    pmap->red[*cptr].co.shco.blue = pshared;		}	    }	}    }    DEALLOCATE_LOCAL(psharedList);    return TRUE;}/* Free colors and/or cells (probably slow for large numbers) */intFreeColors (pmap, client, count, pixels, mask)    ColormapPtr	pmap;    int		client, count;    Pixel	*pixels;    Pixel	mask;{    int		rval, result, class;    Pixel	rmask;    class = pmap->class;    if (pmap->flags & AllAllocated)	return(BadAccess);    if ((class | DynamicClass) == DirectColor)    {	rmask = mask & RGBMASK(pmap->pVisual);        result = FreeCo(pmap, client, REDMAP, count, pixels,			mask & pmap->pVisual->redMask);	/* If any of the three calls fails, we must report that, if more	 * than one fails, it's ok that we report the last one */        rval = FreeCo(pmap, client, GREENMAP, count, pixels,		      mask & pmap->pVisual->greenMask);	if(rval != Success)	    result = rval;	rval = FreeCo(pmap, client, BLUEMAP, count, pixels,		      mask & pmap->pVisual->blueMask);	if(rval != Success)	    result = rval;    }    else    {	rmask = mask & ((((Pixel)1) << pmap->pVisual->nplanes) - 1);        result = FreeCo(pmap, client, PSEUDOMAP, count, pixels, rmask);    }    if ((mask != rmask) && count)    {	clientErrorValue = *pixels | mask;	result = BadValue;    }    /* XXX should worry about removing any RT_CMAPENTRY resource */    return (result);}/* Helper for FreeColors -- frees all combinations of *newpixels and mask bits * which the client has allocated in channel colormap cells of pmap. * doesn't change newpixels if it doesn't need to */static intFreeCo (pmap, client, color, npixIn, ppixIn, mask)    ColormapPtr	pmap;		/* which colormap head */    int		client;		    int		color;		/* which sub-map, eg RED, BLUE, PSEUDO */    int		npixIn;		/* number of pixels passed in */    Pixel	*ppixIn;	/* list of base pixels */    Pixel	mask;		/* mask client gave us */ {    Pixel	*ppixClient, pixTest;    int		npixClient, npixNew, npix;    Pixel	bits, base, cmask, rgbbad;    Pixel	*pptr, *cptr;    int 	n, zapped;    int		errVal = Success;    int		offset, numents;#ifdef LBX    Bool	grabbed;    Bool	zeroRefCount;    Bool	anyRefCountReachedZero = 0;#endif    if (npixIn == 0)        return (errVal);    bits = 0;    zapped = 0;    base = lowbit (mask);    switch(color)    {      case REDMAP:	cmask = pmap->pVisual->redMask;	rgbbad = ~RGBMASK(pmap->pVisual);	offset = pmap->pVisual->offsetRed;	numents = (cmask >> offset) + 1;	ppixClient = pmap->clientPixelsRed[client];	npixClient = pmap->numPixelsRed[client];	break;      case GREENMAP:	cmask = pmap->pVisual->greenMask;	rgbbad = ~RGBMASK(pmap->pVisual);	offset = pmap->pVisual->offsetGreen;	numents = (cmask >> offset) + 1;	ppixClient = pmap->clientPixelsGreen[client];	npixClient = pmap->numPixelsGreen[client];	break;      case BLUEMAP:	cmask = pmap->pVisual->blueMask;	rgbbad = ~RGBMASK(pmap->pVisual);	offset = pmap->pVisual->offsetBlue;	numents = (cmask >> offset) + 1;	ppixClient = pmap->clientPixelsBlue[client];	npixClient = pmap->numPixelsBlue[client];	break;      default:	/* so compiler can see that everything gets initialized */      case PSEUDOMAP:	cmask = ~((Pixel)0);	rgbbad = 0;	offset = 0;	numents = pmap->pVisual->ColormapEntries;	ppixClient = pmap->clientPixelsRed[client];	npixClient = pmap->numPixelsRed[client];	break;    }#ifdef LBX    grabbed = LbxCheckCmapGrabbed (pmap);    if (grabbed)    {	/*	 * If the colormap is grabbed by a proxy, the server must	 * notify the proxy of all cells that are freed (the refcount	 * has reached zero on these cells).	 */	LbxBeginFreeCellsEvent (pmap);	LbxSortPixelList (ppixIn, npixIn);    }#endif    /* zap all pixels which match */    while (1)    {        /* go through pixel list */        for (pptr = ppixIn, n = npixIn; --n >= 0; pptr++)	{	    pixTest = ((*pptr | bits) & cmask) >> offset;	    if ((pixTest >= numents) || (*pptr & rgbbad))	    {		clientErrorValue = *pptr | bits;		errVal = BadValue;		continue;	    }	    /* find match in client list */	    for (cptr = ppixClient, npix = npixClient;	         --npix >= 0 && *cptr != pixTest;		 cptr++) ;	    if (npix >= 0)	    {		if (pmap->class & DynamicClass)		{		    FreeCell(pmap, pixTest, color);#ifdef LBX		    /*		     * Only PSEUDO colormaps are grabbed by LBX proxies.		     * Check if the ref count reached zero on this pixel.		     */		    zeroRefCount = pmap->red[pixTest].refcnt == 0;		    if (zeroRefCount)			anyRefCountReachedZero = 1;		    if (grabbed && zeroRefCount)			LbxAddFreeCellToEvent (pmap, pixTest);#endif		}		*cptr = ~((Pixel)0);		zapped++;	    }	    else		errVal = BadAccess;	}        /* generate next bits value */	GetNextBitsOrBreak(bits, mask, base);    }#ifdef LBX    if (grabbed)	LbxEndFreeCellsEvent (pmap);    else if (anyRefCountReachedZero)    {	/*	 * We only send LbxFreeCell events to a proxy that has the colormap	 * grabbed.  If the colormap is not grabbed, the proxy that last	 * had the colormap grabbed will not be able to do a smart grab	 * in the future.  A smart grab can only occur if the proxy is kept	 * up to date on every alloc/free change in the colormap.	 */		LbxDisableSmartGrab (pmap);    }#endif    /* delete freed pixels from client pixel list */    if (zapped)    {        npixNew = npixClient - zapped;        if (npixNew)	{	    /* Since the list can only get smaller, we can do a copy in	     * place and then realloc to a smaller size */    	    pptr = cptr = ppixClient;	    /* If we have all the new pixels, we don't have to examine the	     * rest of the old ones */	    for(npix = 0; npix < npixNew; cptr++)	    {    	        if (*cptr != ~((Pixel)0))		{    		    *pptr++ = *cptr;		    npix++;    	        }    	    }	    pptr = (Pixel *)xrealloc(ppixClient, npixNew * sizeof(Pixel));	    if (pptr)		ppixClient = pptr;	    npixClient = npixNew;        }

⌨️ 快捷键说明

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