imDefLkup.c revision e9628295
11ab64890Smrg/******************************************************************
21ab64890Smrg
31ab64890Smrg           Copyright 1992, 1993, 1994 by FUJITSU LIMITED
41ab64890Smrg
51ab64890SmrgPermission to use, copy, modify, distribute, and sell this software
61ab64890Smrgand its documentation for any purpose is hereby granted without fee,
71ab64890Smrgprovided that the above copyright notice appear in all copies and
81ab64890Smrgthat both that copyright notice and this permission notice appear
91ab64890Smrgin supporting documentation, and that the name of FUJITSU LIMITED
101ab64890Smrgnot be used in advertising or publicity pertaining to distribution
111ab64890Smrgof the software without specific, written prior permission.
121ab64890SmrgFUJITSU LIMITED makes no representations about the suitability of
1361b2299dSmrgthis software for any purpose.
141ab64890SmrgIt is provided "as is" without express or implied warranty.
151ab64890Smrg
161ab64890SmrgFUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
171ab64890SmrgINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
181ab64890SmrgEVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
191ab64890SmrgCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
201ab64890SmrgUSE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
211ab64890SmrgOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
221ab64890SmrgPERFORMANCE OF THIS SOFTWARE.
231ab64890Smrg
2461b2299dSmrg  Author: Takashi Fujiwara     FUJITSU LIMITED
251ab64890Smrg                               fujiwara@a80.tech.yk.fujitsu.co.jp
261ab64890Smrg
271ab64890Smrg******************************************************************/
281ab64890Smrg
291ab64890Smrg#ifdef HAVE_CONFIG_H
301ab64890Smrg#include <config.h>
311ab64890Smrg#endif
321ab64890Smrg#include <X11/Xatom.h>
331ab64890Smrg#include "Xlibint.h"
341ab64890Smrg#include "Xlcint.h"
351ab64890Smrg#include "Ximint.h"
361ab64890Smrg
37eb411b4bSmrgXic
381ab64890Smrg_XimICOfXICID(
391ab64890Smrg    Xim		  im,
401ab64890Smrg    XICID	  icid)
411ab64890Smrg{
421ab64890Smrg    Xic		  pic;
431ab64890Smrg
441ab64890Smrg    for (pic = (Xic)im->core.ic_chain; pic; pic = (Xic)pic->core.next) {
451ab64890Smrg	if (pic->private.proto.icid == icid)
461ab64890Smrg	    return pic;
471ab64890Smrg    }
481ab64890Smrg    return (Xic)0;
491ab64890Smrg}
501ab64890Smrg
51eb411b4bSmrgstatic void
521ab64890Smrg_XimProcIMSetEventMask(
531ab64890Smrg    Xim		 im,
541ab64890Smrg    XPointer	 buf)
551ab64890Smrg{
561ab64890Smrg    EVENTMASK	*buf_l = (EVENTMASK *)buf;
571ab64890Smrg
581ab64890Smrg    im->private.proto.forward_event_mask     = buf_l[0];
591ab64890Smrg    im->private.proto.synchronous_event_mask = buf_l[1];
601ab64890Smrg    return;
611ab64890Smrg}
621ab64890Smrg
63eb411b4bSmrgstatic void
641ab64890Smrg_XimProcICSetEventMask(
651ab64890Smrg    Xic		 ic,
661ab64890Smrg    XPointer	 buf)
671ab64890Smrg{
681ab64890Smrg    EVENTMASK	*buf_l = (EVENTMASK *)buf;
691ab64890Smrg
701ab64890Smrg    ic->private.proto.forward_event_mask     = buf_l[0];
711ab64890Smrg    ic->private.proto.synchronous_event_mask = buf_l[1];
721ab64890Smrg    _XimReregisterFilter(ic);
731ab64890Smrg    return;
741ab64890Smrg}
751ab64890Smrg
76eb411b4bSmrgBool
771ab64890Smrg_XimSetEventMaskCallback(
781ab64890Smrg    Xim		 xim,
791ab64890Smrg    INT16	 len,
801ab64890Smrg    XPointer	 data,
811ab64890Smrg    XPointer	 call_data)
821ab64890Smrg{
831ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
841ab64890Smrg    XIMID        imid = buf_s[0];
851ab64890Smrg    XICID        icid = buf_s[1];
861ab64890Smrg    Xim		 im = (Xim)call_data;
871ab64890Smrg    Xic		 ic;
881ab64890Smrg
891ab64890Smrg    if (imid == im->private.proto.imid) {
901ab64890Smrg	if (icid) {
91e9628295Smrg	    if (!(ic = _XimICOfXICID(im, icid)))
92e9628295Smrg		return False;
931ab64890Smrg	    _XimProcICSetEventMask(ic, (XPointer)&buf_s[2]);
941ab64890Smrg	} else {
951ab64890Smrg	    _XimProcIMSetEventMask(im, (XPointer)&buf_s[2]);
961ab64890Smrg	}
971ab64890Smrg	return True;
981ab64890Smrg    }
991ab64890Smrg    return False;
1001ab64890Smrg}
1011ab64890Smrg
102eb411b4bSmrgstatic Bool
1031ab64890Smrg_XimSyncCheck(
1041ab64890Smrg    Xim          im,
1051ab64890Smrg    INT16        len,
1061ab64890Smrg    XPointer	 data,
1071ab64890Smrg    XPointer     arg)
1081ab64890Smrg{
1091ab64890Smrg    Xic		 ic  = (Xic)arg;
1101ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
1111ab64890Smrg    CARD8	 major_opcode = *((CARD8 *)data);
1121ab64890Smrg    CARD8	 minor_opcode = *((CARD8 *)data + 1);
1131ab64890Smrg    XIMID	 imid = buf_s[0];
1141ab64890Smrg    XICID	 icid = buf_s[1];
1151ab64890Smrg
1161ab64890Smrg    if ((major_opcode == XIM_SYNC_REPLY)
1171ab64890Smrg     && (minor_opcode == 0)
1181ab64890Smrg     && (imid == im->private.proto.imid)
1191ab64890Smrg     && (icid == ic->private.proto.icid))
1201ab64890Smrg	return True;
1211ab64890Smrg    if ((major_opcode == XIM_ERROR)
1221ab64890Smrg     && (minor_opcode == 0)
1231ab64890Smrg     && (buf_s[2] & XIM_IMID_VALID)
1241ab64890Smrg     && (imid == im->private.proto.imid)
1251ab64890Smrg     && (buf_s[2] & XIM_ICID_VALID)
1261ab64890Smrg     && (icid == ic->private.proto.icid))
1271ab64890Smrg	return True;
1281ab64890Smrg    return False;
1291ab64890Smrg}
1301ab64890Smrg
131eb411b4bSmrgBool
1321ab64890Smrg_XimSync(
1331ab64890Smrg    Xim		 im,
1341ab64890Smrg    Xic		 ic)
1351ab64890Smrg{
1361ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
1371ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
1381ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
1391ab64890Smrg    INT16	 len;
1401ab64890Smrg    CARD32	 reply32[BUFSIZE/4];
1411ab64890Smrg    char	*reply = (char *)reply32;
1421ab64890Smrg    XPointer	 preply;
1431ab64890Smrg    int		 buf_size;
1441ab64890Smrg    int		 ret_code;
1451ab64890Smrg
1461ab64890Smrg    buf_s[0] = im->private.proto.imid;		/* imid */
1471ab64890Smrg    buf_s[1] = ic->private.proto.icid;		/* icid */
1481ab64890Smrg
1491ab64890Smrg    len = sizeof(CARD16)			/* sizeof imid */
1501ab64890Smrg	+ sizeof(CARD16);			/* sizeof icid */
1511ab64890Smrg
1521ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_SYNC, 0, &len);
1531ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
1541ab64890Smrg	return False;
1551ab64890Smrg    _XimFlush(im);
1561ab64890Smrg    buf_size = BUFSIZE;
1571ab64890Smrg    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
1581ab64890Smrg					_XimSyncCheck, (XPointer)ic);
1591ab64890Smrg    if(ret_code == XIM_TRUE) {
1601ab64890Smrg	preply = reply;
1611ab64890Smrg    } else if(ret_code == XIM_OVERFLOW) {
1621ab64890Smrg	if(len <= 0) {
1631ab64890Smrg	    preply = reply;
1641ab64890Smrg	} else {
1651ab64890Smrg	    buf_size = len;
166818534a1Smrg	    preply = Xmalloc(len);
1671ab64890Smrg	    ret_code = _XimRead(im, &len, preply, buf_size,
1681ab64890Smrg					_XimSyncCheck, (XPointer)ic);
1691ab64890Smrg	    if(ret_code != XIM_TRUE) {
1701ab64890Smrg		Xfree(preply);
1711ab64890Smrg		return False;
1721ab64890Smrg	    }
1731ab64890Smrg	}
1741ab64890Smrg    } else {
1751ab64890Smrg	return False;
1761ab64890Smrg    }
1771ab64890Smrg    buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
1781ab64890Smrg    if (*((CARD8 *)preply) == XIM_ERROR) {
1791ab64890Smrg	_XimProcError(im, 0, (XPointer)&buf_s[3]);
1801ab64890Smrg	if(reply != preply)
1811ab64890Smrg	    Xfree(preply);
1821ab64890Smrg	return False;
1831ab64890Smrg    }
1841ab64890Smrg    if(reply != preply)
1851ab64890Smrg	Xfree(preply);
1861ab64890Smrg    return True;
1871ab64890Smrg}
1881ab64890Smrg
189eb411b4bSmrgBool
1901ab64890Smrg_XimProcSyncReply(
1911ab64890Smrg    Xim		 im,
1921ab64890Smrg    Xic		 ic)
1931ab64890Smrg{
1941ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
1951ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
1961ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
1971ab64890Smrg    INT16	 len;
1981ab64890Smrg
1991ab64890Smrg    buf_s[0] = im->private.proto.imid;		/* imid */
2001ab64890Smrg    buf_s[1] = ic->private.proto.icid;		/* icid */
2011ab64890Smrg
2021ab64890Smrg    len = sizeof(CARD16)			/* sizeof imid */
2031ab64890Smrg	+ sizeof(CARD16);			/* sizeof icid */
2041ab64890Smrg
2051ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_SYNC_REPLY, 0, &len);
2061ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
2071ab64890Smrg	return False;
2081ab64890Smrg    _XimFlush(im);
2091ab64890Smrg    return True;
2101ab64890Smrg}
2111ab64890Smrg
212eb411b4bSmrgBool
2131ab64890Smrg_XimRespSyncReply(
2141ab64890Smrg    Xic		 ic,
2151ab64890Smrg    BITMASK16	 mode)
2161ab64890Smrg{
217eb411b4bSmrg    if (mode & XimSYNCHRONUS) /* SYNC Request */
218eb411b4bSmrg	MARK_NEED_SYNC_REPLY(ic->core.im);
21961b2299dSmrg
2201ab64890Smrg    return True;
2211ab64890Smrg}
2221ab64890Smrg
223eb411b4bSmrgBool
2241ab64890Smrg_XimSyncCallback(
2251ab64890Smrg    Xim		 xim,
2261ab64890Smrg    INT16	 len,
2271ab64890Smrg    XPointer	 data,
2281ab64890Smrg    XPointer	 call_data)
2291ab64890Smrg{
2301ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
2311ab64890Smrg    XIMID        imid = buf_s[0];
2321ab64890Smrg    XICID        icid = buf_s[1];
2331ab64890Smrg    Xim		 im = (Xim)call_data;
2341ab64890Smrg    Xic		 ic;
2351ab64890Smrg
2361ab64890Smrg    if ((imid == im->private.proto.imid)
2371ab64890Smrg     && (ic = _XimICOfXICID(im, icid))) {
2381ab64890Smrg	(void)_XimProcSyncReply(im, ic);
2391ab64890Smrg	return True;
2401ab64890Smrg    }
2411ab64890Smrg    return False;
2421ab64890Smrg}
2431ab64890Smrg
244eb411b4bSmrgstatic INT16
2451ab64890Smrg_XimSetEventToWire(
2461ab64890Smrg    XEvent	*ev,
2471ab64890Smrg    xEvent	*event)
2481ab64890Smrg{
2491ab64890Smrg    if (!(_XimProtoEventToWire(ev, event, False)))
2501ab64890Smrg	return 0;
2511ab64890Smrg    event->u.u.sequenceNumber =
2521ab64890Smrg		((XAnyEvent *)ev)->serial & (unsigned long)0xffff;
2531ab64890Smrg    return sz_xEvent;
2541ab64890Smrg}
2551ab64890Smrg
256eb411b4bSmrgstatic Bool
2571ab64890Smrg_XimForwardEventCore(
2581ab64890Smrg    Xic		 ic,
2591ab64890Smrg    XEvent	*ev,
2601ab64890Smrg    Bool	 sync)
2611ab64890Smrg{
2621ab64890Smrg    Xim		 im = (Xim)ic->core.im;
2631ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
2641ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
2651ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
2661ab64890Smrg    CARD32	 reply32[BUFSIZE/4];
2671ab64890Smrg    char	*reply = (char *)reply32;
2681ab64890Smrg    XPointer	 preply;
2691ab64890Smrg    int		 buf_size;
2701ab64890Smrg    int		 ret_code;
2711ab64890Smrg    INT16	 len;
2721ab64890Smrg
273818534a1Smrg    bzero(buf32, sizeof(buf32)); /* valgrind noticed uninitialized memory use! */
274818534a1Smrg
2751ab64890Smrg    if (!(len = _XimSetEventToWire(ev, (xEvent *)&buf_s[4])))
2761ab64890Smrg	return False;				/* X event */
2771ab64890Smrg
2781ab64890Smrg    buf_s[0] = im->private.proto.imid;		/* imid */
2791ab64890Smrg    buf_s[1] = ic->private.proto.icid;		/* icid */
2801ab64890Smrg    buf_s[2] = sync ? XimSYNCHRONUS : 0;	/* flag */
2811ab64890Smrg    buf_s[3] =
2821ab64890Smrg        (CARD16)((((XAnyEvent *)ev)->serial & ~((unsigned long)0xffff)) >> 16);
2831ab64890Smrg						/* serial number */
2841ab64890Smrg
2851ab64890Smrg    len += sizeof(CARD16)			/* sizeof imid */
2861ab64890Smrg	 + sizeof(CARD16)			/* sizeof icid */
2871ab64890Smrg	 + sizeof(BITMASK16)			/* sizeof flag */
2881ab64890Smrg	 + sizeof(CARD16);			/* sizeof serila number */
2891ab64890Smrg
2901ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_FORWARD_EVENT, 0, &len);
2911ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
2921ab64890Smrg	return False;
2931ab64890Smrg    _XimFlush(im);
2941ab64890Smrg
2951ab64890Smrg    if (sync) {
2961ab64890Smrg	buf_size = BUFSIZE;
2971ab64890Smrg	ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
2981ab64890Smrg					_XimSyncCheck, (XPointer)ic);
2991ab64890Smrg	if(ret_code == XIM_TRUE) {
3001ab64890Smrg	    preply = reply;
3011ab64890Smrg	} else if(ret_code == XIM_OVERFLOW) {
3021ab64890Smrg	    if(len <= 0) {
3031ab64890Smrg		preply = reply;
3041ab64890Smrg	    } else {
3051ab64890Smrg		buf_size = len;
306818534a1Smrg		preply = Xmalloc(len);
3071ab64890Smrg		ret_code = _XimRead(im, &len, preply, buf_size,
3081ab64890Smrg					_XimSyncCheck, (XPointer)ic);
3091ab64890Smrg		if(ret_code != XIM_TRUE) {
3101ab64890Smrg		    Xfree(preply);
3111ab64890Smrg		    return False;
3121ab64890Smrg		}
3131ab64890Smrg	    }
3141ab64890Smrg	} else {
3151ab64890Smrg	    return False;
3161ab64890Smrg	}
3171ab64890Smrg	buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
3181ab64890Smrg	if (*((CARD8 *)preply) == XIM_ERROR) {
3191ab64890Smrg	    _XimProcError(im, 0, (XPointer)&buf_s[3]);
3201ab64890Smrg	    if(reply != preply)
3211ab64890Smrg		Xfree(preply);
3221ab64890Smrg	    return False;
3231ab64890Smrg	}
3241ab64890Smrg	if(reply != preply)
3251ab64890Smrg	    Xfree(preply);
3261ab64890Smrg    }
3271ab64890Smrg    return True;
3281ab64890Smrg}
3291ab64890Smrg
330eb411b4bSmrgBool
3311ab64890Smrg_XimForwardEvent(
3321ab64890Smrg    Xic		 ic,
3331ab64890Smrg    XEvent	*ev,
3341ab64890Smrg    Bool	 sync)
3351ab64890Smrg{
3361ab64890Smrg#ifdef EXT_FORWARD
3371ab64890Smrg    if (((ev->type == KeyPress) || (ev->type == KeyRelease)))
3381ab64890Smrg	if (_XimExtForwardKeyEvent(ic, (XKeyEvent *)ev, sync))
3391ab64890Smrg	    return True;
3401ab64890Smrg#endif
3411ab64890Smrg    return _XimForwardEventCore(ic, ev, sync);
3421ab64890Smrg}
3431ab64890Smrg
344eb411b4bSmrgstatic void
3451ab64890Smrg_XimProcEvent(
3461ab64890Smrg    Display		*d,
3471ab64890Smrg    Xic			 ic,
3481ab64890Smrg    XEvent		*ev,
3491ab64890Smrg    CARD16		*buf)
3501ab64890Smrg{
3511ab64890Smrg    INT16	 serial = buf[0];
3521ab64890Smrg    xEvent	*xev = (xEvent *)&buf[1];
3531ab64890Smrg
3541ab64890Smrg    _XimProtoWireToEvent(ev, xev, False);
3551ab64890Smrg    ev->xany.serial |= serial << 16;
3561ab64890Smrg    ev->xany.send_event = False;
3571ab64890Smrg    ev->xany.display = d;
358eb411b4bSmrg    MARK_FABRICATED(ic->core.im);
3591ab64890Smrg    return;
3601ab64890Smrg}
3611ab64890Smrg
362eb411b4bSmrgstatic Bool
3631ab64890Smrg_XimForwardEventRecv(
3641ab64890Smrg    Xim		 im,
3651ab64890Smrg    Xic		 ic,
3661ab64890Smrg    XPointer	 buf)
3671ab64890Smrg{
3681ab64890Smrg    CARD16	*buf_s = (CARD16 *)buf;
3691ab64890Smrg    Display	*d = im->core.display;
3701ab64890Smrg    XEvent	 ev;
3711ab64890Smrg
3721ab64890Smrg    _XimProcEvent(d, ic, &ev, &buf_s[1]);
3731ab64890Smrg
3741ab64890Smrg    (void)_XimRespSyncReply(ic, buf_s[0]);
3751ab64890Smrg
3761ab64890Smrg    XPutBackEvent(d, &ev);
3771ab64890Smrg
3781ab64890Smrg    return True;
3791ab64890Smrg}
3801ab64890Smrg
381eb411b4bSmrgBool
3821ab64890Smrg_XimForwardEventCallback(
3831ab64890Smrg    Xim		 xim,
3841ab64890Smrg    INT16	 len,
3851ab64890Smrg    XPointer	 data,
3861ab64890Smrg    XPointer	 call_data)
3871ab64890Smrg{
3881ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
3891ab64890Smrg    XIMID        imid = buf_s[0];
3901ab64890Smrg    XICID        icid = buf_s[1];
3911ab64890Smrg    Xim		 im = (Xim)call_data;
3921ab64890Smrg    Xic		 ic;
3931ab64890Smrg
3941ab64890Smrg    if ((imid == im->private.proto.imid)
3951ab64890Smrg     && (ic = _XimICOfXICID(im, icid))) {
3961ab64890Smrg	(void)_XimForwardEventRecv(im, ic, (XPointer)&buf_s[2]);
3971ab64890Smrg	return True;
3981ab64890Smrg    }
3991ab64890Smrg    return False;
4001ab64890Smrg}
4011ab64890Smrg
402eb411b4bSmrgstatic Bool
4031ab64890Smrg_XimRegisterTriggerkey(
4041ab64890Smrg    Xim			 im,
4051ab64890Smrg    XPointer		 buf)
4061ab64890Smrg{
4071ab64890Smrg    CARD32		*buf_l = (CARD32 *)buf;
4081ab64890Smrg    CARD32		 len;
4091ab64890Smrg    CARD32 		*key;
4101ab64890Smrg
4111ab64890Smrg    if (IS_DYNAMIC_EVENT_FLOW(im))	/* already Dynamic event flow mode */
4121ab64890Smrg	return True;
4131ab64890Smrg
4141ab64890Smrg    /*
4151ab64890Smrg     *  register onkeylist
4161ab64890Smrg     */
4171ab64890Smrg
4181ab64890Smrg    len = buf_l[0];				/* length of on-keys */
4191ab64890Smrg    len += sizeof(INT32);			/* sizeof length of on-keys */
4201ab64890Smrg
421818534a1Smrg    if (!(key = Xmalloc(len))) {
4221ab64890Smrg	_XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
4231ab64890Smrg	return False;
4241ab64890Smrg    }
4251ab64890Smrg    memcpy((char *)key, (char *)buf_l, len);
4261ab64890Smrg    im->private.proto.im_onkeylist = key;
4271ab64890Smrg
4281ab64890Smrg    MARK_DYNAMIC_EVENT_FLOW(im);
4291ab64890Smrg
4301ab64890Smrg    /*
4311ab64890Smrg     *  register offkeylist
4321ab64890Smrg     */
4331ab64890Smrg
4341ab64890Smrg    buf_l = (CARD32 *)((char *)buf + len);
4351ab64890Smrg    len = buf_l[0];				/* length of off-keys */
4361ab64890Smrg    len += sizeof(INT32);			/* sizeof length of off-keys */
4371ab64890Smrg
438818534a1Smrg    if (!(key = Xmalloc(len))) {
4391ab64890Smrg	_XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
4401ab64890Smrg	return False;
4411ab64890Smrg    }
4421ab64890Smrg
4431ab64890Smrg    memcpy((char *)key, (char *)buf_l, len);
4441ab64890Smrg    im->private.proto.im_offkeylist = key;
4451ab64890Smrg
4461ab64890Smrg    return True;
4471ab64890Smrg}
4481ab64890Smrg
449eb411b4bSmrgBool
4501ab64890Smrg_XimRegisterTriggerKeysCallback(
4511ab64890Smrg    Xim		 xim,
4521ab64890Smrg    INT16	 len,
4531ab64890Smrg    XPointer	 data,
4541ab64890Smrg    XPointer	 call_data)
4551ab64890Smrg{
4561ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
4571ab64890Smrg    Xim		 im = (Xim)call_data;
4581ab64890Smrg
4591ab64890Smrg    (void )_XimRegisterTriggerkey(im, (XPointer)&buf_s[2]);
4601ab64890Smrg    return True;
4611ab64890Smrg}
4621ab64890Smrg
463eb411b4bSmrgEVENTMASK
4641ab64890Smrg_XimGetWindowEventmask(
4651ab64890Smrg    Xic		 ic)
4661ab64890Smrg{
4671ab64890Smrg    Xim			im = (Xim )ic->core.im;
4681ab64890Smrg    XWindowAttributes	atr;
4691ab64890Smrg
4701ab64890Smrg    if (!XGetWindowAttributes(im->core.display, ic->core.focus_window, &atr))
4711ab64890Smrg	return 0;
4721ab64890Smrg    return (EVENTMASK)atr.your_event_mask;
4731ab64890Smrg}
4741ab64890Smrg
4751ab64890Smrg
476eb411b4bSmrgstatic Bool
4771ab64890Smrg_XimTriggerNotifyCheck(
4781ab64890Smrg    Xim          im,
4791ab64890Smrg    INT16        len,
4801ab64890Smrg    XPointer	 data,
4811ab64890Smrg    XPointer     arg)
4821ab64890Smrg{
4831ab64890Smrg    Xic		 ic  = (Xic)arg;
4841ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
4851ab64890Smrg    CARD8	 major_opcode = *((CARD8 *)data);
4861ab64890Smrg    CARD8	 minor_opcode = *((CARD8 *)data + 1);
4871ab64890Smrg    XIMID	 imid = buf_s[0];
4881ab64890Smrg    XICID	 icid = buf_s[1];
4891ab64890Smrg
4901ab64890Smrg    if ((major_opcode == XIM_TRIGGER_NOTIFY_REPLY)
4911ab64890Smrg     && (minor_opcode == 0)
4921ab64890Smrg     && (imid == im->private.proto.imid)
4931ab64890Smrg     && (icid == ic->private.proto.icid))
4941ab64890Smrg	return True;
4951ab64890Smrg    if ((major_opcode == XIM_ERROR)
4961ab64890Smrg     && (minor_opcode == 0)
4971ab64890Smrg     && (buf_s[2] & XIM_IMID_VALID)
4981ab64890Smrg     && (imid == im->private.proto.imid)
4991ab64890Smrg     && (buf_s[2] & XIM_ICID_VALID)
5001ab64890Smrg     && (icid == ic->private.proto.icid))
5011ab64890Smrg	return True;
5021ab64890Smrg    return False;
5031ab64890Smrg}
5041ab64890Smrg
505eb411b4bSmrgBool
5061ab64890Smrg_XimTriggerNotify(
5071ab64890Smrg    Xim		 im,
5081ab64890Smrg    Xic		 ic,
5091ab64890Smrg    int		 mode,
5101ab64890Smrg    CARD32	 idx)
5111ab64890Smrg{
5121ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
5131ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
5141ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
5151ab64890Smrg    CARD32	*buf_l = (CARD32 *)&buf[XIM_HEADER_SIZE];
5161ab64890Smrg    CARD32	 reply32[BUFSIZE/4];
5171ab64890Smrg    char	*reply = (char *)reply32;
5181ab64890Smrg    XPointer	 preply;
5191ab64890Smrg    int		 buf_size;
5201ab64890Smrg    int		 ret_code;
5211ab64890Smrg    INT16	 len;
5221ab64890Smrg    EVENTMASK	 mask = _XimGetWindowEventmask(ic);
5231ab64890Smrg
5241ab64890Smrg    buf_s[0] = im->private.proto.imid;	/* imid */
5251ab64890Smrg    buf_s[1] = ic->private.proto.icid;	/* icid */
5261ab64890Smrg    buf_l[1] = mode;			/* flag */
5271ab64890Smrg    buf_l[2] = idx;			/* index of keys list */
5281ab64890Smrg    buf_l[3] = mask;			/* select-event-mask */
5291ab64890Smrg
5301ab64890Smrg    len = sizeof(CARD16)		/* sizeof imid */
5311ab64890Smrg	+ sizeof(CARD16)		/* sizeof icid */
5321ab64890Smrg	+ sizeof(CARD32)		/* sizeof flag */
5331ab64890Smrg	+ sizeof(CARD32)		/* sizeof index of key list */
5341ab64890Smrg	+ sizeof(EVENTMASK);		/* sizeof select-event-mask */
5351ab64890Smrg
5361ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_TRIGGER_NOTIFY, 0, &len);
5371ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
5381ab64890Smrg	return False;
5391ab64890Smrg    _XimFlush(im);
5401ab64890Smrg    buf_size = BUFSIZE;
5411ab64890Smrg    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
5421ab64890Smrg				_XimTriggerNotifyCheck, (XPointer)ic);
5431ab64890Smrg    if(ret_code == XIM_TRUE) {
5441ab64890Smrg	preply = reply;
5451ab64890Smrg    } else if(ret_code == XIM_OVERFLOW) {
5461ab64890Smrg	if(len <= 0) {
5471ab64890Smrg	    preply = reply;
5481ab64890Smrg	} else {
5491ab64890Smrg	    buf_size = len;
550818534a1Smrg	    preply = Xmalloc(len);
5511ab64890Smrg	    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
5521ab64890Smrg				_XimTriggerNotifyCheck, (XPointer)ic);
5531ab64890Smrg	    if(ret_code != XIM_TRUE) {
5541ab64890Smrg		Xfree(preply);
5551ab64890Smrg		return False;
5561ab64890Smrg	    }
5571ab64890Smrg	}
5581ab64890Smrg    } else {
5591ab64890Smrg	return False;
5601ab64890Smrg    }
5611ab64890Smrg    buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
5621ab64890Smrg    if (*((CARD8 *)preply) == XIM_ERROR) {
5631ab64890Smrg	_XimProcError(im, 0, (XPointer)&buf_s[3]);
5641ab64890Smrg	if(reply != preply)
5651ab64890Smrg	    Xfree(preply);
5661ab64890Smrg	return False;
5671ab64890Smrg    }
5681ab64890Smrg    if(reply != preply)
5691ab64890Smrg	Xfree(preply);
5701ab64890Smrg    return True;
5711ab64890Smrg}
5721ab64890Smrg
573eb411b4bSmrgstatic Bool
5741ab64890Smrg_XimRegCommitInfo(
5751ab64890Smrg    Xic			 ic,
5761ab64890Smrg    char		*string,
5771ab64890Smrg    int			 string_len,
5781ab64890Smrg    KeySym		*keysym,
5791ab64890Smrg    int			 keysym_len)
5801ab64890Smrg{
5811ab64890Smrg    XimCommitInfo	info;
5821ab64890Smrg
583818534a1Smrg    if (!(info = Xmalloc(sizeof(XimCommitInfoRec))))
5841ab64890Smrg	return False;
5851ab64890Smrg    info->string	= string;
5861ab64890Smrg    info->string_len	= string_len;
5871ab64890Smrg    info->keysym	= keysym;
5881ab64890Smrg    info->keysym_len	= keysym_len;
5891ab64890Smrg    info->next = ic->private.proto.commit_info;
5901ab64890Smrg    ic->private.proto.commit_info = info;
5911ab64890Smrg    return True;
5921ab64890Smrg}
5931ab64890Smrg
594eb411b4bSmrgstatic void
5951ab64890Smrg_XimUnregCommitInfo(
5961ab64890Smrg    Xic			ic)
5971ab64890Smrg{
5981ab64890Smrg    XimCommitInfo	info;
5991ab64890Smrg
6001ab64890Smrg    if (!(info = ic->private.proto.commit_info))
6011ab64890Smrg	return;
6021ab64890Smrg
6030f8248bfSmrg
6040f8248bfSmrg    Xfree(info->string);
6050f8248bfSmrg    Xfree(info->keysym);
6061ab64890Smrg    ic->private.proto.commit_info = info->next;
6071ab64890Smrg    Xfree(info);
6081ab64890Smrg    return;
6091ab64890Smrg}
6101ab64890Smrg
611eb411b4bSmrgvoid
6121ab64890Smrg_XimFreeCommitInfo(
6131ab64890Smrg    Xic			ic)
6141ab64890Smrg{
6151ab64890Smrg    while (ic->private.proto.commit_info)
6161ab64890Smrg	_XimUnregCommitInfo(ic);
6171ab64890Smrg    return;
6181ab64890Smrg}
6191ab64890Smrg
620eb411b4bSmrgstatic Bool
6211ab64890Smrg_XimProcKeySym(
6221ab64890Smrg    Xic			  ic,
6231ab64890Smrg    CARD32		  sym,
6241ab64890Smrg    KeySym		**xim_keysym,
6251ab64890Smrg    int			 *xim_keysym_len)
6261ab64890Smrg{
6271ab64890Smrg    Xim			 im = (Xim)ic->core.im;
6281ab64890Smrg
629818534a1Smrg    if (!(*xim_keysym = Xmalloc(sizeof(KeySym)))) {
6301ab64890Smrg	_XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
6311ab64890Smrg	return False;
6321ab64890Smrg    }
6331ab64890Smrg
6341ab64890Smrg    **xim_keysym = (KeySym)sym;
6351ab64890Smrg    *xim_keysym_len = 1;
6361ab64890Smrg
6371ab64890Smrg    return True;
6381ab64890Smrg}
6391ab64890Smrg
640eb411b4bSmrgstatic Bool
6411ab64890Smrg_XimProcCommit(
6421ab64890Smrg    Xic		  ic,
6431ab64890Smrg    BYTE	 *buf,
6441ab64890Smrg    int		  len,
6451ab64890Smrg    char	**xim_string,
6461ab64890Smrg    int		 *xim_string_len)
6471ab64890Smrg{
6481ab64890Smrg    Xim		 im = (Xim)ic->core.im;
6491ab64890Smrg    char	*string;
6501ab64890Smrg
651818534a1Smrg    if (!(string = Xmalloc(len + 1))) {
6521ab64890Smrg	_XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
6531ab64890Smrg	return False;
6541ab64890Smrg    }
6551ab64890Smrg
6561ab64890Smrg    (void)memcpy(string, (char *)buf, len);
6571ab64890Smrg    string[len] = '\0';
6581ab64890Smrg
6591ab64890Smrg    *xim_string = string;
6601ab64890Smrg    *xim_string_len = len;
6611ab64890Smrg    return True;
6621ab64890Smrg}
6631ab64890Smrg
664eb411b4bSmrgstatic Bool
6651ab64890Smrg_XimCommitRecv(
6661ab64890Smrg    Xim		 im,
6671ab64890Smrg    Xic		 ic,
6681ab64890Smrg    XPointer	 buf)
6691ab64890Smrg{
6701ab64890Smrg    CARD16	*buf_s = (CARD16 *)buf;
6711ab64890Smrg    BITMASK16	 flag = buf_s[0];
6721ab64890Smrg    XKeyEvent	 ev;
6731ab64890Smrg    char	*string = NULL;
6741ab64890Smrg    int		 string_len = 0;
6751ab64890Smrg    KeySym	*keysym = NULL;
6761ab64890Smrg    int		 keysym_len = 0;
6771ab64890Smrg
6781ab64890Smrg    if ((flag & XimLookupBoth) == XimLookupChars) {
6791ab64890Smrg	if (!(_XimProcCommit(ic, (BYTE *)&buf_s[2],
6801ab64890Smrg			 		(int)buf_s[1], &string, &string_len)))
6811ab64890Smrg	    return False;
6821ab64890Smrg
6831ab64890Smrg    } else if ((flag & XimLookupBoth) == XimLookupKeySym) {
6841ab64890Smrg	if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len)))
6851ab64890Smrg	    return False;
6861ab64890Smrg
6871ab64890Smrg    } else if ((flag & XimLookupBoth) == XimLookupBoth) {
6881ab64890Smrg	if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len)))
6891ab64890Smrg	    return False;
6901ab64890Smrg
6911ab64890Smrg	if (!(_XimProcCommit(ic, (BYTE *)&buf_s[5],
6926cc2b21fSmrg					(int)buf_s[4], &string, &string_len))) {
6936cc2b21fSmrg	    Xfree(keysym);
6941ab64890Smrg	    return False;
6956cc2b21fSmrg	}
6961ab64890Smrg    }
6971ab64890Smrg
6981ab64890Smrg    if (!(_XimRegCommitInfo(ic, string, string_len, keysym, keysym_len))) {
6990f8248bfSmrg       Xfree(string);
7000f8248bfSmrg	Xfree(keysym);
7011ab64890Smrg	_XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
7021ab64890Smrg	return False;
7031ab64890Smrg    }
7041ab64890Smrg
7051ab64890Smrg    (void)_XimRespSyncReply(ic, flag);
7061ab64890Smrg
707818534a1Smrg    if (ic->private.proto.registed_filter_event
708818534a1Smrg	& (KEYPRESS_MASK | KEYRELEASE_MASK))
709818534a1Smrg	    MARK_FABRICATED(im);
710818534a1Smrg
711818534a1Smrg    bzero(&ev, sizeof(ev));	/* uninitialized : found when running kterm under valgrind */
7121ab64890Smrg
7131ab64890Smrg    ev.type = KeyPress;
7141ab64890Smrg    ev.send_event = False;
7151ab64890Smrg    ev.display = im->core.display;
7161ab64890Smrg    ev.window = ic->core.focus_window;
7171ab64890Smrg    ev.keycode = 0;
7181ab64890Smrg    ev.state = 0;
7191ab64890Smrg
720818534a1Smrg    ev.time = 0L;
721818534a1Smrg    ev.serial = LastKnownRequestProcessed(im->core.display);
722818534a1Smrg    /* FIXME :
723818534a1Smrg       I wish there were COMMENTs (!) about the data passed around.
724818534a1Smrg    */
725818534a1Smrg#if 0
726818534a1Smrg    fprintf(stderr,"%s,%d: putback k press   FIXED ev.time=0 ev.serial=%lu\n", __FILE__, __LINE__, ev.serial);
727818534a1Smrg#endif
728818534a1Smrg
7291ab64890Smrg    XPutBackEvent(im->core.display, (XEvent *)&ev);
7301ab64890Smrg
7311ab64890Smrg    return True;
7321ab64890Smrg}
7331ab64890Smrg
734eb411b4bSmrgBool
7351ab64890Smrg_XimCommitCallback(
7361ab64890Smrg    Xim		 xim,
7371ab64890Smrg    INT16	 len,
7381ab64890Smrg    XPointer	 data,
7391ab64890Smrg    XPointer	 call_data)
7401ab64890Smrg{
7411ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
7421ab64890Smrg    XIMID        imid = buf_s[0];
7431ab64890Smrg    XICID        icid = buf_s[1];
7441ab64890Smrg    Xim		 im = (Xim)call_data;
7451ab64890Smrg    Xic		 ic;
7461ab64890Smrg
7471ab64890Smrg    if ((imid == im->private.proto.imid)
7481ab64890Smrg     && (ic = _XimICOfXICID(im, icid))) {
7491ab64890Smrg	(void)_XimCommitRecv(im, ic, (XPointer)&buf_s[2]);
7501ab64890Smrg	return True;
7511ab64890Smrg    }
7521ab64890Smrg    return False;
7531ab64890Smrg}
7541ab64890Smrg
755eb411b4bSmrgvoid
7561ab64890Smrg_XimProcError(
7571ab64890Smrg    Xim		 im,
7581ab64890Smrg    Xic		 ic,
7591ab64890Smrg    XPointer	 data)
7601ab64890Smrg{
7611ab64890Smrg    return;
7621ab64890Smrg}
7631ab64890Smrg
764eb411b4bSmrgBool
7651ab64890Smrg_XimErrorCallback(
7661ab64890Smrg    Xim		 xim,
7671ab64890Smrg    INT16	 len,
7681ab64890Smrg    XPointer	 data,
7691ab64890Smrg    XPointer	 call_data)
7701ab64890Smrg{
7711ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
7721ab64890Smrg    BITMASK16	 flag = buf_s[2];
7731ab64890Smrg    XIMID        imid;
7741ab64890Smrg    XICID        icid;
7751ab64890Smrg    Xim		 im = (Xim)call_data;
7761ab64890Smrg    Xic		 ic = NULL;
7771ab64890Smrg
7781ab64890Smrg    if (flag & XIM_IMID_VALID) {
7791ab64890Smrg	imid = buf_s[0];
7801ab64890Smrg	if (imid != im->private.proto.imid)
7811ab64890Smrg	    return False;
7821ab64890Smrg    }
7831ab64890Smrg    if (flag & XIM_ICID_VALID) {
7841ab64890Smrg	icid = buf_s[1];
7851ab64890Smrg	if (!(ic = _XimICOfXICID(im, icid)))
7861ab64890Smrg	    return False;
7871ab64890Smrg    }
7881ab64890Smrg    _XimProcError(im, ic, (XPointer)&buf_s[3]);
7891ab64890Smrg
7901ab64890Smrg    return True;
7911ab64890Smrg}
7921ab64890Smrg
793eb411b4bSmrgBool
7941ab64890Smrg_XimError(
7951ab64890Smrg    Xim		 im,
7961ab64890Smrg    Xic		 ic,
7971ab64890Smrg    CARD16	 error_code,
7981ab64890Smrg    INT16	 detail_length,
7991ab64890Smrg    CARD16	 type,
8001ab64890Smrg    char	*detail)
8011ab64890Smrg{
8021ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
8031ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
8041ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
8051ab64890Smrg    INT16	 len = 0;
8061ab64890Smrg
8071ab64890Smrg    buf_s[0] = im->private.proto.imid;	/* imid */
8081ab64890Smrg    buf_s[2] = XIM_IMID_VALID;		/* flag */
8091ab64890Smrg    if (ic) {
8101ab64890Smrg    	buf_s[1] = ic->private.proto.icid;	/* icid */
8111ab64890Smrg	buf_s[2] |= XIM_ICID_VALID;		/* flag */
8121ab64890Smrg    }
8131ab64890Smrg    buf_s[3] = error_code;			/* Error Code */
8141ab64890Smrg    buf_s[4] = detail_length;			/* length of error detail */
8151ab64890Smrg    buf_s[5] = type;				/* type of error detail */
8161ab64890Smrg
8171ab64890Smrg    if (detail_length && detail) {
8181ab64890Smrg	len = detail_length;
8191ab64890Smrg	memcpy((char *)&buf_s[6], detail, len);
8201ab64890Smrg	XIM_SET_PAD(&buf_s[6], len);
8211ab64890Smrg    }
8221ab64890Smrg
8231ab64890Smrg    len += sizeof(CARD16)		/* sizeof imid */
8241ab64890Smrg	 + sizeof(CARD16)		/* sizeof icid */
8251ab64890Smrg	 + sizeof(BITMASK16)		/* sizeof flag */
8261ab64890Smrg	 + sizeof(CARD16)		/* sizeof error_code */
8271ab64890Smrg	 + sizeof(INT16)		/* sizeof length of detail */
8281ab64890Smrg	 + sizeof(CARD16);		/* sizeof type */
8291ab64890Smrg
8301ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_ERROR, 0, &len);
8311ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
8321ab64890Smrg	return False;
8331ab64890Smrg    _XimFlush(im);
8341ab64890Smrg    return True;
8351ab64890Smrg}
8361ab64890Smrg
837eb411b4bSmrgstatic int
8381ab64890Smrg_Ximctsconvert(
8391ab64890Smrg    XlcConv	 conv,
8401ab64890Smrg    char	*from,
8411ab64890Smrg    int		 from_len,
8421ab64890Smrg    char	*to,
8431ab64890Smrg    int		 to_len,
8441ab64890Smrg    Status	*state)
8451ab64890Smrg{
8461ab64890Smrg    int		 from_left;
8471ab64890Smrg    int		 to_left;
8481ab64890Smrg    int		 from_savelen;
8491ab64890Smrg    int		 to_savelen;
8501ab64890Smrg    int		 from_cnvlen;
8511ab64890Smrg    int		 to_cnvlen;
8521ab64890Smrg    char	*from_buf;
8531ab64890Smrg    char	*to_buf;
8541ab64890Smrg    char	 scratchbuf[BUFSIZ];
8551ab64890Smrg    Status	 tmp_state;
8561ab64890Smrg
8571ab64890Smrg    if (!state)
8581ab64890Smrg	state = &tmp_state;
8591ab64890Smrg
8601ab64890Smrg    if (!conv || !from || !from_len) {
8611ab64890Smrg	*state = XLookupNone;
8621ab64890Smrg	return 0;
8631ab64890Smrg    }
8641ab64890Smrg
8651ab64890Smrg    /* Reset the converter.  The CompoundText at 'from' starts in
8661ab64890Smrg       initial state.  */
8671ab64890Smrg    _XlcResetConverter(conv);
8681ab64890Smrg
8691ab64890Smrg    from_left = from_len;
8701ab64890Smrg    to_left = BUFSIZ;
8711ab64890Smrg    from_cnvlen = 0;
8721ab64890Smrg    to_cnvlen = 0;
8731ab64890Smrg    for (;;) {
8741ab64890Smrg	from_buf = &from[from_cnvlen];
8751ab64890Smrg	from_savelen = from_left;
8761ab64890Smrg	to_buf = &scratchbuf[to_cnvlen];
8771ab64890Smrg	to_savelen = to_left;
8781ab64890Smrg	if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
8791ab64890Smrg				 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
8801ab64890Smrg	    *state = XLookupNone;
8811ab64890Smrg	    return 0;
8821ab64890Smrg	}
8831ab64890Smrg	from_cnvlen += (from_savelen - from_left);
8841ab64890Smrg	to_cnvlen += (to_savelen - to_left);
8851ab64890Smrg	if (from_left == 0) {
8861ab64890Smrg	    if (!to_cnvlen) {
8871ab64890Smrg		*state = XLookupNone;
8881ab64890Smrg		return 0;
8891ab64890Smrg           }
8901ab64890Smrg	   break;
8911ab64890Smrg	}
8921ab64890Smrg    }
8931ab64890Smrg
8941ab64890Smrg    if (!to || !to_len || (to_len < to_cnvlen)) {
8951ab64890Smrg       *state = XBufferOverflow;
8961ab64890Smrg    } else {
8971ab64890Smrg       memcpy(to, scratchbuf, to_cnvlen);
8981ab64890Smrg       *state = XLookupChars;
8991ab64890Smrg    }
9001ab64890Smrg    return to_cnvlen;
9011ab64890Smrg}
9021ab64890Smrg
903eb411b4bSmrgint
90461b2299dSmrg_Ximctstombs(XIM xim, char *from, int from_len,
90561b2299dSmrg	     char *to, int to_len, Status *state)
9061ab64890Smrg{
9071ab64890Smrg    return _Ximctsconvert(((Xim)xim)->private.proto.ctom_conv,
9081ab64890Smrg			  from, from_len, to, to_len, state);
9091ab64890Smrg}
9101ab64890Smrg
911eb411b4bSmrgint
9121ab64890Smrg_Ximctstowcs(
9131ab64890Smrg    XIM		 xim,
9141ab64890Smrg    char	*from,
9151ab64890Smrg    int		 from_len,
9161ab64890Smrg    wchar_t	*to,
9171ab64890Smrg    int		 to_len,
9181ab64890Smrg    Status	*state)
9191ab64890Smrg{
9201ab64890Smrg    Xim		 im = (Xim)xim;
9211ab64890Smrg    XlcConv	 conv = im->private.proto.ctow_conv;
9221ab64890Smrg    int		 from_left;
9231ab64890Smrg    int		 to_left;
9241ab64890Smrg    int		 from_savelen;
9251ab64890Smrg    int		 to_savelen;
9261ab64890Smrg    int		 from_cnvlen;
9271ab64890Smrg    int		 to_cnvlen;
9281ab64890Smrg    char	*from_buf;
9291ab64890Smrg    wchar_t	*to_buf;
9301ab64890Smrg    wchar_t	 scratchbuf[BUFSIZ];
9311ab64890Smrg    Status	 tmp_state;
9321ab64890Smrg
9331ab64890Smrg    if (!state)
9341ab64890Smrg	state = &tmp_state;
9351ab64890Smrg
9361ab64890Smrg    if (!conv || !from || !from_len) {
9371ab64890Smrg	*state = XLookupNone;
9381ab64890Smrg	return 0;
9391ab64890Smrg    }
9401ab64890Smrg
9411ab64890Smrg    /* Reset the converter.  The CompoundText at 'from' starts in
9421ab64890Smrg       initial state.  */
9431ab64890Smrg    _XlcResetConverter(conv);
94461b2299dSmrg
9451ab64890Smrg    from_left = from_len;
9461ab64890Smrg    to_left = BUFSIZ;
9471ab64890Smrg    from_cnvlen = 0;
9481ab64890Smrg    to_cnvlen = 0;
9491ab64890Smrg    for (;;) {
9501ab64890Smrg	from_buf = &from[from_cnvlen];
9511ab64890Smrg       from_savelen = from_left;
9521ab64890Smrg       to_buf = &scratchbuf[to_cnvlen];
9531ab64890Smrg       to_savelen = to_left;
9541ab64890Smrg	if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
9551ab64890Smrg				 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
9561ab64890Smrg	    *state = XLookupNone;
9571ab64890Smrg	    return 0;
9581ab64890Smrg	}
9591ab64890Smrg	from_cnvlen += (from_savelen - from_left);
9601ab64890Smrg       to_cnvlen += (to_savelen - to_left);
9611ab64890Smrg	if (from_left == 0) {
9621ab64890Smrg           if (!to_cnvlen){
9631ab64890Smrg		*state = XLookupNone;
9641ab64890Smrg               return 0;
9651ab64890Smrg           }
9661ab64890Smrg	    break;
9671ab64890Smrg	}
9681ab64890Smrg    }
9691ab64890Smrg
9701ab64890Smrg    if (!to || !to_len || (to_len < to_cnvlen)) {
9711ab64890Smrg       *state = XBufferOverflow;
9721ab64890Smrg    } else {
9731ab64890Smrg       memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t));
9741ab64890Smrg       *state = XLookupChars;
9751ab64890Smrg    }
9761ab64890Smrg    return to_cnvlen;
9771ab64890Smrg}
9781ab64890Smrg
979eb411b4bSmrgint
9801ab64890Smrg_Ximctstoutf8(
9811ab64890Smrg    XIM		 xim,
9821ab64890Smrg    char	*from,
9831ab64890Smrg    int		 from_len,
9841ab64890Smrg    char	*to,
9851ab64890Smrg    int		 to_len,
9861ab64890Smrg    Status	*state)
9871ab64890Smrg{
9881ab64890Smrg    return _Ximctsconvert(((Xim)xim)->private.proto.ctoutf8_conv,
9891ab64890Smrg			  from, from_len, to, to_len, state);
9901ab64890Smrg}
9911ab64890Smrg
992eb411b4bSmrgint
9931ab64890Smrg_XimProtoMbLookupString(
9941ab64890Smrg    XIC			 xic,
9951ab64890Smrg    XKeyEvent		*ev,
9961ab64890Smrg    char		*buffer,
9971ab64890Smrg    int			 bytes,
9981ab64890Smrg    KeySym		*keysym,
9991ab64890Smrg    Status		*state)
10001ab64890Smrg{
10011ab64890Smrg    Xic			 ic = (Xic)xic;
10021ab64890Smrg    Xim			 im = (Xim)ic->core.im;
10031ab64890Smrg    int			 ret;
10041ab64890Smrg    Status		 tmp_state;
10051ab64890Smrg    XimCommitInfo	 info;
10061ab64890Smrg
10071ab64890Smrg    if (!IS_SERVER_CONNECTED(im))
10081ab64890Smrg	return 0;
10091ab64890Smrg
10101ab64890Smrg    if (!state)
10111ab64890Smrg	state = &tmp_state;
10121ab64890Smrg
10131ab64890Smrg    if ((ev->type == KeyPress) && (ev->keycode == 0)) { /* Filter function */
10141ab64890Smrg	if (!(info = ic->private.proto.commit_info)) {
10151ab64890Smrg	    *state = XLookupNone;
10161ab64890Smrg	    return 0;
10171ab64890Smrg	}
10181ab64890Smrg
10191ab64890Smrg	ret = im->methods->ctstombs((XIM)im, info->string,
10201ab64890Smrg			 	info->string_len, buffer, bytes, state);
10211ab64890Smrg	if (*state == XBufferOverflow)
10221ab64890Smrg            return ret;
10231ab64890Smrg	if (keysym && (info->keysym && *(info->keysym))) {
10241ab64890Smrg	    *keysym = *(info->keysym);
10251ab64890Smrg	    if (*state == XLookupChars)
10261ab64890Smrg		*state = XLookupBoth;
10271ab64890Smrg	    else
10281ab64890Smrg		*state = XLookupKeySym;
10291ab64890Smrg	}
10301ab64890Smrg	_XimUnregCommitInfo(ic);
10311ab64890Smrg
10321ab64890Smrg    } else  if (ev->type == KeyPress) {
10331ab64890Smrg	ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL);
10341ab64890Smrg	if (ret > 0) {
10351ab64890Smrg           if (ret > bytes)
10361ab64890Smrg               *state = XBufferOverflow;
10371ab64890Smrg           else if (keysym && *keysym != NoSymbol)
10381ab64890Smrg		*state = XLookupBoth;
10391ab64890Smrg	    else
10401ab64890Smrg		*state = XLookupChars;
10411ab64890Smrg	} else {
10421ab64890Smrg	    if (keysym && *keysym != NoSymbol)
10431ab64890Smrg		*state = XLookupKeySym;
10441ab64890Smrg	    else
10451ab64890Smrg		*state = XLookupNone;
10461ab64890Smrg	}
10471ab64890Smrg    } else {
10481ab64890Smrg	*state = XLookupNone;
10491ab64890Smrg	ret = 0;
10501ab64890Smrg    }
10511ab64890Smrg
10521ab64890Smrg    return ret;
10531ab64890Smrg}
10541ab64890Smrg
1055eb411b4bSmrgint
10561ab64890Smrg_XimProtoWcLookupString(
10571ab64890Smrg    XIC			 xic,
10581ab64890Smrg    XKeyEvent		*ev,
10591ab64890Smrg    wchar_t		*buffer,
10601ab64890Smrg    int			 bytes,
10611ab64890Smrg    KeySym		*keysym,
10621ab64890Smrg    Status		*state)
10631ab64890Smrg{
10641ab64890Smrg    Xic			 ic = (Xic)xic;
10651ab64890Smrg    Xim			 im = (Xim)ic->core.im;
10661ab64890Smrg    int			 ret;
10671ab64890Smrg    Status		 tmp_state;
10681ab64890Smrg    XimCommitInfo	 info;
10691ab64890Smrg
10701ab64890Smrg    if (!IS_SERVER_CONNECTED(im))
10711ab64890Smrg	return 0;
10721ab64890Smrg
10731ab64890Smrg    if (!state)
10741ab64890Smrg	state = &tmp_state;
10751ab64890Smrg
10761ab64890Smrg    if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */
10771ab64890Smrg	if (!(info = ic->private.proto.commit_info)) {
10781ab64890Smrg           *state = XLookupNone;
10791ab64890Smrg	    return 0;
10801ab64890Smrg	}
10811ab64890Smrg
10821ab64890Smrg	ret = im->methods->ctstowcs((XIM)im, info->string,
10831ab64890Smrg			 	info->string_len, buffer, bytes, state);
10841ab64890Smrg	if (*state == XBufferOverflow)
10851ab64890Smrg           return ret;
10861ab64890Smrg	if (keysym && (info->keysym && *(info->keysym))) {
10871ab64890Smrg	    *keysym = *(info->keysym);
10881ab64890Smrg	    if (*state == XLookupChars)
10891ab64890Smrg		*state = XLookupBoth;
10901ab64890Smrg	    else
10911ab64890Smrg		*state = XLookupKeySym;
10921ab64890Smrg	}
10931ab64890Smrg	_XimUnregCommitInfo(ic);
10941ab64890Smrg
10951ab64890Smrg    } else if (ev->type == KeyPress) {
10961ab64890Smrg	ret = _XimLookupWCText(ic, ev, buffer, bytes, keysym, NULL);
10971ab64890Smrg	if (ret > 0) {
10981ab64890Smrg           if (ret > bytes)
10991ab64890Smrg               *state = XBufferOverflow;
11001ab64890Smrg           else if (keysym && *keysym != NoSymbol)
11011ab64890Smrg		*state = XLookupBoth;
11021ab64890Smrg	    else
11031ab64890Smrg		*state = XLookupChars;
11041ab64890Smrg	} else {
11051ab64890Smrg	    if (keysym && *keysym != NoSymbol)
11061ab64890Smrg		*state = XLookupKeySym;
11071ab64890Smrg	    else
11081ab64890Smrg		*state = XLookupNone;
11091ab64890Smrg	}
11101ab64890Smrg    } else {
11111ab64890Smrg	*state = XLookupNone;
11121ab64890Smrg	ret = 0;
11131ab64890Smrg    }
11141ab64890Smrg
11151ab64890Smrg    return ret;
11161ab64890Smrg}
11171ab64890Smrg
1118eb411b4bSmrgint
11191ab64890Smrg_XimProtoUtf8LookupString(
11201ab64890Smrg    XIC			 xic,
11211ab64890Smrg    XKeyEvent		*ev,
11221ab64890Smrg    char		*buffer,
11231ab64890Smrg    int			 bytes,
11241ab64890Smrg    KeySym		*keysym,
11251ab64890Smrg    Status		*state)
11261ab64890Smrg{
11271ab64890Smrg    Xic			 ic = (Xic)xic;
11281ab64890Smrg    Xim			 im = (Xim)ic->core.im;
11291ab64890Smrg    int			 ret;
11301ab64890Smrg    Status		 tmp_state;
11311ab64890Smrg    XimCommitInfo	 info;
11321ab64890Smrg
11331ab64890Smrg    if (!IS_SERVER_CONNECTED(im))
11341ab64890Smrg	return 0;
11351ab64890Smrg
11361ab64890Smrg    if (!state)
11371ab64890Smrg	state = &tmp_state;
11381ab64890Smrg
11391ab64890Smrg    if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */
11401ab64890Smrg	if (!(info = ic->private.proto.commit_info)) {
11411ab64890Smrg           *state = XLookupNone;
11421ab64890Smrg	    return 0;
11431ab64890Smrg	}
11441ab64890Smrg
11451ab64890Smrg	ret = im->methods->ctstoutf8((XIM)im, info->string,
11461ab64890Smrg			 	info->string_len, buffer, bytes, state);
11471ab64890Smrg	if (*state == XBufferOverflow)
11481ab64890Smrg           return ret;
11491ab64890Smrg	if (keysym && (info->keysym && *(info->keysym))) {
11501ab64890Smrg	    *keysym = *(info->keysym);
11511ab64890Smrg	    if (*state == XLookupChars)
11521ab64890Smrg		*state = XLookupBoth;
11531ab64890Smrg	    else
11541ab64890Smrg		*state = XLookupKeySym;
11551ab64890Smrg	}
11561ab64890Smrg	_XimUnregCommitInfo(ic);
11571ab64890Smrg
11581ab64890Smrg    } else if (ev->type == KeyPress) {
11591ab64890Smrg	ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL);
11601ab64890Smrg	if (ret > 0) {
11611ab64890Smrg           if (ret > bytes)
11621ab64890Smrg               *state = XBufferOverflow;
11631ab64890Smrg           else if (keysym && *keysym != NoSymbol)
11641ab64890Smrg		*state = XLookupBoth;
11651ab64890Smrg	    else
11661ab64890Smrg		*state = XLookupChars;
11671ab64890Smrg	} else {
11681ab64890Smrg	    if (keysym && *keysym != NoSymbol)
11691ab64890Smrg		*state = XLookupKeySym;
11701ab64890Smrg	    else
11711ab64890Smrg		*state = XLookupNone;
11721ab64890Smrg	}
11731ab64890Smrg    } else {
11741ab64890Smrg	*state = XLookupNone;
11751ab64890Smrg	ret = 0;
11761ab64890Smrg    }
11771ab64890Smrg
11781ab64890Smrg    return ret;
11791ab64890Smrg}
1180