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 | #ifdef HAVE_CONFIG_H1 |
36 | #include <config.h> |
37 | #endif |
38 | #include <stdio.h> |
39 | #include <stdlib.h> |
40 | #include <X11/Xlib.h> |
41 | #include <X11/Xutil.h> |
42 | #include <X11/Xmu/StdCmap.h> |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | static int ROmap(Display*, Colormap, unsigned long[], int, int); |
49 | |
50 | |
51 | static Statusint ROorRWcell(Display*, Colormap, unsigned long[], int, |
52 | XColor*, unsigned long); |
53 | |
54 | |
55 | static Statusint RWcell(Display*, Colormap, XColor*, XColor*, unsigned long*); |
56 | |
57 | |
58 | static int compare(_Xconstconst void*, _Xconstconst void*); |
59 | |
60 | |
61 | static Statusint contiguous(unsigned long[], int, int, unsigned long, int*, int*); |
62 | |
63 | |
64 | static void free_cells(Display*, Colormap, unsigned long[], int, int); |
65 | |
66 | |
67 | static Statusint readonly_map(Display*, XVisualInfo*, XStandardColormap*); |
68 | |
69 | |
70 | static Statusint readwrite_map(Display*, XVisualInfo*, XStandardColormap*); |
71 | |
72 | #define lowbit(x)((x) & (~(x) + 1)) ((x) & (~(x) + 1)) |
73 | #define TRUEMATCH(mult,max,mask)(colormap->max * colormap->mult <= vinfo->mask && ((vinfo->mask) & (~(vinfo->mask) + 1)) == colormap ->mult) \ |
74 | (colormap->max * colormap->mult <= vinfo->mask && \ |
75 | lowbit(vinfo->mask)((vinfo->mask) & (~(vinfo->mask) + 1)) == colormap->mult) |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | Statusint |
98 | XmuCreateColormap(Display *dpy, XStandardColormap *colormap) |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | { |
105 | XVisualInfo vinfo_template; |
106 | XVisualInfo *vinfo; |
107 | XVisualInfo *vpointer; |
108 | long vinfo_mask; |
109 | int n; |
110 | int status; |
111 | |
112 | vinfo_template.visualid = colormap->visualid; |
113 | vinfo_mask = VisualIDMask0x1; |
114 | if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL((void*)0)) |
115 | return 0; |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | vpointer = vinfo; |
123 | if (n > 1) |
124 | { |
125 | register int i; |
126 | register int screen_number; |
127 | Boolint def_cmap; |
128 | |
129 | def_cmap = False0; |
130 | for (screen_number = ScreenCount(dpy)(((_XPrivDisplay)dpy)->nscreens); --screen_number >= 0; ) |
131 | if (colormap->colormap == DefaultColormap(dpy, screen_number)((&((_XPrivDisplay)dpy)->screens[screen_number])->cmap )) { |
132 | def_cmap = True1; |
133 | break; |
134 | } |
135 | |
136 | if (def_cmap) { |
137 | for (i=0; i < n; i++, vinfo++) { |
138 | if (vinfo->visual == DefaultVisual(dpy, screen_number)((&((_XPrivDisplay)dpy)->screens[screen_number])->root_visual )) |
139 | break; |
140 | } |
141 | } else { |
142 | int maxdepth = 0; |
143 | XVisualInfo *v = NULL((void*)0); |
144 | |
145 | for (i=0; i < n; i++, vinfo++) |
146 | if (vinfo->depth > maxdepth) { |
147 | maxdepth = vinfo->depth; |
148 | v = vinfo; |
149 | } |
150 | vinfo = v; |
151 | } |
152 | } |
153 | |
154 | if (vinfo->class == PseudoColor3 || vinfo->class == DirectColor5 || |
155 | vinfo->class == GrayScale1) |
156 | status = readwrite_map(dpy, vinfo, colormap); |
157 | else if (vinfo->class == TrueColor4) |
158 | status = TRUEMATCH(red_mult, red_max, red_mask)(colormap->red_max * colormap->red_mult <= vinfo-> red_mask && ((vinfo->red_mask) & (~(vinfo-> red_mask) + 1)) == colormap->red_mult) && |
159 | TRUEMATCH(green_mult, green_max, green_mask)(colormap->green_max * colormap->green_mult <= vinfo ->green_mask && ((vinfo->green_mask) & (~(vinfo ->green_mask) + 1)) == colormap->green_mult) && |
160 | TRUEMATCH(blue_mult, blue_max, blue_mask)(colormap->blue_max * colormap->blue_mult <= vinfo-> blue_mask && ((vinfo->blue_mask) & (~(vinfo-> blue_mask) + 1)) == colormap->blue_mult); |
161 | else |
162 | status = readonly_map(dpy, vinfo, colormap); |
163 | |
164 | XFree((char *) vpointer); |
165 | return status; |
166 | } |
167 | |
168 | |
169 | static Statusint |
170 | readwrite_map(Display *dpy, XVisualInfo *vinfo, XStandardColormap *colormap) |
171 | { |
172 | register unsigned long i, n; |
173 | unsigned long ncolors; |
174 | int npixels; |
175 | int first_index; |
176 | int remainder; |
177 | XColor color; |
178 | unsigned long *pixels; |
179 | unsigned long delta; |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | if (vinfo->class == DirectColor5) { |
| |
186 | ncolors = colormap->red_max; |
187 | if (colormap->green_max > ncolors) |
188 | ncolors = colormap->green_max; |
189 | if (colormap->blue_max > ncolors) |
190 | ncolors = colormap->blue_max; |
191 | ncolors++; |
192 | delta = lowbit(vinfo->red_mask)((vinfo->red_mask) & (~(vinfo->red_mask) + 1)) + |
193 | lowbit(vinfo->green_mask)((vinfo->green_mask) & (~(vinfo->green_mask) + 1)) + |
194 | lowbit(vinfo->blue_mask)((vinfo->blue_mask) & (~(vinfo->blue_mask) + 1)); |
195 | } else { |
196 | ncolors = colormap->red_max * colormap->red_mult + |
197 | colormap->green_max * colormap->green_mult + |
198 | colormap->blue_max * colormap->blue_mult + 1; |
199 | delta = 1; |
200 | } |
201 | if (ncolors <= 1 || (int) ncolors > vinfo->colormap_size) return 0; |
| 2 | Assuming 'ncolors' is > 1 |
|
| |
202 | |
203 | |
204 | |
205 | |
206 | |
207 | |
208 | |
209 | |
210 | |
211 | |
212 | |
213 | |
214 | |
215 | |
216 | |
217 | |
218 | |
219 | |
220 | |
221 | if ((pixels = (unsigned long *) calloc((unsigned) vinfo->colormap_size, |
| |
222 | sizeof(unsigned long))) == NULL((void*)0)) |
223 | return 0; |
224 | |
225 | if ((npixels = ROmap(dpy, colormap->colormap, pixels, |
| |
226 | vinfo->colormap_size, ncolors)) == 0) { |
227 | free((char *) pixels); |
228 | return 0; |
229 | } |
230 | |
231 | qsort((char *) pixels, npixels, sizeof(unsigned long), compare); |
232 | |
233 | if (!contiguous(pixels, npixels, ncolors, delta, &first_index, &remainder)) |
| |
234 | { |
235 | |
236 | XFreeColors(dpy, colormap->colormap, pixels, npixels, |
237 | (unsigned long) 0); |
238 | free((char *) pixels); |
239 | return 0; |
240 | } |
241 | colormap->base_pixel = pixels[first_index]; |
242 | |
243 | |
244 | if (colormap->red_mult == 1 && colormap->green_mult == 1 && |
| |
245 | colormap->blue_mult == 1) |
246 | for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta) |
247 | { |
248 | color.pixel = n; |
249 | color.blue = color.green = color.red = |
250 | (unsigned short) ((i * 65535) / (colormap->red_max + |
251 | colormap->green_max + |
252 | colormap->blue_max)); |
253 | |
254 | if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, |
255 | first_index + i)) |
256 | return 0; |
257 | } |
258 | |
259 | |
260 | else if (colormap->green_max == 0 && colormap->blue_max == 0) |
| |
261 | for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta) |
262 | { |
263 | color.pixel = n; |
264 | color.red = (unsigned short) ((i * 65535) / colormap->red_max); |
265 | color.green = color.blue = 0; |
266 | |
267 | if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, |
268 | first_index + i)) |
269 | return 0; |
270 | } |
271 | |
272 | |
273 | else if (colormap->red_max == 0 && colormap->blue_max == 0) |
| |
274 | for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta) |
275 | { |
276 | color.pixel = n; |
277 | color.green = (unsigned short) ((i * 65535) / colormap->green_max); |
278 | color.red = color.blue = 0; |
279 | |
280 | if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, |
281 | first_index + i)) |
282 | return 0; |
283 | } |
284 | |
285 | |
286 | else if (colormap->red_max == 0 && colormap->green_max == 0) |
| |
287 | for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta) |
288 | { |
289 | color.pixel = n; |
290 | color.blue = (unsigned short) ((i * 65535) / colormap->blue_max); |
291 | color.red = color.green = 0; |
292 | |
293 | if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, |
294 | first_index + i)) |
295 | return 0; |
296 | } |
297 | |
298 | |
299 | else |
300 | { |
301 | #define calc(max,mult) (((n / colormap->mult) % \ |
302 | (colormap->max + 1)) * 65535) / colormap->max |
303 | |
304 | for (n=0, i=0; i < ncolors; i++, n += delta) |
| 11 | Loop condition is true. Entering loop body |
|
305 | { |
306 | color.pixel = n + colormap->base_pixel; |
307 | color.red = calc(red_max, red_mult); |
308 | color.green = calc(green_max, green_mult); |
| 12 | Within the expansion of the macro 'calc':
|
|
309 | color.blue = calc(blue_max, blue_mult); |
310 | if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, |
311 | first_index + i)) |
312 | return 0; |
313 | } |
314 | #undef calc |
315 | } |
316 | |
317 | |
318 | |
319 | |
320 | |
321 | if (first_index) |
322 | XFreeColors(dpy, colormap->colormap, pixels, first_index, |
323 | (unsigned long) 0); |
324 | if (remainder) |
325 | XFreeColors(dpy, colormap->colormap, |
326 | &(pixels[first_index + ncolors]), remainder, |
327 | (unsigned long) 0); |
328 | |
329 | free((char *) pixels); |
330 | return 1; |
331 | } |
332 | |
333 | |
334 | |
335 | static int |
336 | ROmap(Display *dpy, Colormap cmap, unsigned long pixels[], int m, int n) |
337 | |
338 | |
339 | |
340 | |
341 | |
342 | |
343 | |
344 | { |
345 | register int p; |
346 | |
347 | |
348 | if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL((void*)0), |
349 | (unsigned) 0, pixels, (unsigned) m)) |
350 | return m; |
351 | |
352 | |
353 | |
354 | |
355 | m--; |
356 | while (n <= m) { |
357 | p = n + ((m - n + 1) / 2); |
358 | if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL((void*)0), |
359 | (unsigned) 0, pixels, (unsigned) p)) { |
360 | if (p == m) |
361 | return p; |
362 | else { |
363 | XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0); |
364 | n = p; |
365 | } |
366 | } |
367 | else |
368 | m = p - 1; |
369 | } |
370 | return 0; |
371 | } |
372 | |
373 | |
374 | |
375 | static Statusint |
376 | contiguous(unsigned long pixels[], int npixels, int ncolors, |
377 | unsigned long delta, int *first, int *rem) |
378 | |
379 | |
380 | |
381 | |
382 | |
383 | |
384 | |
385 | { |
386 | register int i = 1; |
387 | register int count = 1; |
388 | |
389 | *first = 0; |
390 | if (npixels == ncolors) { |
391 | *rem = 0; |
392 | return 1; |
393 | } |
394 | *rem = npixels - 1; |
395 | while (count < ncolors && ncolors - count <= *rem) |
396 | { |
397 | if (pixels[i-1] + delta == pixels[i]) |
398 | count++; |
399 | else { |
400 | count = 1; |
401 | *first = i; |
402 | } |
403 | i++; |
404 | (*rem)--; |
405 | } |
406 | if (count != ncolors) |
407 | return 0; |
408 | return 1; |
409 | } |
410 | |
411 | |
412 | |
413 | static Statusint |
414 | ROorRWcell(Display *dpy, Colormap cmap, unsigned long pixels[], |
415 | int npixels, XColor *color, unsigned long p) |
416 | { |
417 | unsigned long pixel; |
418 | XColor request; |
419 | |
420 | |
421 | |
422 | |
423 | |
424 | |
425 | |
426 | |
427 | |
428 | |
429 | |
430 | |
431 | |
432 | pixel = color->pixel; |
433 | request.red = color->red; |
434 | request.green = color->green; |
435 | request.blue = color->blue; |
436 | |
437 | XFreeColors(dpy, cmap, &pixel, 1, (unsigned long) 0); |
438 | if (! XAllocColor(dpy, cmap, color) |
439 | || (color->pixel != pixel && |
440 | (!RWcell(dpy, cmap, color, &request, &pixel)))) |
441 | { |
442 | free_cells(dpy, cmap, pixels, npixels, (int)p); |
443 | return 0; |
444 | } |
445 | return 1; |
446 | } |
447 | |
448 | |
449 | |
450 | static void |
451 | free_cells(Display *dpy, Colormap cmap, unsigned long pixels[], |
452 | int npixels, int p) |
453 | |
454 | |
455 | |
456 | |
457 | { |
458 | |
459 | |
460 | |
461 | |
462 | |
463 | XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0); |
464 | XFreeColors(dpy, cmap, &(pixels[p+1]), npixels - p - 1, (unsigned long) 0); |
465 | free((char *) pixels); |
466 | } |
467 | |
468 | |
469 | |
470 | static Statusint |
471 | RWcell(Display *dpy, Colormap cmap, XColor *color, XColor *request, |
472 | unsigned long *pixel) |
473 | { |
474 | unsigned long n = *pixel; |
475 | |
476 | XFreeColors(dpy, cmap, &(color->pixel), 1, (unsigned long)0); |
477 | if (! XAllocColorCells(dpy, cmap, (Boolint) 0, (unsigned long *) NULL((void*)0), |
478 | (unsigned) 0, pixel, (unsigned) 1)) |
479 | return 0; |
480 | if (*pixel != n) |
481 | { |
482 | XFreeColors(dpy, cmap, pixel, 1, (unsigned long) 0); |
483 | return 0; |
484 | } |
485 | color->pixel = *pixel; |
486 | color->flags = DoRed(1<<0) | DoGreen(1<<1) | DoBlue(1<<2); |
487 | color->red = request->red; |
488 | color->green = request->green; |
489 | color->blue = request->blue; |
490 | XStoreColors(dpy, cmap, color, 1); |
491 | return 1; |
492 | } |
493 | |
494 | |
495 | |
496 | static int |
497 | compare(_Xconstconst void *e1, _Xconstconst void *e2) |
498 | { |
499 | return ((int)(*(long *)e1 - *(long *)e2)); |
500 | } |
501 | |
502 | |
503 | |
504 | static Statusint |
505 | readonly_map(Display *dpy, XVisualInfo *vinfo, XStandardColormap *colormap) |
506 | { |
507 | int i, last_pixel; |
508 | XColor color; |
509 | |
510 | last_pixel = (colormap->red_max + 1) * (colormap->green_max + 1) * |
511 | (colormap->blue_max + 1) + colormap->base_pixel - 1; |
512 | |
513 | for(i=colormap->base_pixel; i <= last_pixel; i++) { |
514 | |
515 | color.pixel = (unsigned long) i; |
516 | color.red = (unsigned short) |
517 | (((i/colormap->red_mult) * 65535) / colormap->red_max); |
518 | |
519 | if (vinfo->class == StaticColor2) { |
520 | color.green = (unsigned short) |
521 | ((((i/colormap->green_mult) % (colormap->green_max + 1)) * |
522 | 65535) / colormap->green_max); |
523 | color.blue = (unsigned short) |
524 | (((i%colormap->green_mult) * 65535) / colormap->blue_max); |
525 | } |
526 | else |
527 | color.green = color.blue = color.red; |
528 | |
529 | XAllocColor(dpy, colormap->colormap, &color); |
530 | if (color.pixel != (unsigned long) i) |
531 | return 0; |
532 | } |
533 | return 1; |
534 | } |