📄 colormap.c
字号:
register int n; int class;#ifdef LBX Bool grabbed; Bool zeroRefCount; Bool anyRefCountReachedZero = 0;#endif class = pmap->class; ppixStart = pmap->clientPixelsRed[client]; if (class & DynamicClass) { n = pmap->numPixelsRed[client];#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 (ppixStart, n); }#endif for (ppix = ppixStart; --n >= 0; ) { FreeCell(pmap, *ppix, REDMAP);#ifdef LBX /* * Only PSEUDO colormaps are grabbed by LBX proxies. * Check if the ref count reached zero on this pixel. */ zeroRefCount = pmap->red[*ppix].refcnt == 0; if (zeroRefCount) anyRefCountReachedZero = 1; if (grabbed && zeroRefCount) LbxAddFreeCellToEvent (pmap, *ppix);#endif ppix++; }#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 } xfree(ppixStart); pmap->clientPixelsRed[client] = (Pixel *) NULL; pmap->numPixelsRed[client] = 0; if ((class | DynamicClass) == DirectColor) { ppixStart = pmap->clientPixelsGreen[client]; if (class & DynamicClass) for (ppix = ppixStart, n = pmap->numPixelsGreen[client]; --n >= 0;) FreeCell(pmap, *ppix++, GREENMAP); xfree(ppixStart); pmap->clientPixelsGreen[client] = (Pixel *) NULL; pmap->numPixelsGreen[client] = 0; ppixStart = pmap->clientPixelsBlue[client]; if (class & DynamicClass) for (ppix = ppixStart, n = pmap->numPixelsBlue[client]; --n >= 0; ) FreeCell(pmap, *ppix++, BLUEMAP); xfree(ppixStart); pmap->clientPixelsBlue[client] = (Pixel *) NULL; pmap->numPixelsBlue[client] = 0; }}/* Free all of a client's colors and cells *//*ARGSUSED*/intFreeClientPixels (value, fakeid) pointer value; /* must conform to DeleteType */ XID fakeid;{ ColormapPtr pmap; colorResource *pcr = (colorResource *)value; pmap = (ColormapPtr) LookupIDByType(pcr->mid, RT_COLORMAP); if (pmap) FreePixels(pmap, pcr->client); xfree(pcr); return Success;}intAllocColorCells (client, pmap, colors, planes, contig, ppix, masks) int client; ColormapPtr pmap; int colors, planes; Bool contig; Pixel *ppix; Pixel *masks;{ Pixel rmask, gmask, bmask, *ppixFirst, r, g, b; int n, class; int ok; int oldcount; colorResource *pcr = (colorResource *)NULL; class = pmap->class; if (!(class & DynamicClass)) return (BadAlloc); /* Shouldn't try on this type */ oldcount = pmap->numPixelsRed[client]; if (pmap->class == DirectColor) oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client]; if (!oldcount && (CLIENT_ID(pmap->mid) != client)) { pcr = (colorResource *) xalloc(sizeof(colorResource)); if (!pcr) return (BadAlloc); } if (pmap->class == DirectColor) { ok = AllocDirect (client, pmap, colors, planes, planes, planes, contig, ppix, &rmask, &gmask, &bmask); if(ok == Success) { for (r = g = b = 1, n = planes; --n >= 0; r += r, g += g, b += b) { while(!(rmask & r)) r += r; while(!(gmask & g)) g += g; while(!(bmask & b)) b += b; *masks++ = r | g | b; } } } else { ok = AllocPseudo (client, pmap, colors, planes, contig, ppix, &rmask, &ppixFirst); if(ok == Success) { for (r = 1, n = planes; --n >= 0; r += r) { while(!(rmask & r)) r += r; *masks++ = r; } } } /* if this is the client's first pixels in this colormap, tell the * resource manager that the client has pixels in this colormap which * should be freed when the client dies */ if ((ok == Success) && pcr) { pcr->mid = pmap->mid; pcr->client = client; if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr)) ok = BadAlloc; } else if (pcr) xfree(pcr); return (ok);}intAllocColorPlanes (client, pmap, colors, r, g, b, contig, pixels, prmask, pgmask, pbmask) int client; ColormapPtr pmap; int colors, r, g, b; Bool contig; Pixel *pixels; Pixel *prmask, *pgmask, *pbmask;{ int ok; Pixel mask, *ppixFirst; register Pixel shift; register int i; int class; int oldcount; colorResource *pcr = (colorResource *)NULL; class = pmap->class; if (!(class & DynamicClass)) return (BadAlloc); /* Shouldn't try on this type */ oldcount = pmap->numPixelsRed[client]; if (class == DirectColor) oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client]; if (!oldcount && (CLIENT_ID(pmap->mid) != client)) { pcr = (colorResource *) xalloc(sizeof(colorResource)); if (!pcr) return (BadAlloc); } if (class == DirectColor) { ok = AllocDirect (client, pmap, colors, r, g, b, contig, pixels, prmask, pgmask, pbmask); } else { /* Allocate the proper pixels */ /* XXX This is sort of bad, because of contig is set, we force all * r + g + b bits to be contiguous. Should only force contiguity * per mask */ ok = AllocPseudo (client, pmap, colors, r + g + b, contig, pixels, &mask, &ppixFirst); if(ok == Success) { /* now split that mask into three */ *prmask = *pgmask = *pbmask = 0; shift = 1; for (i = r; --i >= 0; shift += shift) { while (!(mask & shift)) shift += shift; *prmask |= shift; } for (i = g; --i >= 0; shift += shift) { while (!(mask & shift)) shift += shift; *pgmask |= shift; } for (i = b; --i >= 0; shift += shift) { while (!(mask & shift)) shift += shift; *pbmask |= shift; } /* set up the shared color cells */ if (!AllocShared(pmap, pixels, colors, r, g, b, *prmask, *pgmask, *pbmask, ppixFirst)) { (void)FreeColors(pmap, client, colors, pixels, mask); ok = BadAlloc; } } } /* if this is the client's first pixels in this colormap, tell the * resource manager that the client has pixels in this colormap which * should be freed when the client dies */ if ((ok == Success) && pcr) { pcr->mid = pmap->mid; pcr->client = client; if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr)) ok = BadAlloc; } else if (pcr) xfree(pcr); return (ok);}static intAllocDirect (client, pmap, c, r, g, b, contig, pixels, prmask, pgmask, pbmask) int client; ColormapPtr pmap; int c, r, g, b; Bool contig; Pixel *pixels; Pixel *prmask, *pgmask, *pbmask;{ Pixel *ppixRed, *ppixGreen, *ppixBlue; Pixel *ppix, *pDst, *p; int npix, npixR, npixG, npixB; Bool okR, okG, okB; Pixel *rpix = 0, *gpix = 0, *bpix = 0; npixR = c << r; npixG = c << g; npixB = c << b; if ((r >= 32) || (g >= 32) || (b >= 32) || (npixR > pmap->freeRed) || (npixR < c) || (npixG > pmap->freeGreen) || (npixG < c) || (npixB > pmap->freeBlue) || (npixB < c)) return BadAlloc; /* start out with empty pixels */ for(p = pixels; p < pixels + c; p++) *p = 0; ppixRed = (Pixel *)ALLOCATE_LOCAL(npixR * sizeof(Pixel)); ppixGreen = (Pixel *)ALLOCATE_LOCAL(npixG * sizeof(Pixel)); ppixBlue = (Pixel *)ALLOCATE_LOCAL(npixB * sizeof(Pixel)); if (!ppixRed || !ppixGreen || !ppixBlue) { if (ppixBlue) DEALLOCATE_LOCAL(ppixBlue); if (ppixGreen) DEALLOCATE_LOCAL(ppixGreen); if (ppixRed) DEALLOCATE_LOCAL(ppixRed); return(BadAlloc); } okR = AllocCP(pmap, pmap->red, c, r, contig, ppixRed, prmask); okG = AllocCP(pmap, pmap->green, c, g, contig, ppixGreen, pgmask); okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask); if (okR && okG && okB) { rpix = (Pixel *) xrealloc(pmap->clientPixelsRed[client], (pmap->numPixelsRed[client] + (c << r)) * sizeof(Pixel)); if (rpix) pmap->clientPixelsRed[client] = rpix; gpix = (Pixel *) xrealloc(pmap->clientPixelsGreen[client], (pmap->numPixelsGreen[client] + (c << g)) * sizeof(Pixel)); if (gpix) pmap->clientPixelsGreen[client] = gpix; bpix = (Pixel *) xrealloc(pmap->clientPixelsBlue[client], (pmap->numPixelsBlue[client] + (c << b)) * sizeof(Pixel)); if (bpix) pmap->clientPixelsBlue[client] = bpix; } if (!okR || !okG || !okB || !rpix || !gpix || !bpix) { if (okR) for(ppix = ppixRed, npix = npixR; --npix >= 0; ppix++) pmap->red[*ppix].refcnt = 0; if (okG) for(ppix = ppixGreen, npix = npixG; --npix >= 0; ppix++) pmap->green[*ppix].refcnt = 0; if (okB) for(ppix = ppixBlue, npix = npixB; --npix >= 0; ppix++) pmap->blue[*ppix].refcnt = 0; DEALLOCATE_LOCAL(ppixBlue); DEALLOCATE_LOCAL(ppixGreen); DEALLOCATE_LOCAL(ppixRed); return(BadAlloc); } *prmask <<= pmap->pVisual->offsetRed; *pgmask <<= pmap->pVisual->offsetGreen; *pbmask <<= pmap->pVisual->offsetBlue; ppix = rpix + pmap->numPixelsRed[client]; for (pDst = pixels, p = ppixRed; p < ppixRed + npixR; p++) { *ppix++ = *p; if(p < ppixRed + c) *pDst++ |= *p << pmap->pVisual->offsetRed; } pmap->numPixelsRed[client] += npixR; pmap->freeRed -= npixR; ppix = gpix + pmap->numPixelsGreen[client]; for (pDst = pixels, p = ppixGreen; p < ppixGreen + npixG; p++) { *ppix++ = *p; if(p < ppixGreen + c) *pDst++ |= *p << pmap->pVisual->offsetGreen; } pmap->numPixelsGreen[client] += npixG; pmap->freeGreen -= npixG; ppix = bpix + pmap->numPixelsBlue[client]; for (pDst = pixels, p = ppixBlue; p < ppixBlue + npixB; p++) { *ppix++ = *p; if(p < ppixBlue + c) *pDst++ |= *p << pmap->pVisual->offsetBlue; } pmap->numPixelsBlue[client] += npixB; pmap->freeBlue -= npixB; DEALLOCATE_LOCAL(ppixBlue); DEALLOCATE_LOCAL(ppixGreen); DEALLOCATE_LOCAL(ppixRed); return (Success);}static intAllocPseudo (client, pmap, c, r, contig, pixels, pmask, pppixFirst) int client; ColormapPtr pmap; int c, r; Bool contig; Pixel *pixels; Pixel *pmask; Pixel **pppixFirst;{ Pixel *ppix, *p, *pDst, *ppixTemp; int npix; Bool ok; npix = c << r; if ((r >= 32) || (npix > pmap->freeRed) || (npix < c)) return(BadAlloc); if(!(ppixTemp = (Pixel *)ALLOCATE_LOCAL(npix * sizeof(Pixel)))) return(BadAlloc); ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask); if (ok) { /* all the allocated pixels are added to the client pixel list, * but only the unique ones are returned to the client */ ppix = (Pixel *)xrealloc(pmap->clientPixelsRed[client], (pmap->numPixelsRed[client] + npix) * sizeof(Pixel)); if (!ppix) { for (p = ppixTemp; p < ppixTemp + npix; p++) pmap->red[*p].refcnt = 0; return (BadAlloc); } pmap->clientPixelsRed[client] = ppix; ppix += pmap->numPixelsRed[client]; *pppixFirst = ppix; pDst = pixels; for (p = ppixTemp; p < ppixTemp + npix; p++) { *ppix++ = *p; if(p < ppixTemp + c) *pDst++ = *p; } pmap->numPixelsRed[client] += npix; pmap->freeRed -= npix; } DEALLOCATE_LOCAL(ppixTemp); return (ok ? Success : BadAlloc);}/* Allocates count << planes pixels from colormap pmap for client. If * contig, then the plane mask is made of consecutive bits. Returns * all count << pixels in the array pixels. The first count of those * pixels are the unique pixels. *pMask has the mask to Or with the * unique pixels to get the rest of them. * * Returns True iff all pixels could be allocated * All cells allocated will have refcnt set to AllocPrivate and shared to FALSE * (see AllocShared for why we care) */static BoolAllocCP (pmap, pentFirst, count, planes, contig, pixels, pMask) ColormapPtr pmap; EntryPtr pentFirst; int count, planes; Bool contig; Pixel *pixels, *pMask; { EntryPtr ent; Pixel pixel, base, entries, maxp, save; int dplanes, found; Pixel *ppix; Pixel mask; Pixel finalmask; dplanes = pmap->pVisual->nplanes; /* Easy case. Allocate pixels only */ if (planes == 0) { /* allocate writable entries */ ppix = pixels; ent = pentFirst; pixel = 0; while (--count >= 0) { /* Just find count unallocated cells */ while (ent->refcnt) { ent++; pixel++; } ent->refcnt = AllocPrivate; *ppix++ = pixel; ent->fShared = FALSE; } *pMask = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -