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