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