CrCmap.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xmu/StdCmap.h>

Include dependency graph for CrCmap.c:

Go to the source code of this file.

Defines

#define lowbit(x)   ((x) & (~(x) + 1))
#define TRUEMATCH(mult, max, mask)
#define calc(max, mult)

Functions

static int ROmap (Display *, Colormap, unsigned long[], int, int)
static Status ROorRWcell (Display *, Colormap, unsigned long[], int, XColor *, unsigned long)
static Status RWcell (Display *, Colormap, XColor *, XColor *, unsigned long *)
static int compare (_Xconst void *, _Xconst void *)
static Status contiguous (unsigned long[], int, int, unsigned long, int *, int *)
static void free_cells (Display *, Colormap, unsigned long[], int, int)
static Status readonly_map (Display *, XVisualInfo *, XStandardColormap *)
static Status readwrite_map (Display *, XVisualInfo *, XStandardColormap *)
Status XmuCreateColormap (Display *dpy, XStandardColormap *colormap)


Define Documentation

#define calc ( max,
mult   ) 

Value:

(((n / colormap->mult) % \
                         (colormap->max + 1)) * 65535) / colormap->max

Referenced by readwrite_map().

#define lowbit ( x   )     ((x) & (~(x) + 1))

Definition at line 72 of file CrCmap.c.

#define TRUEMATCH ( mult,
max,
mask   ) 

Value:

(colormap->max * colormap->mult <= vinfo->mask && \
     lowbit(vinfo->mask) == colormap->mult)

Definition at line 73 of file CrCmap.c.


Function Documentation

static int compare ( _Xconst void *  ,
_Xconst void *   
) [static]

Definition at line 497 of file CrCmap.c.

00498 {
00499   return ((int)(*(long *)e1 - *(long *)e2));
00500 }

static Status contiguous ( unsigned  long[],
int  ,
int  ,
unsigned  long,
int ,
int  
) [static]

Definition at line 376 of file CrCmap.c.

References count, and i.

Referenced by readwrite_map().

00385 {
00386     register int i = 1;         /* walking index into the pixel array */
00387     register int count = 1;     /* length of sequence discovered so far */
00388 
00389     *first = 0;
00390     if (npixels == ncolors) {
00391         *rem = 0;
00392         return 1;
00393     }
00394     *rem = npixels - 1;
00395     while (count < ncolors && ncolors - count <= *rem)
00396     {
00397         if (pixels[i-1] + delta == pixels[i])
00398             count++;
00399         else {
00400             count = 1;
00401             *first = i;
00402         }
00403         i++;
00404         (*rem)--;
00405     }
00406     if (count != ncolors)
00407         return 0;
00408     return 1;
00409 }

Here is the caller graph for this function:

static void free_cells ( Display *  ,
Colormap  ,
unsigned  long[],
int  ,
int   
) [static]

Definition at line 451 of file CrCmap.c.

References free().

Referenced by ROorRWcell().

00457 {
00458     /* One of the npixels allocated has already been freed.
00459      * p is the index of the freed pixel.
00460      * First free the pixels preceeding p, and there are p of them;
00461      * then free the pixels following p, there are npixels - p - 1 of them.
00462      */
00463     XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
00464     XFreeColors(dpy, cmap, &(pixels[p+1]), npixels - p - 1, (unsigned long) 0);
00465     free((char *) pixels);
00466 }

Here is the call graph for this function:

Here is the caller graph for this function:

static Status readonly_map ( Display *  ,
XVisualInfo *  ,
XStandardColormap *   
) [static]

Definition at line 505 of file CrCmap.c.

References i, and long.

00506 {
00507     int                 i, last_pixel;
00508     XColor              color;
00509 
00510     last_pixel = (colormap->red_max + 1) * (colormap->green_max + 1) * 
00511         (colormap->blue_max + 1) + colormap->base_pixel - 1;
00512 
00513     for(i=colormap->base_pixel; i <= last_pixel; i++) {
00514 
00515         color.pixel = (unsigned long) i;
00516         color.red = (unsigned short)
00517             (((i/colormap->red_mult) * 65535) / colormap->red_max);
00518 
00519         if (vinfo->class == StaticColor) {
00520             color.green = (unsigned short)
00521                 ((((i/colormap->green_mult) % (colormap->green_max + 1)) *
00522                   65535) / colormap->green_max);
00523             color.blue = (unsigned short)
00524                 (((i%colormap->green_mult) * 65535) / colormap->blue_max);
00525         }
00526         else    /* vinfo->class == GrayScale, old style allocation XXX */
00527             color.green = color.blue = color.red;
00528 
00529         XAllocColor(dpy, colormap->colormap, &color);
00530         if (color.pixel != (unsigned long) i)
00531             return 0;
00532     }
00533     return 1;
00534 }

