forked from enlightenment/efl
338 lines
9.9 KiB
C
338 lines
9.9 KiB
C
#include "evas_common.h"
|
|
#include "evas_engine.h"
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
|
|
typedef struct _Convert_Pal_Priv Convert_Pal_Priv;
|
|
|
|
struct _Convert_Pal_Priv
|
|
{
|
|
Display *disp;
|
|
Colormap cmap;
|
|
Visual *vis;
|
|
};
|
|
|
|
typedef DATA8 * (*X_Func_Alloc_Colors) (Display *d, Colormap cmap, Visual *v);
|
|
|
|
static X_Func_Alloc_Colors x_software_x11_color_alloc[PAL_MODE_LAST + 1];
|
|
static int x_software_x11_color_count[PAL_MODE_LAST + 1];
|
|
static Evas_List *palettes = NULL;
|
|
|
|
static DATA8 * x_software_x11_color_alloc_rgb(int nr, int ng, int nb, Display *d, Colormap cmap, Visual *v);
|
|
static DATA8 * x_software_x11_color_alloc_gray(int ng, Display *d, Colormap cmap, Visual *v);
|
|
|
|
static DATA8 * x_software_x11_color_alloc_rgb_332(Display *d, Colormap cmap, Visual *v);
|
|
static DATA8 * x_software_x11_color_alloc_rgb_666(Display *d, Colormap cmap, Visual *v);
|
|
static DATA8 * x_software_x11_color_alloc_rgb_232(Display *d, Colormap cmap, Visual *v);
|
|
static DATA8 * x_software_x11_color_alloc_rgb_222(Display *d, Colormap cmap, Visual *v);
|
|
static DATA8 * x_software_x11_color_alloc_rgb_221(Display *d, Colormap cmap, Visual *v);
|
|
static DATA8 * x_software_x11_color_alloc_rgb_121(Display *d, Colormap cmap, Visual *v);
|
|
static DATA8 * x_software_x11_color_alloc_rgb_111(Display *d, Colormap cmap, Visual *v);
|
|
static DATA8 * x_software_x11_color_alloc_gray_256(Display *d, Colormap cmap, Visual *v);
|
|
static DATA8 * x_software_x11_color_alloc_gray_64(Display *d, Colormap cmap, Visual *v);
|
|
static DATA8 * x_software_x11_color_alloc_gray_16(Display *d, Colormap cmap, Visual *v);
|
|
static DATA8 * x_software_x11_color_alloc_gray_4(Display *d, Colormap cmap, Visual *v);
|
|
static DATA8 * x_software_x11_color_alloc_mono(Display *d, Colormap cmap, Visual *v);
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_rgb(int nr, int ng, int nb, Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
int r, g, b, i;
|
|
DATA8 *color_lut;
|
|
int sig_mask = 0;
|
|
|
|
for (i = 0; i < v->bits_per_rgb; i++) sig_mask |= (0x1 << i);
|
|
sig_mask <<= (16 - v->bits_per_rgb);
|
|
i = 0;
|
|
color_lut = malloc((nr) * (ng) * (nb));
|
|
if (!color_lut) return NULL;
|
|
for (r = 0; r < (nr); r++)
|
|
{
|
|
for (g = 0; g < (ng); g++)
|
|
{
|
|
for (b = 0; b < (nb); b++)
|
|
{
|
|
XColor xcl;
|
|
XColor xcl_in;
|
|
int val;
|
|
Status ret;
|
|
|
|
val = (int)((((double)r) / ((nr) - 1)) * 65535);
|
|
xcl.red = (unsigned short)(val);
|
|
val = (int)((((double)g) / ((ng) - 1)) * 65535);
|
|
xcl.green = (unsigned short)(val);
|
|
val = (int)((((double)b) / ((nb) - 1)) * 65535);
|
|
xcl.blue = (unsigned short)(val);
|
|
xcl_in = xcl;
|
|
ret = XAllocColor(d, cmap, &xcl);
|
|
if ((ret == Success) ||
|
|
((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)))
|
|
{
|
|
unsigned long pixels[256];
|
|
int j;
|
|
|
|
if (i > 0)
|
|
{
|
|
for(j = 0; j < i; j++)
|
|
pixels[j] = (unsigned long) color_lut[j];
|
|
XFreeColors(d, cmap, pixels, i, 0);
|
|
}
|
|
free(color_lut);
|
|
return NULL;
|
|
}
|
|
color_lut[i] = xcl.pixel;
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
return color_lut;
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_gray(int ng, Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
int g, i;
|
|
DATA8 *color_lut;
|
|
int sig_mask = 0;
|
|
|
|
for (i = 0; i < v->bits_per_rgb; i++) sig_mask |= (0x1 << i);
|
|
sig_mask <<= (16 - v->bits_per_rgb);
|
|
i = 0;
|
|
color_lut = malloc(ng);
|
|
if (!color_lut) return NULL;
|
|
for (g = 0; g < (ng); g++)
|
|
{
|
|
XColor xcl;
|
|
XColor xcl_in;
|
|
int val;
|
|
Status ret;
|
|
|
|
val = (int)((((double)g) / ((ng) - 1)) * 65535);
|
|
xcl.red = (unsigned short)(val);
|
|
xcl.green = (unsigned short)(val);
|
|
xcl.blue = (unsigned short)(val);
|
|
xcl_in = xcl;
|
|
ret = XAllocColor(d, cmap, &xcl);
|
|
if ((ret == Success) ||
|
|
((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)))
|
|
{
|
|
unsigned long pixels[256];
|
|
int j;
|
|
|
|
if (i > 0)
|
|
{
|
|
for(j = 0; j < i; j++)
|
|
pixels[j] = (unsigned long) color_lut[j];
|
|
XFreeColors(d, cmap, pixels, i, 0);
|
|
}
|
|
free(color_lut);
|
|
return NULL;
|
|
}
|
|
color_lut[i] = xcl.pixel;
|
|
i++;
|
|
}
|
|
return color_lut;
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_rgb_332(Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
return x_software_x11_color_alloc_rgb(8, 8, 4, d, cmap, v);
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_rgb_666(Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
return x_software_x11_color_alloc_rgb(6, 6, 6, d, cmap, v);
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_rgb_232(Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
return x_software_x11_color_alloc_rgb(4, 8, 4, d, cmap, v);
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_rgb_222(Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
return x_software_x11_color_alloc_rgb(4, 4, 4, d, cmap, v);
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_rgb_221(Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
return x_software_x11_color_alloc_rgb(4, 4, 2, d, cmap, v);
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_rgb_121(Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
return x_software_x11_color_alloc_rgb(2, 4, 2, d, cmap, v);
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_rgb_111(Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
return x_software_x11_color_alloc_rgb(2, 2, 2, d, cmap, v);
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_gray_256(Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
return x_software_x11_color_alloc_gray(256, d, cmap, v);
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_gray_64(Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
return x_software_x11_color_alloc_gray(64, d, cmap, v);
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_gray_16(Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
return x_software_x11_color_alloc_gray(32, d, cmap, v);
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_gray_4(Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
return x_software_x11_color_alloc_gray(16, d, cmap, v);
|
|
}
|
|
|
|
static DATA8 *
|
|
x_software_x11_color_alloc_mono(Display *d, Colormap cmap, Visual *v)
|
|
{
|
|
return x_software_x11_color_alloc_gray(2, d, cmap, v);
|
|
}
|
|
|
|
void
|
|
x_software_x11_color_init(void)
|
|
{
|
|
static int initialised = 0;
|
|
|
|
if (initialised) return;
|
|
x_software_x11_color_alloc[PAL_MODE_NONE] = NULL;
|
|
x_software_x11_color_count[PAL_MODE_NONE] = 0;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_MONO] = x_software_x11_color_alloc_mono;
|
|
x_software_x11_color_count[PAL_MODE_MONO] = 2;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_GRAY4] = x_software_x11_color_alloc_gray_4;
|
|
x_software_x11_color_count[PAL_MODE_GRAY4] = 4;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_GRAY16] = x_software_x11_color_alloc_gray_16;
|
|
x_software_x11_color_count[PAL_MODE_GRAY16] = 16;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_GRAY64] = x_software_x11_color_alloc_gray_64;
|
|
x_software_x11_color_count[PAL_MODE_GRAY64] = 64;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_GRAY256] = x_software_x11_color_alloc_gray_256;
|
|
x_software_x11_color_count[PAL_MODE_GRAY256] = 256;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_RGB111] = x_software_x11_color_alloc_rgb_111;
|
|
x_software_x11_color_count[PAL_MODE_RGB111] = 2 * 2 * 2;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_RGB121] = x_software_x11_color_alloc_rgb_121;
|
|
x_software_x11_color_count[PAL_MODE_RGB121] = 2 * 4 * 2;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_RGB221] = x_software_x11_color_alloc_rgb_221;
|
|
x_software_x11_color_count[PAL_MODE_RGB221] = 4 * 4 * 2;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_RGB222] = x_software_x11_color_alloc_rgb_222;
|
|
x_software_x11_color_count[PAL_MODE_RGB222] = 4 * 4 * 4;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_RGB232] = x_software_x11_color_alloc_rgb_232;
|
|
x_software_x11_color_count[PAL_MODE_RGB232] = 4 * 8 * 4;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_RGB666] = x_software_x11_color_alloc_rgb_666;
|
|
x_software_x11_color_count[PAL_MODE_RGB666] = 6 * 6 * 6;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_RGB332] = x_software_x11_color_alloc_rgb_332;
|
|
x_software_x11_color_count[PAL_MODE_RGB332] = 8 * 8 * 4;
|
|
|
|
x_software_x11_color_alloc[PAL_MODE_LAST] = NULL;
|
|
x_software_x11_color_count[PAL_MODE_LAST] = 0;
|
|
initialised = 1;
|
|
}
|
|
|
|
Convert_Pal *
|
|
evas_software_x11_x_software_x11_color_allocate(Display *disp, Colormap cmap, Visual *vis, Convert_Pal_Mode colors)
|
|
{
|
|
Convert_Pal_Priv *palpriv;
|
|
Convert_Pal *pal;
|
|
Convert_Pal_Mode c;
|
|
Evas_List *l;
|
|
|
|
for (l = palettes; l; l = l->next)
|
|
{
|
|
pal = l->data;
|
|
palpriv = pal->data;
|
|
if ((disp == palpriv->disp) &&
|
|
(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_software_x11_color_alloc[c])
|
|
{
|
|
pal->lookup = (x_software_x11_color_alloc[c])(disp, cmap, vis);
|
|
if (pal->lookup) break;
|
|
}
|
|
}
|
|
pal->references = 1;
|
|
pal->colors = c;
|
|
pal->count = x_software_x11_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->disp = disp;
|
|
palpriv->vis = vis;
|
|
palpriv->cmap = cmap;
|
|
if (pal->colors == PAL_MODE_NONE)
|
|
{
|
|
if (pal->lookup) free(pal->lookup);
|
|
free(pal);
|
|
return NULL;
|
|
}
|
|
palettes = evas_list_append(palettes, pal);
|
|
return pal;
|
|
}
|
|
|
|
void
|
|
evas_software_x11_x_software_x11_color_deallocate(Display *disp, Colormap cmap, Visual *vis,
|
|
Convert_Pal *pal)
|
|
{
|
|
unsigned long pixels[256];
|
|
int j;
|
|
|
|
pal->references--;
|
|
if (pal->references > 0) return;
|
|
if (pal->lookup)
|
|
{
|
|
for(j = 0; j < pal->count; j++)
|
|
pixels[j] = (unsigned long) pal->lookup[j];
|
|
XFreeColors(disp, cmap, pixels, pal->count, 0);
|
|
free(pal->lookup);
|
|
}
|
|
free(pal->data);
|
|
palettes = evas_list_remove(palettes, pal);
|
|
free(pal);
|
|
}
|