File: getcolors.c

package info (click to toggle)
pgplot5 5.2-13
  • links: PTS
  • area: non-free
  • in suites: potato
  • size: 6,280 kB
  • ctags: 5,903
  • sloc: fortran: 37,938; ansic: 18,809; sh: 1,147; objc: 532; makefile: 363; perl: 234; pascal: 233; tcl: 178; awk: 51; csh: 25
file content (169 lines) | stat: -rw-r--r-- 5,525 bytes parent folder | download | duplicates (15)
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);
}