imRmAttr.c revision 57f47464
11ab64890Smrg/******************************************************************
21ab64890Smrg
31ab64890Smrg           Copyright 1992, 1993, 1994 by FUJITSU LIMITED
41ab64890Smrg
51ab64890SmrgPermission to use, copy, modify, distribute, and sell this software
61ab64890Smrgand its documentation for any purpose is hereby granted without fee,
71ab64890Smrgprovided that the above copyright notice appear in all copies and
81ab64890Smrgthat both that copyright notice and this permission notice appear
91ab64890Smrgin supporting documentation, and that the name of FUJITSU LIMITED
101ab64890Smrgnot be used in advertising or publicity pertaining to distribution
111ab64890Smrgof the software without specific, written prior permission.
121ab64890SmrgFUJITSU LIMITED makes no representations about the suitability of
1361b2299dSmrgthis software for any purpose.
141ab64890SmrgIt is provided "as is" without express or implied warranty.
151ab64890Smrg
161ab64890SmrgFUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
171ab64890SmrgINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
181ab64890SmrgEVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
191ab64890SmrgCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
201ab64890SmrgUSE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
211ab64890SmrgOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
221ab64890SmrgPERFORMANCE OF THIS SOFTWARE.
231ab64890Smrg
2461b2299dSmrg  Author: Takashi Fujiwara     FUJITSU LIMITED
251ab64890Smrg                               fujiwara@a80.tech.yk.fujitsu.co.jp
261ab64890Smrg
271ab64890Smrg******************************************************************/
281ab64890Smrg
291ab64890Smrg#ifdef HAVE_CONFIG_H
301ab64890Smrg#include <config.h>
311ab64890Smrg#endif
321ab64890Smrg#include "Xlibint.h"
331ab64890Smrg#include "Xlcint.h"
341ab64890Smrg#include "Ximint.h"
351ab64890Smrg
361ab64890Smrg
371ab64890SmrgPrivate XIMResourceList
381ab64890Smrg_XimGetNestedListSeparator(
391ab64890Smrg    XIMResourceList	 res_list,		/* LISTofIMATTR or IMATTR */
401ab64890Smrg    unsigned int	 res_num)
411ab64890Smrg{
421ab64890Smrg    return  _XimGetResourceListRec(res_list, res_num, XNSeparatorofNestedList);
431ab64890Smrg}
441ab64890Smrg
451ab64890SmrgPrivate Bool
461ab64890Smrg_XimCheckInnerIMAttributes(
471ab64890Smrg    Xim			 im,
481ab64890Smrg    XIMArg		*arg,
491ab64890Smrg    unsigned long	 mode)
501ab64890Smrg{
511ab64890Smrg    XIMResourceList	 res;
521ab64890Smrg    int			 check;
531ab64890Smrg
541ab64890Smrg    if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
551ab64890Smrg			im->private.proto.im_num_inner_resources, arg->name)))
561ab64890Smrg	return False;
571ab64890Smrg
581ab64890Smrg    check = _XimCheckIMMode(res, mode);
591ab64890Smrg    if(check == XIM_CHECK_INVALID)
601ab64890Smrg	return True;
611ab64890Smrg    else if(check == XIM_CHECK_ERROR)
621ab64890Smrg	return False;
631ab64890Smrg
641ab64890Smrg    return True;
651ab64890Smrg}
661ab64890Smrg
671ab64890SmrgPublic char *
681ab64890Smrg_XimMakeIMAttrIDList(
691ab64890Smrg    Xim			 im,
701ab64890Smrg    XIMResourceList	 res_list,
711ab64890Smrg    unsigned int	 res_num,
721ab64890Smrg    XIMArg		*arg,
731ab64890Smrg    CARD16		*buf,
741ab64890Smrg    INT16		*len,
751ab64890Smrg    unsigned long	 mode)
761ab64890Smrg{
771ab64890Smrg    register XIMArg	*p;
781ab64890Smrg    XIMResourceList	 res;
791ab64890Smrg    int			 check;
801ab64890Smrg
811ab64890Smrg    *len = 0;
821ab64890Smrg    if (!arg)
831ab64890Smrg	return (char *)NULL;
841ab64890Smrg
851ab64890Smrg    for (p = arg; p->name; p++) {
861ab64890Smrg	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
871ab64890Smrg	    if (_XimCheckInnerIMAttributes(im, p, mode))
881ab64890Smrg		continue;
891ab64890Smrg	    return p->name;
901ab64890Smrg	}
911ab64890Smrg
921ab64890Smrg	check = _XimCheckIMMode(res, mode);
931ab64890Smrg	if (check == XIM_CHECK_INVALID)
941ab64890Smrg	    continue;
951ab64890Smrg	else if (check == XIM_CHECK_ERROR)
961ab64890Smrg	    return p->name;
971ab64890Smrg
981ab64890Smrg	*buf = res->id;
991ab64890Smrg	*len += sizeof(CARD16);
1001ab64890Smrg	 buf++;
1011ab64890Smrg    }
1021ab64890Smrg    return (char *)NULL;
1031ab64890Smrg}
1041ab64890Smrg
1051ab64890SmrgPrivate Bool
1061ab64890Smrg_XimCheckInnerICAttributes(
1071ab64890Smrg    Xic			 ic,
1081ab64890Smrg    XIMArg		*arg,
1091ab64890Smrg    unsigned long	 mode)
1101ab64890Smrg{
1111ab64890Smrg    XIMResourceList	 res;
1121ab64890Smrg    int			 check;
1131ab64890Smrg
1141ab64890Smrg    if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
1151ab64890Smrg			ic->private.proto.ic_num_inner_resources, arg->name)))
1161ab64890Smrg	return False;
1171ab64890Smrg
1181ab64890Smrg    check = _XimCheckICMode(res, mode);
1191ab64890Smrg    if(check == XIM_CHECK_INVALID)
1201ab64890Smrg	return True;
1211ab64890Smrg    else if(check == XIM_CHECK_ERROR)
1221ab64890Smrg	return False;
1231ab64890Smrg
1241ab64890Smrg    return True;
1251ab64890Smrg}
1261ab64890Smrg
1271ab64890SmrgPublic char *
1281ab64890Smrg_XimMakeICAttrIDList(
1291ab64890Smrg    Xic			 ic,
1301ab64890Smrg    XIMResourceList	 res_list,
1311ab64890Smrg    unsigned int	 res_num,
1321ab64890Smrg    XIMArg		*arg,
1331ab64890Smrg    CARD16		*buf,
1341ab64890Smrg    INT16		*len,
1351ab64890Smrg    unsigned long	 mode)
1361ab64890Smrg{
1371ab64890Smrg    register XIMArg	*p;
1381ab64890Smrg    XIMResourceList	 res;
1391ab64890Smrg    int			 check;
1401ab64890Smrg    XrmQuark		 pre_quark;
1411ab64890Smrg    XrmQuark		 sts_quark;
1421ab64890Smrg    char		*name;
1431ab64890Smrg    INT16		 new_len;
1441ab64890Smrg
1451ab64890Smrg    *len = 0;
1461ab64890Smrg    if (!arg)
1471ab64890Smrg	return (char *)NULL;
1481ab64890Smrg
1491ab64890Smrg    pre_quark = XrmStringToQuark(XNPreeditAttributes);
1501ab64890Smrg    sts_quark = XrmStringToQuark(XNStatusAttributes);
1511ab64890Smrg
1521ab64890Smrg    for (p = arg; p && p->name; p++) {
1531ab64890Smrg	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
1541ab64890Smrg	    if (_XimCheckInnerICAttributes(ic, p, mode))
1551ab64890Smrg		continue;
1561ab64890Smrg	    *len = -1;
1571ab64890Smrg	    return p->name;
1581ab64890Smrg	}
1591ab64890Smrg
1601ab64890Smrg	check = _XimCheckICMode(res, mode);
1611ab64890Smrg	if(check == XIM_CHECK_INVALID)
1621ab64890Smrg	    continue;
1631ab64890Smrg	else if(check == XIM_CHECK_ERROR) {
1641ab64890Smrg	    *len = -1;
1651ab64890Smrg	    return p->name;
1661ab64890Smrg	}
1671ab64890Smrg
1681ab64890Smrg	*buf = res->id;
1691ab64890Smrg	*len += sizeof(CARD16);
1701ab64890Smrg	buf++;
1711ab64890Smrg	if (res->resource_size == XimType_NEST) {
1721ab64890Smrg	    if (res->xrm_name == pre_quark) {
1731ab64890Smrg		if ((name = _XimMakeICAttrIDList(ic, res_list, res_num,
1741ab64890Smrg				(XIMArg *)p->value, buf, &new_len,
1751ab64890Smrg				(mode | XIM_PREEDIT_ATTR)))) {
1761ab64890Smrg		    if (new_len < 0) *len = -1;
1771ab64890Smrg		    else *len += new_len;
1781ab64890Smrg		    return name;
1791ab64890Smrg		}
1801ab64890Smrg	    } else if (res->xrm_name == sts_quark) {
1811ab64890Smrg		if ((name = _XimMakeICAttrIDList(ic, res_list, res_num,
1821ab64890Smrg				(XIMArg *)p->value, buf, &new_len,
1831ab64890Smrg				(mode | XIM_STATUS_ATTR)))) {
1841ab64890Smrg		    if (new_len < 0) *len = -1;
1851ab64890Smrg		    else *len += new_len;
1861ab64890Smrg		    return name;
1871ab64890Smrg		}
1881ab64890Smrg	    }
1891ab64890Smrg	    *len += new_len;
1901ab64890Smrg	    buf = (CARD16 *)((char *)buf + new_len);
1911ab64890Smrg	    if (!(res = _XimGetNestedListSeparator(res_list, res_num))) {
1921ab64890Smrg		p++;
1931ab64890Smrg		if (p) {
1941ab64890Smrg		    *len = -1;
1951ab64890Smrg		    return p->name;
1961ab64890Smrg		}
1971ab64890Smrg		else {
1981ab64890Smrg		    return (char *)NULL;
1991ab64890Smrg		}
2001ab64890Smrg	    }
2011ab64890Smrg	    *buf = res->id;
2021ab64890Smrg	    *len += sizeof(CARD16);
2031ab64890Smrg	    buf++;
2041ab64890Smrg	}
2051ab64890Smrg    }
2061ab64890Smrg    return (char *)NULL;
2071ab64890Smrg}
2081ab64890Smrg
2091ab64890SmrgPrivate Bool
2101ab64890Smrg_XimAttributeToValue(
2111ab64890Smrg    Xic			  ic,
2121ab64890Smrg    XIMResourceList	  res,
2131ab64890Smrg    CARD16		 *data,
2141ab64890Smrg    INT16		  data_len,
2151ab64890Smrg    XPointer		  value,
2161ab64890Smrg    BITMASK32		  mode)
2171ab64890Smrg{
2181ab64890Smrg    switch (res->resource_size) {
2191ab64890Smrg    case XimType_SeparatorOfNestedList:
2201ab64890Smrg    case XimType_NEST:
2211ab64890Smrg	break;
2221ab64890Smrg
2231ab64890Smrg    case XimType_CARD8:
2241ab64890Smrg    case XimType_CARD16:
2251ab64890Smrg    case XimType_CARD32:
2261ab64890Smrg    case XimType_Window:
2271ab64890Smrg    case XimType_XIMHotKeyState:
2281ab64890Smrg	_XCopyToArg((XPointer)data, (XPointer *)&value, data_len);
2291ab64890Smrg	break;
2301ab64890Smrg
2311ab64890Smrg    case XimType_STRING8:
2321ab64890Smrg	{
2331ab64890Smrg	    char	*str;
2341ab64890Smrg
2351ab64890Smrg	    if (!(value))
2361ab64890Smrg		return False;
2371ab64890Smrg
2381ab64890Smrg	    if (!(str = (char *)Xmalloc(data_len + 1)))
2391ab64890Smrg		return False;
2401ab64890Smrg
2411ab64890Smrg	    (void)memcpy(str, (char *)data, data_len);
2421ab64890Smrg	    str[data_len] = '\0';
2431ab64890Smrg
2441ab64890Smrg	    *((char **)value) = str;
2451ab64890Smrg	    break;
2461ab64890Smrg	}
2471ab64890Smrg
2481ab64890Smrg    case XimType_XIMStyles:
2491ab64890Smrg	{
2501ab64890Smrg	    INT16		 num = data[0];
2511ab64890Smrg	    register CARD32	*style_list = (CARD32 *)&data[2];
2521ab64890Smrg	    XIMStyle		*style;
2531ab64890Smrg	    XIMStyles		*rep;
2541ab64890Smrg	    register int	 i;
2551ab64890Smrg	    char		*p;
2561ab64890Smrg	    int			 alloc_len;
2571ab64890Smrg
2581ab64890Smrg	    if (!(value))
2591ab64890Smrg		return False;
2601ab64890Smrg
2611ab64890Smrg	    alloc_len = sizeof(XIMStyles) + sizeof(XIMStyle) * num;
2621ab64890Smrg	    if (!(p = (char *)Xmalloc(alloc_len)))
2631ab64890Smrg		return False;
2641ab64890Smrg
2651ab64890Smrg	    rep   = (XIMStyles *)p;
2661ab64890Smrg	    style = (XIMStyle *)(p + sizeof(XIMStyles));
2671ab64890Smrg
2681ab64890Smrg	    for (i = 0; i < num; i++)
2691ab64890Smrg		style[i] = (XIMStyle)style_list[i];
2701ab64890Smrg
2711ab64890Smrg	    rep->count_styles = (unsigned short)num;
2721ab64890Smrg	    rep->supported_styles = style;
2731ab64890Smrg	    *((XIMStyles **)value) = rep;
2741ab64890Smrg	    break;
2751ab64890Smrg	}
2761ab64890Smrg
2771ab64890Smrg    case XimType_XRectangle:
2781ab64890Smrg	{
2791ab64890Smrg	    XRectangle	*rep;
2801ab64890Smrg
2811ab64890Smrg	    if (!(value))
2821ab64890Smrg		return False;
2831ab64890Smrg
2841ab64890Smrg	    if (!(rep = (XRectangle *)Xmalloc(sizeof(XRectangle))))
2851ab64890Smrg		return False;
2861ab64890Smrg
2871ab64890Smrg	    rep->x      = data[0];
2881ab64890Smrg	    rep->y      = data[1];
2891ab64890Smrg	    rep->width  = data[2];
2901ab64890Smrg	    rep->height = data[3];
2911ab64890Smrg	    *((XRectangle **)value) = rep;
2921ab64890Smrg	    break;
2931ab64890Smrg	}
2941ab64890Smrg
2951ab64890Smrg    case XimType_XPoint:
2961ab64890Smrg	{
2971ab64890Smrg	    XPoint	*rep;
2981ab64890Smrg
2991ab64890Smrg	    if (!(value))
3001ab64890Smrg		return False;
3011ab64890Smrg
3021ab64890Smrg	    if (!(rep = (XPoint *)Xmalloc(sizeof(XPoint))))
3031ab64890Smrg		return False;
3041ab64890Smrg
3051ab64890Smrg	    rep->x = data[0];
3061ab64890Smrg	    rep->y = data[1];
3071ab64890Smrg	    *((XPoint **)value) = rep;
3081ab64890Smrg	    break;
3091ab64890Smrg	}
3101ab64890Smrg
3111ab64890Smrg    case XimType_XFontSet:
3121ab64890Smrg	{
3131ab64890Smrg	    INT16	 len = data[0];
3141ab64890Smrg	    char	*base_name;
3151ab64890Smrg	    XFontSet	 rep = (XFontSet)NULL;
31657f47464Smrg	    char	**missing_list = NULL;
3171ab64890Smrg	    int		 missing_count;
3181ab64890Smrg	    char	*def_string;
3191ab64890Smrg
3201ab64890Smrg	    if (!(value))
3211ab64890Smrg		return False;
3221ab64890Smrg	    if (!ic)
3231ab64890Smrg		return False;
3241ab64890Smrg
3251ab64890Smrg	    if (!(base_name = (char *)Xmalloc(len + 1)))
3261ab64890Smrg		return False;
3271ab64890Smrg
3281ab64890Smrg	    (void)strncpy(base_name, (char *)&data[1], (int)len);
3291ab64890Smrg	    base_name[len] = '\0';
3301ab64890Smrg
3311ab64890Smrg	    if (mode & XIM_PREEDIT_ATTR) {
3321ab64890Smrg		if (!strcmp(base_name, ic->private.proto.preedit_font)) {
3331ab64890Smrg		    rep = ic->core.preedit_attr.fontset;
3341ab64890Smrg		} else if (!ic->private.proto.preedit_font_length) {
3351ab64890Smrg		    rep = XCreateFontSet(ic->core.im->core.display,
3361ab64890Smrg					base_name, &missing_list,
3371ab64890Smrg					&missing_count, &def_string);
3381ab64890Smrg		}
3391ab64890Smrg	    } else if (mode & XIM_STATUS_ATTR) {
3401ab64890Smrg		if (!strcmp(base_name, ic->private.proto.status_font)) {
3411ab64890Smrg		    rep = ic->core.status_attr.fontset;
3421ab64890Smrg		} else if (!ic->private.proto.status_font_length) {
3431ab64890Smrg		    rep = XCreateFontSet(ic->core.im->core.display,
3441ab64890Smrg					base_name, &missing_list,
3451ab64890Smrg					&missing_count, &def_string);
3461ab64890Smrg		}
3471ab64890Smrg	    }
3481ab64890Smrg
3491ab64890Smrg	    Xfree(base_name);
35057f47464Smrg	    Xfree(missing_list);
3511ab64890Smrg	    *((XFontSet *)value) = rep;
3521ab64890Smrg	    break;
3531ab64890Smrg	}
3541ab64890Smrg
3551ab64890Smrg    case XimType_XIMHotKeyTriggers:
3561ab64890Smrg	{
3571ab64890Smrg	    INT32			 num = *((CARD32 *)data);
3581ab64890Smrg	    register CARD32		*key_list = (CARD32 *)&data[2];
3591ab64890Smrg	    XIMHotKeyTrigger		*key;
3601ab64890Smrg	    XIMHotKeyTriggers		*rep;
3611ab64890Smrg	    register int		 i;
3621ab64890Smrg	    char			*p;
3631ab64890Smrg	    int				 alloc_len;
3641ab64890Smrg
3651ab64890Smrg	    if (!(value))
3661ab64890Smrg		return False;
3671ab64890Smrg
3681ab64890Smrg	    alloc_len = sizeof(XIMHotKeyTriggers)
3691ab64890Smrg		      + sizeof(XIMHotKeyTrigger) * num;
3701ab64890Smrg	    if (!(p = (char *)Xmalloc(alloc_len)))
3711ab64890Smrg		return False;
3721ab64890Smrg
3731ab64890Smrg	    rep = (XIMHotKeyTriggers *)p;
3741ab64890Smrg	    key = (XIMHotKeyTrigger *)(p + sizeof(XIMHotKeyTriggers));
3751ab64890Smrg
3761ab64890Smrg	    for (i = 0; i < num; i++, key_list += 3) {
3771ab64890Smrg		key[i].keysym        = (KeySym)key_list[0]; /* keysym */
3781ab64890Smrg		key[i].modifier      = (int)key_list[1];    /* modifier */
3791ab64890Smrg		key[i].modifier_mask = (int)key_list[2];    /* modifier_mask */
3801ab64890Smrg	    }
3811ab64890Smrg
3821ab64890Smrg	    rep->num_hot_key = (int)num;
3831ab64890Smrg	    rep->key = key;
3841ab64890Smrg	    *((XIMHotKeyTriggers **)value) = rep;
3851ab64890Smrg	    break;
3861ab64890Smrg	}
3871ab64890Smrg
3881ab64890Smrg    case XimType_XIMStringConversion:
3891ab64890Smrg	{
3901ab64890Smrg	    break;
3911ab64890Smrg	}
3921ab64890Smrg
3931ab64890Smrg    default:
3941ab64890Smrg	return False;
3951ab64890Smrg    }
3961ab64890Smrg    return True;
3971ab64890Smrg}
3981ab64890Smrg
3991ab64890SmrgPrivate Bool
4001ab64890Smrg_XimDecodeInnerIMATTRIBUTE(
4011ab64890Smrg    Xim			 im,
4021ab64890Smrg    XIMArg		*arg)
4031ab64890Smrg{
4041ab64890Smrg    XIMResourceList	 res;
4051ab64890Smrg    XimDefIMValues	 im_values;
4061ab64890Smrg
4071ab64890Smrg    if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
4081ab64890Smrg			im->private.proto.im_num_inner_resources, arg->name)))
4091ab64890Smrg	return False;
4101ab64890Smrg
4111ab64890Smrg    _XimGetCurrentIMValues(im, &im_values);
4121ab64890Smrg    return _XimDecodeLocalIMAttr(res, (XPointer)&im_values, arg->value);
4131ab64890Smrg}
4141ab64890Smrg
4151ab64890SmrgPublic char *
4161ab64890Smrg_XimDecodeIMATTRIBUTE(
4171ab64890Smrg    Xim			 im,
4181ab64890Smrg    XIMResourceList	 res_list,
4191ab64890Smrg    unsigned int	 res_num,
4201ab64890Smrg    CARD16		*data,
4211ab64890Smrg    INT16		 data_len,
4221ab64890Smrg    XIMArg		*arg,
4231ab64890Smrg    BITMASK32		 mode)
4241ab64890Smrg{
4251ab64890Smrg    register XIMArg	*p;
4261ab64890Smrg    XIMResourceList	 res;
4271ab64890Smrg    int			 check;
4281ab64890Smrg    INT16		 len;
4291ab64890Smrg    CARD16		*buf;
4301ab64890Smrg    INT16		 total;
4311ab64890Smrg    INT16		 min_len = sizeof(CARD16)	/* sizeof attributeID */
4321ab64890Smrg			 	 + sizeof(INT16);	/* sizeof length */
4331ab64890Smrg
4341ab64890Smrg    for (p = arg; p->name; p++) {
4351ab64890Smrg	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
4361ab64890Smrg	    if (_XimDecodeInnerIMATTRIBUTE(im, p))
4371ab64890Smrg		continue;
4381ab64890Smrg	    return p->name;
4391ab64890Smrg	}
4401ab64890Smrg
4411ab64890Smrg	check = _XimCheckIMMode(res, mode);
4421ab64890Smrg	if(check == XIM_CHECK_INVALID)
4431ab64890Smrg	    continue;
4441ab64890Smrg	else if(check == XIM_CHECK_ERROR)
4451ab64890Smrg	    return p->name;
4461ab64890Smrg
4471ab64890Smrg	total = data_len;
4481ab64890Smrg	buf = data;
4491ab64890Smrg	while (total >= min_len) {
4501ab64890Smrg	    if (res->id == buf[0])
4511ab64890Smrg		break;
4521ab64890Smrg
4531ab64890Smrg	    len = buf[1];
4541ab64890Smrg	    len += XIM_PAD(len) + min_len;
4551ab64890Smrg	    buf = (CARD16 *)((char *)buf + len);
4561ab64890Smrg	    total -= len;
4571ab64890Smrg	}
4581ab64890Smrg	if (total < min_len)
4591ab64890Smrg	    return p->name;
4601ab64890Smrg
46161b2299dSmrg	if (!(_XimAttributeToValue((Xic) im->private.local.current_ic,
4621ab64890Smrg				   res, &buf[2], buf[1], p->value, mode)))
4631ab64890Smrg	    return p->name;
4641ab64890Smrg    }
4651ab64890Smrg    return (char *)NULL;
4661ab64890Smrg}
4671ab64890Smrg
4681ab64890SmrgPrivate Bool
4691ab64890Smrg_XimDecodeInnerICATTRIBUTE(
4701ab64890Smrg    Xic			 ic,
4711ab64890Smrg    XIMArg		*arg,
4721ab64890Smrg    unsigned long	 mode)
4731ab64890Smrg{
4741ab64890Smrg    XIMResourceList	 res;
4751ab64890Smrg    XimDefICValues	 ic_values;
4761ab64890Smrg
4771ab64890Smrg    if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
4781ab64890Smrg			ic->private.proto.ic_num_inner_resources, arg->name)))
4791ab64890Smrg	return False;
4801ab64890Smrg
4811ab64890Smrg    _XimGetCurrentICValues(ic, &ic_values);
4821ab64890Smrg    if (!_XimDecodeLocalICAttr(res, (XPointer)&ic_values, arg->value, mode))
4831ab64890Smrg	return False;
4841ab64890Smrg    _XimSetCurrentICValues(ic, &ic_values);
4851ab64890Smrg    return True;
4861ab64890Smrg}
4871ab64890Smrg
4881ab64890SmrgPublic char *
4891ab64890Smrg_XimDecodeICATTRIBUTE(
4901ab64890Smrg    Xic			 ic,
4911ab64890Smrg    XIMResourceList	 res_list,
4921ab64890Smrg    unsigned int	 res_num,
4931ab64890Smrg    CARD16		*data,
4941ab64890Smrg    INT16		 data_len,
4951ab64890Smrg    XIMArg		*arg,
4961ab64890Smrg    BITMASK32		 mode)
4971ab64890Smrg{
4981ab64890Smrg    register XIMArg	*p;
4991ab64890Smrg    XIMResourceList	 res;
5001ab64890Smrg    int			 check;
5011ab64890Smrg    INT16		 len;
5021ab64890Smrg    CARD16		*buf;
5031ab64890Smrg    INT16		 total;
5041ab64890Smrg    char		*name;
5051ab64890Smrg    INT16		 min_len = sizeof(CARD16)	/* sizeof attributeID */
5061ab64890Smrg			 	 + sizeof(INT16);	/* sizeof length */
5071ab64890Smrg    XrmQuark		 pre_quark;
5081ab64890Smrg    XrmQuark		 sts_quark;
5091ab64890Smrg
5101ab64890Smrg    if (!arg)
5111ab64890Smrg	return (char *)NULL;
5121ab64890Smrg
5131ab64890Smrg    pre_quark = XrmStringToQuark(XNPreeditAttributes);
5141ab64890Smrg    sts_quark = XrmStringToQuark(XNStatusAttributes);
5151ab64890Smrg
5161ab64890Smrg    for (p = arg; p->name; p++) {
5171ab64890Smrg	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
5181ab64890Smrg	    if (_XimDecodeInnerICATTRIBUTE(ic, p, mode))
5191ab64890Smrg		continue;
5201ab64890Smrg	    return p->name;
5211ab64890Smrg	}
5221ab64890Smrg
5231ab64890Smrg	check = _XimCheckICMode(res, mode);
5241ab64890Smrg	if (check == XIM_CHECK_INVALID)
5251ab64890Smrg	    continue;
5261ab64890Smrg	else if (check == XIM_CHECK_ERROR)
5271ab64890Smrg	    return p->name;
5281ab64890Smrg
5291ab64890Smrg	total = data_len;
5301ab64890Smrg	buf = data;
5311ab64890Smrg	while (total >= min_len) {
5321ab64890Smrg	    if (res->id == buf[0])
5331ab64890Smrg		break;
5341ab64890Smrg
5351ab64890Smrg	    len = buf[1];
5361ab64890Smrg	    len += XIM_PAD(len) + min_len;
5371ab64890Smrg	    buf = (CARD16 *)((char *)buf + len);
5381ab64890Smrg	    total -= len;
5391ab64890Smrg	}
5401ab64890Smrg	if (total < min_len)
5411ab64890Smrg	    return p->name;
5421ab64890Smrg
5431ab64890Smrg	if (res->resource_size == XimType_NEST) {
5441ab64890Smrg	    if (res->xrm_name == pre_quark) {
5451ab64890Smrg	        if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num,
5461ab64890Smrg			&buf[2], buf[1], (XIMArg *)p->value,
5471ab64890Smrg			(mode | XIM_PREEDIT_ATTR))))
5481ab64890Smrg		    return name;
5491ab64890Smrg	    } else if (res->xrm_name == sts_quark) {
5501ab64890Smrg	        if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num,
5511ab64890Smrg			&buf[2], buf[1], (XIMArg *)p->value,
5521ab64890Smrg			(mode | XIM_STATUS_ATTR))))
5531ab64890Smrg		    return name;
5541ab64890Smrg	    }
5551ab64890Smrg	} else {
5561ab64890Smrg	    if (!(_XimAttributeToValue(ic, res, &buf[2], buf[1],
5571ab64890Smrg							p->value, mode)))
5581ab64890Smrg		return p->name;
5591ab64890Smrg	}
5601ab64890Smrg    }
5611ab64890Smrg    return (char *)NULL;
5621ab64890Smrg}
5631ab64890Smrg
5641ab64890SmrgPrivate Bool
5651ab64890Smrg_XimValueToAttribute(
5661ab64890Smrg    XIMResourceList	 res,
5671ab64890Smrg    XPointer		 buf,
5681ab64890Smrg    int			 buf_size,
5691ab64890Smrg    XPointer		 value,
5701ab64890Smrg    int			*len,
5711ab64890Smrg    unsigned long	 mode,
5721ab64890Smrg    XPointer		 param)
5731ab64890Smrg{
5741ab64890Smrg    int			 ret_len;
5751ab64890Smrg
5761ab64890Smrg    switch (res->resource_size) {
5771ab64890Smrg    case XimType_SeparatorOfNestedList:
5781ab64890Smrg    case XimType_NEST:
5791ab64890Smrg	*len = 0;
5801ab64890Smrg	break;
5811ab64890Smrg
5821ab64890Smrg    case XimType_CARD8:
5831ab64890Smrg	ret_len = sizeof(CARD8);
5841ab64890Smrg	if (buf_size < ret_len + XIM_PAD(ret_len)) {
5851ab64890Smrg	    *len = -1;
5861ab64890Smrg	    return False;
5871ab64890Smrg	}
5881ab64890Smrg
5891ab64890Smrg	*((CARD8 *)buf) = (CARD8)(long)value;
5901ab64890Smrg	*len = ret_len;
5911ab64890Smrg	break;
5921ab64890Smrg
5931ab64890Smrg    case XimType_CARD16:
5941ab64890Smrg	ret_len = sizeof(CARD16);
5951ab64890Smrg	if (buf_size < ret_len + XIM_PAD(ret_len)) {
5961ab64890Smrg	    *len = -1;
5971ab64890Smrg	    return False;
5981ab64890Smrg	}
5991ab64890Smrg
6001ab64890Smrg	*((CARD16 *)buf) = (CARD16)(long)value;
6011ab64890Smrg	*len = ret_len;
6021ab64890Smrg	break;
6031ab64890Smrg
6041ab64890Smrg    case XimType_CARD32:
6051ab64890Smrg    case XimType_Window:
6061ab64890Smrg    case XimType_XIMHotKeyState:
6071ab64890Smrg	ret_len = sizeof(CARD32);
6081ab64890Smrg	if (buf_size < ret_len + XIM_PAD(ret_len)) {
6091ab64890Smrg	    *len = -1;
6101ab64890Smrg	    return False;
6111ab64890Smrg	}
6121ab64890Smrg
6131ab64890Smrg	*((CARD32 *)buf) = (CARD32)(long)value;
6141ab64890Smrg	*len = ret_len;
6151ab64890Smrg	break;
6161ab64890Smrg
6171ab64890Smrg    case XimType_STRING8:
6181ab64890Smrg	if (!value) {
6191ab64890Smrg	    *len = 0;
6201ab64890Smrg	    return False;
6211ab64890Smrg	}
6221ab64890Smrg
6231ab64890Smrg	ret_len = strlen((char *)value);
6241ab64890Smrg	if (buf_size < ret_len + XIM_PAD(ret_len)) {
6251ab64890Smrg	    *len = -1;
6261ab64890Smrg	    return False;
6271ab64890Smrg	}
6281ab64890Smrg
6291ab64890Smrg	(void)memcpy((char *)buf, (char *)value, ret_len);
6301ab64890Smrg	*len = ret_len;
6311ab64890Smrg	break;
6321ab64890Smrg
6331ab64890Smrg    case XimType_XRectangle:
6341ab64890Smrg	{
6351ab64890Smrg	    XRectangle	*rect = (XRectangle *)value;
6361ab64890Smrg	    CARD16	*buf_s = (CARD16 *)buf;
6371ab64890Smrg
6381ab64890Smrg	    if (!rect) {
6391ab64890Smrg		*len = 0;
6401ab64890Smrg		return False;
6411ab64890Smrg	    }
6421ab64890Smrg
6431ab64890Smrg	    ret_len = sizeof(INT16)		/* sizeof X */
6441ab64890Smrg	    	    + sizeof(INT16)		/* sizeof Y */
6451ab64890Smrg	            + sizeof(CARD16)		/* sizeof width */
6461ab64890Smrg	            + sizeof(CARD16);		/* sizeof height */
6471ab64890Smrg	    if (buf_size < ret_len + XIM_PAD(ret_len)) {
6481ab64890Smrg		*len = -1;
6491ab64890Smrg		return False;
6501ab64890Smrg	    }
6511ab64890Smrg
6521ab64890Smrg	    buf_s[0] = (CARD16)rect->x;		/* X */
6531ab64890Smrg	    buf_s[1] = (CARD16)rect->y;		/* Y */
6541ab64890Smrg	    buf_s[2] = (CARD16)rect->width;	/* width */
6551ab64890Smrg	    buf_s[3] = (CARD16)rect->height;	/* heght */
6561ab64890Smrg	    *len = ret_len;
6571ab64890Smrg	    break;
6581ab64890Smrg	}
6591ab64890Smrg
6601ab64890Smrg    case XimType_XPoint:
6611ab64890Smrg	{
6621ab64890Smrg	    XPoint	*point = (XPoint *)value;
6631ab64890Smrg	    CARD16	*buf_s = (CARD16 *)buf;
6641ab64890Smrg
6651ab64890Smrg	    if (!point) {
6661ab64890Smrg		*len = 0;
6671ab64890Smrg		return False;
6681ab64890Smrg	    }
6691ab64890Smrg
6701ab64890Smrg	    ret_len = sizeof(INT16)		/* sizeof X */
6711ab64890Smrg	            + sizeof(INT16);		/* sizeof Y */
6721ab64890Smrg	    if (buf_size < ret_len + XIM_PAD(ret_len)) {
6731ab64890Smrg		*len = -1;
6741ab64890Smrg		return False;
6751ab64890Smrg	    }
6761ab64890Smrg
6771ab64890Smrg	    buf_s[0] = (CARD16)point->x;		/* X */
6781ab64890Smrg	    buf_s[1] = (CARD16)point->y;		/* Y */
6791ab64890Smrg	    *len = ret_len;
6801ab64890Smrg	    break;
6811ab64890Smrg	}
6821ab64890Smrg
6831ab64890Smrg    case XimType_XFontSet:
6841ab64890Smrg	{
6851ab64890Smrg	    XFontSet	 font = (XFontSet)value;
6861ab64890Smrg	    Xic		 ic = (Xic)param;
6871ab64890Smrg	    char	*base_name = NULL;
6881ab64890Smrg	    int		 length = 0;
6891ab64890Smrg	    CARD16	*buf_s = (CARD16 *)buf;
6901ab64890Smrg
6911ab64890Smrg	    if (!font) {
6921ab64890Smrg		*len = 0;
6931ab64890Smrg		return False;
6941ab64890Smrg	    }
6951ab64890Smrg
6961ab64890Smrg	    if (mode & XIM_PREEDIT_ATTR) {
6971ab64890Smrg		base_name = ic->private.proto.preedit_font;
6981ab64890Smrg		length	  = ic->private.proto.preedit_font_length;
6991ab64890Smrg	    } else if (mode & XIM_STATUS_ATTR) {
7001ab64890Smrg		base_name = ic->private.proto.status_font;
7011ab64890Smrg		length	  = ic->private.proto.status_font_length;
7021ab64890Smrg	    }
7031ab64890Smrg
7041ab64890Smrg	    if (!base_name) {
7051ab64890Smrg		*len = 0;
7061ab64890Smrg		return False;
7071ab64890Smrg	    }
7081ab64890Smrg
7091ab64890Smrg	    ret_len = sizeof(CARD16)		/* sizeof length of Base name */
7101ab64890Smrg		    + length;			/* sizeof Base font name list */
7111ab64890Smrg	    if (buf_size < ret_len + XIM_PAD(ret_len)) {
7121ab64890Smrg		*len = -1;
7131ab64890Smrg		return False;
7141ab64890Smrg	    }
7151ab64890Smrg
7161ab64890Smrg	    buf_s[0] = (INT16)length;		/* length of Base font name */
7171ab64890Smrg	    (void)memcpy((char *)&buf_s[1], base_name, length);
7181ab64890Smrg						/* Base font name list */
7191ab64890Smrg	    *len = ret_len;
7201ab64890Smrg	    break;
7211ab64890Smrg	}
7221ab64890Smrg
7231ab64890Smrg    case XimType_XIMHotKeyTriggers:
7241ab64890Smrg	{
7251ab64890Smrg	    XIMHotKeyTriggers	*hotkey = (XIMHotKeyTriggers *)value;
7261ab64890Smrg	    INT32		 num;
7271ab64890Smrg	    CARD32		*buf_l = (CARD32 *)buf;
7281ab64890Smrg	    register CARD32	*key = (CARD32 *)&buf_l[1];
7291ab64890Smrg	    register int	 i;
7301ab64890Smrg
7311ab64890Smrg	    if (!hotkey) {
7321ab64890Smrg		*len = 0;
7331ab64890Smrg		return False;
7341ab64890Smrg	    }
7351ab64890Smrg	    num = (INT32)hotkey->num_hot_key;
7361ab64890Smrg
7371ab64890Smrg	    ret_len = sizeof(INT32)		/* sizeof number of key list */
7381ab64890Smrg	           + (sizeof(CARD32)		/* sizeof keysyn */
7391ab64890Smrg	           +  sizeof(CARD32)		/* sizeof modifier */
7401ab64890Smrg	           +  sizeof(CARD32))		/* sizeof modifier_mask */
7411ab64890Smrg	           *  num;			/* number of key list */
7421ab64890Smrg	    if (buf_size < ret_len + XIM_PAD(ret_len)) {
7431ab64890Smrg		*len = -1;
7441ab64890Smrg		return False;
7451ab64890Smrg	    }
7461ab64890Smrg
7471ab64890Smrg	    buf_l[0] = num;		/* number of key list */
7481ab64890Smrg	    for (i = 0; i < num; i++, key += 3) {
7491ab64890Smrg		key[0] = (CARD32)(hotkey->key[i].keysym);
7501ab64890Smrg						/* keysym */
7511ab64890Smrg		key[1] = (CARD32)(hotkey->key[i].modifier);
7521ab64890Smrg						/* modifier */
7531ab64890Smrg		key[2] = (CARD32)(hotkey->key[i].modifier_mask);
7541ab64890Smrg						/* modifier_mask */
7551ab64890Smrg	    }
7561ab64890Smrg	    *len = ret_len;
7571ab64890Smrg	    break;
7581ab64890Smrg	}
7591ab64890Smrg
7601ab64890Smrg    case XimType_XIMStringConversion:
7611ab64890Smrg	{
7621ab64890Smrg	    *len = 0;
7631ab64890Smrg	    break;
7641ab64890Smrg	}
7651ab64890Smrg
7661ab64890Smrg    default:
7671ab64890Smrg	return False;
7681ab64890Smrg    }
7691ab64890Smrg    return True;
7701ab64890Smrg}
7711ab64890Smrg
7721ab64890SmrgPrivate Bool
7731ab64890Smrg_XimSetInnerIMAttributes(
7741ab64890Smrg    Xim			 im,
7751ab64890Smrg    XPointer		 top,
7761ab64890Smrg    XIMArg		*arg,
7771ab64890Smrg    unsigned long	 mode)
7781ab64890Smrg{
7791ab64890Smrg    XIMResourceList	 res;
7801ab64890Smrg    int			 check;
7811ab64890Smrg
7821ab64890Smrg    if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
7831ab64890Smrg			im->private.proto.im_num_inner_resources, arg->name)))
7841ab64890Smrg	return False;
7851ab64890Smrg
7861ab64890Smrg    check = _XimCheckIMMode(res, mode);
7871ab64890Smrg    if(check == XIM_CHECK_INVALID)
7881ab64890Smrg	return True;
7891ab64890Smrg    else if(check == XIM_CHECK_ERROR)
7901ab64890Smrg	return False;
7911ab64890Smrg
7921ab64890Smrg    return _XimEncodeLocalIMAttr(res, top, arg->value);
7931ab64890Smrg}
7941ab64890Smrg
7951ab64890SmrgPublic char *
7961ab64890Smrg_XimEncodeIMATTRIBUTE(
7971ab64890Smrg    Xim			  im,
7981ab64890Smrg    XIMResourceList	  res_list,
7991ab64890Smrg    unsigned int	  res_num,
8001ab64890Smrg    XIMArg		 *arg,
8011ab64890Smrg    XIMArg		**arg_ret,
8021ab64890Smrg    char		 *buf,
8031ab64890Smrg    int			  size,
8041ab64890Smrg    int			 *ret_len,
8051ab64890Smrg    XPointer		  top,
8061ab64890Smrg    unsigned long	  mode)
8071ab64890Smrg{
8081ab64890Smrg    register XIMArg	*p;
8091ab64890Smrg    XIMResourceList	 res;
8101ab64890Smrg    int			 check;
8111ab64890Smrg    CARD16		*buf_s;
8121ab64890Smrg    int			 len;
8131ab64890Smrg    int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
8141ab64890Smrg				 + sizeof(INT16); /* sizeof value length */
8151ab64890Smrg
8161ab64890Smrg    *ret_len = 0;
8171ab64890Smrg    for (p = arg; p->name; p++) {
8181ab64890Smrg	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
8191ab64890Smrg	    if (_XimSetInnerIMAttributes(im, top, p, mode))
8201ab64890Smrg		continue;
8211ab64890Smrg	    return p->name;
8221ab64890Smrg	}
8231ab64890Smrg
8241ab64890Smrg	check = _XimCheckIMMode(res, mode);
8251ab64890Smrg	if (check == XIM_CHECK_INVALID)
8261ab64890Smrg	    continue;
8271ab64890Smrg	else if (check == XIM_CHECK_ERROR)
8281ab64890Smrg	    return p->name;
8291ab64890Smrg
8301ab64890Smrg	if (!(_XimEncodeLocalIMAttr(res, top, p->value)))
8311ab64890Smrg	    return p->name;
8321ab64890Smrg
8331ab64890Smrg	buf_s = (CARD16 *)buf;
8341ab64890Smrg	if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2], (size - min_len),
8351ab64890Smrg				p->value, &len, mode, (XPointer)NULL)))
8361ab64890Smrg	    return p->name;
8371ab64890Smrg
8381ab64890Smrg	if (len == 0) {
8391ab64890Smrg	    continue;
8401ab64890Smrg	} else if (len < 0) {
8411ab64890Smrg	    *arg_ret = p;
8421ab64890Smrg	    return (char *)NULL;
8431ab64890Smrg	}
8441ab64890Smrg
8451ab64890Smrg	buf_s[0] = res->id;			/* attribute ID */
8461ab64890Smrg	buf_s[1] = len;				/* value length */
8471ab64890Smrg	XIM_SET_PAD(&buf_s[2], len);		/* pad */
8481ab64890Smrg	len += min_len;
8491ab64890Smrg
8501ab64890Smrg	buf += len;
8511ab64890Smrg	*ret_len += len;
8521ab64890Smrg	size -= len;
8531ab64890Smrg    }
8541ab64890Smrg    *arg_ret = (XIMArg *)NULL;
8551ab64890Smrg    return (char *)NULL;
8561ab64890Smrg}
8571ab64890Smrg
8581ab64890Smrg#ifdef XIM_CONNECTABLE
8591ab64890SmrgPublic	Bool
8601ab64890Smrg_XimEncodeSavedIMATTRIBUTE(
8611ab64890Smrg    Xim			 im,
8621ab64890Smrg    XIMResourceList	 res_list,
8631ab64890Smrg    unsigned int	 res_num,
8641ab64890Smrg    int			*idx,
8651ab64890Smrg    char		*buf,
8661ab64890Smrg    int			 size,
8671ab64890Smrg    int			*ret_len,
8681ab64890Smrg    XPointer		 top,
8691ab64890Smrg    unsigned long	 mode)
8701ab64890Smrg{
8711ab64890Smrg    register int	 i;
8721ab64890Smrg    int			 num = im->private.proto.num_saved_imvalues;
8731ab64890Smrg    XrmQuark		*quark_list = im->private.proto.saved_imvalues;
8741ab64890Smrg    XIMResourceList	 res;
8751ab64890Smrg    XPointer		 value;
8761ab64890Smrg    CARD16		*buf_s;
8771ab64890Smrg    int			 len;
8781ab64890Smrg    int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
8791ab64890Smrg				 + sizeof(INT16); /* sizeof value length */
8801ab64890Smrg
8811ab64890Smrg    if (!im->private.proto.saved_imvalues) {
8821ab64890Smrg	*idx = -1;
8831ab64890Smrg	*ret_len = 0;
8841ab64890Smrg	return True;
8851ab64890Smrg    }
8861ab64890Smrg
8871ab64890Smrg    *ret_len = 0;
8881ab64890Smrg    for (i = *idx; i < num; i++) {
8891ab64890Smrg	if (!(res = _XimGetResourceListRecByQuark(res_list,
8901ab64890Smrg						res_num, quark_list[i])))
8911ab64890Smrg	    continue;
8921ab64890Smrg
8931ab64890Smrg	if (!_XimDecodeLocalIMAttr(res, top, value))
8941ab64890Smrg	    return False;
8951ab64890Smrg
8961ab64890Smrg	buf_s = (CARD16 *)buf;
8971ab64890Smrg	if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
8981ab64890Smrg			(size - min_len), value, &len, mode, (XPointer)NULL)))
8991ab64890Smrg	    return False;
9001ab64890Smrg
9011ab64890Smrg	if (len == 0) {
9021ab64890Smrg	    continue;
9031ab64890Smrg	} else if (len < 0) {
9041ab64890Smrg	    *idx = i;
9051ab64890Smrg	    return True;
9061ab64890Smrg	}
9071ab64890Smrg
9081ab64890Smrg	buf_s[0] = res->id;			/* attribute ID */
9091ab64890Smrg	buf_s[1] = len;				/* value length */
9101ab64890Smrg	XIM_SET_PAD(&buf_s[2], len);		/* pad */
9111ab64890Smrg	len += min_len;
9121ab64890Smrg
9131ab64890Smrg	buf += len;
9141ab64890Smrg	*ret_len += len;
9151ab64890Smrg	size -= len;
9161ab64890Smrg    }
9171ab64890Smrg    *idx = -1;
9181ab64890Smrg    return True;
9191ab64890Smrg}
9201ab64890Smrg#endif /* XIM_CONNECTABLE */
9211ab64890Smrg
9221ab64890SmrgPrivate Bool
9231ab64890Smrg_XimEncodeTopValue(
9241ab64890Smrg    Xic			 ic,
9251ab64890Smrg    XIMResourceList	 res,
9261ab64890Smrg    XIMArg		*p)
9271ab64890Smrg{
9281ab64890Smrg    if (res->xrm_name == XrmStringToQuark(XNClientWindow)) {
9291ab64890Smrg	ic->core.client_window = (Window)p->value;
9301ab64890Smrg	if (ic->core.focus_window == (Window)0)
9311ab64890Smrg	    ic->core.focus_window = ic->core.client_window;
9321ab64890Smrg	_XimRegisterFilter(ic);
9331ab64890Smrg
9341ab64890Smrg    } else if (res->xrm_name == XrmStringToQuark(XNFocusWindow)) {
9351ab64890Smrg	if (ic->core.client_window) {
9361ab64890Smrg	    _XimUnregisterFilter(ic);
9371ab64890Smrg	    ic->core.focus_window = (Window)p->value;
9381ab64890Smrg	    _XimRegisterFilter(ic);
9391ab64890Smrg	} else /* client_window not yet */
9401ab64890Smrg	    ic->core.focus_window = (Window)p->value;
9411ab64890Smrg    }
9421ab64890Smrg    return True;
9431ab64890Smrg}
9441ab64890Smrg
9451ab64890SmrgPrivate Bool
9461ab64890Smrg_XimEncodePreeditValue(
9471ab64890Smrg    Xic			 ic,
9481ab64890Smrg    XIMResourceList	 res,
9491ab64890Smrg    XIMArg		*p)
9501ab64890Smrg{
9511ab64890Smrg    if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
9521ab64890Smrg	XStandardColormap	*colormap_ret;
9531ab64890Smrg	int			 count;
9541ab64890Smrg
9551ab64890Smrg	if (!(XGetRGBColormaps(ic->core.im->core.display,
9561ab64890Smrg				ic->core.focus_window, &colormap_ret,
9571ab64890Smrg				&count, (Atom)p->value)))
9581ab64890Smrg	    return False;
9591ab64890Smrg
96057f47464Smrg	XFree(colormap_ret);
9611ab64890Smrg    } else if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
9621ab64890Smrg	int		  list_ret;
9631ab64890Smrg	XFontStruct	**struct_list;
9641ab64890Smrg	char		**name_list;
9651ab64890Smrg	char		 *tmp;
9661ab64890Smrg	int		  len;
9671ab64890Smrg	register int	  i;
9681ab64890Smrg
9691ab64890Smrg	if (!p->value)
9701ab64890Smrg	    return False;
9711ab64890Smrg
9721ab64890Smrg	if (ic->private.proto.preedit_font)
9731ab64890Smrg	    Xfree(ic->private.proto.preedit_font);
9741ab64890Smrg
9751ab64890Smrg	list_ret = XFontsOfFontSet((XFontSet)p->value,
9761ab64890Smrg						 &struct_list, &name_list);
9771ab64890Smrg	for (i = 0, len = 0; i < list_ret; i++) {
9781ab64890Smrg	     len += (strlen(name_list[i]) + sizeof(char));
9791ab64890Smrg	}
9801ab64890Smrg	if (!(tmp = Xmalloc(len + 1))) {
9811ab64890Smrg	    ic->private.proto.preedit_font = NULL;
9821ab64890Smrg	    return False;
9831ab64890Smrg	}
9841ab64890Smrg
9851ab64890Smrg	tmp[0] = '\0';
9861ab64890Smrg	for (i = 0; i < list_ret; i++) {
9871ab64890Smrg	    strcat(tmp, name_list[i]);
9881ab64890Smrg	    strcat(tmp, ",");
9891ab64890Smrg	}
9901ab64890Smrg	tmp[len - 1] = 0;
9911ab64890Smrg	ic->private.proto.preedit_font        = tmp;
9921ab64890Smrg	ic->private.proto.preedit_font_length = len - 1;
9931ab64890Smrg    }
9941ab64890Smrg    return True;
9951ab64890Smrg}
9961ab64890Smrg
9971ab64890SmrgPrivate Bool
9981ab64890Smrg_XimEncodeStatusValue(
9991ab64890Smrg    Xic			 ic,
10001ab64890Smrg    XIMResourceList	 res,
10011ab64890Smrg    XIMArg		*p)
10021ab64890Smrg{
10031ab64890Smrg    if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
100457f47464Smrg	XStandardColormap	*colormap_ret = NULL;
10051ab64890Smrg	int			 count;
10061ab64890Smrg
10071ab64890Smrg	if (!(XGetRGBColormaps(ic->core.im->core.display,
10081ab64890Smrg				ic->core.focus_window, &colormap_ret,
10091ab64890Smrg				&count, (Atom)p->value)))
10101ab64890Smrg	    return False;
10111ab64890Smrg
101257f47464Smrg	XFree(colormap_ret);
10131ab64890Smrg    } else if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
10141ab64890Smrg	int		  list_ret;
10151ab64890Smrg	XFontStruct	**struct_list;
10161ab64890Smrg	char		**name_list;
10171ab64890Smrg	char		 *tmp;
10181ab64890Smrg	int		  len;
10191ab64890Smrg	register int	  i;
10201ab64890Smrg
10211ab64890Smrg	if (!p->value)
10221ab64890Smrg	    return False;
10231ab64890Smrg
10241ab64890Smrg	if (ic->private.proto.status_font)
10251ab64890Smrg	    Xfree(ic->private.proto.status_font);
10261ab64890Smrg
10271ab64890Smrg	list_ret = XFontsOfFontSet((XFontSet)p->value,
10281ab64890Smrg						 &struct_list, &name_list);
10291ab64890Smrg	for (i = 0, len = 0; i < list_ret; i++) {
10301ab64890Smrg	     len += (strlen(name_list[i]) + sizeof(char));
10311ab64890Smrg	}
10321ab64890Smrg	if (!(tmp = Xmalloc(len+1))) {
10331ab64890Smrg	    ic->private.proto.status_font = NULL;
10341ab64890Smrg	    return False;
10351ab64890Smrg	}
10361ab64890Smrg
10371ab64890Smrg	tmp[0] = '\0';
10381ab64890Smrg	for(i = 0; i < list_ret; i++) {
10391ab64890Smrg	    strcat(tmp, name_list[i]);
10401ab64890Smrg	    strcat(tmp, ",");
10411ab64890Smrg	}
10421ab64890Smrg	tmp[len - 1] = 0;
10431ab64890Smrg	ic->private.proto.status_font        = tmp;
10441ab64890Smrg	ic->private.proto.status_font_length = len - 1;
10451ab64890Smrg    }
10461ab64890Smrg    return True;
10471ab64890Smrg}
10481ab64890Smrg
10491ab64890SmrgPrivate Bool
10501ab64890Smrg_XimSetInnerICAttributes(
10511ab64890Smrg    Xic			 ic,
10521ab64890Smrg    XPointer		 top,
10531ab64890Smrg    XIMArg		*arg,
10541ab64890Smrg    unsigned long	 mode)
10551ab64890Smrg{
10561ab64890Smrg    XIMResourceList	 res;
10571ab64890Smrg    int			 check;
10581ab64890Smrg
10591ab64890Smrg    if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
10601ab64890Smrg			ic->private.proto.ic_num_inner_resources, arg->name)))
10611ab64890Smrg	return False;
10621ab64890Smrg
10631ab64890Smrg    check = _XimCheckICMode(res, mode);
10641ab64890Smrg    if(check == XIM_CHECK_INVALID)
10651ab64890Smrg	return True;
10661ab64890Smrg    else if(check == XIM_CHECK_ERROR)
10671ab64890Smrg	return False;
10681ab64890Smrg
10691ab64890Smrg    return _XimEncodeLocalICAttr(ic, res, top, arg, mode);
10701ab64890Smrg}
10711ab64890Smrg
10721ab64890SmrgPublic char *
10731ab64890Smrg_XimEncodeICATTRIBUTE(
10741ab64890Smrg    Xic			  ic,
10751ab64890Smrg    XIMResourceList	  res_list,
10761ab64890Smrg    unsigned int	  res_num,
10771ab64890Smrg    XIMArg		 *arg,
10781ab64890Smrg    XIMArg		**arg_ret,
10791ab64890Smrg    char		 *buf,
10801ab64890Smrg    int			  size,
10811ab64890Smrg    int			 *ret_len,
10821ab64890Smrg    XPointer		  top,
10831ab64890Smrg    BITMASK32		 *flag,
10841ab64890Smrg    unsigned long	  mode)
10851ab64890Smrg{
10861ab64890Smrg    register XIMArg	*p;
10871ab64890Smrg    XIMResourceList	 res;
10881ab64890Smrg    int			 check;
10891ab64890Smrg    CARD16		*buf_s;
10901ab64890Smrg    int			 len;
10911ab64890Smrg    int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
10921ab64890Smrg				 + sizeof(INT16); /* sizeof value length */
10931ab64890Smrg    XrmQuark		 pre_quark;
10941ab64890Smrg    XrmQuark		 sts_quark;
10951ab64890Smrg    char		*name;
10961ab64890Smrg
10971ab64890Smrg    pre_quark = XrmStringToQuark(XNPreeditAttributes);
10981ab64890Smrg    sts_quark = XrmStringToQuark(XNStatusAttributes);
10991ab64890Smrg
11001ab64890Smrg    *ret_len = 0;
11011ab64890Smrg    for (p = arg; p && p->name; p++) {
11021ab64890Smrg	buf_s = (CARD16 *)buf;
11031ab64890Smrg	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
11041ab64890Smrg	    if (_XimSetInnerICAttributes(ic, top, p, mode))
11051ab64890Smrg		continue;
11061ab64890Smrg	    return p->name;
11071ab64890Smrg	}
11081ab64890Smrg
11091ab64890Smrg	check = _XimCheckICMode(res, mode);
11101ab64890Smrg	if (check == XIM_CHECK_INVALID)
11111ab64890Smrg	    continue;
11121ab64890Smrg	else if (check == XIM_CHECK_ERROR)
11131ab64890Smrg	    return p->name;
11141ab64890Smrg
11151ab64890Smrg	if (mode & XIM_PREEDIT_ATTR) {
11161ab64890Smrg	    if (!(_XimEncodePreeditValue(ic, res, p)))
11171ab64890Smrg		return p->name;
11181ab64890Smrg	} else if (mode & XIM_STATUS_ATTR) {
11191ab64890Smrg	    if (!(_XimEncodeStatusValue(ic, res, p)))
11201ab64890Smrg		return p->name;
11211ab64890Smrg	} else {
11221ab64890Smrg	    if (!(_XimEncodeTopValue(ic, res, p)))
11231ab64890Smrg		return p->name;
11241ab64890Smrg	}
11251ab64890Smrg
11261ab64890Smrg	if (res->resource_size == XimType_NEST) {
11271ab64890Smrg	    XimDefICValues	*ic_attr = (XimDefICValues *)top;
11281ab64890Smrg
11291ab64890Smrg	    if (res->xrm_name == pre_quark) {
11301ab64890Smrg		XIMArg		*arg_rt;
11311ab64890Smrg		if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
11321ab64890Smrg				(XIMArg *)p->value, &arg_rt,
11331ab64890Smrg				(char *)&buf_s[2], (size - min_len),
11341ab64890Smrg				 &len, (XPointer)&ic_attr->preedit_attr, flag,
11351ab64890Smrg				(mode | XIM_PREEDIT_ATTR)))) {
11361ab64890Smrg		    return name;
11371ab64890Smrg		}
11381ab64890Smrg
11391ab64890Smrg	    } else if (res->xrm_name == sts_quark) {
11401ab64890Smrg		XIMArg		*arg_rt;
11411ab64890Smrg		if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
11421ab64890Smrg				(XIMArg *)p->value,  &arg_rt,
11431ab64890Smrg				(char *)&buf_s[2], (size - min_len),
11441ab64890Smrg				 &len, (XPointer)&ic_attr->status_attr, flag,
11451ab64890Smrg				(mode | XIM_STATUS_ATTR)))) {
11461ab64890Smrg		    return name;
11471ab64890Smrg		}
11481ab64890Smrg	    }
11491ab64890Smrg	} else {
11501ab64890Smrg#ifdef EXT_MOVE
11511ab64890Smrg	    if (flag)
11521ab64890Smrg		*flag |= _XimExtenArgCheck(p);
11531ab64890Smrg#endif
11541ab64890Smrg    	    if (!(_XimEncodeLocalICAttr(ic, res, top, p, mode)))
11551ab64890Smrg		return p->name;
11561ab64890Smrg
11571ab64890Smrg	    if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
11581ab64890Smrg			 	(size - min_len), p->value,
11591ab64890Smrg				&len, mode, (XPointer)ic)))
11601ab64890Smrg		return p->name;
11611ab64890Smrg	}
11621ab64890Smrg
11631ab64890Smrg	if (len == 0) {
11641ab64890Smrg	    continue;
11651ab64890Smrg	} else if (len < 0) {
11661ab64890Smrg	    *arg_ret = p;
11671ab64890Smrg	    return (char *)NULL;
11681ab64890Smrg	}
11691ab64890Smrg
11701ab64890Smrg	buf_s[0] = res->id;			/* attribute ID */
11711ab64890Smrg	buf_s[1] = len;				/* value length */
11721ab64890Smrg	XIM_SET_PAD(&buf_s[2], len);		/* pad */
11731ab64890Smrg	len += min_len;
11741ab64890Smrg
11751ab64890Smrg	buf += len;
11761ab64890Smrg	*ret_len += len;
11771ab64890Smrg	size -= len;
11781ab64890Smrg    }
11791ab64890Smrg    *arg_ret = (XIMArg *)NULL;
11801ab64890Smrg    return (char *)NULL;
11811ab64890Smrg}
11821ab64890Smrg
11831ab64890Smrg#ifdef XIM_CONNECTABLE
11841ab64890SmrgPrivate Bool
11851ab64890Smrg_XimEncodeSavedPreeditValue(
11861ab64890Smrg    Xic			  ic,
11871ab64890Smrg    XIMResourceList	  res,
11881ab64890Smrg    XPointer		  value)
11891ab64890Smrg{
11901ab64890Smrg    int			  list_ret;
11911ab64890Smrg    XFontStruct		**struct_list;
11921ab64890Smrg    char		**name_list;
11931ab64890Smrg    char		 *tmp;
11941ab64890Smrg    int			  len;
11951ab64890Smrg    register int	  i;
11961ab64890Smrg
11971ab64890Smrg    if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
11981ab64890Smrg	if (!value)
11991ab64890Smrg	    return False;
12001ab64890Smrg
12011ab64890Smrg	if (ic->private.proto.preedit_font)
12021ab64890Smrg	    Xfree(ic->private.proto.preedit_font);
12031ab64890Smrg
12041ab64890Smrg	list_ret = XFontsOfFontSet((XFontSet)value,
12051ab64890Smrg						&struct_list, &name_list);
12061ab64890Smrg	for(i = 0, len = 0; i < list_ret; i++) {
12071ab64890Smrg	    len += (strlen(name_list[i]) + sizeof(char));
12081ab64890Smrg	}
12091ab64890Smrg	if(!(tmp = Xmalloc(len + 1))) {
12101ab64890Smrg	    ic->private.proto.preedit_font = NULL;
12111ab64890Smrg	    return False;
12121ab64890Smrg	}
12131ab64890Smrg
12141ab64890Smrg	tmp[0] = '\0';
12151ab64890Smrg	for(i = 0; i < list_ret; i++) {
12161ab64890Smrg	    strcat(tmp, name_list[i]);
12171ab64890Smrg	    strcat(tmp, ",");
12181ab64890Smrg	}
12191ab64890Smrg	tmp[len - 1] = 0;
12201ab64890Smrg	ic->private.proto.preedit_font        = tmp;
12211ab64890Smrg	ic->private.proto.preedit_font_length = len - 1;
12221ab64890Smrg    }
12231ab64890Smrg    return True;
12241ab64890Smrg}
12251ab64890Smrg
12261ab64890SmrgPrivate Bool
12271ab64890Smrg_XimEncodeSavedStatusValue(
12281ab64890Smrg    Xic			  ic,
12291ab64890Smrg    XIMResourceList	  res,
12301ab64890Smrg    XPointer		  value)
12311ab64890Smrg{
12321ab64890Smrg    int			  list_ret;
12331ab64890Smrg    XFontStruct		**struct_list;
12341ab64890Smrg    char		**name_list;
12351ab64890Smrg    char		 *tmp;
12361ab64890Smrg    int			  len;
12371ab64890Smrg    register int	  i;
12381ab64890Smrg
12391ab64890Smrg    if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
12401ab64890Smrg	if (!value)
12411ab64890Smrg	    return False;
12421ab64890Smrg
12431ab64890Smrg	if (ic->private.proto.status_font)
12441ab64890Smrg	    Xfree(ic->private.proto.status_font);
12451ab64890Smrg
12461ab64890Smrg	list_ret = XFontsOfFontSet((XFontSet)value,
12471ab64890Smrg						&struct_list, &name_list);
12481ab64890Smrg	for(i = 0, len = 0; i < list_ret; i++) {
12491ab64890Smrg	    len += (strlen(name_list[i]) + sizeof(char));
12501ab64890Smrg	}
12511ab64890Smrg	if(!(tmp = Xmalloc(len + 1))) {
12521ab64890Smrg	    ic->private.proto.status_font = NULL;
12531ab64890Smrg	    return False;
12541ab64890Smrg	}
12551ab64890Smrg
12561ab64890Smrg	tmp[0] = '\0';
12571ab64890Smrg	for(i = 0; i < list_ret; i++) {
12581ab64890Smrg	    strcat(tmp, name_list[i]);
12591ab64890Smrg	    strcat(tmp, ",");
12601ab64890Smrg	}
12611ab64890Smrg	tmp[len - 1] = 0;
12621ab64890Smrg	ic->private.proto.status_font        = tmp;
12631ab64890Smrg	ic->private.proto.status_font_length = len - 1;
12641ab64890Smrg    }
12651ab64890Smrg    return True;
12661ab64890Smrg}
12671ab64890Smrg
12681ab64890SmrgPublic	Bool
12691ab64890Smrg_XimEncodeSavedICATTRIBUTE(
12701ab64890Smrg    Xic			 ic,
12711ab64890Smrg    XIMResourceList	 res_list,
12721ab64890Smrg    unsigned int	 res_num,
12731ab64890Smrg    int			*idx,
12741ab64890Smrg    char		*buf,
12751ab64890Smrg    int			 size,
12761ab64890Smrg    int			*ret_len,
12771ab64890Smrg    XPointer		 top,
12781ab64890Smrg    unsigned long	 mode)
12791ab64890Smrg{
12801ab64890Smrg    int			 i;
12811ab64890Smrg    int			 num = ic->private.proto.num_saved_icvalues;
12821ab64890Smrg    XrmQuark		*quark_list = ic->private.proto.saved_icvalues;
12831ab64890Smrg    XIMResourceList	 res;
12841ab64890Smrg    XPointer		 value;
12851ab64890Smrg    CARD16		*buf_s;
12861ab64890Smrg    int			 len;
12871ab64890Smrg    int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
12881ab64890Smrg				 + sizeof(INT16); /* sizeof value length */
12891ab64890Smrg    XrmQuark		 pre_quark;
12901ab64890Smrg    XrmQuark		 sts_quark;
12911ab64890Smrg    XrmQuark		 separator;
12921ab64890Smrg
12931ab64890Smrg    if (!ic->private.proto.saved_icvalues) {
12941ab64890Smrg	*idx = -1;
12951ab64890Smrg	*ret_len = 0;
12961ab64890Smrg	return True;
12971ab64890Smrg    }
12981ab64890Smrg
12991ab64890Smrg    pre_quark = XrmStringToQuark(XNPreeditAttributes);
13001ab64890Smrg    sts_quark = XrmStringToQuark(XNStatusAttributes);
13011ab64890Smrg    separator = XrmStringToQuark(XNSeparatorofNestedList);
13021ab64890Smrg
13031ab64890Smrg    *ret_len = 0;
13041ab64890Smrg    for (i = *idx; i < num; i++) {
13051ab64890Smrg	if (quark_list[i] == separator) {
13061ab64890Smrg	    *idx = i;
13071ab64890Smrg	    return True;
13081ab64890Smrg	}
13091ab64890Smrg
13101ab64890Smrg	if (!(res = _XimGetResourceListRecByQuark(res_list,
13111ab64890Smrg						res_num, quark_list[i])))
13121ab64890Smrg	    continue;
13131ab64890Smrg
13141ab64890Smrg	if (!_XimDecodeLocalICAttr(res, top,(XPointer)&value, mode))
13151ab64890Smrg	    return False;
13161ab64890Smrg
13171ab64890Smrg	if (mode & XIM_PREEDIT_ATTR) {
13181ab64890Smrg	    if (!(_XimEncodeSavedPreeditValue(ic, res, value))) {
13191ab64890Smrg		return False;
13201ab64890Smrg	    }
13211ab64890Smrg	} else if (mode & XIM_STATUS_ATTR) {
13221ab64890Smrg	    if (!(_XimEncodeSavedStatusValue(ic, res, value))) {
13231ab64890Smrg		return False;
13241ab64890Smrg	    }
13251ab64890Smrg	}
13261ab64890Smrg
13271ab64890Smrg	buf_s = (CARD16 *)buf;
13281ab64890Smrg	if (res->resource_size == XimType_NEST) {
13291ab64890Smrg	    XimDefICValues	*ic_attr = (XimDefICValues *)top;
13301ab64890Smrg
13311ab64890Smrg	    i++;
13321ab64890Smrg	    if (res->xrm_name == pre_quark) {
13331ab64890Smrg		if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
13341ab64890Smrg				 &i, (char *)&buf_s[2], (size - min_len),
13351ab64890Smrg				 &len, (XPointer)&ic_attr->preedit_attr,
13361ab64890Smrg				(mode | XIM_PREEDIT_ATTR))) {
13371ab64890Smrg		    return False;
13381ab64890Smrg		}
13391ab64890Smrg
13401ab64890Smrg	    } else if (res->xrm_name == sts_quark) {
13411ab64890Smrg		if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
13421ab64890Smrg				&i, (char *)&buf_s[2], (size - min_len),
13431ab64890Smrg				&len, (XPointer)&ic_attr->status_attr,
13441ab64890Smrg				(mode | XIM_STATUS_ATTR))) {
13451ab64890Smrg		    return False;
13461ab64890Smrg		}
13471ab64890Smrg	    }
13481ab64890Smrg	} else {
13491ab64890Smrg	    if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
13501ab64890Smrg			 	(size - min_len), value,
13511ab64890Smrg				&len, mode, (XPointer)ic))) {
13521ab64890Smrg		return False;
13531ab64890Smrg	    }
13541ab64890Smrg	}
13551ab64890Smrg
13561ab64890Smrg	if (len == 0) {
13571ab64890Smrg	    continue;
13581ab64890Smrg	} else if (len < 0) {
13591ab64890Smrg	    if (quark_list[i] == separator)
13601ab64890Smrg		i++;
13611ab64890Smrg	    *idx = i;
13621ab64890Smrg	    return True;
13631ab64890Smrg	}
13641ab64890Smrg
13651ab64890Smrg	buf_s[0] = res->id;			/* attribute ID */
13661ab64890Smrg	buf_s[1] = len;				/* value length */
13671ab64890Smrg	XIM_SET_PAD(&buf_s[2], len);		/* pad */
13681ab64890Smrg	len += min_len;
13691ab64890Smrg
13701ab64890Smrg	buf += len;
13711ab64890Smrg	*ret_len += len;
13721ab64890Smrg	size -= len;
13731ab64890Smrg    }
13741ab64890Smrg    *idx = -1;
13751ab64890Smrg    return True;
13761ab64890Smrg}
13771ab64890Smrg#endif /* XIM_CONNECTABLE */
13781ab64890Smrg
13791ab64890SmrgPrivate unsigned int
13801ab64890Smrg_XimCountNumberOfAttr(
13811ab64890Smrg    INT16	 total,
13821ab64890Smrg    CARD16	*attr,
13831ab64890Smrg    int		*names_len)
13841ab64890Smrg{
13851ab64890Smrg    unsigned int n;
13861ab64890Smrg    INT16	 len;
13871ab64890Smrg    INT16	 min_len = sizeof(CARD16)	/* sizeof attrinute ID */
13881ab64890Smrg			 + sizeof(CARD16)	/* sizeof type of value */
13891ab64890Smrg			 + sizeof(INT16);	/* sizeof length of attribute */
13901ab64890Smrg
13911ab64890Smrg    n = 0;
13921ab64890Smrg    *names_len = 0;
13931ab64890Smrg    while (total > min_len) {
13941ab64890Smrg	len = attr[2];
13951ab64890Smrg	*names_len += (len + 1);
13961ab64890Smrg	len += (min_len + XIM_PAD(len + 2));
13971ab64890Smrg	total -= len;
13981ab64890Smrg	attr = (CARD16 *)((char *)attr + len);
13991ab64890Smrg	n++;
14001ab64890Smrg    }
14011ab64890Smrg    return n;
14021ab64890Smrg}
14031ab64890Smrg
14041ab64890SmrgPublic Bool
14051ab64890Smrg_XimGetAttributeID(
14061ab64890Smrg    Xim			  im,
14071ab64890Smrg    CARD16		 *buf)
14081ab64890Smrg{
14091ab64890Smrg    unsigned int	  n;
14101ab64890Smrg    XIMResourceList	  res;
14111ab64890Smrg    int			  res_len;
14121ab64890Smrg    char		 *names;
14131ab64890Smrg    int			  names_len;
14141ab64890Smrg    XPointer		  tmp;
14151ab64890Smrg    XIMValuesList	 *values_list;
14161ab64890Smrg    char		**values;
14171ab64890Smrg    int			  values_len;
14181ab64890Smrg    register int	  i;
14191ab64890Smrg    INT16		  len;
14201ab64890Smrg    INT16		  min_len = sizeof(CARD16) /* sizeof attrinute ID */
14211ab64890Smrg				  + sizeof(CARD16) /* sizeof type of value */
14221ab64890Smrg				  + sizeof(INT16); /* sizeof length of attr */
14231ab64890Smrg    /*
14241ab64890Smrg     * IM attribute ID
14251ab64890Smrg     */
14261ab64890Smrg
14271ab64890Smrg    if (!(n = _XimCountNumberOfAttr(buf[0], &buf[1], &names_len)))
14281ab64890Smrg	return False;
14291ab64890Smrg    res_len = sizeof(XIMResource) * n;
14301ab64890Smrg
14311ab64890Smrg    if (!(res = (XIMResourceList)Xmalloc(res_len)))
14321ab64890Smrg	return False;
14331ab64890Smrg    bzero((char *)res, res_len);
14341ab64890Smrg
14351ab64890Smrg    values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
14361ab64890Smrg    if (!(tmp = (XPointer)Xmalloc(values_len)))
14371ab64890Smrg	return False;
14381ab64890Smrg    bzero(tmp, values_len);
14391ab64890Smrg
14401ab64890Smrg    values_list = (XIMValuesList *)tmp;
14411ab64890Smrg    values = (char **)((char *)tmp + sizeof(XIMValuesList));
14421ab64890Smrg    names = (char *)((char *)values + (sizeof(char **) * n));
14431ab64890Smrg
14441ab64890Smrg    values_list->count_values = n;
14451ab64890Smrg    values_list->supported_values = values;
14461ab64890Smrg
14471ab64890Smrg    buf++;
14481ab64890Smrg    for (i = 0; i < n; i++) {
14491ab64890Smrg	len = buf[2];
14501ab64890Smrg	(void)memcpy(names, (char *)&buf[3], len);
14511ab64890Smrg	values[i] = names;
14521ab64890Smrg	names[len] = '\0';
14531ab64890Smrg	res[i].resource_name = names;
14541ab64890Smrg	res[i].resource_size = buf[1];
14551ab64890Smrg	res[i].id	     = buf[0];
14561ab64890Smrg	names += (len + 1);
14571ab64890Smrg	len += (min_len + XIM_PAD(len + 2));
14581ab64890Smrg	buf = (CARD16 *)((char *)buf + len);
14591ab64890Smrg    }
14601ab64890Smrg    _XIMCompileResourceList(res, n);
14611ab64890Smrg
14621ab64890Smrg    if (im->core.im_resources)
14631ab64890Smrg	Xfree(im->core.im_resources);
14641ab64890Smrg    if (im->core.im_values_list)
14651ab64890Smrg	Xfree(im->core.im_values_list);
14661ab64890Smrg    im->core.im_resources     = res;
14671ab64890Smrg    im->core.im_num_resources = n;
14681ab64890Smrg    im->core.im_values_list   = values_list;
14691ab64890Smrg
14701ab64890Smrg    /*
14711ab64890Smrg     * IC attribute ID
14721ab64890Smrg     */
14731ab64890Smrg
14741ab64890Smrg    if (!(n = _XimCountNumberOfAttr(buf[0], &buf[2], &names_len)))
14751ab64890Smrg	return False;
14761ab64890Smrg    res_len = sizeof(XIMResource) * n;
14771ab64890Smrg
14781ab64890Smrg    if (!(res = (XIMResourceList)Xmalloc(res_len)))
14791ab64890Smrg	return False;
14801ab64890Smrg    bzero((char *)res, res_len);
14811ab64890Smrg
14821ab64890Smrg    values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
14831ab64890Smrg    if (!(tmp = (XPointer)Xmalloc(values_len)))
14841ab64890Smrg	return False;
14851ab64890Smrg    bzero(tmp, values_len);
14861ab64890Smrg
14871ab64890Smrg    values_list = (XIMValuesList *)tmp;
14881ab64890Smrg    values = (char **)((char *)tmp + sizeof(XIMValuesList));
14891ab64890Smrg    names = (char *)((char *)values + (sizeof(char **) * n));
14901ab64890Smrg
14911ab64890Smrg    values_list->count_values = n;
14921ab64890Smrg    values_list->supported_values = values;
14931ab64890Smrg
14941ab64890Smrg    buf += 2;
14951ab64890Smrg    for (i = 0; i < n; i++) {
14961ab64890Smrg	len = buf[2];
14971ab64890Smrg	(void)memcpy(names, (char *)&buf[3], len);
14981ab64890Smrg	values[i] = names;
14991ab64890Smrg	names[len] = '\0';
15001ab64890Smrg	res[i].resource_name = names;
15011ab64890Smrg	res[i].resource_size = buf[1];
15021ab64890Smrg	res[i].id	     = buf[0];
15031ab64890Smrg	names += (len + 1);
15041ab64890Smrg	len += (min_len + XIM_PAD(len + 2));
15051ab64890Smrg	buf = (CARD16 *)((char *)buf + len);
15061ab64890Smrg    }
15071ab64890Smrg    _XIMCompileResourceList(res, n);
15081ab64890Smrg
15091ab64890Smrg    if (im->core.ic_resources)
15101ab64890Smrg	Xfree(im->core.ic_resources);
15111ab64890Smrg    if (im->core.ic_values_list)
15121ab64890Smrg	Xfree(im->core.ic_values_list);
15131ab64890Smrg    im->core.ic_resources     = res;
15141ab64890Smrg    im->core.ic_num_resources = n;
15151ab64890Smrg    im->core.ic_values_list   = values_list;
15161ab64890Smrg
15171ab64890Smrg    return True;
15181ab64890Smrg}
1519