scx/c/xlib/colormap.c

283 lines
8.9 KiB
C

#include "xlib.h"
s48_value scx_colormap_alloc_binding = S48_FALSE;
#define scx_extract_colormap_alloc(x) S48_EXTRACT_ENUM(x, scx_colormap_alloc_binding)
double s48_extract_number(s48_value v) {
if (S48_DOUBLE_P(v))
return s48_extract_double(v);
else return s48_extract_integer(v);
}
void scx_extract_color(s48_value v, XColor* c) {
S48_DECLARE_GC_PROTECT_1(v);
s48_check_record_type(v, scx_color);
c->pixel = scx_extract_pixel(S48_RECORD_REF(v, 0));
c->flags = 0;
if (S48_RECORD_REF(v, 1) != S48_FALSE) {
c->flags |= DoRed;
c->red = s48_extract_number(S48_RECORD_REF(v, 1)) * 65536;
}
if (S48_RECORD_REF(v, 2) != S48_FALSE) {
c->flags |= DoGreen;
c->green = s48_extract_number(S48_RECORD_REF(v, 2)) * 65536;
}
if (S48_RECORD_REF(v, 3) != S48_FALSE) {
c->flags |= DoBlue;
c->blue = s48_extract_number(S48_RECORD_REF(v, 3)) * 65536;
}
S48_GC_UNPROTECT();
}
void scx_copy_color(const XColor* c, s48_value v) {
S48_DECLARE_GC_PROTECT(1);
s48_check_record_type(v, scx_color);
S48_GC_PROTECT_1(v);
S48_RECORD_SET(v, 0, scx_enter_pixel(c->pixel));
S48_RECORD_SET(v, 1, (c->flags & DoRed) ?
s48_enter_double((double)c->red / 65636.0) : S48_FALSE);
S48_RECORD_SET(v, 2, (c->flags & DoGreen) ?
s48_enter_double((double)c->green / 65636.0) : S48_FALSE);
S48_RECORD_SET(v, 3, (c->flags & DoBlue) ?
s48_enter_double((double)c->blue / 65636.0) : S48_FALSE);
S48_GC_UNPROTECT();
}
s48_value scx_enter_color(const XColor* c) {
s48_value res = s48_make_record(scx_color);
scx_copy_color(c, res);
return res;
}
s48_value scx_Create_Colormap (s48_value display, s48_value window,
s48_value visual, s48_value alloc) {
S48_DECLARE_GC_PROTECT_4(display, window, visual, alloc);
Colormap cm = XCreateColormap(scx_extract_display(display),
scx_extract_window(window),
scx_extract_visual(visual),
scx_extract_colormap_alloc(alloc));
S48_GC_RETURN(scx_enter_colormap(cm));
}
s48_value scx_Copy_Colormap_And_Free(s48_value display, s48_value colormap) {
S48_DECLARE_GC_PROTECT_2(display, colormap);
Colormap cm = XCopyColormapAndFree(scx_extract_display(display),
scx_extract_colormap(colormap));
S48_GC_RETURN(scx_enter_colormap(cm));
}
s48_value scx_Free_Colormap (s48_value display, s48_value colormap) {
S48_DECLARE_GC_PROTECT_2(display, colormap);
XFreeColormap(scx_extract_display(display),
scx_extract_colormap(colormap));
S48_GC_RETURN(S48_UNSPECIFIC);
}
s48_value scx_Alloc_Color(s48_value display, s48_value colormap,
s48_value color) {
XColor cp;
S48_DECLARE_GC_PROTECT_3(display, colormap, color);
scx_extract_color(color, &cp);
if (!XAllocColor(scx_extract_display(display),
scx_extract_colormap(colormap), &cp))
S48_GC_RETURN(S48_FALSE);
else {
scx_copy_color(&cp, color);
S48_GC_RETURN(S48_UNSPECIFIC);
}
}
s48_value scx_Alloc_Named_Color(s48_value display, s48_value colormap,
s48_value color_name) {
XColor screen, exact;
int r;
s48_value s = S48_NULL, e = S48_NULL;
S48_DECLARE_GC_PROTECT_5(display, colormap, color_name , s, e);
r = XAllocNamedColor(scx_extract_display(display),
scx_extract_colormap(colormap),
s48_extract_string(color_name),
&screen, &exact);
if (r != 0) {
s = scx_enter_color(&screen);
e = scx_enter_color(&exact);
S48_GC_RETURN(s48_cons(s, e));
} else
S48_GC_RETURN(S48_FALSE);
}
s48_value scx_Alloc_Color_Cells (s48_value display, s48_value colormap,
s48_value contig, s48_value nplanes,
s48_value npixels) {
int npl = s48_extract_integer(nplanes);
int npx = s48_extract_integer(npixels);
unsigned long plane_masks[npl];
unsigned long pixels[npx];
s48_value pls = S48_NULL, pxs = S48_NULL;
S48_DECLARE_GC_PROTECT_7(display, colormap, contig, nplanes, npixels,
pls, pxs);
if (XAllocColorCells(scx_extract_display(display),
scx_extract_colormap(colormap),
!S48_FALSE_P(contig),
plane_masks, npl,
pixels, npx)) {
int i;
for (i = npl-1; i >= 0; i--)
pls = s48_cons(s48_enter_integer(plane_masks[i]), pls);
for (i = npx-1; i >= 0; i--)
pxs = s48_cons(scx_enter_pixel(pixels[i]), pxs);
S48_GC_RETURN(s48_cons(pls, pxs));
} else
S48_GC_RETURN(S48_FALSE);
}
s48_value scx_Alloc_Color_Planes(s48_value display, s48_value colormap,
s48_value contig, s48_value ncolors,
s48_value nreds, s48_value ngreens,
s48_value nblues) {
int npx = s48_extract_integer(ncolors);
int nre = s48_extract_integer(nreds);
int ngr = s48_extract_integer(ngreens);
int nbl = s48_extract_integer(nblues);
unsigned long pixels[npx];
unsigned long rmask, gmask, bmask;
s48_value pxs = S48_NULL;
s48_value res = S48_NULL;
S48_DECLARE_GC_PROTECT_9(display, colormap, contig, ncolors, nreds, ngreens,
nblues, pxs, res);
if (XAllocColorPlanes(scx_extract_display(display),
scx_extract_colormap(colormap),
!S48_FALSE_P(contig),
pixels, npx,
nre, ngr, nbl,
&rmask, &gmask, &bmask)) {
int i;
for (i = npx-1; i >= 0; i--)
pxs = s48_cons(scx_enter_pixel(pixels[i]), pxs);
res = s48_cons(s48_enter_integer(bmask), res);
res = s48_cons(s48_enter_integer(gmask), res);
res = s48_cons(s48_enter_integer(rmask), res);
res = s48_cons(pxs, res);
S48_GC_RETURN(res);
} else
S48_GC_RETURN(S48_FALSE);
}
s48_value scx_Free_Colors(s48_value display, s48_value colormap,
s48_value pixels, s48_value planes) {
int i, n = s48_list_length(pixels);
unsigned long cpixels[n];
s48_value l = pixels;
S48_DECLARE_GC_PROTECT_5(display, colormap, pixels, planes, l);
for (i = 0; i < n; i++) {
cpixels[i] = scx_extract_pixel(S48_CAR(l));
l = S48_CDR(l);
}
XFreeColors(scx_extract_display(display), scx_extract_colormap(colormap),
cpixels, n, s48_extract_integer(planes));
S48_GC_RETURN(S48_UNSPECIFIC);
}
s48_value scx_Query_Colors(s48_value display, s48_value colormap,
s48_value colors) {
int i, n = s48_list_length(colors);
XColor ccolors[n];
s48_value l = colors;
S48_DECLARE_GC_PROTECT_4(display, colormap, colors, l);
for (i = 0; i < n; i++) {
scx_extract_color(S48_CAR(l), &ccolors[i]);
l = S48_CDR(l);
}
XQueryColors(scx_extract_display(display), scx_extract_colormap(colormap),
ccolors, n);
l = colors;
for (i = 0; i < n; i++) {
scx_copy_color(&ccolors[i], S48_CAR(l));
l = S48_CDR(l);
}
S48_GC_RETURN(S48_UNSPECIFIC);
}
s48_value scx_Lookup_Color(s48_value display, s48_value colormap,
s48_value color_name) {
XColor cexact, cscreen;
s48_value r = S48_NULL;
S48_DECLARE_GC_PROTECT_4(display, colormap, color_name, r);
int res = XLookupColor(scx_extract_display(display),
scx_extract_colormap(colormap),
s48_extract_string(color_name),
&cexact, &cscreen);
if (res == 0) S48_GC_RETURN(S48_FALSE);
r = scx_enter_color(&cscreen);
r = s48_cons(scx_enter_color(&cexact), r);
S48_GC_RETURN(r);
}
s48_value scx_Parse_Color(s48_value display, s48_value colormap,
s48_value spec) {
XColor ret;
S48_DECLARE_GC_PROTECT_3(display, colormap, spec);
if (XParseColor(scx_extract_display(display),
scx_extract_colormap(colormap),
s48_extract_string(spec),
&ret)) {
S48_GC_RETURN(scx_enter_color(&ret));
} else
S48_GC_RETURN(S48_FALSE);
}
s48_value scx_Store_Colors(s48_value display, s48_value colormap,
s48_value colors) {
int i, n = s48_list_length(colors);
XColor ccolors[n];
s48_value l = colors;
S48_DECLARE_GC_PROTECT_4(display, colormap, colors, l);
for (i = 0; i < n; i++) {
scx_extract_color(S48_CAR(l), &ccolors[i]);
l = S48_CDR(l);
}
XStoreColors(scx_extract_display(display),
scx_extract_colormap(colormap),
ccolors, n);
S48_GC_RETURN(S48_UNSPECIFIC);
}
s48_value scx_Store_Named_Color(s48_value display, s48_value colormap,
s48_value color_name, s48_value pixel,
s48_value do_red, s48_value do_green,
s48_value do_blue) {
S48_DECLARE_GC_PROTECT_7(display, colormap, color_name, pixel, do_red,
do_green, do_blue);
XStoreNamedColor(scx_extract_display(display),
scx_extract_colormap(colormap),
s48_extract_string(color_name),
scx_extract_pixel(pixel),
(S48_EXTRACT_BOOLEAN(do_red) ? DoRed : 0) |
(S48_EXTRACT_BOOLEAN(do_green) ? DoGreen : 0) |
(S48_EXTRACT_BOOLEAN(do_blue) ? DoBlue : 0));
S48_GC_RETURN(S48_UNSPECIFIC);
}
void scx_init_colormap(void) {
SCX_PRO_IMP(scx_colormap_alloc_binding, "scx-colormap-alloc");
S48_EXPORT_FUNCTION(scx_Create_Colormap);
S48_EXPORT_FUNCTION(scx_Copy_Colormap_And_Free);
S48_EXPORT_FUNCTION(scx_Free_Colormap);
S48_EXPORT_FUNCTION(scx_Alloc_Color);
S48_EXPORT_FUNCTION(scx_Alloc_Named_Color);
S48_EXPORT_FUNCTION(scx_Alloc_Color_Cells);
S48_EXPORT_FUNCTION(scx_Alloc_Color_Planes);
S48_EXPORT_FUNCTION(scx_Free_Colors);
S48_EXPORT_FUNCTION(scx_Query_Colors);
S48_EXPORT_FUNCTION(scx_Lookup_Color);
S48_EXPORT_FUNCTION(scx_Parse_Color);
S48_EXPORT_FUNCTION(scx_Store_Colors);
S48_EXPORT_FUNCTION(scx_Store_Named_Color);
}