XDefaultOMIF.c revision 61b2299d
11ab64890Smrg/*
21ab64890SmrgCopyright 1985, 1986, 1987, 1991, 1998  The Open Group
31ab64890Smrg
41ab64890SmrgPortions Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
51ab64890Smrg
61ab64890SmrgPermission is hereby granted, free of charge, to any person obtaining a
71ab64890Smrgcopy of this software and associated documentation files (the
81ab64890Smrg"Software"), to deal in the Software without restriction, including
91ab64890Smrgwithout limitation the rights to use, copy, modify, merge, publish,
101ab64890Smrgdistribute, sublicense, and/or sell copies of the Software, and to
111ab64890Smrgpermit persons to whom the Software is furnished to do so, subject to
121ab64890Smrgthe following conditions: The above copyright notice and this
131ab64890Smrgpermission notice shall be included in all copies or substantial
141ab64890Smrgportions of the Software.
151ab64890Smrg
161ab64890Smrg
171ab64890SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
181ab64890SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
191ab64890SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
201ab64890SmrgIN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
211ab64890SmrgFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
221ab64890SmrgCONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
231ab64890SmrgTHE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
241ab64890SmrgADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
251ab64890Smrg
261ab64890Smrg
271ab64890SmrgExcept as contained in this notice, the names of The Open Group and/or
281ab64890SmrgSun Microsystems, Inc. shall not be used in advertising or otherwise to
291ab64890Smrgpromote the sale, use or other dealings in this Software without prior
301ab64890Smrgwritten authorization from The Open Group and/or Sun Microsystems,
311ab64890SmrgInc., as applicable.
321ab64890Smrg
331ab64890Smrg
341ab64890SmrgX Window System is a trademark of The Open Group
351ab64890Smrg
361ab64890SmrgOSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
371ab64890Smrglogo, LBX, X Window System, and Xinerama are trademarks of the Open
381ab64890SmrgGroup. All other trademarks and registered trademarks mentioned herein
391ab64890Smrgare the property of their respective owners. No right, title or
401ab64890Smrginterest in or to any trademark, service mark, logo or trade name of
411ab64890SmrgSun Microsystems, Inc. or its licensors is granted.
421ab64890Smrg
431ab64890Smrg*/
441ab64890Smrg/* $XFree86: xc/lib/X11/XDefaultOMIF.c,v 1.5 2003/04/17 02:39:56 dawes Exp $ */
451ab64890Smrg
461ab64890Smrg#ifdef HAVE_CONFIG_H
471ab64890Smrg#include <config.h>
481ab64890Smrg#endif
491ab64890Smrg#include "Xlibint.h"
501ab64890Smrg#include "Xlcint.h"
511ab64890Smrg#include "XlcPublic.h"
521ab64890Smrg#include <X11/Xos.h>
531ab64890Smrg#include <X11/Xatom.h>
541ab64890Smrg#include <stdio.h>
551ab64890Smrg
561ab64890Smrg#define MAXFONTS		100
571ab64890Smrg
581ab64890Smrg#define XOM_GENERIC(om)		(&((XOMGeneric) om)->gen)
591ab64890Smrg#define XOC_GENERIC(font_set)	(&((XOCGeneric) font_set)->gen)
601ab64890Smrg
611ab64890Smrg#define DefineLocalBuf		char local_buf[BUFSIZ]
621ab64890Smrg#define AllocLocalBuf(length)	(length > BUFSIZ ? (char *)Xmalloc(length) : local_buf)
631ab64890Smrg#define FreeLocalBuf(ptr)	if (ptr != local_buf) Xfree(ptr)
641ab64890Smrg
651ab64890Smrgtypedef struct _FontDataRec {
661ab64890Smrg    char *name;
671ab64890Smrg} FontDataRec, *FontData;
681ab64890Smrg
691ab64890Smrgtypedef struct _OMDataRec {
701ab64890Smrg    int font_data_count;
711ab64890Smrg    FontData font_data;
721ab64890Smrg} OMDataRec, *OMData;
731ab64890Smrg
741ab64890Smrgtypedef struct _XOMGenericPart {
751ab64890Smrg    OMData data;
761ab64890Smrg} XOMGenericPart;
771ab64890Smrg
781ab64890Smrgtypedef struct _XOMGenericRec {
791ab64890Smrg    XOMMethods methods;
801ab64890Smrg    XOMCoreRec core;
811ab64890Smrg    XOMGenericPart gen;
821ab64890Smrg} XOMGenericRec, *XOMGeneric;
831ab64890Smrg
841ab64890Smrgtypedef struct _FontSetRec {
851ab64890Smrg    int id;
861ab64890Smrg    int font_data_count;
871ab64890Smrg    FontData font_data;
881ab64890Smrg    char *font_name;
891ab64890Smrg    XFontStruct *info;
901ab64890Smrg    XFontStruct *font;
911ab64890Smrg} FontSetRec, *FontSet;
921ab64890Smrg
931ab64890Smrgtypedef struct _XOCGenericPart {
941ab64890Smrg    XlcConv wcs_to_cs;
951ab64890Smrg    FontSet font_set;
961ab64890Smrg} XOCGenericPart;
971ab64890Smrg
981ab64890Smrgtypedef struct _XOCGenericRec {
991ab64890Smrg    XOCMethods methods;
10061b2299dSmrg    XOCCoreRec core;
1011ab64890Smrg    XOCGenericPart gen;
1021ab64890Smrg} XOCGenericRec, *XOCGeneric;
1031ab64890Smrg
1041ab64890Smrgstatic Bool
1051ab64890Smrginit_fontset(
1061ab64890Smrg    XOC oc)
1071ab64890Smrg{
1081ab64890Smrg    XOCGenericPart *gen;
1091ab64890Smrg    FontSet font_set;
1101ab64890Smrg    OMData data;
1111ab64890Smrg
1121ab64890Smrg    data = XOM_GENERIC(oc->core.om)->data;
1131ab64890Smrg
1141ab64890Smrg    font_set = (FontSet) Xmalloc(sizeof(FontSetRec));
1151ab64890Smrg    if (font_set == NULL)
1161ab64890Smrg	return False;
1171ab64890Smrg    bzero((char *) font_set, sizeof(FontSetRec));
1181ab64890Smrg
1191ab64890Smrg    gen = XOC_GENERIC(oc);
1201ab64890Smrg    gen->font_set = font_set;
1211ab64890Smrg
1221ab64890Smrg    font_set->font_data_count = data->font_data_count;
1231ab64890Smrg    font_set->font_data = data->font_data;
1241ab64890Smrg
1251ab64890Smrg    return True;
1261ab64890Smrg}
1271ab64890Smrg
1281ab64890Smrgstatic char *
1291ab64890Smrgget_prop_name(
1301ab64890Smrg    Display *dpy,
1311ab64890Smrg    XFontStruct	*fs)
1321ab64890Smrg{
1331ab64890Smrg    unsigned long fp;
1341ab64890Smrg
1351ab64890Smrg    if (XGetFontProperty(fs, XA_FONT, &fp))
13661b2299dSmrg	return XGetAtomName(dpy, fp);
1371ab64890Smrg
1381ab64890Smrg    return (char *) NULL;
1391ab64890Smrg}
1401ab64890Smrg
1411ab64890Smrgstatic FontData
1421ab64890Smrgcheck_charset(
1431ab64890Smrg    FontSet font_set,
1441ab64890Smrg    char *font_name)
1451ab64890Smrg{
1461ab64890Smrg    FontData font_data;
1471ab64890Smrg    char *last;
1481ab64890Smrg    int count;
1491ab64890Smrg    ssize_t length, name_len;
1501ab64890Smrg
1511ab64890Smrg    name_len = strlen(font_name);
1521ab64890Smrg    last = font_name + name_len;
1531ab64890Smrg
1541ab64890Smrg    count = font_set->font_data_count;
1551ab64890Smrg    font_data = font_set->font_data;
1561ab64890Smrg
1571ab64890Smrg    for ( ; count-- > 0; font_data++) {
1581ab64890Smrg	length = strlen(font_data->name);
1591ab64890Smrg
1601ab64890Smrg	if (length > name_len)
1611ab64890Smrg	    return(NULL);
16261b2299dSmrg
1631ab64890Smrg	if (_XlcCompareISOLatin1(last - length, font_data->name) == 0)
1641ab64890Smrg	    return font_data;
1651ab64890Smrg    }
1661ab64890Smrg    return (FontData) NULL;
1671ab64890Smrg}
1681ab64890Smrg
1691ab64890Smrg#if 0 /* Unused */
1701ab64890Smrgstatic int
1711ab64890Smrgcheck_fontname(
1721ab64890Smrg    XOC oc,
1731ab64890Smrg    char *name)
1741ab64890Smrg{
1751ab64890Smrg    Display *dpy = oc->core.om->core.display;
1761ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
1771ab64890Smrg    FontData data;
1781ab64890Smrg    FontSet font_set;
1791ab64890Smrg    XFontStruct *fs_list;
1801ab64890Smrg    char **fn_list, *fname, *prop_fname = NULL;
1811ab64890Smrg    int list_num, i;
1821ab64890Smrg    int list2_num;
1831ab64890Smrg    char **fn2_list = NULL;
1841ab64890Smrg    int found_num = 0;
1851ab64890Smrg
1861ab64890Smrg    fn_list = XListFonts(dpy, name, MAXFONTS, &list_num);
1871ab64890Smrg    if (fn_list == NULL)
1881ab64890Smrg	return found_num;
1891ab64890Smrg
1901ab64890Smrg    for (i = 0; i < list_num; i++) {
1911ab64890Smrg	fname = fn_list[i];
1921ab64890Smrg
1931ab64890Smrg	font_set = gen->font_set;
1941ab64890Smrg
1951ab64890Smrg	if ((data = check_charset(font_set, fname)) == NULL) {
1961ab64890Smrg	    if ((fn2_list = XListFontsWithInfo(dpy, name, MAXFONTS,
1971ab64890Smrg					       &list2_num, &fs_list))
1981ab64890Smrg		&& (prop_fname = get_prop_name(dpy, fs_list))
1991ab64890Smrg		&& (data = check_charset(font_set, prop_fname)))
2001ab64890Smrg		fname = prop_fname;
2011ab64890Smrg	}
2021ab64890Smrg	if (data) {
2031ab64890Smrg	    font_set->font_name = (char *) Xmalloc(strlen(fname) + 1);
2041ab64890Smrg	    if (font_set->font_name) {
2051ab64890Smrg		strcpy(font_set->font_name, fname);
2061ab64890Smrg		found_num++;
2071ab64890Smrg	    }
2081ab64890Smrg	}
2091ab64890Smrg	if (fn2_list) {
2101ab64890Smrg	    XFreeFontInfo(fn2_list, fs_list, list2_num);
2111ab64890Smrg	    fn2_list = NULL;
2121ab64890Smrg	    if (prop_fname) {
2131ab64890Smrg		Xfree(prop_fname);
2141ab64890Smrg		prop_fname = NULL;
2151ab64890Smrg	    }
2161ab64890Smrg	}
2171ab64890Smrg	if (found_num == 1)
2181ab64890Smrg	    break;
2191ab64890Smrg    }
2201ab64890Smrg    XFreeFontNames(fn_list);
2211ab64890Smrg    return found_num;
2221ab64890Smrg}
2231ab64890Smrg#endif
2241ab64890Smrg
2251ab64890Smrgstatic Bool
2261ab64890Smrgload_font(
2271ab64890Smrg    XOC oc)
2281ab64890Smrg{
2291ab64890Smrg    Display *dpy = oc->core.om->core.display;
2301ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
2311ab64890Smrg    FontSet font_set = gen->font_set;
2321ab64890Smrg
2331ab64890Smrg    if (font_set->font_name == NULL)
2341ab64890Smrg	return False;
2351ab64890Smrg
2361ab64890Smrg    if (font_set->font == NULL) {
2371ab64890Smrg	font_set->font = XLoadQueryFont(dpy, font_set->font_name);
2381ab64890Smrg	if (font_set->font == NULL)
2391ab64890Smrg	    return False;
2401ab64890Smrg    }
2411ab64890Smrg    return True;
2421ab64890Smrg}
2431ab64890Smrg
2441ab64890Smrg#if 0
2451ab64890Smrgstatic Bool
2461ab64890Smrgload_font_info(
2471ab64890Smrg    XOC oc)
2481ab64890Smrg{
2491ab64890Smrg    Display *dpy = oc->core.om->core.display;
2501ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
2511ab64890Smrg    FontSet font_set = gen->font_set;
2521ab64890Smrg    char **fn_list;
2531ab64890Smrg    int fn_num;
2541ab64890Smrg
2551ab64890Smrg    if (font_set->font_name == NULL)
2561ab64890Smrg	return False;
2571ab64890Smrg
2581ab64890Smrg    if (font_set->info == NULL) {
2591ab64890Smrg	fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num,
2601ab64890Smrg				     &font_set->info);
2611ab64890Smrg	if (font_set->info == NULL)
2621ab64890Smrg	    return False;
2631ab64890Smrg	if (fn_num > 0)
2641ab64890Smrg	    font_set->info->fid = XLoadFont(dpy, font_set->font_name);
26561b2299dSmrg
2661ab64890Smrg	if (fn_list) XFreeFontNames(fn_list);
2671ab64890Smrg    }
2681ab64890Smrg    return True;
2691ab64890Smrg}
2701ab64890Smrg#endif
2711ab64890Smrg
2721ab64890Smrgstatic void
2731ab64890Smrgset_fontset_extents(
2741ab64890Smrg    XOC oc)
2751ab64890Smrg{
2761ab64890Smrg    XRectangle *ink = &oc->core.font_set_extents.max_ink_extent;
2771ab64890Smrg    XRectangle *logical = &oc->core.font_set_extents.max_logical_extent;
2781ab64890Smrg    XFontStruct **font_list, *font;
2791ab64890Smrg    XCharStruct overall;
2801ab64890Smrg    int logical_ascent, logical_descent;
2811ab64890Smrg
2821ab64890Smrg    font_list = oc->core.font_info.font_struct_list;
2831ab64890Smrg    font = *font_list++;
2841ab64890Smrg    overall = font->max_bounds;
2851ab64890Smrg    overall.lbearing = font->min_bounds.lbearing;
2861ab64890Smrg    logical_ascent = font->ascent;
2871ab64890Smrg    logical_descent = font->descent;
2881ab64890Smrg
2891ab64890Smrg    ink->x = overall.lbearing;
2901ab64890Smrg    ink->y = -(overall.ascent);
2911ab64890Smrg    ink->width = overall.rbearing - overall.lbearing;
2921ab64890Smrg    ink->height = overall.ascent + overall.descent;
2931ab64890Smrg
2941ab64890Smrg    logical->x = 0;
2951ab64890Smrg    logical->y = -(logical_ascent);
2961ab64890Smrg    logical->width = overall.width;
2971ab64890Smrg    logical->height = logical_ascent + logical_descent;
2981ab64890Smrg}
2991ab64890Smrg
3001ab64890Smrgstatic Bool
3011ab64890Smrginit_core_part(
3021ab64890Smrg    XOC oc)
3031ab64890Smrg{
3041ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
3051ab64890Smrg    FontSet font_set;
3061ab64890Smrg    XFontStruct **font_struct_list;
3071ab64890Smrg    char **font_name_list, *font_name_buf;
3081ab64890Smrg    int	count, length;
3091ab64890Smrg
3101ab64890Smrg    font_set = gen->font_set;
3111ab64890Smrg    count = length = 0;
3121ab64890Smrg
3131ab64890Smrg    if (font_set->font_name != NULL) {
3141ab64890Smrg	length += strlen(font_set->font_name) + 1;
3151ab64890Smrg	count++;
3161ab64890Smrg    }
3171ab64890Smrg    if (count == 0)
3181ab64890Smrg        return False;
3191ab64890Smrg
3201ab64890Smrg    font_struct_list = (XFontStruct **) Xmalloc(sizeof(XFontStruct *));
3211ab64890Smrg    if (font_struct_list == NULL)
3221ab64890Smrg	return False;
3231ab64890Smrg
3241ab64890Smrg    font_name_list = (char **) Xmalloc(sizeof(char *));
3251ab64890Smrg    if (font_name_list == NULL)
3261ab64890Smrg	goto err;
3271ab64890Smrg
3281ab64890Smrg    font_name_buf = (char *) Xmalloc(length);
3291ab64890Smrg    if (font_name_buf == NULL)
3301ab64890Smrg	goto err;
3311ab64890Smrg
3321ab64890Smrg    oc->core.font_info.num_font = 1;
3331ab64890Smrg    oc->core.font_info.font_name_list = font_name_list;
3341ab64890Smrg    oc->core.font_info.font_struct_list = font_struct_list;
3351ab64890Smrg
3361ab64890Smrg    font_set = gen->font_set;
3371ab64890Smrg
3381ab64890Smrg    if (font_set->font_name != NULL) {
3391ab64890Smrg	font_set->id = 1;
3401ab64890Smrg	if (font_set->font)
3411ab64890Smrg	    *font_struct_list++ = font_set->font;
3421ab64890Smrg	else
3431ab64890Smrg	    *font_struct_list++ = font_set->info;
3441ab64890Smrg	strcpy(font_name_buf, font_set->font_name);
3451ab64890Smrg	Xfree(font_set->font_name);
3461ab64890Smrg	*font_name_list++ = font_set->font_name = font_name_buf;
3471ab64890Smrg	font_name_buf += strlen(font_name_buf) + 1;
3481ab64890Smrg    }
3491ab64890Smrg
3501ab64890Smrg    set_fontset_extents(oc);
3511ab64890Smrg
3521ab64890Smrg    return True;
3531ab64890Smrg
3541ab64890Smrgerr:
3551ab64890Smrg    if (font_name_list)
3561ab64890Smrg	Xfree(font_name_list);
3571ab64890Smrg    Xfree(font_struct_list);
3581ab64890Smrg
3591ab64890Smrg    return False;
3601ab64890Smrg}
3611ab64890Smrg
3621ab64890Smrgstatic char *
3631ab64890Smrgget_font_name(
3641ab64890Smrg    XOC oc,
3651ab64890Smrg    char *pattern)
3661ab64890Smrg{
3671ab64890Smrg    char **list, *name, *prop_name;
3681ab64890Smrg    int count;
3691ab64890Smrg    XFontStruct *fs;
3701ab64890Smrg    Display *dpy = oc->core.om->core.display;
3711ab64890Smrg
3721ab64890Smrg    list = XListFonts(dpy, pattern, 1, &count);
3731ab64890Smrg    if (list != NULL) {
3741ab64890Smrg	name = (char *) Xmalloc(strlen(*list) + 1);
3751ab64890Smrg	if (name)
3761ab64890Smrg	    strcpy(name, *list);
37761b2299dSmrg
3781ab64890Smrg	XFreeFontNames(list);
3791ab64890Smrg    } else {
3801ab64890Smrg	fs = XLoadQueryFont(dpy, pattern);
3811ab64890Smrg	if (fs == NULL) return NULL;
3821ab64890Smrg
3831ab64890Smrg	prop_name = get_prop_name(dpy, fs);
3841ab64890Smrg	if (prop_name == NULL) return NULL;
3851ab64890Smrg
3861ab64890Smrg	name = (char*) Xmalloc(strlen(prop_name) + 1);
3871ab64890Smrg	if (name)
3881ab64890Smrg	    strcpy(name, prop_name);
3891ab64890Smrg
3901ab64890Smrg	XFreeFont(dpy, fs);
3911ab64890Smrg    }
3921ab64890Smrg    return name;
3931ab64890Smrg}
3941ab64890Smrg
3951ab64890Smrgstatic int
3961ab64890Smrgparse_fontname(
3971ab64890Smrg    XOC oc)
3981ab64890Smrg{
3991ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
4001ab64890Smrg    FontSet font_set;
4011ab64890Smrg    FontData font_data;
4021ab64890Smrg    char *pattern, *last, buf[BUFSIZ];
4031ab64890Smrg    int font_data_count, found_num = 0;
4041ab64890Smrg    ssize_t length;
4051ab64890Smrg    int count, num_fields;
4061ab64890Smrg    char *base_name, *font_name, **name_list, **cur_name_list;
4071ab64890Smrg    char *charset_p = NULL;
4081ab64890Smrg    Bool append_charset;
4091ab64890Smrg    /*
4101ab64890Smrg       append_charset flag should be set to True when the XLFD fontname
4111ab64890Smrg       doesn't contain a chaset part.
4121ab64890Smrg     */
4131ab64890Smrg
4141ab64890Smrg    name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count);
4151ab64890Smrg    if (name_list == NULL)
4161ab64890Smrg	return -1;
4171ab64890Smrg    cur_name_list = name_list;
4181ab64890Smrg
4191ab64890Smrg    while (count-- > 0) {
4201ab64890Smrg        pattern = *cur_name_list++;
4211ab64890Smrg	if (pattern == NULL || *pattern == '\0')
4221ab64890Smrg	    continue;
4231ab64890Smrg
4241ab64890Smrg	append_charset = False;
4251ab64890Smrg
4261ab64890Smrg	if (strchr(pattern, '*') == NULL &&
4271ab64890Smrg	    (font_name = get_font_name(oc, pattern))) {
4281ab64890Smrg
4291ab64890Smrg	    font_set = gen->font_set;
4301ab64890Smrg
4311ab64890Smrg	    font_data = check_charset(font_set, font_name);
4321ab64890Smrg	    if (font_data == NULL) {
4331ab64890Smrg		Display *dpy = oc->core.om->core.display;
4341ab64890Smrg		char **fn_list = NULL, *prop_fname = NULL;
4351ab64890Smrg		int list_num;
4361ab64890Smrg		XFontStruct *fs_list;
4371ab64890Smrg		if ((fn_list = XListFontsWithInfo(dpy, font_name,
4381ab64890Smrg						  MAXFONTS,
4391ab64890Smrg						  &list_num, &fs_list))
4401ab64890Smrg		    && (prop_fname = get_prop_name(dpy, fs_list))
4411ab64890Smrg		    && (font_data = check_charset(font_set, prop_fname))) {
4421ab64890Smrg		    if (fn_list) {
4431ab64890Smrg			XFreeFontInfo(fn_list, fs_list, list_num);
4441ab64890Smrg			fn_list = NULL;
4451ab64890Smrg		    }
4461ab64890Smrg		    font_name = prop_fname;
4471ab64890Smrg		}
4481ab64890Smrg	    }
4491ab64890Smrg	    if (font_data == NULL)
4501ab64890Smrg		continue;
4511ab64890Smrg
4521ab64890Smrg	    font_set->font_name = (char *) Xmalloc(strlen(font_name) + 1);
4531ab64890Smrg	    if (font_set->font_name == NULL) {
4541ab64890Smrg		Xfree(font_name);
4551ab64890Smrg		goto err;
4561ab64890Smrg	    }
4571ab64890Smrg	    strcpy(font_set->font_name, font_name);
4581ab64890Smrg	    Xfree(font_name);
4591ab64890Smrg	    found_num++;
4601ab64890Smrg	    goto found;
4611ab64890Smrg	}
4621ab64890Smrg/*
4631ab64890Smrg1266793
4641ab64890SmrgLimit the length of the string copy to prevent stack corruption.
4651ab64890Smrg	strcpy(buf, pattern);
4661ab64890Smrg*/
4671ab64890Smrg	strncpy(buf, pattern, BUFSIZ);
4681ab64890Smrg	buf[BUFSIZ-1] = '\0';
4691ab64890Smrg	length = strlen(buf);
4701ab64890Smrg	last = buf + length - 1;
4711ab64890Smrg
4721ab64890Smrg	for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++)
4731ab64890Smrg	    if (*base_name == '-') num_fields++;
4741ab64890Smrg	if (strchr(pattern, '*') == NULL) {
4751ab64890Smrg	    if (num_fields == 12) {
4761ab64890Smrg		append_charset = True;
4771ab64890Smrg		*++last = '-';
4781ab64890Smrg		last++;
4791ab64890Smrg	    } else
4801ab64890Smrg		continue;
4811ab64890Smrg	} else {
4821ab64890Smrg	    if (num_fields == 13 || num_fields == 14) {
48361b2299dSmrg	    /*
4841ab64890Smrg	     * There are 14 fields in an XLFD name -- make certain the
4851ab64890Smrg	     * charset (& encoding) is placed in the correct field.
4861ab64890Smrg	     */
4871ab64890Smrg		append_charset = True;
4881ab64890Smrg		last = strrchr (buf, '-');
4891ab64890Smrg		if (num_fields == 14) {
4901ab64890Smrg		    *last = '\0';
4911ab64890Smrg		    last = strrchr (buf, '-');
4921ab64890Smrg		}
4931ab64890Smrg		last++;
4941ab64890Smrg	    } else if (*last == '*') {
4951ab64890Smrg		append_charset = True;
4961ab64890Smrg		if (length > 3 && *(last-3) == '-' && *(last-2) == '*'
4971ab64890Smrg		    && *(last-1) == '-') {
4981ab64890Smrg		    last -= 2;
4991ab64890Smrg		}
5001ab64890Smrg		*++last = '-';
5011ab64890Smrg		last++;
5021ab64890Smrg	    } else {
5031ab64890Smrg		last = strrchr (buf, '-');
5041ab64890Smrg		charset_p = last;
5051ab64890Smrg		charset_p = strrchr (buf, '-');
5061ab64890Smrg		while (*(--charset_p) != '-');
5071ab64890Smrg		charset_p++;
5081ab64890Smrg	    }
5091ab64890Smrg	}
5101ab64890Smrg
5111ab64890Smrg	font_set = gen->font_set;
5121ab64890Smrg
5131ab64890Smrg	font_data = font_set->font_data;
5141ab64890Smrg	font_data_count = font_set->font_data_count;
5151ab64890Smrg	for ( ; font_data_count-- > 0; font_data++) {
5161ab64890Smrg	    if (append_charset)
5171ab64890Smrg		{
5181ab64890Smrg/*
5191ab64890Smrg1266793
5201ab64890SmrgLimit the length of the string copy to prevent stack corruption.
5211ab64890Smrg		strcpy(last, font_data->name);
5221ab64890Smrg*/
5231ab64890Smrg		strncpy(last, font_data->name, BUFSIZ - length);
5241ab64890Smrg		buf[BUFSIZ-1] = '\0';
5251ab64890Smrg		}
5261ab64890Smrg	    else {
5271ab64890Smrg		if (_XlcCompareISOLatin1(charset_p,
5281ab64890Smrg					 font_data->name)) {
5291ab64890Smrg		    continue;
5301ab64890Smrg		}
5311ab64890Smrg	    }
5321ab64890Smrg	    if ((font_set->font_name = get_font_name(oc, buf)))
5331ab64890Smrg		break;
5341ab64890Smrg	}
5351ab64890Smrg	if (font_set->font_name != NULL) {
5361ab64890Smrg	    found_num++;
5371ab64890Smrg	    goto found;
5381ab64890Smrg	}
5391ab64890Smrg    }
5401ab64890Smrg  found:
5411ab64890Smrg    base_name = (char *) Xmalloc(strlen(oc->core.base_name_list) + 1);
5421ab64890Smrg    if (base_name == NULL)
5431ab64890Smrg	goto err;
5441ab64890Smrg
5451ab64890Smrg    strcpy(base_name, oc->core.base_name_list);
5461ab64890Smrg    oc->core.base_name_list = base_name;
5471ab64890Smrg
54861b2299dSmrg    XFreeStringList(name_list);
5491ab64890Smrg
5501ab64890Smrg    return found_num;
5511ab64890Smrgerr:
55261b2299dSmrg    XFreeStringList(name_list);
5531ab64890Smrg
5541ab64890Smrg    return -1;
5551ab64890Smrg}
5561ab64890Smrg
5571ab64890Smrgstatic Bool
5581ab64890Smrgset_missing_list(
5591ab64890Smrg    XOC oc)
5601ab64890Smrg{
5611ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
5621ab64890Smrg    FontSet font_set;
5631ab64890Smrg    char **charset_list, *charset_buf;
5641ab64890Smrg    int	count, length;
5651ab64890Smrg
5661ab64890Smrg    font_set = gen->font_set;
5671ab64890Smrg    count = length = 0;
5681ab64890Smrg
5691ab64890Smrg    if (!font_set->info && !font_set->font) {
5701ab64890Smrg	length += strlen(font_set->font_data->name) + 1;
5711ab64890Smrg	count++;
5721ab64890Smrg    }
5731ab64890Smrg
5741ab64890Smrg    if (count == 0)
5751ab64890Smrg	return True;
5761ab64890Smrg
5771ab64890Smrg    charset_list = (char **) Xmalloc(sizeof(char *));
5781ab64890Smrg    if (charset_list == NULL)
5791ab64890Smrg	return False;
5801ab64890Smrg
5811ab64890Smrg    charset_buf = (char *) Xmalloc(length);
5821ab64890Smrg    if (charset_buf == NULL) {
5831ab64890Smrg	Xfree(charset_list);
5841ab64890Smrg	return False;
5851ab64890Smrg    }
5861ab64890Smrg
5871ab64890Smrg    oc->core.missing_list.charset_list = charset_list;
5881ab64890Smrg
5891ab64890Smrg    font_set = gen->font_set;
5901ab64890Smrg
5911ab64890Smrg    if (!font_set->info && !font_set->font) {
5921ab64890Smrg	strcpy(charset_buf, font_set->font_data->name);
5931ab64890Smrg	*charset_list++ = charset_buf;
5941ab64890Smrg	charset_buf += strlen(charset_buf) + 1;
5951ab64890Smrg    }
5961ab64890Smrg    return True;
5971ab64890Smrg}
5981ab64890Smrg
5991ab64890Smrgstatic Bool
6001ab64890Smrgcreate_fontset(
6011ab64890Smrg    XOC oc)
6021ab64890Smrg{
6031ab64890Smrg    int found_num;
6041ab64890Smrg
6051ab64890Smrg    if (init_fontset(oc) == False)
6061ab64890Smrg        return False;
6071ab64890Smrg
6081ab64890Smrg    found_num = parse_fontname(oc);
6091ab64890Smrg    if (found_num <= 0) {
6101ab64890Smrg	if (found_num == 0)
6111ab64890Smrg	    set_missing_list(oc);
6121ab64890Smrg	return False;
6131ab64890Smrg    }
6141ab64890Smrg
6151ab64890Smrg    if (load_font(oc) == False)
6161ab64890Smrg	return False;
6171ab64890Smrg
6181ab64890Smrg    if (init_core_part(oc) == False)
6191ab64890Smrg	return False;
6201ab64890Smrg
6211ab64890Smrg    if (set_missing_list(oc) == False)
6221ab64890Smrg	return False;
6231ab64890Smrg
6241ab64890Smrg    return True;
6251ab64890Smrg}
6261ab64890Smrg
6271ab64890Smrgstatic void
6281ab64890Smrgdestroy_oc(
6291ab64890Smrg    XOC oc)
6301ab64890Smrg{
6311ab64890Smrg    Display *dpy = oc->core.om->core.display;
6321ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
6331ab64890Smrg    XFontStruct **font_list, *font;
6341ab64890Smrg
6351ab64890Smrg    if (gen->font_set)
6361ab64890Smrg	Xfree(gen->font_set);
6371ab64890Smrg
6381ab64890Smrg    if (oc->core.base_name_list)
6391ab64890Smrg	Xfree(oc->core.base_name_list);
6401ab64890Smrg
6411ab64890Smrg    if (oc->core.font_info.font_name_list)
6421ab64890Smrg	XFreeStringList(oc->core.font_info.font_name_list);
6431ab64890Smrg
6441ab64890Smrg    if ((font_list = oc->core.font_info.font_struct_list)) {
6451ab64890Smrg	if ((font = *font_list)) {
6461ab64890Smrg	    if (font->fid)
6471ab64890Smrg		XFreeFont(dpy, font);
6481ab64890Smrg	    else
6491ab64890Smrg		XFreeFontInfo(NULL, font, 1);
6501ab64890Smrg	}
6511ab64890Smrg	Xfree(oc->core.font_info.font_struct_list);
6521ab64890Smrg    }
6531ab64890Smrg
6541ab64890Smrg    if (oc->core.missing_list.charset_list)
6551ab64890Smrg	XFreeStringList(oc->core.missing_list.charset_list);
6561ab64890Smrg
6571ab64890Smrg#ifdef notdef
6581ab64890Smrg    if (oc->core.res_name)
6591ab64890Smrg	Xfree(oc->core.res_name);
6601ab64890Smrg    if (oc->core.res_class)
6611ab64890Smrg	Xfree(oc->core.res_class);
6621ab64890Smrg#endif
66361b2299dSmrg
6641ab64890Smrg    Xfree(oc);
6651ab64890Smrg}
6661ab64890Smrg
6671ab64890Smrgstatic char *
6681ab64890Smrgset_oc_values(
6691ab64890Smrg    XOC oc,
6701ab64890Smrg    XlcArgList args,
6711ab64890Smrg    int num_args)
6721ab64890Smrg{
6731ab64890Smrg    if (oc->core.resources == NULL)
6741ab64890Smrg	return NULL;
6751ab64890Smrg
6761ab64890Smrg    return _XlcSetValues((XPointer) oc, oc->core.resources,
6771ab64890Smrg			 oc->core.num_resources, args, num_args, XlcSetMask);
6781ab64890Smrg}
6791ab64890Smrg
6801ab64890Smrgstatic char *
6811ab64890Smrgget_oc_values(
6821ab64890Smrg    XOC oc,
6831ab64890Smrg    XlcArgList args,
6841ab64890Smrg    int num_args)
6851ab64890Smrg{
6861ab64890Smrg    if (oc->core.resources == NULL)
6871ab64890Smrg	return NULL;
6881ab64890Smrg
6891ab64890Smrg    return _XlcGetValues((XPointer) oc, oc->core.resources,
6901ab64890Smrg			 oc->core.num_resources, args, num_args, XlcGetMask);
6911ab64890Smrg}
6921ab64890Smrg
6931ab64890Smrgstatic Bool
6941ab64890Smrgwcs_to_mbs(
6951ab64890Smrg    XOC oc,
6961ab64890Smrg    char *to,
6971ab64890Smrg    _Xconst wchar_t *from,
6981ab64890Smrg    int length)
6991ab64890Smrg{
7001ab64890Smrg    XlcConv conv = XOC_GENERIC(oc)->wcs_to_cs;
7011ab64890Smrg    XLCd lcd;
7021ab64890Smrg    int ret, to_left = length;
7031ab64890Smrg
7041ab64890Smrg    if (conv == NULL) {
7051ab64890Smrg	lcd = oc->core.om->core.lcd;
7061ab64890Smrg	conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte);
7071ab64890Smrg	if (conv == NULL)
7081ab64890Smrg	    return False;
7091ab64890Smrg	XOC_GENERIC(oc)->wcs_to_cs = conv;
7101ab64890Smrg    } else
7111ab64890Smrg	_XlcResetConverter(conv);
7121ab64890Smrg
7131ab64890Smrg    ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to,
7141ab64890Smrg		      &to_left, NULL, 0);
7151ab64890Smrg    if (ret != 0 || length > 0)
7161ab64890Smrg	return False;
71761b2299dSmrg
7181ab64890Smrg    return True;
7191ab64890Smrg}
7201ab64890Smrg
7211ab64890Smrgstatic int
7221ab64890Smrg_XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length)
7231ab64890Smrg{
7241ab64890Smrg    return XTextWidth(*oc->core.font_info.font_struct_list, text, length);
7251ab64890Smrg}
7261ab64890Smrg
7271ab64890Smrgstatic int
7281ab64890Smrg_XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length)
7291ab64890Smrg{
7301ab64890Smrg    DefineLocalBuf;
7311ab64890Smrg    char *buf = AllocLocalBuf(length);
7321ab64890Smrg    int ret = 0;
7331ab64890Smrg
7341ab64890Smrg    if (buf == NULL)
7351ab64890Smrg	return 0;
7361ab64890Smrg
7371ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
7381ab64890Smrg	goto err;
7391ab64890Smrg
7401ab64890Smrg    ret = _XmbDefaultTextEscapement(oc, buf, length);
7411ab64890Smrg
7421ab64890Smrgerr:
7431ab64890Smrg    FreeLocalBuf(buf);
7441ab64890Smrg
7451ab64890Smrg    return ret;
7461ab64890Smrg}
7471ab64890Smrg
7481ab64890Smrgstatic int
7491ab64890Smrg_XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length,
7501ab64890Smrg		       XRectangle *overall_ink, XRectangle *overall_logical)
7511ab64890Smrg{
7521ab64890Smrg    int direction, logical_ascent, logical_descent;
7531ab64890Smrg    XCharStruct overall;
7541ab64890Smrg
7551ab64890Smrg    XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction,
7561ab64890Smrg		 &logical_ascent, &logical_descent, &overall);
7571ab64890Smrg
7581ab64890Smrg    if (overall_ink) {
7591ab64890Smrg	overall_ink->x = overall.lbearing;
7601ab64890Smrg	overall_ink->y = -(overall.ascent);
7611ab64890Smrg	overall_ink->width = overall.rbearing - overall.lbearing;
7621ab64890Smrg	overall_ink->height = overall.ascent + overall.descent;
7631ab64890Smrg    }
7641ab64890Smrg
7651ab64890Smrg    if (overall_logical) {
7661ab64890Smrg	overall_logical->x = 0;
7671ab64890Smrg        overall_logical->y = -(logical_ascent);
7681ab64890Smrg	overall_logical->width = overall.width;
7691ab64890Smrg        overall_logical->height = logical_ascent + logical_descent;
7701ab64890Smrg    }
7711ab64890Smrg
7721ab64890Smrg    return overall.width;
7731ab64890Smrg}
7741ab64890Smrg
7751ab64890Smrgstatic int
7761ab64890Smrg_XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length,
7771ab64890Smrg		       XRectangle *overall_ink, XRectangle *overall_logical)
7781ab64890Smrg{
7791ab64890Smrg    DefineLocalBuf;
7801ab64890Smrg    char *buf = AllocLocalBuf(length);
7811ab64890Smrg    int ret = 0;
7821ab64890Smrg
7831ab64890Smrg    if (buf == NULL)
7841ab64890Smrg	return 0;
7851ab64890Smrg
7861ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
7871ab64890Smrg	goto err;
7881ab64890Smrg
7891ab64890Smrg    ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical);
7901ab64890Smrg
7911ab64890Smrgerr:
7921ab64890Smrg    FreeLocalBuf(buf);
7931ab64890Smrg
7941ab64890Smrg    return ret;
7951ab64890Smrg}
7961ab64890Smrg
7971ab64890Smrgstatic Status
7981ab64890Smrg_XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length,
7991ab64890Smrg			      XRectangle *ink_buf, XRectangle *logical_buf,
8001ab64890Smrg			      int buf_size, int *num_chars,
8011ab64890Smrg			      XRectangle *overall_ink,
8021ab64890Smrg			      XRectangle *overall_logical)
8031ab64890Smrg{
8041ab64890Smrg    XFontStruct *font = *oc->core.font_info.font_struct_list;
8051ab64890Smrg    XCharStruct *def, *cs, overall;
8061ab64890Smrg    Bool first = True;
8071ab64890Smrg
8081ab64890Smrg    if (buf_size < length)
8091ab64890Smrg	return 0;
8101ab64890Smrg
8111ab64890Smrg    bzero((char *) &overall, sizeof(XCharStruct));
8121ab64890Smrg    *num_chars = 0;
8131ab64890Smrg
8141ab64890Smrg    CI_GET_DEFAULT_INFO_1D(font, def)
8151ab64890Smrg
8161ab64890Smrg    while (length-- > 0) {
8171ab64890Smrg	CI_GET_CHAR_INFO_1D(font, *text, def, cs)
8181ab64890Smrg	text++;
8191ab64890Smrg	if (cs == NULL)
8201ab64890Smrg	    continue;
8211ab64890Smrg
8221ab64890Smrg	ink_buf->x = overall.width + cs->lbearing;
8231ab64890Smrg	ink_buf->y = -(cs->ascent);
8241ab64890Smrg	ink_buf->width = cs->rbearing - cs->lbearing;
8251ab64890Smrg	ink_buf->height = cs->ascent + cs->descent;
8261ab64890Smrg	ink_buf++;
8271ab64890Smrg
8281ab64890Smrg	logical_buf->x = overall.width;
8291ab64890Smrg	logical_buf->y = -(font->ascent);
8301ab64890Smrg	logical_buf->width = cs->width;
8311ab64890Smrg	logical_buf->height = font->ascent + font->descent;
8321ab64890Smrg	logical_buf++;
8331ab64890Smrg
8341ab64890Smrg	if (first) {
8351ab64890Smrg	    overall = *cs;
8361ab64890Smrg	    first = False;
8371ab64890Smrg	} else {
8381ab64890Smrg	    overall.ascent = max(overall.ascent, cs->ascent);
8391ab64890Smrg	    overall.descent = max(overall.descent, cs->descent);
8401ab64890Smrg	    overall.lbearing = min(overall.lbearing, overall.width +
8411ab64890Smrg				   cs->lbearing);
8421ab64890Smrg	    overall.rbearing = max(overall.rbearing, overall.width +
8431ab64890Smrg				   cs->rbearing);
8441ab64890Smrg	    overall.width += cs->width;
8451ab64890Smrg	}
84661b2299dSmrg   	(*num_chars)++;
8471ab64890Smrg    }
8481ab64890Smrg
8491ab64890Smrg    if (overall_ink) {
8501ab64890Smrg	overall_ink->x = overall.lbearing;
8511ab64890Smrg	overall_ink->y = -(overall.ascent);
8521ab64890Smrg	overall_ink->width = overall.rbearing - overall.lbearing;
8531ab64890Smrg	overall_ink->height = overall.ascent + overall.descent;
8541ab64890Smrg    }
8551ab64890Smrg
8561ab64890Smrg    if (overall_logical) {
8571ab64890Smrg	overall_logical->x = 0;
8581ab64890Smrg	overall_logical->y = -(font->ascent);
8591ab64890Smrg	overall_logical->width = overall.width;
8601ab64890Smrg	overall_logical->height = font->ascent + font->descent;
8611ab64890Smrg    }
8621ab64890Smrg
8631ab64890Smrg    return 1;
8641ab64890Smrg}
8651ab64890Smrg
8661ab64890Smrgstatic Status
8671ab64890Smrg_XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length,
8681ab64890Smrg			      XRectangle *ink_buf, XRectangle *logical_buf,
8691ab64890Smrg			      int buf_size, int *num_chars,
8701ab64890Smrg			      XRectangle *overall_ink,
8711ab64890Smrg			      XRectangle *overall_logical)
8721ab64890Smrg{
8731ab64890Smrg    DefineLocalBuf;
8741ab64890Smrg    char *buf = AllocLocalBuf(length);
8751ab64890Smrg    Status ret = 0;
8761ab64890Smrg
8771ab64890Smrg    if (buf == NULL)
8781ab64890Smrg	return 0;
8791ab64890Smrg
8801ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
8811ab64890Smrg	goto err;
8821ab64890Smrg
8831ab64890Smrg    ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf,
8841ab64890Smrg					buf_size, num_chars, overall_ink,
8851ab64890Smrg					overall_logical);
8861ab64890Smrg
8871ab64890Smrgerr:
8881ab64890Smrg    FreeLocalBuf(buf);
8891ab64890Smrg
8901ab64890Smrg    return ret;
8911ab64890Smrg}
8921ab64890Smrg
8931ab64890Smrgstatic int
8941ab64890Smrg_XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
8951ab64890Smrg		      _Xconst char *text, int length)
8961ab64890Smrg{
8971ab64890Smrg    XFontStruct *font = *oc->core.font_info.font_struct_list;
8981ab64890Smrg
8991ab64890Smrg    XSetFont(dpy, gc, font->fid);
9001ab64890Smrg    XDrawString(dpy, d, gc, x, y, text, length);
9011ab64890Smrg
9021ab64890Smrg    return XTextWidth(font, text, length);
9031ab64890Smrg}
9041ab64890Smrg
9051ab64890Smrgstatic int
9061ab64890Smrg_XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
9071ab64890Smrg		      _Xconst wchar_t *text, int length)
9081ab64890Smrg{
9091ab64890Smrg    DefineLocalBuf;
9101ab64890Smrg    char *buf = AllocLocalBuf(length);
9111ab64890Smrg    int ret = 0;
9121ab64890Smrg
9131ab64890Smrg    if (buf == NULL)
9141ab64890Smrg	return 0;
9151ab64890Smrg
9161ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
9171ab64890Smrg	goto err;
9181ab64890Smrg
9191ab64890Smrg    ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length);
9201ab64890Smrg
9211ab64890Smrgerr:
9221ab64890Smrg    FreeLocalBuf(buf);
9231ab64890Smrg
9241ab64890Smrg    return ret;
9251ab64890Smrg}
9261ab64890Smrg
9271ab64890Smrgstatic void
9281ab64890Smrg_XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
9291ab64890Smrg			   int y, _Xconst char *text, int length)
9301ab64890Smrg{
9311ab64890Smrg    XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid);
9321ab64890Smrg    XDrawImageString(dpy, d, gc, x, y, text, length);
9331ab64890Smrg}
9341ab64890Smrg
9351ab64890Smrgstatic void
9361ab64890Smrg_XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
9371ab64890Smrg			   int y, _Xconst wchar_t *text, int length)
9381ab64890Smrg{
9391ab64890Smrg    DefineLocalBuf;
9401ab64890Smrg    char *buf = AllocLocalBuf(length);
9411ab64890Smrg
9421ab64890Smrg    if (buf == NULL)
9431ab64890Smrg	return;
9441ab64890Smrg
9451ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
9461ab64890Smrg	goto err;
9471ab64890Smrg
9481ab64890Smrg    _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length);
9491ab64890Smrg
9501ab64890Smrgerr:
9511ab64890Smrg    FreeLocalBuf(buf);
9521ab64890Smrg}
9531ab64890Smrg
9541ab64890Smrgstatic _Xconst XOCMethodsRec oc_default_methods = {
9551ab64890Smrg    destroy_oc,
9561ab64890Smrg    set_oc_values,
9571ab64890Smrg    get_oc_values,
9581ab64890Smrg    _XmbDefaultTextEscapement,
9591ab64890Smrg    _XmbDefaultTextExtents,
9601ab64890Smrg    _XmbDefaultTextPerCharExtents,
9611ab64890Smrg    _XmbDefaultDrawString,
9621ab64890Smrg    _XmbDefaultDrawImageString,
9631ab64890Smrg    _XwcDefaultTextEscapement,
9641ab64890Smrg    _XwcDefaultTextExtents,
9651ab64890Smrg    _XwcDefaultTextPerCharExtents,
9661ab64890Smrg    _XwcDefaultDrawString,
9671ab64890Smrg    _XwcDefaultDrawImageString
9681ab64890Smrg};
9691ab64890Smrg
9701ab64890Smrgstatic XlcResource oc_resources[] = {
9711ab64890Smrg    { XNBaseFontName, NULLQUARK, sizeof(char *),
9721ab64890Smrg      XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask },
9731ab64890Smrg    { XNOMAutomatic, NULLQUARK, sizeof(Bool),
9741ab64890Smrg      XOffsetOf(XOCRec, core.om_automatic), XlcGetMask },
9751ab64890Smrg    { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList),
9761ab64890Smrg      XOffsetOf(XOCRec, core.missing_list), XlcGetMask },
9771ab64890Smrg    { XNDefaultString, NULLQUARK, sizeof(char *),
9781ab64890Smrg      XOffsetOf(XOCRec, core.default_string), XlcGetMask },
9791ab64890Smrg    { XNOrientation, NULLQUARK, sizeof(XOrientation),
9801ab64890Smrg      XOffsetOf(XOCRec, core.orientation), XlcSetMask | XlcGetMask },
9811ab64890Smrg    { XNResourceName, NULLQUARK, sizeof(char *),
9821ab64890Smrg      XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask },
9831ab64890Smrg    { XNResourceClass, NULLQUARK, sizeof(char *),
9841ab64890Smrg      XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask },
9851ab64890Smrg    { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo),
9861ab64890Smrg      XOffsetOf(XOCRec, core.font_info), XlcGetMask }
9871ab64890Smrg};
9881ab64890Smrg
9891ab64890Smrgstatic XOC
9901ab64890Smrgcreate_oc(
9911ab64890Smrg    XOM om,
9921ab64890Smrg    XlcArgList args,
9931ab64890Smrg    int num_args)
9941ab64890Smrg{
9951ab64890Smrg    XOC oc;
9961ab64890Smrg
9971ab64890Smrg    oc = (XOC) Xmalloc(sizeof(XOCGenericRec));
9981ab64890Smrg    if (oc == NULL)
9991ab64890Smrg	return (XOC) NULL;
10001ab64890Smrg    bzero((char *) oc, sizeof(XOCGenericRec));
100161b2299dSmrg
10021ab64890Smrg    oc->core.om = om;
10031ab64890Smrg
10041ab64890Smrg    if (oc_resources[0].xrm_name == NULLQUARK)
10051ab64890Smrg	_XlcCompileResourceList(oc_resources, XlcNumber(oc_resources));
100661b2299dSmrg
10071ab64890Smrg    if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources),
10081ab64890Smrg		      args, num_args, XlcCreateMask | XlcDefaultMask))
10091ab64890Smrg	goto err;
10101ab64890Smrg
10111ab64890Smrg    if (oc->core.base_name_list == NULL)
10121ab64890Smrg	goto err;
10131ab64890Smrg
10141ab64890Smrg    oc->core.resources = oc_resources;
10151ab64890Smrg    oc->core.num_resources = XlcNumber(oc_resources);
10161ab64890Smrg
10171ab64890Smrg    if (create_fontset(oc) == False)
10181ab64890Smrg	goto err;
10191ab64890Smrg
10201ab64890Smrg    oc->methods = (XOCMethods)&oc_default_methods;
10211ab64890Smrg
10221ab64890Smrg    return oc;
10231ab64890Smrg
10241ab64890Smrgerr:
10251ab64890Smrg    destroy_oc(oc);
10261ab64890Smrg
10271ab64890Smrg    return (XOC) NULL;
10281ab64890Smrg}
10291ab64890Smrg
10301ab64890Smrgstatic Status
10311ab64890Smrgclose_om(
10321ab64890Smrg    XOM om)
10331ab64890Smrg{
10341ab64890Smrg    XOMGenericPart *gen = XOM_GENERIC(om);
10351ab64890Smrg    OMData data;
10361ab64890Smrg    FontData font_data;
10371ab64890Smrg    int count;
10381ab64890Smrg
10391ab64890Smrg    if ((data = gen->data)) {
10401ab64890Smrg	if (data->font_data) {
10411ab64890Smrg	  for (font_data = data->font_data, count = data->font_data_count;
104261b2299dSmrg	       count-- > 0 ; font_data++) {
10431ab64890Smrg	    if (font_data->name)
10441ab64890Smrg		Xfree(font_data->name);
10451ab64890Smrg	  }
10461ab64890Smrg	  Xfree(data->font_data);
10471ab64890Smrg	}
10481ab64890Smrg	Xfree(gen->data);
10491ab64890Smrg    }
10501ab64890Smrg
10511ab64890Smrg    if (om->core.res_name)
10521ab64890Smrg	Xfree(om->core.res_name);
10531ab64890Smrg    if (om->core.res_class)
10541ab64890Smrg	Xfree(om->core.res_class);
10551ab64890Smrg    if (om->core.required_charset.charset_list)
10561ab64890Smrg	XFreeStringList(om->core.required_charset.charset_list);
10571ab64890Smrg    else
10581ab64890Smrg	Xfree((char*)om->core.required_charset.charset_list);
10591ab64890Smrg    if (om->core.orientation_list.orientation)
10601ab64890Smrg	Xfree(om->core.orientation_list.orientation);
10611ab64890Smrg
10621ab64890Smrg    Xfree(om);
10631ab64890Smrg
10641ab64890Smrg    return 1;
10651ab64890Smrg}
10661ab64890Smrg
10671ab64890Smrgstatic char *
10681ab64890Smrgset_om_values(
10691ab64890Smrg    XOM om,
10701ab64890Smrg    XlcArgList args,
10711ab64890Smrg    int num_args)
10721ab64890Smrg{
10731ab64890Smrg    if (om->core.resources == NULL)
10741ab64890Smrg	return NULL;
10751ab64890Smrg
10761ab64890Smrg    return _XlcSetValues((XPointer) om, om->core.resources,
10771ab64890Smrg			 om->core.num_resources, args, num_args, XlcSetMask);
10781ab64890Smrg}
10791ab64890Smrg
10801ab64890Smrgstatic char *
10811ab64890Smrgget_om_values(
10821ab64890Smrg    XOM om,
10831ab64890Smrg    XlcArgList args,
10841ab64890Smrg    int num_args)
10851ab64890Smrg{
10861ab64890Smrg    if (om->core.resources == NULL)
10871ab64890Smrg	return NULL;
10881ab64890Smrg
10891ab64890Smrg    return _XlcGetValues((XPointer) om, om->core.resources,
10901ab64890Smrg			 om->core.num_resources, args, num_args, XlcGetMask);
10911ab64890Smrg}
10921ab64890Smrg
10931ab64890Smrgstatic _Xconst XOMMethodsRec methods = {
10941ab64890Smrg    close_om,
10951ab64890Smrg    set_om_values,
10961ab64890Smrg    get_om_values,
10971ab64890Smrg    create_oc
10981ab64890Smrg};
10991ab64890Smrg
11001ab64890Smrgstatic XlcResource om_resources[] = {
11011ab64890Smrg    { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList),
11021ab64890Smrg      XOffsetOf(XOMRec, core.required_charset), XlcGetMask },
11031ab64890Smrg    { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation),
11041ab64890Smrg      XOffsetOf(XOMRec, core.orientation_list), XlcGetMask },
11051ab64890Smrg    { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool),
11061ab64890Smrg      XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask },
11071ab64890Smrg    { XNContextualDrawing, NULLQUARK, sizeof(Bool),
11081ab64890Smrg      XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask }
11091ab64890Smrg};
11101ab64890Smrg
11111ab64890Smrgstatic OMData
11121ab64890Smrgadd_data(
11131ab64890Smrg    XOM om)
11141ab64890Smrg{
11151ab64890Smrg    XOMGenericPart *gen = XOM_GENERIC(om);
11161ab64890Smrg    OMData new;
11171ab64890Smrg
11181ab64890Smrg    new = (OMData) Xmalloc(sizeof(OMDataRec));
11191ab64890Smrg
11201ab64890Smrg    if (new == NULL)
11211ab64890Smrg        return NULL;
11221ab64890Smrg
11231ab64890Smrg    gen->data = new;
11241ab64890Smrg
11251ab64890Smrg    bzero((char *) new, sizeof(OMDataRec));
11261ab64890Smrg
11271ab64890Smrg    return new;
11281ab64890Smrg}
11291ab64890Smrg
11301ab64890Smrgstatic _Xconst char *supported_charset_list[] = {
11311ab64890Smrg    "ISO8859-1",
11321ab64890Smrg/* fix for bug4332979 */
11331ab64890Smrg    "adobe-fontspecific",
11341ab64890Smrg/* fix for bug4237353: "JISX0201.1976-0" entry should be removed from
11351ab64890Smrg   supported_charset_list because it is not a supported_charset for C locale
11361ab64890Smrg    "JISX0201.1976-0", */
11371ab64890Smrg    "SUNOLCURSOR-1",
11381ab64890Smrg    "SUNOLGLYPH-1"
11391ab64890Smrg};
114061b2299dSmrg
11411ab64890Smrgstatic Bool
11421ab64890Smrginit_om(
11431ab64890Smrg    XOM om)
11441ab64890Smrg{
11451ab64890Smrg    XOMGenericPart *gen = XOM_GENERIC(om);
11461ab64890Smrg    OMData data;
11471ab64890Smrg    FontData font_data;
11481ab64890Smrg    char **required_list;
11491ab64890Smrg    XOrientation *orientation;
11501ab64890Smrg    char **value, buf[BUFSIZ], *bufptr;
11511ab64890Smrg    int count, length = 0;
11521ab64890Smrg
11531ab64890Smrg    value = (char**)supported_charset_list;
11541ab64890Smrg    count = XlcNumber(supported_charset_list);
11551ab64890Smrg
11561ab64890Smrg    data = add_data(om);
11571ab64890Smrg    if (data == NULL)
11581ab64890Smrg	return False;
11591ab64890Smrg
11601ab64890Smrg    font_data = (FontData) Xmalloc(sizeof(FontDataRec) * count);
11611ab64890Smrg    if (font_data == NULL)
11621ab64890Smrg	return False;
11631ab64890Smrg    bzero((char *) font_data, sizeof(FontDataRec) * count);
11641ab64890Smrg    data->font_data = font_data;
11651ab64890Smrg    data->font_data_count = count;
11661ab64890Smrg
11671ab64890Smrg    for ( ; count-- > 0; font_data++) {
11681ab64890Smrg/*
11691ab64890Smrg1266793
11701ab64890SmrgThis one is fine.  *value points to one of the local strings in
11711ab64890Smrgsupported_charset_list[].
11721ab64890Smrg*/
11731ab64890Smrg	strcpy(buf, *value++);
11741ab64890Smrg	font_data->name = (char *) Xmalloc(strlen(buf) + 1);
11751ab64890Smrg	if (font_data->name == NULL)
11761ab64890Smrg	    return False;
11771ab64890Smrg	strcpy(font_data->name, buf);
11781ab64890Smrg    }
11791ab64890Smrg
11801ab64890Smrg    length += strlen(data->font_data->name) + 1;
11811ab64890Smrg
11821ab64890Smrg    /* required charset list */
11831ab64890Smrg    required_list = (char **) Xmalloc(sizeof(char *));
11841ab64890Smrg    if (required_list == NULL)
11851ab64890Smrg	return False;
11861ab64890Smrg
11871ab64890Smrg    bufptr = (char *) Xmalloc(length);
11881ab64890Smrg    if (bufptr == NULL) {
11891ab64890Smrg	Xfree(required_list);
11901ab64890Smrg	return False;
11911ab64890Smrg    }
11921ab64890Smrg
11931ab64890Smrg    om->core.required_charset.charset_list = required_list;
11941ab64890Smrg    om->core.required_charset.charset_count = 1; /* always 1 */
11951ab64890Smrg
11961ab64890Smrg    data = gen->data;
11971ab64890Smrg
11981ab64890Smrg    strcpy(bufptr, data->font_data->name);
11991ab64890Smrg    *required_list++ = bufptr;
12001ab64890Smrg    bufptr += strlen(bufptr) + 1;
12011ab64890Smrg
12021ab64890Smrg    /* orientation list */
12031ab64890Smrg    orientation = (XOrientation *) Xmalloc(sizeof(XOrientation));
12041ab64890Smrg    if (orientation == NULL)
12051ab64890Smrg	return False;
12061ab64890Smrg
12071ab64890Smrg    *orientation = XOMOrientation_LTR_TTB;
12081ab64890Smrg    om->core.orientation_list.orientation = orientation;
12091ab64890Smrg    om->core.orientation_list.num_orientation = 1;
12101ab64890Smrg
12111ab64890Smrg    /* directional dependent drawing */
12121ab64890Smrg    om->core.directional_dependent = False;
12131ab64890Smrg
12141ab64890Smrg    /* contexual drawing */
12151ab64890Smrg    om->core.contextual_drawing = False;
12161ab64890Smrg
12171ab64890Smrg    /* context dependent */
12181ab64890Smrg    om->core.context_dependent = False;
12191ab64890Smrg
12201ab64890Smrg    return True;
12211ab64890Smrg}
12221ab64890Smrg
12231ab64890SmrgXOM
12241ab64890Smrg_XDefaultOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb,
12251ab64890Smrg		_Xconst char *res_name, _Xconst char *res_class)
12261ab64890Smrg{
12271ab64890Smrg    XOM om;
12281ab64890Smrg
12291ab64890Smrg    om = (XOM) Xmalloc(sizeof(XOMGenericRec));
12301ab64890Smrg    if (om == NULL)
12311ab64890Smrg	return (XOM) NULL;
12321ab64890Smrg    bzero((char *) om, sizeof(XOMGenericRec));
123361b2299dSmrg
12341ab64890Smrg    om->methods = (XOMMethods)&methods;
12351ab64890Smrg    om->core.lcd = lcd;
12361ab64890Smrg    om->core.display = dpy;
12371ab64890Smrg    om->core.rdb = rdb;
12381ab64890Smrg    if (res_name) {
12391ab64890Smrg	om->core.res_name = (char *)Xmalloc(strlen(res_name) + 1);
12401ab64890Smrg	if (om->core.res_name == NULL)
12411ab64890Smrg	    goto err;
12421ab64890Smrg	strcpy(om->core.res_name, res_name);
12431ab64890Smrg    }
12441ab64890Smrg    if (res_class) {
12451ab64890Smrg	om->core.res_class = (char *)Xmalloc(strlen(res_class) + 1);
12461ab64890Smrg	if (om->core.res_class == NULL)
12471ab64890Smrg	    goto err;
12481ab64890Smrg	strcpy(om->core.res_class, res_class);
12491ab64890Smrg    }
12501ab64890Smrg
12511ab64890Smrg    if (om_resources[0].xrm_name == NULLQUARK)
12521ab64890Smrg	_XlcCompileResourceList(om_resources, XlcNumber(om_resources));
125361b2299dSmrg
12541ab64890Smrg    om->core.resources = om_resources;
12551ab64890Smrg    om->core.num_resources = XlcNumber(om_resources);
12561ab64890Smrg
12571ab64890Smrg    if (init_om(om) == False)
12581ab64890Smrg	goto err;
12591ab64890Smrg
12601ab64890Smrg    return om;
12611ab64890Smrgerr:
12621ab64890Smrg    close_om(om);
12631ab64890Smrg
12641ab64890Smrg    return (XOM) NULL;
12651ab64890Smrg}
1266