1b4ee4795Smrg/*
25efbdfc3Smrg * Copyright (c) 1991, 1992, Oracle and/or its affiliates.
3b4ee4795Smrg *
4b4ee4795Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b4ee4795Smrg * copy of this software and associated documentation files (the "Software"),
6b4ee4795Smrg * to deal in the Software without restriction, including without limitation
7b4ee4795Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b4ee4795Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b4ee4795Smrg * Software is furnished to do so, subject to the following conditions:
10b4ee4795Smrg *
11b4ee4795Smrg * The above copyright notice and this permission notice (including the next
12b4ee4795Smrg * paragraph) shall be included in all copies or substantial portions of the
13b4ee4795Smrg * Software.
14b4ee4795Smrg *
15b4ee4795Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b4ee4795Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b4ee4795Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b4ee4795Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b4ee4795Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b4ee4795Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21b4ee4795Smrg * DEALINGS IN THE SOFTWARE.
22b4ee4795Smrg */
231ab64890Smrg/******************************************************************
241ab64890Smrg
251ab64890Smrg           Copyright 1992, 1993, 1994 by FUJITSU LIMITED
261ab64890Smrg
271ab64890SmrgPermission to use, copy, modify, distribute, and sell this software
281ab64890Smrgand its documentation for any purpose is hereby granted without fee,
291ab64890Smrgprovided that the above copyright notice appear in all copies and
301ab64890Smrgthat both that copyright notice and this permission notice appear
31b4ee4795Smrgin supporting documentation, and that the name of FUJITSU LIMITED
32b4ee4795Smrgnot be used in advertising or publicity pertaining to distribution
33b4ee4795Smrgof the software without specific, written prior permission.
34b4ee4795SmrgFUJITSU LIMITED makes no representations about the suitability of
35b4ee4795Smrgthis software for any purpose.
361ab64890SmrgIt is provided "as is" without express or implied warranty.
371ab64890Smrg
38b4ee4795SmrgFUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
39b4ee4795SmrgINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
40b4ee4795SmrgEVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
41b4ee4795SmrgCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
42b4ee4795SmrgUSE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
43b4ee4795SmrgOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
44b4ee4795SmrgPERFORMANCE OF THIS SOFTWARE.
451ab64890Smrg
461ab64890Smrg  Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
4761b2299dSmrg          Takashi Fujiwara     FUJITSU LIMITED
481ab64890Smrg                               fujiwara@a80.tech.yk.fujitsu.co.jp
491ab64890Smrg
501ab64890Smrg******************************************************************/
511ab64890Smrg
521ab64890Smrg#ifdef HAVE_CONFIG_H
531ab64890Smrg#include <config.h>
541ab64890Smrg#endif
551ab64890Smrg#include "Xlibint.h"
561ab64890Smrg#include "Xlcint.h"
571ab64890Smrg#include "Ximint.h"
581ab64890Smrg
59eb411b4bSmrgstatic Bool
601ab64890Smrg_XimCreateICCheck(
611ab64890Smrg    Xim          im,
621ab64890Smrg    INT16        len,
631ab64890Smrg    XPointer	 data,
641ab64890Smrg    XPointer     arg)
651ab64890Smrg{
661ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
671ab64890Smrg    CARD8	 major_opcode = *((CARD8 *)data);
681ab64890Smrg    CARD8	 minor_opcode = *((CARD8 *)data + 1);
691ab64890Smrg    XIMID	 imid = buf_s[0];
701ab64890Smrg
711ab64890Smrg    if ((major_opcode == XIM_CREATE_IC_REPLY)
721ab64890Smrg     && (minor_opcode == 0)
731ab64890Smrg     && (imid == im->private.proto.imid))
741ab64890Smrg	return True;
751ab64890Smrg    if ((major_opcode == XIM_ERROR)
761ab64890Smrg     && (minor_opcode == 0)
771ab64890Smrg     && (buf_s[2] & XIM_IMID_VALID)
781ab64890Smrg     && (imid == im->private.proto.imid))
791ab64890Smrg	return True;
801ab64890Smrg    return False;
811ab64890Smrg}
821ab64890Smrg
831ab64890Smrg#ifdef XIM_CONNECTABLE
84eb411b4bSmrgBool
851ab64890Smrg_XimReCreateIC(ic)
861ab64890Smrg    Xic			 ic;
871ab64890Smrg{
881ab64890Smrg    Xim			 im = (Xim)ic->core.im;
891ab64890Smrg    Xic			 save_ic;
901ab64890Smrg    XIMResourceList	 res;
911ab64890Smrg    unsigned int         num;
921ab64890Smrg    XIMStyle		 input_style = ic->core.input_style;
931ab64890Smrg    XimDefICValues	 ic_values;
941ab64890Smrg    INT16		 len;
951ab64890Smrg    CARD16		*buf_s;
961ab64890Smrg    char		*tmp;
971ab64890Smrg    CARD32		 tmp_buf32[BUFSIZE/4];
981ab64890Smrg    char		*tmp_buf = (char *)tmp_buf32;
991ab64890Smrg    char		*buf;
1001ab64890Smrg    int			 buf_size;
1011ab64890Smrg    char		*data;
1021ab64890Smrg    int			 data_len;
1031ab64890Smrg    int			 ret_len;
1041ab64890Smrg    int			 total;
1051ab64890Smrg    int			 idx;
1061ab64890Smrg    CARD32		 reply32[BUFSIZE/4];
1071ab64890Smrg    char		*reply = (char *)reply32;
1081ab64890Smrg    XPointer		 preply;
1091ab64890Smrg    int			 ret_code;
1101ab64890Smrg
111818534a1Smrg    if (!(save_ic = Xmalloc(sizeof(XicRec))))
1121ab64890Smrg	return False;
1131ab64890Smrg    memcpy((char *)save_ic, (char *)ic, sizeof(XicRec));
1141ab64890Smrg
1151ab64890Smrg    ic->core.filter_events = im->private.proto.forward_event_mask;
1161ab64890Smrg    ic->private.proto.forward_event_mask =
1171ab64890Smrg				im->private.proto.forward_event_mask;
1181ab64890Smrg    ic->private.proto.synchronous_event_mask =
1191ab64890Smrg				im->private.proto.synchronous_event_mask;
1201ab64890Smrg
1211ab64890Smrg    num = im->core.ic_num_resources;
1221ab64890Smrg    buf_size = sizeof(XIMResource) * num;
123818534a1Smrg    if (!(res = Xmalloc(buf_size)))
1241ab64890Smrg	goto ErrorOnReCreateIC;
1251ab64890Smrg    (void)memcpy((char *)res, (char *)im->core.ic_resources, buf_size);
1261ab64890Smrg    ic->private.proto.ic_resources     = res;
1271ab64890Smrg    ic->private.proto.ic_num_resources = num;
1281ab64890Smrg
1291ab64890Smrg    num = im->private.proto.ic_num_inner_resources;
1301ab64890Smrg    buf_size = sizeof(XIMResource) * num;
131818534a1Smrg    if (!(res = Xmalloc(buf_size)))
1321ab64890Smrg	goto ErrorOnReCreateIC;
1331ab64890Smrg    (void)memcpy((char *)res,
1341ab64890Smrg			(char *)im->private.proto.ic_inner_resources, buf_size);
1351ab64890Smrg    ic->private.proto.ic_inner_resources     = res;
1361ab64890Smrg    ic->private.proto.ic_num_inner_resources = num;
1371ab64890Smrg
1381ab64890Smrg    _XimSetICMode(ic->private.proto.ic_resources,
1391ab64890Smrg			ic->private.proto.ic_num_resources, input_style);
1401ab64890Smrg
1411ab64890Smrg    _XimSetICMode(ic->private.proto.ic_inner_resources,
1421ab64890Smrg			ic->private.proto.ic_num_inner_resources, input_style);
1431ab64890Smrg
1441ab64890Smrg    _XimGetCurrentICValues(ic, &ic_values);
1451ab64890Smrg    buf = tmp_buf;
1461ab64890Smrg    buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
1471ab64890Smrg    data_len = BUFSIZE - buf_size;
1481ab64890Smrg    total = 0;
1491ab64890Smrg    idx = 0;
1501ab64890Smrg    for (;;) {
1511ab64890Smrg	data = &buf[buf_size];
1521ab64890Smrg	if (!_XimEncodeSavedICATTRIBUTE(ic, ic->private.proto.ic_resources,
1531ab64890Smrg		ic->private.proto.ic_num_resources, &idx, data, data_len,
1541ab64890Smrg		&ret_len, (XPointer)&ic_values, XIM_CREATEIC)) {
1551ab64890Smrg	    if (buf != tmp_buf)
1561ab64890Smrg		Xfree(buf);
1571ab64890Smrg	    goto ErrorOnReCreateIC;
1581ab64890Smrg	}
1591ab64890Smrg
1601ab64890Smrg	total += ret_len;
1611ab64890Smrg	if (idx == -1) {
1621ab64890Smrg	    break;
1631ab64890Smrg	}
1641ab64890Smrg
1651ab64890Smrg	buf_size += ret_len;
1661ab64890Smrg	if (buf == tmp_buf) {
167818534a1Smrg	    if (!(tmp = Xmalloc(buf_size + data_len))) {
1681ab64890Smrg		goto ErrorOnReCreateIC;
1691ab64890Smrg	    }
1701ab64890Smrg	    memcpy(tmp, buf, buf_size);
1711ab64890Smrg	    buf = tmp;
1721ab64890Smrg	} else {
173818534a1Smrg	    if (!(tmp = Xrealloc(buf, (buf_size + data_len)))) {
1741ab64890Smrg		Xfree(buf);
1751ab64890Smrg		goto ErrorOnReCreateIC;
1761ab64890Smrg	    }
1771ab64890Smrg	    buf = tmp;
1781ab64890Smrg	}
1791ab64890Smrg    }
1801ab64890Smrg
1811ab64890Smrg    buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
1821ab64890Smrg    buf_s[0] = im->private.proto.imid;
1831ab64890Smrg    buf_s[1] = (INT16)total;
1841ab64890Smrg
1851ab64890Smrg    len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
1861ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len);
1871ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf))) {
1881ab64890Smrg	if (buf != tmp_buf)
1891ab64890Smrg	    Xfree(buf);
1901ab64890Smrg	goto ErrorOnReCreateIC;
1911ab64890Smrg    }
1921ab64890Smrg    _XimFlush(im);
1931ab64890Smrg    if (buf != tmp_buf)
1941ab64890Smrg	Xfree(buf);
1951ab64890Smrg    ic->private.proto.waitCallback = True;
1961ab64890Smrg    buf_size = BUFSIZE;
1971ab64890Smrg    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
1981ab64890Smrg						 _XimCreateICCheck, 0);
1991ab64890Smrg    if (ret_code == XIM_TRUE) {
2001ab64890Smrg	preply = reply;
2011ab64890Smrg    } else if (ret_code == XIM_OVERFLOW) {
2021ab64890Smrg	if (len <= 0) {
2031ab64890Smrg	    preply = reply;
2041ab64890Smrg	} else {
2051ab64890Smrg	    buf_size = (int)len;
206818534a1Smrg	    preply = Xmalloc(buf_size);
2071ab64890Smrg	    ret_code = _XimRead(im, &len, preply, buf_size,
2081ab64890Smrg						 _XimCreateICCheck, 0);
2091ab64890Smrg	    if (ret_code != XIM_TRUE) {
2101ab64890Smrg		Xfree(preply);
2111ab64890Smrg		ic->private.proto.waitCallback = False;
2121ab64890Smrg		goto ErrorOnReCreateIC;
2131ab64890Smrg	    }
2141ab64890Smrg	}
2151ab64890Smrg    } else {
2161ab64890Smrg	ic->private.proto.waitCallback = False;
2171ab64890Smrg	goto ErrorOnReCreateIC;
2181ab64890Smrg    }
2191ab64890Smrg    ic->private.proto.waitCallback = False;
2201ab64890Smrg    buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
2211ab64890Smrg    if (*((CARD8 *)preply) == XIM_ERROR) {
2221ab64890Smrg	_XimProcError(im, 0, (XPointer)&buf_s[3]);
2231ab64890Smrg	if (reply != preply)
2241ab64890Smrg	    Xfree(preply);
2251ab64890Smrg	goto ErrorOnReCreateIC;
2261ab64890Smrg    }
2271ab64890Smrg
2281ab64890Smrg    ic->private.proto.icid = buf_s[1];		/* icid */
2291ab64890Smrg    if (reply != preply)
2301ab64890Smrg	Xfree(preply);
2311ab64890Smrg
2321ab64890Smrg    _XimRegisterFilter(ic);
2331ab64890Smrg    MARK_IC_CONNECTED(ic);
2343233502eSmrg
2353233502eSmrg    Xfree(save_ic->private.proto.ic_resources);
2363233502eSmrg    Xfree(save_ic->private.proto.ic_inner_resources);
2371ab64890Smrg    Xfree(save_ic);
2381ab64890Smrg    return True;
2391ab64890Smrg
2401ab64890SmrgErrorOnReCreateIC:
2411ab64890Smrg    memcpy((char *)ic, (char *)save_ic, sizeof(XicRec));
2421ab64890Smrg    Xfree(save_ic);
2431ab64890Smrg    return False;
2441ab64890Smrg}
2451ab64890Smrg
246eb411b4bSmrgstatic char *
2471ab64890Smrg_XimDelayModeGetICValues(ic, arg)
2481ab64890Smrg    Xic			 ic;
2491ab64890Smrg    XIMArg		*arg;
2501ab64890Smrg{
2511ab64890Smrg    XimDefICValues	 ic_values;
2521ab64890Smrg
2531ab64890Smrg    _XimGetCurrentICValues(ic, &ic_values);
2541ab64890Smrg    return  _XimGetICValueData(ic, (XPointer)&ic_values,
2551ab64890Smrg				ic->private.proto.ic_resources,
2561ab64890Smrg				ic->private.proto.ic_num_resources,
2571ab64890Smrg				arg, XIM_GETICVALUES);
2581ab64890Smrg}
2591ab64890Smrg#endif /* XIM_CONNECTABLE */
2601ab64890Smrg
261eb411b4bSmrgstatic Bool
2621ab64890Smrg_XimGetICValuesCheck(
2631ab64890Smrg    Xim          im,
2641ab64890Smrg    INT16        len,
2651ab64890Smrg    XPointer	 data,
2661ab64890Smrg    XPointer     arg)
2671ab64890Smrg{
2681ab64890Smrg    Xic		 ic = (Xic)arg;
2691ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
2701ab64890Smrg    CARD8	 major_opcode = *((CARD8 *)data);
2711ab64890Smrg    CARD8	 minor_opcode = *((CARD8 *)data + 1);
2721ab64890Smrg    XIMID	 imid = buf_s[0];
2731ab64890Smrg    XICID	 icid = buf_s[1];
2741ab64890Smrg
2751ab64890Smrg    if ((major_opcode == XIM_GET_IC_VALUES_REPLY)
2761ab64890Smrg     && (minor_opcode == 0)
2771ab64890Smrg     && (imid == im->private.proto.imid)
2781ab64890Smrg     && (icid == ic->private.proto.icid))
2791ab64890Smrg	return True;
2801ab64890Smrg    if ((major_opcode == XIM_ERROR)
2811ab64890Smrg     && (minor_opcode == 0)
2821ab64890Smrg     && (buf_s[2] & XIM_IMID_VALID)
2831ab64890Smrg     && (imid == im->private.proto.imid)
2841ab64890Smrg     && (buf_s[2] & XIM_ICID_VALID)
2851ab64890Smrg     && (icid == ic->private.proto.icid))
2861ab64890Smrg	return True;
2871ab64890Smrg    return False;
2881ab64890Smrg}
2891ab64890Smrg
290eb411b4bSmrgstatic char *
2911ab64890Smrg_XimProtoGetICValues(
2921ab64890Smrg    XIC			 xic,
2931ab64890Smrg    XIMArg		*arg)
2941ab64890Smrg{
2951ab64890Smrg    Xic			 ic = (Xic)xic;
2961ab64890Smrg    Xim			 im = (Xim)ic->core.im;
2971ab64890Smrg    register XIMArg	*p;
2981ab64890Smrg    register XIMArg	*pp;
2991ab64890Smrg    register int	 n;
3001ab64890Smrg    CARD8		*buf;
3011ab64890Smrg    CARD16		*buf_s;
3021ab64890Smrg    INT16		 len;
3031ab64890Smrg    CARD32		 reply32[BUFSIZE/4];
3041ab64890Smrg    char		*reply = (char *)reply32;
3051ab64890Smrg    XPointer		 preply = NULL;
3061ab64890Smrg    int			 buf_size;
3071ab64890Smrg    int			 ret_code;
3081ab64890Smrg    char		*makeid_name;
3091ab64890Smrg    char		*decode_name;
3101ab64890Smrg    CARD16		*data = NULL;
3111ab64890Smrg    INT16		 data_len = 0;
3121ab64890Smrg
3131ab64890Smrg#ifndef XIM_CONNECTABLE
3141ab64890Smrg    if (!IS_IC_CONNECTED(ic))
3151ab64890Smrg	return arg->name;
3161ab64890Smrg#else
3171ab64890Smrg    if (!IS_IC_CONNECTED(ic)) {
3181ab64890Smrg	if (IS_CONNECTABLE(im)) {
3191ab64890Smrg	    if (_XimConnectServer(im)) {
3201ab64890Smrg		if (!_XimReCreateIC(ic)) {
3211ab64890Smrg		    _XimDelayModeSetAttr(im);
3221ab64890Smrg	            return _XimDelayModeGetICValues(ic, arg);
3231ab64890Smrg		}
3241ab64890Smrg	    } else {
3251ab64890Smrg	        return _XimDelayModeGetICValues(ic, arg);
3261ab64890Smrg	    }
3271ab64890Smrg        } else {
3281ab64890Smrg	    return arg->name;
3291ab64890Smrg        }
3301ab64890Smrg    }
3311ab64890Smrg#endif /* XIM_CONNECTABLE */
3321ab64890Smrg
3331ab64890Smrg    for (n = 0, p = arg; p && p->name; p++) {
3341ab64890Smrg	n++;
3351ab64890Smrg	if ((strcmp(p->name, XNPreeditAttributes) == 0)
3361ab64890Smrg	 || (strcmp(p->name, XNStatusAttributes) == 0)) {
3371ab64890Smrg	     n++;
3381ab64890Smrg	     for (pp = (XIMArg *)p->value; pp && pp->name; pp++)
3391ab64890Smrg	 	n++;
3401ab64890Smrg	}
3411ab64890Smrg    }
3421ab64890Smrg
3431ab64890Smrg    if (!n)
3441ab64890Smrg	return (char *)NULL;
3451ab64890Smrg
3461ab64890Smrg    buf_size =  sizeof(CARD16) * n;
3471ab64890Smrg    buf_size += XIM_HEADER_SIZE
3481ab64890Smrg	     + sizeof(CARD16)
3491ab64890Smrg	     + sizeof(CARD16)
3501ab64890Smrg	     + sizeof(INT16)
3511ab64890Smrg	     + XIM_PAD(2 + buf_size);
3521ab64890Smrg
3539c019ec5Smaya    if (!(buf = Xcalloc(buf_size, 1)))
3541ab64890Smrg	return arg->name;
3551ab64890Smrg    buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
3561ab64890Smrg
3571ab64890Smrg    makeid_name = _XimMakeICAttrIDList(ic, ic->private.proto.ic_resources,
3581ab64890Smrg				ic->private.proto.ic_num_resources, arg,
3591ab64890Smrg				&buf_s[3], &len, XIM_GETICVALUES);
3601ab64890Smrg
3611ab64890Smrg    if (len > 0) {
3621ab64890Smrg	buf_s[0] = im->private.proto.imid;		/* imid */
3631ab64890Smrg	buf_s[1] = ic->private.proto.icid;		/* icid */
3641ab64890Smrg	buf_s[2] = len;				/* length of ic-attr-id */
3651ab64890Smrg	len += sizeof(INT16);                       /* sizeof length of attr */
3661ab64890Smrg	XIM_SET_PAD(&buf_s[2], len);		/* pad */
3671ab64890Smrg	len += sizeof(CARD16)			/* sizeof imid */
3681ab64890Smrg	     + sizeof(CARD16);			/* sizeof icid */
3691ab64890Smrg
3701ab64890Smrg	_XimSetHeader((XPointer)buf, XIM_GET_IC_VALUES, 0, &len);
3711ab64890Smrg	if (!(_XimWrite(im, len, (XPointer)buf))) {
3721ab64890Smrg	    Xfree(buf);
3731ab64890Smrg	    return arg->name;
3741ab64890Smrg	}
3751ab64890Smrg	_XimFlush(im);
3761ab64890Smrg	Xfree(buf);
3771ab64890Smrg	buf_size = BUFSIZE;
3781ab64890Smrg	ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
3791ab64890Smrg				 _XimGetICValuesCheck, (XPointer)ic);
3801ab64890Smrg	if (ret_code == XIM_TRUE) {
3811ab64890Smrg	    preply = reply;
3821ab64890Smrg	} else if (ret_code == XIM_OVERFLOW) {
3831ab64890Smrg	    if (len <= 0) {
3841ab64890Smrg		preply = reply;
3851ab64890Smrg	    } else {
3861ab64890Smrg		buf_size = (int)len;
387818534a1Smrg		preply = Xmalloc(len);
3881ab64890Smrg		ret_code = _XimRead(im, &len, preply, buf_size,
3891ab64890Smrg				_XimGetICValuesCheck, (XPointer)ic);
3901ab64890Smrg		if (ret_code != XIM_TRUE) {
3911ab64890Smrg		    if (preply != reply)
3921ab64890Smrg		        Xfree(preply);
3931ab64890Smrg		    return arg->name;
3941ab64890Smrg		}
3951ab64890Smrg	    }
3961ab64890Smrg	} else {
3971ab64890Smrg	    return arg->name;
3981ab64890Smrg	}
3991ab64890Smrg	buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
4001ab64890Smrg	if (*((CARD8 *)preply) == XIM_ERROR) {
4011ab64890Smrg	    _XimProcError(im, 0, (XPointer)&buf_s[3]);
4021ab64890Smrg	    if (reply != preply)
4031ab64890Smrg		Xfree(preply);
4041ab64890Smrg	    return arg->name;
4051ab64890Smrg	}
4061ab64890Smrg	data = &buf_s[4];
4071ab64890Smrg	data_len = buf_s[2];
4081ab64890Smrg    }
4091ab64890Smrg    else if (len < 0) {
4101ab64890Smrg	return arg->name;
4111ab64890Smrg    }
4121ab64890Smrg
4131ab64890Smrg    decode_name = _XimDecodeICATTRIBUTE(ic, ic->private.proto.ic_resources,
4141ab64890Smrg			ic->private.proto.ic_num_resources, data, data_len,
4151ab64890Smrg			arg, XIM_GETICVALUES);
4161ab64890Smrg    if (reply != preply)
4171ab64890Smrg	Xfree(preply);
4181ab64890Smrg
4191ab64890Smrg    if (decode_name)
4201ab64890Smrg	return decode_name;
4211ab64890Smrg    else
4221ab64890Smrg	return makeid_name;
4231ab64890Smrg}
4241ab64890Smrg
4251ab64890Smrg#ifdef XIM_CONNECTABLE
426eb411b4bSmrgstatic Bool
4271ab64890Smrg_XimCheckNestQuarkList(quark_list, num_quark, quark, separator)
4281ab64890Smrg    XrmQuark		*quark_list;
4291ab64890Smrg    int			 num_quark;
4301ab64890Smrg    XrmQuark		 quark;
4311ab64890Smrg    XrmQuark		 separator;
4321ab64890Smrg{
4331ab64890Smrg    register int	 i;
4341ab64890Smrg
4351ab64890Smrg    for (i = 0; i < num_quark; i++) {
4361ab64890Smrg	if (quark_list[i] == separator) {
4371ab64890Smrg	    break;
4381ab64890Smrg	}
4391ab64890Smrg	if (quark_list[i] == quark) {
4401ab64890Smrg	    return True;
4411ab64890Smrg	}
4421ab64890Smrg    }
4431ab64890Smrg    return False;
4441ab64890Smrg}
4451ab64890Smrg
446eb411b4bSmrgstatic Bool
4471ab64890Smrg_XimCheckNestedQuarkList(quark_list, idx, num_quark, arg, separator)
4481ab64890Smrg    XrmQuark		**quark_list;
4491ab64890Smrg    int			  idx;
4501ab64890Smrg    int			 *num_quark;
4511ab64890Smrg    XIMArg		 *arg;
4521ab64890Smrg    XrmQuark		  separator;
4531ab64890Smrg{
4541ab64890Smrg    XrmQuark		 *q_list = *quark_list;
4551ab64890Smrg    int			  n_quark = *num_quark;
4561ab64890Smrg    register XIMArg	 *p;
4571ab64890Smrg    XrmQuark		  quark;
4581ab64890Smrg    XrmQuark		 *tmp;
4591ab64890Smrg    register int	  i;
4601ab64890Smrg
4611ab64890Smrg    for (p = arg; p && p->name; p++) {
4621ab64890Smrg	quark = XrmStringToQuark(p->name);
4631ab64890Smrg	if (_XimCheckNestQuarkList(&q_list[idx], n_quark - idx,
4641ab64890Smrg							quark, separator)) {
4651ab64890Smrg	    continue;
4661ab64890Smrg	}
467818534a1Smrg	if (!(tmp = Xmalloc((sizeof(XrmQuark) * (n_quark + 1))))) {
4681ab64890Smrg	    *quark_list = q_list;
4691ab64890Smrg	    *num_quark = n_quark;
4701ab64890Smrg	    return False;
4711ab64890Smrg	}
4721ab64890Smrg	n_quark++;
4731ab64890Smrg	for (i = 0; i < idx; i++) {
4741ab64890Smrg	    tmp[i] = q_list[i];
4751ab64890Smrg	}
4761ab64890Smrg	tmp[i] = quark;
4771ab64890Smrg	for (i = idx  + 1; i < n_quark; i++) {
4781ab64890Smrg	    tmp[i] = q_list[i - 1];
4791ab64890Smrg	}
4801ab64890Smrg	q_list = tmp;
4811ab64890Smrg    }
4821ab64890Smrg    *quark_list = q_list;
4831ab64890Smrg    *num_quark = n_quark;
4841ab64890Smrg    return True;
4851ab64890Smrg}
4861ab64890Smrg
487eb411b4bSmrgstatic Bool
4881ab64890Smrg_XimCheckICQuarkList(quark_list, num_quark, quark, idx)
4891ab64890Smrg    XrmQuark		*quark_list;
4901ab64890Smrg    int			 num_quark;
4911ab64890Smrg    XrmQuark		 quark;
4921ab64890Smrg    int			*idx;
4931ab64890Smrg{
4941ab64890Smrg    register int	 i;
4951ab64890Smrg
4961ab64890Smrg    for (i = 0; i < num_quark; i++) {
4971ab64890Smrg	if (quark_list[i] == quark) {
4981ab64890Smrg	    *idx = i;
4991ab64890Smrg	    return True;
5001ab64890Smrg	}
5011ab64890Smrg    }
5021ab64890Smrg    return False;
5031ab64890Smrg}
5041ab64890Smrg
505eb411b4bSmrgstatic Bool
5061ab64890Smrg_XimSaveICValues(ic, arg)
5071ab64890Smrg    Xic			 ic;
5081ab64890Smrg    XIMArg		*arg;
5091ab64890Smrg{
5101ab64890Smrg    register XIMArg	*p;
5111ab64890Smrg    register int	 n;
5121ab64890Smrg    XrmQuark		*quark_list;
5131ab64890Smrg    XrmQuark		*tmp;
5141ab64890Smrg    XrmQuark		 quark;
5151ab64890Smrg    int			 num_quark;
5161ab64890Smrg    XrmQuark		 pre_quark;
5171ab64890Smrg    XrmQuark		 sts_quark;
5181ab64890Smrg    XrmQuark		 separator;
5191ab64890Smrg    int			 idx;
5201ab64890Smrg
5211ab64890Smrg    pre_quark = XrmStringToQuark(XNPreeditAttributes);
5221ab64890Smrg    sts_quark = XrmStringToQuark(XNStatusAttributes);
5231ab64890Smrg    separator = XrmStringToQuark(XNSeparatorofNestedList);
5241ab64890Smrg
5251ab64890Smrg    if (quark_list = ic->private.proto.saved_icvalues) {
5261ab64890Smrg	num_quark = ic->private.proto.num_saved_icvalues;
5271ab64890Smrg	for (p = arg; p && p->name; p++) {
5281ab64890Smrg	    quark = XrmStringToQuark(p->name);
5291ab64890Smrg	    if ((quark == pre_quark) || (quark == sts_quark)) {
5301ab64890Smrg	        if (!_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) {
5311ab64890Smrg		    register XIMArg	*pp;
5321ab64890Smrg		    int			 nn;
5331ab64890Smrg		    XrmQuark		*q_list;
5341ab64890Smrg
5351ab64890Smrg		    for (pp = (XIMArg *)p->value, nn = 0;
5361ab64890Smrg						pp && pp->name; pp++, nn++);
537818534a1Smrg	            if (!(tmp = Xrealloc(quark_list,
5381ab64890Smrg				(sizeof(XrmQuark) * (num_quark + nn + 2))))) {
5391ab64890Smrg		        ic->private.proto.saved_icvalues = quark_list;
5401ab64890Smrg		        ic->private.proto.num_saved_icvalues = num_quark;
5411ab64890Smrg		        return False;
5421ab64890Smrg	            }
5431ab64890Smrg	            quark_list = tmp;
5441ab64890Smrg		    q_list = &quark_list[num_quark];
5451ab64890Smrg	            num_quark += nn + 2;
5461ab64890Smrg		    *q_list++ = quark;
5471ab64890Smrg		    for (pp = (XIMArg *)p->value;
5481ab64890Smrg					pp && pp->name; pp++, quark_list++) {
5491ab64890Smrg			*q_list = XrmStringToQuark(pp->name);
5501ab64890Smrg		    }
5511ab64890Smrg		    *q_list = separator;
5521ab64890Smrg		} else {
5531ab64890Smrg		    if (!_XimCheckNestedQuarkList(&quark_list, idx + 1,
5541ab64890Smrg				&num_quark, (XIMArg *)p->value, separator)) {
5551ab64890Smrg		        ic->private.proto.saved_icvalues = quark_list;
5561ab64890Smrg		        ic->private.proto.num_saved_icvalues = num_quark;
5571ab64890Smrg		        return False;
5581ab64890Smrg		    }
5591ab64890Smrg		}
5601ab64890Smrg	    } else {
5611ab64890Smrg	        if (_XimCheckICQuarkList(quark_list, num_quark, quark, &idx)) {
5621ab64890Smrg		    continue;
5631ab64890Smrg	        }
564818534a1Smrg	        if (!(tmp = Xrealloc(quark_list,
5651ab64890Smrg				(sizeof(XrmQuark) * (num_quark + 1))))) {
5661ab64890Smrg		    ic->private.proto.saved_icvalues = quark_list;
5671ab64890Smrg		    ic->private.proto.num_saved_icvalues = num_quark;
5681ab64890Smrg		    return False;
5691ab64890Smrg	        }
5701ab64890Smrg	        quark_list = tmp;
5711ab64890Smrg	        quark_list[num_quark] = quark;
5721ab64890Smrg	        num_quark++;
5731ab64890Smrg	    }
5741ab64890Smrg	}
5751ab64890Smrg	ic->private.proto.saved_icvalues = quark_list;
5761ab64890Smrg	ic->private.proto.num_saved_icvalues = num_quark;
5771ab64890Smrg	return True;
5781ab64890Smrg    }
5791ab64890Smrg
5801ab64890Smrg    for (p = arg, n = 0; p && p->name; p++, n++) {
5811ab64890Smrg	if ((!strcmp(p->name, XNPreeditAttributes))
5821ab64890Smrg	 || (!strcmp(p->name, XNStatusAttributes))) {
5831ab64890Smrg	    register XIMArg	*pp;
5841ab64890Smrg	    int			 nn;
5851ab64890Smrg
5861ab64890Smrg	    for (pp = (XIMArg *)p->value, nn = 0; pp && pp->name; pp++, nn++);
5871ab64890Smrg	    n += nn + 1;
5881ab64890Smrg	}
5891ab64890Smrg    }
5901ab64890Smrg
591818534a1Smrg    if (!(quark_list = Xmalloc(sizeof(XrmQuark) * n))) {
5921ab64890Smrg	return False;
5931ab64890Smrg    }
5941ab64890Smrg
5951ab64890Smrg    ic->private.proto.saved_icvalues = quark_list;
5961ab64890Smrg    ic->private.proto.num_saved_icvalues = n;
5971ab64890Smrg    for (p = arg; p && p->name; p++, quark_list++) {
5981ab64890Smrg	*quark_list = XrmStringToQuark(p->name);
5991ab64890Smrg	if ((*quark_list == pre_quark) || (*quark_list == sts_quark)) {
6001ab64890Smrg	    register XIMArg	*pp;
6011ab64890Smrg
6021ab64890Smrg	    quark_list++;
6031ab64890Smrg	    for (pp = (XIMArg *)p->value; pp && pp->name; pp++, quark_list++) {
6041ab64890Smrg		*quark_list = XrmStringToQuark(pp->name);
6051ab64890Smrg	    }
6061ab64890Smrg	    *quark_list = separator;
6071ab64890Smrg	}
6081ab64890Smrg    }
6091ab64890Smrg    return True;
6101ab64890Smrg}
6111ab64890Smrg
612eb411b4bSmrgstatic char *
6131ab64890Smrg_XimDelayModeSetICValues(ic, arg)
6141ab64890Smrg    Xic			 ic;
6151ab64890Smrg    XIMArg		*arg;
6161ab64890Smrg{
6171ab64890Smrg    XimDefICValues	 ic_values;
6181ab64890Smrg    char		*name;
6191ab64890Smrg
6201ab64890Smrg    _XimGetCurrentICValues(ic, &ic_values);
6211ab64890Smrg    name = _XimSetICValueData(ic, (XPointer)&ic_values,
6221ab64890Smrg			ic->private.proto.ic_resources,
6231ab64890Smrg			ic->private.proto.ic_num_resources,
6241ab64890Smrg			arg, XIM_SETICVALUES, False);
6251ab64890Smrg    _XimSetCurrentICValues(ic, &ic_values);
6261ab64890Smrg    return name;
6271ab64890Smrg}
6281ab64890Smrg#endif /* XIM_CONNECTABLE */
6291ab64890Smrg
630eb411b4bSmrgstatic Bool
6311ab64890Smrg_XimSetICValuesCheck(
6321ab64890Smrg    Xim          im,
6331ab64890Smrg    INT16        len,
6341ab64890Smrg    XPointer	 data,
6351ab64890Smrg    XPointer     arg)
6361ab64890Smrg{
6371ab64890Smrg    Xic		 ic = (Xic)arg;
6381ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
6391ab64890Smrg    CARD8	 major_opcode = *((CARD8 *)data);
6401ab64890Smrg    CARD8	 minor_opcode = *((CARD8 *)data + 1);
6411ab64890Smrg    XIMID	 imid = buf_s[0];
6421ab64890Smrg    XICID	 icid = buf_s[1];
6431ab64890Smrg
6441ab64890Smrg    if ((major_opcode == XIM_SET_IC_VALUES_REPLY)
6451ab64890Smrg     && (minor_opcode == 0)
6461ab64890Smrg     && (imid == im->private.proto.imid)
6471ab64890Smrg     && (icid == ic->private.proto.icid))
6481ab64890Smrg	return True;
6491ab64890Smrg    if ((major_opcode == XIM_ERROR)
6501ab64890Smrg     && (minor_opcode == 0)
6511ab64890Smrg     && (buf_s[2] & XIM_IMID_VALID)
6521ab64890Smrg     && (imid == im->private.proto.imid)
6531ab64890Smrg     && (buf_s[2] & XIM_ICID_VALID)
6541ab64890Smrg     && (icid == ic->private.proto.icid))
6551ab64890Smrg	return True;
6561ab64890Smrg    return False;
6571ab64890Smrg}
6581ab64890Smrg
659eb411b4bSmrgstatic char *
6601ab64890Smrg_XimProtoSetICValues(
6611ab64890Smrg    XIC			 xic,
6621ab64890Smrg    XIMArg		*arg)
6631ab64890Smrg{
6641ab64890Smrg    Xic			 ic = (Xic)xic;
6651ab64890Smrg    Xim			 im = (Xim)ic->core.im;
6661ab64890Smrg    XimDefICValues	 ic_values;
6671ab64890Smrg    INT16		 len;
6681ab64890Smrg    CARD16		*buf_s;
6691ab64890Smrg    char		*tmp;
6701ab64890Smrg    CARD32		 tmp_buf32[BUFSIZE/4];
6711ab64890Smrg    char		*tmp_buf = (char *)tmp_buf32;
6721ab64890Smrg    char		*buf;
6731ab64890Smrg    int			 buf_size;
6741ab64890Smrg    char		*data;
6751ab64890Smrg    int			 data_len;
6761ab64890Smrg    int			 ret_len;
6771ab64890Smrg    int			 total;
6781ab64890Smrg    XIMArg		*arg_ret;
6791ab64890Smrg    CARD32		 reply32[BUFSIZE/4];
6801ab64890Smrg    char		*reply = (char *)reply32;
6811ab64890Smrg    XPointer		 preply = NULL;
6821ab64890Smrg    int			 ret_code;
6831ab64890Smrg    BITMASK32		 flag = 0L;
6841ab64890Smrg    char		*name;
6851ab64890Smrg    char		*tmp_name = (arg) ? arg->name : NULL;
6861ab64890Smrg
6871ab64890Smrg#ifndef XIM_CONNECTABLE
6881ab64890Smrg    if (!IS_IC_CONNECTED(ic))
6891ab64890Smrg	return tmp_name;
6901ab64890Smrg#else
6911ab64890Smrg    if (!_XimSaveICValues(ic, arg))
6921ab64890Smrg	return NULL;
6931ab64890Smrg
6941ab64890Smrg    if (!IS_IC_CONNECTED(ic)) {
6951ab64890Smrg	if (IS_CONNECTABLE(im)) {
6961ab64890Smrg	    if (_XimConnectServer(im)) {
6971ab64890Smrg	        if (!_XimReCreateIC(ic)) {
6981ab64890Smrg		    _XimDelayModeSetAttr(im);
6991ab64890Smrg	            return _XimDelayModeSetICValues(ic, arg);
7001ab64890Smrg		}
7011ab64890Smrg	    } else {
7021ab64890Smrg	        return _XimDelayModeSetICValues(ic, arg);
7031ab64890Smrg	    }
7041ab64890Smrg        } else {
7051ab64890Smrg	    return tmp_name;
7061ab64890Smrg        }
7071ab64890Smrg    }
7081ab64890Smrg#endif /* XIM_CONNECTABLE */
7091ab64890Smrg
7101ab64890Smrg    _XimGetCurrentICValues(ic, &ic_values);
7119c019ec5Smaya    memset(tmp_buf, 0, sizeof(tmp_buf32));
7121ab64890Smrg    buf = tmp_buf;
7131ab64890Smrg    buf_size = XIM_HEADER_SIZE
7141ab64890Smrg	+ sizeof(CARD16) + sizeof(CARD16) + sizeof(INT16) + sizeof(CARD16);
7151ab64890Smrg    data_len = BUFSIZE - buf_size;
7161ab64890Smrg    total = 0;
7171ab64890Smrg    arg_ret = arg;
7181ab64890Smrg    for (;;) {
7191ab64890Smrg	data = &buf[buf_size];
7201ab64890Smrg	if ((name = _XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources,
7211ab64890Smrg			ic->private.proto.ic_num_resources, arg, &arg_ret,
7221ab64890Smrg			data, data_len, &ret_len, (XPointer)&ic_values,
7231ab64890Smrg			&flag, XIM_SETICVALUES))) {
7241ab64890Smrg	    break;
7251ab64890Smrg	}
7261ab64890Smrg
7271ab64890Smrg	total += ret_len;
7281ab64890Smrg	if (!(arg = arg_ret)) {
7291ab64890Smrg	    break;
7301ab64890Smrg	}
7311ab64890Smrg
7321ab64890Smrg	buf_size += ret_len;
7331ab64890Smrg	if (buf == tmp_buf) {
7349c019ec5Smaya	    if (!(tmp = Xcalloc(buf_size + data_len, 1))) {
7351ab64890Smrg		return tmp_name;
7361ab64890Smrg	    }
7371ab64890Smrg	    memcpy(tmp, buf, buf_size);
7381ab64890Smrg	    buf = tmp;
7391ab64890Smrg	} else {
740818534a1Smrg	    if (!(tmp = Xrealloc(buf, (buf_size + data_len)))) {
7411ab64890Smrg		Xfree(buf);
7421ab64890Smrg		return tmp_name;
7431ab64890Smrg	    }
7449c019ec5Smaya            memset(&tmp[buf_size], 0, data_len);
7451ab64890Smrg	    buf = tmp;
7461ab64890Smrg	}
7471ab64890Smrg    }
7481ab64890Smrg    _XimSetCurrentICValues(ic, &ic_values);
7491ab64890Smrg
7501ab64890Smrg    if (!total) {
7511ab64890Smrg        return tmp_name;
7521ab64890Smrg    }
7531ab64890Smrg
7541ab64890Smrg    buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
7551ab64890Smrg
7561ab64890Smrg#ifdef EXT_MOVE
7571ab64890Smrg    if (_XimExtenMove(im, ic, flag, &buf_s[4], (INT16)total))
7581ab64890Smrg	return name;
7591ab64890Smrg#endif
7601ab64890Smrg
7611ab64890Smrg    buf_s[0] = im->private.proto.imid;
7621ab64890Smrg    buf_s[1] = ic->private.proto.icid;
7631ab64890Smrg    buf_s[2] = (INT16)total;
7641ab64890Smrg    buf_s[3] = 0;
7651ab64890Smrg    len = (INT16)(sizeof(CARD16) + sizeof(CARD16)
7661ab64890Smrg				+ sizeof(INT16) + sizeof(CARD16) + total);
7671ab64890Smrg
7681ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_SET_IC_VALUES, 0, &len);
7691ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf))) {
7701ab64890Smrg	if (buf != tmp_buf)
7711ab64890Smrg	    Xfree(buf);
7721ab64890Smrg	return tmp_name;
7731ab64890Smrg    }
7741ab64890Smrg    _XimFlush(im);
7751ab64890Smrg    if (buf != tmp_buf)
7761ab64890Smrg	Xfree(buf);
7771ab64890Smrg    ic->private.proto.waitCallback = True;
7781ab64890Smrg    buf_size = BUFSIZE;
7791ab64890Smrg    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
7801ab64890Smrg					_XimSetICValuesCheck, (XPointer)ic);
7811ab64890Smrg    if (ret_code == XIM_TRUE) {
7821ab64890Smrg	preply = reply;
7831ab64890Smrg    } else if (ret_code == XIM_OVERFLOW) {
7841ab64890Smrg	buf_size = (int)len;
785818534a1Smrg	preply = Xmalloc(buf_size);
7861ab64890Smrg	ret_code = _XimRead(im, &len, preply, buf_size,
7871ab64890Smrg					_XimSetICValuesCheck, (XPointer)ic);
7881ab64890Smrg	if (ret_code != XIM_TRUE) {
7891ab64890Smrg	    Xfree(preply);
7901ab64890Smrg	    ic->private.proto.waitCallback = False;
7911ab64890Smrg	    return tmp_name;
7921ab64890Smrg	}
7931ab64890Smrg    } else {
7941ab64890Smrg	ic->private.proto.waitCallback = False;
7951ab64890Smrg	return tmp_name;
7961ab64890Smrg    }
7971ab64890Smrg    ic->private.proto.waitCallback = False;
7981ab64890Smrg    buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
7991ab64890Smrg    if (*((CARD8 *)preply) == XIM_ERROR) {
8001ab64890Smrg	_XimProcError(im, 0, (XPointer)&buf_s[3]);
8011ab64890Smrg	if (reply != preply)
8021ab64890Smrg	    Xfree(preply);
8031ab64890Smrg	return tmp_name;
8041ab64890Smrg    }
8051ab64890Smrg    if (reply != preply)
8061ab64890Smrg	Xfree(preply);
8071ab64890Smrg
8081ab64890Smrg    return name;
8091ab64890Smrg}
8101ab64890Smrg
811eb411b4bSmrgstatic Bool
8121ab64890Smrg_XimDestroyICCheck(
8131ab64890Smrg    Xim          im,
8141ab64890Smrg    INT16        len,
8151ab64890Smrg    XPointer	 data,
8161ab64890Smrg    XPointer     arg)
8171ab64890Smrg{
8181ab64890Smrg    Xic		 ic = (Xic)arg;
8191ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
8201ab64890Smrg    CARD8	 major_opcode = *((CARD8 *)data);
8211ab64890Smrg    CARD8	 minor_opcode = *((CARD8 *)data + 1);
8221ab64890Smrg    XIMID	 imid = buf_s[0];
8231ab64890Smrg    XICID	 icid = buf_s[1];
8241ab64890Smrg    Bool	 ret = False;
8251ab64890Smrg
8261ab64890Smrg    if ((major_opcode == XIM_DESTROY_IC_REPLY)
8271ab64890Smrg     && (minor_opcode == 0)
8281ab64890Smrg     && (imid == im->private.proto.imid)
8291ab64890Smrg     && (icid == ic->private.proto.icid))
8301ab64890Smrg	ret = True;
8311ab64890Smrg    if ((major_opcode == XIM_ERROR)
8321ab64890Smrg     && (minor_opcode == 0)
8331ab64890Smrg     && (buf_s[2] & XIM_IMID_VALID)
8341ab64890Smrg     && (imid == im->private.proto.imid)
8351ab64890Smrg     && (buf_s[2] & XIM_ICID_VALID)
8361ab64890Smrg     && (icid == ic->private.proto.icid))
8373233502eSmrg        ret = False;
8381ab64890Smrg    return ret;
8391ab64890Smrg}
8401ab64890Smrg
841eb411b4bSmrgstatic void
8421ab64890Smrg_XimProtoICFree(
8431ab64890Smrg    Xic		 ic)
8441ab64890Smrg{
8451ab64890Smrg#ifdef XIM_CONNECTABLE
8461ab64890Smrg    Xim		 im = (Xim)ic->core.im;
8471ab64890Smrg#endif
8481ab64890Smrg
8493233502eSmrg
8503233502eSmrg    Xfree(ic->private.proto.preedit_font);
8513233502eSmrg    ic->private.proto.preedit_font = NULL;
8523233502eSmrg
8533233502eSmrg
8543233502eSmrg    Xfree(ic->private.proto.status_font);
8553233502eSmrg    ic->private.proto.status_font = NULL;
8563233502eSmrg
8571ab64890Smrg    if (ic->private.proto.commit_info) {
8581ab64890Smrg	_XimFreeCommitInfo(ic);
8591ab64890Smrg	ic->private.proto.commit_info = NULL;
8601ab64890Smrg    }
8613233502eSmrg
8623233502eSmrg    Xfree(ic->private.proto.ic_inner_resources);
8633233502eSmrg    ic->private.proto.ic_inner_resources = NULL;
8643233502eSmrg
8651ab64890Smrg
8661ab64890Smrg#ifdef XIM_CONNECTABLE
8671ab64890Smrg    if (IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
8681ab64890Smrg	return;
8691ab64890Smrg    }
8701ab64890Smrg#endif /* XIM_CONNECTABLE */
8711ab64890Smrg
8723233502eSmrg
8733233502eSmrg    Xfree(ic->private.proto.saved_icvalues);
8743233502eSmrg    ic->private.proto.saved_icvalues = NULL;
8753233502eSmrg
8763233502eSmrg
8773233502eSmrg    Xfree(ic->private.proto.ic_resources);
8783233502eSmrg    ic->private.proto.ic_resources = NULL;
8793233502eSmrg
8803233502eSmrg
8813233502eSmrg    Xfree(ic->core.hotkey);
8823233502eSmrg    ic->core.hotkey = NULL;
8833233502eSmrg
8841ab64890Smrg
8851ab64890Smrg    return;
8861ab64890Smrg}
8871ab64890Smrg
888eb411b4bSmrgstatic void
8891ab64890Smrg_XimProtoDestroyIC(
8901ab64890Smrg    XIC		 xic)
8911ab64890Smrg{
8921ab64890Smrg    Xic		 ic = (Xic)xic;
8931ab64890Smrg    Xim	 	 im = (Xim)ic->core.im;
8941ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
8951ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
8961ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
8971ab64890Smrg    INT16	 len;
8981ab64890Smrg    CARD32	 reply32[BUFSIZE/4];
8991ab64890Smrg    char	*reply = (char *)reply32;
9001ab64890Smrg    XPointer	 preply;
9011ab64890Smrg    int		 buf_size;
9021ab64890Smrg    int		 ret_code;
9031ab64890Smrg
9041ab64890Smrg    if (IS_SERVER_CONNECTED(im)) {
9051ab64890Smrg	buf_s[0] = im->private.proto.imid;		/* imid */
9061ab64890Smrg	buf_s[1] = ic->private.proto.icid;		/* icid */
9071ab64890Smrg
9081ab64890Smrg	len = sizeof(CARD16)			/* sizeof imid */
9091ab64890Smrg	    + sizeof(CARD16);			/* sizeof icid */
9101ab64890Smrg
9111ab64890Smrg	_XimSetHeader((XPointer)buf, XIM_DESTROY_IC, 0, &len);
9121ab64890Smrg	(void)_XimWrite(im, len, (XPointer)buf);
9131ab64890Smrg	_XimFlush(im);
9141ab64890Smrg	buf_size = BUFSIZE;
9151ab64890Smrg	ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
9161ab64890Smrg					_XimDestroyICCheck, (XPointer)ic);
9171ab64890Smrg	if (ret_code == XIM_OVERFLOW) {
9181ab64890Smrg	    buf_size = len;
919818534a1Smrg	    preply = Xmalloc(buf_size);
9201ab64890Smrg	    (void)_XimRead(im, &len, preply, buf_size,
9211ab64890Smrg					_XimDestroyICCheck, (XPointer)ic);
9221ab64890Smrg	    Xfree(preply);
9231ab64890Smrg	}
9241ab64890Smrg    }
9251ab64890Smrg    UNMARK_IC_CONNECTED(ic);
9261ab64890Smrg    _XimUnregisterFilter(ic);
9271ab64890Smrg    _XimProtoICFree(ic);
9281ab64890Smrg    return;
9291ab64890Smrg}
9301ab64890Smrg
931818534a1Smrg/*
932818534a1Smrg * Some functions require the request queue from the server to be flushed
933818534a1Smrg * so that the ordering of client initiated status changes and those requested
934818534a1Smrg * by the server is well defined.
935818534a1Smrg * _XimSync() would be the function of choice here as it should get a
936818534a1Smrg * XIM_SYNC_REPLY back from the server.
937818534a1Smrg * This however isn't implemented in the piece of junk that is used by most
938818534a1Smrg * input servers as the server side protocol if to XIM.
939818534a1Smrg * Since this code is not shipped as a library together with the client side
940818534a1Smrg * XIM code but is duplicated by every input server around the world there
941818534a1Smrg * is no easy fix to this but this ugly hack below.
942818534a1Smrg * Obtaining an IC value from the server sends a request and empties out the
943818534a1Smrg * event/server request queue until the answer to this request is found.
944818534a1Smrg * Thus it is guaranteed that any pending server side request gets processed.
945818534a1Smrg * This is what the hack below is doing.
946818534a1Smrg */
947818534a1Smrg
948818534a1Smrgstatic void
949818534a1SmrgBrokenSyncWithServer(XIC xic)
950818534a1Smrg{
951818534a1Smrg    CARD32 dummy;
952818534a1Smrg    XGetICValues(xic, XNFilterEvents, &dummy, NULL);
953818534a1Smrg}
954818534a1Smrg
955eb411b4bSmrgstatic void
9561ab64890Smrg_XimProtoSetFocus(
9571ab64890Smrg    XIC		 xic)
9581ab64890Smrg{
9591ab64890Smrg    Xic		 ic = (Xic)xic;
9601ab64890Smrg    Xim		 im = (Xim)ic->core.im;
9611ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
9621ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
9631ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
9641ab64890Smrg    INT16	 len;
96561b2299dSmrg
9661ab64890Smrg#ifndef XIM_CONNECTABLE
9671ab64890Smrg    if (!IS_IC_CONNECTED(ic))
9681ab64890Smrg	return;
9691ab64890Smrg#else
9701ab64890Smrg    if (!IS_IC_CONNECTED(ic)) {
9711ab64890Smrg	if (IS_CONNECTABLE(im)) {
9721ab64890Smrg	    if (_XimConnectServer(im)) {
9731ab64890Smrg		if (!_XimReCreateIC(ic)) {
9741ab64890Smrg		    _XimDelayModeSetAttr(im);
9751ab64890Smrg		    return;
9761ab64890Smrg		}
9771ab64890Smrg	    } else {
9781ab64890Smrg		return;
9791ab64890Smrg	    }
9801ab64890Smrg	} else {
9811ab64890Smrg	    return;
9821ab64890Smrg	}
9831ab64890Smrg    }
9841ab64890Smrg#endif /* XIM_CONNECTABLE */
985818534a1Smrg    BrokenSyncWithServer(xic);
9861ab64890Smrg
9871ab64890Smrg    buf_s[0] = im->private.proto.imid;		/* imid */
9881ab64890Smrg    buf_s[1] = ic->private.proto.icid;		/* icid */
9891ab64890Smrg
9901ab64890Smrg    len = sizeof(CARD16)			/* sizeof imid */
9911ab64890Smrg	+ sizeof(CARD16);			/* sizeof icid */
9921ab64890Smrg
9931ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_SET_IC_FOCUS, 0, &len);
9941ab64890Smrg    (void)_XimWrite(im, len, (XPointer)buf);
9951ab64890Smrg    _XimFlush(im);
9961ab64890Smrg
9971ab64890Smrg    _XimRegisterFilter(ic);
9981ab64890Smrg    return;
9991ab64890Smrg}
10001ab64890Smrg
1001eb411b4bSmrgstatic void
10021ab64890Smrg_XimProtoUnsetFocus(
10031ab64890Smrg    XIC		 xic)
10041ab64890Smrg{
10051ab64890Smrg    Xic		 ic = (Xic)xic;
10061ab64890Smrg    Xim		 im = (Xim)ic->core.im;
10071ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
10081ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
10091ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
10101ab64890Smrg    INT16	 len;
10111ab64890Smrg
10121ab64890Smrg#ifndef XIM_CONNECTABLE
10131ab64890Smrg    if (!IS_IC_CONNECTED(ic))
10141ab64890Smrg	return;
10151ab64890Smrg#else
10161ab64890Smrg    if (!IS_IC_CONNECTED(ic)) {
10171ab64890Smrg	if (IS_CONNECTABLE(im)) {
10181ab64890Smrg	    if (_XimConnectServer(im)) {
10191ab64890Smrg		if (!_XimReCreateIC(ic)) {
10201ab64890Smrg		    _XimDelayModeSetAttr(im);
10211ab64890Smrg		    return;
10221ab64890Smrg		}
10231ab64890Smrg	    } else {
10241ab64890Smrg		return;
10251ab64890Smrg	    }
10261ab64890Smrg	} else {
10271ab64890Smrg	    return;
10281ab64890Smrg	}
10291ab64890Smrg    }
10301ab64890Smrg#endif /* XIM_CONNECTABLE */
10311ab64890Smrg
1032818534a1Smrg    BrokenSyncWithServer(xic);
1033818534a1Smrg
10341ab64890Smrg    buf_s[0] = im->private.proto.imid;		/* imid */
10351ab64890Smrg    buf_s[1] = ic->private.proto.icid;		/* icid */
10361ab64890Smrg
10371ab64890Smrg    len = sizeof(CARD16)			/* sizeof imid */
10381ab64890Smrg	+ sizeof(CARD16);			/* sizeof icid */
10391ab64890Smrg
10401ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_UNSET_IC_FOCUS, 0, &len);
10411ab64890Smrg    (void)_XimWrite(im, len, (XPointer)buf);
10421ab64890Smrg    _XimFlush(im);
10431ab64890Smrg
10441ab64890Smrg    _XimUnregisterFilter(ic);
10451ab64890Smrg    return;
10461ab64890Smrg}
10471ab64890Smrg
1048eb411b4bSmrgstatic Bool
10491ab64890Smrg_XimResetICCheck(
10501ab64890Smrg    Xim          im,
10511ab64890Smrg    INT16        len,
10521ab64890Smrg    XPointer	 data,
10531ab64890Smrg    XPointer     arg)
10541ab64890Smrg{
10551ab64890Smrg    Xic		 ic = (Xic)arg;
10561ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
10571ab64890Smrg    CARD8	 major_opcode = *((CARD8 *)data);
10581ab64890Smrg    CARD8	 minor_opcode = *((CARD8 *)data + 1);
10591ab64890Smrg    XIMID	 imid = buf_s[0];
10601ab64890Smrg    XICID	 icid = buf_s[1];
10611ab64890Smrg
10621ab64890Smrg    if ((major_opcode == XIM_RESET_IC_REPLY)
10631ab64890Smrg     && (minor_opcode == 0)
10641ab64890Smrg     && (imid == im->private.proto.imid)
10651ab64890Smrg     && (icid == ic->private.proto.icid))
10661ab64890Smrg	return True;
10671ab64890Smrg    if ((major_opcode == XIM_ERROR)
10681ab64890Smrg     && (minor_opcode == 0)
10691ab64890Smrg     && (buf_s[2] & XIM_IMID_VALID)
10701ab64890Smrg     && (imid == im->private.proto.imid)
10711ab64890Smrg     && (buf_s[2] & XIM_ICID_VALID)
10721ab64890Smrg     && (icid == ic->private.proto.icid))
10731ab64890Smrg	return True;
10741ab64890Smrg    return False;
10751ab64890Smrg}
10761ab64890Smrg
1077eb411b4bSmrgstatic char *
10781ab64890Smrg_XimProtoReset(
10791ab64890Smrg    XIC		 xic,
10801ab64890Smrg    char *     (*retfunc) (Xim im, Xic ic, XPointer buf) )
10811ab64890Smrg{
10821ab64890Smrg    Xic		 ic = (Xic)xic;
10831ab64890Smrg    Xim	 	 im = (Xim)ic->core.im;
10841ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
10851ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
10861ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
10871ab64890Smrg    INT16	 len;
10881ab64890Smrg    CARD32	 reply32[BUFSIZE/4];
10891ab64890Smrg    char	*reply = (char *)reply32;
10901ab64890Smrg    XPointer	 preply;
10911ab64890Smrg    int		 buf_size;
10921ab64890Smrg    int		 ret_code;
10931ab64890Smrg    char	*commit;
10941ab64890Smrg
10951ab64890Smrg    if (!IS_IC_CONNECTED(ic))
10961ab64890Smrg	return (char *)NULL;
10971ab64890Smrg
10981ab64890Smrg    buf_s[0] = im->private.proto.imid;		/* imid */
10991ab64890Smrg    buf_s[1] = ic->private.proto.icid;		/* icid */
11001ab64890Smrg
11011ab64890Smrg    len = sizeof(CARD16)			/* sizeof imid */
11021ab64890Smrg	+ sizeof(CARD16);			/* sizeof icid */
11031ab64890Smrg
11041ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_RESET_IC, 0, &len);
11051ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
11061ab64890Smrg	return NULL;
11071ab64890Smrg    _XimFlush(im);
11081ab64890Smrg    ic->private.proto.waitCallback = True;
11091ab64890Smrg    buf_size = BUFSIZE;
11101ab64890Smrg    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
11111ab64890Smrg    					_XimResetICCheck, (XPointer)ic);
11121ab64890Smrg    if (ret_code == XIM_TRUE) {
11131ab64890Smrg    	preply = reply;
11141ab64890Smrg    } else if (ret_code == XIM_OVERFLOW) {
11151ab64890Smrg    	if (len < 0) {
11161ab64890Smrg    	    preply = reply;
11171ab64890Smrg    	} else {
11181ab64890Smrg    	    buf_size = len;
1119818534a1Smrg	    preply = Xmalloc(buf_size);
11201ab64890Smrg    	    ret_code = _XimRead(im, &len, preply, buf_size,
11211ab64890Smrg    					_XimResetICCheck, (XPointer)ic);
11221ab64890Smrg    	    if (ret_code != XIM_TRUE) {
11231ab64890Smrg		Xfree(preply);
11241ab64890Smrg    		ic->private.proto.waitCallback = False;
11251ab64890Smrg    		return NULL;
11261ab64890Smrg    	    }
11271ab64890Smrg    	}
11281ab64890Smrg    } else {
11291ab64890Smrg	ic->private.proto.waitCallback = False;
11301ab64890Smrg	return NULL;
11311ab64890Smrg    }
11321ab64890Smrg    ic->private.proto.waitCallback = False;
11331ab64890Smrg    buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
11341ab64890Smrg    if (*((CARD8 *)preply) == XIM_ERROR) {
11351ab64890Smrg	_XimProcError(im, 0, (XPointer)&buf_s[3]);
11361ab64890Smrg    	if (reply != preply)
11371ab64890Smrg    	    free(preply);
11381ab64890Smrg	return NULL;
11391ab64890Smrg    }
11401ab64890Smrg
11411ab64890Smrg    commit = retfunc(im, ic, (XPointer)&buf_s[2]);
11421ab64890Smrg
11431ab64890Smrg    if (reply != preply)
11441ab64890Smrg    	Xfree(preply);
11451ab64890Smrg    return commit;
11461ab64890Smrg}
11471ab64890Smrg
1148eb411b4bSmrgstatic char *
11491ab64890Smrg_XimCommitedMbString(
11501ab64890Smrg    Xim			 im,
11511ab64890Smrg    Xic			 ic,
11521ab64890Smrg    XPointer		 buf)
11531ab64890Smrg{
11541ab64890Smrg    CARD16		*buf_s = (CARD16 *)buf;
11551ab64890Smrg    XimCommitInfo	 info;
11561ab64890Smrg    int			 len;
11571ab64890Smrg    int			 new_len;
11581ab64890Smrg    char		*commit;
11591ab64890Smrg    char		*new_commit = NULL;
11601ab64890Smrg    char		*str;
11611ab64890Smrg    Status		 status;
11621ab64890Smrg
11631ab64890Smrg    len = 0;
11641ab64890Smrg    for (info = ic->private.proto.commit_info; info; info = info->next)
11651ab64890Smrg	len += info->string_len;
11661ab64890Smrg    len += buf_s[0];
11671ab64890Smrg    if ( len == 0 )
11681ab64890Smrg	return( NULL );
11691ab64890Smrg
1170818534a1Smrg    if (!(commit = Xmalloc(len + 1)))
11711ab64890Smrg	goto Error_On_Reset;
11721ab64890Smrg
11731ab64890Smrg    str = commit;
11741ab64890Smrg    for (info = ic->private.proto.commit_info; info; info = info->next) {
11751ab64890Smrg	(void)memcpy(str, info->string, info->string_len);
11761ab64890Smrg	str += info->string_len;
11771ab64890Smrg    }
11781ab64890Smrg    (void)memcpy(str, (char *)&buf_s[1], buf_s[0]);
11791ab64890Smrg    commit[len] = '\0';
11801ab64890Smrg
11811ab64890Smrg    new_len = im->methods->ctstombs((XIM)im, commit, len, NULL, 0, &status);
11821ab64890Smrg    if (status != XLookupNone) {
11831ab64890Smrg	if (!(new_commit = Xmalloc(new_len + 1))) {
11841ab64890Smrg	    Xfree(commit);
11851ab64890Smrg	    goto Error_On_Reset;
11861ab64890Smrg	}
11871ab64890Smrg	(void)im->methods->ctstombs((XIM)im, commit, len,
11881ab64890Smrg						new_commit, new_len, NULL);
11891ab64890Smrg	new_commit[new_len] = '\0';
11901ab64890Smrg    }
11911ab64890Smrg    Xfree(commit);
11921ab64890Smrg
11931ab64890SmrgError_On_Reset:
11941ab64890Smrg    _XimFreeCommitInfo( ic );
11951ab64890Smrg    return new_commit;
11961ab64890Smrg}
11971ab64890Smrg
1198eb411b4bSmrgstatic char *
11991ab64890Smrg_XimProtoMbReset(
12001ab64890Smrg    XIC		 xic)
12011ab64890Smrg{
12021ab64890Smrg    return _XimProtoReset(xic, _XimCommitedMbString);
12031ab64890Smrg}
12041ab64890Smrg
1205eb411b4bSmrgstatic wchar_t *
12061ab64890Smrg_XimCommitedWcString(
12071ab64890Smrg    Xim		 im,
12081ab64890Smrg    Xic		 ic,
12091ab64890Smrg    XPointer	 buf)
12101ab64890Smrg{
12111ab64890Smrg    CARD16		*buf_s = (CARD16 *)buf;
12121ab64890Smrg    XimCommitInfo	 info;
12131ab64890Smrg    int			 len;
12141ab64890Smrg    int			 new_len;
12151ab64890Smrg    char		*commit;
12161ab64890Smrg    wchar_t		*new_commit = (wchar_t *)NULL;
12171ab64890Smrg    char		*str;
12181ab64890Smrg    Status		 status;
12191ab64890Smrg
12201ab64890Smrg    len = 0;
12211ab64890Smrg    for (info = ic->private.proto.commit_info; info; info = info->next)
12221ab64890Smrg	len += info->string_len;
12231ab64890Smrg    len += buf_s[0];
12241ab64890Smrg    if ( len == 0 )
12251ab64890Smrg	return( (wchar_t *)NULL );
12261ab64890Smrg
1227818534a1Smrg    if (!(commit = Xmalloc(len + 1)))
12281ab64890Smrg	goto Error_On_Reset;
12291ab64890Smrg
12301ab64890Smrg    str = commit;
12311ab64890Smrg    for (info = ic->private.proto.commit_info; info; info = info->next) {
12321ab64890Smrg	(void)memcpy(str, info->string, info->string_len);
12331ab64890Smrg	str += info->string_len;
12341ab64890Smrg    }
12351ab64890Smrg    (void)memcpy(str, (char *)&buf_s[1], buf_s[0]);
12361ab64890Smrg    commit[len] = '\0';
12371ab64890Smrg
12381ab64890Smrg    new_len = im->methods->ctstowcs((XIM)im, commit, len, NULL, 0, &status);
12391ab64890Smrg    if (status != XLookupNone) {
12401ab64890Smrg	if (!(new_commit =
12411ab64890Smrg		     (wchar_t *)Xmalloc(sizeof(wchar_t) * (new_len + 1)))) {
12421ab64890Smrg	    Xfree(commit);
12431ab64890Smrg	    goto Error_On_Reset;
12441ab64890Smrg	}
12451ab64890Smrg	(void)im->methods->ctstowcs((XIM)im, commit, len,
12461ab64890Smrg						new_commit, new_len, NULL);
12471ab64890Smrg	new_commit[new_len] = (wchar_t)'\0';
12481ab64890Smrg    }
12491ab64890Smrg    Xfree(commit);
12501ab64890Smrg
12511ab64890SmrgError_On_Reset:
12521ab64890Smrg    _XimFreeCommitInfo( ic );
12531ab64890Smrg    return new_commit;
12541ab64890Smrg}
12551ab64890Smrg
1256eb411b4bSmrgstatic wchar_t *
12571ab64890Smrg_XimProtoWcReset(
12581ab64890Smrg    XIC		 xic)
12591ab64890Smrg{
12601ab64890Smrg    return (wchar_t *) _XimProtoReset(xic,
12611ab64890Smrg			(char * (*) (Xim, Xic, XPointer)) _XimCommitedWcString);
12621ab64890Smrg}
12631ab64890Smrg
1264eb411b4bSmrgstatic char *
12651ab64890Smrg_XimCommitedUtf8String(
12661ab64890Smrg    Xim			 im,
12671ab64890Smrg    Xic			 ic,
12681ab64890Smrg    XPointer		 buf)
12691ab64890Smrg{
12701ab64890Smrg    CARD16		*buf_s = (CARD16 *)buf;
12711ab64890Smrg    XimCommitInfo	 info;
12721ab64890Smrg    int			 len;
12731ab64890Smrg    int			 new_len;
12741ab64890Smrg    char		*commit;
12751ab64890Smrg    char		*new_commit = NULL;
12761ab64890Smrg    char		*str;
12771ab64890Smrg    Status		 status;
12781ab64890Smrg
12791ab64890Smrg    len = 0;
12801ab64890Smrg    for (info = ic->private.proto.commit_info; info; info = info->next)
12811ab64890Smrg	len += info->string_len;
12821ab64890Smrg    len += buf_s[0];
12831ab64890Smrg    if ( len == 0 )
12841ab64890Smrg	return( NULL );
12851ab64890Smrg
1286818534a1Smrg    if (!(commit = Xmalloc(len + 1)))
12871ab64890Smrg	goto Error_On_Reset;
12881ab64890Smrg
12891ab64890Smrg    str = commit;
12901ab64890Smrg    for (info = ic->private.proto.commit_info; info; info = info->next) {
12911ab64890Smrg	(void)memcpy(str, info->string, info->string_len);
12921ab64890Smrg	str += info->string_len;
12931ab64890Smrg    }
12941ab64890Smrg    (void)memcpy(str, (char *)&buf_s[1], buf_s[0]);
12951ab64890Smrg    commit[len] = '\0';
12961ab64890Smrg
12971ab64890Smrg    new_len = im->methods->ctstoutf8((XIM)im, commit, len, NULL, 0, &status);
12981ab64890Smrg    if (status != XLookupNone) {
12991ab64890Smrg	if (!(new_commit = Xmalloc(new_len + 1))) {
13001ab64890Smrg	    Xfree(commit);
13011ab64890Smrg	    goto Error_On_Reset;
13021ab64890Smrg	}
13031ab64890Smrg	(void)im->methods->ctstoutf8((XIM)im, commit, len,
13041ab64890Smrg						new_commit, new_len, NULL);
13051ab64890Smrg	new_commit[new_len] = '\0';
13061ab64890Smrg    }
13071ab64890Smrg    Xfree(commit);
13081ab64890Smrg
13091ab64890SmrgError_On_Reset:
13101ab64890Smrg    _XimFreeCommitInfo( ic );
13111ab64890Smrg    return new_commit;
13121ab64890Smrg}
13131ab64890Smrg
1314eb411b4bSmrgstatic char *
13151ab64890Smrg_XimProtoUtf8Reset(
13161ab64890Smrg    XIC		 xic)
13171ab64890Smrg{
13181ab64890Smrg    return _XimProtoReset(xic, _XimCommitedUtf8String);
13191ab64890Smrg}
13201ab64890Smrg
1321eb411b4bSmrgstatic XICMethodsRec ic_methods = {
13221ab64890Smrg    _XimProtoDestroyIC,		/* destroy */
13231ab64890Smrg    _XimProtoSetFocus,		/* set_focus */
13241ab64890Smrg    _XimProtoUnsetFocus,	/* unset_focus */
13251ab64890Smrg    _XimProtoSetICValues,	/* set_values */
13261ab64890Smrg    _XimProtoGetICValues,	/* get_values */
13271ab64890Smrg    _XimProtoMbReset,		/* mb_reset */
13281ab64890Smrg    _XimProtoWcReset,		/* wc_reset */
13291ab64890Smrg    _XimProtoUtf8Reset,		/* utf8_reset */
13301ab64890Smrg    _XimProtoMbLookupString,	/* mb_lookup_string */
13311ab64890Smrg    _XimProtoWcLookupString,	/* wc_lookup_string */
13321ab64890Smrg    _XimProtoUtf8LookupString	/* utf8_lookup_string */
13331ab64890Smrg};
13341ab64890Smrg
1335eb411b4bSmrgstatic Bool
13361ab64890Smrg_XimGetInputStyle(
13371ab64890Smrg    XIMArg		*arg,
13381ab64890Smrg    XIMStyle		*input_style)
13391ab64890Smrg{
13401ab64890Smrg    register XIMArg	*p;
13411ab64890Smrg
13421ab64890Smrg    for (p = arg; p && p->name; p++) {
13431ab64890Smrg	if (!(strcmp(p->name, XNInputStyle))) {
13441ab64890Smrg	    *input_style = (XIMStyle)p->value;
13451ab64890Smrg	    return True;
13461ab64890Smrg	}
13471ab64890Smrg    }
13481ab64890Smrg    return False;
13491ab64890Smrg}
13501ab64890Smrg
13511ab64890Smrg#ifdef XIM_CONNECTABLE
1352eb411b4bSmrgstatic Bool
13531ab64890Smrg_XimDelayModeCreateIC(
13541ab64890Smrg    Xic			 ic,
13551ab64890Smrg    XIMArg		*values,
13561ab64890Smrg    XIMResourceList	 res,
13571ab64890Smrg    unsigned int	 num)
13581ab64890Smrg{
13591ab64890Smrg    Xim			 im = (Xim)ic->core.im;
13601ab64890Smrg    XimDefICValues	 ic_values;
13611ab64890Smrg    int			 len;
13621ab64890Smrg    XIMStyle		 input_style;
136361b2299dSmrg
13641ab64890Smrg    bzero((char *)&ic_values, sizeof(XimDefICValues));
13651ab64890Smrg    _XimGetCurrentICValues(ic, &ic_values);
13661ab64890Smrg    if (!(_XimGetInputStyle(values, &input_style)))
13671ab64890Smrg	return False;
13681ab64890Smrg
13691ab64890Smrg    _XimSetICMode(res, num, input_style);
13701ab64890Smrg
13711ab64890Smrg    if (_XimSetICValueData(ic, (XPointer)&ic_values, res, num,
13721ab64890Smrg					values, XIM_CREATEIC, False)) {
13731ab64890Smrg	return False;
13741ab64890Smrg    }
13751ab64890Smrg    _XimSetCurrentICValues(ic, &ic_values);
13761ab64890Smrg    if (!_XimSetICDefaults(ic, (XPointer)&ic_values,
13771ab64890Smrg					XIM_SETICDEFAULTS, res, num)) {
13781ab64890Smrg	return False;
13791ab64890Smrg    }
13801ab64890Smrg    ic_values.filter_events = KeyPressMask;
13811ab64890Smrg    _XimSetCurrentICValues(ic, &ic_values);
13821ab64890Smrg    _XimRegisterFilter(ic);
13831ab64890Smrg
13841ab64890Smrg    return True;
13851ab64890Smrg}
13861ab64890Smrg
1387eb411b4bSmrgBool
13881ab64890Smrg_XimReconnectModeCreateIC(ic)
13891ab64890Smrg    Xic			 ic;
13901ab64890Smrg{
13911ab64890Smrg    Xim			 im = (Xim)ic->core.im;
13921ab64890Smrg    int			 len;
13931ab64890Smrg    XIMStyle		 input_style = ic->core.input_style;
13941ab64890Smrg    XIMResourceList	 res;
13951ab64890Smrg    unsigned int	 num;
13961ab64890Smrg
13971ab64890Smrg    num = im->core.ic_num_resources;
13981ab64890Smrg    len = sizeof(XIMResource) * num;
1399818534a1Smrg    if (!(res = Xmalloc(len)))
14001ab64890Smrg	return False;
14011ab64890Smrg    (void)memcpy((char *)res, (char *)im->core.ic_resources, len);
14021ab64890Smrg    ic->private.proto.ic_resources     = res;
14031ab64890Smrg    ic->private.proto.ic_num_resources = num;
14041ab64890Smrg
14051ab64890Smrg    _XimSetICMode(res, num, input_style);
14061ab64890Smrg
14071ab64890Smrg    ic->core.filter_events = KeyPressMask;
14081ab64890Smrg
14091ab64890Smrg    return True;
14101ab64890Smrg}
14111ab64890Smrg#endif /* XIM_CONNECTABLE */
14121ab64890Smrg
1413eb411b4bSmrgXIC
14141ab64890Smrg_XimProtoCreateIC(
14151ab64890Smrg    XIM			 xim,
14161ab64890Smrg    XIMArg		*arg)
14171ab64890Smrg{
14181ab64890Smrg    Xim			 im = (Xim)xim;
14191ab64890Smrg    Xic			 ic;
14201ab64890Smrg    XimDefICValues	 ic_values;
14211ab64890Smrg    XIMResourceList	 res;
14221ab64890Smrg    unsigned int         num;
14231ab64890Smrg    XIMStyle		 input_style;
14241ab64890Smrg    INT16		 len;
14251ab64890Smrg    CARD16		*buf_s;
14261ab64890Smrg    char		*tmp;
14271ab64890Smrg    CARD32		 tmp_buf32[BUFSIZE/4];
14281ab64890Smrg    char		*tmp_buf = (char *)tmp_buf32;
14291ab64890Smrg    char		*buf;
14301ab64890Smrg    int			 buf_size;
14311ab64890Smrg    char		*data;
14321ab64890Smrg    int			 data_len;
14331ab64890Smrg    int			 ret_len;
14341ab64890Smrg    int			 total;
14351ab64890Smrg    XIMArg		*arg_ret;
14361ab64890Smrg    CARD32		 reply32[BUFSIZE/4];
14371ab64890Smrg    char		*reply = (char *)reply32;
14381ab64890Smrg    XPointer		 preply;
14391ab64890Smrg    int			 ret_code;
14401ab64890Smrg
14411ab64890Smrg#ifdef XIM_CONNECTABLE
14421ab64890Smrg    if (!IS_SERVER_CONNECTED(im) && !IS_CONNECTABLE(im))
14431ab64890Smrg	return (XIC)NULL;
14441ab64890Smrg#else
14451ab64890Smrg    if (!IS_SERVER_CONNECTED(im))
14461ab64890Smrg	return (XIC)NULL;
14471ab64890Smrg#endif /* XIM_CONNECTABLE */
14481ab64890Smrg
14491ab64890Smrg    if (!(_XimGetInputStyle(arg, &input_style)))
14501ab64890Smrg	return (XIC)NULL;
14511ab64890Smrg
14526cc2b21fSmrg    if ((ic = Xcalloc(1, sizeof(XicRec))) == (Xic)NULL)
14531ab64890Smrg	return (XIC)NULL;
14541ab64890Smrg
14551ab64890Smrg    ic->methods = &ic_methods;
14561ab64890Smrg    ic->core.im = (XIM)im;
14571ab64890Smrg    ic->core.input_style = input_style;
14581ab64890Smrg
14591ab64890Smrg    num = im->core.ic_num_resources;
14601ab64890Smrg    len = sizeof(XIMResource) * num;
1461818534a1Smrg    if (!(res = Xmalloc(len)))
14626cc2b21fSmrg	goto ErrorOnCreatingIC;
14631ab64890Smrg    (void)memcpy((char *)res, (char *)im->core.ic_resources, len);
14641ab64890Smrg    ic->private.proto.ic_resources     = res;
14651ab64890Smrg    ic->private.proto.ic_num_resources = num;
14661ab64890Smrg
14671ab64890Smrg#ifdef XIM_CONNECTABLE
14681ab64890Smrg    if (!_XimSaveICValues(ic, arg))
14691ab64890Smrg	return False;
14701ab64890Smrg
14711ab64890Smrg    if (!IS_SERVER_CONNECTED(im)) {
14721ab64890Smrg	if (!_XimConnectServer(im)) {
14731ab64890Smrg	    if (_XimDelayModeCreateIC(ic, arg, res, num)) {
14741ab64890Smrg		return (XIC)ic;
14751ab64890Smrg	    }
14761ab64890Smrg	    goto ErrorOnCreatingIC;
14771ab64890Smrg	}
14781ab64890Smrg    }
14791ab64890Smrg#endif /* XIM_CONNECTABLE */
14801ab64890Smrg
14811ab64890Smrg    ic->core.filter_events = im->private.proto.forward_event_mask;
14821ab64890Smrg    ic->private.proto.forward_event_mask =
14831ab64890Smrg				im->private.proto.forward_event_mask;
14841ab64890Smrg    ic->private.proto.synchronous_event_mask =
14851ab64890Smrg				im->private.proto.synchronous_event_mask;
14861ab64890Smrg
14871ab64890Smrg    num = im->private.proto.ic_num_inner_resources;
14881ab64890Smrg    len = sizeof(XIMResource) * num;
1489818534a1Smrg    if (!(res = Xmalloc(len)))
14906cc2b21fSmrg	goto ErrorOnCreatingIC;
14911ab64890Smrg    (void)memcpy((char *)res,
14921ab64890Smrg			 (char *)im->private.proto.ic_inner_resources, len);
14931ab64890Smrg    ic->private.proto.ic_inner_resources     = res;
14941ab64890Smrg    ic->private.proto.ic_num_inner_resources = num;
14951ab64890Smrg
14961ab64890Smrg    _XimSetICMode(ic->private.proto.ic_resources,
14971ab64890Smrg			ic->private.proto.ic_num_resources, input_style);
14981ab64890Smrg
14991ab64890Smrg    _XimSetICMode(ic->private.proto.ic_inner_resources,
15001ab64890Smrg			ic->private.proto.ic_num_inner_resources, input_style);
15011ab64890Smrg
15021ab64890Smrg    _XimGetCurrentICValues(ic, &ic_values);
15031ab64890Smrg    buf = tmp_buf;
15041ab64890Smrg    buf_size = XIM_HEADER_SIZE + sizeof(CARD16) + sizeof(INT16);
15051ab64890Smrg    data_len = BUFSIZE - buf_size;
15061ab64890Smrg    total = 0;
15071ab64890Smrg    arg_ret = arg;
15081ab64890Smrg    for (;;) {
15091ab64890Smrg	data = &buf[buf_size];
15101ab64890Smrg	if (_XimEncodeICATTRIBUTE(ic, ic->private.proto.ic_resources,
15111ab64890Smrg		ic->private.proto.ic_num_resources, arg, &arg_ret, data,
15121ab64890Smrg		data_len, &ret_len, (XPointer)&ic_values, 0, XIM_CREATEIC)) {
15131ab64890Smrg	    goto ErrorOnCreatingIC;
15141ab64890Smrg	}
15151ab64890Smrg
15161ab64890Smrg	total += ret_len;
15171ab64890Smrg	if (!(arg = arg_ret)) {
15181ab64890Smrg	    break;
15191ab64890Smrg	}
15201ab64890Smrg
15211ab64890Smrg	buf_size += ret_len;
15221ab64890Smrg	if (buf == tmp_buf) {
1523818534a1Smrg	    if (!(tmp = Xmalloc(buf_size + data_len))) {
15241ab64890Smrg	        goto ErrorOnCreatingIC;
15251ab64890Smrg	    }
15261ab64890Smrg	    memcpy(tmp, buf, buf_size);
15271ab64890Smrg	    buf = tmp;
15281ab64890Smrg	} else {
1529818534a1Smrg	    if (!(tmp = Xrealloc(buf, (buf_size + data_len)))) {
15301ab64890Smrg		Xfree(buf);
15311ab64890Smrg	        goto ErrorOnCreatingIC;
15321ab64890Smrg	    }
15331ab64890Smrg	    buf = tmp;
15341ab64890Smrg	}
15351ab64890Smrg    }
15361ab64890Smrg    _XimSetCurrentICValues(ic, &ic_values);
15371ab64890Smrg
15381ab64890Smrg    if (!(_XimCheckCreateICValues(ic->private.proto.ic_resources,
15391ab64890Smrg					ic->private.proto.ic_num_resources)))
15401ab64890Smrg	goto ErrorOnCreatingIC;
15411ab64890Smrg
15421ab64890Smrg    _XimRegisterFilter(ic);
15431ab64890Smrg
15441ab64890Smrg    buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
15451ab64890Smrg    buf_s[0] = im->private.proto.imid;
15461ab64890Smrg    buf_s[1] = (INT16)total;
15471ab64890Smrg
15481ab64890Smrg    len = (INT16)(sizeof(CARD16) + sizeof(INT16) + total);
15491ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_CREATE_IC, 0, &len);
15501ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf))) {
15511ab64890Smrg	if (buf != tmp_buf)
15521ab64890Smrg	    Xfree(buf);
15531ab64890Smrg	goto ErrorOnCreatingIC;
15541ab64890Smrg    }
15551ab64890Smrg    _XimFlush(im);
15561ab64890Smrg    if (buf != tmp_buf)
15571ab64890Smrg	Xfree(buf);
15581ab64890Smrg    ic->private.proto.waitCallback = True;
15591ab64890Smrg    buf_size = BUFSIZE;
15601ab64890Smrg    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
15611ab64890Smrg						 _XimCreateICCheck, 0);
15621ab64890Smrg    if (ret_code == XIM_TRUE) {
15631ab64890Smrg	preply = reply;
15641ab64890Smrg    } else if (ret_code == XIM_OVERFLOW) {
15651ab64890Smrg	if (len <= 0) {
15661ab64890Smrg	    preply = reply;
15671ab64890Smrg	} else {
15681ab64890Smrg	    buf_size = (int)len;
1569818534a1Smrg	    preply = Xmalloc(buf_size);
15701ab64890Smrg	    ret_code = _XimRead(im, &len, preply, buf_size,
15711ab64890Smrg						 _XimCreateICCheck, 0);
15721ab64890Smrg	    if (ret_code != XIM_TRUE) {
15731ab64890Smrg		Xfree(preply);
15741ab64890Smrg		ic->private.proto.waitCallback = False;
15751ab64890Smrg		goto ErrorOnCreatingIC;
15761ab64890Smrg	    }
15771ab64890Smrg	}
15781ab64890Smrg    } else {
15791ab64890Smrg	ic->private.proto.waitCallback = False;
15801ab64890Smrg	goto ErrorOnCreatingIC;
15811ab64890Smrg    }
15821ab64890Smrg    ic->private.proto.waitCallback = False;
15831ab64890Smrg    buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
15841ab64890Smrg    if (*((CARD8 *)preply) == XIM_ERROR) {
15851ab64890Smrg	_XimProcError(im, 0, (XPointer)&buf_s[3]);
15861ab64890Smrg	if (reply != preply)
15871ab64890Smrg	    Xfree(preply);
15881ab64890Smrg	goto ErrorOnCreatingIC;
15891ab64890Smrg    }
15901ab64890Smrg
15911ab64890Smrg    ic->private.proto.icid = buf_s[1];		/* icid */
15921ab64890Smrg    if (reply != preply)
15931ab64890Smrg	Xfree(preply);
15941ab64890Smrg    MARK_IC_CONNECTED(ic);
15951ab64890Smrg    return (XIC)ic;
15961ab64890Smrg
15971ab64890SmrgErrorOnCreatingIC:
15981ab64890Smrg    _XimUnregisterFilter(ic);
15990f8248bfSmrg
16000f8248bfSmrg    Xfree(ic->private.proto.ic_resources);
16010f8248bfSmrg    Xfree(ic->private.proto.ic_inner_resources);
16021ab64890Smrg    Xfree(ic);
16031ab64890Smrg    return (XIC)NULL;
16041ab64890Smrg}
1605