1 /* -*- c-basic-offset:2; tab-width:2; indent-tabs-mode:nil -*- */
2
3 #ifndef __EXSB_COMMON_H__
4 #define __EXSB_COMMON_H__
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <X11/Xlib.h>
9
10 /* --- static functions --- */
11
get_closest_xcolor_pseudo(Display * display,int screen,Colormap cmap,XColor * color,XColor * closest_color)12 static void get_closest_xcolor_pseudo(Display *display, int screen, Colormap cmap, XColor *color,
13 XColor *closest_color) {
14 XColor *all_colors;
15 int i;
16 int closest_index = 0;
17 unsigned long min = 0xffffffff;
18 unsigned long diff;
19 unsigned long diff_r = 0, diff_g = 0, diff_b = 0;
20 int ncells = DisplayCells(display, screen);
21
22 all_colors = malloc(ncells * sizeof(XColor));
23
24 /* get all colors from default colormap */
25 for (i = 0; i < ncells; i++) {
26 all_colors[i].pixel = i;
27 }
28 XQueryColors(display, cmap, all_colors, ncells);
29
30 /* find closest color */
31 for (i = 0; i < ncells; i++) {
32 diff_r = (color->red - all_colors[i].red) >> 8;
33 diff_g = (color->green - all_colors[i].green) >> 8;
34 diff_b = (color->blue - all_colors[i].blue) >> 8;
35
36 diff = diff_r * diff_r + diff_g * diff_g + diff_b * diff_b;
37
38 if (diff < min) /* closest ? */
39 {
40 min = diff;
41 closest_index = i;
42 }
43 }
44
45 closest_color->red = all_colors[closest_index].red;
46 closest_color->green = all_colors[closest_index].green;
47 closest_color->blue = all_colors[closest_index].blue;
48 closest_color->flags = DoRed | DoGreen | DoBlue;
49
50 free(all_colors);
51
52 if (XAllocColor(display, cmap, closest_color) == 0) {
53 closest_color->pixel = BlackPixel(display, screen);
54 }
55 }
56
57 /* --- global functions -- */
58
exsb_get_pixel(Display * display,int screen,Colormap cmap,Visual * visual,char * color_name)59 static unsigned long exsb_get_pixel(Display *display, int screen, Colormap cmap, Visual *visual,
60 char *color_name) {
61 XColor color;
62 XColor closest_color;
63
64 if (XParseColor(display, cmap, color_name, &color) == 0) {
65 return BlackPixel(display, screen);
66 }
67
68 if (XAllocColor(display, cmap, &color) == 0) {
69 if (visual->class == PseudoColor || visual->class == GrayScale) {
70 get_closest_xcolor_pseudo(display, screen, cmap, &color, &closest_color);
71 return closest_color.pixel;
72 }
73
74 return BlackPixel(display, screen);
75 }
76
77 return color.pixel;
78 }
79
80 #endif
81