static Status readwrite_map ( Display *  ,
XVisualInfo *  ,
XStandardColormap *   
) [static]

Definition at line 170 of file CrCmap.c.

References calc, calloc(), compare(), contiguous(), free(), i, lowbit, n, NULL, ROmap(), and ROorRWcell().

00171 {
00172     register unsigned long i, n;        /* index counters */
00173     unsigned long       ncolors;        /* number of colors to be defined */
00174     int                 npixels;        /* number of pixels allocated R/W */
00175     int                 first_index;    /* first index of pixels to use */
00176     int                 remainder;      /* first index of remainder */
00177     XColor              color;          /* the definition of a color */
00178     unsigned long       *pixels;        /* array of colormap pixels */
00179     unsigned long       delta;
00180 
00181     
00182     /* Determine ncolors, the number of colors to be defined.
00183      * Insure that 1 < ncolors <= the colormap size.
00184      */
00185     if (vinfo->class == DirectColor) {
00186         ncolors = colormap->red_max;
00187         if (colormap->green_max > ncolors)
00188             ncolors = colormap->green_max;
00189         if (colormap->blue_max > ncolors)
00190             ncolors = colormap->blue_max;
00191         ncolors++;
00192         delta = lowbit(vinfo->red_mask) +
00193                 lowbit(vinfo->green_mask) +
00194                 lowbit(vinfo->blue_mask);
00195     } else {
00196         ncolors = colormap->red_max * colormap->red_mult +
00197                   colormap->green_max * colormap->green_mult +
00198                   colormap->blue_max * colormap->blue_mult + 1;
00199         delta = 1;
00200     }
00201     if (ncolors <= 1 || (int) ncolors > vinfo->colormap_size)   return 0;
00202 
00203     /* Allocate Read/Write as much of the colormap as we can possibly get.
00204      * Then insure that the pixels we were allocated are given in 
00205      * monotonically increasing order, using a quicksort.  Next, insure
00206      * that our allocation includes a subset of contiguous pixels at least
00207      * as long as the number of colors to be defined.  Now we know that 
00208      * these conditions are met:
00209      *  1) There are no free cells in the colormap.
00210      *  2) We have a contiguous sequence of pixels, monotonically 
00211      *     increasing, of length >= the number of colors requested.
00212      *
00213      * One cell at a time, we will free, compute the next color value, 
00214      * then allocate read only.  This takes a long time.
00215      * This is done to insure that cells are allocated read only in the
00216      * contiguous order which we prefer.  If the server has a choice of
00217      * cells to grant to an allocation request, the server may give us any
00218      * cell, so that is why we do these slow gymnastics.
00219      */
00220 
00221     if ((pixels = (unsigned long *) calloc((unsigned) vinfo->colormap_size,
00222                                       sizeof(unsigned long))) == NULL)
00223         return 0;
00224 
00225     if ((npixels = ROmap(dpy, colormap->colormap, pixels,
00226                            vinfo->colormap_size, ncolors)) == 0) {
00227         free((char *) pixels);
00228         return 0;
00229     }
00230 
00231     qsort((char *) pixels, npixels, sizeof(unsigned long), compare);
00232 
00233     if (!contiguous(pixels, npixels, ncolors, delta, &first_index, &remainder))
00234     {
00235         /* can't find enough contiguous cells, give up */
00236         XFreeColors(dpy, colormap->colormap, pixels, npixels,
00237                     (unsigned long) 0);
00238         free((char *) pixels);
00239         return 0;
00240     }
00241     colormap->base_pixel = pixels[first_index];
00242 
00243     /* construct a gray map */
00244     if (colormap->red_mult == 1 && colormap->green_mult == 1 &&
00245         colormap->blue_mult == 1)
00246         for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
00247         {
00248             color.pixel = n;
00249             color.blue = color.green = color.red =
00250                 (unsigned short) ((i * 65535) / (colormap->red_max +
00251                                                  colormap->green_max +
00252                                                  colormap->blue_max));
00253 
00254             if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
00255                              first_index + i))
00256                 return 0;
00257         }
00258 
00259     /* construct a red ramp map */
00260     else if (colormap->green_max == 0 && colormap->blue_max == 0)
00261         for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
00262         {
00263             color.pixel = n;
00264             color.red = (unsigned short) ((i * 65535) / colormap->red_max);
00265             color.green = color.blue = 0;
00266 
00267             if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
00268                              first_index + i))
00269                 return 0;
00270         }
00271 
00272     /* construct a green ramp map */
00273     else if (colormap->red_max == 0 && colormap->blue_max == 0)
00274         for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
00275         {
00276             color.pixel = n;
00277             color.green = (unsigned short) ((i * 65535) / colormap->green_max);
00278             color.red = color.blue = 0;
00279 
00280             if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
00281                              first_index + i))
00282                 return 0;
00283         }
00284 
00285     /* construct a blue ramp map */
00286     else if (colormap->red_max == 0 && colormap->green_max == 0)
00287         for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
00288         {
00289             color.pixel = n;
00290             color.blue = (unsigned short) ((i * 65535) / colormap->blue_max);
00291             color.red = color.green = 0;
00292 
00293             if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
00294                              first_index + i))
00295                 return 0;
00296         }
00297 
00298     /* construct a standard red green blue cube map */
00299     else
00300     {
00301 #define calc(max,mult) (((n / colormap->mult) % \
00302                          (colormap->max + 1)) * 65535) / colormap->max
00303 
00304         for (n=0, i=0; i < ncolors; i++, n += delta)
00305         {
00306             color.pixel = n + colormap->base_pixel;
00307             color.red = calc(red_max, red_mult);
00308             color.green = calc(green_max, green_mult);
00309             color.blue = calc(blue_max, blue_mult);
00310             if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
00311                              first_index + i))
00312                 return 0;
00313         }
00314 #undef calc
00315     }
00316     /* We have a read-only map defined.  Now free unused cells,
00317      * first those occuring before the contiguous sequence begins,
00318      * then any following the contiguous sequence.
00319      */
00320 
00321     if (first_index)
00322         XFreeColors(dpy, colormap->colormap, pixels, first_index, 
00323                     (unsigned long) 0);
00324     if (remainder)
00325         XFreeColors(dpy, colormap->colormap,
00326                     &(pixels[first_index + ncolors]), remainder,
00327                     (unsigned long) 0);
00328 
00329     free((char *) pixels);
00330     return 1;
00331 }

