diff --git a/c/libs/xft.c b/c/libs/xft.c new file mode 100644 index 0000000..a588cfd --- /dev/null +++ b/c/libs/xft.c @@ -0,0 +1,370 @@ +#include "xft.h" + +/* XftPattern */ +XFT_REC_ACCESSOR_MAKER(scx_enter_xftpattern, XftPattern, scx_xftpattern_record_type); + +#define scx_extract_xftpattern(x) \ + ((XftPattern *) s48_extract_integer(s48_checked_record_ref(x, 0, scx_xftpattern_record_type))) + +/* XftFont */ +XFT_REC_ACCESSOR_MAKER(scx_enter_xftfont, XftFont, scx_xftfont_record_type); + +#define scx_extract_xftfont(x) \ + ((XftFont *) s48_extract_integer(s48_checked_record_ref(x, 0, scx_xftfont_record_type))) + +/* XftDraw */ +XFT_REC_ACCESSOR_MAKER(scx_enter_xftdraw, XftDraw, scx_xftdraw_record_type); + +#define scx_extract_xftdraw(x) \ + ((XftDraw *) s48_extract_integer(s48_checked_record_ref(x, 0, scx_xftdraw_record_type))) + +/* XftColor */ +XFT_REC_ACCESSOR_MAKER(scx_enter_xftcolor, XftColor, scx_xftcolor_record_type); + +#define scx_extract_xftcolor(x) \ + ((XftColor *) s48_extract_integer(s48_checked_record_ref(x, 0, scx_xftcolor_record_type))) + +/* XftObjectSet */ +XFT_REC_ACCESSOR_MAKER(scx_enter_xftobjectset, XftObjectSet, scx_xftobjectset_record_type); + +#define scx_extract_xftobjectset(x) \ + ((XftObjectSet *) s48_extract_integer(s48_checked_record_ref(x, 0, scx_xftobjectset_record_type))) + +/* XftFontSet */ +XFT_REC_ACCESSOR_MAKER(scx_enter_xftfontset, XftFontSet, scx_xftfontset_record_type); + +#define scx_extract_xftfontset(x) \ + ((XftFontSet *) s48_extract_integer(s48_checked_record_ref(x, 0, scx_xftfontset_record_type))) + + +s48_value scx_XftPatternCreate(void) +{ + return s48_enter_xftpattern(XftPatternCreate()); +} + + +s48_value scx_XftPatternDestroy(s48_value sxp) +{ + XftPatternDestroy((XftPattern *) scx_extract_xftpattern(sxp)); + return S48_UNSPECIFIC; +} + +s48_value scx_XftPatternDuplicate(s48_value sxp) +{ + XftPattern *p; + + p = XftPatternDuplicate(scx_extract_xftpattern(sxp)); + return scx_enter_xftpattern(p); +} + +struct xft_pattern_property* lookup_pattern_property_by_id(int id) +{ + struct xft_pattern_property *tbl; + + for (tbl = &xft_pattern_property_tbl[0]; + (tbl->scx_id != id) && (tbl->type != SCX_XFT_INVALID); + tbl++) + ; + return tbl; +} + +s48_value scx_XftPatternGet(s48_value sxp, s48_value sobj, s48_value sid) +{ + XftPattern *p; + XftResult rc; + XftValue v; + int obj, i; + s48_value rv = S48_UNSPECIFIC; + s48_value rl = S48_UNSPECIFIC; + struct xft_pattern_property *tbl; + + S48_DECLARE_GC_PROTECT(2); + S48_GC_PROTECT_2(rl, rv); + p = scx_extract_xftpattern(sxp); + obj = s48_extract_integer(sobj); + i = (int) s48_extract_integer(sid); + + tbl = lookup_pattern_property_by_id(obj); + rc = XftPatternGet(p, tbl->name, i, &v); + + if ((rc != XftResultMatch) || (rc != XftResultNoMatch)) + { + rl = s48_list_2(s48_enter_integer(rc), S48_UNSPECIFIC); + S48_GC_UNPROTECT(); + return rl; + } + + switch (tbl->type) { + case SCX_XFT_STRING: + rv = s48_enter_string(v.u.s); + break; + case SCX_XFT_DOUBLE: + rv = s48_enter_double(v.u.d); + break; + case SCX_XFT_INT: + rv = s48_enter_integer(v.u.i); + break; + case SCX_XFT_BOOL: + rv = v.u.b ? S48_TRUE : S48_FALSE; + break; + case SCX_XFT_UNIMPLEMENTED: + rv = S48_UNSPECIFIC; + break; + } + + rl = s48_list_2(s48_enter_integer(rc), rv); + S48_GC_UNPROTECT(); + XftValueDestroy(v); + return rl; +} + +s48_value scx_XftPatternAdd(s48_value sxp, s48_value sobj, + s48_value sval, s48_value sappend) +{ + XftPattern *p; + XftValue v; + int obj; + Bool append, rv; + struct xft_pattern_property *tbl; + + p = scx_extract_xftpattern(sxp); + obj = s48_extract_integer(sobj); + append = S48_TRUE_P(sappend); + tbl = lookup_pattern_property_by_id(sobj); + + switch (tbl->type) { + case SCX_XFT_STRING: + v.type = XftTypeString; + v.u.s = s48_extract_string(sval); + break; + case SCX_XFT_DOUBLE: + v.type = XftTypeDouble; + v.u.d = s48_extract_double(sval); + break; + case SCX_XFT_INT: + v.type = XftTypeInteger; + v.u.i = s48_extract_integer(sval); + break; + case SCX_XFT_BOOL: + v.type = XftTypeBool; + v.u.b = S48_TRUE_P(sval) ? True : False; + break; + } + rv = XftPatternAdd(p, tbl->name, v, append); + + return rv ? S48_TRUE : S48_FALSE; +} + +s48_value scx_XftFontMatch(s48_value sdpy, s48_value sscreen, s48_value sxp) +{ + XftPattern *p; + XftResult r; + + p = XftFontMatch(scx_extract_display(sdpy), + s48_extract_integer(sscreen), + scx_extract_xftpattern(sxp), + &r); + + if (p == NULL) + return s48_list_2(S48_FALSE, S48_UNSPECIFIC); + else + return s48_list_2(s48_enter_integer(r), scx_enter_xftpattern(p)); +} + +s48_value scx_XftFontOpenPattern(s48_value sdpy, s48_value sxp) +{ + return scx_enter_xftfont(XftFontOpenPattern(scx_extract_display(sdpy), + scx_extract_xftpattern(sxp))); +} + +s48_value scx_XftFontOpenName(s48_value sdpy, s48_value sscreen, s48_value sname) +{ + return scx_enter_xftfont(scx_extract_display(sdpy), + scx_extract_integer(sscreen), + s48_extract_string(sname)); +} + +s48_value scx_XftFontOpenXlfd(s48_value sdpy, s48_value sscreen, s48_value sxlfd) +{ + return scx_enter_xftfont(scx_extract_display(sdpy), + s48_extract_integer(sscreen), + s48_extract_string(sxlfd)); +} + +s48_value scx_XftFontClose(s48_value sdpy, s48_value sxf) +{ + XftFontClose(scx_extract_display(sdpy), + scx_extract_xftfont(sxf)); + return S48_UNSPECIFIC; +} + +s48_value scx_XftDrawCreate(s48_value sdpy, s48_value sdrawable, + s48_value svisual, s48_value scolormap) +{ + XftDraw *d; + + d = XftDrawCreate(scx_extract_display(sdpy), + scx_extract_drawable(sdrawable), + scx_extract_visual(svisual), + scx_extract_colormap(scolormap)); + + return scx_enter_xftdraw(d); +} + +s48_value scx_XftDrawCreateBitmap(s48_value sdpy, s48_value sdrawable) +{ + XftDraw *d; + + d = XftDrawCreateBitmap(scx_extract_display(sdpy), + scx_extract_drawable(sdrawable)); + + return scx_enter_xftdraw(d); +} + +s48_value scx_XftDrawChange(s48_value sxd, s48_value sdrawable) +{ + XftDrawChange(scx_extract_xftdraw(sxd), + scx_extract_drawable(sdrawable)); + return S48_UNSPECIFIC; +} + +s48_value scx_XftDrawDisplay(s48_value sxd) +{ + return scx_enter_display(XftDrawDisplay(scx_extract_xftdraw(sxd))); +} + +s48_value scx_XftDrawDrawable(s48_value sxd) +{ + return scx_enter_drawable(XftDrawDrawabale(scx_extract_xftdraw(sxd))); +} + +s48_value scx_XftDrawColormap(s48_value sxd) +{ + return scx_enter_colormap(XftDrawColormap(scx_extract_xftdraw(sxd))); +} + +s48_value scx_XftDrawVisual(s48_value sxd) +{ + return scx_enter_visual(XftDrawVisual(scx_extract_xftdraw(sxd))); +} + +s48_value scx_XftDrawDestroy(s48_value sxd) +{ + XftDrawDestroy(scx_extract_xftdraw(sxd)); + return S48_UNSPECIFIC; +} + +s48_value scx_XftTextExtents8(s48_value sdpy, s48_value sxf, s48_value sstr) +{ + XGlyphInfo extents; + + XftTextExtents8(scx_extract_display(sdpy), + scx_extract_xftfont(sxf), + (XftChar8 *) s48_extract_string(sstr), + S48_STRING_LENGTH(sstr), + &extents); + + return scx_enter_glyphinfo(extents); +} + +s48_value scx_XftDrawString8(s48_value sxd, s48_value sxc, + s48_value sxf, s48_value sx, + s48_value sy, s48_value sstr) +{ + XftDrawString8(scx_extract_xftdraw(sxd), scx_extract_xftcolor(sxc), + scx_extract_xftfont(sxf), + s48_extract_integer(sx), s48_extract_integer(sy), + (XftChar8 *) s48_extract_string(sstr), + S48_STRING_LENGTH(sstr)); + return S48_UNSPECIFIC; +} + +s48_value scx_XftDrawRect(s48_value sxd, s48_value sxc, + s48_value sx, s48_value sy, + s48_value sw, s48_value sh) +{ + XftDrawRect(scx_extract_xftdraw(sxd), scx_extract_xftcolor(sxc), + s48_extract_integer(sx), s48_extract_integer(sy), + s48_extract_integer(sw), s48_extract_integer(sh)); + return S48_UNSPECIFIC; +} + +s48_value scx_XftDrawSetClip(s48_value sxd, s48_value sreg) +{ + return (XftDrawSetClip(scx_extract_draw(sxd), S48_EXTRACT_REGION(sreg)) + ? S48_TRUE : S48_FALSE); +} + +s48_value scx_XftObjectSetCreate(void) +{ + return scx_enter_xftobjectset(XftObjectSetCreate()); +} + +s48_value scx_XftObjectSetAdd(s48_value sxo, s48_value sobj) +{ + struct xft_pattern_property *tbl; + Bool b; + + tbl = lookup_pattern_property_by_id(s48_extract_integer(sobj)); + b = XftObjectSetAdd(scx_extract_xftobjectset(sxo), tbl->name); + return b ? S48_TRUE : S48_FALSE; +} + +s48_value scx_XftListFontsPatternObjects(s48_value sdpy, s48_value sscreen, + s48_value sxp, s48_value sxo) +{ + XftFontSet *fs; + + fs = XftListFontsPatternObjects(scx_extract_display(sdpy), + s48_extract_integer(sscreen), + scx_extract_xftpatter(sxp), + scx_extract_objectset(sxo)); + + return scx_enter_fontset(fs); +} + + +void scx_xft_init(void) +{ + XFT_GC_PROTECT_IMPORT_BINDING(scx_xftpattern_record_type, "xft-pattern"); + XFT_GC_PROTECT_IMPORT_BINDING(scx_xftfontset_record_type, "xft-font"); + XFT_GC_PROTECT_IMPORT_BINDING(scx_xftdraw_record_type, "xft-draw"); + XFT_GC_PROTECT_IMPORT_BINDING(scx_xftcolor_record_type, "xft-color"); + XFT_GC_PROTECT_IMPORT_BINDING(scx_xftobjectset_record_type, "xft-objectset"); + XFT_GC_PROTECT_IMPORT_BINDING(scx_xftfontset_record_type, "xft-fontset"); + + GC_PROTECT_ENTER_INT(scx_XftResultMatch, XftResultMatch); + GC_PROTECT_ENTER_INT(scx_XftResultNoMatch, XftResultNoMatch); + GC_PROTECT_ENTER_INT(scx_XftResultTypeMismatch, XftResultTypeMismatch); + GC_PROTECT_ENTER_INT(scx_XftResultNoId, XftResultNoId); + + S48_EXPORT_FUNCTION(scx_XftPatternCreate); + S48_EXPORT_FUNCTION(scx_XftPatternDestroy); + S48_EXPORT_FUNCTION(scx_XftPatternDuplicate); + S48_EXPORT_FUNCTION(scx_XftPatternGet); + S48_EXPORT_FUNCTION(scx_XftPatternAdd); + + S48_EXPORT_FUNCTION(scx_XftFontMatch); + S48_EXPORT_FUNCTION(scx_XftFontOpenPattern); + S48_EXPORT_FUNCTION(scx_XftFontOpenName); + S48_EXPORT_FUNCTION(scx_XftFontOpenXlfd); + S48_EXPORT_FUNCTION(scx_XftFontClose); + + S48_EXPORT_FUNCTION(scx_XftDrawCreate); + S48_EXPORT_FUNCTION(scx_XftDrawCreateBitmap); + S48_EXPORT_FUNCTION(scx_XftDrawChange); + S48_EXPORT_FUNCTION(scx_XftDrawDisplay); + S48_EXPORT_FUNCTION(scx_XftDrawDrawable); + S48_EXPORT_FUNCTION(scx_XftDrawColormap); + S48_EXPORT_FUNCTION(scx_XftDrawVisual); + S48_EXPORT_FUNCTION(scx_XftDrawDestroy); + + S48_EXPORT_FUNCTION(scx_XftTextExtents8); + S48_EXPORT_FUNCTION(scx_XftDrawString8); + S48_EXPORT_FUNCTION(scx_XftDrawRect); + S48_EXPORT_FUNCTION(scx_XftDrawSetClip); + + S48_EXPORT_FUNCTION(scx_XftObjectSetCreate); + S48_EXPORT_FUNCTION(scx_XftObjectSetAdd); + S48_EXPORT_FUNCTION(scx_XftListFontsPatternObjects); +} diff --git a/c/libs/xft.h b/c/libs/xft.h new file mode 100644 index 0000000..14aa278 --- /dev/null +++ b/c/libs/xft.h @@ -0,0 +1,144 @@ +#include +#include + +#ifndef XFT_VERSION +#define XFT_VERSION 1 +#endif + +#define SCX_XFT_FAMILY 0 /* String */ +#define SCX_XFT_STYLE 1 /* String */ +#define SCX_XFT_SLANT 2 /* Int */ +#define SCX_XFT_WEIGHT 3 /* Int */ +#define SCX_XFT_SIZE 4 /* Double */ +#define SCX_XFT_PIXEL_SIZE 5 /* Double */ +#define SCX_XFT_ENCODING 6 /* String */ +#define SCX_XFT_SPACING 7 /* Int */ +#define SCX_XFT_FOUNDRY 8 /* String */ +#define SCX_XFT_CORE 9 /* Bool */ +#define SCX_XFT_ANTIALIAS 10 /* Bool */ +#define SCX_XFT_XLFD 11 /* String */ +#define SCX_XFT_FILE 12 /* String */ +#define SCX_XFT_INDEX 13 /* Int */ +#define SCX_XFT_RASTERIZER 14 /* String */ +#define SCX_XFT_OUTLINE 15 /* Bool */ +#define SCX_XFT_SCALABLE 16 /* Bool */ +#define SCX_XFT_RGBA 17 /* Int */ +#define SCX_XFT_SCALE 18 /* double */ +#define SCX_XFT_RENDER 19 /* Bool */ +#define SCX_XFT_MINSPACE 20 /* Bool use minimum line spacing */ +#define SCX_XFT_DPI 21 /* double */ +#define SCX_XFT_CHAR_WIDTH 22 /* Int */ +#define SCX_XFT_CHAR_HEIGHT 23 /* Int */ + +enum xft_pattern_get_return_type { + SCX_XFT_INVALID, + SCX_XFT_UNIMPLEMENTED, + SCX_XFT_STRING, + SCX_XFT_DOUBLE, + SCX_XFT_INT, + SCX_XFT_BOOL +}; + +struct xft_pattern_property { + int scx_id; + char *name; + enum xft_pattern_get_return_type type; +}; + +static struct xft_pattern_property xft_pattern_property_tbl [] = { + {SCX_XFT_FAMILY, XFT_FAMILY, SCX_XFT_STRING}, + {SCX_XFT_STYLE, XFT_STYLE, SCX_XFT_STRING}, + {SCX_XFT_SLANT, XFT_SLANT, SCX_XFT_INT}, + {SCX_XFT_WEIGHT, XFT_WEIGHT, SCX_XFT_INT}, + {SCX_XFT_SIZE, XFT_SIZE, SCX_XFT_DOUBLE}, + {SCX_XFT_PIXEL_SIZE, XFT_PIXEL_SIZE, SCX_XFT_DOUBLE}, +#if XFT_VERSION < 2 + {SCX_XFT_ENCODING, XFT_ENCODING, SCX_XFT_STRING}, +#else + {SCX_XFT_ENCODING, XFT_ENCODING, SCX_XFT_UNIMPLEMENTED}, +#endif + {SCX_XFT_SPACING, XFT_SPACING, SCX_XFT_INT}, + {SCX_XFT_FOUNDRY, XFT_FOUNDRY, SCX_XFT_STRING}, +#if XFT_VERSION < 2 + {SCX_XFT_CORE, XFT_CORE, SCX_XFT_BOOL}, +#else + {SCX_XFT_CORE, XFT_CORE, SCX_XFT_UNIMPLEMENTED}, +#endif + {SCX_XFT_ANTIALIAS, XFT_ANTIALIAS, SCX_XFT_BOOL}, + {SCX_XFT_XLFD, XFT_XLFD, SCX_XFT_STRING}, + {SCX_XFT_FILE, XFT_FILE, SCX_XFT_STRING}, + {SCX_XFT_INDEX, XFT_INDEX, SCX_XFT_INT}, + {SCX_XFT_RASTERIZER, XFT_RASTERIZER, SCX_XFT_STRING}, + {SCX_XFT_OUTLINE, XFT_OUTLINE, SCX_XFT_STRING}, + {SCX_XFT_SCALABLE, XFT_SCALABLE, SCX_XFT_BOOL}, + {SCX_XFT_RGBA, XFT_RGBA, SCX_XFT_INT}, + {SCX_XFT_SCALE, XFT_SCALE, SCX_XFT_DOUBLE}, + {SCX_XFT_RENDER, XFT_RENDER, SCX_XFT_BOOL}, + {SCX_XFT_MINSPACE, XFT_MINSPACE, SCX_XFT_BOOL}, + {SCX_XFT_DPI, XFT_DPI, SCX_XFT_DOUBLE}, +#if XFT_VERSION < 2 + {SCX_XFT_CHAR_WIDTH, XFT_CHAR_WIDTH, SCX_XFT_INT}, + {SCX_XFT_CHAR_HEIGHT, XFT_CHAR_HEIGHT, SCX_XFT_INT}, +#else + {SCX_XFT_CHAR_WIDTH, XFT_CHAR_WIDTH, SCX_XFT_UNIMPLEMENTED}, + {SCX_XFT_CHAR_HEIGHT, XFT_CHAR_HEIGHT, SCX_XFT_UNIMPLEMENTED}, +#endif + {NULL, NULL, SCX_XFT_INVALID} +}; + +/* scheme record types */ +static s48_value scx_xftpattern_record_type = S48_UNSPECIFIC; +static s48_value scx_xftfont_record_type = S48_UNSPECIFIC; +static s48_value scx_xftdraw_record_type = S48_UNSPECIFIC; +static s48_value scx_xftcolor_record_type = S48_UNSPECIFIC; +static s48_value scx_xftobjectset_record_type = S48_UNSPECIFIC; +static s48_value scx_xftfontset_record_type = S48_UNSPECIFIC; + +#define XFT_GC_PROTECT_IMPORT_BINDING(CN, SN) \ + S48_GC_PROTECT_GLOBAL(CN); \ + CN = s48_get_imported_binding("SN"); + +/* C values exported to scheme */ +static s48_value scx_XftResultMatch = S48_UNSPECIFIC; +static s48_value scx_XftResultNoMatch = S48_UNSPECIFIC; +static s48_value scx_XftResultTypeMismatch = S48_UNSPECIFIC; +static s48_value scx_XftResultNoId = S48_UNSPECIFIC; + +#define XFT_REC_ACCESSOR_MAKER(FN, TN, RN) \ + s48_value FN(TN *p) \ + { \ + s48_value xftrec = S48_UNSPECIFIC; \ + S48_DECLARE_GC_PROTECT(1); \ + \ + S48_GC_PROTECT_1(xftrec); \ + xftrec = s48_make_record(RN); \ + S48_RECORD_SET(xftrec, 0, s48_enter_integer((long) p)); \ + S48_GC_UNPROTECT(); \ + return xftrec; \ + } + +#define GC_PROTECT_ENTER_INT(schemeval, i) \ + S48_GC_PROTECT_GLOBAL(schemeval); \ + schemeval = s48_enter_integer(i); + +/* function prototypes */ +s48_value scx_enter_xftpattern(XftPattern *p); +s48_value scx_extract_xftpattern(s48_value s); + +s48_value scx_enter_xftfont(XftFont *f); +s48_value scx_extract_xftfont(s48_value s); + +s48_value scx_enter_xftdraw(XftDraw *d); +s48_value scx_extract_xftdraw(s48_value s); + +s48_value scx_enter_xftcolor(XftColor *c); +s48_value scx_extract_xftcolor(s48_value s); + +s48_value scx_enter_xftobjectset(XftObjectSet *os); +s48_value scx_extract_xftobjectset(s48_value s); + +s48_value scx_enter_xftfontset(XftFontSet *fs); +s48_value scx_extract_xftfontset(s48_value s); + +struct xft_pattern_property* lookup_pattern_property_by_id(int id); +