1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "tk.h"
5 #include "private.h"
6 
7 
8 /*
9  * Return the index of the first bit set.  I'm using this instead of the
10  * ffs() function because I'm not sure it's really portable.
11  */
my_ffs(unsigned int n)12 static int my_ffs( unsigned int n )
13 {
14    if (n==0) {
15       return 0;
16    }
17    else {
18       unsigned int m = 1;
19       int index = 1;
20 
21       while ((n&m)==0) {
22 	 m <<= 1;
23 	 index++;
24       }
25       return index;
26    }
27 }
28 
29 
30 /******************************************************************************/
31 
tkGetColorMapSize(void)32 int tkGetColorMapSize(void)
33 {
34 
35     if (!xDisplay) {
36 	return 0;
37     } else {
38 	return w.vInfoMain->colormap_size;
39     }
40 }
41 
42 /******************************************************************************/
43 
tkGetMouseLoc(int * x,int * y)44 void tkGetMouseLoc(int *x, int *y)
45 {
46     int junk;
47 
48     *x = 0;
49     *y = 0;
50     XQueryPointer(xDisplay, w.wMain, (Window *)&junk, (Window *)&junk,
51 		  &junk, &junk, x, y, (unsigned int *)&junk);
52 }
53 
54 /******************************************************************************/
55 
tkGetSystem(TKenum type,void * ptr)56 void tkGetSystem(TKenum type, void *ptr)
57 {
58 
59     switch (type) {
60       case TK_X_DISPLAY:
61 	*(Display **)ptr = xDisplay;
62 	break;
63       case TK_X_WINDOW:
64 	*(Window *)ptr = w.wMain;
65 	break;
66     }
67 }
68 
69 /******************************************************************************/
70 
tkSetFogRamp(int density,int startIndex)71 void tkSetFogRamp(int density, int startIndex)
72 {
73     XColor c[4096];
74     int rShift, gShift, bShift, intensity, fogValues, colorValues;
75     int i, j, k;
76 
77     switch (w.vInfoMain->class) {
78       case DirectColor:
79 	fogValues = 1 << density;
80 	colorValues = 1 << startIndex;
81 	for (i = 0; i < colorValues; i++) {
82 	    for (j = 0; j < fogValues; j++) {
83 		k = i * fogValues + j;
84 		intensity = i * fogValues + j * colorValues;
85 		if (intensity > w.vInfoMain->colormap_size) {
86 		    intensity = w.vInfoMain->colormap_size;
87 		}
88 		intensity = (intensity << 8) | intensity;
89 		rShift = my_ffs((unsigned int)w.vInfoMain->red_mask) - 1;
90 		gShift = my_ffs((unsigned int)w.vInfoMain->green_mask) - 1;
91 		bShift = my_ffs((unsigned int)w.vInfoMain->blue_mask) - 1;
92 		c[k].pixel = ((k << rShift) & w.vInfoMain->red_mask) |
93 			     ((k << gShift) & w.vInfoMain->green_mask) |
94 			     ((k << bShift) & w.vInfoMain->blue_mask);
95 		c[k].red = (unsigned short)intensity;
96 		c[k].green = (unsigned short)intensity;
97 		c[k].blue = (unsigned short)intensity;
98 		c[k].flags = DoRed | DoGreen | DoBlue;
99 	    }
100 	}
101 	XStoreColors(xDisplay, w.cMapMain, c, w.vInfoMain->colormap_size);
102 	break;
103       case GrayScale:
104       case PseudoColor:
105 	fogValues = 1 << density;
106 	colorValues = 1 << startIndex;
107 	for (i = 0; i < colorValues; i++) {
108 	    for (j = 0; j < fogValues; j++) {
109 		k = i * fogValues + j;
110 		intensity = i * fogValues + j * colorValues;
111 		if (intensity > w.vInfoMain->colormap_size) {
112 		    intensity = w.vInfoMain->colormap_size;
113 		}
114 		intensity = (intensity << 8) | intensity;
115 		c[k].pixel = k;
116 		c[k].red = (unsigned short)intensity;
117 		c[k].green = (unsigned short)intensity;
118 		c[k].blue = (unsigned short)intensity;
119 		c[k].flags = DoRed | DoGreen | DoBlue;
120 	    }
121 	}
122 	XStoreColors(xDisplay, w.cMapMain, c, w.vInfoMain->colormap_size);
123 	break;
124     }
125 
126     XSync(xDisplay, 0);
127 }
128 
129 /******************************************************************************/
130 
tkSetGreyRamp(void)131 void tkSetGreyRamp(void)
132 {
133     XColor c[4096];
134     float intensity;
135     int rShift, gShift, bShift, i;
136 
137     switch (w.vInfoMain->class) {
138       case DirectColor:
139 	for (i = 0; i < w.vInfoMain->colormap_size; i++) {
140 	    intensity = (float)i / (float)w.vInfoMain->colormap_size *
141 			65535.0 + 0.5;
142 	    rShift = my_ffs((unsigned int)w.vInfoMain->red_mask) - 1;
143 	    gShift = my_ffs((unsigned int)w.vInfoMain->green_mask) - 1;
144 	    bShift = my_ffs((unsigned int)w.vInfoMain->blue_mask) - 1;
145 	    c[i].pixel = ((i << rShift) & w.vInfoMain->red_mask) |
146 			 ((i << gShift) & w.vInfoMain->green_mask) |
147 			 ((i << bShift) & w.vInfoMain->blue_mask);
148 	    c[i].red = (unsigned short)intensity;
149 	    c[i].green = (unsigned short)intensity;
150 	    c[i].blue = (unsigned short)intensity;
151 	    c[i].flags = DoRed | DoGreen | DoBlue;
152 	}
153 	XStoreColors(xDisplay, w.cMapMain, c, w.vInfoMain->colormap_size);
154 	break;
155       case GrayScale:
156       case PseudoColor:
157 	for (i = 0; i < w.vInfoMain->colormap_size; i++) {
158 	    intensity = (float)i / (float)w.vInfoMain->colormap_size *
159 			65535.0 + 0.5;
160 	    c[i].pixel = i;
161 	    c[i].red = (unsigned short)intensity;
162 	    c[i].green = (unsigned short)intensity;
163 	    c[i].blue = (unsigned short)intensity;
164 	    c[i].flags = DoRed | DoGreen | DoBlue;
165 	}
166 	XStoreColors(xDisplay, w.cMapMain, c, w.vInfoMain->colormap_size);
167 	break;
168     }
169 
170     XSync(xDisplay, 0);
171 }
172 
173 /******************************************************************************/
174 
tkSetOneColor(int index,float r,float g,float b)175 void tkSetOneColor(int index, float r, float g, float b)
176 {
177     XColor c;
178     int rShift, gShift, bShift;
179 
180     switch (w.vInfoMain->class) {
181       case DirectColor:
182 	rShift = my_ffs((unsigned int)w.vInfoMain->red_mask) - 1;
183 	gShift = my_ffs((unsigned int)w.vInfoMain->green_mask) - 1;
184 	bShift = my_ffs((unsigned int)w.vInfoMain->blue_mask) - 1;
185 	c.pixel = ((index << rShift) & w.vInfoMain->red_mask) |
186 		  ((index << gShift) & w.vInfoMain->green_mask) |
187 		  ((index << bShift) & w.vInfoMain->blue_mask);
188 	c.red = (unsigned short)(r * 65535.0 + 0.5);
189 	c.green = (unsigned short)(g * 65535.0 + 0.5);
190 	c.blue = (unsigned short)(b * 65535.0 + 0.5);
191 	c.flags = DoRed | DoGreen | DoBlue;
192 	XStoreColor(xDisplay, w.cMapMain, &c);
193 	break;
194       case GrayScale:
195       case PseudoColor:
196 	if (index < w.vInfoMain->colormap_size) {
197 	    c.pixel = index;
198 	    c.red = (unsigned short)(r * 65535.0 + 0.5);
199 	    c.green = (unsigned short)(g * 65535.0 + 0.5);
200 	    c.blue = (unsigned short)(b * 65535.0 + 0.5);
201 	    c.flags = DoRed | DoGreen | DoBlue;
202 	    XStoreColor(xDisplay, w.cMapMain, &c);
203 	}
204 	break;
205     }
206 
207     XSync(xDisplay, 0);
208 }
209 
210 /******************************************************************************/
211 
tkSetOverlayMap(int size,float * rgb)212 void tkSetOverlayMap(int size, float *rgb)
213 {
214     XColor c;
215     unsigned long *buf;
216     int max, i;
217 
218     if (w.vInfoOverlay->class == PseudoColor) {
219 	max = (size > w.vInfoOverlay->colormap_size) ?
220 	      w.vInfoOverlay->colormap_size : size;
221 	buf = (unsigned long *)calloc(max, sizeof(unsigned long));
222 	XAllocColorCells(xDisplay, w.cMapOverlay, True, NULL, 0, buf, max);
223 	for (i = 1; i < max; i++) {
224 	    c.pixel = i;
225 	    c.red = (unsigned short)(rgb[i] * 65535.0 + 0.5);
226 	    c.green = (unsigned short)(rgb[size+i] * 65535.0 + 0.5);
227 	    c.blue = (unsigned short)(rgb[size*2+i] * 65535.0 + 0.5);
228 	    c.flags = DoRed | DoGreen | DoBlue;
229 	    XStoreColor(xDisplay, w.cMapOverlay, &c);
230 	}
231 	free(buf);
232     }
233 
234     XSync(xDisplay, 0);
235 }
236 
237 /******************************************************************************/
238 
tkSetRGBMap(int size,float * rgb)239 void tkSetRGBMap(int size, float *rgb)
240 {
241     XColor c;
242     int rShift, gShift, bShift, max, i;
243 
244     switch (w.vInfoMain->class) {
245       case DirectColor:
246 	max = (size > w.vInfoMain->colormap_size) ? w.vInfoMain->colormap_size
247 						  : size;
248 	rShift = my_ffs((unsigned int)w.vInfoMain->red_mask) - 1;
249 	gShift = my_ffs((unsigned int)w.vInfoMain->green_mask) - 1;
250 	bShift = my_ffs((unsigned int)w.vInfoMain->blue_mask) - 1;
251 	c.flags = DoRed | DoGreen | DoBlue;
252 	for (i = 0; i < max; i++) {
253 	    c.pixel = ((i << rShift) & w.vInfoMain->red_mask) |
254 		      ((i << gShift) & w.vInfoMain->green_mask) |
255 		      ((i << bShift) & w.vInfoMain->blue_mask);
256 	    c.red = c.green = c.blue = (unsigned short) (i * 65535 / (max-1));
257 	    XStoreColor(xDisplay, w.cMapMain, &c);
258 	}
259 	break;
260       case GrayScale:
261       case PseudoColor:
262 	max = (size > w.vInfoMain->colormap_size) ? w.vInfoMain->colormap_size
263 						  : size;
264 	for (i = 0; i < max; i++) {
265 	    c.pixel = i;
266 	    c.red = (unsigned short)(rgb[i] * 65535.0 + 0.5);
267 	    c.green = (unsigned short)(rgb[size+i] * 65535.0 + 0.5);
268 	    c.blue = (unsigned short)(rgb[size*2+i] * 65535.0 + 0.5);
269 	    c.flags = DoRed | DoGreen | DoBlue;
270 	    XStoreColor(xDisplay, w.cMapMain, &c);
271 	}
272 	break;
273     }
274 
275     XSync(xDisplay, 0);
276 }
277 
278 /******************************************************************************/
279 
tkSetWindowLevel(GLenum level)280 GLenum tkSetWindowLevel(GLenum level)
281 {
282 
283     switch (level) {
284       case TK_OVERLAY:
285 	if (TK_HAS_OVERLAY(w.type)) {
286 	    if (!glXMakeCurrent(xDisplay, w.wOverlay, w.cOverlay)) {
287 		return GL_FALSE;
288 	    }
289 	} else {
290 	    return GL_FALSE;
291 	}
292 	break;
293       case TK_RGB:
294       case TK_INDEX:
295 	if (!glXMakeCurrent(xDisplay, w.wMain, w.cMain)) {
296 	    return GL_FALSE;
297 	}
298 	break;
299     }
300     return GL_TRUE;
301 }
302 
303 /******************************************************************************/
304