Home | History | Annotate | Line # | Download | only in ximcp
      1 /******************************************************************
      2 
      3            Copyright 1992, 1993, 1994 by FUJITSU LIMITED
      4 
      5 Permission to use, copy, modify, distribute, and sell this software
      6 and its documentation for any purpose is hereby granted without fee,
      7 provided that the above copyright notice appear in all copies and
      8 that both that copyright notice and this permission notice appear
      9 in supporting documentation, and that the name of FUJITSU LIMITED
     10 not be used in advertising or publicity pertaining to distribution
     11 of the software without specific, written prior permission.
     12 FUJITSU LIMITED makes no representations about the suitability of
     13 this software for any purpose.
     14 It is provided "as is" without express or implied warranty.
     15 
     16 FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     17 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     18 EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     19 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
     20 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
     21 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     22 PERFORMANCE OF THIS SOFTWARE.
     23 
     24   Author: Takashi Fujiwara     FUJITSU LIMITED
     25                                fujiwara (at) a80.tech.yk.fujitsu.co.jp
     26 
     27 ******************************************************************/
     28 
     29 #ifdef HAVE_CONFIG_H
     30 #include <config.h>
     31 #endif
     32 #include <limits.h>
     33 
     34 #include "Xlibint.h"
     35 #include "Xlcint.h"
     36 #include "Ximint.h"
     37 
     38 
     39 static XIMResourceList
     40 _XimGetNestedListSeparator(
     41     XIMResourceList	 res_list,		/* LISTofIMATTR or IMATTR */
     42     unsigned int	 res_num)
     43 {
     44     return  _XimGetResourceListRec(res_list, res_num, XNSeparatorofNestedList);
     45 }
     46 
     47 static Bool
     48 _XimCheckInnerIMAttributes(
     49     Xim			 im,
     50     XIMArg		*arg,
     51     unsigned long	 mode)
     52 {
     53     XIMResourceList	 res;
     54     int			 check;
     55 
     56     if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
     57 			im->private.proto.im_num_inner_resources, arg->name)))
     58 	return False;
     59 
     60     check = _XimCheckIMMode(res, mode);
     61     if(check == XIM_CHECK_INVALID)
     62 	return True;
     63     else if(check == XIM_CHECK_ERROR)
     64 	return False;
     65 
     66     return True;
     67 }
     68 
     69 char *
     70 _XimMakeIMAttrIDList(
     71     Xim			 im,
     72     XIMResourceList	 res_list,
     73     unsigned int	 res_num,
     74     XIMArg		*arg,
     75     CARD16		*buf,
     76     INT16		*len,
     77     unsigned long	 mode)
     78 {
     79     register XIMArg	*p;
     80     XIMResourceList	 res;
     81     int			 check;
     82 
     83     *len = 0;
     84     if (!arg)
     85 	return (char *)NULL;
     86 
     87     for (p = arg; p->name; p++) {
     88 	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
     89 	    if (_XimCheckInnerIMAttributes(im, p, mode))
     90 		continue;
     91 	    return p->name;
     92 	}
     93 
     94 	check = _XimCheckIMMode(res, mode);
     95 	if (check == XIM_CHECK_INVALID)
     96 	    continue;
     97 	else if (check == XIM_CHECK_ERROR)
     98 	    return p->name;
     99 
    100 	*buf = res->id;
    101 	*len += sizeof(CARD16);
    102 	 buf++;
    103     }
    104     return (char *)NULL;
    105 }
    106 
    107 static Bool
    108 _XimCheckInnerICAttributes(
    109     Xic			 ic,
    110     XIMArg		*arg,
    111     unsigned long	 mode)
    112 {
    113     XIMResourceList	 res;
    114     int			 check;
    115 
    116     if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
    117 			ic->private.proto.ic_num_inner_resources, arg->name)))
    118 	return False;
    119 
    120     check = _XimCheckICMode(res, mode);
    121     if(check == XIM_CHECK_INVALID)
    122 	return True;
    123     else if(check == XIM_CHECK_ERROR)
    124 	return False;
    125 
    126     return True;
    127 }
    128 
    129 char *
    130 _XimMakeICAttrIDList(
    131     Xic			 ic,
    132     XIMResourceList	 res_list,
    133     unsigned int	 res_num,
    134     XIMArg		*arg,
    135     CARD16		*buf,
    136     INT16		*len,
    137     unsigned long	 mode)
    138 {
    139     register XIMArg	*p;
    140     XIMResourceList	 res;
    141     int			 check;
    142     XrmQuark		 pre_quark;
    143     XrmQuark		 sts_quark;
    144     char		*name;
    145     INT16		 new_len;
    146 
    147     *len = 0;
    148     if (!arg)
    149 	return (char *)NULL;
    150 
    151     pre_quark = XrmStringToQuark(XNPreeditAttributes);
    152     sts_quark = XrmStringToQuark(XNStatusAttributes);
    153 
    154     for (p = arg; p && p->name; p++) {
    155 	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
    156 	    if (_XimCheckInnerICAttributes(ic, p, mode))
    157 		continue;
    158 	    *len = -1;
    159 	    return p->name;
    160 	}
    161 
    162 	check = _XimCheckICMode(res, mode);
    163 	if(check == XIM_CHECK_INVALID)
    164 	    continue;
    165 	else if(check == XIM_CHECK_ERROR) {
    166 	    *len = -1;
    167 	    return p->name;
    168 	}
    169 
    170 	*buf = res->id;
    171 	*len += sizeof(CARD16);
    172 	buf++;
    173 	if (res->resource_size == XimType_NEST) {
    174 	    if (res->xrm_name == pre_quark) {
    175 		if ((name = _XimMakeICAttrIDList(ic, res_list, res_num,
    176 				(XIMArg *)p->value, buf, &new_len,
    177 				(mode | XIM_PREEDIT_ATTR)))) {
    178 		    if (new_len < 0) *len = -1;
    179 		    else *len += new_len;
    180 		    return name;
    181 		}
    182 		*len += new_len;
    183 		buf = (CARD16 *)((char *)buf + new_len);
    184 	    } else if (res->xrm_name == sts_quark) {
    185 		if ((name = _XimMakeICAttrIDList(ic, res_list, res_num,
    186 				(XIMArg *)p->value, buf, &new_len,
    187 				(mode | XIM_STATUS_ATTR)))) {
    188 		    if (new_len < 0) *len = -1;
    189 		    else *len += new_len;
    190 		    return name;
    191 		}
    192 		*len += new_len;
    193 		buf = (CARD16 *)((char *)buf + new_len);
    194 	    }
    195 
    196 	    if (!(res = _XimGetNestedListSeparator(res_list, res_num))) {
    197 		p++;
    198 		if (p) {
    199 		    *len = -1;
    200 		    return p->name;
    201 		}
    202 		else {
    203 		    return (char *)NULL;
    204 		}
    205 	    }
    206 	    *buf = res->id;
    207 	    *len += sizeof(CARD16);
    208 	    buf++;
    209 	}
    210     }
    211     return (char *)NULL;
    212 }
    213 
    214 static Bool
    215 _XimAttributeToValue(
    216     Xic			  ic,
    217     XIMResourceList	  res,
    218     CARD16		 *data,
    219     CARD16		  data_len,
    220     XPointer		  value,
    221     BITMASK32		  mode)
    222 {
    223     switch (res->resource_size) {
    224     case XimType_SeparatorOfNestedList:
    225     case XimType_NEST:
    226 	break;
    227 
    228     case XimType_CARD8:
    229     case XimType_CARD16:
    230     case XimType_CARD32:
    231     case XimType_Window:
    232     case XimType_XIMHotKeyState:
    233 	_XCopyToArg((XPointer)data, (XPointer *)&value, data_len);
    234 	break;
    235 
    236     case XimType_STRING8:
    237 	{
    238 	    char	*str;
    239 
    240 	    if (!(value))
    241 		return False;
    242 
    243 	    if (!(str = Xmalloc(data_len + 1)))
    244 		return False;
    245 
    246 	    (void)memcpy(str, (char *)data, data_len);
    247 	    str[data_len] = '\0';
    248 
    249 	    *((char **)value) = str;
    250 	    break;
    251 	}
    252 
    253     case XimType_XIMStyles:
    254 	{
    255 	    CARD16		 num = data[0];
    256 	    register CARD32	*style_list = (CARD32 *)&data[2];
    257 	    XIMStyle		*style;
    258 	    XIMStyles		*rep;
    259 	    register int	 i;
    260 	    char		*p;
    261 	    unsigned int         alloc_len;
    262 
    263 	    if (!(value))
    264 		return False;
    265 
    266 	    if (num > (USHRT_MAX / sizeof(XIMStyle)))
    267 		return False;
    268 	    if ((2 * sizeof(CARD16) + (num * sizeof(CARD32))) > data_len)
    269 		return False;
    270 	    alloc_len = sizeof(XIMStyles) + sizeof(XIMStyle) * num;
    271 	    if (alloc_len < sizeof(XIMStyles))
    272 		return False;
    273 	    if (!(p = Xmalloc(alloc_len)))
    274 		return False;
    275 
    276 	    rep   = (XIMStyles *)p;
    277 	    style = (XIMStyle *)(p + sizeof(XIMStyles));
    278 
    279 	    for (i = 0; i < num; i++)
    280 		style[i] = (XIMStyle)style_list[i];
    281 
    282 	    rep->count_styles = (unsigned short)num;
    283 	    rep->supported_styles = style;
    284 	    *((XIMStyles **)value) = rep;
    285 	    break;
    286 	}
    287 
    288     case XimType_XRectangle:
    289 	{
    290 	    XRectangle	*rep;
    291 
    292 	    if (!(value))
    293 		return False;
    294 
    295 	    if (!(rep = Xmalloc(sizeof(XRectangle))))
    296 		return False;
    297 
    298 	    rep->x      = data[0];
    299 	    rep->y      = data[1];
    300 	    rep->width  = data[2];
    301 	    rep->height = data[3];
    302 	    *((XRectangle **)value) = rep;
    303 	    break;
    304 	}
    305 
    306     case XimType_XPoint:
    307 	{
    308 	    XPoint	*rep;
    309 
    310 	    if (!(value))
    311 		return False;
    312 
    313 	    if (!(rep = Xmalloc(sizeof(XPoint))))
    314 		return False;
    315 
    316 	    rep->x = data[0];
    317 	    rep->y = data[1];
    318 	    *((XPoint **)value) = rep;
    319 	    break;
    320 	}
    321 
    322     case XimType_XFontSet:
    323 	{
    324 	    CARD16	 len = data[0];
    325 	    char	*base_name;
    326 	    XFontSet	 rep = (XFontSet)NULL;
    327 	    char	**missing_list = NULL;
    328 	    int		 missing_count;
    329 	    char	*def_string;
    330 
    331 	    if (!(value))
    332 		return False;
    333 	    if (!ic)
    334 		return False;
    335 	    if (len > data_len)
    336 		return False;
    337 	    if (!(base_name = Xmalloc(len + 1)))
    338 		return False;
    339 
    340 	    (void)strncpy(base_name, (char *)&data[1], (size_t)len);
    341 	    base_name[len] = '\0';
    342 
    343 	    if (mode & XIM_PREEDIT_ATTR) {
    344 		if (!strcmp(base_name, ic->private.proto.preedit_font)) {
    345 		    rep = ic->core.preedit_attr.fontset;
    346 		} else if (!ic->private.proto.preedit_font_length) {
    347 		    rep = XCreateFontSet(ic->core.im->core.display,
    348 					base_name, &missing_list,
    349 					&missing_count, &def_string);
    350 		}
    351 	    } else if (mode & XIM_STATUS_ATTR) {
    352 		if (!strcmp(base_name, ic->private.proto.status_font)) {
    353 		    rep = ic->core.status_attr.fontset;
    354 		} else if (!ic->private.proto.status_font_length) {
    355 		    rep = XCreateFontSet(ic->core.im->core.display,
    356 					base_name, &missing_list,
    357 					&missing_count, &def_string);
    358 		}
    359 	    }
    360 
    361 	    Xfree(base_name);
    362 	    Xfree(missing_list);
    363 	    *((XFontSet *)value) = rep;
    364 	    break;
    365 	}
    366 
    367     case XimType_XIMHotKeyTriggers:
    368 	{
    369 	    CARD32			 num = *((CARD32 *)data);
    370 	    register CARD32		*key_list = (CARD32 *)&data[2];
    371 	    XIMHotKeyTrigger		*key;
    372 	    XIMHotKeyTriggers		*rep;
    373 	    register int		 i;
    374 	    char			*p;
    375 	    unsigned int		 alloc_len;
    376 
    377 	    if (!(value))
    378 		return False;
    379 
    380 	    if (num > (UINT_MAX / sizeof(XIMHotKeyTrigger)))
    381 		return False;
    382 	    if ((2 * sizeof(CARD16) + (num * 3 * sizeof(CARD32))) > data_len)
    383 		return False;
    384 	    alloc_len = sizeof(XIMHotKeyTriggers)
    385 		      + sizeof(XIMHotKeyTrigger) * num;
    386 	    if (alloc_len < sizeof(XIMHotKeyTriggers))
    387 		return False;
    388 	    if (!(p = Xmalloc(alloc_len)))
    389 		return False;
    390 
    391 	    rep = (XIMHotKeyTriggers *)p;
    392 	    key = (XIMHotKeyTrigger *)(p + sizeof(XIMHotKeyTriggers));
    393 
    394 	    for (i = 0; i < num; i++, key_list += 3) {
    395 		key[i].keysym        = (KeySym)key_list[0]; /* keysym */
    396 		key[i].modifier      = (int)key_list[1];    /* modifier */
    397 		key[i].modifier_mask = (int)key_list[2];    /* modifier_mask */
    398 	    }
    399 
    400 	    rep->num_hot_key = (int)num;
    401 	    rep->key = key;
    402 	    *((XIMHotKeyTriggers **)value) = rep;
    403 	    break;
    404 	}
    405 
    406     case XimType_XIMStringConversion:
    407 	{
    408 	    break;
    409 	}
    410 
    411     default:
    412 	return False;
    413     }
    414     return True;
    415 }
    416 
    417 static Bool
    418 _XimDecodeInnerIMATTRIBUTE(
    419     Xim			 im,
    420     XIMArg		*arg)
    421 {
    422     XIMResourceList	 res;
    423     XimDefIMValues	 im_values;
    424 
    425     if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
    426 			im->private.proto.im_num_inner_resources, arg->name)))
    427 	return False;
    428 
    429     _XimGetCurrentIMValues(im, &im_values);
    430     return _XimDecodeLocalIMAttr(res, (XPointer)&im_values, arg->value);
    431 }
    432 
    433 char *
    434 _XimDecodeIMATTRIBUTE(
    435     Xim			 im,
    436     XIMResourceList	 res_list,
    437     unsigned int	 res_num,
    438     CARD16		*data,
    439     INT16		 data_len,
    440     XIMArg		*arg,
    441     BITMASK32		 mode)
    442 {
    443     register XIMArg	*p;
    444     XIMResourceList	 res;
    445     int			 check;
    446     INT16		 len;
    447     CARD16		*buf;
    448     INT16		 total;
    449     INT16		 min_len = sizeof(CARD16)	/* sizeof attributeID */
    450 			 	 + sizeof(INT16);	/* sizeof length */
    451 
    452     for (p = arg; p->name; p++) {
    453 	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
    454 	    if (_XimDecodeInnerIMATTRIBUTE(im, p))
    455 		continue;
    456 	    return p->name;
    457 	}
    458 
    459 	check = _XimCheckIMMode(res, mode);
    460 	if(check == XIM_CHECK_INVALID)
    461 	    continue;
    462 	else if(check == XIM_CHECK_ERROR)
    463 	    return p->name;
    464 
    465 	total = data_len;
    466 	buf = data;
    467 	while (total >= min_len) {
    468 	    if (res->id == buf[0])
    469 		break;
    470 
    471 	    len = buf[1];
    472 	    len += XIM_PAD(len) + min_len;
    473 	    buf = (CARD16 *)((char *)buf + len);
    474 	    total -= len;
    475 	}
    476 	if (total < min_len)
    477 	    return p->name;
    478 
    479 	if (!(_XimAttributeToValue((Xic) im->private.local.current_ic,
    480 				   res, &buf[2], buf[1], p->value, mode)))
    481 	    return p->name;
    482     }
    483     return (char *)NULL;
    484 }
    485 
    486 static Bool
    487 _XimDecodeInnerICATTRIBUTE(
    488     Xic			 ic,
    489     XIMArg		*arg,
    490     unsigned long	 mode)
    491 {
    492     XIMResourceList	 res;
    493     XimDefICValues	 ic_values;
    494 
    495     if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
    496 			ic->private.proto.ic_num_inner_resources, arg->name)))
    497 	return False;
    498 
    499     _XimGetCurrentICValues(ic, &ic_values);
    500     if (!_XimDecodeLocalICAttr(res, (XPointer)&ic_values, arg->value, mode))
    501 	return False;
    502     _XimSetCurrentICValues(ic, &ic_values);
    503     return True;
    504 }
    505 
    506 char *
    507 _XimDecodeICATTRIBUTE(
    508     Xic			 ic,
    509     XIMResourceList	 res_list,
    510     unsigned int	 res_num,
    511     CARD16		*data,
    512     INT16		 data_len,
    513     XIMArg		*arg,
    514     BITMASK32		 mode)
    515 {
    516     register XIMArg	*p;
    517     XIMResourceList	 res;
    518     int			 check;
    519     INT16		 len;
    520     CARD16		*buf;
    521     INT16		 total;
    522     char		*name;
    523     INT16		 min_len = sizeof(CARD16)	/* sizeof attributeID */
    524 			 	 + sizeof(INT16);	/* sizeof length */
    525     XrmQuark		 pre_quark;
    526     XrmQuark		 sts_quark;
    527 
    528     if (!arg)
    529 	return (char *)NULL;
    530 
    531     pre_quark = XrmStringToQuark(XNPreeditAttributes);
    532     sts_quark = XrmStringToQuark(XNStatusAttributes);
    533 
    534     for (p = arg; p->name; p++) {
    535 	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
    536 	    if (_XimDecodeInnerICATTRIBUTE(ic, p, mode))
    537 		continue;
    538 	    return p->name;
    539 	}
    540 
    541 	check = _XimCheckICMode(res, mode);
    542 	if (check == XIM_CHECK_INVALID)
    543 	    continue;
    544 	else if (check == XIM_CHECK_ERROR)
    545 	    return p->name;
    546 
    547 	total = data_len;
    548 	buf = data;
    549 	while (total >= min_len) {
    550 	    if (res->id == buf[0])
    551 		break;
    552 
    553 	    len = buf[1];
    554 	    len += XIM_PAD(len) + min_len;
    555 	    buf = (CARD16 *)((char *)buf + len);
    556 	    total -= len;
    557 	}
    558 	if (total < min_len)
    559 	    return p->name;
    560 
    561 	if (res->resource_size == XimType_NEST) {
    562 	    if (res->xrm_name == pre_quark) {
    563 	        if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num,
    564 			&buf[2], buf[1], (XIMArg *)p->value,
    565 			(mode | XIM_PREEDIT_ATTR))))
    566 		    return name;
    567 	    } else if (res->xrm_name == sts_quark) {
    568 	        if ((name = _XimDecodeICATTRIBUTE(ic, res_list, res_num,
    569 			&buf[2], buf[1], (XIMArg *)p->value,
    570 			(mode | XIM_STATUS_ATTR))))
    571 		    return name;
    572 	    }
    573 	} else {
    574 	    if (!(_XimAttributeToValue(ic, res, &buf[2], buf[1],
    575 							p->value, mode)))
    576 		return p->name;
    577 	}
    578     }
    579     return (char *)NULL;
    580 }
    581 
    582 static Bool
    583 _XimValueToAttribute(
    584     XIMResourceList	 res,
    585     XPointer		 buf,
    586     int			 buf_size,
    587     XPointer		 value,
    588     int			*len,
    589     unsigned long	 mode,
    590     XPointer		 param)
    591 {
    592     int			 ret_len;
    593 
    594     switch (res->resource_size) {
    595     case XimType_SeparatorOfNestedList:
    596     case XimType_NEST:
    597 	*len = 0;
    598 	break;
    599 
    600     case XimType_CARD8:
    601 	ret_len = sizeof(CARD8);
    602 	if (buf_size < ret_len + XIM_PAD(ret_len)) {
    603 	    *len = -1;
    604 	    return False;
    605 	}
    606 
    607 	*((CARD8 *)buf) = (CARD8)(long)value;
    608 	*len = ret_len;
    609 	break;
    610 
    611     case XimType_CARD16:
    612 	ret_len = sizeof(CARD16);
    613 	if (buf_size < ret_len + XIM_PAD(ret_len)) {
    614 	    *len = -1;
    615 	    return False;
    616 	}
    617 
    618 	*((CARD16 *)buf) = (CARD16)(long)value;
    619 	*len = ret_len;
    620 	break;
    621 
    622     case XimType_CARD32:
    623     case XimType_Window:
    624     case XimType_XIMHotKeyState:
    625 	ret_len = sizeof(CARD32);
    626 	if (buf_size < ret_len + XIM_PAD(ret_len)) {
    627 	    *len = -1;
    628 	    return False;
    629 	}
    630 
    631 	*((CARD32 *)buf) = (CARD32)(long)value;
    632 	*len = ret_len;
    633 	break;
    634 
    635     case XimType_STRING8:
    636 	if (!value) {
    637 	    *len = 0;
    638 	    return False;
    639 	}
    640 
    641 	ret_len = strlen((char *)value);
    642 	if (buf_size < ret_len + XIM_PAD(ret_len)) {
    643 	    *len = -1;
    644 	    return False;
    645 	}
    646 
    647 	(void)memcpy((char *)buf, (char *)value, ret_len);
    648 	*len = ret_len;
    649 	break;
    650 
    651     case XimType_XRectangle:
    652 	{
    653 	    XRectangle	*rect = (XRectangle *)value;
    654 	    CARD16	*buf_s = (CARD16 *)buf;
    655 
    656 	    if (!rect) {
    657 		*len = 0;
    658 		return False;
    659 	    }
    660 
    661 	    ret_len = sizeof(INT16)		/* sizeof X */
    662 	    	    + sizeof(INT16)		/* sizeof Y */
    663 	            + sizeof(CARD16)		/* sizeof width */
    664 	            + sizeof(CARD16);		/* sizeof height */
    665 	    if (buf_size < ret_len + XIM_PAD(ret_len)) {
    666 		*len = -1;
    667 		return False;
    668 	    }
    669 
    670 	    buf_s[0] = (CARD16)rect->x;		/* X */
    671 	    buf_s[1] = (CARD16)rect->y;		/* Y */
    672 	    buf_s[2] = (CARD16)rect->width;	/* width */
    673 	    buf_s[3] = (CARD16)rect->height;	/* heght */
    674 	    *len = ret_len;
    675 	    break;
    676 	}
    677 
    678     case XimType_XPoint:
    679 	{
    680 	    XPoint	*point = (XPoint *)value;
    681 	    CARD16	*buf_s = (CARD16 *)buf;
    682 
    683 	    if (!point) {
    684 		*len = 0;
    685 		return False;
    686 	    }
    687 
    688 	    ret_len = sizeof(INT16)		/* sizeof X */
    689 	            + sizeof(INT16);		/* sizeof Y */
    690 	    if (buf_size < ret_len + XIM_PAD(ret_len)) {
    691 		*len = -1;
    692 		return False;
    693 	    }
    694 
    695 	    buf_s[0] = (CARD16)point->x;		/* X */
    696 	    buf_s[1] = (CARD16)point->y;		/* Y */
    697 	    *len = ret_len;
    698 	    break;
    699 	}
    700 
    701     case XimType_XFontSet:
    702 	{
    703 	    XFontSet	 font = (XFontSet)value;
    704 	    Xic		 ic = (Xic)param;
    705 	    char	*base_name = NULL;
    706 	    int		 length = 0;
    707 	    CARD16	*buf_s = (CARD16 *)buf;
    708 
    709 	    if (!font) {
    710 		*len = 0;
    711 		return False;
    712 	    }
    713 
    714 	    if (mode & XIM_PREEDIT_ATTR) {
    715 		base_name = ic->private.proto.preedit_font;
    716 		length	  = ic->private.proto.preedit_font_length;
    717 	    } else if (mode & XIM_STATUS_ATTR) {
    718 		base_name = ic->private.proto.status_font;
    719 		length	  = ic->private.proto.status_font_length;
    720 	    }
    721 
    722 	    if (!base_name) {
    723 		*len = 0;
    724 		return False;
    725 	    }
    726 
    727 	    ret_len = sizeof(CARD16)		/* sizeof length of Base name */
    728 		    + length;			/* sizeof Base font name list */
    729 	    if (buf_size < ret_len + XIM_PAD(ret_len)) {
    730 		*len = -1;
    731 		return False;
    732 	    }
    733 
    734 	    buf_s[0] = (INT16)length;		/* length of Base font name */
    735 	    (void)memcpy((char *)&buf_s[1], base_name, length);
    736 						/* Base font name list */
    737 	    *len = ret_len;
    738 	    break;
    739 	}
    740 
    741     case XimType_XIMHotKeyTriggers:
    742 	{
    743 	    XIMHotKeyTriggers	*hotkey = (XIMHotKeyTriggers *)value;
    744 	    INT32		 num;
    745 	    CARD32		*buf_l = (CARD32 *)buf;
    746 	    register CARD32	*key = (CARD32 *)&buf_l[1];
    747 	    register int	 i;
    748 
    749 	    if (!hotkey) {
    750 		*len = 0;
    751 		return False;
    752 	    }
    753 	    num = (INT32)hotkey->num_hot_key;
    754 
    755 	    ret_len = sizeof(INT32)		/* sizeof number of key list */
    756 	           + (sizeof(CARD32)		/* sizeof keysyn */
    757 	           +  sizeof(CARD32)		/* sizeof modifier */
    758 	           +  sizeof(CARD32))		/* sizeof modifier_mask */
    759 	           *  num;			/* number of key list */
    760 	    if (buf_size < ret_len + XIM_PAD(ret_len)) {
    761 		*len = -1;
    762 		return False;
    763 	    }
    764 
    765 	    buf_l[0] = num;		/* number of key list */
    766 	    for (i = 0; i < num; i++, key += 3) {
    767 		key[0] = (CARD32)(hotkey->key[i].keysym);
    768 						/* keysym */
    769 		key[1] = (CARD32)(hotkey->key[i].modifier);
    770 						/* modifier */
    771 		key[2] = (CARD32)(hotkey->key[i].modifier_mask);
    772 						/* modifier_mask */
    773 	    }
    774 	    *len = ret_len;
    775 	    break;
    776 	}
    777 
    778     case XimType_XIMStringConversion:
    779 	{
    780 	    *len = 0;
    781 	    break;
    782 	}
    783 
    784     default:
    785 	return False;
    786     }
    787     return True;
    788 }
    789 
    790 static Bool
    791 _XimSetInnerIMAttributes(
    792     Xim			 im,
    793     XPointer		 top,
    794     XIMArg		*arg,
    795     unsigned long	 mode)
    796 {
    797     XIMResourceList	 res;
    798     int			 check;
    799 
    800     if (!(res = _XimGetResourceListRec(im->private.proto.im_inner_resources,
    801 			im->private.proto.im_num_inner_resources, arg->name)))
    802 	return False;
    803 
    804     check = _XimCheckIMMode(res, mode);
    805     if(check == XIM_CHECK_INVALID)
    806 	return True;
    807     else if(check == XIM_CHECK_ERROR)
    808 	return False;
    809 
    810     return _XimEncodeLocalIMAttr(res, top, arg->value);
    811 }
    812 
    813 char *
    814 _XimEncodeIMATTRIBUTE(
    815     Xim			  im,
    816     XIMResourceList	  res_list,
    817     unsigned int	  res_num,
    818     XIMArg		 *arg,
    819     XIMArg		**arg_ret,
    820     char		 *buf,
    821     int			  size,
    822     int			 *ret_len,
    823     XPointer		  top,
    824     unsigned long	  mode)
    825 {
    826     register XIMArg	*p;
    827     XIMResourceList	 res;
    828     int			 check;
    829     CARD16		*buf_s;
    830     int			 len;
    831     int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
    832 				 + sizeof(INT16); /* sizeof value length */
    833 
    834     *ret_len = 0;
    835     for (p = arg; p->name; p++) {
    836 	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
    837 	    if (_XimSetInnerIMAttributes(im, top, p, mode))
    838 		continue;
    839 	    return p->name;
    840 	}
    841 
    842 	check = _XimCheckIMMode(res, mode);
    843 	if (check == XIM_CHECK_INVALID)
    844 	    continue;
    845 	else if (check == XIM_CHECK_ERROR)
    846 	    return p->name;
    847 
    848 	if (!(_XimEncodeLocalIMAttr(res, top, p->value)))
    849 	    return p->name;
    850 
    851 	buf_s = (CARD16 *)buf;
    852 	if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2], (size - min_len),
    853 				p->value, &len, mode, (XPointer)NULL)))
    854 	    return p->name;
    855 
    856 	if (len == 0) {
    857 	    continue;
    858 	} else if (len < 0) {
    859 	    *arg_ret = p;
    860 	    return (char *)NULL;
    861 	}
    862 
    863 	buf_s[0] = res->id;			/* attribute ID */
    864 	buf_s[1] = len;				/* value length */
    865 	XIM_SET_PAD(&buf_s[2], len);		/* pad */
    866 	len += min_len;
    867 
    868 	buf += len;
    869 	*ret_len += len;
    870 	size -= len;
    871     }
    872     *arg_ret = (XIMArg *)NULL;
    873     return (char *)NULL;
    874 }
    875 
    876 #ifdef XIM_CONNECTABLE
    877 Bool
    878 _XimEncodeSavedIMATTRIBUTE(
    879     Xim			 im,
    880     XIMResourceList	 res_list,
    881     unsigned int	 res_num,
    882     int			*idx,
    883     char		*buf,
    884     int			 size,
    885     int			*ret_len,
    886     XPointer		 top,
    887     unsigned long	 mode)
    888 {
    889     register int	 i;
    890     int			 num = im->private.proto.num_saved_imvalues;
    891     XrmQuark		*quark_list = im->private.proto.saved_imvalues;
    892     XIMResourceList	 res;
    893     XPointer		 value;
    894     CARD16		*buf_s;
    895     int			 len;
    896     int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
    897 				 + sizeof(INT16); /* sizeof value length */
    898 
    899     if (!im->private.proto.saved_imvalues) {
    900 	*idx = -1;
    901 	*ret_len = 0;
    902 	return True;
    903     }
    904 
    905     *ret_len = 0;
    906     for (i = *idx; i < num; i++) {
    907 	if (!(res = _XimGetResourceListRecByQuark(res_list,
    908 						res_num, quark_list[i])))
    909 	    continue;
    910 
    911 	if (!_XimDecodeLocalIMAttr(res, top, value))
    912 	    return False;
    913 
    914 	buf_s = (CARD16 *)buf;
    915 	if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
    916 			(size - min_len), value, &len, mode, (XPointer)NULL)))
    917 	    return False;
    918 
    919 	if (len == 0) {
    920 	    continue;
    921 	} else if (len < 0) {
    922 	    *idx = i;
    923 	    return True;
    924 	}
    925 
    926 	buf_s[0] = res->id;			/* attribute ID */
    927 	buf_s[1] = len;				/* value length */
    928 	XIM_SET_PAD(&buf_s[2], len);		/* pad */
    929 	len += min_len;
    930 
    931 	buf += len;
    932 	*ret_len += len;
    933 	size -= len;
    934     }
    935     *idx = -1;
    936     return True;
    937 }
    938 #endif /* XIM_CONNECTABLE */
    939 
    940 static Bool
    941 _XimEncodeTopValue(
    942     Xic			 ic,
    943     XIMResourceList	 res,
    944     XIMArg		*p)
    945 {
    946     if (res->xrm_name == XrmStringToQuark(XNClientWindow)) {
    947 	ic->core.client_window = (Window)p->value;
    948 	if (ic->core.focus_window == (Window)0)
    949 	    ic->core.focus_window = ic->core.client_window;
    950 	_XimRegisterFilter(ic);
    951 
    952     } else if (res->xrm_name == XrmStringToQuark(XNFocusWindow)) {
    953 	if (ic->core.client_window) {
    954 	    _XimUnregisterFilter(ic);
    955 	    ic->core.focus_window = (Window)p->value;
    956 	    _XimRegisterFilter(ic);
    957 	} else /* client_window not yet */
    958 	    ic->core.focus_window = (Window)p->value;
    959     }
    960     return True;
    961 }
    962 
    963 static Bool
    964 _XimEncodePreeditValue(
    965     Xic			 ic,
    966     XIMResourceList	 res,
    967     XIMArg		*p)
    968 {
    969     if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
    970 	XStandardColormap	*colormap_ret;
    971 	int			 count;
    972 
    973 	if (!(XGetRGBColormaps(ic->core.im->core.display,
    974 				ic->core.focus_window, &colormap_ret,
    975 				&count, (Atom)p->value)))
    976 	    return False;
    977 
    978 	XFree(colormap_ret);
    979     } else if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
    980 	int		  list_ret;
    981 	XFontStruct	**struct_list;
    982 	char		**name_list;
    983 	char		 *tmp;
    984 	int		  len;
    985 	register int	  i;
    986 
    987 	if (!p->value)
    988 	    return False;
    989 
    990 	Xfree(ic->private.proto.preedit_font);
    991 
    992 	list_ret = XFontsOfFontSet((XFontSet)p->value,
    993 						 &struct_list, &name_list);
    994 	for (i = 0, len = 0; i < list_ret; i++) {
    995 	     len += (strlen(name_list[i]) + sizeof(char));
    996 	}
    997 	if (!(tmp = Xmalloc(len + 1))) {
    998 	    ic->private.proto.preedit_font = NULL;
    999 	    return False;
   1000 	}
   1001 
   1002 	tmp[0] = '\0';
   1003 	for (i = 0; i < list_ret; i++) {
   1004 	    strcat(tmp, name_list[i]);
   1005 	    strcat(tmp, ",");
   1006 	}
   1007 	tmp[len - 1] = 0;
   1008 	ic->private.proto.preedit_font        = tmp;
   1009 	ic->private.proto.preedit_font_length = len - 1;
   1010     }
   1011     return True;
   1012 }
   1013 
   1014 static Bool
   1015 _XimEncodeStatusValue(
   1016     Xic			 ic,
   1017     XIMResourceList	 res,
   1018     XIMArg		*p)
   1019 {
   1020     if (res->xrm_name == XrmStringToQuark(XNStdColormap)) {
   1021 	XStandardColormap	*colormap_ret = NULL;
   1022 	int			 count;
   1023 
   1024 	if (!(XGetRGBColormaps(ic->core.im->core.display,
   1025 				ic->core.focus_window, &colormap_ret,
   1026 				&count, (Atom)p->value)))
   1027 	    return False;
   1028 
   1029 	XFree(colormap_ret);
   1030     } else if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
   1031 	int		  list_ret;
   1032 	XFontStruct	**struct_list;
   1033 	char		**name_list;
   1034 	char		 *tmp;
   1035 	int		  len;
   1036 	register int	  i;
   1037 
   1038 	if (!p->value)
   1039 	    return False;
   1040 
   1041 	Xfree(ic->private.proto.status_font);
   1042 
   1043 	list_ret = XFontsOfFontSet((XFontSet)p->value,
   1044 						 &struct_list, &name_list);
   1045 	for (i = 0, len = 0; i < list_ret; i++) {
   1046 	     len += (strlen(name_list[i]) + sizeof(char));
   1047 	}
   1048 	if (!(tmp = Xmalloc(len+1))) {
   1049 	    ic->private.proto.status_font = NULL;
   1050 	    return False;
   1051 	}
   1052 
   1053 	tmp[0] = '\0';
   1054 	for(i = 0; i < list_ret; i++) {
   1055 	    strcat(tmp, name_list[i]);
   1056 	    strcat(tmp, ",");
   1057 	}
   1058 	tmp[len - 1] = 0;
   1059 	ic->private.proto.status_font        = tmp;
   1060 	ic->private.proto.status_font_length = len - 1;
   1061     }
   1062     return True;
   1063 }
   1064 
   1065 static Bool
   1066 _XimSetInnerICAttributes(
   1067     Xic			 ic,
   1068     XPointer		 top,
   1069     XIMArg		*arg,
   1070     unsigned long	 mode)
   1071 {
   1072     XIMResourceList	 res;
   1073     int			 check;
   1074 
   1075     if (!(res = _XimGetResourceListRec(ic->private.proto.ic_inner_resources,
   1076 			ic->private.proto.ic_num_inner_resources, arg->name)))
   1077 	return False;
   1078 
   1079     check = _XimCheckICMode(res, mode);
   1080     if(check == XIM_CHECK_INVALID)
   1081 	return True;
   1082     else if(check == XIM_CHECK_ERROR)
   1083 	return False;
   1084 
   1085     return _XimEncodeLocalICAttr(ic, res, top, arg, mode);
   1086 }
   1087 
   1088 char *
   1089 _XimEncodeICATTRIBUTE(
   1090     Xic			  ic,
   1091     XIMResourceList	  res_list,
   1092     unsigned int	  res_num,
   1093     XIMArg		 *arg,
   1094     XIMArg		**arg_ret,
   1095     char		 *buf,
   1096     int			  size,
   1097     int			 *ret_len,
   1098     XPointer		  top,
   1099     BITMASK32		 *flag,
   1100     unsigned long	  mode)
   1101 {
   1102     register XIMArg	*p;
   1103     XIMResourceList	 res;
   1104     int			 check;
   1105     CARD16		*buf_s;
   1106     int			 len;
   1107     int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
   1108 				 + sizeof(INT16); /* sizeof value length */
   1109     XrmQuark		 pre_quark;
   1110     XrmQuark		 sts_quark;
   1111     char		*name;
   1112 
   1113     pre_quark = XrmStringToQuark(XNPreeditAttributes);
   1114     sts_quark = XrmStringToQuark(XNStatusAttributes);
   1115 
   1116     *ret_len = 0;
   1117     for (p = arg; p && p->name; p++) {
   1118 	len = 0;
   1119 	buf_s = (CARD16 *)buf;
   1120 	if (!(res = _XimGetResourceListRec(res_list, res_num, p->name))) {
   1121 	    if (_XimSetInnerICAttributes(ic, top, p, mode))
   1122 		continue;
   1123 	    return p->name;
   1124 	}
   1125 
   1126 	check = _XimCheckICMode(res, mode);
   1127 	if (check == XIM_CHECK_INVALID)
   1128 	    continue;
   1129 	else if (check == XIM_CHECK_ERROR)
   1130 	    return p->name;
   1131 
   1132 	if (mode & XIM_PREEDIT_ATTR) {
   1133 	    if (!(_XimEncodePreeditValue(ic, res, p)))
   1134 		return p->name;
   1135 	} else if (mode & XIM_STATUS_ATTR) {
   1136 	    if (!(_XimEncodeStatusValue(ic, res, p)))
   1137 		return p->name;
   1138 	} else {
   1139 	    if (!(_XimEncodeTopValue(ic, res, p)))
   1140 		return p->name;
   1141 	}
   1142 
   1143 	if (res->resource_size == XimType_NEST) {
   1144 	    XimDefICValues	*ic_attr = (XimDefICValues *)top;
   1145 
   1146 	    if (res->xrm_name == pre_quark) {
   1147 		XIMArg		*arg_rt;
   1148 		if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
   1149 				(XIMArg *)p->value, &arg_rt,
   1150 				(char *)&buf_s[2], (size - min_len),
   1151 				 &len, (XPointer)&ic_attr->preedit_attr, flag,
   1152 				(mode | XIM_PREEDIT_ATTR)))) {
   1153 		    return name;
   1154 		}
   1155 
   1156 	    } else if (res->xrm_name == sts_quark) {
   1157 		XIMArg		*arg_rt;
   1158 		if ((name = _XimEncodeICATTRIBUTE(ic, res_list, res_num,
   1159 				(XIMArg *)p->value,  &arg_rt,
   1160 				(char *)&buf_s[2], (size - min_len),
   1161 				 &len, (XPointer)&ic_attr->status_attr, flag,
   1162 				(mode | XIM_STATUS_ATTR)))) {
   1163 		    return name;
   1164 		}
   1165 	    }
   1166 	} else {
   1167 #ifdef EXT_MOVE
   1168 	    if (flag)
   1169 		*flag |= _XimExtenArgCheck(p);
   1170 #endif
   1171     	    if (!(_XimEncodeLocalICAttr(ic, res, top, p, mode)))
   1172 		return p->name;
   1173 
   1174 	    if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
   1175 			 	(size - min_len), p->value,
   1176 				&len, mode, (XPointer)ic)))
   1177 		return p->name;
   1178 	}
   1179 
   1180 	if (len == 0) {
   1181 	    continue;
   1182 	} else if (len < 0) {
   1183 	    *arg_ret = p;
   1184 	    return (char *)NULL;
   1185 	}
   1186 
   1187 	buf_s[0] = res->id;			/* attribute ID */
   1188 	buf_s[1] = len;				/* value length */
   1189 	XIM_SET_PAD(&buf_s[2], len);		/* pad */
   1190 	len += min_len;
   1191 
   1192 	buf += len;
   1193 	*ret_len += len;
   1194 	size -= len;
   1195     }
   1196     *arg_ret = (XIMArg *)NULL;
   1197     return (char *)NULL;
   1198 }
   1199 
   1200 #ifdef XIM_CONNECTABLE
   1201 static Bool
   1202 _XimEncodeSavedPreeditValue(
   1203     Xic			  ic,
   1204     XIMResourceList	  res,
   1205     XPointer		  value)
   1206 {
   1207     int			  list_ret;
   1208     XFontStruct		**struct_list;
   1209     char		**name_list;
   1210     char		 *tmp;
   1211     int			  len;
   1212     register int	  i;
   1213 
   1214     if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
   1215 	if (!value)
   1216 	    return False;
   1217 
   1218 	if (ic->private.proto.preedit_font)
   1219 	    Xfree(ic->private.proto.preedit_font);
   1220 
   1221 	list_ret = XFontsOfFontSet((XFontSet)value,
   1222 						&struct_list, &name_list);
   1223 	for(i = 0, len = 0; i < list_ret; i++) {
   1224 	    len += (strlen(name_list[i]) + sizeof(char));
   1225 	}
   1226 	if(!(tmp = Xmalloc(len + 1))) {
   1227 	    ic->private.proto.preedit_font = NULL;
   1228 	    return False;
   1229 	}
   1230 
   1231 	tmp[0] = '\0';
   1232 	for(i = 0; i < list_ret; i++) {
   1233 	    strcat(tmp, name_list[i]);
   1234 	    strcat(tmp, ",");
   1235 	}
   1236 	tmp[len - 1] = 0;
   1237 	ic->private.proto.preedit_font        = tmp;
   1238 	ic->private.proto.preedit_font_length = len - 1;
   1239     }
   1240     return True;
   1241 }
   1242 
   1243 static Bool
   1244 _XimEncodeSavedStatusValue(
   1245     Xic			  ic,
   1246     XIMResourceList	  res,
   1247     XPointer		  value)
   1248 {
   1249     int			  list_ret;
   1250     XFontStruct		**struct_list;
   1251     char		**name_list;
   1252     char		 *tmp;
   1253     int			  len;
   1254     register int	  i;
   1255 
   1256     if (res->xrm_name == XrmStringToQuark(XNFontSet)) {
   1257 	if (!value)
   1258 	    return False;
   1259 
   1260 	Xfree(ic->private.proto.status_font);
   1261 
   1262 	list_ret = XFontsOfFontSet((XFontSet)value,
   1263 						&struct_list, &name_list);
   1264 	for(i = 0, len = 0; i < list_ret; i++) {
   1265 	    len += (strlen(name_list[i]) + sizeof(char));
   1266 	}
   1267 	if(!(tmp = Xmalloc(len + 1))) {
   1268 	    ic->private.proto.status_font = NULL;
   1269 	    return False;
   1270 	}
   1271 
   1272 	tmp[0] = '\0';
   1273 	for(i = 0; i < list_ret; i++) {
   1274 	    strcat(tmp, name_list[i]);
   1275 	    strcat(tmp, ",");
   1276 	}
   1277 	tmp[len - 1] = 0;
   1278 	ic->private.proto.status_font        = tmp;
   1279 	ic->private.proto.status_font_length = len - 1;
   1280     }
   1281     return True;
   1282 }
   1283 
   1284 Bool
   1285 _XimEncodeSavedICATTRIBUTE(
   1286     Xic			 ic,
   1287     XIMResourceList	 res_list,
   1288     unsigned int	 res_num,
   1289     int			*idx,
   1290     char		*buf,
   1291     int			 size,
   1292     int			*ret_len,
   1293     XPointer		 top,
   1294     unsigned long	 mode)
   1295 {
   1296     int			 i;
   1297     int			 num = ic->private.proto.num_saved_icvalues;
   1298     XrmQuark		*quark_list = ic->private.proto.saved_icvalues;
   1299     XIMResourceList	 res;
   1300     XPointer		 value;
   1301     CARD16		*buf_s;
   1302     int			 len;
   1303     int			 min_len = sizeof(CARD16) /* sizeof attribute ID */
   1304 				 + sizeof(INT16); /* sizeof value length */
   1305     XrmQuark		 pre_quark;
   1306     XrmQuark		 sts_quark;
   1307     XrmQuark		 separator;
   1308 
   1309     if (!ic->private.proto.saved_icvalues) {
   1310 	*idx = -1;
   1311 	*ret_len = 0;
   1312 	return True;
   1313     }
   1314 
   1315     pre_quark = XrmStringToQuark(XNPreeditAttributes);
   1316     sts_quark = XrmStringToQuark(XNStatusAttributes);
   1317     separator = XrmStringToQuark(XNSeparatorofNestedList);
   1318 
   1319     *ret_len = 0;
   1320     for (i = *idx; i < num; i++) {
   1321 	if (quark_list[i] == separator) {
   1322 	    *idx = i;
   1323 	    return True;
   1324 	}
   1325 
   1326 	if (!(res = _XimGetResourceListRecByQuark(res_list,
   1327 						res_num, quark_list[i])))
   1328 	    continue;
   1329 
   1330 	if (!_XimDecodeLocalICAttr(res, top,(XPointer)&value, mode))
   1331 	    return False;
   1332 
   1333 	if (mode & XIM_PREEDIT_ATTR) {
   1334 	    if (!(_XimEncodeSavedPreeditValue(ic, res, value))) {
   1335 		return False;
   1336 	    }
   1337 	} else if (mode & XIM_STATUS_ATTR) {
   1338 	    if (!(_XimEncodeSavedStatusValue(ic, res, value))) {
   1339 		return False;
   1340 	    }
   1341 	}
   1342 
   1343 	buf_s = (CARD16 *)buf;
   1344 	if (res->resource_size == XimType_NEST) {
   1345 	    XimDefICValues	*ic_attr = (XimDefICValues *)top;
   1346 
   1347 	    i++;
   1348 	    if (res->xrm_name == pre_quark) {
   1349 		if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
   1350 				 &i, (char *)&buf_s[2], (size - min_len),
   1351 				 &len, (XPointer)&ic_attr->preedit_attr,
   1352 				(mode | XIM_PREEDIT_ATTR))) {
   1353 		    return False;
   1354 		}
   1355 
   1356 	    } else if (res->xrm_name == sts_quark) {
   1357 		if (!_XimEncodeSavedICATTRIBUTE(ic, res_list, res_num,
   1358 				&i, (char *)&buf_s[2], (size - min_len),
   1359 				&len, (XPointer)&ic_attr->status_attr,
   1360 				(mode | XIM_STATUS_ATTR))) {
   1361 		    return False;
   1362 		}
   1363 	    }
   1364 	} else {
   1365 	    if (!(_XimValueToAttribute(res, (XPointer)&buf_s[2],
   1366 			 	(size - min_len), value,
   1367 				&len, mode, (XPointer)ic))) {
   1368 		return False;
   1369 	    }
   1370 	}
   1371 
   1372 	if (len == 0) {
   1373 	    continue;
   1374 	} else if (len < 0) {
   1375 	    if (quark_list[i] == separator)
   1376 		i++;
   1377 	    *idx = i;
   1378 	    return True;
   1379 	}
   1380 
   1381 	buf_s[0] = res->id;			/* attribute ID */
   1382 	buf_s[1] = len;				/* value length */
   1383 	XIM_SET_PAD(&buf_s[2], len);		/* pad */
   1384 	len += min_len;
   1385 
   1386 	buf += len;
   1387 	*ret_len += len;
   1388 	size -= len;
   1389     }
   1390     *idx = -1;
   1391     return True;
   1392 }
   1393 #endif /* XIM_CONNECTABLE */
   1394 
   1395 static unsigned int
   1396 _XimCountNumberOfAttr(
   1397     CARD16	  total,
   1398     CARD16	 *attr,
   1399     unsigned int *names_len)
   1400 {
   1401     unsigned int n;
   1402     CARD16	 len;
   1403     CARD16	 min_len = sizeof(CARD16)	/* sizeof attribute ID */
   1404 			 + sizeof(CARD16)	/* sizeof type of value */
   1405 			 + sizeof(INT16);	/* sizeof length of attribute */
   1406 
   1407     n = 0;
   1408     *names_len = 0;
   1409     while (total > min_len) {
   1410 	len = attr[2];
   1411 	if (len > (total - min_len)) {
   1412 	    return 0;
   1413 	}
   1414 	*names_len += (len + 1);
   1415 	len += (min_len + XIM_PAD(len + 2));
   1416 	total -= len;
   1417 	attr = (CARD16 *)((char *)attr + len);
   1418 	n++;
   1419     }
   1420     return n;
   1421 }
   1422 
   1423 Bool
   1424 _XimGetAttributeID(
   1425     Xim			  im,
   1426     CARD16		 *buf)
   1427 {
   1428     unsigned int	  n, names_len, values_len;
   1429     XIMResourceList	  res;
   1430     char		 *names;
   1431     XPointer		  tmp;
   1432     XIMValuesList	 *values_list;
   1433     char		**values;
   1434     register int	  i;
   1435     CARD16		  len;
   1436     CARD16		  min_len = sizeof(CARD16) /* sizeof attribute ID */
   1437 				  + sizeof(CARD16) /* sizeof type of value */
   1438 				  + sizeof(INT16); /* sizeof length of attr */
   1439     /*
   1440      * IM attribute ID
   1441      */
   1442 
   1443     if (!(n = _XimCountNumberOfAttr(buf[0], &buf[1], &names_len)))
   1444 	return False;
   1445 
   1446     if (!(res = Xcalloc(n, sizeof(XIMResource))))
   1447 	return False;
   1448 
   1449     values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
   1450     if (!(tmp = Xcalloc(1, values_len))) {
   1451 	Xfree(res);
   1452 	return False;
   1453     }
   1454 
   1455     values_list = (XIMValuesList *)tmp;
   1456     values = (char **)((char *)tmp + sizeof(XIMValuesList));
   1457     names = (char *)((char *)values + (sizeof(char **) * n));
   1458 
   1459     values_list->count_values = n;
   1460     values_list->supported_values = values;
   1461 
   1462     buf++;
   1463     for (i = 0; i < n; i++) {
   1464 	len = buf[2];
   1465 	(void)memcpy(names, (char *)&buf[3], len);
   1466 	values[i] = names;
   1467 	names[len] = '\0';
   1468 	res[i].resource_name = names;
   1469 	res[i].resource_size = buf[1];
   1470 	res[i].id	     = buf[0];
   1471 	names += (len + 1);
   1472 	len += (min_len + XIM_PAD(len + 2));
   1473 	buf = (CARD16 *)((char *)buf + len);
   1474     }
   1475     _XIMCompileResourceList(res, n);
   1476 
   1477     Xfree(im->core.im_resources);
   1478     Xfree(im->core.im_values_list);
   1479 
   1480     im->core.im_resources     = res;
   1481     im->core.im_num_resources = n;
   1482     im->core.im_values_list   = values_list;
   1483 
   1484     /*
   1485      * IC attribute ID
   1486      */
   1487 
   1488     if (!(n = _XimCountNumberOfAttr(buf[0], &buf[2], &names_len)))
   1489 	return False;
   1490 
   1491     if (!(res = Xcalloc(n, sizeof(XIMResource))))
   1492 	return False;
   1493 
   1494     values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
   1495     if (!(tmp = Xcalloc(1, values_len))) {
   1496 	Xfree(res);
   1497 	return False;
   1498     }
   1499 
   1500     values_list = (XIMValuesList *)tmp;
   1501     values = (char **)((char *)tmp + sizeof(XIMValuesList));
   1502     names = (char *)((char *)values + (sizeof(char **) * n));
   1503 
   1504     values_list->count_values = n;
   1505     values_list->supported_values = values;
   1506 
   1507     buf += 2;
   1508     for (i = 0; i < n; i++) {
   1509 	len = buf[2];
   1510 	(void)memcpy(names, (char *)&buf[3], len);
   1511 	values[i] = names;
   1512 	names[len] = '\0';
   1513 	res[i].resource_name = names;
   1514 	res[i].resource_size = buf[1];
   1515 	res[i].id	     = buf[0];
   1516 	names += (len + 1);
   1517 	len += (min_len + XIM_PAD(len + 2));
   1518 	buf = (CARD16 *)((char *)buf + len);
   1519     }
   1520     _XIMCompileResourceList(res, n);
   1521 
   1522 
   1523     Xfree(im->core.ic_resources);
   1524     Xfree(im->core.ic_values_list);
   1525 
   1526     im->core.ic_resources     = res;
   1527     im->core.ic_num_resources = n;
   1528     im->core.ic_values_list   = values_list;
   1529 
   1530     return True;
   1531 }
   1532