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