Here is the call graph for this function:

static int ROmap ( Display *  ,
Colormap  ,
unsigned  long[],
int  ,
int   
) [static]

Definition at line 336 of file CrCmap.c.

References NULL, and p.

Referenced by readwrite_map().

00344 {
00345     register int        p;
00346 
00347     /* first try to allocate the entire colormap */
00348     if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL, 
00349                          (unsigned) 0, pixels, (unsigned) m))
00350         return m;
00351 
00352     /* Allocate all available cells in the colormap, using a binary
00353      * algorithm to discover how many cells we can allocate in the colormap.
00354      */
00355     m--;
00356     while (n <= m) {
00357         p = n + ((m - n + 1) / 2);
00358         if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL,
00359                              (unsigned) 0, pixels, (unsigned) p)) {
00360             if (p == m)
00361                 return p;
00362             else {
00363                 XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
00364                 n = p;
00365             }
00366         }
00367         else
00368             m = p - 1;
00369     }
00370     return 0;
00371 }

Here is the caller graph for this function:

static Status ROorRWcell ( Display *  ,
Colormap  ,
unsigned  long[],
int  ,
XColor *  ,
unsigned  long 
) [static]

Definition at line 414 of file CrCmap.c.

References free_cells(), and RWcell().

Referenced by readwrite_map().

00416 {
00417     unsigned long       pixel;
00418     XColor              request;
00419 
00420     /* Free the read/write allocation of one cell in the colormap.
00421      * Request a read only allocation of one cell in the colormap.
00422      * If the read only allocation cannot be granted, give up, because
00423      * there must be no free cells in the colormap.
00424      * If the read only allocation is granted, but gives us a cell which
00425      * is not the one that we just freed, it is probably the case that
00426      * we are trying allocate White or Black or some other color which
00427      * already has a read-only allocation in the map.  So we try to 
00428      * allocate the previously freed cell with a read/write allocation,
00429      * because we want contiguous cells for image processing algorithms.
00430      */
00431      
00432     pixel = color->pixel;
00433     request.red = color->red;
00434     request.green = color->green;
00435     request.blue = color->blue;
00436 
00437     XFreeColors(dpy, cmap, &pixel, 1, (unsigned long) 0);
00438     if (! XAllocColor(dpy, cmap, color) 
00439         || (color->pixel != pixel &&
00440             (!RWcell(dpy, cmap, color, &request, &pixel)))) 
00441     {
00442         free_cells(dpy, cmap, pixels, npixels, (int)p);
00443         return 0;
00444     }
00445     return 1;
00446 }

