📄 colormap.c
字号:
xE.u.u.type = ColormapNotify; xE.u.colormap.window = pwin->drawable.id; xE.u.colormap.colormap = None; xE.u.colormap.new = TRUE; xE.u.colormap.state = ColormapUninstalled; DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL); if (pwin->optional) { pwin->optional->colormap = None; CheckWindowOptionalNeed (pwin); } } return (WT_WALKCHILDREN);}/* Tell window that pmid got uninstalled */intTellLostMap (pwin, value) WindowPtr pwin; pointer value;{ Colormap *pmid = (Colormap *)value; xEvent xE; if (wColormap(pwin) == *pmid) { /* This should be call to DeliverEvent */ xE.u.u.type = ColormapNotify; xE.u.colormap.window = pwin->drawable.id; xE.u.colormap.colormap = *pmid; xE.u.colormap.new = FALSE; xE.u.colormap.state = ColormapUninstalled; DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL); } return (WT_WALKCHILDREN);}/* Tell window that pmid got installed */intTellGainedMap (pwin, value) WindowPtr pwin; pointer value;{ Colormap *pmid = (Colormap *)value; xEvent xE; if (wColormap (pwin) == *pmid) { /* This should be call to DeliverEvent */ xE.u.u.type = ColormapNotify; xE.u.colormap.window = pwin->drawable.id; xE.u.colormap.colormap = *pmid; xE.u.colormap.new = FALSE; xE.u.colormap.state = ColormapInstalled; DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL); } return (WT_WALKCHILDREN);} intCopyColormapAndFree (mid, pSrc, client) Colormap mid; ColormapPtr pSrc; int client;{ ColormapPtr pmap = (ColormapPtr) NULL; int result, alloc, size; Colormap midSrc; ScreenPtr pScreen; VisualPtr pVisual; pScreen = pSrc->pScreen; pVisual = pSrc->pVisual; midSrc = pSrc->mid; alloc = ((pSrc->flags & AllAllocated) && CLIENT_ID(midSrc) == client) ? AllocAll : AllocNone; size = pVisual->ColormapEntries; /* If the create returns non-0, it failed */ result = CreateColormap (mid, pScreen, pVisual, &pmap, alloc, client); if(result != Success) return(result); if(alloc == AllocAll) { memmove((char *)pmap->red, (char *)pSrc->red, size * sizeof(Entry)); if((pmap->class | DynamicClass) == DirectColor) { memmove((char *)pmap->green, (char *)pSrc->green, size * sizeof(Entry)); memmove((char *)pmap->blue, (char *)pSrc->blue, size * sizeof(Entry)); } pSrc->flags &= ~AllAllocated; FreePixels(pSrc, client); UpdateColors(pmap); return(Success); } CopyFree(REDMAP, client, pSrc, pmap); if ((pmap->class | DynamicClass) == DirectColor) { CopyFree(GREENMAP, client, pSrc, pmap); CopyFree(BLUEMAP, client, pSrc, pmap); } if (pmap->class & DynamicClass) UpdateColors(pmap); /* XXX should worry about removing any RT_CMAPENTRY resource */ return(Success);}/* Helper routine for freeing large numbers of cells from a map */static voidCopyFree (channel, client, pmapSrc, pmapDst) int channel, client; ColormapPtr pmapSrc, pmapDst;{ int z, npix, oldFree; EntryPtr pentSrcFirst, pentDstFirst; EntryPtr pentSrc, pentDst; Pixel *ppix; int nalloc; switch(channel) { default: /* so compiler can see that everything gets initialized */ case REDMAP: ppix = (pmapSrc->clientPixelsRed)[client]; npix = (pmapSrc->numPixelsRed)[client]; pentSrcFirst = pmapSrc->red; pentDstFirst = pmapDst->red; oldFree = pmapSrc->freeRed; break; case GREENMAP: ppix = (pmapSrc->clientPixelsGreen)[client]; npix = (pmapSrc->numPixelsGreen)[client]; pentSrcFirst = pmapSrc->green; pentDstFirst = pmapDst->green; oldFree = pmapSrc->freeGreen; break; case BLUEMAP: ppix = (pmapSrc->clientPixelsBlue)[client]; npix = (pmapSrc->numPixelsBlue)[client]; pentSrcFirst = pmapSrc->blue; pentDstFirst = pmapDst->blue; oldFree = pmapSrc->freeBlue; break; } nalloc = 0; if (pmapSrc->class & DynamicClass) { for(z = npix; --z >= 0; ppix++) { /* Copy entries */ pentSrc = pentSrcFirst + *ppix; pentDst = pentDstFirst + *ppix; if (pentDst->refcnt > 0) { pentDst->refcnt++; } else { *pentDst = *pentSrc; nalloc++; if (pentSrc->refcnt > 0) pentDst->refcnt = 1; else pentSrc->fShared = FALSE; } FreeCell(pmapSrc, *ppix, channel); } } /* Note that FreeCell has already fixed pmapSrc->free{Color} */ switch(channel) { case REDMAP: pmapDst->freeRed -= nalloc; (pmapDst->clientPixelsRed)[client] = (pmapSrc->clientPixelsRed)[client]; (pmapSrc->clientPixelsRed)[client] = (Pixel *) NULL; (pmapDst->numPixelsRed)[client] = (pmapSrc->numPixelsRed)[client]; (pmapSrc->numPixelsRed)[client] = 0; break; case GREENMAP: pmapDst->freeGreen -= nalloc; (pmapDst->clientPixelsGreen)[client] = (pmapSrc->clientPixelsGreen)[client]; (pmapSrc->clientPixelsGreen)[client] = (Pixel *) NULL; (pmapDst->numPixelsGreen)[client] = (pmapSrc->numPixelsGreen)[client]; (pmapSrc->numPixelsGreen)[client] = 0; break; case BLUEMAP: pmapDst->freeBlue -= nalloc; pmapDst->clientPixelsBlue[client] = pmapSrc->clientPixelsBlue[client]; pmapSrc->clientPixelsBlue[client] = (Pixel *) NULL; pmapDst->numPixelsBlue[client] = pmapSrc->numPixelsBlue[client]; pmapSrc->numPixelsBlue[client] = 0; break; }}/* Free the ith entry in a color map. Must handle freeing of * colors allocated through AllocColorPlanes */static voidFreeCell (pmap, i, channel) ColormapPtr pmap; Pixel i; int channel;{ EntryPtr pent; int *pCount; switch (channel) { default: /* so compiler can see that everything gets initialized */ case PSEUDOMAP: case REDMAP: pent = (EntryPtr) &pmap->red[i]; pCount = &pmap->freeRed; break; case GREENMAP: pent = (EntryPtr) &pmap->green[i]; pCount = &pmap->freeGreen; break; case BLUEMAP: pent = (EntryPtr) &pmap->blue[i]; pCount = &pmap->freeBlue; break; } /* If it's not privately allocated and it's not time to free it, just * decrement the count */ if (pent->refcnt > 1) pent->refcnt--; else { /* If the color type is shared, find the sharedcolor. If decremented * refcnt is 0, free the shared cell. */ if (pent->fShared) { if(--pent->co.shco.red->refcnt == 0) xfree(pent->co.shco.red); if(--pent->co.shco.green->refcnt == 0) xfree(pent->co.shco.green); if(--pent->co.shco.blue->refcnt == 0) xfree(pent->co.shco.blue); pent->fShared = FALSE; } pent->refcnt = 0; *pCount += 1; }}static voidUpdateColors (pmap) ColormapPtr pmap;{ xColorItem *defs; register xColorItem *pdef; register EntryPtr pent; register VisualPtr pVisual; int i, n, size; pVisual = pmap->pVisual; size = pVisual->ColormapEntries; defs = (xColorItem *)ALLOCATE_LOCAL(size * sizeof(xColorItem)); if (!defs) return; n = 0; pdef = defs; if (pmap->class == DirectColor) { for (i = 0; i < size; i++) { if (!pmap->red[i].refcnt && !pmap->green[i].refcnt && !pmap->blue[i].refcnt) continue; pdef->pixel = ((Pixel)i << pVisual->offsetRed) | ((Pixel)i << pVisual->offsetGreen) | ((Pixel)i << pVisual->offsetBlue); pdef->red = pmap->red[i].co.local.red; pdef->green = pmap->green[i].co.local.green; pdef->blue = pmap->blue[i].co.local.blue; pdef->flags = DoRed|DoGreen|DoBlue; pdef++; n++; } } else { for (i = 0, pent = pmap->red; i < size; i++, pent++) { if (!pent->refcnt) continue; pdef->pixel = i; if(pent->fShared) { pdef->red = pent->co.shco.red->color; pdef->green = pent->co.shco.green->color; pdef->blue = pent->co.shco.blue->color; } else { pdef->red = pent->co.local.red; pdef->green = pent->co.local.green; pdef->blue = pent->co.local.blue; } pdef->flags = DoRed|DoGreen|DoBlue; pdef++; n++; } } if (n) (*pmap->pScreen->StoreColors)(pmap, n, defs); DEALLOCATE_LOCAL(defs);}/* Get a read-only color from a ColorMap (probably slow for large maps) * Returns by changing the value in pred, pgreen, pblue and pPix */intAllocColor (pmap, pred, pgreen, pblue, pPix, client) ColormapPtr pmap; unsigned short *pred, *pgreen, *pblue; Pixel *pPix; int client;{ Pixel pixR, pixG, pixB; int entries; xrgb rgb; int class; VisualPtr pVisual; int npix; Pixel *ppix; pVisual = pmap->pVisual; (*pmap->pScreen->ResolveColor) (pred, pgreen, pblue, pVisual); rgb.red = *pred; rgb.green = *pgreen; rgb.blue = *pblue; class = pmap->class; entries = pVisual->ColormapEntries; /* If the colormap is being created, then we want to be able to change * the colormap, even if it's a static type. Otherwise, we'd never be * able to initialize static colormaps */ if(pmap->flags & BeingCreated) class |= DynamicClass; /* If this is one of the static storage classes, and we're not initializing * it, the best we can do is to find the closest color entry to the * requested one and return that. */ switch (class) { case StaticColor: case StaticGray: /* Look up all three components in the same pmap */ *pPix = pixR = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP); *pred = pmap->red[pixR].co.local.red; *pgreen = pmap->red[pixR].co.local.green; *pblue = pmap->red[pixR].co.local.blue; npix = pmap->numPixelsRed[client]; ppix = (Pixel *) xrealloc(pmap->clientPixelsRed[client], (npix + 1) * sizeof(Pixel)); if (!ppix) return (BadAlloc); ppix[npix] = pixR; pmap->clientPixelsRed[client] = ppix; pmap->numPixelsRed[client]++; break; case TrueColor: /* Look up each component in its own map, then OR them together */ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP); pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP); pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP); *pPix = (pixR << pVisual->offsetRed) | (pixG << pVisual->offsetGreen) | (pixB << pVisual->offsetBlue); *pred = pmap->red[pixR].co.local.red; *pgreen = pmap->green[pixG].co.local.green; *pblue = pmap->blue[pixB].co.local.blue; npix = pmap->numPixelsRed[client]; ppix = (Pixel *) xrealloc(pmap->clientPixelsRed[client], (npix + 1) * sizeof(Pixel)); if (!ppix) return (BadAlloc); ppix[npix] = pixR; pmap->clientPixelsRed[client] = ppix; npix = pmap->numPixelsGreen[client]; ppix = (Pixel *) xrealloc(pmap->clientPixelsGreen[client], (npix + 1) * sizeof(Pixel)); if (!ppix) return (BadAlloc); ppix[npix] = pixG; pmap->clientPixelsGreen[client] = ppix; npix = pmap->numPixelsBlue[client]; ppix = (Pixel *) xrealloc(pmap->clientPixelsBlue[client], (npix + 1) * sizeof(Pixel)); if (!ppix) return (BadAlloc); ppix[npix] = pixB; pmap->clientPixelsBlue[client] = ppix; pmap->numPixelsRed[client]++; pmap->numPixelsGreen[client]++; pmap->numPixelsBlue[client]++; break; case GrayScale: case PseudoColor: if (FindColor(pmap, pmap->red, entries, &rgb, pPix, PSEUDOMAP, client, AllComp) != Success) return (BadAlloc); break; case DirectColor: pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed; if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP, client, RedComp) != Success) return (BadAlloc); pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen; if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG, GREENMAP, client, GreenComp) != Success) { (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0); return (BadAlloc); } pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue; if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP, client, BlueComp) != Success) { (void)FreeCo(pmap, client, GREENMAP, 1, &pixG, (Pixel)0); (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0); return (BadAlloc); } *pPix = pixR | pixG | pixB; break; } /* if this is the client's first pixel in this colormap, tell the * resource manager that the client has pixels in this colormap which * should be freed when the client dies */ if ((pmap->numPixelsRed[client] == 1) && (CLIENT_ID(pmap->mid) != client) && !(pmap->flags & BeingCreated)) { colorResource *pcr; pcr = (colorResource *) xalloc(sizeof(colorResource)); if (!pcr) { (void)FreeColors(pmap, client, 1, pPix, (Pixel)0); return (BadAlloc); } pcr->mid = pmap->mid; pcr->client = client; if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr)) return (BadAlloc); } return (Success);}/* * FakeAllocColor -- fake an AllocColor request by * returning a free pixel if availible, otherwise returning * the closest matching pixel. This is used by the mi * software sprite code to recolor cursors. A nice side-effect * is that this routine will never return failure. */voidFakeAllocColor (pmap, item) register ColormapPtr pmap; register xColorItem *item;{ Pixel pixR, pixG, pixB; Pixel temp; int entries; xrgb rgb; int class; register VisualPtr pVisual; pVisual = pmap->pVisual; rgb.red = item->red; rgb.green = item->green; rgb.blue = item->blue; (*pmap->pScreen->ResolveColor) (&rgb.red, &rgb.green, &rgb.blue, pVisual); class = pmap->class; entries = pVisual->ColormapEntries; switch (class) { case GrayScale: case PseudoColor:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -