imDefLkup.c revision 0f8248bf
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) {
911ab64890Smrg	    ic = _XimICOfXICID(im, icid);
921ab64890Smrg	    _XimProcICSetEventMask(ic, (XPointer)&buf_s[2]);
931ab64890Smrg	} else {
941ab64890Smrg	    _XimProcIMSetEventMask(im, (XPointer)&buf_s[2]);
951ab64890Smrg	}
961ab64890Smrg	return True;
971ab64890Smrg    }
981ab64890Smrg    return False;
991ab64890Smrg}
1001ab64890Smrg
101eb411b4bSmrgstatic Bool
1021ab64890Smrg_XimSyncCheck(
1031ab64890Smrg    Xim          im,
1041ab64890Smrg    INT16        len,
1051ab64890Smrg    XPointer	 data,
1061ab64890Smrg    XPointer     arg)
1071ab64890Smrg{
1081ab64890Smrg    Xic		 ic  = (Xic)arg;
1091ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
1101ab64890Smrg    CARD8	 major_opcode = *((CARD8 *)data);
1111ab64890Smrg    CARD8	 minor_opcode = *((CARD8 *)data + 1);
1121ab64890Smrg    XIMID	 imid = buf_s[0];
1131ab64890Smrg    XICID	 icid = buf_s[1];
1141ab64890Smrg
1151ab64890Smrg    if ((major_opcode == XIM_SYNC_REPLY)
1161ab64890Smrg     && (minor_opcode == 0)
1171ab64890Smrg     && (imid == im->private.proto.imid)
1181ab64890Smrg     && (icid == ic->private.proto.icid))
1191ab64890Smrg	return True;
1201ab64890Smrg    if ((major_opcode == XIM_ERROR)
1211ab64890Smrg     && (minor_opcode == 0)
1221ab64890Smrg     && (buf_s[2] & XIM_IMID_VALID)
1231ab64890Smrg     && (imid == im->private.proto.imid)
1241ab64890Smrg     && (buf_s[2] & XIM_ICID_VALID)
1251ab64890Smrg     && (icid == ic->private.proto.icid))
1261ab64890Smrg	return True;
1271ab64890Smrg    return False;
1281ab64890Smrg}
1291ab64890Smrg
130eb411b4bSmrgBool
1311ab64890Smrg_XimSync(
1321ab64890Smrg    Xim		 im,
1331ab64890Smrg    Xic		 ic)
1341ab64890Smrg{
1351ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
1361ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
1371ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
1381ab64890Smrg    INT16	 len;
1391ab64890Smrg    CARD32	 reply32[BUFSIZE/4];
1401ab64890Smrg    char	*reply = (char *)reply32;
1411ab64890Smrg    XPointer	 preply;
1421ab64890Smrg    int		 buf_size;
1431ab64890Smrg    int		 ret_code;
1441ab64890Smrg
1451ab64890Smrg    buf_s[0] = im->private.proto.imid;		/* imid */
1461ab64890Smrg    buf_s[1] = ic->private.proto.icid;		/* icid */
1471ab64890Smrg
1481ab64890Smrg    len = sizeof(CARD16)			/* sizeof imid */
1491ab64890Smrg	+ sizeof(CARD16);			/* sizeof icid */
1501ab64890Smrg
1511ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_SYNC, 0, &len);
1521ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
1531ab64890Smrg	return False;
1541ab64890Smrg    _XimFlush(im);
1551ab64890Smrg    buf_size = BUFSIZE;
1561ab64890Smrg    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
1571ab64890Smrg					_XimSyncCheck, (XPointer)ic);
1581ab64890Smrg    if(ret_code == XIM_TRUE) {
1591ab64890Smrg	preply = reply;
1601ab64890Smrg    } else if(ret_code == XIM_OVERFLOW) {
1611ab64890Smrg	if(len <= 0) {
1621ab64890Smrg	    preply = reply;
1631ab64890Smrg	} else {
1641ab64890Smrg	    buf_size = len;
165818534a1Smrg	    preply = Xmalloc(len);
1661ab64890Smrg	    ret_code = _XimRead(im, &len, preply, buf_size,
1671ab64890Smrg					_XimSyncCheck, (XPointer)ic);
1681ab64890Smrg	    if(ret_code != XIM_TRUE) {
1691ab64890Smrg		Xfree(preply);
1701ab64890Smrg		return False;
1711ab64890Smrg	    }
1721ab64890Smrg	}
1731ab64890Smrg    } else {
1741ab64890Smrg	return False;
1751ab64890Smrg    }
1761ab64890Smrg    buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
1771ab64890Smrg    if (*((CARD8 *)preply) == XIM_ERROR) {
1781ab64890Smrg	_XimProcError(im, 0, (XPointer)&buf_s[3]);
1791ab64890Smrg	if(reply != preply)
1801ab64890Smrg	    Xfree(preply);
1811ab64890Smrg	return False;
1821ab64890Smrg    }
1831ab64890Smrg    if(reply != preply)
1841ab64890Smrg	Xfree(preply);
1851ab64890Smrg    return True;
1861ab64890Smrg}
1871ab64890Smrg
188eb411b4bSmrgBool
1891ab64890Smrg_XimProcSyncReply(
1901ab64890Smrg    Xim		 im,
1911ab64890Smrg    Xic		 ic)
1921ab64890Smrg{
1931ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
1941ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
1951ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
1961ab64890Smrg    INT16	 len;
1971ab64890Smrg
1981ab64890Smrg    buf_s[0] = im->private.proto.imid;		/* imid */
1991ab64890Smrg    buf_s[1] = ic->private.proto.icid;		/* icid */
2001ab64890Smrg
2011ab64890Smrg    len = sizeof(CARD16)			/* sizeof imid */
2021ab64890Smrg	+ sizeof(CARD16);			/* sizeof icid */
2031ab64890Smrg
2041ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_SYNC_REPLY, 0, &len);
2051ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
2061ab64890Smrg	return False;
2071ab64890Smrg    _XimFlush(im);
2081ab64890Smrg    return True;
2091ab64890Smrg}
2101ab64890Smrg
211eb411b4bSmrgBool
2121ab64890Smrg_XimRespSyncReply(
2131ab64890Smrg    Xic		 ic,
2141ab64890Smrg    BITMASK16	 mode)
2151ab64890Smrg{
216eb411b4bSmrg    if (mode & XimSYNCHRONUS) /* SYNC Request */
217eb411b4bSmrg	MARK_NEED_SYNC_REPLY(ic->core.im);
21861b2299dSmrg
2191ab64890Smrg    return True;
2201ab64890Smrg}
2211ab64890Smrg
222eb411b4bSmrgBool
2231ab64890Smrg_XimSyncCallback(
2241ab64890Smrg    Xim		 xim,
2251ab64890Smrg    INT16	 len,
2261ab64890Smrg    XPointer	 data,
2271ab64890Smrg    XPointer	 call_data)
2281ab64890Smrg{
2291ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
2301ab64890Smrg    XIMID        imid = buf_s[0];
2311ab64890Smrg    XICID        icid = buf_s[1];
2321ab64890Smrg    Xim		 im = (Xim)call_data;
2331ab64890Smrg    Xic		 ic;
2341ab64890Smrg
2351ab64890Smrg    if ((imid == im->private.proto.imid)
2361ab64890Smrg     && (ic = _XimICOfXICID(im, icid))) {
2371ab64890Smrg	(void)_XimProcSyncReply(im, ic);
2381ab64890Smrg	return True;
2391ab64890Smrg    }
2401ab64890Smrg    return False;
2411ab64890Smrg}
2421ab64890Smrg
243eb411b4bSmrgstatic INT16
2441ab64890Smrg_XimSetEventToWire(
2451ab64890Smrg    XEvent	*ev,
2461ab64890Smrg    xEvent	*event)
2471ab64890Smrg{
2481ab64890Smrg    if (!(_XimProtoEventToWire(ev, event, False)))
2491ab64890Smrg	return 0;
2501ab64890Smrg    event->u.u.sequenceNumber =
2511ab64890Smrg		((XAnyEvent *)ev)->serial & (unsigned long)0xffff;
2521ab64890Smrg    return sz_xEvent;
2531ab64890Smrg}
2541ab64890Smrg
255eb411b4bSmrgstatic Bool
2561ab64890Smrg_XimForwardEventCore(
2571ab64890Smrg    Xic		 ic,
2581ab64890Smrg    XEvent	*ev,
2591ab64890Smrg    Bool	 sync)
2601ab64890Smrg{
2611ab64890Smrg    Xim		 im = (Xim)ic->core.im;
2621ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
2631ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
2641ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
2651ab64890Smrg    CARD32	 reply32[BUFSIZE/4];
2661ab64890Smrg    char	*reply = (char *)reply32;
2671ab64890Smrg    XPointer	 preply;
2681ab64890Smrg    int		 buf_size;
2691ab64890Smrg    int		 ret_code;
2701ab64890Smrg    INT16	 len;
2711ab64890Smrg
272818534a1Smrg    bzero(buf32, sizeof(buf32)); /* valgrind noticed uninitialized memory use! */
273818534a1Smrg
2741ab64890Smrg    if (!(len = _XimSetEventToWire(ev, (xEvent *)&buf_s[4])))
2751ab64890Smrg	return False;				/* X event */
2761ab64890Smrg
2771ab64890Smrg    buf_s[0] = im->private.proto.imid;		/* imid */
2781ab64890Smrg    buf_s[1] = ic->private.proto.icid;		/* icid */
2791ab64890Smrg    buf_s[2] = sync ? XimSYNCHRONUS : 0;	/* flag */
2801ab64890Smrg    buf_s[3] =
2811ab64890Smrg        (CARD16)((((XAnyEvent *)ev)->serial & ~((unsigned long)0xffff)) >> 16);
2821ab64890Smrg						/* serial number */
2831ab64890Smrg
2841ab64890Smrg    len += sizeof(CARD16)			/* sizeof imid */
2851ab64890Smrg	 + sizeof(CARD16)			/* sizeof icid */
2861ab64890Smrg	 + sizeof(BITMASK16)			/* sizeof flag */
2871ab64890Smrg	 + sizeof(CARD16);			/* sizeof serila number */
2881ab64890Smrg
2891ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_FORWARD_EVENT, 0, &len);
2901ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
2911ab64890Smrg	return False;
2921ab64890Smrg    _XimFlush(im);
2931ab64890Smrg
2941ab64890Smrg    if (sync) {
2951ab64890Smrg	buf_size = BUFSIZE;
2961ab64890Smrg	ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
2971ab64890Smrg					_XimSyncCheck, (XPointer)ic);
2981ab64890Smrg	if(ret_code == XIM_TRUE) {
2991ab64890Smrg	    preply = reply;
3001ab64890Smrg	} else if(ret_code == XIM_OVERFLOW) {
3011ab64890Smrg	    if(len <= 0) {
3021ab64890Smrg		preply = reply;
3031ab64890Smrg	    } else {
3041ab64890Smrg		buf_size = len;
305818534a1Smrg		preply = Xmalloc(len);
3061ab64890Smrg		ret_code = _XimRead(im, &len, preply, buf_size,
3071ab64890Smrg					_XimSyncCheck, (XPointer)ic);
3081ab64890Smrg		if(ret_code != XIM_TRUE) {
3091ab64890Smrg		    Xfree(preply);
3101ab64890Smrg		    return False;
3111ab64890Smrg		}
3121ab64890Smrg	    }
3131ab64890Smrg	} else {
3141ab64890Smrg	    return False;
3151ab64890Smrg	}
3161ab64890Smrg	buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
3171ab64890Smrg	if (*((CARD8 *)preply) == XIM_ERROR) {
3181ab64890Smrg	    _XimProcError(im, 0, (XPointer)&buf_s[3]);
3191ab64890Smrg	    if(reply != preply)
3201ab64890Smrg		Xfree(preply);
3211ab64890Smrg	    return False;
3221ab64890Smrg	}
3231ab64890Smrg	if(reply != preply)
3241ab64890Smrg	    Xfree(preply);
3251ab64890Smrg    }
3261ab64890Smrg    return True;
3271ab64890Smrg}
3281ab64890Smrg
329eb411b4bSmrgBool
3301ab64890Smrg_XimForwardEvent(
3311ab64890Smrg    Xic		 ic,
3321ab64890Smrg    XEvent	*ev,
3331ab64890Smrg    Bool	 sync)
3341ab64890Smrg{
3351ab64890Smrg#ifdef EXT_FORWARD
3361ab64890Smrg    if (((ev->type == KeyPress) || (ev->type == KeyRelease)))
3371ab64890Smrg	if (_XimExtForwardKeyEvent(ic, (XKeyEvent *)ev, sync))
3381ab64890Smrg	    return True;
3391ab64890Smrg#endif
3401ab64890Smrg    return _XimForwardEventCore(ic, ev, sync);
3411ab64890Smrg}
3421ab64890Smrg
343eb411b4bSmrgstatic void
3441ab64890Smrg_XimProcEvent(
3451ab64890Smrg    Display		*d,
3461ab64890Smrg    Xic			 ic,
3471ab64890Smrg    XEvent		*ev,
3481ab64890Smrg    CARD16		*buf)
3491ab64890Smrg{
3501ab64890Smrg    INT16	 serial = buf[0];
3511ab64890Smrg    xEvent	*xev = (xEvent *)&buf[1];
3521ab64890Smrg
3531ab64890Smrg    _XimProtoWireToEvent(ev, xev, False);
3541ab64890Smrg    ev->xany.serial |= serial << 16;
3551ab64890Smrg    ev->xany.send_event = False;
3561ab64890Smrg    ev->xany.display = d;
357eb411b4bSmrg    MARK_FABRICATED(ic->core.im);
3581ab64890Smrg    return;
3591ab64890Smrg}
3601ab64890Smrg
361eb411b4bSmrgstatic Bool
3621ab64890Smrg_XimForwardEventRecv(
3631ab64890Smrg    Xim		 im,
3641ab64890Smrg    Xic		 ic,
3651ab64890Smrg    XPointer	 buf)
3661ab64890Smrg{
3671ab64890Smrg    CARD16	*buf_s = (CARD16 *)buf;
3681ab64890Smrg    Display	*d = im->core.display;
3691ab64890Smrg    XEvent	 ev;
3701ab64890Smrg
3711ab64890Smrg    _XimProcEvent(d, ic, &ev, &buf_s[1]);
3721ab64890Smrg
3731ab64890Smrg    (void)_XimRespSyncReply(ic, buf_s[0]);
3741ab64890Smrg
3751ab64890Smrg    XPutBackEvent(d, &ev);
3761ab64890Smrg
3771ab64890Smrg    return True;
3781ab64890Smrg}
3791ab64890Smrg
380eb411b4bSmrgBool
3811ab64890Smrg_XimForwardEventCallback(
3821ab64890Smrg    Xim		 xim,
3831ab64890Smrg    INT16	 len,
3841ab64890Smrg    XPointer	 data,
3851ab64890Smrg    XPointer	 call_data)
3861ab64890Smrg{
3871ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
3881ab64890Smrg    XIMID        imid = buf_s[0];
3891ab64890Smrg    XICID        icid = buf_s[1];
3901ab64890Smrg    Xim		 im = (Xim)call_data;
3911ab64890Smrg    Xic		 ic;
3921ab64890Smrg
3931ab64890Smrg    if ((imid == im->private.proto.imid)
3941ab64890Smrg     && (ic = _XimICOfXICID(im, icid))) {
3951ab64890Smrg	(void)_XimForwardEventRecv(im, ic, (XPointer)&buf_s[2]);
3961ab64890Smrg	return True;
3971ab64890Smrg    }
3981ab64890Smrg    return False;
3991ab64890Smrg}
4001ab64890Smrg
401eb411b4bSmrgstatic Bool
4021ab64890Smrg_XimRegisterTriggerkey(
4031ab64890Smrg    Xim			 im,
4041ab64890Smrg    XPointer		 buf)
4051ab64890Smrg{
4061ab64890Smrg    CARD32		*buf_l = (CARD32 *)buf;
4071ab64890Smrg    CARD32		 len;
4081ab64890Smrg    CARD32 		*key;
4091ab64890Smrg
4101ab64890Smrg    if (IS_DYNAMIC_EVENT_FLOW(im))	/* already Dynamic event flow mode */
4111ab64890Smrg	return True;
4121ab64890Smrg
4131ab64890Smrg    /*
4141ab64890Smrg     *  register onkeylist
4151ab64890Smrg     */
4161ab64890Smrg
4171ab64890Smrg    len = buf_l[0];				/* length of on-keys */
4181ab64890Smrg    len += sizeof(INT32);			/* sizeof length of on-keys */
4191ab64890Smrg
420818534a1Smrg    if (!(key = Xmalloc(len))) {
4211ab64890Smrg	_XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
4221ab64890Smrg	return False;
4231ab64890Smrg    }
4241ab64890Smrg    memcpy((char *)key, (char *)buf_l, len);
4251ab64890Smrg    im->private.proto.im_onkeylist = key;
4261ab64890Smrg
4271ab64890Smrg    MARK_DYNAMIC_EVENT_FLOW(im);
4281ab64890Smrg
4291ab64890Smrg    /*
4301ab64890Smrg     *  register offkeylist
4311ab64890Smrg     */
4321ab64890Smrg
4331ab64890Smrg    buf_l = (CARD32 *)((char *)buf + len);
4341ab64890Smrg    len = buf_l[0];				/* length of off-keys */
4351ab64890Smrg    len += sizeof(INT32);			/* sizeof length of off-keys */
4361ab64890Smrg
437818534a1Smrg    if (!(key = Xmalloc(len))) {
4381ab64890Smrg	_XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
4391ab64890Smrg	return False;
4401ab64890Smrg    }
4411ab64890Smrg
4421ab64890Smrg    memcpy((char *)key, (char *)buf_l, len);
4431ab64890Smrg    im->private.proto.im_offkeylist = key;
4441ab64890Smrg
4451ab64890Smrg    return True;
4461ab64890Smrg}
4471ab64890Smrg
448eb411b4bSmrgBool
4491ab64890Smrg_XimRegisterTriggerKeysCallback(
4501ab64890Smrg    Xim		 xim,
4511ab64890Smrg    INT16	 len,
4521ab64890Smrg    XPointer	 data,
4531ab64890Smrg    XPointer	 call_data)
4541ab64890Smrg{
4551ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
4561ab64890Smrg    Xim		 im = (Xim)call_data;
4571ab64890Smrg
4581ab64890Smrg    (void )_XimRegisterTriggerkey(im, (XPointer)&buf_s[2]);
4591ab64890Smrg    return True;
4601ab64890Smrg}
4611ab64890Smrg
462eb411b4bSmrgEVENTMASK
4631ab64890Smrg_XimGetWindowEventmask(
4641ab64890Smrg    Xic		 ic)
4651ab64890Smrg{
4661ab64890Smrg    Xim			im = (Xim )ic->core.im;
4671ab64890Smrg    XWindowAttributes	atr;
4681ab64890Smrg
4691ab64890Smrg    if (!XGetWindowAttributes(im->core.display, ic->core.focus_window, &atr))
4701ab64890Smrg	return 0;
4711ab64890Smrg    return (EVENTMASK)atr.your_event_mask;
4721ab64890Smrg}
4731ab64890Smrg
4741ab64890Smrg
475eb411b4bSmrgstatic Bool
4761ab64890Smrg_XimTriggerNotifyCheck(
4771ab64890Smrg    Xim          im,
4781ab64890Smrg    INT16        len,
4791ab64890Smrg    XPointer	 data,
4801ab64890Smrg    XPointer     arg)
4811ab64890Smrg{
4821ab64890Smrg    Xic		 ic  = (Xic)arg;
4831ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
4841ab64890Smrg    CARD8	 major_opcode = *((CARD8 *)data);
4851ab64890Smrg    CARD8	 minor_opcode = *((CARD8 *)data + 1);
4861ab64890Smrg    XIMID	 imid = buf_s[0];
4871ab64890Smrg    XICID	 icid = buf_s[1];
4881ab64890Smrg
4891ab64890Smrg    if ((major_opcode == XIM_TRIGGER_NOTIFY_REPLY)
4901ab64890Smrg     && (minor_opcode == 0)
4911ab64890Smrg     && (imid == im->private.proto.imid)
4921ab64890Smrg     && (icid == ic->private.proto.icid))
4931ab64890Smrg	return True;
4941ab64890Smrg    if ((major_opcode == XIM_ERROR)
4951ab64890Smrg     && (minor_opcode == 0)
4961ab64890Smrg     && (buf_s[2] & XIM_IMID_VALID)
4971ab64890Smrg     && (imid == im->private.proto.imid)
4981ab64890Smrg     && (buf_s[2] & XIM_ICID_VALID)
4991ab64890Smrg     && (icid == ic->private.proto.icid))
5001ab64890Smrg	return True;
5011ab64890Smrg    return False;
5021ab64890Smrg}
5031ab64890Smrg
504eb411b4bSmrgBool
5051ab64890Smrg_XimTriggerNotify(
5061ab64890Smrg    Xim		 im,
5071ab64890Smrg    Xic		 ic,
5081ab64890Smrg    int		 mode,
5091ab64890Smrg    CARD32	 idx)
5101ab64890Smrg{
5111ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
5121ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
5131ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
5141ab64890Smrg    CARD32	*buf_l = (CARD32 *)&buf[XIM_HEADER_SIZE];
5151ab64890Smrg    CARD32	 reply32[BUFSIZE/4];
5161ab64890Smrg    char	*reply = (char *)reply32;
5171ab64890Smrg    XPointer	 preply;
5181ab64890Smrg    int		 buf_size;
5191ab64890Smrg    int		 ret_code;
5201ab64890Smrg    INT16	 len;
5211ab64890Smrg    EVENTMASK	 mask = _XimGetWindowEventmask(ic);
5221ab64890Smrg
5231ab64890Smrg    buf_s[0] = im->private.proto.imid;	/* imid */
5241ab64890Smrg    buf_s[1] = ic->private.proto.icid;	/* icid */
5251ab64890Smrg    buf_l[1] = mode;			/* flag */
5261ab64890Smrg    buf_l[2] = idx;			/* index of keys list */
5271ab64890Smrg    buf_l[3] = mask;			/* select-event-mask */
5281ab64890Smrg
5291ab64890Smrg    len = sizeof(CARD16)		/* sizeof imid */
5301ab64890Smrg	+ sizeof(CARD16)		/* sizeof icid */
5311ab64890Smrg	+ sizeof(CARD32)		/* sizeof flag */
5321ab64890Smrg	+ sizeof(CARD32)		/* sizeof index of key list */
5331ab64890Smrg	+ sizeof(EVENTMASK);		/* sizeof select-event-mask */
5341ab64890Smrg
5351ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_TRIGGER_NOTIFY, 0, &len);
5361ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
5371ab64890Smrg	return False;
5381ab64890Smrg    _XimFlush(im);
5391ab64890Smrg    buf_size = BUFSIZE;
5401ab64890Smrg    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
5411ab64890Smrg				_XimTriggerNotifyCheck, (XPointer)ic);
5421ab64890Smrg    if(ret_code == XIM_TRUE) {
5431ab64890Smrg	preply = reply;
5441ab64890Smrg    } else if(ret_code == XIM_OVERFLOW) {
5451ab64890Smrg	if(len <= 0) {
5461ab64890Smrg	    preply = reply;
5471ab64890Smrg	} else {
5481ab64890Smrg	    buf_size = len;
549818534a1Smrg	    preply = Xmalloc(len);
5501ab64890Smrg	    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
5511ab64890Smrg				_XimTriggerNotifyCheck, (XPointer)ic);
5521ab64890Smrg	    if(ret_code != XIM_TRUE) {
5531ab64890Smrg		Xfree(preply);
5541ab64890Smrg		return False;
5551ab64890Smrg	    }
5561ab64890Smrg	}
5571ab64890Smrg    } else {
5581ab64890Smrg	return False;
5591ab64890Smrg    }
5601ab64890Smrg    buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
5611ab64890Smrg    if (*((CARD8 *)preply) == XIM_ERROR) {
5621ab64890Smrg	_XimProcError(im, 0, (XPointer)&buf_s[3]);
5631ab64890Smrg	if(reply != preply)
5641ab64890Smrg	    Xfree(preply);
5651ab64890Smrg	return False;
5661ab64890Smrg    }
5671ab64890Smrg    if(reply != preply)
5681ab64890Smrg	Xfree(preply);
5691ab64890Smrg    return True;
5701ab64890Smrg}
5711ab64890Smrg
572eb411b4bSmrgstatic Bool
5731ab64890Smrg_XimRegCommitInfo(
5741ab64890Smrg    Xic			 ic,
5751ab64890Smrg    char		*string,
5761ab64890Smrg    int			 string_len,
5771ab64890Smrg    KeySym		*keysym,
5781ab64890Smrg    int			 keysym_len)
5791ab64890Smrg{
5801ab64890Smrg    XimCommitInfo	info;
5811ab64890Smrg
582818534a1Smrg    if (!(info = Xmalloc(sizeof(XimCommitInfoRec))))
5831ab64890Smrg	return False;
5841ab64890Smrg    info->string	= string;
5851ab64890Smrg    info->string_len	= string_len;
5861ab64890Smrg    info->keysym	= keysym;
5871ab64890Smrg    info->keysym_len	= keysym_len;
5881ab64890Smrg    info->next = ic->private.proto.commit_info;
5891ab64890Smrg    ic->private.proto.commit_info = info;
5901ab64890Smrg    return True;
5911ab64890Smrg}
5921ab64890Smrg
593eb411b4bSmrgstatic void
5941ab64890Smrg_XimUnregCommitInfo(
5951ab64890Smrg    Xic			ic)
5961ab64890Smrg{
5971ab64890Smrg    XimCommitInfo	info;
5981ab64890Smrg
5991ab64890Smrg    if (!(info = ic->private.proto.commit_info))
6001ab64890Smrg	return;
6011ab64890Smrg
6020f8248bfSmrg
6030f8248bfSmrg    Xfree(info->string);
6040f8248bfSmrg    Xfree(info->keysym);
6051ab64890Smrg    ic->private.proto.commit_info = info->next;
6061ab64890Smrg    Xfree(info);
6071ab64890Smrg    return;
6081ab64890Smrg}
6091ab64890Smrg
610eb411b4bSmrgvoid
6111ab64890Smrg_XimFreeCommitInfo(
6121ab64890Smrg    Xic			ic)
6131ab64890Smrg{
6141ab64890Smrg    while (ic->private.proto.commit_info)
6151ab64890Smrg	_XimUnregCommitInfo(ic);
6161ab64890Smrg    return;
6171ab64890Smrg}
6181ab64890Smrg
619eb411b4bSmrgstatic Bool
6201ab64890Smrg_XimProcKeySym(
6211ab64890Smrg    Xic			  ic,
6221ab64890Smrg    CARD32		  sym,
6231ab64890Smrg    KeySym		**xim_keysym,
6241ab64890Smrg    int			 *xim_keysym_len)
6251ab64890Smrg{
6261ab64890Smrg    Xim			 im = (Xim)ic->core.im;
6271ab64890Smrg
628818534a1Smrg    if (!(*xim_keysym = Xmalloc(sizeof(KeySym)))) {
6291ab64890Smrg	_XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
6301ab64890Smrg	return False;
6311ab64890Smrg    }
6321ab64890Smrg
6331ab64890Smrg    **xim_keysym = (KeySym)sym;
6341ab64890Smrg    *xim_keysym_len = 1;
6351ab64890Smrg
6361ab64890Smrg    return True;
6371ab64890Smrg}
6381ab64890Smrg
639eb411b4bSmrgstatic Bool
6401ab64890Smrg_XimProcCommit(
6411ab64890Smrg    Xic		  ic,
6421ab64890Smrg    BYTE	 *buf,
6431ab64890Smrg    int		  len,
6441ab64890Smrg    char	**xim_string,
6451ab64890Smrg    int		 *xim_string_len)
6461ab64890Smrg{
6471ab64890Smrg    Xim		 im = (Xim)ic->core.im;
6481ab64890Smrg    char	*string;
6491ab64890Smrg
650818534a1Smrg    if (!(string = Xmalloc(len + 1))) {
6511ab64890Smrg	_XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
6521ab64890Smrg	return False;
6531ab64890Smrg    }
6541ab64890Smrg
6551ab64890Smrg    (void)memcpy(string, (char *)buf, len);
6561ab64890Smrg    string[len] = '\0';
6571ab64890Smrg
6581ab64890Smrg    *xim_string = string;
6591ab64890Smrg    *xim_string_len = len;
6601ab64890Smrg    return True;
6611ab64890Smrg}
6621ab64890Smrg
663eb411b4bSmrgstatic Bool
6641ab64890Smrg_XimCommitRecv(
6651ab64890Smrg    Xim		 im,
6661ab64890Smrg    Xic		 ic,
6671ab64890Smrg    XPointer	 buf)
6681ab64890Smrg{
6691ab64890Smrg    CARD16	*buf_s = (CARD16 *)buf;
6701ab64890Smrg    BITMASK16	 flag = buf_s[0];
6711ab64890Smrg    XKeyEvent	 ev;
6721ab64890Smrg    char	*string = NULL;
6731ab64890Smrg    int		 string_len = 0;
6741ab64890Smrg    KeySym	*keysym = NULL;
6751ab64890Smrg    int		 keysym_len = 0;
6761ab64890Smrg
6771ab64890Smrg    if ((flag & XimLookupBoth) == XimLookupChars) {
6781ab64890Smrg	if (!(_XimProcCommit(ic, (BYTE *)&buf_s[2],
6791ab64890Smrg			 		(int)buf_s[1], &string, &string_len)))
6801ab64890Smrg	    return False;
6811ab64890Smrg
6821ab64890Smrg    } else if ((flag & XimLookupBoth) == XimLookupKeySym) {
6831ab64890Smrg	if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len)))
6841ab64890Smrg	    return False;
6851ab64890Smrg
6861ab64890Smrg    } else if ((flag & XimLookupBoth) == XimLookupBoth) {
6871ab64890Smrg	if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len)))
6881ab64890Smrg	    return False;
6891ab64890Smrg
6901ab64890Smrg	if (!(_XimProcCommit(ic, (BYTE *)&buf_s[5],
6916cc2b21fSmrg					(int)buf_s[4], &string, &string_len))) {
6926cc2b21fSmrg	    Xfree(keysym);
6931ab64890Smrg	    return False;
6946cc2b21fSmrg	}
6951ab64890Smrg    }
6961ab64890Smrg
6971ab64890Smrg    if (!(_XimRegCommitInfo(ic, string, string_len, keysym, keysym_len))) {
6980f8248bfSmrg       Xfree(string);
6990f8248bfSmrg	Xfree(keysym);
7001ab64890Smrg	_XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
7011ab64890Smrg	return False;
7021ab64890Smrg    }
7031ab64890Smrg
7041ab64890Smrg    (void)_XimRespSyncReply(ic, flag);
7051ab64890Smrg
706818534a1Smrg    if (ic->private.proto.registed_filter_event
707818534a1Smrg	& (KEYPRESS_MASK | KEYRELEASE_MASK))
708818534a1Smrg	    MARK_FABRICATED(im);
709818534a1Smrg
710818534a1Smrg    bzero(&ev, sizeof(ev));	/* uninitialized : found when running kterm under valgrind */
7111ab64890Smrg
7121ab64890Smrg    ev.type = KeyPress;
7131ab64890Smrg    ev.send_event = False;
7141ab64890Smrg    ev.display = im->core.display;
7151ab64890Smrg    ev.window = ic->core.focus_window;
7161ab64890Smrg    ev.keycode = 0;
7171ab64890Smrg    ev.state = 0;
7181ab64890Smrg
719818534a1Smrg    ev.time = 0L;
720818534a1Smrg    ev.serial = LastKnownRequestProcessed(im->core.display);
721818534a1Smrg    /* FIXME :
722818534a1Smrg       I wish there were COMMENTs (!) about the data passed around.
723818534a1Smrg    */
724818534a1Smrg#if 0
725818534a1Smrg    fprintf(stderr,"%s,%d: putback k press   FIXED ev.time=0 ev.serial=%lu\n", __FILE__, __LINE__, ev.serial);
726818534a1Smrg#endif
727818534a1Smrg
7281ab64890Smrg    XPutBackEvent(im->core.display, (XEvent *)&ev);
7291ab64890Smrg
7301ab64890Smrg    return True;
7311ab64890Smrg}
7321ab64890Smrg
733eb411b4bSmrgBool
7341ab64890Smrg_XimCommitCallback(
7351ab64890Smrg    Xim		 xim,
7361ab64890Smrg    INT16	 len,
7371ab64890Smrg    XPointer	 data,
7381ab64890Smrg    XPointer	 call_data)
7391ab64890Smrg{
7401ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
7411ab64890Smrg    XIMID        imid = buf_s[0];
7421ab64890Smrg    XICID        icid = buf_s[1];
7431ab64890Smrg    Xim		 im = (Xim)call_data;
7441ab64890Smrg    Xic		 ic;
7451ab64890Smrg
7461ab64890Smrg    if ((imid == im->private.proto.imid)
7471ab64890Smrg     && (ic = _XimICOfXICID(im, icid))) {
7481ab64890Smrg	(void)_XimCommitRecv(im, ic, (XPointer)&buf_s[2]);
7491ab64890Smrg	return True;
7501ab64890Smrg    }
7511ab64890Smrg    return False;
7521ab64890Smrg}
7531ab64890Smrg
754eb411b4bSmrgvoid
7551ab64890Smrg_XimProcError(
7561ab64890Smrg    Xim		 im,
7571ab64890Smrg    Xic		 ic,
7581ab64890Smrg    XPointer	 data)
7591ab64890Smrg{
7601ab64890Smrg    return;
7611ab64890Smrg}
7621ab64890Smrg
763eb411b4bSmrgBool
7641ab64890Smrg_XimErrorCallback(
7651ab64890Smrg    Xim		 xim,
7661ab64890Smrg    INT16	 len,
7671ab64890Smrg    XPointer	 data,
7681ab64890Smrg    XPointer	 call_data)
7691ab64890Smrg{
7701ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
7711ab64890Smrg    BITMASK16	 flag = buf_s[2];
7721ab64890Smrg    XIMID        imid;
7731ab64890Smrg    XICID        icid;
7741ab64890Smrg    Xim		 im = (Xim)call_data;
7751ab64890Smrg    Xic		 ic = NULL;
7761ab64890Smrg
7771ab64890Smrg    if (flag & XIM_IMID_VALID) {
7781ab64890Smrg	imid = buf_s[0];
7791ab64890Smrg	if (imid != im->private.proto.imid)
7801ab64890Smrg	    return False;
7811ab64890Smrg    }
7821ab64890Smrg    if (flag & XIM_ICID_VALID) {
7831ab64890Smrg	icid = buf_s[1];
7841ab64890Smrg	if (!(ic = _XimICOfXICID(im, icid)))
7851ab64890Smrg	    return False;
7861ab64890Smrg    }
7871ab64890Smrg    _XimProcError(im, ic, (XPointer)&buf_s[3]);
7881ab64890Smrg
7891ab64890Smrg    return True;
7901ab64890Smrg}
7911ab64890Smrg
792eb411b4bSmrgBool
7931ab64890Smrg_XimError(
7941ab64890Smrg    Xim		 im,
7951ab64890Smrg    Xic		 ic,
7961ab64890Smrg    CARD16	 error_code,
7971ab64890Smrg    INT16	 detail_length,
7981ab64890Smrg    CARD16	 type,
7991ab64890Smrg    char	*detail)
8001ab64890Smrg{
8011ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
8021ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
8031ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
8041ab64890Smrg    INT16	 len = 0;
8051ab64890Smrg
8061ab64890Smrg    buf_s[0] = im->private.proto.imid;	/* imid */
8071ab64890Smrg    buf_s[2] = XIM_IMID_VALID;		/* flag */
8081ab64890Smrg    if (ic) {
8091ab64890Smrg    	buf_s[1] = ic->private.proto.icid;	/* icid */
8101ab64890Smrg	buf_s[2] |= XIM_ICID_VALID;		/* flag */
8111ab64890Smrg    }
8121ab64890Smrg    buf_s[3] = error_code;			/* Error Code */
8131ab64890Smrg    buf_s[4] = detail_length;			/* length of error detail */
8141ab64890Smrg    buf_s[5] = type;				/* type of error detail */
8151ab64890Smrg
8161ab64890Smrg    if (detail_length && detail) {
8171ab64890Smrg	len = detail_length;
8181ab64890Smrg	memcpy((char *)&buf_s[6], detail, len);
8191ab64890Smrg	XIM_SET_PAD(&buf_s[6], len);
8201ab64890Smrg    }
8211ab64890Smrg
8221ab64890Smrg    len += sizeof(CARD16)		/* sizeof imid */
8231ab64890Smrg	 + sizeof(CARD16)		/* sizeof icid */
8241ab64890Smrg	 + sizeof(BITMASK16)		/* sizeof flag */
8251ab64890Smrg	 + sizeof(CARD16)		/* sizeof error_code */
8261ab64890Smrg	 + sizeof(INT16)		/* sizeof length of detail */
8271ab64890Smrg	 + sizeof(CARD16);		/* sizeof type */
8281ab64890Smrg
8291ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_ERROR, 0, &len);
8301ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
8311ab64890Smrg	return False;
8321ab64890Smrg    _XimFlush(im);
8331ab64890Smrg    return True;
8341ab64890Smrg}
8351ab64890Smrg
836eb411b4bSmrgstatic int
8371ab64890Smrg_Ximctsconvert(
8381ab64890Smrg    XlcConv	 conv,
8391ab64890Smrg    char	*from,
8401ab64890Smrg    int		 from_len,
8411ab64890Smrg    char	*to,
8421ab64890Smrg    int		 to_len,
8431ab64890Smrg    Status	*state)
8441ab64890Smrg{
8451ab64890Smrg    int		 from_left;
8461ab64890Smrg    int		 to_left;
8471ab64890Smrg    int		 from_savelen;
8481ab64890Smrg    int		 to_savelen;
8491ab64890Smrg    int		 from_cnvlen;
8501ab64890Smrg    int		 to_cnvlen;
8511ab64890Smrg    char	*from_buf;
8521ab64890Smrg    char	*to_buf;
8531ab64890Smrg    char	 scratchbuf[BUFSIZ];
8541ab64890Smrg    Status	 tmp_state;
8551ab64890Smrg
8561ab64890Smrg    if (!state)
8571ab64890Smrg	state = &tmp_state;
8581ab64890Smrg
8591ab64890Smrg    if (!conv || !from || !from_len) {
8601ab64890Smrg	*state = XLookupNone;
8611ab64890Smrg	return 0;
8621ab64890Smrg    }
8631ab64890Smrg
8641ab64890Smrg    /* Reset the converter.  The CompoundText at 'from' starts in
8651ab64890Smrg       initial state.  */
8661ab64890Smrg    _XlcResetConverter(conv);
8671ab64890Smrg
8681ab64890Smrg    from_left = from_len;
8691ab64890Smrg    to_left = BUFSIZ;
8701ab64890Smrg    from_cnvlen = 0;
8711ab64890Smrg    to_cnvlen = 0;
8721ab64890Smrg    for (;;) {
8731ab64890Smrg	from_buf = &from[from_cnvlen];
8741ab64890Smrg	from_savelen = from_left;
8751ab64890Smrg	to_buf = &scratchbuf[to_cnvlen];
8761ab64890Smrg	to_savelen = to_left;
8771ab64890Smrg	if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
8781ab64890Smrg				 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
8791ab64890Smrg	    *state = XLookupNone;
8801ab64890Smrg	    return 0;
8811ab64890Smrg	}
8821ab64890Smrg	from_cnvlen += (from_savelen - from_left);
8831ab64890Smrg	to_cnvlen += (to_savelen - to_left);
8841ab64890Smrg	if (from_left == 0) {
8851ab64890Smrg	    if (!to_cnvlen) {
8861ab64890Smrg		*state = XLookupNone;
8871ab64890Smrg		return 0;
8881ab64890Smrg           }
8891ab64890Smrg	   break;
8901ab64890Smrg	}
8911ab64890Smrg    }
8921ab64890Smrg
8931ab64890Smrg    if (!to || !to_len || (to_len < to_cnvlen)) {
8941ab64890Smrg       *state = XBufferOverflow;
8951ab64890Smrg    } else {
8961ab64890Smrg       memcpy(to, scratchbuf, to_cnvlen);
8971ab64890Smrg       *state = XLookupChars;
8981ab64890Smrg    }
8991ab64890Smrg    return to_cnvlen;
9001ab64890Smrg}
9011ab64890Smrg
902eb411b4bSmrgint
90361b2299dSmrg_Ximctstombs(XIM xim, char *from, int from_len,
90461b2299dSmrg	     char *to, int to_len, Status *state)
9051ab64890Smrg{
9061ab64890Smrg    return _Ximctsconvert(((Xim)xim)->private.proto.ctom_conv,
9071ab64890Smrg			  from, from_len, to, to_len, state);
9081ab64890Smrg}
9091ab64890Smrg
910eb411b4bSmrgint
9111ab64890Smrg_Ximctstowcs(
9121ab64890Smrg    XIM		 xim,
9131ab64890Smrg    char	*from,
9141ab64890Smrg    int		 from_len,
9151ab64890Smrg    wchar_t	*to,
9161ab64890Smrg    int		 to_len,
9171ab64890Smrg    Status	*state)
9181ab64890Smrg{
9191ab64890Smrg    Xim		 im = (Xim)xim;
9201ab64890Smrg    XlcConv	 conv = im->private.proto.ctow_conv;
9211ab64890Smrg    int		 from_left;
9221ab64890Smrg    int		 to_left;
9231ab64890Smrg    int		 from_savelen;
9241ab64890Smrg    int		 to_savelen;
9251ab64890Smrg    int		 from_cnvlen;
9261ab64890Smrg    int		 to_cnvlen;
9271ab64890Smrg    char	*from_buf;
9281ab64890Smrg    wchar_t	*to_buf;
9291ab64890Smrg    wchar_t	 scratchbuf[BUFSIZ];
9301ab64890Smrg    Status	 tmp_state;
9311ab64890Smrg
9321ab64890Smrg    if (!state)
9331ab64890Smrg	state = &tmp_state;
9341ab64890Smrg
9351ab64890Smrg    if (!conv || !from || !from_len) {
9361ab64890Smrg	*state = XLookupNone;
9371ab64890Smrg	return 0;
9381ab64890Smrg    }
9391ab64890Smrg
9401ab64890Smrg    /* Reset the converter.  The CompoundText at 'from' starts in
9411ab64890Smrg       initial state.  */
9421ab64890Smrg    _XlcResetConverter(conv);
94361b2299dSmrg
9441ab64890Smrg    from_left = from_len;
9451ab64890Smrg    to_left = BUFSIZ;
9461ab64890Smrg    from_cnvlen = 0;
9471ab64890Smrg    to_cnvlen = 0;
9481ab64890Smrg    for (;;) {
9491ab64890Smrg	from_buf = &from[from_cnvlen];
9501ab64890Smrg       from_savelen = from_left;
9511ab64890Smrg       to_buf = &scratchbuf[to_cnvlen];
9521ab64890Smrg       to_savelen = to_left;
9531ab64890Smrg	if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
9541ab64890Smrg				 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
9551ab64890Smrg	    *state = XLookupNone;
9561ab64890Smrg	    return 0;
9571ab64890Smrg	}
9581ab64890Smrg	from_cnvlen += (from_savelen - from_left);
9591ab64890Smrg       to_cnvlen += (to_savelen - to_left);
9601ab64890Smrg	if (from_left == 0) {
9611ab64890Smrg           if (!to_cnvlen){
9621ab64890Smrg		*state = XLookupNone;
9631ab64890Smrg               return 0;
9641ab64890Smrg           }
9651ab64890Smrg	    break;
9661ab64890Smrg	}
9671ab64890Smrg    }
9681ab64890Smrg
9691ab64890Smrg    if (!to || !to_len || (to_len < to_cnvlen)) {
9701ab64890Smrg       *state = XBufferOverflow;
9711ab64890Smrg    } else {
9721ab64890Smrg       memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t));
9731ab64890Smrg       *state = XLookupChars;
9741ab64890Smrg    }
9751ab64890Smrg    return to_cnvlen;
9761ab64890Smrg}
9771ab64890Smrg
978eb411b4bSmrgint
9791ab64890Smrg_Ximctstoutf8(
9801ab64890Smrg    XIM		 xim,
9811ab64890Smrg    char	*from,
9821ab64890Smrg    int		 from_len,
9831ab64890Smrg    char	*to,
9841ab64890Smrg    int		 to_len,
9851ab64890Smrg    Status	*state)
9861ab64890Smrg{
9871ab64890Smrg    return _Ximctsconvert(((Xim)xim)->private.proto.ctoutf8_conv,
9881ab64890Smrg			  from, from_len, to, to_len, state);
9891ab64890Smrg}
9901ab64890Smrg
991eb411b4bSmrgint
9921ab64890Smrg_XimProtoMbLookupString(
9931ab64890Smrg    XIC			 xic,
9941ab64890Smrg    XKeyEvent		*ev,
9951ab64890Smrg    char		*buffer,
9961ab64890Smrg    int			 bytes,
9971ab64890Smrg    KeySym		*keysym,
9981ab64890Smrg    Status		*state)
9991ab64890Smrg{
10001ab64890Smrg    Xic			 ic = (Xic)xic;
10011ab64890Smrg    Xim			 im = (Xim)ic->core.im;
10021ab64890Smrg    int			 ret;
10031ab64890Smrg    Status		 tmp_state;
10041ab64890Smrg    XimCommitInfo	 info;
10051ab64890Smrg
10061ab64890Smrg    if (!IS_SERVER_CONNECTED(im))
10071ab64890Smrg	return 0;
10081ab64890Smrg
10091ab64890Smrg    if (!state)
10101ab64890Smrg	state = &tmp_state;
10111ab64890Smrg
10121ab64890Smrg    if ((ev->type == KeyPress) && (ev->keycode == 0)) { /* Filter function */
10131ab64890Smrg	if (!(info = ic->private.proto.commit_info)) {
10141ab64890Smrg	    *state = XLookupNone;
10151ab64890Smrg	    return 0;
10161ab64890Smrg	}
10171ab64890Smrg
10181ab64890Smrg	ret = im->methods->ctstombs((XIM)im, info->string,
10191ab64890Smrg			 	info->string_len, buffer, bytes, state);
10201ab64890Smrg	if (*state == XBufferOverflow)
10211ab64890Smrg            return ret;
10221ab64890Smrg	if (keysym && (info->keysym && *(info->keysym))) {
10231ab64890Smrg	    *keysym = *(info->keysym);
10241ab64890Smrg	    if (*state == XLookupChars)
10251ab64890Smrg		*state = XLookupBoth;
10261ab64890Smrg	    else
10271ab64890Smrg		*state = XLookupKeySym;
10281ab64890Smrg	}
10291ab64890Smrg	_XimUnregCommitInfo(ic);
10301ab64890Smrg
10311ab64890Smrg    } else  if (ev->type == KeyPress) {
10321ab64890Smrg	ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL);
10331ab64890Smrg	if (ret > 0) {
10341ab64890Smrg           if (ret > bytes)
10351ab64890Smrg               *state = XBufferOverflow;
10361ab64890Smrg           else if (keysym && *keysym != NoSymbol)
10371ab64890Smrg		*state = XLookupBoth;
10381ab64890Smrg	    else
10391ab64890Smrg		*state = XLookupChars;
10401ab64890Smrg	} else {
10411ab64890Smrg	    if (keysym && *keysym != NoSymbol)
10421ab64890Smrg		*state = XLookupKeySym;
10431ab64890Smrg	    else
10441ab64890Smrg		*state = XLookupNone;
10451ab64890Smrg	}
10461ab64890Smrg    } else {
10471ab64890Smrg	*state = XLookupNone;
10481ab64890Smrg	ret = 0;
10491ab64890Smrg    }
10501ab64890Smrg
10511ab64890Smrg    return ret;
10521ab64890Smrg}
10531ab64890Smrg
1054eb411b4bSmrgint
10551ab64890Smrg_XimProtoWcLookupString(
10561ab64890Smrg    XIC			 xic,
10571ab64890Smrg    XKeyEvent		*ev,
10581ab64890Smrg    wchar_t		*buffer,
10591ab64890Smrg    int			 bytes,
10601ab64890Smrg    KeySym		*keysym,
10611ab64890Smrg    Status		*state)
10621ab64890Smrg{
10631ab64890Smrg    Xic			 ic = (Xic)xic;
10641ab64890Smrg    Xim			 im = (Xim)ic->core.im;
10651ab64890Smrg    int			 ret;
10661ab64890Smrg    Status		 tmp_state;
10671ab64890Smrg    XimCommitInfo	 info;
10681ab64890Smrg
10691ab64890Smrg    if (!IS_SERVER_CONNECTED(im))
10701ab64890Smrg	return 0;
10711ab64890Smrg
10721ab64890Smrg    if (!state)
10731ab64890Smrg	state = &tmp_state;
10741ab64890Smrg
10751ab64890Smrg    if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */
10761ab64890Smrg	if (!(info = ic->private.proto.commit_info)) {
10771ab64890Smrg           *state = XLookupNone;
10781ab64890Smrg	    return 0;
10791ab64890Smrg	}
10801ab64890Smrg
10811ab64890Smrg	ret = im->methods->ctstowcs((XIM)im, info->string,
10821ab64890Smrg			 	info->string_len, buffer, bytes, state);
10831ab64890Smrg	if (*state == XBufferOverflow)
10841ab64890Smrg           return ret;
10851ab64890Smrg	if (keysym && (info->keysym && *(info->keysym))) {
10861ab64890Smrg	    *keysym = *(info->keysym);
10871ab64890Smrg	    if (*state == XLookupChars)
10881ab64890Smrg		*state = XLookupBoth;
10891ab64890Smrg	    else
10901ab64890Smrg		*state = XLookupKeySym;
10911ab64890Smrg	}
10921ab64890Smrg	_XimUnregCommitInfo(ic);
10931ab64890Smrg
10941ab64890Smrg    } else if (ev->type == KeyPress) {
10951ab64890Smrg	ret = _XimLookupWCText(ic, ev, buffer, bytes, keysym, NULL);
10961ab64890Smrg	if (ret > 0) {
10971ab64890Smrg           if (ret > bytes)
10981ab64890Smrg               *state = XBufferOverflow;
10991ab64890Smrg           else if (keysym && *keysym != NoSymbol)
11001ab64890Smrg		*state = XLookupBoth;
11011ab64890Smrg	    else
11021ab64890Smrg		*state = XLookupChars;
11031ab64890Smrg	} else {
11041ab64890Smrg	    if (keysym && *keysym != NoSymbol)
11051ab64890Smrg		*state = XLookupKeySym;
11061ab64890Smrg	    else
11071ab64890Smrg		*state = XLookupNone;
11081ab64890Smrg	}
11091ab64890Smrg    } else {
11101ab64890Smrg	*state = XLookupNone;
11111ab64890Smrg	ret = 0;
11121ab64890Smrg    }
11131ab64890Smrg
11141ab64890Smrg    return ret;
11151ab64890Smrg}
11161ab64890Smrg
1117eb411b4bSmrgint
11181ab64890Smrg_XimProtoUtf8LookupString(
11191ab64890Smrg    XIC			 xic,
11201ab64890Smrg    XKeyEvent		*ev,
11211ab64890Smrg    char		*buffer,
11221ab64890Smrg    int			 bytes,
11231ab64890Smrg    KeySym		*keysym,
11241ab64890Smrg    Status		*state)
11251ab64890Smrg{
11261ab64890Smrg    Xic			 ic = (Xic)xic;
11271ab64890Smrg    Xim			 im = (Xim)ic->core.im;
11281ab64890Smrg    int			 ret;
11291ab64890Smrg    Status		 tmp_state;
11301ab64890Smrg    XimCommitInfo	 info;
11311ab64890Smrg
11321ab64890Smrg    if (!IS_SERVER_CONNECTED(im))
11331ab64890Smrg	return 0;
11341ab64890Smrg
11351ab64890Smrg    if (!state)
11361ab64890Smrg	state = &tmp_state;
11371ab64890Smrg
11381ab64890Smrg    if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */
11391ab64890Smrg	if (!(info = ic->private.proto.commit_info)) {
11401ab64890Smrg           *state = XLookupNone;
11411ab64890Smrg	    return 0;
11421ab64890Smrg	}
11431ab64890Smrg
11441ab64890Smrg	ret = im->methods->ctstoutf8((XIM)im, info->string,
11451ab64890Smrg			 	info->string_len, buffer, bytes, state);
11461ab64890Smrg	if (*state == XBufferOverflow)
11471ab64890Smrg           return ret;
11481ab64890Smrg	if (keysym && (info->keysym && *(info->keysym))) {
11491ab64890Smrg	    *keysym = *(info->keysym);
11501ab64890Smrg	    if (*state == XLookupChars)
11511ab64890Smrg		*state = XLookupBoth;
11521ab64890Smrg	    else
11531ab64890Smrg		*state = XLookupKeySym;
11541ab64890Smrg	}
11551ab64890Smrg	_XimUnregCommitInfo(ic);
11561ab64890Smrg
11571ab64890Smrg    } else if (ev->type == KeyPress) {
11581ab64890Smrg	ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL);
11591ab64890Smrg	if (ret > 0) {
11601ab64890Smrg           if (ret > bytes)
11611ab64890Smrg               *state = XBufferOverflow;
11621ab64890Smrg           else if (keysym && *keysym != NoSymbol)
11631ab64890Smrg		*state = XLookupBoth;
11641ab64890Smrg	    else
11651ab64890Smrg		*state = XLookupChars;
11661ab64890Smrg	} else {
11671ab64890Smrg	    if (keysym && *keysym != NoSymbol)
11681ab64890Smrg		*state = XLookupKeySym;
11691ab64890Smrg	    else
11701ab64890Smrg		*state = XLookupNone;
11711ab64890Smrg	}
11721ab64890Smrg    } else {
11731ab64890Smrg	*state = XLookupNone;
11741ab64890Smrg	ret = 0;
11751ab64890Smrg    }
11761ab64890Smrg
11771ab64890Smrg    return ret;
11781ab64890Smrg}
1179