XDefaultOMIF.c revision 818534a1
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/*
40e9fcaa8aSmrg * Copyright 2000 Oracle and/or its affiliates. All rights reserved.
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
1671ab64890Smrg    name_len = 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++) {
1741ab64890Smrg	length = 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
1851ab64890Smrg#if 0 /* Unused */
1861ab64890Smrgstatic int
1871ab64890Smrgcheck_fontname(
1881ab64890Smrg    XOC oc,
1891ab64890Smrg    char *name)
1901ab64890Smrg{
1911ab64890Smrg    Display *dpy = oc->core.om->core.display;
1921ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
1931ab64890Smrg    FontData data;
1941ab64890Smrg    FontSet font_set;
1951ab64890Smrg    XFontStruct *fs_list;
1961ab64890Smrg    char **fn_list, *fname, *prop_fname = NULL;
1971ab64890Smrg    int list_num, i;
1981ab64890Smrg    int list2_num;
1991ab64890Smrg    char **fn2_list = NULL;
2001ab64890Smrg    int found_num = 0;
2011ab64890Smrg
2021ab64890Smrg    fn_list = XListFonts(dpy, name, MAXFONTS, &list_num);
2031ab64890Smrg    if (fn_list == NULL)
2041ab64890Smrg	return found_num;
2051ab64890Smrg
2061ab64890Smrg    for (i = 0; i < list_num; i++) {
2071ab64890Smrg	fname = fn_list[i];
2081ab64890Smrg
2091ab64890Smrg	font_set = gen->font_set;
2101ab64890Smrg
2111ab64890Smrg	if ((data = check_charset(font_set, fname)) == NULL) {
2121ab64890Smrg	    if ((fn2_list = XListFontsWithInfo(dpy, name, MAXFONTS,
2131ab64890Smrg					       &list2_num, &fs_list))
2141ab64890Smrg		&& (prop_fname = get_prop_name(dpy, fs_list))
2151ab64890Smrg		&& (data = check_charset(font_set, prop_fname)))
2161ab64890Smrg		fname = prop_fname;
2171ab64890Smrg	}
2181ab64890Smrg	if (data) {
2196cc2b21fSmrg	    font_set->font_name = strdup(fname);
2201ab64890Smrg	    if (font_set->font_name) {
2211ab64890Smrg		found_num++;
2221ab64890Smrg	    }
2231ab64890Smrg	}
2241ab64890Smrg	if (fn2_list) {
2251ab64890Smrg	    XFreeFontInfo(fn2_list, fs_list, list2_num);
2261ab64890Smrg	    fn2_list = NULL;
2271ab64890Smrg	    if (prop_fname) {
2281ab64890Smrg		Xfree(prop_fname);
2291ab64890Smrg		prop_fname = NULL;
2301ab64890Smrg	    }
2311ab64890Smrg	}
2321ab64890Smrg	if (found_num == 1)
2331ab64890Smrg	    break;
2341ab64890Smrg    }
2351ab64890Smrg    XFreeFontNames(fn_list);
2361ab64890Smrg    return found_num;
2371ab64890Smrg}
2381ab64890Smrg#endif
2391ab64890Smrg
2401ab64890Smrgstatic Bool
2411ab64890Smrgload_font(
2421ab64890Smrg    XOC oc)
2431ab64890Smrg{
2441ab64890Smrg    Display *dpy = oc->core.om->core.display;
2451ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
2461ab64890Smrg    FontSet font_set = gen->font_set;
2471ab64890Smrg
2481ab64890Smrg    if (font_set->font_name == NULL)
2491ab64890Smrg	return False;
2501ab64890Smrg
2511ab64890Smrg    if (font_set->font == NULL) {
2521ab64890Smrg	font_set->font = XLoadQueryFont(dpy, font_set->font_name);
2531ab64890Smrg	if (font_set->font == NULL)
2541ab64890Smrg	    return False;
2551ab64890Smrg    }
2561ab64890Smrg    return True;
2571ab64890Smrg}
2581ab64890Smrg
2591ab64890Smrg#if 0
2601ab64890Smrgstatic Bool
2611ab64890Smrgload_font_info(
2621ab64890Smrg    XOC oc)
2631ab64890Smrg{
2641ab64890Smrg    Display *dpy = oc->core.om->core.display;
2651ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
2661ab64890Smrg    FontSet font_set = gen->font_set;
2671ab64890Smrg    char **fn_list;
2681ab64890Smrg    int fn_num;
2691ab64890Smrg
2701ab64890Smrg    if (font_set->font_name == NULL)
2711ab64890Smrg	return False;
2721ab64890Smrg
2731ab64890Smrg    if (font_set->info == NULL) {
2741ab64890Smrg	fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num,
2751ab64890Smrg				     &font_set->info);
2761ab64890Smrg	if (font_set->info == NULL)
2771ab64890Smrg	    return False;
2781ab64890Smrg	if (fn_num > 0)
2791ab64890Smrg	    font_set->info->fid = XLoadFont(dpy, font_set->font_name);
28061b2299dSmrg
2811ab64890Smrg	if (fn_list) XFreeFontNames(fn_list);
2821ab64890Smrg    }
2831ab64890Smrg    return True;
2841ab64890Smrg}
2851ab64890Smrg#endif
2861ab64890Smrg
2871ab64890Smrgstatic void
2881ab64890Smrgset_fontset_extents(
2891ab64890Smrg    XOC oc)
2901ab64890Smrg{
2911ab64890Smrg    XRectangle *ink = &oc->core.font_set_extents.max_ink_extent;
2921ab64890Smrg    XRectangle *logical = &oc->core.font_set_extents.max_logical_extent;
2931ab64890Smrg    XFontStruct **font_list, *font;
2941ab64890Smrg    XCharStruct overall;
2951ab64890Smrg    int logical_ascent, logical_descent;
2961ab64890Smrg
2971ab64890Smrg    font_list = oc->core.font_info.font_struct_list;
2981ab64890Smrg    font = *font_list++;
2991ab64890Smrg    overall = font->max_bounds;
3001ab64890Smrg    overall.lbearing = font->min_bounds.lbearing;
3011ab64890Smrg    logical_ascent = font->ascent;
3021ab64890Smrg    logical_descent = font->descent;
3031ab64890Smrg
3041ab64890Smrg    ink->x = overall.lbearing;
3051ab64890Smrg    ink->y = -(overall.ascent);
3061ab64890Smrg    ink->width = overall.rbearing - overall.lbearing;
3071ab64890Smrg    ink->height = overall.ascent + overall.descent;
3081ab64890Smrg
3091ab64890Smrg    logical->x = 0;
3101ab64890Smrg    logical->y = -(logical_ascent);
3111ab64890Smrg    logical->width = overall.width;
3121ab64890Smrg    logical->height = logical_ascent + logical_descent;
3131ab64890Smrg}
3141ab64890Smrg
3151ab64890Smrgstatic Bool
3161ab64890Smrginit_core_part(
3171ab64890Smrg    XOC oc)
3181ab64890Smrg{
3191ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
3201ab64890Smrg    FontSet font_set;
3211ab64890Smrg    XFontStruct **font_struct_list;
3221ab64890Smrg    char **font_name_list, *font_name_buf;
3231ab64890Smrg    int	count, length;
3241ab64890Smrg
3251ab64890Smrg    font_set = gen->font_set;
3261ab64890Smrg    count = length = 0;
3271ab64890Smrg
3281ab64890Smrg    if (font_set->font_name != NULL) {
3291ab64890Smrg	length += strlen(font_set->font_name) + 1;
3301ab64890Smrg	count++;
3311ab64890Smrg    }
3321ab64890Smrg    if (count == 0)
3331ab64890Smrg        return False;
3341ab64890Smrg
335818534a1Smrg    font_struct_list = Xmalloc(sizeof(XFontStruct *));
3361ab64890Smrg    if (font_struct_list == NULL)
3371ab64890Smrg	return False;
3381ab64890Smrg
339818534a1Smrg    font_name_list = Xmalloc(sizeof(char *));
3401ab64890Smrg    if (font_name_list == NULL)
3411ab64890Smrg	goto err;
3421ab64890Smrg
343818534a1Smrg    font_name_buf = Xmalloc(length);
3441ab64890Smrg    if (font_name_buf == NULL)
3451ab64890Smrg	goto err;
3461ab64890Smrg
3471ab64890Smrg    oc->core.font_info.num_font = 1;
3481ab64890Smrg    oc->core.font_info.font_name_list = font_name_list;
3491ab64890Smrg    oc->core.font_info.font_struct_list = font_struct_list;
3501ab64890Smrg
3511ab64890Smrg    font_set = gen->font_set;
3521ab64890Smrg
3531ab64890Smrg    if (font_set->font_name != NULL) {
3541ab64890Smrg	font_set->id = 1;
3551ab64890Smrg	if (font_set->font)
3561ab64890Smrg	    *font_struct_list++ = font_set->font;
3571ab64890Smrg	else
3581ab64890Smrg	    *font_struct_list++ = font_set->info;
3591ab64890Smrg	strcpy(font_name_buf, font_set->font_name);
3601ab64890Smrg	Xfree(font_set->font_name);
3611ab64890Smrg	*font_name_list++ = font_set->font_name = font_name_buf;
3621ab64890Smrg	font_name_buf += strlen(font_name_buf) + 1;
3631ab64890Smrg    }
3641ab64890Smrg
3651ab64890Smrg    set_fontset_extents(oc);
3661ab64890Smrg
3671ab64890Smrg    return True;
3681ab64890Smrg
3691ab64890Smrgerr:
3701ab64890Smrg    if (font_name_list)
3711ab64890Smrg	Xfree(font_name_list);
3721ab64890Smrg    Xfree(font_struct_list);
3731ab64890Smrg
3741ab64890Smrg    return False;
3751ab64890Smrg}
3761ab64890Smrg
3771ab64890Smrgstatic char *
3781ab64890Smrgget_font_name(
3791ab64890Smrg    XOC oc,
3801ab64890Smrg    char *pattern)
3811ab64890Smrg{
38257f47464Smrg    char **list, *name;
3831ab64890Smrg    int count;
3841ab64890Smrg    XFontStruct *fs;
3851ab64890Smrg    Display *dpy = oc->core.om->core.display;
3861ab64890Smrg
3871ab64890Smrg    list = XListFonts(dpy, pattern, 1, &count);
3881ab64890Smrg    if (list != NULL) {
3896cc2b21fSmrg	name = strdup(*list);
39061b2299dSmrg
3911ab64890Smrg	XFreeFontNames(list);
3921ab64890Smrg    } else {
3931ab64890Smrg	fs = XLoadQueryFont(dpy, pattern);
3941ab64890Smrg	if (fs == NULL) return NULL;
3951ab64890Smrg
39657f47464Smrg	name = get_prop_name(dpy, fs);
3971ab64890Smrg	XFreeFont(dpy, fs);
3981ab64890Smrg    }
3991ab64890Smrg    return name;
4001ab64890Smrg}
4011ab64890Smrg
4021ab64890Smrgstatic int
4031ab64890Smrgparse_fontname(
4041ab64890Smrg    XOC oc)
4051ab64890Smrg{
4061ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
4071ab64890Smrg    FontSet font_set;
4081ab64890Smrg    FontData font_data;
4091ab64890Smrg    char *pattern, *last, buf[BUFSIZ];
4101ab64890Smrg    int font_data_count, found_num = 0;
4111ab64890Smrg    ssize_t length;
4121ab64890Smrg    int count, num_fields;
4131ab64890Smrg    char *base_name, *font_name, **name_list, **cur_name_list;
4141ab64890Smrg    char *charset_p = NULL;
4151ab64890Smrg    Bool append_charset;
4161ab64890Smrg    /*
4171ab64890Smrg       append_charset flag should be set to True when the XLFD fontname
4181ab64890Smrg       doesn't contain a chaset part.
4191ab64890Smrg     */
4201ab64890Smrg
4211ab64890Smrg    name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count);
4221ab64890Smrg    if (name_list == NULL)
4231ab64890Smrg	return -1;
4241ab64890Smrg    cur_name_list = name_list;
4251ab64890Smrg
4261ab64890Smrg    while (count-- > 0) {
4271ab64890Smrg        pattern = *cur_name_list++;
4281ab64890Smrg	if (pattern == NULL || *pattern == '\0')
4291ab64890Smrg	    continue;
4301ab64890Smrg
4311ab64890Smrg	append_charset = False;
4321ab64890Smrg
4331ab64890Smrg	if (strchr(pattern, '*') == NULL &&
4341ab64890Smrg	    (font_name = get_font_name(oc, pattern))) {
4351ab64890Smrg
4361ab64890Smrg	    font_set = gen->font_set;
4371ab64890Smrg
4381ab64890Smrg	    font_data = check_charset(font_set, font_name);
4391ab64890Smrg	    if (font_data == NULL) {
4401ab64890Smrg		Display *dpy = oc->core.om->core.display;
4411ab64890Smrg		char **fn_list = NULL, *prop_fname = NULL;
4421ab64890Smrg		int list_num;
4431ab64890Smrg		XFontStruct *fs_list;
4441ab64890Smrg		if ((fn_list = XListFontsWithInfo(dpy, font_name,
4451ab64890Smrg						  MAXFONTS,
4461ab64890Smrg						  &list_num, &fs_list))
4471ab64890Smrg		    && (prop_fname = get_prop_name(dpy, fs_list))
4481ab64890Smrg		    && (font_data = check_charset(font_set, prop_fname))) {
4491ab64890Smrg		    if (fn_list) {
4501ab64890Smrg			XFreeFontInfo(fn_list, fs_list, list_num);
4511ab64890Smrg			fn_list = NULL;
4521ab64890Smrg		    }
4531ab64890Smrg		    font_name = prop_fname;
4541ab64890Smrg		}
4551ab64890Smrg	    }
4561ab64890Smrg	    if (font_data == NULL)
4571ab64890Smrg		continue;
4581ab64890Smrg
4596cc2b21fSmrg	    font_set->font_name = strdup(font_name);
4606cc2b21fSmrg	    Xfree(font_name);
4611ab64890Smrg	    if (font_set->font_name == NULL) {
4621ab64890Smrg		goto err;
4631ab64890Smrg	    }
4641ab64890Smrg	    found_num++;
4651ab64890Smrg	    goto found;
4661ab64890Smrg	}
4671ab64890Smrg/*
4681ab64890Smrg1266793
4691ab64890SmrgLimit the length of the string copy to prevent stack corruption.
4701ab64890Smrg	strcpy(buf, pattern);
4711ab64890Smrg*/
4721ab64890Smrg	strncpy(buf, pattern, BUFSIZ);
4731ab64890Smrg	buf[BUFSIZ-1] = '\0';
4741ab64890Smrg	length = strlen(buf);
4751ab64890Smrg	last = buf + length - 1;
4761ab64890Smrg
4771ab64890Smrg	for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++)
4781ab64890Smrg	    if (*base_name == '-') num_fields++;
4791ab64890Smrg	if (strchr(pattern, '*') == NULL) {
4801ab64890Smrg	    if (num_fields == 12) {
4811ab64890Smrg		append_charset = True;
4821ab64890Smrg		*++last = '-';
4831ab64890Smrg		last++;
4841ab64890Smrg	    } else
4851ab64890Smrg		continue;
4861ab64890Smrg	} else {
4871ab64890Smrg	    if (num_fields == 13 || num_fields == 14) {
48861b2299dSmrg	    /*
4891ab64890Smrg	     * There are 14 fields in an XLFD name -- make certain the
4901ab64890Smrg	     * charset (& encoding) is placed in the correct field.
4911ab64890Smrg	     */
4921ab64890Smrg		append_charset = True;
4931ab64890Smrg		last = strrchr (buf, '-');
4941ab64890Smrg		if (num_fields == 14) {
4951ab64890Smrg		    *last = '\0';
4961ab64890Smrg		    last = strrchr (buf, '-');
4971ab64890Smrg		}
4981ab64890Smrg		last++;
4991ab64890Smrg	    } else if (*last == '*') {
5001ab64890Smrg		append_charset = True;
5011ab64890Smrg		if (length > 3 && *(last-3) == '-' && *(last-2) == '*'
5021ab64890Smrg		    && *(last-1) == '-') {
5031ab64890Smrg		    last -= 2;
5041ab64890Smrg		}
5051ab64890Smrg		*++last = '-';
5061ab64890Smrg		last++;
5071ab64890Smrg	    } else {
5081ab64890Smrg		last = strrchr (buf, '-');
5091ab64890Smrg		charset_p = last;
5101ab64890Smrg		charset_p = strrchr (buf, '-');
5111ab64890Smrg		while (*(--charset_p) != '-');
5121ab64890Smrg		charset_p++;
5131ab64890Smrg	    }
5141ab64890Smrg	}
5151ab64890Smrg
5161ab64890Smrg	font_set = gen->font_set;
5171ab64890Smrg
5181ab64890Smrg	font_data = font_set->font_data;
5191ab64890Smrg	font_data_count = font_set->font_data_count;
5201ab64890Smrg	for ( ; font_data_count-- > 0; font_data++) {
5211ab64890Smrg	    if (append_charset)
5221ab64890Smrg		{
5231ab64890Smrg/*
5241ab64890Smrg1266793
5251ab64890SmrgLimit the length of the string copy to prevent stack corruption.
5261ab64890Smrg		strcpy(last, font_data->name);
5271ab64890Smrg*/
5281ab64890Smrg		strncpy(last, font_data->name, BUFSIZ - length);
5291ab64890Smrg		buf[BUFSIZ-1] = '\0';
5301ab64890Smrg		}
5311ab64890Smrg	    else {
5321ab64890Smrg		if (_XlcCompareISOLatin1(charset_p,
5331ab64890Smrg					 font_data->name)) {
5341ab64890Smrg		    continue;
5351ab64890Smrg		}
5361ab64890Smrg	    }
5371ab64890Smrg	    if ((font_set->font_name = get_font_name(oc, buf)))
5381ab64890Smrg		break;
5391ab64890Smrg	}
5401ab64890Smrg	if (font_set->font_name != NULL) {
5411ab64890Smrg	    found_num++;
5421ab64890Smrg	    goto found;
5431ab64890Smrg	}
5441ab64890Smrg    }
5451ab64890Smrg  found:
5466cc2b21fSmrg    base_name = strdup(oc->core.base_name_list);
5471ab64890Smrg    if (base_name == NULL)
5481ab64890Smrg	goto err;
5491ab64890Smrg
5501ab64890Smrg    oc->core.base_name_list = base_name;
5511ab64890Smrg
55261b2299dSmrg    XFreeStringList(name_list);
5531ab64890Smrg
5541ab64890Smrg    return found_num;
5551ab64890Smrgerr:
55661b2299dSmrg    XFreeStringList(name_list);
5571ab64890Smrg
5581ab64890Smrg    return -1;
5591ab64890Smrg}
5601ab64890Smrg
5611ab64890Smrgstatic Bool
5621ab64890Smrgset_missing_list(
5631ab64890Smrg    XOC oc)
5641ab64890Smrg{
5651ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
5661ab64890Smrg    FontSet font_set;
5671ab64890Smrg    char **charset_list, *charset_buf;
5681ab64890Smrg    int	count, length;
5691ab64890Smrg
5701ab64890Smrg    font_set = gen->font_set;
5711ab64890Smrg    count = length = 0;
5721ab64890Smrg
5731ab64890Smrg    if (!font_set->info && !font_set->font) {
5741ab64890Smrg	length += strlen(font_set->font_data->name) + 1;
5751ab64890Smrg	count++;
5761ab64890Smrg    }
5771ab64890Smrg
5781ab64890Smrg    if (count == 0)
5791ab64890Smrg	return True;
5801ab64890Smrg
581818534a1Smrg    charset_list = Xmalloc(sizeof(char *));
5821ab64890Smrg    if (charset_list == NULL)
5831ab64890Smrg	return False;
5841ab64890Smrg
585818534a1Smrg    charset_buf = Xmalloc(length);
5861ab64890Smrg    if (charset_buf == NULL) {
5871ab64890Smrg	Xfree(charset_list);
5881ab64890Smrg	return False;
5891ab64890Smrg    }
5901ab64890Smrg
5911ab64890Smrg    oc->core.missing_list.charset_list = charset_list;
5921ab64890Smrg
5931ab64890Smrg    font_set = gen->font_set;
5941ab64890Smrg
5951ab64890Smrg    if (!font_set->info && !font_set->font) {
5961ab64890Smrg	strcpy(charset_buf, font_set->font_data->name);
5971ab64890Smrg	*charset_list++ = charset_buf;
5981ab64890Smrg	charset_buf += strlen(charset_buf) + 1;
5991ab64890Smrg    }
6001ab64890Smrg    return True;
6011ab64890Smrg}
6021ab64890Smrg
6031ab64890Smrgstatic Bool
6041ab64890Smrgcreate_fontset(
6051ab64890Smrg    XOC oc)
6061ab64890Smrg{
6071ab64890Smrg    int found_num;
6081ab64890Smrg
6091ab64890Smrg    if (init_fontset(oc) == False)
6101ab64890Smrg        return False;
6111ab64890Smrg
6121ab64890Smrg    found_num = parse_fontname(oc);
6131ab64890Smrg    if (found_num <= 0) {
6141ab64890Smrg	if (found_num == 0)
6151ab64890Smrg	    set_missing_list(oc);
6161ab64890Smrg	return False;
6171ab64890Smrg    }
6181ab64890Smrg
6191ab64890Smrg    if (load_font(oc) == False)
6201ab64890Smrg	return False;
6211ab64890Smrg
6221ab64890Smrg    if (init_core_part(oc) == False)
6231ab64890Smrg	return False;
6241ab64890Smrg
6251ab64890Smrg    if (set_missing_list(oc) == False)
6261ab64890Smrg	return False;
6271ab64890Smrg
6281ab64890Smrg    return True;
6291ab64890Smrg}
6301ab64890Smrg
6311ab64890Smrgstatic void
6321ab64890Smrgdestroy_oc(
6331ab64890Smrg    XOC oc)
6341ab64890Smrg{
6351ab64890Smrg    Display *dpy = oc->core.om->core.display;
6361ab64890Smrg    XOCGenericPart *gen = XOC_GENERIC(oc);
6371ab64890Smrg    XFontStruct **font_list, *font;
6381ab64890Smrg
6391ab64890Smrg    if (gen->font_set)
6401ab64890Smrg	Xfree(gen->font_set);
6411ab64890Smrg
6421ab64890Smrg    if (oc->core.base_name_list)
6431ab64890Smrg	Xfree(oc->core.base_name_list);
6441ab64890Smrg
6451ab64890Smrg    if (oc->core.font_info.font_name_list)
6461ab64890Smrg	XFreeStringList(oc->core.font_info.font_name_list);
6471ab64890Smrg
6481ab64890Smrg    if ((font_list = oc->core.font_info.font_struct_list)) {
6491ab64890Smrg	if ((font = *font_list)) {
6501ab64890Smrg	    if (font->fid)
6511ab64890Smrg		XFreeFont(dpy, font);
6521ab64890Smrg	    else
6531ab64890Smrg		XFreeFontInfo(NULL, font, 1);
6541ab64890Smrg	}
6551ab64890Smrg	Xfree(oc->core.font_info.font_struct_list);
6561ab64890Smrg    }
6571ab64890Smrg
6581ab64890Smrg    if (oc->core.missing_list.charset_list)
6591ab64890Smrg	XFreeStringList(oc->core.missing_list.charset_list);
6601ab64890Smrg
6611ab64890Smrg#ifdef notdef
6621ab64890Smrg    if (oc->core.res_name)
6631ab64890Smrg	Xfree(oc->core.res_name);
6641ab64890Smrg    if (oc->core.res_class)
6651ab64890Smrg	Xfree(oc->core.res_class);
6661ab64890Smrg#endif
66761b2299dSmrg
6681ab64890Smrg    Xfree(oc);
6691ab64890Smrg}
6701ab64890Smrg
6711ab64890Smrgstatic char *
6721ab64890Smrgset_oc_values(
6731ab64890Smrg    XOC oc,
6741ab64890Smrg    XlcArgList args,
6751ab64890Smrg    int num_args)
6761ab64890Smrg{
6771ab64890Smrg    if (oc->core.resources == NULL)
6781ab64890Smrg	return NULL;
6791ab64890Smrg
6801ab64890Smrg    return _XlcSetValues((XPointer) oc, oc->core.resources,
6811ab64890Smrg			 oc->core.num_resources, args, num_args, XlcSetMask);
6821ab64890Smrg}
6831ab64890Smrg
6841ab64890Smrgstatic char *
6851ab64890Smrgget_oc_values(
6861ab64890Smrg    XOC oc,
6871ab64890Smrg    XlcArgList args,
6881ab64890Smrg    int num_args)
6891ab64890Smrg{
6901ab64890Smrg    if (oc->core.resources == NULL)
6911ab64890Smrg	return NULL;
6921ab64890Smrg
6931ab64890Smrg    return _XlcGetValues((XPointer) oc, oc->core.resources,
6941ab64890Smrg			 oc->core.num_resources, args, num_args, XlcGetMask);
6951ab64890Smrg}
6961ab64890Smrg
6971ab64890Smrgstatic Bool
6981ab64890Smrgwcs_to_mbs(
6991ab64890Smrg    XOC oc,
7001ab64890Smrg    char *to,
7011ab64890Smrg    _Xconst wchar_t *from,
7021ab64890Smrg    int length)
7031ab64890Smrg{
7041ab64890Smrg    XlcConv conv = XOC_GENERIC(oc)->wcs_to_cs;
7051ab64890Smrg    XLCd lcd;
7061ab64890Smrg    int ret, to_left = length;
7071ab64890Smrg
7081ab64890Smrg    if (conv == NULL) {
7091ab64890Smrg	lcd = oc->core.om->core.lcd;
7101ab64890Smrg	conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte);
7111ab64890Smrg	if (conv == NULL)
7121ab64890Smrg	    return False;
7131ab64890Smrg	XOC_GENERIC(oc)->wcs_to_cs = conv;
7141ab64890Smrg    } else
7151ab64890Smrg	_XlcResetConverter(conv);
7161ab64890Smrg
7171ab64890Smrg    ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to,
7181ab64890Smrg		      &to_left, NULL, 0);
7191ab64890Smrg    if (ret != 0 || length > 0)
7201ab64890Smrg	return False;
72161b2299dSmrg
7221ab64890Smrg    return True;
7231ab64890Smrg}
7241ab64890Smrg
7251ab64890Smrgstatic int
7261ab64890Smrg_XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length)
7271ab64890Smrg{
7281ab64890Smrg    return XTextWidth(*oc->core.font_info.font_struct_list, text, length);
7291ab64890Smrg}
7301ab64890Smrg
7311ab64890Smrgstatic int
7321ab64890Smrg_XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length)
7331ab64890Smrg{
7341ab64890Smrg    DefineLocalBuf;
7351ab64890Smrg    char *buf = AllocLocalBuf(length);
7361ab64890Smrg    int ret = 0;
7371ab64890Smrg
7381ab64890Smrg    if (buf == NULL)
7391ab64890Smrg	return 0;
7401ab64890Smrg
7411ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
7421ab64890Smrg	goto err;
7431ab64890Smrg
7441ab64890Smrg    ret = _XmbDefaultTextEscapement(oc, buf, length);
7451ab64890Smrg
7461ab64890Smrgerr:
7471ab64890Smrg    FreeLocalBuf(buf);
7481ab64890Smrg
7491ab64890Smrg    return ret;
7501ab64890Smrg}
7511ab64890Smrg
7521ab64890Smrgstatic int
7531ab64890Smrg_XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length,
7541ab64890Smrg		       XRectangle *overall_ink, XRectangle *overall_logical)
7551ab64890Smrg{
7561ab64890Smrg    int direction, logical_ascent, logical_descent;
7571ab64890Smrg    XCharStruct overall;
7581ab64890Smrg
7591ab64890Smrg    XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction,
7601ab64890Smrg		 &logical_ascent, &logical_descent, &overall);
7611ab64890Smrg
7621ab64890Smrg    if (overall_ink) {
7631ab64890Smrg	overall_ink->x = overall.lbearing;
7641ab64890Smrg	overall_ink->y = -(overall.ascent);
7651ab64890Smrg	overall_ink->width = overall.rbearing - overall.lbearing;
7661ab64890Smrg	overall_ink->height = overall.ascent + overall.descent;
7671ab64890Smrg    }
7681ab64890Smrg
7691ab64890Smrg    if (overall_logical) {
7701ab64890Smrg	overall_logical->x = 0;
7711ab64890Smrg        overall_logical->y = -(logical_ascent);
7721ab64890Smrg	overall_logical->width = overall.width;
7731ab64890Smrg        overall_logical->height = logical_ascent + logical_descent;
7741ab64890Smrg    }
7751ab64890Smrg
7761ab64890Smrg    return overall.width;
7771ab64890Smrg}
7781ab64890Smrg
7791ab64890Smrgstatic int
7801ab64890Smrg_XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length,
7811ab64890Smrg		       XRectangle *overall_ink, XRectangle *overall_logical)
7821ab64890Smrg{
7831ab64890Smrg    DefineLocalBuf;
7841ab64890Smrg    char *buf = AllocLocalBuf(length);
7851ab64890Smrg    int ret = 0;
7861ab64890Smrg
7871ab64890Smrg    if (buf == NULL)
7881ab64890Smrg	return 0;
7891ab64890Smrg
7901ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
7911ab64890Smrg	goto err;
7921ab64890Smrg
7931ab64890Smrg    ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical);
7941ab64890Smrg
7951ab64890Smrgerr:
7961ab64890Smrg    FreeLocalBuf(buf);
7971ab64890Smrg
7981ab64890Smrg    return ret;
7991ab64890Smrg}
8001ab64890Smrg
8011ab64890Smrgstatic Status
8021ab64890Smrg_XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length,
8031ab64890Smrg			      XRectangle *ink_buf, XRectangle *logical_buf,
8041ab64890Smrg			      int buf_size, int *num_chars,
8051ab64890Smrg			      XRectangle *overall_ink,
8061ab64890Smrg			      XRectangle *overall_logical)
8071ab64890Smrg{
8081ab64890Smrg    XFontStruct *font = *oc->core.font_info.font_struct_list;
8091ab64890Smrg    XCharStruct *def, *cs, overall;
8101ab64890Smrg    Bool first = True;
8111ab64890Smrg
8121ab64890Smrg    if (buf_size < length)
8131ab64890Smrg	return 0;
8141ab64890Smrg
8151ab64890Smrg    bzero((char *) &overall, sizeof(XCharStruct));
8161ab64890Smrg    *num_chars = 0;
8171ab64890Smrg
8181ab64890Smrg    CI_GET_DEFAULT_INFO_1D(font, def)
8191ab64890Smrg
8201ab64890Smrg    while (length-- > 0) {
8211ab64890Smrg	CI_GET_CHAR_INFO_1D(font, *text, def, cs)
8221ab64890Smrg	text++;
8231ab64890Smrg	if (cs == NULL)
8241ab64890Smrg	    continue;
8251ab64890Smrg
8261ab64890Smrg	ink_buf->x = overall.width + cs->lbearing;
8271ab64890Smrg	ink_buf->y = -(cs->ascent);
8281ab64890Smrg	ink_buf->width = cs->rbearing - cs->lbearing;
8291ab64890Smrg	ink_buf->height = cs->ascent + cs->descent;
8301ab64890Smrg	ink_buf++;
8311ab64890Smrg
8321ab64890Smrg	logical_buf->x = overall.width;
8331ab64890Smrg	logical_buf->y = -(font->ascent);
8341ab64890Smrg	logical_buf->width = cs->width;
8351ab64890Smrg	logical_buf->height = font->ascent + font->descent;
8361ab64890Smrg	logical_buf++;
8371ab64890Smrg
8381ab64890Smrg	if (first) {
8391ab64890Smrg	    overall = *cs;
8401ab64890Smrg	    first = False;
8411ab64890Smrg	} else {
8421ab64890Smrg	    overall.ascent = max(overall.ascent, cs->ascent);
8431ab64890Smrg	    overall.descent = max(overall.descent, cs->descent);
8441ab64890Smrg	    overall.lbearing = min(overall.lbearing, overall.width +
8451ab64890Smrg				   cs->lbearing);
8461ab64890Smrg	    overall.rbearing = max(overall.rbearing, overall.width +
8471ab64890Smrg				   cs->rbearing);
8481ab64890Smrg	    overall.width += cs->width;
8491ab64890Smrg	}
85061b2299dSmrg   	(*num_chars)++;
8511ab64890Smrg    }
8521ab64890Smrg
8531ab64890Smrg    if (overall_ink) {
8541ab64890Smrg	overall_ink->x = overall.lbearing;
8551ab64890Smrg	overall_ink->y = -(overall.ascent);
8561ab64890Smrg	overall_ink->width = overall.rbearing - overall.lbearing;
8571ab64890Smrg	overall_ink->height = overall.ascent + overall.descent;
8581ab64890Smrg    }
8591ab64890Smrg
8601ab64890Smrg    if (overall_logical) {
8611ab64890Smrg	overall_logical->x = 0;
8621ab64890Smrg	overall_logical->y = -(font->ascent);
8631ab64890Smrg	overall_logical->width = overall.width;
8641ab64890Smrg	overall_logical->height = font->ascent + font->descent;
8651ab64890Smrg    }
8661ab64890Smrg
8671ab64890Smrg    return 1;
8681ab64890Smrg}
8691ab64890Smrg
8701ab64890Smrgstatic Status
8711ab64890Smrg_XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length,
8721ab64890Smrg			      XRectangle *ink_buf, XRectangle *logical_buf,
8731ab64890Smrg			      int buf_size, int *num_chars,
8741ab64890Smrg			      XRectangle *overall_ink,
8751ab64890Smrg			      XRectangle *overall_logical)
8761ab64890Smrg{
8771ab64890Smrg    DefineLocalBuf;
8781ab64890Smrg    char *buf = AllocLocalBuf(length);
8791ab64890Smrg    Status ret = 0;
8801ab64890Smrg
8811ab64890Smrg    if (buf == NULL)
8821ab64890Smrg	return 0;
8831ab64890Smrg
8841ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
8851ab64890Smrg	goto err;
8861ab64890Smrg
8871ab64890Smrg    ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf,
8881ab64890Smrg					buf_size, num_chars, overall_ink,
8891ab64890Smrg					overall_logical);
8901ab64890Smrg
8911ab64890Smrgerr:
8921ab64890Smrg    FreeLocalBuf(buf);
8931ab64890Smrg
8941ab64890Smrg    return ret;
8951ab64890Smrg}
8961ab64890Smrg
8971ab64890Smrgstatic int
8981ab64890Smrg_XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
8991ab64890Smrg		      _Xconst char *text, int length)
9001ab64890Smrg{
9011ab64890Smrg    XFontStruct *font = *oc->core.font_info.font_struct_list;
9021ab64890Smrg
9031ab64890Smrg    XSetFont(dpy, gc, font->fid);
9041ab64890Smrg    XDrawString(dpy, d, gc, x, y, text, length);
9051ab64890Smrg
9061ab64890Smrg    return XTextWidth(font, text, length);
9071ab64890Smrg}
9081ab64890Smrg
9091ab64890Smrgstatic int
9101ab64890Smrg_XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y,
9111ab64890Smrg		      _Xconst wchar_t *text, int length)
9121ab64890Smrg{
9131ab64890Smrg    DefineLocalBuf;
9141ab64890Smrg    char *buf = AllocLocalBuf(length);
9151ab64890Smrg    int ret = 0;
9161ab64890Smrg
9171ab64890Smrg    if (buf == NULL)
9181ab64890Smrg	return 0;
9191ab64890Smrg
9201ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
9211ab64890Smrg	goto err;
9221ab64890Smrg
9231ab64890Smrg    ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length);
9241ab64890Smrg
9251ab64890Smrgerr:
9261ab64890Smrg    FreeLocalBuf(buf);
9271ab64890Smrg
9281ab64890Smrg    return ret;
9291ab64890Smrg}
9301ab64890Smrg
9311ab64890Smrgstatic void
9321ab64890Smrg_XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
9331ab64890Smrg			   int y, _Xconst char *text, int length)
9341ab64890Smrg{
9351ab64890Smrg    XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid);
9361ab64890Smrg    XDrawImageString(dpy, d, gc, x, y, text, length);
9371ab64890Smrg}
9381ab64890Smrg
9391ab64890Smrgstatic void
9401ab64890Smrg_XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x,
9411ab64890Smrg			   int y, _Xconst wchar_t *text, int length)
9421ab64890Smrg{
9431ab64890Smrg    DefineLocalBuf;
9441ab64890Smrg    char *buf = AllocLocalBuf(length);
9451ab64890Smrg
9461ab64890Smrg    if (buf == NULL)
9471ab64890Smrg	return;
9481ab64890Smrg
9491ab64890Smrg    if (wcs_to_mbs(oc, buf, text, length) == False)
9501ab64890Smrg	goto err;
9511ab64890Smrg
9521ab64890Smrg    _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length);
9531ab64890Smrg
9541ab64890Smrgerr:
9551ab64890Smrg    FreeLocalBuf(buf);
9561ab64890Smrg}
9571ab64890Smrg
9581ab64890Smrgstatic _Xconst XOCMethodsRec oc_default_methods = {
9591ab64890Smrg    destroy_oc,
9601ab64890Smrg    set_oc_values,
9611ab64890Smrg    get_oc_values,
9621ab64890Smrg    _XmbDefaultTextEscapement,
9631ab64890Smrg    _XmbDefaultTextExtents,
9641ab64890Smrg    _XmbDefaultTextPerCharExtents,
9651ab64890Smrg    _XmbDefaultDrawString,
9661ab64890Smrg    _XmbDefaultDrawImageString,
9671ab64890Smrg    _XwcDefaultTextEscapement,
9681ab64890Smrg    _XwcDefaultTextExtents,
9691ab64890Smrg    _XwcDefaultTextPerCharExtents,
9701ab64890Smrg    _XwcDefaultDrawString,
9711ab64890Smrg    _XwcDefaultDrawImageString
9721ab64890Smrg};
9731ab64890Smrg
9741ab64890Smrgstatic XlcResource oc_resources[] = {
9751ab64890Smrg    { XNBaseFontName, NULLQUARK, sizeof(char *),
9761ab64890Smrg      XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask },
9771ab64890Smrg    { XNOMAutomatic, NULLQUARK, sizeof(Bool),
9781ab64890Smrg      XOffsetOf(XOCRec, core.om_automatic), XlcGetMask },
9791ab64890Smrg    { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList),
9801ab64890Smrg      XOffsetOf(XOCRec, core.missing_list), XlcGetMask },
9811ab64890Smrg    { XNDefaultString, NULLQUARK, sizeof(char *),
9821ab64890Smrg      XOffsetOf(XOCRec, core.default_string), XlcGetMask },
9831ab64890Smrg    { XNOrientation, NULLQUARK, sizeof(XOrientation),
9841ab64890Smrg      XOffsetOf(XOCRec, core.orientation), XlcSetMask | XlcGetMask },
9851ab64890Smrg    { XNResourceName, NULLQUARK, sizeof(char *),
9861ab64890Smrg      XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask },
9871ab64890Smrg    { XNResourceClass, NULLQUARK, sizeof(char *),
9881ab64890Smrg      XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask },
9891ab64890Smrg    { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo),
9901ab64890Smrg      XOffsetOf(XOCRec, core.font_info), XlcGetMask }
9911ab64890Smrg};
9921ab64890Smrg
9931ab64890Smrgstatic XOC
9941ab64890Smrgcreate_oc(
9951ab64890Smrg    XOM om,
9961ab64890Smrg    XlcArgList args,
9971ab64890Smrg    int num_args)
9981ab64890Smrg{
9991ab64890Smrg    XOC oc;
10001ab64890Smrg
10016cc2b21fSmrg    oc = Xcalloc(1, sizeof(XOCGenericRec));
10021ab64890Smrg    if (oc == NULL)
10031ab64890Smrg	return (XOC) NULL;
100461b2299dSmrg
10051ab64890Smrg    oc->core.om = om;
10061ab64890Smrg
10071ab64890Smrg    if (oc_resources[0].xrm_name == NULLQUARK)
10081ab64890Smrg	_XlcCompileResourceList(oc_resources, XlcNumber(oc_resources));
100961b2299dSmrg
10101ab64890Smrg    if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources),
10111ab64890Smrg		      args, num_args, XlcCreateMask | XlcDefaultMask))
10121ab64890Smrg	goto err;
10131ab64890Smrg
10141ab64890Smrg    if (oc->core.base_name_list == NULL)
10151ab64890Smrg	goto err;
10161ab64890Smrg
10171ab64890Smrg    oc->core.resources = oc_resources;
10181ab64890Smrg    oc->core.num_resources = XlcNumber(oc_resources);
10191ab64890Smrg
10201ab64890Smrg    if (create_fontset(oc) == False)
10211ab64890Smrg	goto err;
10221ab64890Smrg
10231ab64890Smrg    oc->methods = (XOCMethods)&oc_default_methods;
10241ab64890Smrg
10251ab64890Smrg    return oc;
10261ab64890Smrg
10271ab64890Smrgerr:
10281ab64890Smrg    destroy_oc(oc);
10291ab64890Smrg
10301ab64890Smrg    return (XOC) NULL;
10311ab64890Smrg}
10321ab64890Smrg
10331ab64890Smrgstatic Status
10341ab64890Smrgclose_om(
10351ab64890Smrg    XOM om)
10361ab64890Smrg{
10371ab64890Smrg    XOMGenericPart *gen = XOM_GENERIC(om);
10381ab64890Smrg    OMData data;
10391ab64890Smrg    FontData font_data;
10401ab64890Smrg    int count;
10411ab64890Smrg
10421ab64890Smrg    if ((data = gen->data)) {
10431ab64890Smrg	if (data->font_data) {
10441ab64890Smrg	  for (font_data = data->font_data, count = data->font_data_count;
104561b2299dSmrg	       count-- > 0 ; font_data++) {
10461ab64890Smrg	    if (font_data->name)
10471ab64890Smrg		Xfree(font_data->name);
10481ab64890Smrg	  }
10491ab64890Smrg	  Xfree(data->font_data);
10501ab64890Smrg	}
10511ab64890Smrg	Xfree(gen->data);
10521ab64890Smrg    }
10531ab64890Smrg
10541ab64890Smrg    if (om->core.res_name)
10551ab64890Smrg	Xfree(om->core.res_name);
10561ab64890Smrg    if (om->core.res_class)
10571ab64890Smrg	Xfree(om->core.res_class);
10581ab64890Smrg    if (om->core.required_charset.charset_list)
10591ab64890Smrg	XFreeStringList(om->core.required_charset.charset_list);
10601ab64890Smrg    else
10611ab64890Smrg	Xfree((char*)om->core.required_charset.charset_list);
10621ab64890Smrg    if (om->core.orientation_list.orientation)
10631ab64890Smrg	Xfree(om->core.orientation_list.orientation);
10641ab64890Smrg
10651ab64890Smrg    Xfree(om);
10661ab64890Smrg
10671ab64890Smrg    return 1;
10681ab64890Smrg}
10691ab64890Smrg
10701ab64890Smrgstatic char *
10711ab64890Smrgset_om_values(
10721ab64890Smrg    XOM om,
10731ab64890Smrg    XlcArgList args,
10741ab64890Smrg    int num_args)
10751ab64890Smrg{
10761ab64890Smrg    if (om->core.resources == NULL)
10771ab64890Smrg	return NULL;
10781ab64890Smrg
10791ab64890Smrg    return _XlcSetValues((XPointer) om, om->core.resources,
10801ab64890Smrg			 om->core.num_resources, args, num_args, XlcSetMask);
10811ab64890Smrg}
10821ab64890Smrg
10831ab64890Smrgstatic char *
10841ab64890Smrgget_om_values(
10851ab64890Smrg    XOM om,
10861ab64890Smrg    XlcArgList args,
10871ab64890Smrg    int num_args)
10881ab64890Smrg{
10891ab64890Smrg    if (om->core.resources == NULL)
10901ab64890Smrg	return NULL;
10911ab64890Smrg
10921ab64890Smrg    return _XlcGetValues((XPointer) om, om->core.resources,
10931ab64890Smrg			 om->core.num_resources, args, num_args, XlcGetMask);
10941ab64890Smrg}
10951ab64890Smrg
10961ab64890Smrgstatic _Xconst XOMMethodsRec methods = {
10971ab64890Smrg    close_om,
10981ab64890Smrg    set_om_values,
10991ab64890Smrg    get_om_values,
11001ab64890Smrg    create_oc
11011ab64890Smrg};
11021ab64890Smrg
11031ab64890Smrgstatic XlcResource om_resources[] = {
11041ab64890Smrg    { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList),
11051ab64890Smrg      XOffsetOf(XOMRec, core.required_charset), XlcGetMask },
11061ab64890Smrg    { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation),
11071ab64890Smrg      XOffsetOf(XOMRec, core.orientation_list), XlcGetMask },
11081ab64890Smrg    { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool),
11091ab64890Smrg      XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask },
11101ab64890Smrg    { XNContextualDrawing, NULLQUARK, sizeof(Bool),
11111ab64890Smrg      XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask }
11121ab64890Smrg};
11131ab64890Smrg
11141ab64890Smrgstatic OMData
11151ab64890Smrgadd_data(
11161ab64890Smrg    XOM om)
11171ab64890Smrg{
11181ab64890Smrg    XOMGenericPart *gen = XOM_GENERIC(om);
11191ab64890Smrg    OMData new;
11201ab64890Smrg
11216cc2b21fSmrg    new = Xcalloc(1, sizeof(OMDataRec));
11221ab64890Smrg
11231ab64890Smrg    if (new == NULL)
11241ab64890Smrg        return NULL;
11251ab64890Smrg
11261ab64890Smrg    gen->data = new;
11271ab64890Smrg
11281ab64890Smrg    return new;
11291ab64890Smrg}
11301ab64890Smrg
11311ab64890Smrgstatic _Xconst char *supported_charset_list[] = {
11321ab64890Smrg    "ISO8859-1",
11331ab64890Smrg/* fix for bug4332979 */
11341ab64890Smrg    "adobe-fontspecific",
11351ab64890Smrg/* fix for bug4237353: "JISX0201.1976-0" entry should be removed from
11361ab64890Smrg   supported_charset_list because it is not a supported_charset for C locale
11371ab64890Smrg    "JISX0201.1976-0", */
11381ab64890Smrg    "SUNOLCURSOR-1",
11391ab64890Smrg    "SUNOLGLYPH-1"
11401ab64890Smrg};
114161b2299dSmrg
11421ab64890Smrgstatic Bool
11431ab64890Smrginit_om(
11441ab64890Smrg    XOM om)
11451ab64890Smrg{
11461ab64890Smrg    XOMGenericPart *gen = XOM_GENERIC(om);
11471ab64890Smrg    OMData data;
11481ab64890Smrg    FontData font_data;
11491ab64890Smrg    char **required_list;
11501ab64890Smrg    XOrientation *orientation;
1151818534a1Smrg    char *bufptr;
1152818534a1Smrg    int i, count, length = 0;
11531ab64890Smrg
11541ab64890Smrg    count = XlcNumber(supported_charset_list);
11551ab64890Smrg
11561ab64890Smrg    data = add_data(om);
11571ab64890Smrg    if (data == NULL)
11581ab64890Smrg	return False;
11591ab64890Smrg
11606cc2b21fSmrg    font_data = Xcalloc(count, sizeof(FontDataRec));
11611ab64890Smrg    if (font_data == NULL)
11621ab64890Smrg	return False;
11631ab64890Smrg    data->font_data = font_data;
11641ab64890Smrg    data->font_data_count = count;
11651ab64890Smrg
1166818534a1Smrg    for (i = 0; i < count; i++, font_data++) {
1167818534a1Smrg	font_data->name = strdup(supported_charset_list[i]);
11681ab64890Smrg	if (font_data->name == NULL)
11691ab64890Smrg	    return False;
11701ab64890Smrg    }
11711ab64890Smrg
11721ab64890Smrg    length += strlen(data->font_data->name) + 1;
11731ab64890Smrg
11741ab64890Smrg    /* required charset list */
1175818534a1Smrg    required_list = Xmalloc(sizeof(char *));
11761ab64890Smrg    if (required_list == NULL)
11771ab64890Smrg	return False;
11781ab64890Smrg
1179818534a1Smrg    bufptr = Xmalloc(length);
11801ab64890Smrg    if (bufptr == NULL) {
11811ab64890Smrg	Xfree(required_list);
11821ab64890Smrg	return False;
11831ab64890Smrg    }
11841ab64890Smrg
11851ab64890Smrg    om->core.required_charset.charset_list = required_list;
11861ab64890Smrg    om->core.required_charset.charset_count = 1; /* always 1 */
11871ab64890Smrg
11881ab64890Smrg    data = gen->data;
11891ab64890Smrg
11901ab64890Smrg    strcpy(bufptr, data->font_data->name);
11911ab64890Smrg    *required_list++ = bufptr;
11921ab64890Smrg    bufptr += strlen(bufptr) + 1;
11931ab64890Smrg
11941ab64890Smrg    /* orientation list */
1195818534a1Smrg    orientation = Xmalloc(sizeof(XOrientation));
11961ab64890Smrg    if (orientation == NULL)
11971ab64890Smrg	return False;
11981ab64890Smrg
11991ab64890Smrg    *orientation = XOMOrientation_LTR_TTB;
12001ab64890Smrg    om->core.orientation_list.orientation = orientation;
12011ab64890Smrg    om->core.orientation_list.num_orientation = 1;
12021ab64890Smrg
12031ab64890Smrg    /* directional dependent drawing */
12041ab64890Smrg    om->core.directional_dependent = False;
12051ab64890Smrg
12061ab64890Smrg    /* contexual drawing */
12071ab64890Smrg    om->core.contextual_drawing = False;
12081ab64890Smrg
12091ab64890Smrg    /* context dependent */
12101ab64890Smrg    om->core.context_dependent = False;
12111ab64890Smrg
12121ab64890Smrg    return True;
12131ab64890Smrg}
12141ab64890Smrg
12151ab64890SmrgXOM
12161ab64890Smrg_XDefaultOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb,
12171ab64890Smrg		_Xconst char *res_name, _Xconst char *res_class)
12181ab64890Smrg{
12191ab64890Smrg    XOM om;
12201ab64890Smrg
12216cc2b21fSmrg    om = Xcalloc(1, sizeof(XOMGenericRec));
12221ab64890Smrg    if (om == NULL)
12231ab64890Smrg	return (XOM) NULL;
122461b2299dSmrg
12251ab64890Smrg    om->methods = (XOMMethods)&methods;
12261ab64890Smrg    om->core.lcd = lcd;
12271ab64890Smrg    om->core.display = dpy;
12281ab64890Smrg    om->core.rdb = rdb;
12291ab64890Smrg    if (res_name) {
12306cc2b21fSmrg	om->core.res_name = strdup(res_name);
12311ab64890Smrg	if (om->core.res_name == NULL)
12321ab64890Smrg	    goto err;
12331ab64890Smrg    }
12341ab64890Smrg    if (res_class) {
12356cc2b21fSmrg	om->core.res_class = strdup(res_class);
12361ab64890Smrg	if (om->core.res_class == NULL)
12371ab64890Smrg	    goto err;
12381ab64890Smrg    }
12391ab64890Smrg
12401ab64890Smrg    if (om_resources[0].xrm_name == NULLQUARK)
12411ab64890Smrg	_XlcCompileResourceList(om_resources, XlcNumber(om_resources));
124261b2299dSmrg
12431ab64890Smrg    om->core.resources = om_resources;
12441ab64890Smrg    om->core.num_resources = XlcNumber(om_resources);
12451ab64890Smrg
12461ab64890Smrg    if (init_om(om) == False)
12471ab64890Smrg	goto err;
12481ab64890Smrg
12491ab64890Smrg    return om;
12501ab64890Smrgerr:
12511ab64890Smrg    close_om(om);
12521ab64890Smrg
12531ab64890Smrg    return (XOM) NULL;
12541ab64890Smrg}
1255