diff options
Diffstat (limited to 'xserver/dix/colormap.c')
-rw-r--r-- | xserver/dix/colormap.c | 434 |
1 files changed, 218 insertions, 216 deletions
diff --git a/xserver/dix/colormap.c b/xserver/dix/colormap.c index 4d408d5d2..12a85b256 100644 --- a/xserver/dix/colormap.c +++ b/xserver/dix/colormap.c @@ -64,6 +64,9 @@ SOFTWARE. #include "privates.h" #include "xace.h" +typedef int (*ColorCompareProcPtr) (EntryPtr /*pent */ , + xrgb * /*prgb */ ); + static Pixel FindBestPixel(EntryPtr /*pentFirst */ , int /*size */ , xrgb * /*prgb */ , @@ -249,7 +252,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, size = pVisual->ColormapEntries; sizebytes = (size * sizeof(Entry)) + - (MAXCLIENTS * sizeof(Pixel *)) + (MAXCLIENTS * sizeof(int)); + (LimitClients * sizeof(Pixel *)) + (LimitClients * sizeof(int)); if ((class | DynamicClass) == DirectColor) sizebytes *= 3; sizebytes += sizeof(ColormapRec); @@ -274,7 +277,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, sizebytes = size * sizeof(Entry); pmap->clientPixelsRed = (Pixel **) ((char *) pmap->red + sizebytes); pmap->numPixelsRed = (int *) ((char *) pmap->clientPixelsRed + - (MAXCLIENTS * sizeof(Pixel *))); + (LimitClients * sizeof(Pixel *))); pmap->mid = mid; pmap->flags = 0; /* start out with all flags clear */ if (mid == pScreen->defColormap) @@ -286,8 +289,8 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, size = NUMRED(pVisual); pmap->freeRed = size; memset((char *) pmap->red, 0, (int) sizebytes); - memset((char *) pmap->numPixelsRed, 0, MAXCLIENTS * sizeof(int)); - for (pptr = &pmap->clientPixelsRed[MAXCLIENTS]; + memset((char *) pmap->numPixelsRed, 0, LimitClients * sizeof(int)); + for (pptr = &pmap->clientPixelsRed[LimitClients]; --pptr >= pmap->clientPixelsRed;) *pptr = (Pixel *) NULL; if (alloc == AllocAll) { @@ -296,7 +299,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--) pent->refcnt = AllocPrivate; pmap->freeRed = 0; - ppix = malloc(size * sizeof(Pixel)); + ppix = xallocarray(size, sizeof(Pixel)); if (!ppix) { free(pmap); return BadAlloc; @@ -310,26 +313,26 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, if ((class | DynamicClass) == DirectColor) { pmap->freeGreen = NUMGREEN(pVisual); pmap->green = (EntryPtr) ((char *) pmap->numPixelsRed + - (MAXCLIENTS * sizeof(int))); + (LimitClients * sizeof(int))); pmap->clientPixelsGreen = (Pixel **) ((char *) pmap->green + sizebytes); pmap->numPixelsGreen = (int *) ((char *) pmap->clientPixelsGreen + - (MAXCLIENTS * sizeof(Pixel *))); + (LimitClients * sizeof(Pixel *))); pmap->freeBlue = NUMBLUE(pVisual); pmap->blue = (EntryPtr) ((char *) pmap->numPixelsGreen + - (MAXCLIENTS * sizeof(int))); + (LimitClients * sizeof(int))); pmap->clientPixelsBlue = (Pixel **) ((char *) pmap->blue + sizebytes); pmap->numPixelsBlue = (int *) ((char *) pmap->clientPixelsBlue + - (MAXCLIENTS * sizeof(Pixel *))); + (LimitClients * sizeof(Pixel *))); memset((char *) pmap->green, 0, (int) sizebytes); memset((char *) pmap->blue, 0, (int) sizebytes); memmove((char *) pmap->clientPixelsGreen, - (char *) pmap->clientPixelsRed, MAXCLIENTS * sizeof(Pixel *)); + (char *) pmap->clientPixelsRed, LimitClients * sizeof(Pixel *)); memmove((char *) pmap->clientPixelsBlue, - (char *) pmap->clientPixelsRed, MAXCLIENTS * sizeof(Pixel *)); - memset((char *) pmap->numPixelsGreen, 0, MAXCLIENTS * sizeof(int)); - memset((char *) pmap->numPixelsBlue, 0, MAXCLIENTS * sizeof(int)); + (char *) pmap->clientPixelsRed, LimitClients * sizeof(Pixel *)); + memset((char *) pmap->numPixelsGreen, 0, LimitClients * sizeof(int)); + memset((char *) pmap->numPixelsBlue, 0, LimitClients * sizeof(int)); /* If every cell is allocated, mark its refcnt */ if (alloc == AllocAll) { @@ -337,7 +340,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, for (pent = &pmap->green[size - 1]; pent >= pmap->green; pent--) pent->refcnt = AllocPrivate; pmap->freeGreen = 0; - ppix = malloc(size * sizeof(Pixel)); + ppix = xallocarray(size, sizeof(Pixel)); if (!ppix) { free(pmap->clientPixelsRed[client]); free(pmap); @@ -352,7 +355,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, for (pent = &pmap->blue[size - 1]; pent >= pmap->blue; pent--) pent->refcnt = AllocPrivate; pmap->freeBlue = 0; - ppix = malloc(size * sizeof(Pixel)); + ppix = xallocarray(size, sizeof(Pixel)); if (!ppix) { free(pmap->clientPixelsGreen[client]); free(pmap->clientPixelsRed[client]); @@ -413,7 +416,7 @@ FreeColormap(void *value, XID mid) (*pmap->pScreen->DestroyColormap) (pmap); if (pmap->clientPixelsRed) { - for (i = 0; i < MAXCLIENTS; i++) + for (i = 0; i < LimitClients; i++) free(pmap->clientPixelsRed[i]); } @@ -431,7 +434,7 @@ FreeColormap(void *value, XID mid) } } if ((pmap->class | DynamicClass) == DirectColor) { - for (i = 0; i < MAXCLIENTS; i++) { + for (i = 0; i < LimitClients; i++) { free(pmap->clientPixelsGreen[i]); free(pmap->clientPixelsBlue[i]); } @@ -702,7 +705,7 @@ UpdateColors(ColormapPtr pmap) pVisual = pmap->pVisual; size = pVisual->ColormapEntries; - defs = malloc(size * sizeof(xColorItem)); + defs = xallocarray(size, sizeof(xColorItem)); if (!defs) return; n = 0; @@ -748,6 +751,173 @@ UpdateColors(ColormapPtr pmap) free(defs); } +/* Tries to find a color in pmap that exactly matches the one requested in prgb + * if it can't it allocates one. + * Starts looking at pentFirst + *pPixel, so if you want a specific pixel, + * load *pPixel with that value, otherwise set it to 0 + */ +static int +FindColor(ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb * prgb, + Pixel * pPixel, int channel, int client, ColorCompareProcPtr comp) +{ + EntryPtr pent; + Bool foundFree; + Pixel pixel, Free = 0; + int npix, count, *nump = NULL; + Pixel **pixp = NULL, *ppix; + xColorItem def; + + foundFree = FALSE; + + if ((pixel = *pPixel) >= size) + pixel = 0; + /* see if there is a match, and also look for a free entry */ + for (pent = pentFirst + pixel, count = size; --count >= 0;) { + if (pent->refcnt > 0) { + if ((*comp) (pent, prgb)) { + if (client >= 0) + pent->refcnt++; + *pPixel = pixel; + switch (channel) { + case REDMAP: + *pPixel <<= pmap->pVisual->offsetRed; + case PSEUDOMAP: + break; + case GREENMAP: + *pPixel <<= pmap->pVisual->offsetGreen; + break; + case BLUEMAP: + *pPixel <<= pmap->pVisual->offsetBlue; + break; + } + goto gotit; + } + } + else if (!foundFree && pent->refcnt == 0) { + Free = pixel; + foundFree = TRUE; + /* If we're initializing the colormap, then we are looking for + * the first free cell we can find, not to minimize the number + * of entries we use. So don't look any further. */ + if (pmap->flags & BeingCreated) + break; + } + pixel++; + if (pixel >= size) { + pent = pentFirst; + pixel = 0; + } + else + pent++; + } + + /* If we got here, we didn't find a match. If we also didn't find + * a free entry, we're out of luck. Otherwise, we'll usurp a free + * entry and fill it in */ + if (!foundFree) + return BadAlloc; + pent = pentFirst + Free; + pent->fShared = FALSE; + pent->refcnt = (client >= 0) ? 1 : AllocTemporary; + + switch (channel) { + case PSEUDOMAP: + pent->co.local.red = prgb->red; + pent->co.local.green = prgb->green; + pent->co.local.blue = prgb->blue; + def.red = prgb->red; + def.green = prgb->green; + def.blue = prgb->blue; + def.flags = (DoRed | DoGreen | DoBlue); + if (client >= 0) + pmap->freeRed--; + def.pixel = Free; + break; + + case REDMAP: + pent->co.local.red = prgb->red; + def.red = prgb->red; + def.green = pmap->green[0].co.local.green; + def.blue = pmap->blue[0].co.local.blue; + def.flags = DoRed; + if (client >= 0) + pmap->freeRed--; + def.pixel = Free << pmap->pVisual->offsetRed; + break; + + case GREENMAP: + pent->co.local.green = prgb->green; + def.red = pmap->red[0].co.local.red; + def.green = prgb->green; + def.blue = pmap->blue[0].co.local.blue; + def.flags = DoGreen; + if (client >= 0) + pmap->freeGreen--; + def.pixel = Free << pmap->pVisual->offsetGreen; + break; + + case BLUEMAP: + pent->co.local.blue = prgb->blue; + def.red = pmap->red[0].co.local.red; + def.green = pmap->green[0].co.local.green; + def.blue = prgb->blue; + def.flags = DoBlue; + if (client >= 0) + pmap->freeBlue--; + def.pixel = Free << pmap->pVisual->offsetBlue; + break; + } + (*pmap->pScreen->StoreColors) (pmap, 1, &def); + pixel = Free; + *pPixel = def.pixel; + + gotit: + if (pmap->flags & BeingCreated || client == -1) + return Success; + /* Now remember the pixel, for freeing later */ + switch (channel) { + case PSEUDOMAP: + case REDMAP: + nump = pmap->numPixelsRed; + pixp = pmap->clientPixelsRed; + break; + + case GREENMAP: + nump = pmap->numPixelsGreen; + pixp = pmap->clientPixelsGreen; + break; + + case BLUEMAP: + nump = pmap->numPixelsBlue; + pixp = pmap->clientPixelsBlue; + break; + } + npix = nump[client]; + ppix = reallocarray(pixp[client], npix + 1, sizeof(Pixel)); + if (!ppix) { + pent->refcnt--; + if (!pent->fShared) + switch (channel) { + case PSEUDOMAP: + case REDMAP: + pmap->freeRed++; + break; + case GREENMAP: + pmap->freeGreen++; + break; + case BLUEMAP: + pmap->freeBlue++; + break; + } + return BadAlloc; + } + ppix[npix] = pixel; + pixp[client] = ppix; + nump[client]++; + + return Success; +} + /* Get a read-only color from a ColorMap (probably slow for large maps) * Returns by changing the value in pred, pgreen, pblue and pPix */ @@ -792,8 +962,8 @@ AllocColor(ColormapPtr pmap, *pgreen = pmap->red[pixR].co.local.green; *pblue = pmap->red[pixR].co.local.blue; npix = pmap->numPixelsRed[client]; - ppix = (Pixel *) realloc(pmap->clientPixelsRed[client], - (npix + 1) * sizeof(Pixel)); + ppix = reallocarray(pmap->clientPixelsRed[client], + npix + 1, sizeof(Pixel)); if (!ppix) return BadAlloc; ppix[npix] = pixR; @@ -814,22 +984,22 @@ AllocColor(ColormapPtr pmap, *pgreen = pmap->green[pixG].co.local.green; *pblue = pmap->blue[pixB].co.local.blue; npix = pmap->numPixelsRed[client]; - ppix = (Pixel *) realloc(pmap->clientPixelsRed[client], - (npix + 1) * sizeof(Pixel)); + ppix = reallocarray(pmap->clientPixelsRed[client], + npix + 1, sizeof(Pixel)); if (!ppix) return BadAlloc; ppix[npix] = pixR; pmap->clientPixelsRed[client] = ppix; npix = pmap->numPixelsGreen[client]; - ppix = (Pixel *) realloc(pmap->clientPixelsGreen[client], - (npix + 1) * sizeof(Pixel)); + ppix = reallocarray(pmap->clientPixelsGreen[client], + npix + 1, sizeof(Pixel)); if (!ppix) return BadAlloc; ppix[npix] = pixG; pmap->clientPixelsGreen[client] = ppix; npix = pmap->numPixelsBlue[client]; - ppix = (Pixel *) realloc(pmap->clientPixelsBlue[client], - (npix + 1) * sizeof(Pixel)); + ppix = reallocarray(pmap->clientPixelsBlue[client], + npix + 1, sizeof(Pixel)); if (!ppix) return BadAlloc; ppix[npix] = pixB; @@ -1137,173 +1307,6 @@ FindColorInRootCmap(ColormapPtr pmap, EntryPtr pentFirst, int size, } } -/* Tries to find a color in pmap that exactly matches the one requested in prgb - * if it can't it allocates one. - * Starts looking at pentFirst + *pPixel, so if you want a specific pixel, - * load *pPixel with that value, otherwise set it to 0 - */ -int -FindColor(ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb * prgb, - Pixel * pPixel, int channel, int client, ColorCompareProcPtr comp) -{ - EntryPtr pent; - Bool foundFree; - Pixel pixel, Free = 0; - int npix, count, *nump = NULL; - Pixel **pixp = NULL, *ppix; - xColorItem def; - - foundFree = FALSE; - - if ((pixel = *pPixel) >= size) - pixel = 0; - /* see if there is a match, and also look for a free entry */ - for (pent = pentFirst + pixel, count = size; --count >= 0;) { - if (pent->refcnt > 0) { - if ((*comp) (pent, prgb)) { - if (client >= 0) - pent->refcnt++; - *pPixel = pixel; - switch (channel) { - case REDMAP: - *pPixel <<= pmap->pVisual->offsetRed; - case PSEUDOMAP: - break; - case GREENMAP: - *pPixel <<= pmap->pVisual->offsetGreen; - break; - case BLUEMAP: - *pPixel <<= pmap->pVisual->offsetBlue; - break; - } - goto gotit; - } - } - else if (!foundFree && pent->refcnt == 0) { - Free = pixel; - foundFree = TRUE; - /* If we're initializing the colormap, then we are looking for - * the first free cell we can find, not to minimize the number - * of entries we use. So don't look any further. */ - if (pmap->flags & BeingCreated) - break; - } - pixel++; - if (pixel >= size) { - pent = pentFirst; - pixel = 0; - } - else - pent++; - } - - /* If we got here, we didn't find a match. If we also didn't find - * a free entry, we're out of luck. Otherwise, we'll usurp a free - * entry and fill it in */ - if (!foundFree) - return BadAlloc; - pent = pentFirst + Free; - pent->fShared = FALSE; - pent->refcnt = (client >= 0) ? 1 : AllocTemporary; - - switch (channel) { - case PSEUDOMAP: - pent->co.local.red = prgb->red; - pent->co.local.green = prgb->green; - pent->co.local.blue = prgb->blue; - def.red = prgb->red; - def.green = prgb->green; - def.blue = prgb->blue; - def.flags = (DoRed | DoGreen | DoBlue); - if (client >= 0) - pmap->freeRed--; - def.pixel = Free; - break; - - case REDMAP: - pent->co.local.red = prgb->red; - def.red = prgb->red; - def.green = pmap->green[0].co.local.green; - def.blue = pmap->blue[0].co.local.blue; - def.flags = DoRed; - if (client >= 0) - pmap->freeRed--; - def.pixel = Free << pmap->pVisual->offsetRed; - break; - - case GREENMAP: - pent->co.local.green = prgb->green; - def.red = pmap->red[0].co.local.red; - def.green = prgb->green; - def.blue = pmap->blue[0].co.local.blue; - def.flags = DoGreen; - if (client >= 0) - pmap->freeGreen--; - def.pixel = Free << pmap->pVisual->offsetGreen; - break; - - case BLUEMAP: - pent->co.local.blue = prgb->blue; - def.red = pmap->red[0].co.local.red; - def.green = pmap->green[0].co.local.green; - def.blue = prgb->blue; - def.flags = DoBlue; - if (client >= 0) - pmap->freeBlue--; - def.pixel = Free << pmap->pVisual->offsetBlue; - break; - } - (*pmap->pScreen->StoreColors) (pmap, 1, &def); - pixel = Free; - *pPixel = def.pixel; - - gotit: - if (pmap->flags & BeingCreated || client == -1) - return Success; - /* Now remember the pixel, for freeing later */ - switch (channel) { - case PSEUDOMAP: - case REDMAP: - nump = pmap->numPixelsRed; - pixp = pmap->clientPixelsRed; - break; - - case GREENMAP: - nump = pmap->numPixelsGreen; - pixp = pmap->clientPixelsGreen; - break; - - case BLUEMAP: - nump = pmap->numPixelsBlue; - pixp = pmap->clientPixelsBlue; - break; - } - npix = nump[client]; - ppix = (Pixel *) realloc(pixp[client], (npix + 1) * sizeof(Pixel)); - if (!ppix) { - pent->refcnt--; - if (!pent->fShared) - switch (channel) { - case PSEUDOMAP: - case REDMAP: - pmap->freeRed++; - break; - case GREENMAP: - pmap->freeGreen++; - break; - case BLUEMAP: - pmap->freeBlue++; - break; - } - return BadAlloc; - } - ppix[npix] = pixel; - pixp[client] = ppix; - nump[client]++; - - return Success; -} - /* Comparison functions -- passed to FindColor to determine if an * entry is already the color we're looking for or not */ static int @@ -1647,9 +1650,9 @@ AllocDirect(int client, ColormapPtr pmap, int c, int r, int g, int b, for (p = pixels; p < pixels + c; p++) *p = 0; - ppixRed = malloc(npixR * sizeof(Pixel)); - ppixGreen = malloc(npixG * sizeof(Pixel)); - ppixBlue = malloc(npixB * sizeof(Pixel)); + ppixRed = xallocarray(npixR, sizeof(Pixel)); + ppixGreen = xallocarray(npixG, sizeof(Pixel)); + ppixBlue = xallocarray(npixB, sizeof(Pixel)); if (!ppixRed || !ppixGreen || !ppixBlue) { free(ppixBlue); free(ppixGreen); @@ -1662,19 +1665,19 @@ AllocDirect(int client, ColormapPtr pmap, int c, int r, int g, int b, okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask); if (okR && okG && okB) { - rpix = (Pixel *) realloc(pmap->clientPixelsRed[client], - (pmap->numPixelsRed[client] + (c << r)) * - sizeof(Pixel)); + rpix = reallocarray(pmap->clientPixelsRed[client], + pmap->numPixelsRed[client] + (c << r), + sizeof(Pixel)); if (rpix) pmap->clientPixelsRed[client] = rpix; - gpix = (Pixel *) realloc(pmap->clientPixelsGreen[client], - (pmap->numPixelsGreen[client] + (c << g)) * - sizeof(Pixel)); + gpix = reallocarray(pmap->clientPixelsGreen[client], + pmap->numPixelsGreen[client] + (c << g), + sizeof(Pixel)); if (gpix) pmap->clientPixelsGreen[client] = gpix; - bpix = (Pixel *) realloc(pmap->clientPixelsBlue[client], - (pmap->numPixelsBlue[client] + (c << b)) * - sizeof(Pixel)); + bpix = reallocarray(pmap->clientPixelsBlue[client], + pmap->numPixelsBlue[client] + (c << b), + sizeof(Pixel)); if (bpix) pmap->clientPixelsBlue[client] = bpix; } @@ -1747,7 +1750,7 @@ AllocPseudo(int client, ColormapPtr pmap, int c, int r, Bool contig, npix = c << r; if ((r >= 32) || (npix > pmap->freeRed) || (npix < c)) return BadAlloc; - if (!(ppixTemp = malloc(npix * sizeof(Pixel)))) + if (!(ppixTemp = xallocarray(npix, sizeof(Pixel)))) return BadAlloc; ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask); @@ -1755,9 +1758,8 @@ AllocPseudo(int client, ColormapPtr pmap, int c, int r, Bool contig, /* all the allocated pixels are added to the client pixel list, * but only the unique ones are returned to the client */ - ppix = (Pixel *) realloc(pmap->clientPixelsRed[client], - (pmap->numPixelsRed[client] + - npix) * sizeof(Pixel)); + ppix = reallocarray(pmap->clientPixelsRed[client], + pmap->numPixelsRed[client] + npix, sizeof(Pixel)); if (!ppix) { for (p = ppixTemp; p < ppixTemp + npix; p++) pmap->red[*p].refcnt = 0; @@ -1960,7 +1962,7 @@ AllocShared(ColormapPtr pmap, Pixel * ppix, int c, int r, int g, int b, npixClientNew = c << (r + g + b); npixShared = (c << r) + (c << g) + (c << b); - psharedList = malloc(npixShared * sizeof(SHAREDCOLOR *)); + psharedList = xallocarray(npixShared, sizeof(SHAREDCOLOR *)); if (!psharedList) return FALSE; ppshared = psharedList; @@ -2204,7 +2206,7 @@ FreeCo(ColormapPtr pmap, int client, int color, int npixIn, Pixel * ppixIn, npix++; } } - pptr = (Pixel *) realloc(ppixClient, npixNew * sizeof(Pixel)); + pptr = reallocarray(ppixClient, npixNew, sizeof(Pixel)); if (pptr) ppixClient = pptr; npixClient = npixNew; @@ -2469,8 +2471,8 @@ IsMapInstalled(Colormap map, WindowPtr pWin) Colormap *pmaps; int imap, nummaps, found; - pmaps = - malloc(pWin->drawable.pScreen->maxInstalledCmaps * sizeof(Colormap)); + pmaps = xallocarray(pWin->drawable.pScreen->maxInstalledCmaps, + sizeof(Colormap)); if (!pmaps) return FALSE; nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) @@ -2521,8 +2523,8 @@ ResizeVisualArray(ScreenPtr pScreen, int new_visual_count, DepthPtr depth) first_new_vid = depth->numVids; first_new_visual = pScreen->numVisuals; - vids = - realloc(depth->vids, (depth->numVids + new_visual_count) * sizeof(XID)); + vids = reallocarray(depth->vids, depth->numVids + new_visual_count, + sizeof(XID)); if (!vids) return FALSE; @@ -2530,7 +2532,7 @@ ResizeVisualArray(ScreenPtr pScreen, int new_visual_count, DepthPtr depth) depth->vids = vids; numVisuals = pScreen->numVisuals + new_visual_count; - visuals = realloc(pScreen->visuals, numVisuals * sizeof(VisualRec)); + visuals = reallocarray(pScreen->visuals, numVisuals, sizeof(VisualRec)); if (!visuals) { return FALSE; } |