1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
/* The getcolors routine allocates between mincolors and maxcolors colors in */
/* the specified kind of visual (default color map, read/write visual, or */
/* read only visual). Visual is set to the visual used, cmap is set to the */
/* color map used, and pix is set to the pixels allocated. If the attempt to */
/* allocate colors is unsuccessful the values of these variables are */
/* undefined and may have been changed. If we are told to use a read only */
/* visual, no color map entries are actually allocated. */
/* Return Values: */
/* 0 We were unable to allocate the required number of colors */
/* other The number of colors we allocated. */
/* Sam Southard, Jr. */
/* Created: 20-Feb-1992 */
/* Modification History: */
/* 24-Feb-1992 SNS/CIT Now returns the visual depth as well */
/* 3-Mar-1992 SNS/CIT Now looks at TrueColor and Direct Color visuals as */
/* well. Now examines the user's visual specs. */
/* 6-Mar-1992 SNS/CIT Now takes max and min depth parameters */
/* 14-Apr-1992 SNS/CIT Now uses a quickie version of log2 */
#include "figdisp.h"
#include "globals.h"
/* The visual classes to use for r/w color maps, in order of preference */
static int rwvis[]={DirectColor, PseudoColor, GrayScale};
static int nrwvis=sizeof(rwvis)/sizeof(rwvis[0]);
/* The visual classes to use for read only color maps, in order of preference */
static int rovis[]={TrueColor, StaticColor, StaticGray};
static int nrovis=sizeof(rovis)/sizeof(rovis[0]);
int getcolors(vistype, visual, cmap, pix, maxcolors, mincolors, depth,
maxdepth, mindepth)
int vistype; /* The type of visual to use */
Visual **visual; /* The visual actually used */
Colormap *cmap; /* The color map actually used */
unsigned long *pix; /* The pixels allocated */
int maxcolors; /* The maximum number of colors to allocate */
int mincolors; /* The minimum number of colors to allocate */
int *depth; /* The depth of the visual actually used */
int maxdepth; /* The maximum allowed visual depth */
int mindepth; /* The minimum allowed visual depth */
{
XVisualInfo vinfo; /* The template for our visual */
unsigned long pmtmp[1]; /* temporary for plane masks */
int i,j; /* silly loop variables */
int nvis; /* The number of visual classes to deal with */
int class; /* The visual class to use */
int colors;
int defro; /* if the default visual is read-only */
/* first free up the color map. If it's not been set yet, we do no */
/* harm. */
if (*cmap != DefaultColormap(display, screen))
{
XFreeColormap(display, *cmap);
*cmap = DefaultColormap(display, screen);
}
if (vistype == UseDefaultCmap)
{ /* This is the easy case */
*visual=DefaultVisual(display, screen);
/* make sure the user allows this kind of visual */
if (res.visclass >= 0 && res.visclass != (*visual)->class)
return(0);
*cmap=DefaultColormap(display, screen);
*depth=DefaultDepth(display, screen);
/* see if the default visual is read-only */
if ((*visual)->class == StaticGray ||
(*visual)->class == StaticColor ||
(*visual)->class == TrueColor) defro=1;
else defro=0;
/* Make sure we don't try too hard */
if (maxcolors > (*visual)->map_entries)
maxcolors=(*visual)->map_entries;
/* we may have a read-only default color map */
if (defro && maxcolors >= mincolors)
return(maxcolors);
while (maxcolors >= mincolors)
{
if (XAllocColorCells(display, *cmap, True, &pmtmp[0],
0, pix, (unsigned)maxcolors)) break;
--maxcolors;
}
if (maxcolors >= mincolors) return(maxcolors);
else return(0);
}
/* For these cases we have to go looking for a visual */
if (vistype == UseRWVisual) nvis=nrwvis;
else nvis=nrovis;
/* This is just a very specialized log2() */
for (i=31 ; i >= 0 ; --i)
if (mincolors & (1<<i)) break;
if (i < 0) i=0;
if (i > mindepth) mindepth=i;
for (i=0 ; i < nvis ; ++i)
{
if (vistype == UseRWVisual) class=rwvis[i];
else class=rovis[i];
/* Make sure the user allows this kind of visual */
*visual=DefaultVisual(display, screen);
if (res.visclass >= 0 && res.visclass != class ||
res.visclass == DefaultVis && class != (*visual)->class)
continue;
*depth=maxdepth;
/* find a visual deep enough with enough available colors */
while (*depth >= mindepth)
{
if (XMatchVisualInfo(display, screen, *depth, class,
&vinfo))
{ /* we got a visual - can we allocate enough colors? */
*visual=vinfo.visual;
*cmap=XCreateColormap(display,
RootWindow(display, screen), *visual,
AllocNone);
if (vistype == UseROVisual)
{
if (maxcolors > (*visual)->map_entries)
maxcolors=
(*visual)->map_entries;
if (maxcolors < mincolors)
{ /* this shouldn't happen... */
--(*depth);
continue;
}
return(maxcolors);
}
/* go ahead and try to allocate the colors */
if (maxcolors > (*visual)->map_entries)
colors= (*visual)->map_entries;
else colors=maxcolors;
while (colors >= mincolors)
{
if (XAllocColorCells(display, *cmap,
True, &pmtmp[0], 0, pix,
(unsigned)colors)) break;
--colors;
}
/* Did we make it? */
if (colors >= mincolors) return(colors);
/* well, on to the next visual */
if (*cmap != DefaultColormap(display, screen))
{
XFreeColormap(display, *cmap);
*cmap = DefaultColormap(display,
screen);
}
}
--(*depth);
}
/* we weren't successful, so on to the next visual class */
}
/* Oh well...we gave it our best shot */
return(0);
}
|