#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "Xlibint.h"
#include "Xlcint.h"
#include "XlcPublic.h"
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <stdio.h>
#define MAXFONTS 100
#define XOM_GENERIC(om) (&((XOMGeneric) om)->gen)
#define XOC_GENERIC(font_set) (&((XOCGeneric) font_set)->gen)
#define DefineLocalBuf char local_buf[BUFSIZ]
#define AllocLocalBuf(length) (length > BUFSIZ ? (char *)Xmalloc(length) : local_buf)
#define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr)
typedef struct _FontDataRec {
char *name;
} FontDataRec, *FontData;
typedef struct _OMDataRec {
int font_data_count;
FontData font_data;
} OMDataRec, *OMData;
typedef struct _XOMGenericPart {
OMData data;
} XOMGenericPart;
typedef struct _XOMGenericRec {
XOMMethods methods;
XOMCoreRec core;
XOMGenericPart gen;
} XOMGenericRec, *XOMGeneric;
typedef struct _FontSetRec {
int id;
int font_data_count;
FontData font_data;
char *font_name;
XFontStruct *info;
XFontStruct *font;
} FontSetRec, *FontSet;
typedef struct _XOCGenericPart {
XlcConv wcs_to_cs;
FontSet font_set;
} XOCGenericPart;
typedef struct _XOCGenericRec {
XOCMethods methods;
XOCCoreRec core;
XOCGenericPart gen;
} XOCGenericRec, *XOCGeneric;
static Bool
init_fontset(
XOC oc)
{
XOCGenericPart *gen;
FontSet font_set;
OMData data;
data = XOM_GENERIC(oc->core.om)->data;
font_set = (FontSet) Xmalloc(sizeof(FontSetRec));
if (font_set == NULL)
return False;
bzero((char *) font_set, sizeof(FontSetRec));
gen = XOC_GENERIC(oc);
gen->font_set = font_set;
font_set->font_data_count = data->font_data_count;
font_set->font_data = data->font_data;
return True;
}
static char *
get_prop_name(
Display *dpy,
XFontStruct *fs)
{
unsigned long fp;
if (XGetFontProperty(fs, XA_FONT, &fp))
return XGetAtomName(dpy, fp);
return (char *) NULL;
}
static FontData
check_charset(
FontSet font_set,
char *font_name)
{
FontData font_data;
char *last;
int count;
ssize_t length, name_len;
name_len = strlen(font_name);
last = font_name + name_len;
count = font_set->font_data_count;
font_data = font_set->font_data;
for ( ; count-- > 0; font_data++) {
length = strlen(font_data->name);
if (length > name_len)
return(NULL);
if (_XlcCompareISOLatin1(last - length, font_data->name) == 0)
return font_data;
}
return (FontData) NULL;
}
#if 0
static int
check_fontname(
XOC oc,
char *name)
{
Display *dpy = oc->core.om->core.display;
XOCGenericPart *gen = XOC_GENERIC(oc);
FontData data;
FontSet font_set;
XFontStruct *fs_list;
char **fn_list, *fname, *prop_fname = NULL;
int list_num, i;
int list2_num;
char **fn2_list = NULL;
int found_num = 0;
fn_list = XListFonts(dpy, name, MAXFONTS, &list_num);
if (fn_list == NULL)
return found_num;
for (i = 0; i < list_num; i++) {
fname = fn_list[i];
font_set = gen->font_set;
if ((data = check_charset(font_set, fname)) == NULL) {
if ((fn2_list = XListFontsWithInfo(dpy, name, MAXFONTS,
&list2_num, &fs_list))
&& (prop_fname = get_prop_name(dpy, fs_list))
&& (data = check_charset(font_set, prop_fname)))
fname = prop_fname;
}
if (data) {
font_set->font_name = (char *) Xmalloc(strlen(fname) + 1);
if (font_set->font_name) {
strcpy(font_set->font_name, fname);
found_num++;
}
}
if (fn2_list) {
XFreeFontInfo(fn2_list, fs_list, list2_num);
fn2_list = NULL;
if (prop_fname) {
Xfree(prop_fname);
prop_fname = NULL;
}
}
if (found_num == 1)
break;
}
XFreeFontNames(fn_list);
return found_num;
}
#endif
static Bool
load_font(
XOC oc)
{
Display *dpy = oc->core.om->core.display;
XOCGenericPart *gen = XOC_GENERIC(oc);
FontSet font_set = gen->font_set;
if (font_set->font_name == NULL)
return False;
if (font_set->font == NULL) {
font_set->font = XLoadQueryFont(dpy, font_set->font_name);
if (font_set->font == NULL)
return False;
}
return True;
}
#if 0
static Bool
load_font_info(
XOC oc)
{
Display *dpy = oc->core.om->core.display;
XOCGenericPart *gen = XOC_GENERIC(oc);
FontSet font_set = gen->font_set;
char **fn_list;
int fn_num;
if (font_set->font_name == NULL)
return False;
if (font_set->info == NULL) {
fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num,
&font_set->info);
if (font_set->info == NULL)
return False;
if (fn_num > 0)
font_set->info->fid = XLoadFont(dpy, font_set->font_name);
if (fn_list) XFreeFontNames(fn_list);
}
return True;
}
#endif
static void
set_fontset_extents(
XOC oc)
{
XRectangle *ink = &oc->core.font_set_extents.max_ink_extent;
XRectangle *logical = &oc->core.font_set_extents.max_logical_extent;
XFontStruct **font_list, *font;
XCharStruct overall;
int logical_ascent, logical_descent;
font_list = oc->core.font_info.font_struct_list;
font = *font_list++;
overall = font->max_bounds;
overall.lbearing = font->min_bounds.lbearing;
logical_ascent = font->ascent;
logical_descent = font->descent;
ink->x = overall.lbearing;
ink->y = -(overall.ascent);
ink->width = overall.rbearing - overall.lbearing;
ink->height = overall.ascent + overall.descent;
logical->x = 0;
logical->y = -(logical_ascent);
logical->width = overall.width;
logical->height = logical_ascent + logical_descent;
}
static Bool
init_core_part(
XOC oc)
{
XOCGenericPart *gen = XOC_GENERIC(oc);
FontSet font_set;
XFontStruct **font_struct_list;
char **font_name_list, *font_name_buf;
int count, length;
font_set = gen->font_set;
count = length = 0;
if (font_set->font_name != NULL) {
length += strlen(font_set->font_name) + 1;
count++;
}
if (count == 0)
return False;
font_struct_list = (XFontStruct **) Xmalloc(sizeof(XFontStruct *));
if (font_struct_list == NULL)
return False;
font_name_list = (char **) Xmalloc(sizeof(char *));
if (font_name_list == NULL)
goto err;
font_name_buf = (char *) Xmalloc(length);
if (font_name_buf == NULL)
goto err;
oc->core.font_info.num_font = 1;
oc->core.font_info.font_name_list = font_name_list;
oc->core.font_info.font_struct_list = font_struct_list;
font_set = gen->font_set;
if (font_set->font_name != NULL) {
font_set->id = 1;
if (font_set->font)
*font_struct_list++ = font_set->font;
else
*font_struct_list++ = font_set->info;
strcpy(font_name_buf, font_set->font_name);
Xfree(font_set->font_name);
*font_name_list++ = font_set->font_name = font_name_buf;
font_name_buf += strlen(font_name_buf) + 1;
}
set_fontset_extents(oc);
return True;
err:
if (font_name_list)
Xfree(font_name_list);
Xfree(font_struct_list);
return False;
}
static char *
get_font_name(
XOC oc,
char *pattern)
{
char **list, *name, *prop_name;
int count;
XFontStruct *fs;
Display *dpy = oc->core.om->core.display;
list = XListFonts(dpy, pattern, 1, &count);
if (list != NULL) {
name = (char *) Xmalloc(strlen(*list) + 1);
if (name)
strcpy(name, *list);
XFreeFontNames(list);
} else {
fs = XLoadQueryFont(dpy, pattern);
if (fs == NULL) return NULL;
prop_name = get_prop_name(dpy, fs);
if (prop_name == NULL) return NULL;
name = (char*) Xmalloc(strlen(prop_name) + 1);
if (name)
strcpy(name, prop_name);
XFreeFont(dpy, fs);
}
return name;
}
static int
parse_fontname(
XOC oc)
{
XOCGenericPart *gen = XOC_GENERIC(oc);
FontSet font_set;
FontData font_data;
char *pattern, *last, buf[BUFSIZ];
int font_data_count, found_num = 0;
ssize_t length;
int count, num_fields;
char *base_name, *font_name, **name_list, **cur_name_list;
char *charset_p = NULL;
Bool append_charset;
name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count);
if (name_list == NULL)
return -1;
cur_name_list = name_list;
while (count-- > 0) {
pattern = *cur_name_list++;
if (pattern == NULL || *pattern == '\0')
continue;
append_charset = False;
if (strchr(pattern, '*') == NULL &&
(font_name = get_font_name(oc, pattern))) {
font_set = gen->font_set;
font_data = check_charset(font_set, font_name);
if (font_data == NULL) {
Display *dpy = oc->core.om->core.display;
char **fn_list = NULL, *prop_fname = NULL;
int list_num;
XFontStruct *fs_list;
if ((fn_list = XListFontsWithInfo(dpy, font_name,
MAXFONTS,
&list_num, &fs_list))
&& (prop_fname = get_prop_name(dpy, fs_list))
&& (font_data = check_charset(font_set, prop_fname))) {
if (fn_list) {
XFreeFontInfo(fn_list, fs_list, list_num);
fn_list = NULL;
}
font_name = prop_fname;
}
}
if (font_data == NULL)
continue;
font_set->font_name = (char *) Xmalloc(strlen(font_name) + 1);
if (font_set->font_name == NULL) {
Xfree(font_name);
goto err;
}
strcpy(font_set->font_name, font_name);
Xfree(font_name);
found_num++;
goto found;
}
strncpy(buf, pattern, BUFSIZ);
buf[BUFSIZ-1] = '\0';
length = strlen(buf);
last = buf + length - 1;
for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++)
if (*base_name == '-') num_fields++;
if (strchr(pattern, '*') == NULL) {
if (num_fields == 12) {
append_charset = True;
*++last = '-';
last++;
} else
continue;
} else {
if (num_fields == 13 || num_fields == 14) {
append_charset = True;
last = strrchr (buf, '-');
if (num_fields == 14) {
*last = '\0';
last = strrchr (buf, '-');
}
last++;
} else if (*last == '*') {
append_charset = True;
if (length > 3 && *(last-3) == '-' && *(last-2) == '*'
&& *(last-1) == '-') {
last -= 2;
}
*++last = '-';
last++;
} else {
last = strrchr (buf, '-');
charset_p = last;
charset_p = strrchr (buf, '-');
while (*(--charset_p) != '-');
charset_p++;
}
}
font_set = gen->font_set;
font_data = font_set->font_data;
font_data_count = font_set->font_data_count;
for ( ; font_data_count-- > 0; font_data++) {
if (append_charset)
{
strncpy(last, font_data->name, BUFSIZ - length);
buf[BUFSIZ-1] = '\0';
}
else {
if (_XlcCompareISOLatin1(charset_p,
font_data->name)) {
continue;
}
}
if ((font_set->font_name = get_font_name(oc, buf)))
break;
}
if (font_set->font_name != NULL) {
found_num++;
goto found;
}
}
found:
base_name = (char *) Xmalloc(strlen(oc->core.base_name_list) + 1);
if (base_name == NULL)
goto err;
strcpy(base_name, oc->core.base_name_list);
oc->core.base_name_list = base_name;
XFreeStringList(name_list);
return found_num;
err:
XFreeStringList(name_list);
return -1;
}
static Bool
set_missing_list(
XOC oc)
{
XOCGenericPart *gen = XOC_GENERIC(oc);
FontSet font_set;
char **charset_list, *charset_buf;
int count, length;
font_set = gen->font_set;
count = length = 0;
if (!font_set->info && !font_set->font) {
length += strlen(font_set->font_data->name) + 1;
count++;
}
if (count == 0)
return True;
charset_list = (char **) Xmalloc(sizeof(char *));
if (charset_list == NULL)
return False;
charset_buf = (char *) Xmalloc(length);
if (charset_buf == NULL) {
Xfree(charset_list);
return False;
}
oc->core.missing_list.charset_list = charset_list;
font_set = gen->font_set;
if (!font_set->info && !font_set->font) {
strcpy(charset_buf, font_set->font_data->name);
*charset_list++ = charset_buf;
charset_buf += strlen(charset_buf) + 1;
}
return True;
}
static Bool
create_fontset(
XOC oc)
{
int found_num;
if (init_fontset(oc) == False)
return False;
found_num = parse_fontname(oc);
if (found_num <= 0) {
if (found_num == 0)
set_missing_list(oc);
return False;
}
if (load_font(oc) == False)
return False;
if (init_core_part(oc) == False)
return False;
if (set_missing_list(oc) == False)
return False;
return True;
}
static void
destroy_oc(
XOC oc)
{
Display *dpy = oc->core.om->core.display;
XOCGenericPart *gen = XOC_GENERIC(oc);
XFontStruct **font_list, *font;
if (gen->font_set)
Xfree(gen->font_set);
if (oc->core.base_name_list)
Xfree(oc->core.base_name_list);
if (oc->core.font_info.font_name_list)
XFreeStringList(oc->core.font_info.font_name_list);
if ((font_list = oc->core.font_info.font_struct_list)) {
if ((font = *font_list)) {
if (font->fid)
XFreeFont(dpy, font);
else
XFreeFontInfo(NULL, font, 1);
}
Xfree(oc->core.font_info.font_struct_list);
}
if (oc->core.missing_list.charset_list)
XFreeStringList(oc->core.missing_list.charset_list);
#ifdef notdef
if (oc->core.res_name)
Xfree(oc->core.res_name);
if (oc->core.res_class)
Xfree(oc->core.res_class);
#endif
Xfree(oc);
}
static char *
set_oc_values(
XOC oc,
XlcArgList args,
int num_args)
{
if (oc->core.resources == NULL)
return NULL;
return _XlcSetValues((XPointer) oc, oc->core.resources,
oc->core.num_resources, args, num_args, XlcSetMask);
}
static char *
get_oc_values(
XOC oc,
XlcArgList args,
int num_args)
{
if (oc->core.resources == NULL)
return NULL;
return _XlcGetValues((XPointer) oc, oc->core.resources,
oc->core.num_resources, args, num_args, XlcGetMask);
}
static Bool
wcs_to_mbs(
XOC oc,
char *to,
_Xconst wchar_t *from,
int length)
{
XlcConv conv = XOC_GENERIC(oc)->wcs_to_cs;
XLCd lcd;
int ret, to_left = length;
if (conv == NULL) {
lcd = oc->core.om->core.lcd;
conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte);
if (conv == NULL)
return False;
XOC_GENERIC(oc)->wcs_to_cs = conv;
} else
_XlcResetConverter(conv);
ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to,
&to_left, NULL, 0);
if (ret != 0 || length > 0)
return False;
return True;
}
static int
_XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length)
{
return XTextWidth(*oc->core.font_info.font_struct_list, text, length);
}
static int
_XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length)
{
DefineLocalBuf;
char *buf = AllocLocalBuf(length);
int ret = 0;
if (buf == NULL)
return 0;
if (wcs_to_mbs(oc, buf, text, length) == False)
goto err;
ret = _XmbDefaultTextEscapement(oc, buf, length);
err:
FreeLocalBuf(buf);
return ret;
}
static int
_XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length,
XRectangle *overall_ink, XRectangle *overall_logical)
{
int direction, logical_ascent, logical_descent;
XCharStruct overall;
XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction,
&logical_ascent, &logical_descent, &overall);
if (overall_ink) {
overall_ink->x = overall.lbearing;
overall_ink->y = -(overall.ascent);
overall_ink->width = overall.rbearing - overall.lbearing;
overall_ink->height = overall.ascent + overall.descent;
}
if (overall_logical) {
overall_logical->x = 0;
overall_logical->y = -(logical_ascent);
overall_logical->width = overall.width;
overall_logical->height = logical_ascent + logical_descent;
}
return overall.width;
}
static int
_XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length,
XRectangle *overall_ink, XRectangle *overall_logical)
{
DefineLocalBuf;
char *buf = AllocLocalBuf(length);
int ret = 0;
if (buf == NULL)
return 0;
if (wcs_to_mbs(oc, buf, text, length) == False)
goto err;
ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical);
err:
FreeLocalBuf(buf);
return ret;
}
static Status
_XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length,
XRectangle *ink_buf, XRectangle *logical_buf,
int buf_size, int *num_chars,
XRectangle *overall_ink,
XRectangle *overall_logical)
{
XFontStruct *font = *oc->core.font_info.font_struct_list;
XCharStruct *def, *cs, overall;
Bool first = True;
if (buf_size < length)
return 0;
bzero((char *) &overall, sizeof(XCharStruct));
*num_chars = 0;
CI_GET_DEFAULT_INFO_1D(font, def)
while (length-- > 0) {
CI_GET_CHAR_INFO_1D(font, *text, def, cs)
text++;
if (cs == NULL)
continue;
ink_buf->x = overall.width + cs->lbearing;
ink_buf->y = -(cs->ascent);
ink_buf->width = cs->rbearing - cs->lbearing;
ink_buf->height = cs->ascent + cs->descent;
ink_buf++;
logical_buf->x = overall.width;
logical_buf->y = -(font->ascent);
logical_buf->width = cs->width;
logical_buf->height = font->ascent + font->descent;
logical_buf++;
if (first) {
overall = *cs;
first = False;
} else {
overall.ascent = max(overall.ascent, cs->ascent);
overall.descent = max(overall.descent, cs->descent);
overall.lbearing = min(overall.lbearing, overall.width +
cs->lbearing);
overall.rbearing = max(overall.rbearing, overall.width +
cs->rbearing);
overall.width += cs->width;
}
(*num_chars)++;
}
if (overall_ink) {
overall_ink->x = overall.lbearing;
overall_ink->y = -(overall.ascent);
overall_ink->width = overall.rbearing - overall.lbearing;
overall_ink->height = overall.ascent + overall.descent;
}
if (overall_logical) {
overall_logical->x = 0;
overall_logical->y = -(font->ascent);
overall_logical->width = overall.width;
overall_logical->height = font->ascent + font->descent;
}
return 1;
}
static Status
_XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length,
XRectangle *ink_buf, XRectangle *logical_buf,
int buf_size, int *num_chars,
XRectangle *overall_ink,
XRectangle *overall_logical)
{
DefineLocalBuf;
char *buf = AllocLocalBuf(length);
Status ret = 0;
if (buf == NULL)
return 0;
if (wcs_to_mbs(oc, buf, text, length) == False)
goto err;
ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf,
buf_size, num_chars, overall_ink,
overall_logical);
err:
FreeLocalBuf(buf);
return ret;
}
static int
_XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
_Xconst char *text, int length)
{
XFontStruct *font = *oc->core.font_info.font_struct_list;
XSetFont(dpy, gc, font->fid);
XDrawString(dpy, d, gc, x, y, text, length);
return XTextWidth(font, text, length);
}
static int
_XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
_Xconst wchar_t *text, int length)
{
DefineLocalBuf;
char *buf = AllocLocalBuf(length);
int ret = 0;
if (buf == NULL)
return 0;
if (wcs_to_mbs(oc, buf, text, length) == False)
goto err;
ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length);
err:
FreeLocalBuf(buf);
return ret;
}
static void
_XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
int y, _Xconst char *text, int length)
{
XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid);
XDrawImageString(dpy, d, gc, x, y, text, length);
}
static void
_XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
int y, _Xconst wchar_t *text, int length)
{
DefineLocalBuf;
char *buf = AllocLocalBuf(length);
if (buf == NULL)
return;
if (wcs_to_mbs(oc, buf, text, length) == False)
goto err;
_XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length);
err:
FreeLocalBuf(buf);
}
static _Xconst XOCMethodsRec oc_default_methods = {
destroy_oc,
set_oc_values,
get_oc_values,
_XmbDefaultTextEscapement,
_XmbDefaultTextExtents,
_XmbDefaultTextPerCharExtents,
_XmbDefaultDrawString,
_XmbDefaultDrawImageString,
_XwcDefaultTextEscapement,
_XwcDefaultTextExtents,
_XwcDefaultTextPerCharExtents,
_XwcDefaultDrawString,
_XwcDefaultDrawImageString
};
static XlcResource oc_resources[] = {
{ XNBaseFontName, NULLQUARK, sizeof(char *),
XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask },
{ XNOMAutomatic, NULLQUARK, sizeof(Bool),
XOffsetOf(XOCRec, core.om_automatic), XlcGetMask },
{ XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList),
XOffsetOf(XOCRec, core.missing_list), XlcGetMask },
{ XNDefaultString, NULLQUARK, sizeof(char *),
XOffsetOf(XOCRec, core.default_string), XlcGetMask },
{ XNOrientation, NULLQUARK, sizeof(XOrientation),
XOffsetOf(XOCRec, core.orientation), XlcSetMask | XlcGetMask },
{ XNResourceName, NULLQUARK, sizeof(char *),
XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask },
{ XNResourceClass, NULLQUARK, sizeof(char *),
XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask },
{ XNFontInfo, NULLQUARK, sizeof(XOMFontInfo),
XOffsetOf(XOCRec, core.font_info), XlcGetMask }
};
static XOC
create_oc(
XOM om,
XlcArgList args,
int num_args)
{
XOC oc;
oc = (XOC) Xmalloc(sizeof(XOCGenericRec));
if (oc == NULL)
return (XOC) NULL;
bzero((char *) oc, sizeof(XOCGenericRec));
oc->core.om = om;
if (oc_resources[0].xrm_name == NULLQUARK)
_XlcCompileResourceList(oc_resources, XlcNumber(oc_resources));
if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources),
args, num_args, XlcCreateMask | XlcDefaultMask))
goto err;
if (oc->core.base_name_list == NULL)
goto err;
oc->core.resources = oc_resources;
oc->core.num_resources = XlcNumber(oc_resources);
if (create_fontset(oc) == False)
goto err;
oc->methods = (XOCMethods)&oc_default_methods;
return oc;
err:
destroy_oc(oc);
return (XOC) NULL;
}
static Status
close_om(
XOM om)
{
XOMGenericPart *gen = XOM_GENERIC(om);
OMData data;
FontData font_data;
int count;
if ((data = gen->data)) {
if (data->font_data) {
for (font_data = data->font_data, count = data->font_data_count;
count-- > 0 ; font_data++) {
if (font_data->name)
Xfree(font_data->name);
}
Xfree(data->font_data);
}
Xfree(gen->data);
}
if (om->core.res_name)
Xfree(om->core.res_name);
if (om->core.res_class)
Xfree(om->core.res_class);
if (om->core.required_charset.charset_list)
XFreeStringList(om->core.required_charset.charset_list);
else
Xfree((char*)om->core.required_charset.charset_list);
if (om->core.orientation_list.orientation)
Xfree(om->core.orientation_list.orientation);
Xfree(om);
return 1;
}
static char *
set_om_values(
XOM om,
XlcArgList args,
int num_args)
{
if (om->core.resources == NULL)
return NULL;
return _XlcSetValues((XPointer) om, om->core.resources,
om->core.num_resources, args, num_args, XlcSetMask);
}
static char *
get_om_values(
XOM om,
XlcArgList args,
int num_args)
{
if (om->core.resources == NULL)
return NULL;
return _XlcGetValues((XPointer) om, om->core.resources,
om->core.num_resources, args, num_args, XlcGetMask);
}
static _Xconst XOMMethodsRec methods = {
close_om,
set_om_values,
get_om_values,
create_oc
};
static XlcResource om_resources[] = {
{ XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList),
XOffsetOf(XOMRec, core.required_charset), XlcGetMask },
{ XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation),
XOffsetOf(XOMRec, core.orientation_list), XlcGetMask },
{ XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool),
XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask },
{ XNContextualDrawing, NULLQUARK, sizeof(Bool),
XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask }
};
static OMData
add_data(
XOM om)
{
XOMGenericPart *gen = XOM_GENERIC(om);
OMData new;
new = (OMData) Xmalloc(sizeof(OMDataRec));
if (new == NULL)
return NULL;
gen->data = new;
bzero((char *) new, sizeof(OMDataRec));
return new;
}
static _Xconst char *supported_charset_list[] = {
"ISO8859-1",
"adobe-fontspecific",
"SUNOLCURSOR-1",
"SUNOLGLYPH-1"
};
static Bool
init_om(
XOM om)
{
XOMGenericPart *gen = XOM_GENERIC(om);
OMData data;
FontData font_data;
char **required_list;
XOrientation *orientation;
char **value, buf[BUFSIZ], *bufptr;
int count, length = 0;
value = (char**)supported_charset_list;
count = XlcNumber(supported_charset_list);
data = add_data(om);
if (data == NULL)
return False;
font_data = (FontData) Xmalloc(sizeof(FontDataRec) * count);
if (font_data == NULL)
return False;
bzero((char *) font_data, sizeof(FontDataRec) * count);
data->font_data = font_data;
data->font_data_count = count;
for ( ; count-- > 0; font_data++) {
strcpy(buf, *value++);
font_data->name = (char *) Xmalloc(strlen(buf) + 1);
if (font_data->name == NULL)
return False;
strcpy(font_data->name, buf);
}
length += strlen(data->font_data->name) + 1;
required_list = (char **) Xmalloc(sizeof(char *));
if (required_list == NULL)
return False;
bufptr = (char *) Xmalloc(length);
if (bufptr == NULL) {
Xfree(required_list);
return False;
}
om->core.required_charset.charset_list = required_list;
om->core.required_charset.charset_count = 1;
data = gen->data;
strcpy(bufptr, data->font_data->name);
*required_list++ = bufptr;
bufptr += strlen(bufptr) + 1;
orientation = (XOrientation *) Xmalloc(sizeof(XOrientation));
if (orientation == NULL)
return False;
*orientation = XOMOrientation_LTR_TTB;
om->core.orientation_list.orientation = orientation;
om->core.orientation_list.num_orientation = 1;
om->core.directional_dependent = False;
om->core.contextual_drawing = False;
om->core.context_dependent = False;
return True;
}
XOM
_XDefaultOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb,
_Xconst char *res_name, _Xconst char *res_class)
{
XOM om;
om = (XOM) Xmalloc(sizeof(XOMGenericRec));
if (om == NULL)
return (XOM) NULL;
bzero((char *) om, sizeof(XOMGenericRec));
om->methods = (XOMMethods)&methods;
om->core.lcd = lcd;
om->core.display = dpy;
om->core.rdb = rdb;
if (res_name) {
om->core.res_name = (char *)Xmalloc(strlen(res_name) + 1);
if (om->core.res_name == NULL)
goto err;
strcpy(om->core.res_name, res_name);
}
if (res_class) {
om->core.res_class = (char *)Xmalloc(strlen(res_class) + 1);
if (om->core.res_class == NULL)
goto err;
strcpy(om->core.res_class, res_class);
}
if (om_resources[0].xrm_name == NULLQUARK)
_XlcCompileResourceList(om_resources, XlcNumber(om_resources));
om->core.resources = om_resources;
om->core.num_resources = XlcNumber(om_resources);
if (init_om(om) == False)
goto err;
return om;
err:
close_om(om);
return (XOM) NULL;
}