11ab64890Smrg/*
21ab64890SmrgCopyright 1985, 1986, 1987, 1991, 1998  The Open Group
31ab64890Smrg
41ab64890SmrgPermission is hereby granted, free of charge, to any person obtaining a
51ab64890Smrgcopy of this software and associated documentation files (the
61ab64890Smrg"Software"), to deal in the Software without restriction, including
71ab64890Smrgwithout limitation the rights to use, copy, modify, merge, publish,
81ab64890Smrgdistribute, sublicense, and/or sell copies of the Software, and to
91ab64890Smrgpermit persons to whom the Software is furnished to do so, subject to
101ab64890Smrgthe following conditions: The above copyright notice and this
111ab64890Smrgpermission notice shall be included in all copies or substantial
121ab64890Smrgportions of the Software.
131ab64890Smrg
141ab64890Smrg
15b4ee4795SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b4ee4795SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b4ee4795SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18b4ee4795SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19b4ee4795SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20b4ee4795SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
21b4ee4795SmrgEVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
221ab64890Smrg
231ab64890Smrg
24b4ee4795SmrgExcept as contained in this notice, the name of The Open Group shall not be
25b4ee4795Smrgused in advertising or otherwise to promote the sale, use or other dealings
26b4ee4795Smrgin this Software without prior written authorization from The Open Group.
271ab64890Smrg
281ab64890Smrg
291ab64890SmrgX Window System is a trademark of The Open Group
301ab64890Smrg
311ab64890SmrgOSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
321ab64890Smrglogo, LBX, X Window System, and Xinerama are trademarks of the Open
331ab64890SmrgGroup. All other trademarks and registered trademarks mentioned herein
341ab64890Smrgare the property of their respective owners. No right, title or
351ab64890Smrginterest in or to any trademark, service mark, logo or trade name of
361ab64890SmrgSun Microsystems, Inc. or its licensors is granted.
371ab64890Smrg
381ab64890Smrg*/
39b4ee4795Smrg/*
405efbdfc3Smrg * Copyright (c) 2000, Oracle and/or its affiliates.
41b4ee4795Smrg *
42b4ee4795Smrg * Permission is hereby granted, free of charge, to any person obtaining a
43b4ee4795Smrg * copy of this software and associated documentation files (the "Software"),
44b4ee4795Smrg * to deal in the Software without restriction, including without limitation
45b4ee4795Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
46b4ee4795Smrg * and/or sell copies of the Software, and to permit persons to whom the
47b4ee4795Smrg * Software is furnished to do so, subject to the following conditions:
48b4ee4795Smrg *
49b4ee4795Smrg * The above copyright notice and this permission notice (including the next
50b4ee4795Smrg * paragraph) shall be included in all copies or substantial portions of the
51b4ee4795Smrg * Software.
52b4ee4795Smrg *
53b4ee4795Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54b4ee4795Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55b4ee4795Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
56b4ee4795Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57b4ee4795Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
58b4ee4795Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
59b4ee4795Smrg * DEALINGS IN THE SOFTWARE.
60b4ee4795Smrg */
61b4ee4795Smrg
621ab64890Smrg
631ab64890Smrg#ifdef HAVE_CONFIG_H
641ab64890Smrg#include <config.h>
651ab64890Smrg#endif
661ab64890Smrg#include "Xlibint.h"
671ab64890Smrg#include "Xlcint.h"
681ab64890Smrg#include "XlcPublic.h"
691ab64890Smrg#include <X11/Xos.h>
701ab64890Smrg#include <X11/Xatom.h>
711ab64890Smrg#include <stdio.h>
721ab64890Smrg
731ab64890Smrg#define MAXFONTS		100
741ab64890Smrg
751ab64890Smrg#define XOM_GENERIC(om)		(&((XOMGeneric) om)->gen)
761ab64890Smrg#define XOC_GENERIC(font_set)	(&((XOCGeneric) font_set)->gen)
771ab64890Smrg
781ab64890Smrg#define DefineLocalBuf		char local_buf[BUFSIZ]
79818534a1Smrg#define AllocLocalBuf(length)	(length > BUFSIZ ? Xmalloc(length) : local_buf)
801ab64890Smrg#define FreeLocalBuf(ptr)	if (ptr != local_buf) Xfree(ptr)
811ab64890Smrg
821ab64890Smrgtypedef struct _FontDataRec {
831ab64890Smrg    char *name;
841ab64890Smrg} FontDataRec, *FontData;
851ab64890Smrg
861ab64890Smrgtypedef struct _OMDataRec {
871ab64890Smrg    int font_data_count;
881ab64890Smrg    FontData font_data;
891ab64890Smrg} OMDataRec, *OMData;
901ab64890Smrg
911ab64890Smrgtypedef struct _XOMGenericPart {
921ab64890Smrg    OMData data;
931ab64890Smrg} XOMGenericPart;
941ab64890Smrg
951ab64890Smrgtypedef struct _XOMGenericRec {
961ab64890Smrg    XOMMethods methods;
971ab64890Smrg    XOMCoreRec core;
981ab64890Smrg    XOMGenericPart gen;
991ab64890Smrg} XOMGenericRec, *XOMGeneric;
1001ab64890Smrg
1011ab64890Smrgtypedef struct _FontSetRec {
1021ab64890Smrg    int id;
1031ab64890Smrg    int font_data_count;
1041ab64890Smrg    FontData font_data;
1051ab64890Smrg    char *font_name;
1061ab64890Smrg    XFontStruct *info;
1071ab64890Smrg    XFontStruct *font;
1081ab64890Smrg} FontSetRec, *FontSet;
1091ab64890Smrg
1101ab64890Smrgtypedef struct _XOCGenericPart {
1111ab64890Smrg    XlcConv wcs_to_cs;
1121ab64890Smrg    FontSet font_set;
1131ab64890Smrg} XOCGenericPart;
1141ab64890Smrg
1151ab64890Smrgtypedef struct _XOCGenericRec {
1161ab64890Smrg    XOCMethods methods;
11761b2299dSmrg    XOCCoreRec core;
1181ab64890Smrg    XOCGenericPart gen;
1191ab64890Smrg} XOCGenericRec, *XOCGeneric;
1201ab64890Smrg
1211ab64890Smrgstatic Bool
1221ab64890Smrginit_fontset(
1231ab64890Smrg    XOC oc)
1241ab64890Smrg{
1251ab64890Smrg    XOCGenericPart *gen;
1261ab64890Smrg    FontSet font_set;
1271ab64890Smrg    OMData data;
1281ab64890Smrg
1291ab64890Smrg    data = XOM_GENERIC(oc->core.om)->data;
1301ab64890Smrg
1316cc2b21fSmrg    font_set = Xcalloc(1, sizeof(FontSetRec));
1321ab64890Smrg    if (font_set == NULL)
1331ab64890Smrg	return False;
1341ab64890Smrg
1351ab64890Smrg    gen = XOC_GENERIC(oc);
1361ab64890Smrg    gen->font_set = font_set;
1371ab64890Smrg
1381ab64890Smrg    font_set->font_data_count = data->font_data_count;
1391ab64890Smrg    font_set->font_data = data->font_data;
1401ab64890Smrg
1411ab64890Smrg    return True;
1421ab64890Smrg}
1431ab64890Smrg
1441ab64890Smrgstatic char *
1451ab64890Smrgget_prop_name(
1461ab64890Smrg    Display *dpy,
1471ab64890Smrg    XFontStruct	*fs)
1481ab64890Smrg{
1491ab64890Smrg    unsigned long fp;
1501ab64890Smrg
1511ab64890Smrg    if (XGetFontProperty(fs, XA_FONT, &fp))
15261b2299dSmrg	return XGetAtomName(dpy, fp);
1531ab64890Smrg
1541ab64890Smrg    return (char *) NULL;
1551ab64890Smrg}
1561ab64890Smrg
1571ab64890Smrgstatic FontData
1581ab64890Smrgcheck_charset(
1591ab64890Smrg    FontSet font_set,
1601ab64890Smrg    char *font_name)
1611ab64890Smrg{
1621ab64890Smrg    FontData font_data;
1631ab64890Smrg    char *last;
1641ab64890Smrg    int count;
1651ab64890Smrg    ssize_t length, name_len;
1661ab64890Smrg
1679c019ec5Smaya    name_len = (ssize_t) strlen(font_name);
1681ab64890Smrg    last = font_name + name_len;
1691ab64890Smrg
1701ab64890Smrg    count = font_set->font_data_count;
1711ab64890Smrg    font_data = font_set->font_data;
1721ab64890Smrg
1731ab64890Smrg    for ( ; count-- > 0; font_data++) {
1749c019ec5Smaya	length = (ssize_t) strlen(font_data->name);
1751ab64890Smrg
1761ab64890Smrg	if (length > name_len)
1771ab64890Smrg	    return(NULL);
17861b2299dSmrg
1791ab64890Smrg	if (_XlcCompareISOLatin1(last - length, font_data->name) == 0)
1801ab64890Smrg	    return font_data;
1811ab64890Smrg    }
1821ab64890Smrg    return (FontData) NULL;
1831ab64890Smrg}
1841ab64890Smrg
1851ab64890Smrgstatic Bool
1861ab64890Smrgload_font(
1871ab64890Smrg    XOC oc)
1881ab64890Smrg{
1891ab64890Smrg    Display *dpy = oc->core.om->core.display;
1901ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
1911ab64890Smrg    FontSet font_set = gen->font_set;
1921ab64890Smrg
1931ab64890Smrg    if (font_set->font_name == NULL)
1941ab64890Smrg	return False;
1951ab64890Smrg
1961ab64890Smrg    if (font_set->font == NULL) {
1971ab64890Smrg	font_set->font = XLoadQueryFont(dpy, font_set->font_name);
1981ab64890Smrg	if (font_set->font == NULL)
1991ab64890Smrg	    return False;
2001ab64890Smrg    }
2011ab64890Smrg    return True;
2021ab64890Smrg}
2031ab64890Smrg
2041ab64890Smrgstatic void
2051ab64890Smrgset_fontset_extents(
2061ab64890Smrg    XOC oc)
2071ab64890Smrg{
2081ab64890Smrg    XRectangle *ink = &oc->core.font_set_extents.max_ink_extent;
2091ab64890Smrg    XRectangle *logical = &oc->core.font_set_extents.max_logical_extent;
2101ab64890Smrg    XFontStruct **font_list, *font;
2111ab64890Smrg    XCharStruct overall;
2121ab64890Smrg    int logical_ascent, logical_descent;
2131ab64890Smrg
2141ab64890Smrg    font_list = oc->core.font_info.font_struct_list;
2151ab64890Smrg    font = *font_list++;
2161ab64890Smrg    overall = font->max_bounds;
2171ab64890Smrg    overall.lbearing = font->min_bounds.lbearing;
2181ab64890Smrg    logical_ascent = font->ascent;
2191ab64890Smrg    logical_descent = font->descent;
2201ab64890Smrg
2211ab64890Smrg    ink->x = overall.lbearing;
2221ab64890Smrg    ink->y = -(overall.ascent);
2231ab64890Smrg    ink->width = overall.rbearing - overall.lbearing;
2241ab64890Smrg    ink->height = overall.ascent + overall.descent;
2251ab64890Smrg
2261ab64890Smrg    logical->x = 0;
2271ab64890Smrg    logical->y = -(logical_ascent);
2281ab64890Smrg    logical->width = overall.width;
2291ab64890Smrg    logical->height = logical_ascent + logical_descent;
2301ab64890Smrg}
2311ab64890Smrg
2321ab64890Smrgstatic Bool
2331ab64890Smrginit_core_part(
2341ab64890Smrg    XOC oc)
2351ab64890Smrg{
2361ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
2371ab64890Smrg    FontSet font_set;
2381ab64890Smrg    XFontStruct **font_struct_list;
2391ab64890Smrg    char **font_name_list, *font_name_buf;
2401ab64890Smrg
2411ab64890Smrg    font_set = gen->font_set;
2421ab64890Smrg
2432d67cb4fSmrg    if (font_set->font_name == NULL)
2441ab64890Smrg        return False;
2451ab64890Smrg
246818534a1Smrg    font_struct_list = Xmalloc(sizeof(XFontStruct *));
2471ab64890Smrg    if (font_struct_list == NULL)
2481ab64890Smrg	return False;
2491ab64890Smrg
250818534a1Smrg    font_name_list = Xmalloc(sizeof(char *));
2511ab64890Smrg    if (font_name_list == NULL)
2521ab64890Smrg	goto err;
2531ab64890Smrg
2542d67cb4fSmrg    font_name_buf = strdup(font_set->font_name);
2551ab64890Smrg    if (font_name_buf == NULL)
2561ab64890Smrg	goto err;
2571ab64890Smrg
2581ab64890Smrg    oc->core.font_info.num_font = 1;
2591ab64890Smrg    oc->core.font_info.font_name_list = font_name_list;
2601ab64890Smrg    oc->core.font_info.font_struct_list = font_struct_list;
2611ab64890Smrg
2622d67cb4fSmrg    font_set->id = 1;
2632d67cb4fSmrg    if (font_set->font)
2642d67cb4fSmrg        *font_struct_list = font_set->font;
2652d67cb4fSmrg    else
2662d67cb4fSmrg        *font_struct_list = font_set->info;
2672d67cb4fSmrg    Xfree(font_set->font_name);
2682d67cb4fSmrg    *font_name_list = font_set->font_name = font_name_buf;
2691ab64890Smrg
2701ab64890Smrg    set_fontset_extents(oc);
2711ab64890Smrg
2721ab64890Smrg    return True;
2731ab64890Smrg
2741ab64890Smrgerr:
2750f8248bfSmrg
2760f8248bfSmrg    Xfree(font_name_list);
2771ab64890Smrg    Xfree(font_struct_list);
2781ab64890Smrg
2791ab64890Smrg    return False;
2801ab64890Smrg}
2811ab64890Smrg
2821ab64890Smrgstatic char *
2831ab64890Smrgget_font_name(
2841ab64890Smrg    XOC oc,
2851ab64890Smrg    char *pattern)
2861ab64890Smrg{
28757f47464Smrg    char **list, *name;
2881ab64890Smrg    int count;
2891ab64890Smrg    XFontStruct *fs;
2901ab64890Smrg    Display *dpy = oc->core.om->core.display;
2911ab64890Smrg
2921ab64890Smrg    list = XListFonts(dpy, pattern, 1, &count);
2931ab64890Smrg    if (list != NULL) {
2946cc2b21fSmrg	name = strdup(*list);
29561b2299dSmrg
2961ab64890Smrg	XFreeFontNames(list);
2971ab64890Smrg    } else {
2981ab64890Smrg	fs = XLoadQueryFont(dpy, pattern);
2991ab64890Smrg	if (fs == NULL) return NULL;
3001ab64890Smrg
30157f47464Smrg	name = get_prop_name(dpy, fs);
3021ab64890Smrg	XFreeFont(dpy, fs);
3031ab64890Smrg    }
3041ab64890Smrg    return name;
3051ab64890Smrg}
3061ab64890Smrg
3071ab64890Smrgstatic int
3081ab64890Smrgparse_fontname(
3091ab64890Smrg    XOC oc)
3101ab64890Smrg{
3111ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
3121ab64890Smrg    FontSet font_set;
3131ab64890Smrg    FontData font_data;
3141ab64890Smrg    char *pattern, *last, buf[BUFSIZ];
3151ab64890Smrg    int font_data_count, found_num = 0;
3161ab64890Smrg    ssize_t length;
3171ab64890Smrg    int count, num_fields;
3181ab64890Smrg    char *base_name, *font_name, **name_list, **cur_name_list;
3191ab64890Smrg    char *charset_p = NULL;
3201ab64890Smrg    Bool append_charset;
3211ab64890Smrg    /*
3221ab64890Smrg       append_charset flag should be set to True when the XLFD fontname
3231ab64890Smrg       doesn't contain a chaset part.
3241ab64890Smrg     */
3251ab64890Smrg
3261ab64890Smrg    name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count);
3271ab64890Smrg    if (name_list == NULL)
3281ab64890Smrg	return -1;
3291ab64890Smrg    cur_name_list = name_list;
3301ab64890Smrg
3311ab64890Smrg    while (count-- > 0) {
3321ab64890Smrg        pattern = *cur_name_list++;
3331ab64890Smrg	if (pattern == NULL || *pattern == '\0')
3341ab64890Smrg	    continue;
3351ab64890Smrg
3361ab64890Smrg	append_charset = False;
3371ab64890Smrg
3381ab64890Smrg	if (strchr(pattern, '*') == NULL &&
3391ab64890Smrg	    (font_name = get_font_name(oc, pattern))) {
3401ab64890Smrg
3411ab64890Smrg	    font_set = gen->font_set;
3421ab64890Smrg
3431ab64890Smrg	    font_data = check_charset(font_set, font_name);
3441ab64890Smrg	    if (font_data == NULL) {
3451ab64890Smrg		Display *dpy = oc->core.om->core.display;
3461ab64890Smrg		char **fn_list = NULL, *prop_fname = NULL;
3471ab64890Smrg		int list_num;
3481ab64890Smrg		XFontStruct *fs_list;
3491ab64890Smrg		if ((fn_list = XListFontsWithInfo(dpy, font_name,
3501ab64890Smrg						  MAXFONTS,
3511ab64890Smrg						  &list_num, &fs_list))
3521ab64890Smrg		    && (prop_fname = get_prop_name(dpy, fs_list))
3531ab64890Smrg		    && (font_data = check_charset(font_set, prop_fname))) {
3541ab64890Smrg		    if (fn_list) {
3551ab64890Smrg			XFreeFontInfo(fn_list, fs_list, list_num);
3561ab64890Smrg			fn_list = NULL;
3571ab64890Smrg		    }
3581ab64890Smrg		    font_name = prop_fname;
3591ab64890Smrg		}
3601ab64890Smrg	    }
3611ab64890Smrg	    if (font_data == NULL)
3621ab64890Smrg		continue;
3631ab64890Smrg
3646cc2b21fSmrg	    font_set->font_name = strdup(font_name);
3656cc2b21fSmrg	    Xfree(font_name);
3661ab64890Smrg	    if (font_set->font_name == NULL) {
3671ab64890Smrg		goto err;
3681ab64890Smrg	    }
3691ab64890Smrg	    found_num++;
3701ab64890Smrg	    goto found;
3711ab64890Smrg	}
3722d67cb4fSmrg
3731ab64890Smrg	strncpy(buf, pattern, BUFSIZ);
3741ab64890Smrg	buf[BUFSIZ-1] = '\0';
3759c019ec5Smaya	length = (ssize_t) strlen(buf);
3761ab64890Smrg	last = buf + length - 1;
3771ab64890Smrg
3781ab64890Smrg	for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++)
3791ab64890Smrg	    if (*base_name == '-') num_fields++;
3801ab64890Smrg	if (strchr(pattern, '*') == NULL) {
3811ab64890Smrg	    if (num_fields == 12) {
3821ab64890Smrg		append_charset = True;
3831ab64890Smrg		*++last = '-';
3841ab64890Smrg		last++;
3851ab64890Smrg	    } else
3861ab64890Smrg		continue;
3871ab64890Smrg	} else {
3881ab64890Smrg	    if (num_fields == 13 || num_fields == 14) {
38961b2299dSmrg	    /*
3901ab64890Smrg	     * There are 14 fields in an XLFD name -- make certain the
3911ab64890Smrg	     * charset (& encoding) is placed in the correct field.
3921ab64890Smrg	     */
3931ab64890Smrg		append_charset = True;
3941ab64890Smrg		last = strrchr (buf, '-');
3951ab64890Smrg		if (num_fields == 14) {
3961ab64890Smrg		    *last = '\0';
3971ab64890Smrg		    last = strrchr (buf, '-');
3981ab64890Smrg		}
3991ab64890Smrg		last++;
4001ab64890Smrg	    } else if (*last == '*') {
4011ab64890Smrg		append_charset = True;
4021ab64890Smrg		if (length > 3 && *(last-3) == '-' && *(last-2) == '*'
4031ab64890Smrg		    && *(last-1) == '-') {
4041ab64890Smrg		    last -= 2;
4051ab64890Smrg		}
4061ab64890Smrg		*++last = '-';
4071ab64890Smrg		last++;
4081ab64890Smrg	    } else {
4091ab64890Smrg		last = strrchr (buf, '-');
4101ab64890Smrg		charset_p = last;
4111ab64890Smrg		charset_p = strrchr (buf, '-');
4121ab64890Smrg		while (*(--charset_p) != '-');
4131ab64890Smrg		charset_p++;
4141ab64890Smrg	    }
4151ab64890Smrg	}
4161ab64890Smrg
4171ab64890Smrg	font_set = gen->font_set;
4181ab64890Smrg
4191ab64890Smrg	font_data = font_set->font_data;
4201ab64890Smrg	font_data_count = font_set->font_data_count;
4211ab64890Smrg	for ( ; font_data_count-- > 0; font_data++) {
4221ab64890Smrg	    if (append_charset)
4231ab64890Smrg		{
4249c019ec5Smaya		strncpy(last, font_data->name, (size_t) (BUFSIZ - length));
4251ab64890Smrg		buf[BUFSIZ-1] = '\0';
4261ab64890Smrg		}
4271ab64890Smrg	    else {
4281ab64890Smrg		if (_XlcCompareISOLatin1(charset_p,
4291ab64890Smrg					 font_data->name)) {
4301ab64890Smrg		    continue;
4311ab64890Smrg		}
4321ab64890Smrg	    }
4331ab64890Smrg	    if ((font_set->font_name = get_font_name(oc, buf)))
4341ab64890Smrg		break;
4351ab64890Smrg	}
4361ab64890Smrg	if (font_set->font_name != NULL) {
4371ab64890Smrg	    found_num++;
4381ab64890Smrg	    goto found;
4391ab64890Smrg	}
4401ab64890Smrg    }
4411ab64890Smrg  found:
4426cc2b21fSmrg    base_name = strdup(oc->core.base_name_list);
4431ab64890Smrg    if (base_name == NULL)
4441ab64890Smrg	goto err;
4451ab64890Smrg
4461ab64890Smrg    oc->core.base_name_list = base_name;
4471ab64890Smrg
44861b2299dSmrg    XFreeStringList(name_list);
4491ab64890Smrg
4501ab64890Smrg    return found_num;
4511ab64890Smrgerr:
45261b2299dSmrg    XFreeStringList(name_list);
4531ab64890Smrg
4541ab64890Smrg    return -1;
4551ab64890Smrg}
4561ab64890Smrg
4571ab64890Smrgstatic Bool
4581ab64890Smrgset_missing_list(
4591ab64890Smrg    XOC oc)
4601ab64890Smrg{
4611ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
4621ab64890Smrg    FontSet font_set;
4631ab64890Smrg    char **charset_list, *charset_buf;
4641ab64890Smrg
4651ab64890Smrg    font_set = gen->font_set;
4661ab64890Smrg
4672d67cb4fSmrg    if (font_set->info == NULL || font_set->font == NULL)
4681ab64890Smrg	return True;
4691ab64890Smrg
470818534a1Smrg    charset_list = Xmalloc(sizeof(char *));
4711ab64890Smrg    if (charset_list == NULL)
4721ab64890Smrg	return False;
4731ab64890Smrg
4742d67cb4fSmrg    charset_buf = strdup(font_set->font_data->name);
4751ab64890Smrg    if (charset_buf == NULL) {
4761ab64890Smrg	Xfree(charset_list);
4771ab64890Smrg	return False;
4781ab64890Smrg    }
4791ab64890Smrg
4801ab64890Smrg    oc->core.missing_list.charset_list = charset_list;
4811ab64890Smrg
4822d67cb4fSmrg    *charset_list = charset_buf;
4831ab64890Smrg
4841ab64890Smrg    return True;
4851ab64890Smrg}
4861ab64890Smrg
4871ab64890Smrgstatic Bool
4881ab64890Smrgcreate_fontset(
4891ab64890Smrg    XOC oc)
4901ab64890Smrg{
4911ab64890Smrg    int found_num;
4921ab64890Smrg
4931ab64890Smrg    if (init_fontset(oc) == False)
4941ab64890Smrg        return False;
4951ab64890Smrg
4961ab64890Smrg    found_num = parse_fontname(oc);
4971ab64890Smrg    if (found_num <= 0) {
4981ab64890Smrg	if (found_num == 0)
4991ab64890Smrg	    set_missing_list(oc);
5001ab64890Smrg	return False;
5011ab64890Smrg    }
5021ab64890Smrg
5031ab64890Smrg    if (load_font(oc) == False)
5041ab64890Smrg	return False;
5051ab64890Smrg
5061ab64890Smrg    if (init_core_part(oc) == False)
5071ab64890Smrg	return False;
5081ab64890Smrg
5091ab64890Smrg    if (set_missing_list(oc) == False)
5101ab64890Smrg	return False;
5111ab64890Smrg
5121ab64890Smrg    return True;
5131ab64890Smrg}
5141ab64890Smrg
5151ab64890Smrgstatic void
5161ab64890Smrgdestroy_oc(
5171ab64890Smrg    XOC oc)
5181ab64890Smrg{
5191ab64890Smrg    Display *dpy = oc->core.om->core.display;
5201ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
5211ab64890Smrg    XFontStruct **font_list, *font;
5221ab64890Smrg
5231ab64890Smrg
5240f8248bfSmrg    Xfree(gen->font_set);
5250f8248bfSmrg    Xfree(oc->core.base_name_list);
5260f8248bfSmrg    XFreeStringList(oc->core.font_info.font_name_list);
5271ab64890Smrg
5281ab64890Smrg    if ((font_list = oc->core.font_info.font_struct_list)) {
5291ab64890Smrg	if ((font = *font_list)) {
5301ab64890Smrg	    if (font->fid)
5311ab64890Smrg		XFreeFont(dpy, font);
5321ab64890Smrg	    else
5331ab64890Smrg		XFreeFontInfo(NULL, font, 1);
5341ab64890Smrg	}
5351ab64890Smrg	Xfree(oc->core.font_info.font_struct_list);
5361ab64890Smrg    }
5371ab64890Smrg
5380f8248bfSmrg
5390f8248bfSmrg    XFreeStringList(oc->core.missing_list.charset_list);
5401ab64890Smrg
5411ab64890Smrg#ifdef notdef
5420f8248bfSmrg    Xfree(oc->core.res_name);
5430f8248bfSmrg    Xfree(oc->core.res_class);
5441ab64890Smrg#endif
54561b2299dSmrg
5461ab64890Smrg    Xfree(oc);
5471ab64890Smrg}
5481ab64890Smrg
5491ab64890Smrgstatic char *
5501ab64890Smrgset_oc_values(
5511ab64890Smrg    XOC oc,
5521ab64890Smrg    XlcArgList args,
5531ab64890Smrg    int num_args)
5541ab64890Smrg{
5551ab64890Smrg    if (oc->core.resources == NULL)
5561ab64890Smrg	return NULL;
5571ab64890Smrg
5581ab64890Smrg    return _XlcSetValues((XPointer) oc, oc->core.resources,
5591ab64890Smrg			 oc->core.num_resources, args, num_args, XlcSetMask);
5601ab64890Smrg}
5611ab64890Smrg
5621ab64890Smrgstatic char *
5631ab64890Smrgget_oc_values(
5641ab64890Smrg    XOC oc,
5651ab64890Smrg    XlcArgList args,
5661ab64890Smrg    int num_args)
5671ab64890Smrg{
5681ab64890Smrg    if (oc->core.resources == NULL)
5691ab64890Smrg	return NULL;
5701ab64890Smrg
5711ab64890Smrg    return _XlcGetValues((XPointer) oc, oc->core.resources,
5721ab64890Smrg			 oc->core.num_resources, args, num_args, XlcGetMask);
5731ab64890Smrg}
5741ab64890Smrg
5751ab64890Smrgstatic Bool
5761ab64890Smrgwcs_to_mbs(
5771ab64890Smrg    XOC oc,
5781ab64890Smrg    char *to,
5791ab64890Smrg    _Xconst wchar_t *from,
5801ab64890Smrg    int length)
5811ab64890Smrg{
5821ab64890Smrg    XlcConv conv = XOC_GENERIC(oc)->wcs_to_cs;
5831ab64890Smrg    XLCd lcd;
5841ab64890Smrg    int ret, to_left = length;
5851ab64890Smrg
5861ab64890Smrg    if (conv == NULL) {
5871ab64890Smrg	lcd = oc->core.om->core.lcd;
5881ab64890Smrg	conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte);
5891ab64890Smrg	if (conv == NULL)
5901ab64890Smrg	    return False;
5911ab64890Smrg	XOC_GENERIC(oc)->wcs_to_cs = conv;
5921ab64890Smrg    } else
5931ab64890Smrg	_XlcResetConverter(conv);
5941ab64890Smrg
5951ab64890Smrg    ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to,
5961ab64890Smrg		      &to_left, NULL, 0);
5971ab64890Smrg    if (ret != 0 || length > 0)
5981ab64890Smrg	return False;
59961b2299dSmrg
6001ab64890Smrg    return True;
6011ab64890Smrg}
6021ab64890Smrg
6031ab64890Smrgstatic int
6041ab64890Smrg_XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length)
6051ab64890Smrg{
6061ab64890Smrg    return XTextWidth(*oc->core.font_info.font_struct_list, text, length);
6071ab64890Smrg}
6081ab64890Smrg
6091ab64890Smrgstatic int
6101ab64890Smrg_XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length)
6111ab64890Smrg{
6121ab64890Smrg    DefineLocalBuf;
6131ab64890Smrg    char *buf = AllocLocalBuf(length);
6141ab64890Smrg    int ret = 0;
6151ab64890Smrg
6161ab64890Smrg    if (buf == NULL)
6171ab64890Smrg	return 0;
6181ab64890Smrg
6191ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
6201ab64890Smrg	goto err;
6211ab64890Smrg
6221ab64890Smrg    ret = _XmbDefaultTextEscapement(oc, buf, length);
6231ab64890Smrg
6241ab64890Smrgerr:
6251ab64890Smrg    FreeLocalBuf(buf);
6261ab64890Smrg
6271ab64890Smrg    return ret;
6281ab64890Smrg}
6291ab64890Smrg
6301ab64890Smrgstatic int
6311ab64890Smrg_XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length,
6321ab64890Smrg		       XRectangle *overall_ink, XRectangle *overall_logical)
6331ab64890Smrg{
6341ab64890Smrg    int direction, logical_ascent, logical_descent;
6351ab64890Smrg    XCharStruct overall;
6361ab64890Smrg
6371ab64890Smrg    XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction,
6381ab64890Smrg		 &logical_ascent, &logical_descent, &overall);
6391ab64890Smrg
6401ab64890Smrg    if (overall_ink) {
6411ab64890Smrg	overall_ink->x = overall.lbearing;
6421ab64890Smrg	overall_ink->y = -(overall.ascent);
6431ab64890Smrg	overall_ink->width = overall.rbearing - overall.lbearing;
6441ab64890Smrg	overall_ink->height = overall.ascent + overall.descent;
6451ab64890Smrg    }
6461ab64890Smrg
6471ab64890Smrg    if (overall_logical) {
6481ab64890Smrg	overall_logical->x = 0;
6491ab64890Smrg        overall_logical->y = -(logical_ascent);
6501ab64890Smrg	overall_logical->width = overall.width;
6511ab64890Smrg        overall_logical->height = logical_ascent + logical_descent;
6521ab64890Smrg    }
6531ab64890Smrg
6541ab64890Smrg    return overall.width;
6551ab64890Smrg}
6561ab64890Smrg
6571ab64890Smrgstatic int
6581ab64890Smrg_XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length,
6591ab64890Smrg		       XRectangle *overall_ink, XRectangle *overall_logical)
6601ab64890Smrg{
6611ab64890Smrg    DefineLocalBuf;
6621ab64890Smrg    char *buf = AllocLocalBuf(length);
6631ab64890Smrg    int ret = 0;
6641ab64890Smrg
6651ab64890Smrg    if (buf == NULL)
6661ab64890Smrg	return 0;
6671ab64890Smrg
6681ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
6691ab64890Smrg	goto err;
6701ab64890Smrg
6711ab64890Smrg    ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical);
6721ab64890Smrg
6731ab64890Smrgerr:
6741ab64890Smrg    FreeLocalBuf(buf);
6751ab64890Smrg
6761ab64890Smrg    return ret;
6771ab64890Smrg}
6781ab64890Smrg
6791ab64890Smrgstatic Status
6801ab64890Smrg_XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length,
6811ab64890Smrg			      XRectangle *ink_buf, XRectangle *logical_buf,
6821ab64890Smrg			      int buf_size, int *num_chars,
6831ab64890Smrg			      XRectangle *overall_ink,
6841ab64890Smrg			      XRectangle *overall_logical)
6851ab64890Smrg{
6861ab64890Smrg    XFontStruct *font = *oc->core.font_info.font_struct_list;
6871ab64890Smrg    XCharStruct *def, *cs, overall;
6881ab64890Smrg    Bool first = True;
6891ab64890Smrg
6901ab64890Smrg    if (buf_size < length)
6911ab64890Smrg	return 0;
6921ab64890Smrg
6931ab64890Smrg    bzero((char *) &overall, sizeof(XCharStruct));
6941ab64890Smrg    *num_chars = 0;
6951ab64890Smrg
69607fb9b8fSmrg    CI_GET_DEFAULT_INFO_1D(font, def);
6971ab64890Smrg
6981ab64890Smrg    while (length-- > 0) {
69907fb9b8fSmrg	CI_GET_CHAR_INFO_1D(font, *text, def, cs);
7001ab64890Smrg	text++;
7011ab64890Smrg	if (cs == NULL)
7021ab64890Smrg	    continue;
7031ab64890Smrg
7041ab64890Smrg	ink_buf->x = overall.width + cs->lbearing;
7051ab64890Smrg	ink_buf->y = -(cs->ascent);
7061ab64890Smrg	ink_buf->width = cs->rbearing - cs->lbearing;
7071ab64890Smrg	ink_buf->height = cs->ascent + cs->descent;
7081ab64890Smrg	ink_buf++;
7091ab64890Smrg
7101ab64890Smrg	logical_buf->x = overall.width;
7111ab64890Smrg	logical_buf->y = -(font->ascent);
7121ab64890Smrg	logical_buf->width = cs->width;
7131ab64890Smrg	logical_buf->height = font->ascent + font->descent;
7141ab64890Smrg	logical_buf++;
7151ab64890Smrg
7161ab64890Smrg	if (first) {
7171ab64890Smrg	    overall = *cs;
7181ab64890Smrg	    first = False;
7191ab64890Smrg	} else {
7201ab64890Smrg	    overall.ascent = max(overall.ascent, cs->ascent);
7211ab64890Smrg	    overall.descent = max(overall.descent, cs->descent);
7221ab64890Smrg	    overall.lbearing = min(overall.lbearing, overall.width +
7231ab64890Smrg				   cs->lbearing);
7241ab64890Smrg	    overall.rbearing = max(overall.rbearing, overall.width +
7251ab64890Smrg				   cs->rbearing);
7261ab64890Smrg	    overall.width += cs->width;
7271ab64890Smrg	}
72861b2299dSmrg   	(*num_chars)++;
7291ab64890Smrg    }
7301ab64890Smrg
7311ab64890Smrg    if (overall_ink) {
7321ab64890Smrg	overall_ink->x = overall.lbearing;
7331ab64890Smrg	overall_ink->y = -(overall.ascent);
7341ab64890Smrg	overall_ink->width = overall.rbearing - overall.lbearing;
7351ab64890Smrg	overall_ink->height = overall.ascent + overall.descent;
7361ab64890Smrg    }
7371ab64890Smrg
7381ab64890Smrg    if (overall_logical) {
7391ab64890Smrg	overall_logical->x = 0;
7401ab64890Smrg	overall_logical->y = -(font->ascent);
7411ab64890Smrg	overall_logical->width = overall.width;
7421ab64890Smrg	overall_logical->height = font->ascent + font->descent;
7431ab64890Smrg    }
7441ab64890Smrg
7451ab64890Smrg    return 1;
7461ab64890Smrg}
7471ab64890Smrg
7481ab64890Smrgstatic Status
7491ab64890Smrg_XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length,
7501ab64890Smrg			      XRectangle *ink_buf, XRectangle *logical_buf,
7511ab64890Smrg			      int buf_size, int *num_chars,
7521ab64890Smrg			      XRectangle *overall_ink,
7531ab64890Smrg			      XRectangle *overall_logical)
7541ab64890Smrg{
7551ab64890Smrg    DefineLocalBuf;
7561ab64890Smrg    char *buf = AllocLocalBuf(length);
7571ab64890Smrg    Status ret = 0;
7581ab64890Smrg
7591ab64890Smrg    if (buf == NULL)
7601ab64890Smrg	return 0;
7611ab64890Smrg
7621ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
7631ab64890Smrg	goto err;
7641ab64890Smrg
7651ab64890Smrg    ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf,
7661ab64890Smrg					buf_size, num_chars, overall_ink,
7671ab64890Smrg					overall_logical);
7681ab64890Smrg
7691ab64890Smrgerr:
7701ab64890Smrg    FreeLocalBuf(buf);
7711ab64890Smrg
7721ab64890Smrg    return ret;
7731ab64890Smrg}
7741ab64890Smrg
7751ab64890Smrgstatic int
7761ab64890Smrg_XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
7771ab64890Smrg		      _Xconst char *text, int length)
7781ab64890Smrg{
7791ab64890Smrg    XFontStruct *font = *oc->core.font_info.font_struct_list;
7801ab64890Smrg
7811ab64890Smrg    XSetFont(dpy, gc, font->fid);
7821ab64890Smrg    XDrawString(dpy, d, gc, x, y, text, length);
7831ab64890Smrg
7841ab64890Smrg    return XTextWidth(font, text, length);
7851ab64890Smrg}
7861ab64890Smrg
7871ab64890Smrgstatic int
7881ab64890Smrg_XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
7891ab64890Smrg		      _Xconst wchar_t *text, int length)
7901ab64890Smrg{
7911ab64890Smrg    DefineLocalBuf;
7921ab64890Smrg    char *buf = AllocLocalBuf(length);
7931ab64890Smrg    int ret = 0;
7941ab64890Smrg
7951ab64890Smrg    if (buf == NULL)
7961ab64890Smrg	return 0;
7971ab64890Smrg
7981ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
7991ab64890Smrg	goto err;
8001ab64890Smrg
8011ab64890Smrg    ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length);
8021ab64890Smrg
8031ab64890Smrgerr:
8041ab64890Smrg    FreeLocalBuf(buf);
8051ab64890Smrg
8061ab64890Smrg    return ret;
8071ab64890Smrg}
8081ab64890Smrg
8091ab64890Smrgstatic void
8101ab64890Smrg_XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
8111ab64890Smrg			   int y, _Xconst char *text, int length)
8121ab64890Smrg{
8131ab64890Smrg    XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid);
8141ab64890Smrg    XDrawImageString(dpy, d, gc, x, y, text, length);
8151ab64890Smrg}
8161ab64890Smrg
8171ab64890Smrgstatic void
8181ab64890Smrg_XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
8191ab64890Smrg			   int y, _Xconst wchar_t *text, int length)
8201ab64890Smrg{
8211ab64890Smrg    DefineLocalBuf;
8221ab64890Smrg    char *buf = AllocLocalBuf(length);
8231ab64890Smrg
8241ab64890Smrg    if (buf == NULL)
8251ab64890Smrg	return;
8261ab64890Smrg
8271ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
8281ab64890Smrg	goto err;
8291ab64890Smrg
8301ab64890Smrg    _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length);
8311ab64890Smrg
8321ab64890Smrgerr:
8331ab64890Smrg    FreeLocalBuf(buf);
8341ab64890Smrg}
8351ab64890Smrg
8361ab64890Smrgstatic _Xconst XOCMethodsRec oc_default_methods = {
8371ab64890Smrg    destroy_oc,
8381ab64890Smrg    set_oc_values,
8391ab64890Smrg    get_oc_values,
8401ab64890Smrg    _XmbDefaultTextEscapement,
8411ab64890Smrg    _XmbDefaultTextExtents,
8421ab64890Smrg    _XmbDefaultTextPerCharExtents,
8431ab64890Smrg    _XmbDefaultDrawString,
8441ab64890Smrg    _XmbDefaultDrawImageString,
8451ab64890Smrg    _XwcDefaultTextEscapement,
8461ab64890Smrg    _XwcDefaultTextExtents,
8471ab64890Smrg    _XwcDefaultTextPerCharExtents,
8481ab64890Smrg    _XwcDefaultDrawString,
8491ab64890Smrg    _XwcDefaultDrawImageString
8501ab64890Smrg};
8511ab64890Smrg
8521ab64890Smrgstatic XlcResource oc_resources[] = {
8531ab64890Smrg    { XNBaseFontName, NULLQUARK, sizeof(char *),
8541ab64890Smrg      XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask },
8551ab64890Smrg    { XNOMAutomatic, NULLQUARK, sizeof(Bool),
8561ab64890Smrg      XOffsetOf(XOCRec, core.om_automatic), XlcGetMask },
8571ab64890Smrg    { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList),
8581ab64890Smrg      XOffsetOf(XOCRec, core.missing_list), XlcGetMask },
8591ab64890Smrg    { XNDefaultString, NULLQUARK, sizeof(char *),
8601ab64890Smrg      XOffsetOf(XOCRec, core.default_string), XlcGetMask },
8611ab64890Smrg    { XNOrientation, NULLQUARK, sizeof(XOrientation),
8621ab64890Smrg      XOffsetOf(XOCRec, core.orientation), XlcSetMask | XlcGetMask },
8631ab64890Smrg    { XNResourceName, NULLQUARK, sizeof(char *),
8641ab64890Smrg      XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask },
8651ab64890Smrg    { XNResourceClass, NULLQUARK, sizeof(char *),
8661ab64890Smrg      XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask },
8671ab64890Smrg    { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo),
8681ab64890Smrg      XOffsetOf(XOCRec, core.font_info), XlcGetMask }
8691ab64890Smrg};
8701ab64890Smrg
8711ab64890Smrgstatic XOC
8721ab64890Smrgcreate_oc(
8731ab64890Smrg    XOM om,
8741ab64890Smrg    XlcArgList args,
8751ab64890Smrg    int num_args)
8761ab64890Smrg{
8771ab64890Smrg    XOC oc;
8781ab64890Smrg
8796cc2b21fSmrg    oc = Xcalloc(1, sizeof(XOCGenericRec));
8801ab64890Smrg    if (oc == NULL)
8811ab64890Smrg	return (XOC) NULL;
88261b2299dSmrg
8831ab64890Smrg    oc->core.om = om;
8841ab64890Smrg
8851ab64890Smrg    if (oc_resources[0].xrm_name == NULLQUARK)
8861ab64890Smrg	_XlcCompileResourceList(oc_resources, XlcNumber(oc_resources));
88761b2299dSmrg
8881ab64890Smrg    if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources),
8891ab64890Smrg		      args, num_args, XlcCreateMask | XlcDefaultMask))
8901ab64890Smrg	goto err;
8911ab64890Smrg
8921ab64890Smrg    if (oc->core.base_name_list == NULL)
8931ab64890Smrg	goto err;
8941ab64890Smrg
8951ab64890Smrg    oc->core.resources = oc_resources;
8961ab64890Smrg    oc->core.num_resources = XlcNumber(oc_resources);
8971ab64890Smrg
8981ab64890Smrg    if (create_fontset(oc) == False)
8991ab64890Smrg	goto err;
9001ab64890Smrg
9011ab64890Smrg    oc->methods = (XOCMethods)&oc_default_methods;
9021ab64890Smrg
9031ab64890Smrg    return oc;
9041ab64890Smrg
9051ab64890Smrgerr:
9061ab64890Smrg    destroy_oc(oc);
9071ab64890Smrg
9081ab64890Smrg    return (XOC) NULL;
9091ab64890Smrg}
9101ab64890Smrg
9111ab64890Smrgstatic Status
9121ab64890Smrgclose_om(
9131ab64890Smrg    XOM om)
9141ab64890Smrg{
9151ab64890Smrg    XOMGenericPart *gen = XOM_GENERIC(om);
9161ab64890Smrg    OMData data;
9171ab64890Smrg    FontData font_data;
9181ab64890Smrg    int count;
9191ab64890Smrg
9201ab64890Smrg    if ((data = gen->data)) {
9211ab64890Smrg	if (data->font_data) {
9221ab64890Smrg	  for (font_data = data->font_data, count = data->font_data_count;
92361b2299dSmrg	       count-- > 0 ; font_data++) {
9241ab64890Smrg		Xfree(font_data->name);
9251ab64890Smrg	  }
9261ab64890Smrg	  Xfree(data->font_data);
9271ab64890Smrg	}
9281ab64890Smrg	Xfree(gen->data);
9291ab64890Smrg    }
9301ab64890Smrg
9310f8248bfSmrg
9320f8248bfSmrg    Xfree(om->core.res_name);
9330f8248bfSmrg    Xfree(om->core.res_class);
9340f8248bfSmrg
9351ab64890Smrg    if (om->core.required_charset.charset_list)
9361ab64890Smrg	XFreeStringList(om->core.required_charset.charset_list);
9371ab64890Smrg    else
9381ab64890Smrg	Xfree((char*)om->core.required_charset.charset_list);
9391ab64890Smrg
9400f8248bfSmrg    Xfree(om->core.orientation_list.orientation);
9411ab64890Smrg    Xfree(om);
9421ab64890Smrg
9431ab64890Smrg    return 1;
9441ab64890Smrg}
9451ab64890Smrg
9461ab64890Smrgstatic char *
9471ab64890Smrgset_om_values(
9481ab64890Smrg    XOM om,
9491ab64890Smrg    XlcArgList args,
9501ab64890Smrg    int num_args)
9511ab64890Smrg{
9521ab64890Smrg    if (om->core.resources == NULL)
9531ab64890Smrg	return NULL;
9541ab64890Smrg
9551ab64890Smrg    return _XlcSetValues((XPointer) om, om->core.resources,
9561ab64890Smrg			 om->core.num_resources, args, num_args, XlcSetMask);
9571ab64890Smrg}
9581ab64890Smrg
9591ab64890Smrgstatic char *
9601ab64890Smrgget_om_values(
9611ab64890Smrg    XOM om,
9621ab64890Smrg    XlcArgList args,
9631ab64890Smrg    int num_args)
9641ab64890Smrg{
9651ab64890Smrg    if (om->core.resources == NULL)
9661ab64890Smrg	return NULL;
9671ab64890Smrg
9681ab64890Smrg    return _XlcGetValues((XPointer) om, om->core.resources,
9691ab64890Smrg			 om->core.num_resources, args, num_args, XlcGetMask);
9701ab64890Smrg}
9711ab64890Smrg
9721ab64890Smrgstatic _Xconst XOMMethodsRec methods = {
9731ab64890Smrg    close_om,
9741ab64890Smrg    set_om_values,
9751ab64890Smrg    get_om_values,
9761ab64890Smrg    create_oc
9771ab64890Smrg};
9781ab64890Smrg
9791ab64890Smrgstatic XlcResource om_resources[] = {
9801ab64890Smrg    { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList),
9811ab64890Smrg      XOffsetOf(XOMRec, core.required_charset), XlcGetMask },
9821ab64890Smrg    { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation),
9831ab64890Smrg      XOffsetOf(XOMRec, core.orientation_list), XlcGetMask },
9841ab64890Smrg    { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool),
9851ab64890Smrg      XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask },
9861ab64890Smrg    { XNContextualDrawing, NULLQUARK, sizeof(Bool),
9871ab64890Smrg      XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask }
9881ab64890Smrg};
9891ab64890Smrg
9901ab64890Smrgstatic OMData
9911ab64890Smrgadd_data(
9921ab64890Smrg    XOM om)
9931ab64890Smrg{
9941ab64890Smrg    XOMGenericPart *gen = XOM_GENERIC(om);
9951ab64890Smrg    OMData new;
9961ab64890Smrg
9976cc2b21fSmrg    new = Xcalloc(1, sizeof(OMDataRec));
9981ab64890Smrg
9991ab64890Smrg    if (new == NULL)
10001ab64890Smrg        return NULL;
10011ab64890Smrg
10021ab64890Smrg    gen->data = new;
10031ab64890Smrg
10041ab64890Smrg    return new;
10051ab64890Smrg}
10061ab64890Smrg
10071ab64890Smrgstatic _Xconst char *supported_charset_list[] = {
10081ab64890Smrg    "ISO8859-1",
10091ab64890Smrg    "adobe-fontspecific",
10101ab64890Smrg    "SUNOLCURSOR-1",
10111ab64890Smrg    "SUNOLGLYPH-1"
10121ab64890Smrg};
101361b2299dSmrg
10141ab64890Smrgstatic Bool
10151ab64890Smrginit_om(
10161ab64890Smrg    XOM om)
10171ab64890Smrg{
10181ab64890Smrg    XOMGenericPart *gen = XOM_GENERIC(om);
10191ab64890Smrg    OMData data;
10201ab64890Smrg    FontData font_data;
10211ab64890Smrg    char **required_list;
10221ab64890Smrg    XOrientation *orientation;
1023818534a1Smrg    char *bufptr;
10242d67cb4fSmrg    int i, count;
10251ab64890Smrg
10261ab64890Smrg    count = XlcNumber(supported_charset_list);
10271ab64890Smrg
10281ab64890Smrg    data = add_data(om);
10291ab64890Smrg    if (data == NULL)
10301ab64890Smrg	return False;
10311ab64890Smrg
10326cc2b21fSmrg    font_data = Xcalloc(count, sizeof(FontDataRec));
10331ab64890Smrg    if (font_data == NULL)
10341ab64890Smrg	return False;
10351ab64890Smrg    data->font_data = font_data;
10361ab64890Smrg    data->font_data_count = count;
10371ab64890Smrg
1038818534a1Smrg    for (i = 0; i < count; i++, font_data++) {
1039818534a1Smrg	font_data->name = strdup(supported_charset_list[i]);
10401ab64890Smrg	if (font_data->name == NULL)
10411ab64890Smrg	    return False;
10421ab64890Smrg    }
10431ab64890Smrg
10441ab64890Smrg    /* required charset list */
1045818534a1Smrg    required_list = Xmalloc(sizeof(char *));
10461ab64890Smrg    if (required_list == NULL)
10471ab64890Smrg	return False;
10481ab64890Smrg
10492d67cb4fSmrg    bufptr = strdup(data->font_data->name);
10501ab64890Smrg    if (bufptr == NULL) {
10511ab64890Smrg	Xfree(required_list);
10521ab64890Smrg	return False;
10531ab64890Smrg    }
10541ab64890Smrg
10551ab64890Smrg    om->core.required_charset.charset_list = required_list;
10561ab64890Smrg    om->core.required_charset.charset_count = 1; /* always 1 */
10571ab64890Smrg
10581ab64890Smrg    data = gen->data;
10591ab64890Smrg
10602d67cb4fSmrg    *required_list = bufptr;
10611ab64890Smrg
10621ab64890Smrg    /* orientation list */
1063818534a1Smrg    orientation = Xmalloc(sizeof(XOrientation));
10641ab64890Smrg    if (orientation == NULL)
10651ab64890Smrg	return False;
10661ab64890Smrg
10671ab64890Smrg    *orientation = XOMOrientation_LTR_TTB;
10681ab64890Smrg    om->core.orientation_list.orientation = orientation;
10691ab64890Smrg    om->core.orientation_list.num_orientation = 1;
10701ab64890Smrg
10711ab64890Smrg    /* directional dependent drawing */
10721ab64890Smrg    om->core.directional_dependent = False;
10731ab64890Smrg
10749c019ec5Smaya    /* contextual drawing */
10751ab64890Smrg    om->core.contextual_drawing = False;
10761ab64890Smrg
10771ab64890Smrg    /* context dependent */
10781ab64890Smrg    om->core.context_dependent = False;
10791ab64890Smrg
10801ab64890Smrg    return True;
10811ab64890Smrg}
10821ab64890Smrg
10831ab64890SmrgXOM
10841ab64890Smrg_XDefaultOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb,
10851ab64890Smrg		_Xconst char *res_name, _Xconst char *res_class)
10861ab64890Smrg{
10871ab64890Smrg    XOM om;
10881ab64890Smrg
10896cc2b21fSmrg    om = Xcalloc(1, sizeof(XOMGenericRec));
10901ab64890Smrg    if (om == NULL)
10911ab64890Smrg	return (XOM) NULL;
109261b2299dSmrg
10931ab64890Smrg    om->methods = (XOMMethods)&methods;
10941ab64890Smrg    om->core.lcd = lcd;
10951ab64890Smrg    om->core.display = dpy;
10961ab64890Smrg    om->core.rdb = rdb;
10971ab64890Smrg    if (res_name) {
10986cc2b21fSmrg	om->core.res_name = strdup(res_name);
10991ab64890Smrg	if (om->core.res_name == NULL)
11001ab64890Smrg	    goto err;
11011ab64890Smrg    }
11021ab64890Smrg    if (res_class) {
11036cc2b21fSmrg	om->core.res_class = strdup(res_class);
11041ab64890Smrg	if (om->core.res_class == NULL)
11051ab64890Smrg	    goto err;
11061ab64890Smrg    }
11071ab64890Smrg
11081ab64890Smrg    if (om_resources[0].xrm_name == NULLQUARK)
11091ab64890Smrg	_XlcCompileResourceList(om_resources, XlcNumber(om_resources));
111061b2299dSmrg
11111ab64890Smrg    om->core.resources = om_resources;
11121ab64890Smrg    om->core.num_resources = XlcNumber(om_resources);
11131ab64890Smrg
11141ab64890Smrg    if (init_om(om) == False)
11151ab64890Smrg	goto err;
11161ab64890Smrg
11171ab64890Smrg    return om;
11181ab64890Smrgerr:
11191ab64890Smrg    close_om(om);
11201ab64890Smrg
11211ab64890Smrg    return (XOM) NULL;
11221ab64890Smrg}
1123