Here is the call graph for this function:

Here is the caller graph for this function:

static Status RWcell ( Display *  ,
Colormap  ,
XColor *  ,
XColor *  ,
unsigned long  
) [static]

Definition at line 471 of file CrCmap.c.

References n, and NULL.

Referenced by ROorRWcell().

00473 {
00474     unsigned long       n = *pixel;
00475 
00476     XFreeColors(dpy, cmap, &(color->pixel), 1, (unsigned long)0);
00477     if (! XAllocColorCells(dpy, cmap, (Bool) 0, (unsigned long *) NULL,
00478                            (unsigned) 0, pixel, (unsigned) 1))
00479         return 0;
00480     if (*pixel != n)
00481     {
00482         XFreeColors(dpy, cmap, pixel, 1, (unsigned long) 0);
00483         return 0;
00484     }
00485     color->pixel = *pixel;
00486     color->flags = DoRed | DoGreen | DoBlue;
00487     color->red = request->red;
00488     color->green = request->green;
00489     color->blue = request->blue;
00490     XStoreColors(dpy, cmap, color, 1);
00491     return 1;
00492 }

Here is the caller graph for this function:

Status XmuCreateColormap ( Display *  dpy,
XStandardColormap *  colormap 
)

Definition at line 98 of file CrCmap.c.

References i, n, NULL, and v.

Referenced by XmuStandardColormap().

00104 {
00105     XVisualInfo         vinfo_template; /* template visual information */
00106     XVisualInfo         *vinfo;         /* matching visual information */
00107     XVisualInfo         *vpointer;      /* for freeing the entire list */
00108     long                vinfo_mask;     /* specifies the visual mask value */
00109     int                 n;              /* number of matching visuals */
00110     int                 status;         
00111 
00112     vinfo_template.visualid = colormap->visualid;
00113     vinfo_mask = VisualIDMask;
00114     if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
00115         return 0;
00116 
00117     /* A visual id may be valid on multiple screens.  Also, there may 
00118      * be multiple visuals with identical visual ids at different depths.  
00119      * If the colormap is the Default Colormap, use the Default Visual.
00120      * Otherwise, arbitrarily, use the deepest visual.
00121      */
00122     vpointer = vinfo;
00123     if (n > 1)
00124     {
00125         register int    i;
00126         register int    screen_number;
00127         Bool            def_cmap;
00128 
00129         def_cmap = False;
00130         for (screen_number = ScreenCount(dpy); --screen_number >= 0; )
00131             if (colormap->colormap == DefaultColormap(dpy, screen_number)) {
00132                 def_cmap = True;
00133                 break;
00134             }
00135 
00136         if (def_cmap) {
00137             for (i=0; i < n; i++, vinfo++) {
00138                 if (vinfo->visual == DefaultVisual(dpy, screen_number))
00139                         break;
00140             }
00141         } else {
00142             int                 maxdepth = 0;
00143             XVisualInfo         *v = NULL;
00144 
00145             for (i=0; i < n; i++, vinfo++)
00146                 if (vinfo->depth > maxdepth) {
00147                     maxdepth = vinfo->depth;
00148                     v = vinfo;
00149                 }
00150             vinfo = v;
00151         }
00152     }
00153 
00154     if (vinfo->class == PseudoColor || vinfo->class == DirectColor ||
00155         vinfo->class == GrayScale)
00156         status = readwrite_map(dpy, vinfo, colormap);
00157     else if (vinfo->class == TrueColor)
00158         status = TRUEMATCH(red_mult, red_max, red_mask) &&
00159                  TRUEMATCH(green_mult, green_max, green_mask) &&
00160                  TRUEMATCH(blue_mult, blue_max, blue_mask);
00161     else 
00162         status = readonly_map(dpy, vinfo, colormap);
00163     
00164     XFree((char *) vpointer);
00165     return status;
00166 }

Here is the caller graph for this function:


Generated on Sun Mar 4 16:03:38 2007 for Scilab [trunk] by  doxygen 1.5.1