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;
26872837c87Smaya	    if ((2 * sizeof(CARD16) + (num * sizeof(CARD32))) > 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;
38272837c87Smaya	    if ((2 * sizeof(CARD16) + (num * 3 * sizeof(CARD32))) > 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++) {
11186e467124Smrg	len = 0;
11191ab64890Smrg	buf_s = (CARD16 *)buf;
11201ab64890Smrg	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
11211ab64890Smrg	    if (_XimSetInnerICAttributes(ic, top, p, mode))
11221ab64890Smrg		continue;
11231ab64890Smrg	    return p->name;
11241ab64890Smrg	}
11251ab64890Smrg
11261ab64890Smrg	check = _XimCheckICMode(res, mode);
11271ab64890Smrg	if (check == XIM_CHECK_INVALID)
11281ab64890Smrg	    continue;
11291ab64890Smrg	else if (check == XIM_CHECK_ERROR)
11301ab64890Smrg	    return p->name;
11311ab64890Smrg
11321ab64890Smrg	if (mode & XIM_PREEDIT_ATTR) {
11331ab64890Smrg	    if (!(_XimEncodePreeditValue(ic, res, p)))
11341ab64890Smrg		return p->name;
11351ab64890Smrg	} else if (mode & XIM_STATUS_ATTR) {
11361ab64890Smrg	    if (!(_XimEncodeStatusValue(ic, res, p)))
11371ab64890Smrg		return p->name;
11381ab64890Smrg	} else {
11391ab64890Smrg	    if (!(_XimEncodeTopValue(ic, res, p)))
11401ab64890Smrg		return p->name;
11411ab64890Smrg	}
11421ab64890Smrg
11431ab64890Smrg	if (res->resource_size == XimType_NEST) {
11441ab64890Smrg	    XimDefICValues	*ic_attr = (XimDefICValues *)top;
11451ab64890Smrg
11461ab64890Smrg	    if (res->xrm_name == pre_quark) {
11471ab64890Smrg		XIMArg		*arg_rt;
11481ab64890Smrg		if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
11491ab64890Smrg				(XIMArg *)p->value, &arg_rt,
11501ab64890Smrg				(char *)&buf_s[2], (size - min_len),
11511ab64890Smrg				 &len, (XPointer)&ic_attr->preedit_attr, flag,
11521ab64890Smrg				(mode | XIM_PREEDIT_ATTR)))) {
11531ab64890Smrg		    return name;
11541ab64890Smrg		}
11551ab64890Smrg
11561ab64890Smrg	    } else if (res->xrm_name == sts_quark) {
11571ab64890Smrg		XIMArg		*arg_rt;
11581ab64890Smrg		if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
11591ab64890Smrg				(XIMArg *)p->value,  &arg_rt,
11601ab64890Smrg				(char *)&buf_s[2], (size - min_len),
11611ab64890Smrg				 &len, (XPointer)&ic_attr->status_attr, flag,
11621ab64890Smrg				(mode | XIM_STATUS_ATTR)))) {
11631ab64890Smrg		    return name;
11641ab64890Smrg		}
11651ab64890Smrg	    }
11661ab64890Smrg	} else {
11671ab64890Smrg#ifdef EXT_MOVE
11681ab64890Smrg	    if (flag)
11691ab64890Smrg		*flag |= _XimExtenArgCheck(p);
11701ab64890Smrg#endif
11711ab64890Smrg    	    if (!(_XimEncodeLocalICAttr(ic, res, top, p, mode)))
11721ab64890Smrg		return p->name;
11731ab64890Smrg
11741ab64890Smrg	    if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
11751ab64890Smrg			 	(size - min_len), p->value,
11761ab64890Smrg				&len, mode, (XPointer)ic)))
11771ab64890Smrg		return p->name;
11781ab64890Smrg	}
11791ab64890Smrg
11801ab64890Smrg	if (len == 0) {
11811ab64890Smrg	    continue;
11821ab64890Smrg	} else if (len < 0) {
11831ab64890Smrg	    *arg_ret = p;
11841ab64890Smrg	    return (char *)NULL;
11851ab64890Smrg	}
11861ab64890Smrg
11871ab64890Smrg	buf_s[0] = res->id;			/* attribute ID */
11881ab64890Smrg	buf_s[1] = len;				/* value length */
11891ab64890Smrg	XIM_SET_PAD(&buf_s[2], len);		/* pad */
11901ab64890Smrg	len += min_len;
11911ab64890Smrg
11921ab64890Smrg	buf += len;
11931ab64890Smrg	*ret_len += len;
11941ab64890Smrg	size -= len;
11951ab64890Smrg    }
11961ab64890Smrg    *arg_ret = (XIMArg *)NULL;
11971ab64890Smrg    return (char *)NULL;
11981ab64890Smrg}
11991ab64890Smrg
12001ab64890Smrg#ifdef XIM_CONNECTABLE
1201eb411b4bSmrgstatic Bool
12021ab64890Smrg_XimEncodeSavedPreeditValue(
12031ab64890Smrg    Xic			  ic,
12041ab64890Smrg    XIMResourceList	  res,
12051ab64890Smrg    XPointer		  value)
12061ab64890Smrg{
12071ab64890Smrg    int			  list_ret;
12081ab64890Smrg    XFontStruct		**struct_list;
12091ab64890Smrg    char		**name_list;
12101ab64890Smrg    char		 *tmp;
12111ab64890Smrg    int			  len;
12121ab64890Smrg    register int	  i;
12131ab64890Smrg
12141ab64890Smrg    if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
12151ab64890Smrg	if (!value)
12161ab64890Smrg	    return False;
12171ab64890Smrg
12181ab64890Smrg	if (ic->private.proto.preedit_font)
12191ab64890Smrg	    Xfree(ic->private.proto.preedit_font);
12201ab64890Smrg
12211ab64890Smrg	list_ret = XFontsOfFontSet((XFontSet)value,
12221ab64890Smrg						&struct_list, &name_list);
12231ab64890Smrg	for(i = 0, len = 0; i < list_ret; i++) {
12241ab64890Smrg	    len += (strlen(name_list[i]) + sizeof(char));
12251ab64890Smrg	}
12261ab64890Smrg	if(!(tmp = Xmalloc(len + 1))) {
12271ab64890Smrg	    ic->private.proto.preedit_font = NULL;
12281ab64890Smrg	    return False;
12291ab64890Smrg	}
12301ab64890Smrg
12311ab64890Smrg	tmp[0] = '\0';
12321ab64890Smrg	for(i = 0; i < list_ret; i++) {
12331ab64890Smrg	    strcat(tmp, name_list[i]);
12341ab64890Smrg	    strcat(tmp, ",");
12351ab64890Smrg	}
12361ab64890Smrg	tmp[len - 1] = 0;
12371ab64890Smrg	ic->private.proto.preedit_font        = tmp;
12381ab64890Smrg	ic->private.proto.preedit_font_length = len - 1;
12391ab64890Smrg    }
12401ab64890Smrg    return True;
12411ab64890Smrg}
12421ab64890Smrg
1243eb411b4bSmrgstatic Bool
12441ab64890Smrg_XimEncodeSavedStatusValue(
12451ab64890Smrg    Xic			  ic,
12461ab64890Smrg    XIMResourceList	  res,
12471ab64890Smrg    XPointer		  value)
12481ab64890Smrg{
12491ab64890Smrg    int			  list_ret;
12501ab64890Smrg    XFontStruct		**struct_list;
12511ab64890Smrg    char		**name_list;
12521ab64890Smrg    char		 *tmp;
12531ab64890Smrg    int			  len;
12541ab64890Smrg    register int	  i;
12551ab64890Smrg
12561ab64890Smrg    if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
12571ab64890Smrg	if (!value)
12581ab64890Smrg	    return False;
12591ab64890Smrg
12600f8248bfSmrg	Xfree(ic->private.proto.status_font);
12611ab64890Smrg
12621ab64890Smrg	list_ret = XFontsOfFontSet((XFontSet)value,
12631ab64890Smrg						&struct_list, &name_list);
12641ab64890Smrg	for(i = 0, len = 0; i < list_ret; i++) {
12651ab64890Smrg	    len += (strlen(name_list[i]) + sizeof(char));
12661ab64890Smrg	}
12671ab64890Smrg	if(!(tmp = Xmalloc(len + 1))) {
12681ab64890Smrg	    ic->private.proto.status_font = NULL;
12691ab64890Smrg	    return False;
12701ab64890Smrg	}
12711ab64890Smrg
12721ab64890Smrg	tmp[0] = '\0';
12731ab64890Smrg	for(i = 0; i < list_ret; i++) {
12741ab64890Smrg	    strcat(tmp, name_list[i]);
12751ab64890Smrg	    strcat(tmp, ",");
12761ab64890Smrg	}
12771ab64890Smrg	tmp[len - 1] = 0;
12781ab64890Smrg	ic->private.proto.status_font        = tmp;
12791ab64890Smrg	ic->private.proto.status_font_length = len - 1;
12801ab64890Smrg    }
12811ab64890Smrg    return True;
12821ab64890Smrg}
12831ab64890Smrg
1284eb411b4bSmrgBool
12851ab64890Smrg_XimEncodeSavedICATTRIBUTE(
12861ab64890Smrg    Xic			 ic,
12871ab64890Smrg    XIMResourceList	 res_list,
12881ab64890Smrg    unsigned int	 res_num,
12891ab64890Smrg    int			*idx,
12901ab64890Smrg    char		*buf,
12911ab64890Smrg    int			 size,
12921ab64890Smrg    int			*ret_len,
12931ab64890Smrg    XPointer		 top,
12941ab64890Smrg    unsigned long	 mode)
12951ab64890Smrg{
12961ab64890Smrg    int			 i;
12971ab64890Smrg    int			 num = ic->private.proto.num_saved_icvalues;
12981ab64890Smrg    XrmQuark		*quark_list = ic->private.proto.saved_icvalues;
12991ab64890Smrg    XIMResourceList	 res;
13001ab64890Smrg    XPointer		 value;
13011ab64890Smrg    CARD16		*buf_s;
13021ab64890Smrg    int			 len;
13031ab64890Smrg    int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
13041ab64890Smrg				 + sizeof(INT16); /* sizeof value length */
13051ab64890Smrg    XrmQuark		 pre_quark;
13061ab64890Smrg    XrmQuark		 sts_quark;
13071ab64890Smrg    XrmQuark		 separator;
13081ab64890Smrg
13091ab64890Smrg    if (!ic->private.proto.saved_icvalues) {
13101ab64890Smrg	*idx = -1;
13111ab64890Smrg	*ret_len = 0;
13121ab64890Smrg	return True;
13131ab64890Smrg    }
13141ab64890Smrg
13151ab64890Smrg    pre_quark = XrmStringToQuark(XNPreeditAttributes);
13161ab64890Smrg    sts_quark = XrmStringToQuark(XNStatusAttributes);
13171ab64890Smrg    separator = XrmStringToQuark(XNSeparatorofNestedList);
13181ab64890Smrg
13191ab64890Smrg    *ret_len = 0;
13201ab64890Smrg    for (i = *idx; i < num; i++) {
13211ab64890Smrg	if (quark_list[i] == separator) {
13221ab64890Smrg	    *idx = i;
13231ab64890Smrg	    return True;
13241ab64890Smrg	}
13251ab64890Smrg
13261ab64890Smrg	if (!(res = _XimGetResourceListRecByQuark(res_list,
13271ab64890Smrg						res_num, quark_list[i])))
13281ab64890Smrg	    continue;
13291ab64890Smrg
13301ab64890Smrg	if (!_XimDecodeLocalICAttr(res, top,(XPointer)&value, mode))
13311ab64890Smrg	    return False;
13321ab64890Smrg
13331ab64890Smrg	if (mode & XIM_PREEDIT_ATTR) {
13341ab64890Smrg	    if (!(_XimEncodeSavedPreeditValue(ic, res, value))) {
13351ab64890Smrg		return False;
13361ab64890Smrg	    }
13371ab64890Smrg	} else if (mode & XIM_STATUS_ATTR) {
13381ab64890Smrg	    if (!(_XimEncodeSavedStatusValue(ic, res, value))) {
13391ab64890Smrg		return False;
13401ab64890Smrg	    }
13411ab64890Smrg	}
13421ab64890Smrg
13431ab64890Smrg	buf_s = (CARD16 *)buf;
13441ab64890Smrg	if (res->resource_size == XimType_NEST) {
13451ab64890Smrg	    XimDefICValues	*ic_attr = (XimDefICValues *)top;
13461ab64890Smrg
13471ab64890Smrg	    i++;
13481ab64890Smrg	    if (res->xrm_name == pre_quark) {
13491ab64890Smrg		if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
13501ab64890Smrg				 &i, (char *)&buf_s[2], (size - min_len),
13511ab64890Smrg				 &len, (XPointer)&ic_attr->preedit_attr,
13521ab64890Smrg				(mode | XIM_PREEDIT_ATTR))) {
13531ab64890Smrg		    return False;
13541ab64890Smrg		}
13551ab64890Smrg
13561ab64890Smrg	    } else if (res->xrm_name == sts_quark) {
13571ab64890Smrg		if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
13581ab64890Smrg				&i, (char *)&buf_s[2], (size - min_len),
13591ab64890Smrg				&len, (XPointer)&ic_attr->status_attr,
13601ab64890Smrg				(mode | XIM_STATUS_ATTR))) {
13611ab64890Smrg		    return False;
13621ab64890Smrg		}
13631ab64890Smrg	    }
13641ab64890Smrg	} else {
13651ab64890Smrg	    if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
13661ab64890Smrg			 	(size - min_len), value,
13671ab64890Smrg				&len, mode, (XPointer)ic))) {
13681ab64890Smrg		return False;
13691ab64890Smrg	    }
13701ab64890Smrg	}
13711ab64890Smrg
13721ab64890Smrg	if (len == 0) {
13731ab64890Smrg	    continue;
13741ab64890Smrg	} else if (len < 0) {
13751ab64890Smrg	    if (quark_list[i] == separator)
13761ab64890Smrg		i++;
13771ab64890Smrg	    *idx = i;
13781ab64890Smrg	    return True;
13791ab64890Smrg	}
13801ab64890Smrg
13811ab64890Smrg	buf_s[0] = res->id;			/* attribute ID */
13821ab64890Smrg	buf_s[1] = len;				/* value length */
13831ab64890Smrg	XIM_SET_PAD(&buf_s[2], len);		/* pad */
13841ab64890Smrg	len += min_len;
13851ab64890Smrg
13861ab64890Smrg	buf += len;
13871ab64890Smrg	*ret_len += len;
13881ab64890Smrg	size -= len;
13891ab64890Smrg    }
13901ab64890Smrg    *idx = -1;
13911ab64890Smrg    return True;
13921ab64890Smrg}
13931ab64890Smrg#endif /* XIM_CONNECTABLE */
13941ab64890Smrg
1395eb411b4bSmrgstatic unsigned int
13961ab64890Smrg_XimCountNumberOfAttr(
13979c019ec5Smaya    CARD16	  total,
13989c019ec5Smaya    CARD16	 *attr,
13999c019ec5Smaya    unsigned int *names_len)
14001ab64890Smrg{
14011ab64890Smrg    unsigned int n;
14029c019ec5Smaya    CARD16	 len;
14039c019ec5Smaya    CARD16	 min_len = sizeof(CARD16)	/* sizeof attribute ID */
14041ab64890Smrg			 + sizeof(CARD16)	/* sizeof type of value */
14051ab64890Smrg			 + sizeof(INT16);	/* sizeof length of attribute */
14061ab64890Smrg
14071ab64890Smrg    n = 0;
14081ab64890Smrg    *names_len = 0;
14091ab64890Smrg    while (total > min_len) {
14101ab64890Smrg	len = attr[2];
141116add077Smrg	if (len > (total - min_len)) {
14129c019ec5Smaya	    return 0;
14139c019ec5Smaya	}
14141ab64890Smrg	*names_len += (len + 1);
14151ab64890Smrg	len += (min_len + XIM_PAD(len + 2));
14161ab64890Smrg	total -= len;
14171ab64890Smrg	attr = (CARD16 *)((char *)attr + len);
14181ab64890Smrg	n++;
14191ab64890Smrg    }
14201ab64890Smrg    return n;
14211ab64890Smrg}
14221ab64890Smrg
1423eb411b4bSmrgBool
14241ab64890Smrg_XimGetAttributeID(
14251ab64890Smrg    Xim			  im,
14261ab64890Smrg    CARD16		 *buf)
14271ab64890Smrg{
14289c019ec5Smaya    unsigned int	  n, names_len, values_len;
14291ab64890Smrg    XIMResourceList	  res;
14301ab64890Smrg    char		 *names;
14311ab64890Smrg    XPointer		  tmp;
14321ab64890Smrg    XIMValuesList	 *values_list;
14331ab64890Smrg    char		**values;
14341ab64890Smrg    register int	  i;
14359c019ec5Smaya    CARD16		  len;
14369c019ec5Smaya    CARD16		  min_len = sizeof(CARD16) /* sizeof attribute ID */
14371ab64890Smrg				  + sizeof(CARD16) /* sizeof type of value */
14381ab64890Smrg				  + sizeof(INT16); /* sizeof length of attr */
14391ab64890Smrg    /*
14401ab64890Smrg     * IM attribute ID
14411ab64890Smrg     */
14421ab64890Smrg
14431ab64890Smrg    if (!(n = _XimCountNumberOfAttr(buf[0], &buf[1], &names_len)))
14441ab64890Smrg	return False;
14451ab64890Smrg
14466cc2b21fSmrg    if (!(res = Xcalloc(n, sizeof(XIMResource))))
14471ab64890Smrg	return False;
14481ab64890Smrg
14491ab64890Smrg    values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
14506cc2b21fSmrg    if (!(tmp = Xcalloc(1, values_len))) {
14516cc2b21fSmrg	Xfree(res);
14521ab64890Smrg	return False;
14536cc2b21fSmrg    }
14541ab64890Smrg
14551ab64890Smrg    values_list = (XIMValuesList *)tmp;
14561ab64890Smrg    values = (char **)((char *)tmp + sizeof(XIMValuesList));
14571ab64890Smrg    names = (char *)((char *)values + (sizeof(char **) * n));
14581ab64890Smrg
14591ab64890Smrg    values_list->count_values = n;
14601ab64890Smrg    values_list->supported_values = values;
14611ab64890Smrg
14621ab64890Smrg    buf++;
14631ab64890Smrg    for (i = 0; i < n; i++) {
14641ab64890Smrg	len = buf[2];
14651ab64890Smrg	(void)memcpy(names, (char *)&buf[3], len);
14661ab64890Smrg	values[i] = names;
14671ab64890Smrg	names[len] = '\0';
14681ab64890Smrg	res[i].resource_name = names;
14691ab64890Smrg	res[i].resource_size = buf[1];
14701ab64890Smrg	res[i].id	     = buf[0];
14711ab64890Smrg	names += (len + 1);
14721ab64890Smrg	len += (min_len + XIM_PAD(len + 2));
14731ab64890Smrg	buf = (CARD16 *)((char *)buf + len);
14741ab64890Smrg    }
14751ab64890Smrg    _XIMCompileResourceList(res, n);
14761ab64890Smrg
14770f8248bfSmrg    Xfree(im->core.im_resources);
14780f8248bfSmrg    Xfree(im->core.im_values_list);
14790f8248bfSmrg
14801ab64890Smrg    im->core.im_resources     = res;
14811ab64890Smrg    im->core.im_num_resources = n;
14821ab64890Smrg    im->core.im_values_list   = values_list;
14831ab64890Smrg
14841ab64890Smrg    /*
14851ab64890Smrg     * IC attribute ID
14861ab64890Smrg     */
14871ab64890Smrg
14881ab64890Smrg    if (!(n = _XimCountNumberOfAttr(buf[0], &buf[2], &names_len)))
14891ab64890Smrg	return False;
14901ab64890Smrg
14916cc2b21fSmrg    if (!(res = Xcalloc(n, sizeof(XIMResource))))
14921ab64890Smrg	return False;
14931ab64890Smrg
14941ab64890Smrg    values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
14956cc2b21fSmrg    if (!(tmp = Xcalloc(1, values_len))) {
14966cc2b21fSmrg	Xfree(res);
14971ab64890Smrg	return False;
14986cc2b21fSmrg    }
14991ab64890Smrg
15001ab64890Smrg    values_list = (XIMValuesList *)tmp;
15011ab64890Smrg    values = (char **)((char *)tmp + sizeof(XIMValuesList));
15021ab64890Smrg    names = (char *)((char *)values + (sizeof(char **) * n));
15031ab64890Smrg
15041ab64890Smrg    values_list->count_values = n;
15051ab64890Smrg    values_list->supported_values = values;
15061ab64890Smrg
15071ab64890Smrg    buf += 2;
15081ab64890Smrg    for (i = 0; i < n; i++) {
15091ab64890Smrg	len = buf[2];
15101ab64890Smrg	(void)memcpy(names, (char *)&buf[3], len);
15111ab64890Smrg	values[i] = names;
15121ab64890Smrg	names[len] = '\0';
15131ab64890Smrg	res[i].resource_name = names;
15141ab64890Smrg	res[i].resource_size = buf[1];
15151ab64890Smrg	res[i].id	     = buf[0];
15161ab64890Smrg	names += (len + 1);
15171ab64890Smrg	len += (min_len + XIM_PAD(len + 2));
15181ab64890Smrg	buf = (CARD16 *)((char *)buf + len);
15191ab64890Smrg    }
15201ab64890Smrg    _XIMCompileResourceList(res, n);
15211ab64890Smrg
15220f8248bfSmrg
15230f8248bfSmrg    Xfree(im->core.ic_resources);
15240f8248bfSmrg    Xfree(im->core.ic_values_list);
15250f8248bfSmrg
15261ab64890Smrg    im->core.ic_resources     = res;
15271ab64890Smrg    im->core.ic_num_resources = n;
15281ab64890Smrg    im->core.ic_values_list   = values_list;
15291ab64890Smrg
15301ab64890Smrg    return True;
15311ab64890Smrg}
1532