aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/software_x11/evas_xlib_color.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/engines/software_x11/evas_xlib_color.c')
-rw-r--r--libraries/evas/src/modules/engines/software_x11/evas_xlib_color.c368
1 files changed, 368 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/software_x11/evas_xlib_color.c b/libraries/evas/src/modules/engines/software_x11/evas_xlib_color.c
new file mode 100644
index 0000000..1df0406
--- /dev/null
+++ b/libraries/evas/src/modules/engines/software_x11/evas_xlib_color.c
@@ -0,0 +1,368 @@
1#include "evas_common.h"
2
3#include "evas_engine.h"
4
5#include <X11/Xlib.h>
6#include <X11/Xutil.h>
7
8typedef struct _Convert_Pal_Priv Convert_Pal_Priv;
9
10struct _Convert_Pal_Priv
11{
12 Display *disp;
13 Colormap cmap;
14 Visual *vis;
15};
16
17typedef DATA8 * (*X_Func_Alloc_Colors) (Display *d, Colormap cmap, Visual *v);
18
19static X_Func_Alloc_Colors x_color_alloc[PAL_MODE_LAST + 1];
20static int x_color_count[PAL_MODE_LAST + 1];
21static Eina_List *palettes = NULL;
22
23static DATA8 * x_color_alloc_rgb(int nr, int ng, int nb, Display *d, Colormap cmap, Visual *v);
24static DATA8 * x_color_alloc_gray(int ng, Display *d, Colormap cmap, Visual *v);
25
26static DATA8 * x_color_alloc_rgb_332(Display *d, Colormap cmap, Visual *v);
27static DATA8 * x_color_alloc_rgb_666(Display *d, Colormap cmap, Visual *v);
28static DATA8 * x_color_alloc_rgb_232(Display *d, Colormap cmap, Visual *v);
29static DATA8 * x_color_alloc_rgb_222(Display *d, Colormap cmap, Visual *v);
30static DATA8 * x_color_alloc_rgb_221(Display *d, Colormap cmap, Visual *v);
31static DATA8 * x_color_alloc_rgb_121(Display *d, Colormap cmap, Visual *v);
32static DATA8 * x_color_alloc_rgb_111(Display *d, Colormap cmap, Visual *v);
33static DATA8 * x_color_alloc_gray_256(Display *d, Colormap cmap, Visual *v);
34static DATA8 * x_color_alloc_gray_64(Display *d, Colormap cmap, Visual *v);
35static DATA8 * x_color_alloc_gray_16(Display *d, Colormap cmap, Visual *v);
36static DATA8 * x_color_alloc_gray_4(Display *d, Colormap cmap, Visual *v);
37static DATA8 * x_color_alloc_mono(Display *d, Colormap cmap, Visual *v);
38
39static DATA8 *
40x_color_alloc_rgb(int nr, int ng, int nb, Display *d, Colormap cmap, Visual *v)
41{
42 int r, g, b, i;
43 DATA8 *color_lut;
44 int sig_mask = 0, delt = 0;
45
46 for (i = 0; i < v->bits_per_rgb; i++) sig_mask |= (0x1 << i);
47 sig_mask <<= (16 - v->bits_per_rgb);
48 i = 0;
49 color_lut = malloc((nr) * (ng) * (nb));
50 if (!color_lut) return NULL;
51 delt = 0x0101 * 3;
52 for (r = 0; r < (nr); r++)
53 {
54 for (g = 0; g < (ng); g++)
55 {
56 for (b = 0; b < (nb); b++)
57 {
58 XColor xcl;
59 XColor xcl_in;
60 int val;
61 Status ret;
62 int dr, dg, db;
63
64 val = (int)((((double)r) / ((nr) - 1)) * 255);
65 val = (val << 8) | val;
66 xcl.red = (unsigned short)(val);
67 val = (int)((((double)g) / ((ng) - 1)) * 255);
68 val = (val << 8) | val;
69 xcl.green = (unsigned short)(val);
70 val = (int)((((double)b) / ((nb) - 1)) * 255);
71 val = (val << 8) | val;
72 xcl.blue = (unsigned short)(val);
73 xcl_in = xcl;
74 ret = XAllocColor(d, cmap, &xcl);
75 dr = (int)xcl_in.red - (int)xcl.red;
76 if (dr < 0) dr = -dr;
77 dg = (int)xcl_in.green - (int)xcl.green;
78 if (dg < 0) dg = -dg;
79 db = (int)xcl_in.blue - (int)xcl.blue;
80 if (db < 0) db = -db;
81/*
82 printf("ASK [%i]: %04x %04x %04x = %04x %04x %04x | dif = %04x / %04x\n",
83 ret,
84 xcl_in.red, xcl_in.green, xcl_in.blue,
85 xcl.red, xcl.green, xcl.blue,
86 (dr + dg +db), delt);
87 */
88 if ((ret == 0) ||
89 ((dr + dg + db) > delt)
90/*
91 ||
92 ((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) ||
93 ((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) ||
94 ((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask))
95 */
96 )
97 {
98 unsigned long pixels[256];
99 int j;
100
101 if (i > 0)
102 {
103 for (j = 0; j < i; j++)
104 pixels[j] = (unsigned long) color_lut[j];
105 XFreeColors(d, cmap, pixels, i, 0);
106 }
107 free(color_lut);
108 return NULL;
109 }
110 color_lut[i] = xcl.pixel;
111 i++;
112 }
113 }
114 }
115 return color_lut;
116}
117
118static DATA8 *
119x_color_alloc_gray(int ng, Display *d, Colormap cmap, Visual *v)
120{
121 int g, i;
122 DATA8 *color_lut;
123 int sig_mask = 0;
124
125 for (i = 0; i < v->bits_per_rgb; i++) sig_mask |= (0x1 << i);
126 sig_mask <<= (16 - v->bits_per_rgb);
127 i = 0;
128 color_lut = malloc(ng);
129 if (!color_lut) return NULL;
130 for (g = 0; g < (ng); g++)
131 {
132 XColor xcl;
133 XColor xcl_in;
134 int val;
135 Status ret;
136
137 val = (int)((((double)g) / ((ng) - 1)) * 255);
138 val = (val << 8) | val;
139 xcl.red = (unsigned short)(val);
140 xcl.green = (unsigned short)(val);
141 xcl.blue = (unsigned short)(val);
142 xcl_in = xcl;
143 ret = XAllocColor(d, cmap, &xcl);
144 if ((ret == 0) ||
145 ((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) ||
146 ((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) ||
147 ((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask)))
148 {
149 unsigned long pixels[256];
150 int j;
151
152 if (i > 0)
153 {
154 for (j = 0; j < i; j++)
155 pixels[j] = (unsigned long) color_lut[j];
156 XFreeColors(d, cmap, pixels, i, 0);
157 }
158 free(color_lut);
159 return NULL;
160 }
161 color_lut[i] = xcl.pixel;
162 i++;
163 }
164 return color_lut;
165}
166
167static DATA8 *
168x_color_alloc_rgb_332(Display *d, Colormap cmap, Visual *v)
169{
170 return x_color_alloc_rgb(8, 8, 4, d, cmap, v);
171}
172
173static DATA8 *
174x_color_alloc_rgb_666(Display *d, Colormap cmap, Visual *v)
175{
176 return x_color_alloc_rgb(6, 6, 6, d, cmap, v);
177}
178
179static DATA8 *
180x_color_alloc_rgb_232(Display *d, Colormap cmap, Visual *v)
181{
182 return x_color_alloc_rgb(4, 8, 4, d, cmap, v);
183}
184
185static DATA8 *
186x_color_alloc_rgb_222(Display *d, Colormap cmap, Visual *v)
187{
188 return x_color_alloc_rgb(4, 4, 4, d, cmap, v);
189}
190
191static DATA8 *
192x_color_alloc_rgb_221(Display *d, Colormap cmap, Visual *v)
193{
194 return x_color_alloc_rgb(4, 4, 2, d, cmap, v);
195}
196
197static DATA8 *
198x_color_alloc_rgb_121(Display *d, Colormap cmap, Visual *v)
199{
200 return x_color_alloc_rgb(2, 4, 2, d, cmap, v);
201}
202
203static DATA8 *
204x_color_alloc_rgb_111(Display *d, Colormap cmap, Visual *v)
205{
206 return x_color_alloc_rgb(2, 2, 2, d, cmap, v);
207}
208
209static DATA8 *
210x_color_alloc_gray_256(Display *d, Colormap cmap, Visual *v)
211{
212 return x_color_alloc_gray(256, d, cmap, v);
213}
214
215static DATA8 *
216x_color_alloc_gray_64(Display *d, Colormap cmap, Visual *v)
217{
218 return x_color_alloc_gray(64, d, cmap, v);
219}
220
221static DATA8 *
222x_color_alloc_gray_16(Display *d, Colormap cmap, Visual *v)
223{
224 return x_color_alloc_gray(32, d, cmap, v);
225}
226
227static DATA8 *
228x_color_alloc_gray_4(Display *d, Colormap cmap, Visual *v)
229{
230 return x_color_alloc_gray(16, d, cmap, v);
231}
232
233static DATA8 *
234x_color_alloc_mono(Display *d, Colormap cmap, Visual *v)
235{
236 return x_color_alloc_gray(2, d, cmap, v);
237}
238
239void
240evas_software_xlib_x_color_init(void)
241{
242 static int initialised = 0;
243
244 if (initialised) return;
245 x_color_alloc[PAL_MODE_NONE] = NULL;
246 x_color_count[PAL_MODE_NONE] = 0;
247
248 x_color_alloc[PAL_MODE_MONO] = x_color_alloc_mono;
249 x_color_count[PAL_MODE_MONO] = 2;
250
251 x_color_alloc[PAL_MODE_GRAY4] = x_color_alloc_gray_4;
252 x_color_count[PAL_MODE_GRAY4] = 4;
253
254 x_color_alloc[PAL_MODE_GRAY16] = x_color_alloc_gray_16;
255 x_color_count[PAL_MODE_GRAY16] = 16;
256
257 x_color_alloc[PAL_MODE_GRAY64] = x_color_alloc_gray_64;
258 x_color_count[PAL_MODE_GRAY64] = 64;
259
260 x_color_alloc[PAL_MODE_GRAY256] = x_color_alloc_gray_256;
261 x_color_count[PAL_MODE_GRAY256] = 256;
262
263 x_color_alloc[PAL_MODE_RGB111] = x_color_alloc_rgb_111;
264 x_color_count[PAL_MODE_RGB111] = 2 * 2 * 2;
265
266 x_color_alloc[PAL_MODE_RGB121] = x_color_alloc_rgb_121;
267 x_color_count[PAL_MODE_RGB121] = 2 * 4 * 2;
268
269 x_color_alloc[PAL_MODE_RGB221] = x_color_alloc_rgb_221;
270 x_color_count[PAL_MODE_RGB221] = 4 * 4 * 2;
271
272 x_color_alloc[PAL_MODE_RGB222] = x_color_alloc_rgb_222;
273 x_color_count[PAL_MODE_RGB222] = 4 * 4 * 4;
274
275 x_color_alloc[PAL_MODE_RGB232] = x_color_alloc_rgb_232;
276 x_color_count[PAL_MODE_RGB232] = 4 * 8 * 4;
277
278 x_color_alloc[PAL_MODE_RGB666] = x_color_alloc_rgb_666;
279 x_color_count[PAL_MODE_RGB666] = 6 * 6 * 6;
280
281 x_color_alloc[PAL_MODE_RGB332] = x_color_alloc_rgb_332;
282 x_color_count[PAL_MODE_RGB332] = 8 * 8 * 4;
283
284 x_color_alloc[PAL_MODE_LAST] = NULL;
285 x_color_count[PAL_MODE_LAST] = 0;
286 initialised = 1;
287}
288
289Convert_Pal *
290evas_software_xlib_x_color_allocate(Display *disp,
291 Colormap cmap,
292 Visual *vis,
293 Convert_Pal_Mode colors)
294{
295 Convert_Pal_Priv *palpriv;
296 Convert_Pal *pal;
297 Convert_Pal_Mode c;
298 Eina_List *l;
299
300/* printf("ALLOC cmap=%i vis=%p\n", cmap, vis);*/
301 EINA_LIST_FOREACH(palettes, l, pal)
302 {
303 palpriv = pal->data;
304 if ((disp == palpriv->disp) &&
305 (vis == palpriv->vis) &&
306 (cmap == palpriv->cmap))
307 {
308 pal->references++;
309 return pal;
310 }
311 }
312 pal = calloc(1, sizeof(struct _Convert_Pal));
313 if (!pal) return NULL;
314 for (c = colors; c > PAL_MODE_NONE; c--)
315 {
316 if (x_color_alloc[c])
317 {
318/* printf("TRY PAL %i\n", c);*/
319 pal->lookup = (x_color_alloc[c])(disp, cmap, vis);
320 if (pal->lookup) break;
321 }
322 }
323 pal->references = 1;
324 pal->colors = c;
325 pal->count = x_color_count[c];
326 palpriv = calloc(1, sizeof(Convert_Pal_Priv));
327 pal->data = palpriv;
328 if (!palpriv)
329 {
330 if (pal->lookup) free(pal->lookup);
331 free(pal);
332 return NULL;
333 }
334 palpriv->disp = disp;
335 palpriv->vis = vis;
336 palpriv->cmap = cmap;
337 if (pal->colors == PAL_MODE_NONE)
338 {
339 if (pal->lookup) free(pal->lookup);
340 free(pal);
341 return NULL;
342 }
343 palettes = eina_list_append(palettes, pal);
344 return pal;
345}
346
347void
348evas_software_xlib_x_color_deallocate(Display *disp,
349 Colormap cmap,
350 Visual *vis __UNUSED__,
351 Convert_Pal *pal)
352{
353 unsigned long pixels[256];
354 int j;
355
356 pal->references--;
357 if (pal->references > 0) return;
358 if (pal->lookup)
359 {
360 for(j = 0; j < pal->count; j++)
361 pixels[j] = (unsigned long) pal->lookup[j];
362 XFreeColors(disp, cmap, pixels, pal->count, 0);
363 free(pal->lookup);
364 }
365 free(pal->data);
366 palettes = eina_list_remove(palettes, pal);
367 free(pal);
368}