From dd7595a3475407a7fa96a97393bae8c5220e8762 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Wed, 4 Jan 2012 18:41:13 +1000 Subject: Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje. Note that embryo wont be used, but I'm not sure yet if you can build edje without it. --- .../modules/engines/software_x11/evas_xcb_color.c | 424 +++++++++++++++++++++ 1 file changed, 424 insertions(+) create mode 100644 libraries/evas/src/modules/engines/software_x11/evas_xcb_color.c (limited to 'libraries/evas/src/modules/engines/software_x11/evas_xcb_color.c') 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 @@ +#include "evas_common.h" + +#include "evas_engine.h" + +typedef struct _Convert_Pal_Priv Convert_Pal_Priv; + +struct _Convert_Pal_Priv +{ + xcb_connection_t *conn; + xcb_colormap_t cmap; + xcb_visualtype_t *vis; +}; + +typedef DATA8 * (*Xcb_Func_Alloc_Colors) (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); + +static Xcb_Func_Alloc_Colors x_color_alloc[PAL_MODE_LAST + 1]; +static int x_color_count[PAL_MODE_LAST + 1]; +static Eina_List *palettes = NULL; + +static DATA8 * x_color_alloc_rgb(int nr, int ng, int nb, xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); +static DATA8 * x_color_alloc_gray(int ng, xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); + +static DATA8 * x_color_alloc_rgb_332 (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); +static DATA8 * x_color_alloc_rgb_666 (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); +static DATA8 * x_color_alloc_rgb_232 (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); +static DATA8 * x_color_alloc_rgb_222 (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); +static DATA8 * x_color_alloc_rgb_221 (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); +static DATA8 * x_color_alloc_rgb_121 (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); +static DATA8 * x_color_alloc_rgb_111 (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); +static DATA8 * x_color_alloc_gray_256 (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); +static DATA8 * x_color_alloc_gray_64 (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); +static DATA8 * x_color_alloc_gray_16 (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); +static DATA8 * x_color_alloc_gray_4 (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); +static DATA8 * x_color_alloc_mono (xcb_connection_t *conn, xcb_colormap_t cmap, xcb_visualtype_t *v); + +static DATA8 * +x_color_alloc_rgb(int nr, + int ng, + int nb, + xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + int r, g, b, i; + DATA8 *color_lut; + int sig_mask = 0; + int delt = 0; + + for (i = 0; i < v->bits_per_rgb_value; i++) sig_mask |= (0x1 << i); + sig_mask <<= (16 - v->bits_per_rgb_value); + i = 0; + color_lut = malloc((nr) * (ng) * (nb)); + if (!color_lut) return NULL; + delt = 0x0101 * 3; + /* FIXME: remove the round-trip ? */ + for (r = 0; r < (nr); r++) + { + for (g = 0; g < (ng); g++) + { + for (b = 0; b < (nb); b++) + { + xcb_coloritem_t xcl; + xcb_coloritem_t xcl_in; + xcb_alloc_color_reply_t *rep; + int val; + int dr, dg, db; + + val = (int)((((double)r) / ((nr) - 1)) * 255); + val = (val << 8) | val; + xcl.red = (uint16_t)(val); + val = (int)((((double)g) / ((ng) - 1)) * 255); + val = (val << 8) | val; + xcl.green = (uint16_t)(val); + val = (int)((((double)b) / ((nb) - 1)) * 255); + val = (val << 8) | val; + xcl.blue = (uint16_t)(val); + xcl_in = xcl; + rep = xcb_alloc_color_reply(conn, + xcb_alloc_color_unchecked(conn, + cmap, + xcl.red, + xcl.green, + xcl.blue), + 0); + dr = (int)xcl_in.red - (int)xcl.red; + if (dr < 0) dr = -dr; + dg = (int)xcl_in.green - (int)xcl.green; + if (dg < 0) dg = -dg; + db = (int)xcl_in.blue - (int)xcl.blue; + if (db < 0) db = -db; +/* + printf("ASK [%i]: %04x %04x %04x = %04x %04x %04x | dif = %04x / %04x\n", + ret, + xcl_in.red, xcl_in.green, xcl_in.blue, + xcl.red, xcl.green, xcl.blue, + (dr + dg +db), delt); + */ + + /* TODO: XAllocColor tries to approach the color */ + /* in case the allocation fails */ + /* XCB does not that (i think). It should be done */ + /* So if rep == NULL, the other following tests */ + /* should be always satisfied */ + if ((!rep) || + ((dr + dg + db) > delt) + /* + ((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) || + ((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) || + ((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask)) + */ + ) + { + uint32_t pixels[256]; + int j; + + if (i > 0) + { + for (j = 0; j < i; j++) + pixels[j] = (uint32_t)color_lut[j]; + xcb_free_colors(conn, cmap, 0, i, pixels); + } + free(color_lut); + return NULL; + } + color_lut[i] = rep->pixel; + i++; + free(rep); + } + } + } + return color_lut; +} + +static DATA8 * +x_color_alloc_gray(int ng, + xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + int g, i; + DATA8 *color_lut; + int sig_mask = 0; + + for (i = 0; i < v->bits_per_rgb_value; i++) sig_mask |= (0x1 << i); + sig_mask <<= (16 - v->bits_per_rgb_value); + i = 0; + color_lut = malloc(ng); + if (!color_lut) return NULL; + /* FIXME: remove the round-trip ? */ + for (g = 0; g < (ng); g++) + { + xcb_coloritem_t xcl; + xcb_coloritem_t xcl_in; + int val; + xcb_alloc_color_reply_t *rep; + + val = (int)((((double)g) / ((ng) - 1)) * 255); + val = (val << 8) | val; + xcl.red = (uint16_t)(val); + xcl.green = (uint16_t)(val); + xcl.blue = (uint16_t)(val); + xcl_in = xcl; + rep = xcb_alloc_color_reply(conn, + xcb_alloc_color_unchecked(conn, + cmap, + xcl.red, + xcl.green, + xcl.blue), + 0); + /* FIXME: XAllocColor tries to approach the color */ + /* in case the allocation fails */ + /* XCB does not that (i think). It should be done */ + /* So if rep == NULL, the other following tests */ + /* should be always satisfied */ + if ((!rep) || + ((xcl_in.red & sig_mask) != (xcl.red & sig_mask)) || + ((xcl_in.green & sig_mask) != (xcl.green & sig_mask)) || + ((xcl_in.blue & sig_mask) != (xcl.blue & sig_mask))) + { + uint32_t pixels[256]; + int j; + + if (i > 0) + { + for (j = 0; j < i; j++) + pixels[j] = (uint32_t) color_lut[j]; + xcb_free_colors(conn, cmap, 0, i, pixels); + } + free(color_lut); + return NULL; + } + color_lut[i] = rep->pixel; + i++; + free(rep); + } + return color_lut; +} + +static DATA8 * +x_color_alloc_rgb_332(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + return x_color_alloc_rgb(8, 8, 4, conn, cmap, v); +} + +static DATA8 * +x_color_alloc_rgb_666(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + return x_color_alloc_rgb(6, 6, 6, conn, cmap, v); +} + +static DATA8 * +x_color_alloc_rgb_232(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + return x_color_alloc_rgb(4, 8, 4, conn, cmap, v); +} + +static DATA8 * +x_color_alloc_rgb_222(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + return x_color_alloc_rgb(4, 4, 4, conn, cmap, v); +} + +static DATA8 * +x_color_alloc_rgb_221(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + return x_color_alloc_rgb(4, 4, 2, conn, cmap, v); +} + +static DATA8 * +x_color_alloc_rgb_121(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + return x_color_alloc_rgb(2, 4, 2, conn, cmap, v); +} + +static DATA8 * +x_color_alloc_rgb_111(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + return x_color_alloc_rgb(2, 2, 2, conn, cmap, v); +} + +static DATA8 * +x_color_alloc_gray_256(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + return x_color_alloc_gray(256, conn, cmap, v); +} + +static DATA8 * +x_color_alloc_gray_64(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + return x_color_alloc_gray(64, conn, cmap, v); +} + +static DATA8 * +x_color_alloc_gray_16(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + return x_color_alloc_gray(32, conn, cmap, v); +} + +static DATA8 * +x_color_alloc_gray_4(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + return x_color_alloc_gray(16, conn, cmap, v); +} + +static DATA8 * +x_color_alloc_mono(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *v) +{ + return x_color_alloc_gray(2, conn, cmap, v); +} + +void +evas_software_xcb_color_init(void) +{ + static int initialised = 0; + + if (initialised) return; + x_color_alloc[PAL_MODE_NONE] = NULL; + x_color_count[PAL_MODE_NONE] = 0; + + x_color_alloc[PAL_MODE_MONO] = x_color_alloc_mono; + x_color_count[PAL_MODE_MONO] = 2; + + x_color_alloc[PAL_MODE_GRAY4] = x_color_alloc_gray_4; + x_color_count[PAL_MODE_GRAY4] = 4; + + x_color_alloc[PAL_MODE_GRAY16] = x_color_alloc_gray_16; + x_color_count[PAL_MODE_GRAY16] = 16; + + x_color_alloc[PAL_MODE_GRAY64] = x_color_alloc_gray_64; + x_color_count[PAL_MODE_GRAY64] = 64; + + x_color_alloc[PAL_MODE_GRAY256] = x_color_alloc_gray_256; + x_color_count[PAL_MODE_GRAY256] = 256; + + x_color_alloc[PAL_MODE_RGB111] = x_color_alloc_rgb_111; + x_color_count[PAL_MODE_RGB111] = 2 * 2 * 2; + + x_color_alloc[PAL_MODE_RGB121] = x_color_alloc_rgb_121; + x_color_count[PAL_MODE_RGB121] = 2 * 4 * 2; + + x_color_alloc[PAL_MODE_RGB221] = x_color_alloc_rgb_221; + x_color_count[PAL_MODE_RGB221] = 4 * 4 * 2; + + x_color_alloc[PAL_MODE_RGB222] = x_color_alloc_rgb_222; + x_color_count[PAL_MODE_RGB222] = 4 * 4 * 4; + + x_color_alloc[PAL_MODE_RGB232] = x_color_alloc_rgb_232; + x_color_count[PAL_MODE_RGB232] = 4 * 8 * 4; + + x_color_alloc[PAL_MODE_RGB666] = x_color_alloc_rgb_666; + x_color_count[PAL_MODE_RGB666] = 6 * 6 * 6; + + x_color_alloc[PAL_MODE_RGB332] = x_color_alloc_rgb_332; + x_color_count[PAL_MODE_RGB332] = 8 * 8 * 4; + + x_color_alloc[PAL_MODE_LAST] = NULL; + x_color_count[PAL_MODE_LAST] = 0; + initialised = 1; +} + +Convert_Pal * +evas_software_xcb_color_allocate(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *vis, + Convert_Pal_Mode colors) +{ + Convert_Pal_Priv *palpriv; + Convert_Pal *pal; + Convert_Pal_Mode c; + Eina_List *l; + +/* printf("ALLOC cmap=%i vis=%p\n", cmap, vis);*/ + EINA_LIST_FOREACH(palettes, l, pal) + { + palpriv = pal->data; + if ((conn == palpriv->conn) && + (vis == palpriv->vis) && + (cmap == palpriv->cmap)) + { + pal->references++; + return pal; + } + } + pal = calloc(1, sizeof(struct _Convert_Pal)); + if (!pal) return NULL; + for (c = colors; c > PAL_MODE_NONE; c--) + { + if (x_color_alloc[c]) + { +/* printf("TRY PAL %i\n", c);*/ + pal->lookup = (x_color_alloc[c])(conn, cmap, vis); + if (pal->lookup) break; + } + } + pal->references = 1; + pal->colors = c; + pal->count = x_color_count[c]; + palpriv = calloc(1, sizeof(Convert_Pal_Priv)); + pal->data = palpriv; + if (!palpriv) + { + if (pal->lookup) free(pal->lookup); + free(pal); + return NULL; + } + palpriv->conn = conn; + palpriv->vis = vis; + palpriv->cmap = cmap; + if (pal->colors == PAL_MODE_NONE) + { + if (pal->lookup) free(pal->lookup); + free(pal); + return NULL; + } + palettes = eina_list_append(palettes, pal); + return pal; +} + +void +evas_software_xcb_color_deallocate(xcb_connection_t *conn, + xcb_colormap_t cmap, + xcb_visualtype_t *vis __UNUSED__, + Convert_Pal *pal) +{ + uint32_t pixels[256]; + int j; + + pal->references--; + if (pal->references > 0) return; + if (pal->lookup) + { + for(j = 0; j < pal->count; j++) + pixels[j] = (uint32_t) pal->lookup[j]; + xcb_free_colors(conn, cmap, 0, pal->count, pixels); + free(pal->lookup); + } + free(pal->data); + palettes = eina_list_remove(palettes, pal); + free(pal); +} -- cgit v1.1