imRmAttr.c revision 9c019ec5
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
329c019ec5Smaya#include <limits.h>
339c019ec5Smaya
341ab64890Smrg#include "Xlibint.h"
351ab64890Smrg#include "Xlcint.h"
361ab64890Smrg#include "Ximint.h"
371ab64890Smrg
381ab64890Smrg
39eb411b4bSmrgstatic 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
47eb411b4bSmrgstatic 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
69eb411b4bSmrgchar *
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
107eb411b4bSmrgstatic 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
129eb411b4bSmrgchar *
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		}
182eb411b4bSmrg		*len += new_len;
183eb411b4bSmrg		buf = (CARD16 *)((char *)buf + new_len);
1841ab64890Smrg	    } else if (res->xrm_name == sts_quark) {
1851ab64890Smrg		if ((name = _XimMakeICAttrIDList(ic, res_list, res_num,
1861ab64890Smrg				(XIMArg *)p->value, buf, &new_len,
1871ab64890Smrg				(mode | XIM_STATUS_ATTR)))) {
1881ab64890Smrg		    if (new_len < 0) *len = -1;
1891ab64890Smrg		    else *len += new_len;
1901ab64890Smrg		    return name;
1911ab64890Smrg		}
192eb411b4bSmrg		*len += new_len;
193eb411b4bSmrg		buf = (CARD16 *)((char *)buf + new_len);
1941ab64890Smrg	    }
195eb411b4bSmrg
1961ab64890Smrg	    if (!(res = _XimGetNestedListSeparator(res_list, res_num))) {
1971ab64890Smrg		p++;
1981ab64890Smrg		if (p) {
1991ab64890Smrg		    *len = -1;
2001ab64890Smrg		    return p->name;
2011ab64890Smrg		}
2021ab64890Smrg		else {
2031ab64890Smrg		    return (char *)NULL;
2041ab64890Smrg		}
2051ab64890Smrg	    }
2061ab64890Smrg	    *buf = res->id;
2071ab64890Smrg	    *len += sizeof(CARD16);
2081ab64890Smrg	    buf++;
2091ab64890Smrg	}
2101ab64890Smrg    }
2111ab64890Smrg    return (char *)NULL;
2121ab64890Smrg}
2131ab64890Smrg
214eb411b4bSmrgstatic Bool
2151ab64890Smrg_XimAttributeToValue(
2161ab64890Smrg    Xic			  ic,
2171ab64890Smrg    XIMResourceList	  res,
2181ab64890Smrg    CARD16		 *data,
2199c019ec5Smaya    CARD16		  data_len,
2201ab64890Smrg    XPointer		  value,
2211ab64890Smrg    BITMASK32		  mode)
2221ab64890Smrg{
2231ab64890Smrg    switch (res->resource_size) {
2241ab64890Smrg    case XimType_SeparatorOfNestedList:
2251ab64890Smrg    case XimType_NEST:
2261ab64890Smrg	break;
2271ab64890Smrg
2281ab64890Smrg    case XimType_CARD8:
2291ab64890Smrg    case XimType_CARD16:
2301ab64890Smrg    case XimType_CARD32:
2311ab64890Smrg    case XimType_Window:
2321ab64890Smrg    case XimType_XIMHotKeyState:
2331ab64890Smrg	_XCopyToArg((XPointer)data, (XPointer *)&value, data_len);
2341ab64890Smrg	break;
2351ab64890Smrg
2361ab64890Smrg    case XimType_STRING8:
2371ab64890Smrg	{
2381ab64890Smrg	    char	*str;
2391ab64890Smrg
2401ab64890Smrg	    if (!(value))
2411ab64890Smrg		return False;
2421ab64890Smrg
243818534a1Smrg	    if (!(str = Xmalloc(data_len + 1)))
2441ab64890Smrg		return False;
2451ab64890Smrg
2461ab64890Smrg	    (void)memcpy(str, (char *)data, data_len);
2471ab64890Smrg	    str[data_len] = '\0';
2481ab64890Smrg
2491ab64890Smrg	    *((char **)value) = str;
2501ab64890Smrg	    break;
2511ab64890Smrg	}
2521ab64890Smrg
2531ab64890Smrg    case XimType_XIMStyles:
2541ab64890Smrg	{
2559c019ec5Smaya	    CARD16		 num = data[0];
2561ab64890Smrg	    register CARD32	*style_list = (CARD32 *)&data[2];
2571ab64890Smrg	    XIMStyle		*style;
2581ab64890Smrg	    XIMStyles		*rep;
2591ab64890Smrg	    register int	 i;
2601ab64890Smrg	    char		*p;
2619c019ec5Smaya	    unsigned int         alloc_len;
2621ab64890Smrg
2631ab64890Smrg	    if (!(value))
2641ab64890Smrg		return False;
2651ab64890Smrg
2669c019ec5Smaya	    if (num > (USHRT_MAX / sizeof(XIMStyle)))
2679c019ec5Smaya		return False;
2689c019ec5Smaya	    if ((sizeof(num) + (num * sizeof(XIMStyle))) > data_len)
2699c019ec5Smaya		return False;
2701ab64890Smrg	    alloc_len = sizeof(XIMStyles) + sizeof(XIMStyle) * num;
2719c019ec5Smaya	    if (alloc_len < sizeof(XIMStyles))
2729c019ec5Smaya		return False;
273818534a1Smrg	    if (!(p = Xmalloc(alloc_len)))
2741ab64890Smrg		return False;
2751ab64890Smrg
2761ab64890Smrg	    rep   = (XIMStyles *)p;
2771ab64890Smrg	    style = (XIMStyle *)(p + sizeof(XIMStyles));
2781ab64890Smrg
2791ab64890Smrg	    for (i = 0; i < num; i++)
2801ab64890Smrg		style[i] = (XIMStyle)style_list[i];
2811ab64890Smrg
2821ab64890Smrg	    rep->count_styles = (unsigned short)num;
2831ab64890Smrg	    rep->supported_styles = style;
2841ab64890Smrg	    *((XIMStyles **)value) = rep;
2851ab64890Smrg	    break;
2861ab64890Smrg	}
2871ab64890Smrg
2881ab64890Smrg    case XimType_XRectangle:
2891ab64890Smrg	{
2901ab64890Smrg	    XRectangle	*rep;
2911ab64890Smrg
2921ab64890Smrg	    if (!(value))
2931ab64890Smrg		return False;
2941ab64890Smrg
295818534a1Smrg	    if (!(rep = Xmalloc(sizeof(XRectangle))))
2961ab64890Smrg		return False;
2971ab64890Smrg
2981ab64890Smrg	    rep->x      = data[0];
2991ab64890Smrg	    rep->y      = data[1];
3001ab64890Smrg	    rep->width  = data[2];
3011ab64890Smrg	    rep->height = data[3];
3021ab64890Smrg	    *((XRectangle **)value) = rep;
3031ab64890Smrg	    break;
3041ab64890Smrg	}
3051ab64890Smrg
3061ab64890Smrg    case XimType_XPoint:
3071ab64890Smrg	{
3081ab64890Smrg	    XPoint	*rep;
3091ab64890Smrg
3101ab64890Smrg	    if (!(value))
3111ab64890Smrg		return False;
3121ab64890Smrg
313818534a1Smrg	    if (!(rep = Xmalloc(sizeof(XPoint))))
3141ab64890Smrg		return False;
3151ab64890Smrg
3161ab64890Smrg	    rep->x = data[0];
3171ab64890Smrg	    rep->y = data[1];
3181ab64890Smrg	    *((XPoint **)value) = rep;
3191ab64890Smrg	    break;
3201ab64890Smrg	}
3211ab64890Smrg
3221ab64890Smrg    case XimType_XFontSet:
3231ab64890Smrg	{
3249c019ec5Smaya	    CARD16	 len = data[0];
3251ab64890Smrg	    char	*base_name;
3261ab64890Smrg	    XFontSet	 rep = (XFontSet)NULL;
32757f47464Smrg	    char	**missing_list = NULL;
3281ab64890Smrg	    int		 missing_count;
3291ab64890Smrg	    char	*def_string;
3301ab64890Smrg
3311ab64890Smrg	    if (!(value))
3321ab64890Smrg		return False;
3331ab64890Smrg	    if (!ic)
3341ab64890Smrg		return False;
3359c019ec5Smaya	    if (len > data_len)
3369c019ec5Smaya		return False;
337818534a1Smrg	    if (!(base_name = Xmalloc(len + 1)))
3381ab64890Smrg		return False;
3391ab64890Smrg
3409c019ec5Smaya	    (void)strncpy(base_name, (char *)&data[1], (size_t)len);
3411ab64890Smrg	    base_name[len] = '\0';
3421ab64890Smrg
3431ab64890Smrg	    if (mode & XIM_PREEDIT_ATTR) {
3441ab64890Smrg		if (!strcmp(base_name, ic->private.proto.preedit_font)) {
3451ab64890Smrg		    rep = ic->core.preedit_attr.fontset;
3461ab64890Smrg		} else if (!ic->private.proto.preedit_font_length) {
3471ab64890Smrg		    rep = XCreateFontSet(ic->core.im->core.display,
3481ab64890Smrg					base_name, &missing_list,
3491ab64890Smrg					&missing_count, &def_string);
3501ab64890Smrg		}
3511ab64890Smrg	    } else if (mode & XIM_STATUS_ATTR) {
3521ab64890Smrg		if (!strcmp(base_name, ic->private.proto.status_font)) {
3531ab64890Smrg		    rep = ic->core.status_attr.fontset;
3541ab64890Smrg		} else if (!ic->private.proto.status_font_length) {
3551ab64890Smrg		    rep = XCreateFontSet(ic->core.im->core.display,
3561ab64890Smrg					base_name, &missing_list,
3571ab64890Smrg					&missing_count, &def_string);
3581ab64890Smrg		}
3591ab64890Smrg	    }
3601ab64890Smrg
3611ab64890Smrg	    Xfree(base_name);
36257f47464Smrg	    Xfree(missing_list);
3631ab64890Smrg	    *((XFontSet *)value) = rep;
3641ab64890Smrg	    break;
3651ab64890Smrg	}
3661ab64890Smrg
3671ab64890Smrg    case XimType_XIMHotKeyTriggers:
3681ab64890Smrg	{
3699c019ec5Smaya	    CARD32			 num = *((CARD32 *)data);
3701ab64890Smrg	    register CARD32		*key_list = (CARD32 *)&data[2];
3711ab64890Smrg	    XIMHotKeyTrigger		*key;
3721ab64890Smrg	    XIMHotKeyTriggers		*rep;
3731ab64890Smrg	    register int		 i;
3741ab64890Smrg	    char			*p;
3759c019ec5Smaya	    unsigned int		 alloc_len;
3761ab64890Smrg
3771ab64890Smrg	    if (!(value))
3781ab64890Smrg		return False;
3791ab64890Smrg
3809c019ec5Smaya	    if (num > (UINT_MAX / sizeof(XIMHotKeyTrigger)))
3819c019ec5Smaya		return False;
3829c019ec5Smaya	    if ((sizeof(num) + (num * sizeof(XIMHotKeyTrigger))) > data_len)
3839c019ec5Smaya		return False;
3841ab64890Smrg	    alloc_len = sizeof(XIMHotKeyTriggers)
3851ab64890Smrg		      + sizeof(XIMHotKeyTrigger) * num;
3869c019ec5Smaya	    if (alloc_len < sizeof(XIMHotKeyTriggers))
3879c019ec5Smaya		return False;
388818534a1Smrg	    if (!(p = Xmalloc(alloc_len)))
3891ab64890Smrg		return False;
3901ab64890Smrg
3911ab64890Smrg	    rep = (XIMHotKeyTriggers *)p;
3921ab64890Smrg	    key = (XIMHotKeyTrigger *)(p + sizeof(XIMHotKeyTriggers));
3931ab64890Smrg
3941ab64890Smrg	    for (i = 0; i < num; i++, key_list += 3) {
3951ab64890Smrg		key[i].keysym        = (KeySym)key_list[0]; /* keysym */
3961ab64890Smrg		key[i].modifier      = (int)key_list[1];    /* modifier */
3971ab64890Smrg		key[i].modifier_mask = (int)key_list[2];    /* modifier_mask */
3981ab64890Smrg	    }
3991ab64890Smrg
4001ab64890Smrg	    rep->num_hot_key = (int)num;
4011ab64890Smrg	    rep->key = key;
4021ab64890Smrg	    *((XIMHotKeyTriggers **)value) = rep;
4031ab64890Smrg	    break;
4041ab64890Smrg	}
4051ab64890Smrg
4061ab64890Smrg    case XimType_XIMStringConversion:
4071ab64890Smrg	{
4081ab64890Smrg	    break;
4091ab64890Smrg	}
4101ab64890Smrg
4111ab64890Smrg    default:
4121ab64890Smrg	return False;
4131ab64890Smrg    }
4141ab64890Smrg    return True;
4151ab64890Smrg}
4161ab64890Smrg
417eb411b4bSmrgstatic Bool
4181ab64890Smrg_XimDecodeInnerIMATTRIBUTE(
4191ab64890Smrg    Xim			 im,
4201ab64890Smrg    XIMArg		*arg)
4211ab64890Smrg{
4221ab64890Smrg    XIMResourceList	 res;
4231ab64890Smrg    XimDefIMValues	 im_values;
4241ab64890Smrg
4251ab64890Smrg    if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
4261ab64890Smrg			im->private.proto.im_num_inner_resources, arg->name)))
4271ab64890Smrg	return False;
4281ab64890Smrg
4291ab64890Smrg    _XimGetCurrentIMValues(im, &im_values);
4301ab64890Smrg    return _XimDecodeLocalIMAttr(res, (XPointer)&im_values, arg->value);
4311ab64890Smrg}
4321ab64890Smrg
433eb411b4bSmrgchar *
4341ab64890Smrg_XimDecodeIMATTRIBUTE(
4351ab64890Smrg    Xim			 im,
4361ab64890Smrg    XIMResourceList	 res_list,
4371ab64890Smrg    unsigned int	 res_num,
4381ab64890Smrg    CARD16		*data,
4391ab64890Smrg    INT16		 data_len,
4401ab64890Smrg    XIMArg		*arg,
4411ab64890Smrg    BITMASK32		 mode)
4421ab64890Smrg{
4431ab64890Smrg    register XIMArg	*p;
4441ab64890Smrg    XIMResourceList	 res;
4451ab64890Smrg    int			 check;
4461ab64890Smrg    INT16		 len;
4471ab64890Smrg    CARD16		*buf;
4481ab64890Smrg    INT16		 total;
4491ab64890Smrg    INT16		 min_len = sizeof(CARD16)	/* sizeof attributeID */
4501ab64890Smrg			 	 + sizeof(INT16);	/* sizeof length */
4511ab64890Smrg
4521ab64890Smrg    for (p = arg; p->name; p++) {
4531ab64890Smrg	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
4541ab64890Smrg	    if (_XimDecodeInnerIMATTRIBUTE(im, p))
4551ab64890Smrg		continue;
4561ab64890Smrg	    return p->name;
4571ab64890Smrg	}
4581ab64890Smrg
4591ab64890Smrg	check = _XimCheckIMMode(res, mode);
4601ab64890Smrg	if(check == XIM_CHECK_INVALID)
4611ab64890Smrg	    continue;
4621ab64890Smrg	else if(check == XIM_CHECK_ERROR)
4631ab64890Smrg	    return p->name;
4641ab64890Smrg
4651ab64890Smrg	total = data_len;
4661ab64890Smrg	buf = data;
4671ab64890Smrg	while (total >= min_len) {
4681ab64890Smrg	    if (res->id == buf[0])
4691ab64890Smrg		break;
4701ab64890Smrg
4711ab64890Smrg	    len = buf[1];
4721ab64890Smrg	    len += XIM_PAD(len) + min_len;
4731ab64890Smrg	    buf = (CARD16 *)((char *)buf + len);
4741ab64890Smrg	    total -= len;
4751ab64890Smrg	}
4761ab64890Smrg	if (total < min_len)
4771ab64890Smrg	    return p->name;
4781ab64890Smrg
47961b2299dSmrg	if (!(_XimAttributeToValue((Xic) im->private.local.current_ic,
4801ab64890Smrg				   res, &buf[2], buf[1], p->value, mode)))
4811ab64890Smrg	    return p->name;
4821ab64890Smrg    }
4831ab64890Smrg    return (char *)NULL;
4841ab64890Smrg}
4851ab64890Smrg
486eb411b4bSmrgstatic Bool
4871ab64890Smrg_XimDecodeInnerICATTRIBUTE(
4881ab64890Smrg    Xic			 ic,
4891ab64890Smrg    XIMArg		*arg,
4901ab64890Smrg    unsigned long	 mode)
4911ab64890Smrg{
4921ab64890Smrg    XIMResourceList	 res;
4931ab64890Smrg    XimDefICValues	 ic_values;
4941ab64890Smrg
4951ab64890Smrg    if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
4961ab64890Smrg			ic->private.proto.ic_num_inner_resources, arg->name)))
4971ab64890Smrg	return False;
4981ab64890Smrg
4991ab64890Smrg    _XimGetCurrentICValues(ic, &ic_values);
5001ab64890Smrg    if (!_XimDecodeLocalICAttr(res, (XPointer)&ic_values, arg->value, mode))
5011ab64890Smrg	return False;
5021ab64890Smrg    _XimSetCurrentICValues(ic, &ic_values);
5031ab64890Smrg    return True;
5041ab64890Smrg}
5051ab64890Smrg
506eb411b4bSmrgchar *
5071ab64890Smrg_XimDecodeICATTRIBUTE(
5081ab64890Smrg    Xic			 ic,
5091ab64890Smrg    XIMResourceList	 res_list,
5101ab64890Smrg    unsigned int	 res_num,
5111ab64890Smrg    CARD16		*data,
5121ab64890Smrg    INT16		 data_len,
5131ab64890Smrg    XIMArg		*arg,
5141ab64890Smrg    BITMASK32		 mode)
5151ab64890Smrg{
5161ab64890Smrg    register XIMArg	*p;
5171ab64890Smrg    XIMResourceList	 res;
5181ab64890Smrg    int			 check;
5191ab64890Smrg    INT16		 len;
5201ab64890Smrg    CARD16		*buf;
5211ab64890Smrg    INT16		 total;
5221ab64890Smrg    char		*name;
5231ab64890Smrg    INT16		 min_len = sizeof(CARD16)	/* sizeof attributeID */
5241ab64890Smrg			 	 + sizeof(INT16);	/* sizeof length */
5251ab64890Smrg    XrmQuark		 pre_quark;
5261ab64890Smrg    XrmQuark		 sts_quark;
5271ab64890Smrg
5281ab64890Smrg    if (!arg)
5291ab64890Smrg	return (char *)NULL;
5301ab64890Smrg
5311ab64890Smrg    pre_quark = XrmStringToQuark(XNPreeditAttributes);
5321ab64890Smrg    sts_quark = XrmStringToQuark(XNStatusAttributes);
5331ab64890Smrg
5341ab64890Smrg    for (p = arg; p->name; p++) {
5351ab64890Smrg	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
5361ab64890Smrg	    if (_XimDecodeInnerICATTRIBUTE(ic, p, mode))
5371ab64890Smrg		continue;
5381ab64890Smrg	    return p->name;
5391ab64890Smrg	}
5401ab64890Smrg
5411ab64890Smrg	check = _XimCheckICMode(res, mode);
5421ab64890Smrg	if (check == XIM_CHECK_INVALID)
5431ab64890Smrg	    continue;
5441ab64890Smrg	else if (check == XIM_CHECK_ERROR)
5451ab64890Smrg	    return p->name;
5461ab64890Smrg
5471ab64890Smrg	total = data_len;
5481ab64890Smrg	buf = data;
5491ab64890Smrg	while (total >= min_len) {
5501ab64890Smrg	    if (res->id == buf[0])
5511ab64890Smrg		break;
5521ab64890Smrg
5531ab64890Smrg	    len = buf[1];
5541ab64890Smrg	    len += XIM_PAD(len) + min_len;
5551ab64890Smrg	    buf = (CARD16 *)((char *)buf + len);
5561ab64890Smrg	    total -= len;
5571ab64890Smrg	}
5581ab64890Smrg	if (total < min_len)
5591ab64890Smrg	    return p->name;
5601ab64890Smrg
5611ab64890Smrg	if (res->resource_size == XimType_NEST) {
5621ab64890Smrg	    if (res->xrm_name == pre_quark) {
5631ab64890Smrg	        if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num,
5641ab64890Smrg			&buf[2], buf[1], (XIMArg *)p->value,
5651ab64890Smrg			(mode | XIM_PREEDIT_ATTR))))
5661ab64890Smrg		    return name;
5671ab64890Smrg	    } else if (res->xrm_name == sts_quark) {
5681ab64890Smrg	        if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num,
5691ab64890Smrg			&buf[2], buf[1], (XIMArg *)p->value,
5701ab64890Smrg			(mode | XIM_STATUS_ATTR))))
5711ab64890Smrg		    return name;
5721ab64890Smrg	    }
5731ab64890Smrg	} else {
5741ab64890Smrg	    if (!(_XimAttributeToValue(ic, res, &buf[2], buf[1],
5751ab64890Smrg							p->value, mode)))
5761ab64890Smrg		return p->name;
5771ab64890Smrg	}
5781ab64890Smrg    }
5791ab64890Smrg    return (char *)NULL;
5801ab64890Smrg}
5811ab64890Smrg
582eb411b4bSmrgstatic Bool
5831ab64890Smrg_XimValueToAttribute(
5841ab64890Smrg    XIMResourceList	 res,
5851ab64890Smrg    XPointer		 buf,
5861ab64890Smrg    int			 buf_size,
5871ab64890Smrg    XPointer		 value,
5881ab64890Smrg    int			*len,
5891ab64890Smrg    unsigned long	 mode,
5901ab64890Smrg    XPointer		 param)
5911ab64890Smrg{
5921ab64890Smrg    int			 ret_len;
5931ab64890Smrg
5941ab64890Smrg    switch (res->resource_size) {
5951ab64890Smrg    case XimType_SeparatorOfNestedList:
5961ab64890Smrg    case XimType_NEST:
5971ab64890Smrg	*len = 0;
5981ab64890Smrg	break;
5991ab64890Smrg
6001ab64890Smrg    case XimType_CARD8:
6011ab64890Smrg	ret_len = sizeof(CARD8);
6021ab64890Smrg	if (buf_size < ret_len + XIM_PAD(ret_len)) {
6031ab64890Smrg	    *len = -1;
6041ab64890Smrg	    return False;
6051ab64890Smrg	}
6061ab64890Smrg
6071ab64890Smrg	*((CARD8 *)buf) = (CARD8)(long)value;
6081ab64890Smrg	*len = ret_len;
6091ab64890Smrg	break;
6101ab64890Smrg
6111ab64890Smrg    case XimType_CARD16:
6121ab64890Smrg	ret_len = sizeof(CARD16);
6131ab64890Smrg	if (buf_size < ret_len + XIM_PAD(ret_len)) {
6141ab64890Smrg	    *len = -1;
6151ab64890Smrg	    return False;
6161ab64890Smrg	}
6171ab64890Smrg
6181ab64890Smrg	*((CARD16 *)buf) = (CARD16)(long)value;
6191ab64890Smrg	*len = ret_len;
6201ab64890Smrg	break;
6211ab64890Smrg
6221ab64890Smrg    case XimType_CARD32:
6231ab64890Smrg    case XimType_Window:
6241ab64890Smrg    case XimType_XIMHotKeyState:
6251ab64890Smrg	ret_len = sizeof(CARD32);
6261ab64890Smrg	if (buf_size < ret_len + XIM_PAD(ret_len)) {
6271ab64890Smrg	    *len = -1;
6281ab64890Smrg	    return False;
6291ab64890Smrg	}
6301ab64890Smrg
6311ab64890Smrg	*((CARD32 *)buf) = (CARD32)(long)value;
6321ab64890Smrg	*len = ret_len;
6331ab64890Smrg	break;
6341ab64890Smrg
6351ab64890Smrg    case XimType_STRING8:
6361ab64890Smrg	if (!value) {
6371ab64890Smrg	    *len = 0;
6381ab64890Smrg	    return False;
6391ab64890Smrg	}
6401ab64890Smrg
6411ab64890Smrg	ret_len = strlen((char *)value);
6421ab64890Smrg	if (buf_size < ret_len + XIM_PAD(ret_len)) {
6431ab64890Smrg	    *len = -1;
6441ab64890Smrg	    return False;
6451ab64890Smrg	}
6461ab64890Smrg
6471ab64890Smrg	(void)memcpy((char *)buf, (char *)value, ret_len);
6481ab64890Smrg	*len = ret_len;
6491ab64890Smrg	break;
6501ab64890Smrg
6511ab64890Smrg    case XimType_XRectangle:
6521ab64890Smrg	{
6531ab64890Smrg	    XRectangle	*rect = (XRectangle *)value;
6541ab64890Smrg	    CARD16	*buf_s = (CARD16 *)buf;
6551ab64890Smrg
6561ab64890Smrg	    if (!rect) {
6571ab64890Smrg		*len = 0;
6581ab64890Smrg		return False;
6591ab64890Smrg	    }
6601ab64890Smrg
6611ab64890Smrg	    ret_len = sizeof(INT16)		/* sizeof X */
6621ab64890Smrg	    	    + sizeof(INT16)		/* sizeof Y */
6631ab64890Smrg	            + sizeof(CARD16)		/* sizeof width */
6641ab64890Smrg	            + sizeof(CARD16);		/* sizeof height */
6651ab64890Smrg	    if (buf_size < ret_len + XIM_PAD(ret_len)) {
6661ab64890Smrg		*len = -1;
6671ab64890Smrg		return False;
6681ab64890Smrg	    }
6691ab64890Smrg
6701ab64890Smrg	    buf_s[0] = (CARD16)rect->x;		/* X */
6711ab64890Smrg	    buf_s[1] = (CARD16)rect->y;		/* Y */
6721ab64890Smrg	    buf_s[2] = (CARD16)rect->width;	/* width */
6731ab64890Smrg	    buf_s[3] = (CARD16)rect->height;	/* heght */
6741ab64890Smrg	    *len = ret_len;
6751ab64890Smrg	    break;
6761ab64890Smrg	}
6771ab64890Smrg
6781ab64890Smrg    case XimType_XPoint:
6791ab64890Smrg	{
6801ab64890Smrg	    XPoint	*point = (XPoint *)value;
6811ab64890Smrg	    CARD16	*buf_s = (CARD16 *)buf;
6821ab64890Smrg
6831ab64890Smrg	    if (!point) {
6841ab64890Smrg		*len = 0;
6851ab64890Smrg		return False;
6861ab64890Smrg	    }
6871ab64890Smrg
6881ab64890Smrg	    ret_len = sizeof(INT16)		/* sizeof X */
6891ab64890Smrg	            + sizeof(INT16);		/* sizeof Y */
6901ab64890Smrg	    if (buf_size < ret_len + XIM_PAD(ret_len)) {
6911ab64890Smrg		*len = -1;
6921ab64890Smrg		return False;
6931ab64890Smrg	    }
6941ab64890Smrg
6951ab64890Smrg	    buf_s[0] = (CARD16)point->x;		/* X */
6961ab64890Smrg	    buf_s[1] = (CARD16)point->y;		/* Y */
6971ab64890Smrg	    *len = ret_len;
6981ab64890Smrg	    break;
6991ab64890Smrg	}
7001ab64890Smrg
7011ab64890Smrg    case XimType_XFontSet:
7021ab64890Smrg	{
7031ab64890Smrg	    XFontSet	 font = (XFontSet)value;
7041ab64890Smrg	    Xic		 ic = (Xic)param;
7051ab64890Smrg	    char	*base_name = NULL;
7061ab64890Smrg	    int		 length = 0;
7071ab64890Smrg	    CARD16	*buf_s = (CARD16 *)buf;
7081ab64890Smrg
7091ab64890Smrg	    if (!font) {
7101ab64890Smrg		*len = 0;
7111ab64890Smrg		return False;
7121ab64890Smrg	    }
7131ab64890Smrg
7141ab64890Smrg	    if (mode & XIM_PREEDIT_ATTR) {
7151ab64890Smrg		base_name = ic->private.proto.preedit_font;
7161ab64890Smrg		length	  = ic->private.proto.preedit_font_length;
7171ab64890Smrg	    } else if (mode & XIM_STATUS_ATTR) {
7181ab64890Smrg		base_name = ic->private.proto.status_font;
7191ab64890Smrg		length	  = ic->private.proto.status_font_length;
7201ab64890Smrg	    }
7211ab64890Smrg
7221ab64890Smrg	    if (!base_name) {
7231ab64890Smrg		*len = 0;
7241ab64890Smrg		return False;
7251ab64890Smrg	    }
7261ab64890Smrg
7271ab64890Smrg	    ret_len = sizeof(CARD16)		/* sizeof length of Base name */
7281ab64890Smrg		    + length;			/* sizeof Base font name list */
7291ab64890Smrg	    if (buf_size < ret_len + XIM_PAD(ret_len)) {
7301ab64890Smrg		*len = -1;
7311ab64890Smrg		return False;
7321ab64890Smrg	    }
7331ab64890Smrg
7341ab64890Smrg	    buf_s[0] = (INT16)length;		/* length of Base font name */
7351ab64890Smrg	    (void)memcpy((char *)&buf_s[1], base_name, length);
7361ab64890Smrg						/* Base font name list */
7371ab64890Smrg	    *len = ret_len;
7381ab64890Smrg	    break;
7391ab64890Smrg	}
7401ab64890Smrg
7411ab64890Smrg    case XimType_XIMHotKeyTriggers:
7421ab64890Smrg	{
7431ab64890Smrg	    XIMHotKeyTriggers	*hotkey = (XIMHotKeyTriggers *)value;
7441ab64890Smrg	    INT32		 num;
7451ab64890Smrg	    CARD32		*buf_l = (CARD32 *)buf;
7461ab64890Smrg	    register CARD32	*key = (CARD32 *)&buf_l[1];
7471ab64890Smrg	    register int	 i;
7481ab64890Smrg
7491ab64890Smrg	    if (!hotkey) {
7501ab64890Smrg		*len = 0;
7511ab64890Smrg		return False;
7521ab64890Smrg	    }
7531ab64890Smrg	    num = (INT32)hotkey->num_hot_key;
7541ab64890Smrg
7551ab64890Smrg	    ret_len = sizeof(INT32)		/* sizeof number of key list */
7561ab64890Smrg	           + (sizeof(CARD32)		/* sizeof keysyn */
7571ab64890Smrg	           +  sizeof(CARD32)		/* sizeof modifier */
7581ab64890Smrg	           +  sizeof(CARD32))		/* sizeof modifier_mask */
7591ab64890Smrg	           *  num;			/* number of key list */
7601ab64890Smrg	    if (buf_size < ret_len + XIM_PAD(ret_len)) {
7611ab64890Smrg		*len = -1;
7621ab64890Smrg		return False;
7631ab64890Smrg	    }
7641ab64890Smrg
7651ab64890Smrg	    buf_l[0] = num;		/* number of key list */
7661ab64890Smrg	    for (i = 0; i < num; i++, key += 3) {
7671ab64890Smrg		key[0] = (CARD32)(hotkey->key[i].keysym);
7681ab64890Smrg						/* keysym */
7691ab64890Smrg		key[1] = (CARD32)(hotkey->key[i].modifier);
7701ab64890Smrg						/* modifier */
7711ab64890Smrg		key[2] = (CARD32)(hotkey->key[i].modifier_mask);
7721ab64890Smrg						/* modifier_mask */
7731ab64890Smrg	    }
7741ab64890Smrg	    *len = ret_len;
7751ab64890Smrg	    break;
7761ab64890Smrg	}
7771ab64890Smrg
7781ab64890Smrg    case XimType_XIMStringConversion:
7791ab64890Smrg	{
7801ab64890Smrg	    *len = 0;
7811ab64890Smrg	    break;
7821ab64890Smrg	}
7831ab64890Smrg
7841ab64890Smrg    default:
7851ab64890Smrg	return False;
7861ab64890Smrg    }
7871ab64890Smrg    return True;
7881ab64890Smrg}
7891ab64890Smrg
790eb411b4bSmrgstatic Bool
7911ab64890Smrg_XimSetInnerIMAttributes(
7921ab64890Smrg    Xim			 im,
7931ab64890Smrg    XPointer		 top,
7941ab64890Smrg    XIMArg		*arg,
7951ab64890Smrg    unsigned long	 mode)
7961ab64890Smrg{
7971ab64890Smrg    XIMResourceList	 res;
7981ab64890Smrg    int			 check;
7991ab64890Smrg
8001ab64890Smrg    if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
8011ab64890Smrg			im->private.proto.im_num_inner_resources, arg->name)))
8021ab64890Smrg	return False;
8031ab64890Smrg
8041ab64890Smrg    check = _XimCheckIMMode(res, mode);
8051ab64890Smrg    if(check == XIM_CHECK_INVALID)
8061ab64890Smrg	return True;
8071ab64890Smrg    else if(check == XIM_CHECK_ERROR)
8081ab64890Smrg	return False;
8091ab64890Smrg
8101ab64890Smrg    return _XimEncodeLocalIMAttr(res, top, arg->value);
8111ab64890Smrg}
8121ab64890Smrg
813eb411b4bSmrgchar *
8141ab64890Smrg_XimEncodeIMATTRIBUTE(
8151ab64890Smrg    Xim			  im,
8161ab64890Smrg    XIMResourceList	  res_list,
8171ab64890Smrg    unsigned int	  res_num,
8181ab64890Smrg    XIMArg		 *arg,
8191ab64890Smrg    XIMArg		**arg_ret,
8201ab64890Smrg    char		 *buf,
8211ab64890Smrg    int			  size,
8221ab64890Smrg    int			 *ret_len,
8231ab64890Smrg    XPointer		  top,
8241ab64890Smrg    unsigned long	  mode)
8251ab64890Smrg{
8261ab64890Smrg    register XIMArg	*p;
8271ab64890Smrg    XIMResourceList	 res;
8281ab64890Smrg    int			 check;
8291ab64890Smrg    CARD16		*buf_s;
8301ab64890Smrg    int			 len;
8311ab64890Smrg    int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
8321ab64890Smrg				 + sizeof(INT16); /* sizeof value length */
8331ab64890Smrg
8341ab64890Smrg    *ret_len = 0;
8351ab64890Smrg    for (p = arg; p->name; p++) {
8361ab64890Smrg	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
8371ab64890Smrg	    if (_XimSetInnerIMAttributes(im, top, p, mode))
8381ab64890Smrg		continue;
8391ab64890Smrg	    return p->name;
8401ab64890Smrg	}
8411ab64890Smrg
8421ab64890Smrg	check = _XimCheckIMMode(res, mode);
8431ab64890Smrg	if (check == XIM_CHECK_INVALID)
8441ab64890Smrg	    continue;
8451ab64890Smrg	else if (check == XIM_CHECK_ERROR)
8461ab64890Smrg	    return p->name;
8471ab64890Smrg
8481ab64890Smrg	if (!(_XimEncodeLocalIMAttr(res, top, p->value)))
8491ab64890Smrg	    return p->name;
8501ab64890Smrg
8511ab64890Smrg	buf_s = (CARD16 *)buf;
8521ab64890Smrg	if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2], (size - min_len),
8531ab64890Smrg				p->value, &len, mode, (XPointer)NULL)))
8541ab64890Smrg	    return p->name;
8551ab64890Smrg
8561ab64890Smrg	if (len == 0) {
8571ab64890Smrg	    continue;
8581ab64890Smrg	} else if (len < 0) {
8591ab64890Smrg	    *arg_ret = p;
8601ab64890Smrg	    return (char *)NULL;
8611ab64890Smrg	}
8621ab64890Smrg
8631ab64890Smrg	buf_s[0] = res->id;			/* attribute ID */
8641ab64890Smrg	buf_s[1] = len;				/* value length */
8651ab64890Smrg	XIM_SET_PAD(&buf_s[2], len);		/* pad */
8661ab64890Smrg	len += min_len;
8671ab64890Smrg
8681ab64890Smrg	buf += len;
8691ab64890Smrg	*ret_len += len;
8701ab64890Smrg	size -= len;
8711ab64890Smrg    }
8721ab64890Smrg    *arg_ret = (XIMArg *)NULL;
8731ab64890Smrg    return (char *)NULL;
8741ab64890Smrg}
8751ab64890Smrg
8761ab64890Smrg#ifdef XIM_CONNECTABLE
877eb411b4bSmrgBool
8781ab64890Smrg_XimEncodeSavedIMATTRIBUTE(
8791ab64890Smrg    Xim			 im,
8801ab64890Smrg    XIMResourceList	 res_list,
8811ab64890Smrg    unsigned int	 res_num,
8821ab64890Smrg    int			*idx,
8831ab64890Smrg    char		*buf,
8841ab64890Smrg    int			 size,
8851ab64890Smrg    int			*ret_len,
8861ab64890Smrg    XPointer		 top,
8871ab64890Smrg    unsigned long	 mode)
8881ab64890Smrg{
8891ab64890Smrg    register int	 i;
8901ab64890Smrg    int			 num = im->private.proto.num_saved_imvalues;
8911ab64890Smrg    XrmQuark		*quark_list = im->private.proto.saved_imvalues;
8921ab64890Smrg    XIMResourceList	 res;
8931ab64890Smrg    XPointer		 value;
8941ab64890Smrg    CARD16		*buf_s;
8951ab64890Smrg    int			 len;
8961ab64890Smrg    int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
8971ab64890Smrg				 + sizeof(INT16); /* sizeof value length */
8981ab64890Smrg
8991ab64890Smrg    if (!im->private.proto.saved_imvalues) {
9001ab64890Smrg	*idx = -1;
9011ab64890Smrg	*ret_len = 0;
9021ab64890Smrg	return True;
9031ab64890Smrg    }
9041ab64890Smrg
9051ab64890Smrg    *ret_len = 0;
9061ab64890Smrg    for (i = *idx; i < num; i++) {
9071ab64890Smrg	if (!(res = _XimGetResourceListRecByQuark(res_list,
9081ab64890Smrg						res_num, quark_list[i])))
9091ab64890Smrg	    continue;
9101ab64890Smrg
9111ab64890Smrg	if (!_XimDecodeLocalIMAttr(res, top, value))
9121ab64890Smrg	    return False;
9131ab64890Smrg
9141ab64890Smrg	buf_s = (CARD16 *)buf;
9151ab64890Smrg	if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
9161ab64890Smrg			(size - min_len), value, &len, mode, (XPointer)NULL)))
9171ab64890Smrg	    return False;
9181ab64890Smrg
9191ab64890Smrg	if (len == 0) {
9201ab64890Smrg	    continue;
9211ab64890Smrg	} else if (len < 0) {
9221ab64890Smrg	    *idx = i;
9231ab64890Smrg	    return True;
9241ab64890Smrg	}
9251ab64890Smrg
9261ab64890Smrg	buf_s[0] = res->id;			/* attribute ID */
9271ab64890Smrg	buf_s[1] = len;				/* value length */
9281ab64890Smrg	XIM_SET_PAD(&buf_s[2], len);		/* pad */
9291ab64890Smrg	len += min_len;
9301ab64890Smrg
9311ab64890Smrg	buf += len;
9321ab64890Smrg	*ret_len += len;
9331ab64890Smrg	size -= len;
9341ab64890Smrg    }
9351ab64890Smrg    *idx = -1;
9361ab64890Smrg    return True;
9371ab64890Smrg}
9381ab64890Smrg#endif /* XIM_CONNECTABLE */
9391ab64890Smrg
940eb411b4bSmrgstatic Bool
9411ab64890Smrg_XimEncodeTopValue(
9421ab64890Smrg    Xic			 ic,
9431ab64890Smrg    XIMResourceList	 res,
9441ab64890Smrg    XIMArg		*p)
9451ab64890Smrg{
9461ab64890Smrg    if (res->xrm_name == XrmStringToQuark(XNClientWindow)) {
9471ab64890Smrg	ic->core.client_window = (Window)p->value;
9481ab64890Smrg	if (ic->core.focus_window == (Window)0)
9491ab64890Smrg	    ic->core.focus_window = ic->core.client_window;
9501ab64890Smrg	_XimRegisterFilter(ic);
9511ab64890Smrg
9521ab64890Smrg    } else if (res->xrm_name == XrmStringToQuark(XNFocusWindow)) {
9531ab64890Smrg	if (ic->core.client_window) {
9541ab64890Smrg	    _XimUnregisterFilter(ic);
9551ab64890Smrg	    ic->core.focus_window = (Window)p->value;
9561ab64890Smrg	    _XimRegisterFilter(ic);
9571ab64890Smrg	} else /* client_window not yet */
9581ab64890Smrg	    ic->core.focus_window = (Window)p->value;
9591ab64890Smrg    }
9601ab64890Smrg    return True;
9611ab64890Smrg}
9621ab64890Smrg
963eb411b4bSmrgstatic Bool
9641ab64890Smrg_XimEncodePreeditValue(
9651ab64890Smrg    Xic			 ic,
9661ab64890Smrg    XIMResourceList	 res,
9671ab64890Smrg    XIMArg		*p)
9681ab64890Smrg{
9691ab64890Smrg    if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
9701ab64890Smrg	XStandardColormap	*colormap_ret;
9711ab64890Smrg	int			 count;
9721ab64890Smrg
9731ab64890Smrg	if (!(XGetRGBColormaps(ic->core.im->core.display,
9741ab64890Smrg				ic->core.focus_window, &colormap_ret,
9751ab64890Smrg				&count, (Atom)p->value)))
9761ab64890Smrg	    return False;
9771ab64890Smrg
97857f47464Smrg	XFree(colormap_ret);
9791ab64890Smrg    } else if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
9801ab64890Smrg	int		  list_ret;
9811ab64890Smrg	XFontStruct	**struct_list;
9821ab64890Smrg	char		**name_list;
9831ab64890Smrg	char		 *tmp;
9841ab64890Smrg	int		  len;
9851ab64890Smrg	register int	  i;
9861ab64890Smrg
9871ab64890Smrg	if (!p->value)
9881ab64890Smrg	    return False;
9891ab64890Smrg
9900f8248bfSmrg	Xfree(ic->private.proto.preedit_font);
9911ab64890Smrg
9921ab64890Smrg	list_ret = XFontsOfFontSet((XFontSet)p->value,
9931ab64890Smrg						 &struct_list, &name_list);
9941ab64890Smrg	for (i = 0, len = 0; i < list_ret; i++) {
9951ab64890Smrg	     len += (strlen(name_list[i]) + sizeof(char));
9961ab64890Smrg	}
9971ab64890Smrg	if (!(tmp = Xmalloc(len + 1))) {
9981ab64890Smrg	    ic->private.proto.preedit_font = NULL;
9991ab64890Smrg	    return False;
10001ab64890Smrg	}
10011ab64890Smrg
10021ab64890Smrg	tmp[0] = '\0';
10031ab64890Smrg	for (i = 0; i < list_ret; i++) {
10041ab64890Smrg	    strcat(tmp, name_list[i]);
10051ab64890Smrg	    strcat(tmp, ",");
10061ab64890Smrg	}
10071ab64890Smrg	tmp[len - 1] = 0;
10081ab64890Smrg	ic->private.proto.preedit_font        = tmp;
10091ab64890Smrg	ic->private.proto.preedit_font_length = len - 1;
10101ab64890Smrg    }
10111ab64890Smrg    return True;
10121ab64890Smrg}
10131ab64890Smrg
1014eb411b4bSmrgstatic Bool
10151ab64890Smrg_XimEncodeStatusValue(
10161ab64890Smrg    Xic			 ic,
10171ab64890Smrg    XIMResourceList	 res,
10181ab64890Smrg    XIMArg		*p)
10191ab64890Smrg{
10201ab64890Smrg    if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
102157f47464Smrg	XStandardColormap	*colormap_ret = NULL;
10221ab64890Smrg	int			 count;
10231ab64890Smrg
10241ab64890Smrg	if (!(XGetRGBColormaps(ic->core.im->core.display,
10251ab64890Smrg				ic->core.focus_window, &colormap_ret,
10261ab64890Smrg				&count, (Atom)p->value)))
10271ab64890Smrg	    return False;
10281ab64890Smrg
102957f47464Smrg	XFree(colormap_ret);
10301ab64890Smrg    } else if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
10311ab64890Smrg	int		  list_ret;
10321ab64890Smrg	XFontStruct	**struct_list;
10331ab64890Smrg	char		**name_list;
10341ab64890Smrg	char		 *tmp;
10351ab64890Smrg	int		  len;
10361ab64890Smrg	register int	  i;
10371ab64890Smrg
10381ab64890Smrg	if (!p->value)
10391ab64890Smrg	    return False;
10401ab64890Smrg
10410f8248bfSmrg	Xfree(ic->private.proto.status_font);
10421ab64890Smrg
10431ab64890Smrg	list_ret = XFontsOfFontSet((XFontSet)p->value,
10441ab64890Smrg						 &struct_list, &name_list);
10451ab64890Smrg	for (i = 0, len = 0; i < list_ret; i++) {
10461ab64890Smrg	     len += (strlen(name_list[i]) + sizeof(char));
10471ab64890Smrg	}
10481ab64890Smrg	if (!(tmp = Xmalloc(len+1))) {
10491ab64890Smrg	    ic->private.proto.status_font = NULL;
10501ab64890Smrg	    return False;
10511ab64890Smrg	}
10521ab64890Smrg
10531ab64890Smrg	tmp[0] = '\0';
10541ab64890Smrg	for(i = 0; i < list_ret; i++) {
10551ab64890Smrg	    strcat(tmp, name_list[i]);
10561ab64890Smrg	    strcat(tmp, ",");
10571ab64890Smrg	}
10581ab64890Smrg	tmp[len - 1] = 0;
10591ab64890Smrg	ic->private.proto.status_font        = tmp;
10601ab64890Smrg	ic->private.proto.status_font_length = len - 1;
10611ab64890Smrg    }
10621ab64890Smrg    return True;
10631ab64890Smrg}
10641ab64890Smrg
1065eb411b4bSmrgstatic Bool
10661ab64890Smrg_XimSetInnerICAttributes(
10671ab64890Smrg    Xic			 ic,
10681ab64890Smrg    XPointer		 top,
10691ab64890Smrg    XIMArg		*arg,
10701ab64890Smrg    unsigned long	 mode)
10711ab64890Smrg{
10721ab64890Smrg    XIMResourceList	 res;
10731ab64890Smrg    int			 check;
10741ab64890Smrg
10751ab64890Smrg    if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
10761ab64890Smrg			ic->private.proto.ic_num_inner_resources, arg->name)))
10771ab64890Smrg	return False;
10781ab64890Smrg
10791ab64890Smrg    check = _XimCheckICMode(res, mode);
10801ab64890Smrg    if(check == XIM_CHECK_INVALID)
10811ab64890Smrg	return True;
10821ab64890Smrg    else if(check == XIM_CHECK_ERROR)
10831ab64890Smrg	return False;
10841ab64890Smrg
10851ab64890Smrg    return _XimEncodeLocalICAttr(ic, res, top, arg, mode);
10861ab64890Smrg}
10871ab64890Smrg
1088eb411b4bSmrgchar *
10891ab64890Smrg_XimEncodeICATTRIBUTE(
10901ab64890Smrg    Xic			  ic,
10911ab64890Smrg    XIMResourceList	  res_list,
10921ab64890Smrg    unsigned int	  res_num,
10931ab64890Smrg    XIMArg		 *arg,
10941ab64890Smrg    XIMArg		**arg_ret,
10951ab64890Smrg    char		 *buf,
10961ab64890Smrg    int			  size,
10971ab64890Smrg    int			 *ret_len,
10981ab64890Smrg    XPointer		  top,
10991ab64890Smrg    BITMASK32		 *flag,
11001ab64890Smrg    unsigned long	  mode)
11011ab64890Smrg{
11021ab64890Smrg    register XIMArg	*p;
11031ab64890Smrg    XIMResourceList	 res;
11041ab64890Smrg    int			 check;
11051ab64890Smrg    CARD16		*buf_s;
11061ab64890Smrg    int			 len;
11071ab64890Smrg    int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
11081ab64890Smrg				 + sizeof(INT16); /* sizeof value length */
11091ab64890Smrg    XrmQuark		 pre_quark;
11101ab64890Smrg    XrmQuark		 sts_quark;
11111ab64890Smrg    char		*name;
11121ab64890Smrg
11131ab64890Smrg    pre_quark = XrmStringToQuark(XNPreeditAttributes);
11141ab64890Smrg    sts_quark = XrmStringToQuark(XNStatusAttributes);
11151ab64890Smrg
11161ab64890Smrg    *ret_len = 0;
11171ab64890Smrg    for (p = arg; p && p->name; p++) {
11181ab64890Smrg	buf_s = (CARD16 *)buf;
11191ab64890Smrg	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
11201ab64890Smrg	    if (_XimSetInnerICAttributes(ic, top, p, mode))
11211ab64890Smrg		continue;
11221ab64890Smrg	    return p->name;
11231ab64890Smrg	}
11241ab64890Smrg
11251ab64890Smrg	check = _XimCheckICMode(res, mode);
11261ab64890Smrg	if (check == XIM_CHECK_INVALID)
11271ab64890Smrg	    continue;
11281ab64890Smrg	else if (check == XIM_CHECK_ERROR)
11291ab64890Smrg	    return p->name;
11301ab64890Smrg
11311ab64890Smrg	if (mode & XIM_PREEDIT_ATTR) {
11321ab64890Smrg	    if (!(_XimEncodePreeditValue(ic, res, p)))
11331ab64890Smrg		return p->name;
11341ab64890Smrg	} else if (mode & XIM_STATUS_ATTR) {
11351ab64890Smrg	    if (!(_XimEncodeStatusValue(ic, res, p)))
11361ab64890Smrg		return p->name;
11371ab64890Smrg	} else {
11381ab64890Smrg	    if (!(_XimEncodeTopValue(ic, res, p)))
11391ab64890Smrg		return p->name;
11401ab64890Smrg	}
11411ab64890Smrg
11421ab64890Smrg	if (res->resource_size == XimType_NEST) {
11431ab64890Smrg	    XimDefICValues	*ic_attr = (XimDefICValues *)top;
11441ab64890Smrg
11451ab64890Smrg	    if (res->xrm_name == pre_quark) {
11461ab64890Smrg		XIMArg		*arg_rt;
11471ab64890Smrg		if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
11481ab64890Smrg				(XIMArg *)p->value, &arg_rt,
11491ab64890Smrg				(char *)&buf_s[2], (size - min_len),
11501ab64890Smrg				 &len, (XPointer)&ic_attr->preedit_attr, flag,
11511ab64890Smrg				(mode | XIM_PREEDIT_ATTR)))) {
11521ab64890Smrg		    return name;
11531ab64890Smrg		}
11541ab64890Smrg
11551ab64890Smrg	    } else if (res->xrm_name == sts_quark) {
11561ab64890Smrg		XIMArg		*arg_rt;
11571ab64890Smrg		if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
11581ab64890Smrg				(XIMArg *)p->value,  &arg_rt,
11591ab64890Smrg				(char *)&buf_s[2], (size - min_len),
11601ab64890Smrg				 &len, (XPointer)&ic_attr->status_attr, flag,
11611ab64890Smrg				(mode | XIM_STATUS_ATTR)))) {
11621ab64890Smrg		    return name;
11631ab64890Smrg		}
11641ab64890Smrg	    }
11651ab64890Smrg	} else {
11661ab64890Smrg#ifdef EXT_MOVE
11671ab64890Smrg	    if (flag)
11681ab64890Smrg		*flag |= _XimExtenArgCheck(p);
11691ab64890Smrg#endif
11701ab64890Smrg    	    if (!(_XimEncodeLocalICAttr(ic, res, top, p, mode)))
11711ab64890Smrg		return p->name;
11721ab64890Smrg
11731ab64890Smrg	    if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
11741ab64890Smrg			 	(size - min_len), p->value,
11751ab64890Smrg				&len, mode, (XPointer)ic)))
11761ab64890Smrg		return p->name;
11771ab64890Smrg	}
11781ab64890Smrg
11791ab64890Smrg	if (len == 0) {
11801ab64890Smrg	    continue;
11811ab64890Smrg	} else if (len < 0) {
11821ab64890Smrg	    *arg_ret = p;
11831ab64890Smrg	    return (char *)NULL;
11841ab64890Smrg	}
11851ab64890Smrg
11861ab64890Smrg	buf_s[0] = res->id;			/* attribute ID */
11871ab64890Smrg	buf_s[1] = len;				/* value length */
11881ab64890Smrg	XIM_SET_PAD(&buf_s[2], len);		/* pad */
11891ab64890Smrg	len += min_len;
11901ab64890Smrg
11911ab64890Smrg	buf += len;
11921ab64890Smrg	*ret_len += len;
11931ab64890Smrg	size -= len;
11941ab64890Smrg    }
11951ab64890Smrg    *arg_ret = (XIMArg *)NULL;
11961ab64890Smrg    return (char *)NULL;
11971ab64890Smrg}
11981ab64890Smrg
11991ab64890Smrg#ifdef XIM_CONNECTABLE
1200eb411b4bSmrgstatic Bool
12011ab64890Smrg_XimEncodeSavedPreeditValue(
12021ab64890Smrg    Xic			  ic,
12031ab64890Smrg    XIMResourceList	  res,
12041ab64890Smrg    XPointer		  value)
12051ab64890Smrg{
12061ab64890Smrg    int			  list_ret;
12071ab64890Smrg    XFontStruct		**struct_list;
12081ab64890Smrg    char		**name_list;
12091ab64890Smrg    char		 *tmp;
12101ab64890Smrg    int			  len;
12111ab64890Smrg    register int	  i;
12121ab64890Smrg
12131ab64890Smrg    if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
12141ab64890Smrg	if (!value)
12151ab64890Smrg	    return False;
12161ab64890Smrg
12171ab64890Smrg	if (ic->private.proto.preedit_font)
12181ab64890Smrg	    Xfree(ic->private.proto.preedit_font);
12191ab64890Smrg
12201ab64890Smrg	list_ret = XFontsOfFontSet((XFontSet)value,
12211ab64890Smrg						&struct_list, &name_list);
12221ab64890Smrg	for(i = 0, len = 0; i < list_ret; i++) {
12231ab64890Smrg	    len += (strlen(name_list[i]) + sizeof(char));
12241ab64890Smrg	}
12251ab64890Smrg	if(!(tmp = Xmalloc(len + 1))) {
12261ab64890Smrg	    ic->private.proto.preedit_font = NULL;
12271ab64890Smrg	    return False;
12281ab64890Smrg	}
12291ab64890Smrg
12301ab64890Smrg	tmp[0] = '\0';
12311ab64890Smrg	for(i = 0; i < list_ret; i++) {
12321ab64890Smrg	    strcat(tmp, name_list[i]);
12331ab64890Smrg	    strcat(tmp, ",");
12341ab64890Smrg	}
12351ab64890Smrg	tmp[len - 1] = 0;
12361ab64890Smrg	ic->private.proto.preedit_font        = tmp;
12371ab64890Smrg	ic->private.proto.preedit_font_length = len - 1;
12381ab64890Smrg    }
12391ab64890Smrg    return True;
12401ab64890Smrg}
12411ab64890Smrg
1242eb411b4bSmrgstatic Bool
12431ab64890Smrg_XimEncodeSavedStatusValue(
12441ab64890Smrg    Xic			  ic,
12451ab64890Smrg    XIMResourceList	  res,
12461ab64890Smrg    XPointer		  value)
12471ab64890Smrg{
12481ab64890Smrg    int			  list_ret;
12491ab64890Smrg    XFontStruct		**struct_list;
12501ab64890Smrg    char		**name_list;
12511ab64890Smrg    char		 *tmp;
12521ab64890Smrg    int			  len;
12531ab64890Smrg    register int	  i;
12541ab64890Smrg
12551ab64890Smrg    if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
12561ab64890Smrg	if (!value)
12571ab64890Smrg	    return False;
12581ab64890Smrg
12590f8248bfSmrg	Xfree(ic->private.proto.status_font);
12601ab64890Smrg
12611ab64890Smrg	list_ret = XFontsOfFontSet((XFontSet)value,
12621ab64890Smrg						&struct_list, &name_list);
12631ab64890Smrg	for(i = 0, len = 0; i < list_ret; i++) {
12641ab64890Smrg	    len += (strlen(name_list[i]) + sizeof(char));
12651ab64890Smrg	}
12661ab64890Smrg	if(!(tmp = Xmalloc(len + 1))) {
12671ab64890Smrg	    ic->private.proto.status_font = NULL;
12681ab64890Smrg	    return False;
12691ab64890Smrg	}
12701ab64890Smrg
12711ab64890Smrg	tmp[0] = '\0';
12721ab64890Smrg	for(i = 0; i < list_ret; i++) {
12731ab64890Smrg	    strcat(tmp, name_list[i]);
12741ab64890Smrg	    strcat(tmp, ",");
12751ab64890Smrg	}
12761ab64890Smrg	tmp[len - 1] = 0;
12771ab64890Smrg	ic->private.proto.status_font        = tmp;
12781ab64890Smrg	ic->private.proto.status_font_length = len - 1;
12791ab64890Smrg    }
12801ab64890Smrg    return True;
12811ab64890Smrg}
12821ab64890Smrg
1283eb411b4bSmrgBool
12841ab64890Smrg_XimEncodeSavedICATTRIBUTE(
12851ab64890Smrg    Xic			 ic,
12861ab64890Smrg    XIMResourceList	 res_list,
12871ab64890Smrg    unsigned int	 res_num,
12881ab64890Smrg    int			*idx,
12891ab64890Smrg    char		*buf,
12901ab64890Smrg    int			 size,
12911ab64890Smrg    int			*ret_len,
12921ab64890Smrg    XPointer		 top,
12931ab64890Smrg    unsigned long	 mode)
12941ab64890Smrg{
12951ab64890Smrg    int			 i;
12961ab64890Smrg    int			 num = ic->private.proto.num_saved_icvalues;
12971ab64890Smrg    XrmQuark		*quark_list = ic->private.proto.saved_icvalues;
12981ab64890Smrg    XIMResourceList	 res;
12991ab64890Smrg    XPointer		 value;
13001ab64890Smrg    CARD16		*buf_s;
13011ab64890Smrg    int			 len;
13021ab64890Smrg    int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
13031ab64890Smrg				 + sizeof(INT16); /* sizeof value length */
13041ab64890Smrg    XrmQuark		 pre_quark;
13051ab64890Smrg    XrmQuark		 sts_quark;
13061ab64890Smrg    XrmQuark		 separator;
13071ab64890Smrg
13081ab64890Smrg    if (!ic->private.proto.saved_icvalues) {
13091ab64890Smrg	*idx = -1;
13101ab64890Smrg	*ret_len = 0;
13111ab64890Smrg	return True;
13121ab64890Smrg    }
13131ab64890Smrg
13141ab64890Smrg    pre_quark = XrmStringToQuark(XNPreeditAttributes);
13151ab64890Smrg    sts_quark = XrmStringToQuark(XNStatusAttributes);
13161ab64890Smrg    separator = XrmStringToQuark(XNSeparatorofNestedList);
13171ab64890Smrg
13181ab64890Smrg    *ret_len = 0;
13191ab64890Smrg    for (i = *idx; i < num; i++) {
13201ab64890Smrg	if (quark_list[i] == separator) {
13211ab64890Smrg	    *idx = i;
13221ab64890Smrg	    return True;
13231ab64890Smrg	}
13241ab64890Smrg
13251ab64890Smrg	if (!(res = _XimGetResourceListRecByQuark(res_list,
13261ab64890Smrg						res_num, quark_list[i])))
13271ab64890Smrg	    continue;
13281ab64890Smrg
13291ab64890Smrg	if (!_XimDecodeLocalICAttr(res, top,(XPointer)&value, mode))
13301ab64890Smrg	    return False;
13311ab64890Smrg
13321ab64890Smrg	if (mode & XIM_PREEDIT_ATTR) {
13331ab64890Smrg	    if (!(_XimEncodeSavedPreeditValue(ic, res, value))) {
13341ab64890Smrg		return False;
13351ab64890Smrg	    }
13361ab64890Smrg	} else if (mode & XIM_STATUS_ATTR) {
13371ab64890Smrg	    if (!(_XimEncodeSavedStatusValue(ic, res, value))) {
13381ab64890Smrg		return False;
13391ab64890Smrg	    }
13401ab64890Smrg	}
13411ab64890Smrg
13421ab64890Smrg	buf_s = (CARD16 *)buf;
13431ab64890Smrg	if (res->resource_size == XimType_NEST) {
13441ab64890Smrg	    XimDefICValues	*ic_attr = (XimDefICValues *)top;
13451ab64890Smrg
13461ab64890Smrg	    i++;
13471ab64890Smrg	    if (res->xrm_name == pre_quark) {
13481ab64890Smrg		if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
13491ab64890Smrg				 &i, (char *)&buf_s[2], (size - min_len),
13501ab64890Smrg				 &len, (XPointer)&ic_attr->preedit_attr,
13511ab64890Smrg				(mode | XIM_PREEDIT_ATTR))) {
13521ab64890Smrg		    return False;
13531ab64890Smrg		}
13541ab64890Smrg
13551ab64890Smrg	    } else if (res->xrm_name == sts_quark) {
13561ab64890Smrg		if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
13571ab64890Smrg				&i, (char *)&buf_s[2], (size - min_len),
13581ab64890Smrg				&len, (XPointer)&ic_attr->status_attr,
13591ab64890Smrg				(mode | XIM_STATUS_ATTR))) {
13601ab64890Smrg		    return False;
13611ab64890Smrg		}
13621ab64890Smrg	    }
13631ab64890Smrg	} else {
13641ab64890Smrg	    if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
13651ab64890Smrg			 	(size - min_len), value,
13661ab64890Smrg				&len, mode, (XPointer)ic))) {
13671ab64890Smrg		return False;
13681ab64890Smrg	    }
13691ab64890Smrg	}
13701ab64890Smrg
13711ab64890Smrg	if (len == 0) {
13721ab64890Smrg	    continue;
13731ab64890Smrg	} else if (len < 0) {
13741ab64890Smrg	    if (quark_list[i] == separator)
13751ab64890Smrg		i++;
13761ab64890Smrg	    *idx = i;
13771ab64890Smrg	    return True;
13781ab64890Smrg	}
13791ab64890Smrg
13801ab64890Smrg	buf_s[0] = res->id;			/* attribute ID */
13811ab64890Smrg	buf_s[1] = len;				/* value length */
13821ab64890Smrg	XIM_SET_PAD(&buf_s[2], len);		/* pad */
13831ab64890Smrg	len += min_len;
13841ab64890Smrg
13851ab64890Smrg	buf += len;
13861ab64890Smrg	*ret_len += len;
13871ab64890Smrg	size -= len;
13881ab64890Smrg    }
13891ab64890Smrg    *idx = -1;
13901ab64890Smrg    return True;
13911ab64890Smrg}
13921ab64890Smrg#endif /* XIM_CONNECTABLE */
13931ab64890Smrg
1394eb411b4bSmrgstatic unsigned int
13951ab64890Smrg_XimCountNumberOfAttr(
13969c019ec5Smaya    CARD16	  total,
13979c019ec5Smaya    CARD16	 *attr,
13989c019ec5Smaya    unsigned int *names_len)
13991ab64890Smrg{
14001ab64890Smrg    unsigned int n;
14019c019ec5Smaya    CARD16	 len;
14029c019ec5Smaya    CARD16	 min_len = sizeof(CARD16)	/* sizeof attribute ID */
14031ab64890Smrg			 + sizeof(CARD16)	/* sizeof type of value */
14041ab64890Smrg			 + sizeof(INT16);	/* sizeof length of attribute */
14051ab64890Smrg
14061ab64890Smrg    n = 0;
14071ab64890Smrg    *names_len = 0;
14081ab64890Smrg    while (total > min_len) {
14091ab64890Smrg	len = attr[2];
14109c019ec5Smaya	if (len >= (total - min_len)) {
14119c019ec5Smaya	    return 0;
14129c019ec5Smaya	}
14131ab64890Smrg	*names_len += (len + 1);
14141ab64890Smrg	len += (min_len + XIM_PAD(len + 2));
14151ab64890Smrg	total -= len;
14161ab64890Smrg	attr = (CARD16 *)((char *)attr + len);
14171ab64890Smrg	n++;
14181ab64890Smrg    }
14191ab64890Smrg    return n;
14201ab64890Smrg}
14211ab64890Smrg
1422eb411b4bSmrgBool
14231ab64890Smrg_XimGetAttributeID(
14241ab64890Smrg    Xim			  im,
14251ab64890Smrg    CARD16		 *buf)
14261ab64890Smrg{
14279c019ec5Smaya    unsigned int	  n, names_len, values_len;
14281ab64890Smrg    XIMResourceList	  res;
14291ab64890Smrg    char		 *names;
14301ab64890Smrg    XPointer		  tmp;
14311ab64890Smrg    XIMValuesList	 *values_list;
14321ab64890Smrg    char		**values;
14331ab64890Smrg    register int	  i;
14349c019ec5Smaya    CARD16		  len;
14359c019ec5Smaya    CARD16		  min_len = sizeof(CARD16) /* sizeof attribute ID */
14361ab64890Smrg				  + sizeof(CARD16) /* sizeof type of value */
14371ab64890Smrg				  + sizeof(INT16); /* sizeof length of attr */
14381ab64890Smrg    /*
14391ab64890Smrg     * IM attribute ID
14401ab64890Smrg     */
14411ab64890Smrg
14421ab64890Smrg    if (!(n = _XimCountNumberOfAttr(buf[0], &buf[1], &names_len)))
14431ab64890Smrg	return False;
14441ab64890Smrg
14456cc2b21fSmrg    if (!(res = Xcalloc(n, sizeof(XIMResource))))
14461ab64890Smrg	return False;
14471ab64890Smrg
14481ab64890Smrg    values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
14496cc2b21fSmrg    if (!(tmp = Xcalloc(1, values_len))) {
14506cc2b21fSmrg	Xfree(res);
14511ab64890Smrg	return False;
14526cc2b21fSmrg    }
14531ab64890Smrg
14541ab64890Smrg    values_list = (XIMValuesList *)tmp;
14551ab64890Smrg    values = (char **)((char *)tmp + sizeof(XIMValuesList));
14561ab64890Smrg    names = (char *)((char *)values + (sizeof(char **) * n));
14571ab64890Smrg
14581ab64890Smrg    values_list->count_values = n;
14591ab64890Smrg    values_list->supported_values = values;
14601ab64890Smrg
14611ab64890Smrg    buf++;
14621ab64890Smrg    for (i = 0; i < n; i++) {
14631ab64890Smrg	len = buf[2];
14641ab64890Smrg	(void)memcpy(names, (char *)&buf[3], len);
14651ab64890Smrg	values[i] = names;
14661ab64890Smrg	names[len] = '\0';
14671ab64890Smrg	res[i].resource_name = names;
14681ab64890Smrg	res[i].resource_size = buf[1];
14691ab64890Smrg	res[i].id	     = buf[0];
14701ab64890Smrg	names += (len + 1);
14711ab64890Smrg	len += (min_len + XIM_PAD(len + 2));
14721ab64890Smrg	buf = (CARD16 *)((char *)buf + len);
14731ab64890Smrg    }
14741ab64890Smrg    _XIMCompileResourceList(res, n);
14751ab64890Smrg
14760f8248bfSmrg    Xfree(im->core.im_resources);
14770f8248bfSmrg    Xfree(im->core.im_values_list);
14780f8248bfSmrg
14791ab64890Smrg    im->core.im_resources     = res;
14801ab64890Smrg    im->core.im_num_resources = n;
14811ab64890Smrg    im->core.im_values_list   = values_list;
14821ab64890Smrg
14831ab64890Smrg    /*
14841ab64890Smrg     * IC attribute ID
14851ab64890Smrg     */
14861ab64890Smrg
14871ab64890Smrg    if (!(n = _XimCountNumberOfAttr(buf[0], &buf[2], &names_len)))
14881ab64890Smrg	return False;
14891ab64890Smrg
14906cc2b21fSmrg    if (!(res = Xcalloc(n, sizeof(XIMResource))))
14911ab64890Smrg	return False;
14921ab64890Smrg
14931ab64890Smrg    values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
14946cc2b21fSmrg    if (!(tmp = Xcalloc(1, values_len))) {
14956cc2b21fSmrg	Xfree(res);
14961ab64890Smrg	return False;
14976cc2b21fSmrg    }
14981ab64890Smrg
14991ab64890Smrg    values_list = (XIMValuesList *)tmp;
15001ab64890Smrg    values = (char **)((char *)tmp + sizeof(XIMValuesList));
15011ab64890Smrg    names = (char *)((char *)values + (sizeof(char **) * n));
15021ab64890Smrg
15031ab64890Smrg    values_list->count_values = n;
15041ab64890Smrg    values_list->supported_values = values;
15051ab64890Smrg
15061ab64890Smrg    buf += 2;
15071ab64890Smrg    for (i = 0; i < n; i++) {
15081ab64890Smrg	len = buf[2];
15091ab64890Smrg	(void)memcpy(names, (char *)&buf[3], len);
15101ab64890Smrg	values[i] = names;
15111ab64890Smrg	names[len] = '\0';
15121ab64890Smrg	res[i].resource_name = names;
15131ab64890Smrg	res[i].resource_size = buf[1];
15141ab64890Smrg	res[i].id	     = buf[0];
15151ab64890Smrg	names += (len + 1);
15161ab64890Smrg	len += (min_len + XIM_PAD(len + 2));
15171ab64890Smrg	buf = (CARD16 *)((char *)buf + len);
15181ab64890Smrg    }
15191ab64890Smrg    _XIMCompileResourceList(res, n);
15201ab64890Smrg
15210f8248bfSmrg
15220f8248bfSmrg    Xfree(im->core.ic_resources);
15230f8248bfSmrg    Xfree(im->core.ic_values_list);
15240f8248bfSmrg
15251ab64890Smrg    im->core.ic_resources     = res;
15261ab64890Smrg    im->core.ic_num_resources = n;
15271ab64890Smrg    im->core.ic_values_list   = values_list;
15281ab64890Smrg
15291ab64890Smrg    return True;
15301ab64890Smrg}
1531