imDefLkup.c revision 6cc2b21f
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
371ab64890SmrgPublic Xic
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
511ab64890SmrgPrivate 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
631ab64890SmrgPrivate 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
761ab64890SmrgPublic Bool
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
1011ab64890SmrgPrivate 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
1301ab64890SmrgPublic Bool
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;
1651ab64890Smrg	    preply = (XPointer)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
1881ab64890SmrgPublic Bool
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
2111ab64890SmrgPublic Bool
2121ab64890Smrg_XimRespSyncReply(
2131ab64890Smrg    Xic		 ic,
2141ab64890Smrg    BITMASK16	 mode)
2151ab64890Smrg{
2161ab64890Smrg    if (mode & XimSYNCHRONUS) /* SYNC Request */ {
2171ab64890Smrg	if (IS_FOCUSED(ic))
2181ab64890Smrg	    MARK_NEED_SYNC_REPLY(ic);
2191ab64890Smrg	else
22061b2299dSmrg	    _XimProcSyncReply((Xim)ic->core.im, ic);
2211ab64890Smrg    }
22261b2299dSmrg
2231ab64890Smrg    return True;
2241ab64890Smrg}
2251ab64890Smrg
2261ab64890SmrgPublic Bool
2271ab64890Smrg_XimSyncCallback(
2281ab64890Smrg    Xim		 xim,
2291ab64890Smrg    INT16	 len,
2301ab64890Smrg    XPointer	 data,
2311ab64890Smrg    XPointer	 call_data)
2321ab64890Smrg{
2331ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
2341ab64890Smrg    XIMID        imid = buf_s[0];
2351ab64890Smrg    XICID        icid = buf_s[1];
2361ab64890Smrg    Xim		 im = (Xim)call_data;
2371ab64890Smrg    Xic		 ic;
2381ab64890Smrg
2391ab64890Smrg    if ((imid == im->private.proto.imid)
2401ab64890Smrg     && (ic = _XimICOfXICID(im, icid))) {
2411ab64890Smrg	(void)_XimProcSyncReply(im, ic);
2421ab64890Smrg	return True;
2431ab64890Smrg    }
2441ab64890Smrg    return False;
2451ab64890Smrg}
2461ab64890Smrg
2471ab64890SmrgPrivate INT16
2481ab64890Smrg_XimSetEventToWire(
2491ab64890Smrg    XEvent	*ev,
2501ab64890Smrg    xEvent	*event)
2511ab64890Smrg{
2521ab64890Smrg    if (!(_XimProtoEventToWire(ev, event, False)))
2531ab64890Smrg	return 0;
2541ab64890Smrg    event->u.u.sequenceNumber =
2551ab64890Smrg		((XAnyEvent *)ev)->serial & (unsigned long)0xffff;
2561ab64890Smrg    return sz_xEvent;
2571ab64890Smrg}
2581ab64890Smrg
2591ab64890SmrgPrivate Bool
2601ab64890Smrg_XimForwardEventCore(
2611ab64890Smrg    Xic		 ic,
2621ab64890Smrg    XEvent	*ev,
2631ab64890Smrg    Bool	 sync)
2641ab64890Smrg{
2651ab64890Smrg    Xim		 im = (Xim)ic->core.im;
2661ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
2671ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
2681ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
2691ab64890Smrg    CARD32	 reply32[BUFSIZE/4];
2701ab64890Smrg    char	*reply = (char *)reply32;
2711ab64890Smrg    XPointer	 preply;
2721ab64890Smrg    int		 buf_size;
2731ab64890Smrg    int		 ret_code;
2741ab64890Smrg    INT16	 len;
2751ab64890Smrg
2761ab64890Smrg    if (!(len = _XimSetEventToWire(ev, (xEvent *)&buf_s[4])))
2771ab64890Smrg	return False;				/* X event */
2781ab64890Smrg
2791ab64890Smrg    buf_s[0] = im->private.proto.imid;		/* imid */
2801ab64890Smrg    buf_s[1] = ic->private.proto.icid;		/* icid */
2811ab64890Smrg    buf_s[2] = sync ? XimSYNCHRONUS : 0;	/* flag */
2821ab64890Smrg    buf_s[3] =
2831ab64890Smrg        (CARD16)((((XAnyEvent *)ev)->serial & ~((unsigned long)0xffff)) >> 16);
2841ab64890Smrg						/* serial number */
2851ab64890Smrg
2861ab64890Smrg    len += sizeof(CARD16)			/* sizeof imid */
2871ab64890Smrg	 + sizeof(CARD16)			/* sizeof icid */
2881ab64890Smrg	 + sizeof(BITMASK16)			/* sizeof flag */
2891ab64890Smrg	 + sizeof(CARD16);			/* sizeof serila number */
2901ab64890Smrg
2911ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_FORWARD_EVENT, 0, &len);
2921ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
2931ab64890Smrg	return False;
2941ab64890Smrg    _XimFlush(im);
2951ab64890Smrg
2961ab64890Smrg    if (sync) {
2971ab64890Smrg	buf_size = BUFSIZE;
2981ab64890Smrg	ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
2991ab64890Smrg					_XimSyncCheck, (XPointer)ic);
3001ab64890Smrg	if(ret_code == XIM_TRUE) {
3011ab64890Smrg	    preply = reply;
3021ab64890Smrg	} else if(ret_code == XIM_OVERFLOW) {
3031ab64890Smrg	    if(len <= 0) {
3041ab64890Smrg		preply = reply;
3051ab64890Smrg	    } else {
3061ab64890Smrg		buf_size = len;
3071ab64890Smrg		preply = (XPointer)Xmalloc(len);
3081ab64890Smrg		ret_code = _XimRead(im, &len, preply, buf_size,
3091ab64890Smrg					_XimSyncCheck, (XPointer)ic);
3101ab64890Smrg		if(ret_code != XIM_TRUE) {
3111ab64890Smrg		    Xfree(preply);
3121ab64890Smrg		    return False;
3131ab64890Smrg		}
3141ab64890Smrg	    }
3151ab64890Smrg	} else {
3161ab64890Smrg	    return False;
3171ab64890Smrg	}
3181ab64890Smrg	buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
3191ab64890Smrg	if (*((CARD8 *)preply) == XIM_ERROR) {
3201ab64890Smrg	    _XimProcError(im, 0, (XPointer)&buf_s[3]);
3211ab64890Smrg	    if(reply != preply)
3221ab64890Smrg		Xfree(preply);
3231ab64890Smrg	    return False;
3241ab64890Smrg	}
3251ab64890Smrg	if(reply != preply)
3261ab64890Smrg	    Xfree(preply);
3271ab64890Smrg    }
3281ab64890Smrg    return True;
3291ab64890Smrg}
3301ab64890Smrg
3311ab64890SmrgPublic Bool
3321ab64890Smrg_XimForwardEvent(
3331ab64890Smrg    Xic		 ic,
3341ab64890Smrg    XEvent	*ev,
3351ab64890Smrg    Bool	 sync)
3361ab64890Smrg{
3371ab64890Smrg#ifdef EXT_FORWARD
3381ab64890Smrg    if (((ev->type == KeyPress) || (ev->type == KeyRelease)))
3391ab64890Smrg	if (_XimExtForwardKeyEvent(ic, (XKeyEvent *)ev, sync))
3401ab64890Smrg	    return True;
3411ab64890Smrg#endif
3421ab64890Smrg    return _XimForwardEventCore(ic, ev, sync);
3431ab64890Smrg}
3441ab64890Smrg
3451ab64890SmrgPrivate void
3461ab64890Smrg_XimProcEvent(
3471ab64890Smrg    Display		*d,
3481ab64890Smrg    Xic			 ic,
3491ab64890Smrg    XEvent		*ev,
3501ab64890Smrg    CARD16		*buf)
3511ab64890Smrg{
3521ab64890Smrg    INT16	 serial = buf[0];
3531ab64890Smrg    xEvent	*xev = (xEvent *)&buf[1];
3541ab64890Smrg
3551ab64890Smrg    _XimProtoWireToEvent(ev, xev, False);
3561ab64890Smrg    ev->xany.serial |= serial << 16;
3571ab64890Smrg    ev->xany.send_event = False;
3581ab64890Smrg    ev->xany.display = d;
3591ab64890Smrg    MARK_FABLICATED(ic);
3601ab64890Smrg    return;
3611ab64890Smrg}
3621ab64890Smrg
3631ab64890SmrgPrivate Bool
3641ab64890Smrg_XimForwardEventRecv(
3651ab64890Smrg    Xim		 im,
3661ab64890Smrg    Xic		 ic,
3671ab64890Smrg    XPointer	 buf)
3681ab64890Smrg{
3691ab64890Smrg    CARD16	*buf_s = (CARD16 *)buf;
3701ab64890Smrg    Display	*d = im->core.display;
3711ab64890Smrg    XEvent	 ev;
3721ab64890Smrg
3731ab64890Smrg    _XimProcEvent(d, ic, &ev, &buf_s[1]);
3741ab64890Smrg
3751ab64890Smrg    (void)_XimRespSyncReply(ic, buf_s[0]);
3761ab64890Smrg
3771ab64890Smrg    XPutBackEvent(d, &ev);
3781ab64890Smrg
3791ab64890Smrg    return True;
3801ab64890Smrg}
3811ab64890Smrg
3821ab64890SmrgPublic Bool
3831ab64890Smrg_XimForwardEventCallback(
3841ab64890Smrg    Xim		 xim,
3851ab64890Smrg    INT16	 len,
3861ab64890Smrg    XPointer	 data,
3871ab64890Smrg    XPointer	 call_data)
3881ab64890Smrg{
3891ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
3901ab64890Smrg    XIMID        imid = buf_s[0];
3911ab64890Smrg    XICID        icid = buf_s[1];
3921ab64890Smrg    Xim		 im = (Xim)call_data;
3931ab64890Smrg    Xic		 ic;
3941ab64890Smrg
3951ab64890Smrg    if ((imid == im->private.proto.imid)
3961ab64890Smrg     && (ic = _XimICOfXICID(im, icid))) {
3971ab64890Smrg	(void)_XimForwardEventRecv(im, ic, (XPointer)&buf_s[2]);
3981ab64890Smrg	return True;
3991ab64890Smrg    }
4001ab64890Smrg    return False;
4011ab64890Smrg}
4021ab64890Smrg
4031ab64890SmrgPrivate Bool
4041ab64890Smrg_XimRegisterTriggerkey(
4051ab64890Smrg    Xim			 im,
4061ab64890Smrg    XPointer		 buf)
4071ab64890Smrg{
4081ab64890Smrg    CARD32		*buf_l = (CARD32 *)buf;
4091ab64890Smrg    CARD32		 len;
4101ab64890Smrg    CARD32 		*key;
4111ab64890Smrg
4121ab64890Smrg    if (IS_DYNAMIC_EVENT_FLOW(im))	/* already Dynamic event flow mode */
4131ab64890Smrg	return True;
4141ab64890Smrg
4151ab64890Smrg    /*
4161ab64890Smrg     *  register onkeylist
4171ab64890Smrg     */
4181ab64890Smrg
4191ab64890Smrg    len = buf_l[0];				/* length of on-keys */
4201ab64890Smrg    len += sizeof(INT32);			/* sizeof length of on-keys */
4211ab64890Smrg
4221ab64890Smrg    if (!(key = (CARD32 *)Xmalloc(len))) {
4231ab64890Smrg	_XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
4241ab64890Smrg	return False;
4251ab64890Smrg    }
4261ab64890Smrg    memcpy((char *)key, (char *)buf_l, len);
4271ab64890Smrg    im->private.proto.im_onkeylist = key;
4281ab64890Smrg
4291ab64890Smrg    MARK_DYNAMIC_EVENT_FLOW(im);
4301ab64890Smrg
4311ab64890Smrg    /*
4321ab64890Smrg     *  register offkeylist
4331ab64890Smrg     */
4341ab64890Smrg
4351ab64890Smrg    buf_l = (CARD32 *)((char *)buf + len);
4361ab64890Smrg    len = buf_l[0];				/* length of off-keys */
4371ab64890Smrg    len += sizeof(INT32);			/* sizeof length of off-keys */
4381ab64890Smrg
4391ab64890Smrg    if (!(key = (CARD32 *)Xmalloc(len))) {
4401ab64890Smrg	_XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
4411ab64890Smrg	return False;
4421ab64890Smrg    }
4431ab64890Smrg
4441ab64890Smrg    memcpy((char *)key, (char *)buf_l, len);
4451ab64890Smrg    im->private.proto.im_offkeylist = key;
4461ab64890Smrg
4471ab64890Smrg    return True;
4481ab64890Smrg}
4491ab64890Smrg
4501ab64890SmrgPublic Bool
4511ab64890Smrg_XimRegisterTriggerKeysCallback(
4521ab64890Smrg    Xim		 xim,
4531ab64890Smrg    INT16	 len,
4541ab64890Smrg    XPointer	 data,
4551ab64890Smrg    XPointer	 call_data)
4561ab64890Smrg{
4571ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
4581ab64890Smrg    Xim		 im = (Xim)call_data;
4591ab64890Smrg
4601ab64890Smrg    (void )_XimRegisterTriggerkey(im, (XPointer)&buf_s[2]);
4611ab64890Smrg    return True;
4621ab64890Smrg}
4631ab64890Smrg
4641ab64890SmrgPublic EVENTMASK
4651ab64890Smrg_XimGetWindowEventmask(
4661ab64890Smrg    Xic		 ic)
4671ab64890Smrg{
4681ab64890Smrg    Xim			im = (Xim )ic->core.im;
4691ab64890Smrg    XWindowAttributes	atr;
4701ab64890Smrg
4711ab64890Smrg    if (!XGetWindowAttributes(im->core.display, ic->core.focus_window, &atr))
4721ab64890Smrg	return 0;
4731ab64890Smrg    return (EVENTMASK)atr.your_event_mask;
4741ab64890Smrg}
4751ab64890Smrg
4761ab64890Smrg
4771ab64890SmrgPrivate Bool
4781ab64890Smrg_XimTriggerNotifyCheck(
4791ab64890Smrg    Xim          im,
4801ab64890Smrg    INT16        len,
4811ab64890Smrg    XPointer	 data,
4821ab64890Smrg    XPointer     arg)
4831ab64890Smrg{
4841ab64890Smrg    Xic		 ic  = (Xic)arg;
4851ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
4861ab64890Smrg    CARD8	 major_opcode = *((CARD8 *)data);
4871ab64890Smrg    CARD8	 minor_opcode = *((CARD8 *)data + 1);
4881ab64890Smrg    XIMID	 imid = buf_s[0];
4891ab64890Smrg    XICID	 icid = buf_s[1];
4901ab64890Smrg
4911ab64890Smrg    if ((major_opcode == XIM_TRIGGER_NOTIFY_REPLY)
4921ab64890Smrg     && (minor_opcode == 0)
4931ab64890Smrg     && (imid == im->private.proto.imid)
4941ab64890Smrg     && (icid == ic->private.proto.icid))
4951ab64890Smrg	return True;
4961ab64890Smrg    if ((major_opcode == XIM_ERROR)
4971ab64890Smrg     && (minor_opcode == 0)
4981ab64890Smrg     && (buf_s[2] & XIM_IMID_VALID)
4991ab64890Smrg     && (imid == im->private.proto.imid)
5001ab64890Smrg     && (buf_s[2] & XIM_ICID_VALID)
5011ab64890Smrg     && (icid == ic->private.proto.icid))
5021ab64890Smrg	return True;
5031ab64890Smrg    return False;
5041ab64890Smrg}
5051ab64890Smrg
5061ab64890SmrgPublic Bool
5071ab64890Smrg_XimTriggerNotify(
5081ab64890Smrg    Xim		 im,
5091ab64890Smrg    Xic		 ic,
5101ab64890Smrg    int		 mode,
5111ab64890Smrg    CARD32	 idx)
5121ab64890Smrg{
5131ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
5141ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
5151ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
5161ab64890Smrg    CARD32	*buf_l = (CARD32 *)&buf[XIM_HEADER_SIZE];
5171ab64890Smrg    CARD32	 reply32[BUFSIZE/4];
5181ab64890Smrg    char	*reply = (char *)reply32;
5191ab64890Smrg    XPointer	 preply;
5201ab64890Smrg    int		 buf_size;
5211ab64890Smrg    int		 ret_code;
5221ab64890Smrg    INT16	 len;
5231ab64890Smrg    EVENTMASK	 mask = _XimGetWindowEventmask(ic);
5241ab64890Smrg
5251ab64890Smrg    buf_s[0] = im->private.proto.imid;	/* imid */
5261ab64890Smrg    buf_s[1] = ic->private.proto.icid;	/* icid */
5271ab64890Smrg    buf_l[1] = mode;			/* flag */
5281ab64890Smrg    buf_l[2] = idx;			/* index of keys list */
5291ab64890Smrg    buf_l[3] = mask;			/* select-event-mask */
5301ab64890Smrg
5311ab64890Smrg    len = sizeof(CARD16)		/* sizeof imid */
5321ab64890Smrg	+ sizeof(CARD16)		/* sizeof icid */
5331ab64890Smrg	+ sizeof(CARD32)		/* sizeof flag */
5341ab64890Smrg	+ sizeof(CARD32)		/* sizeof index of key list */
5351ab64890Smrg	+ sizeof(EVENTMASK);		/* sizeof select-event-mask */
5361ab64890Smrg
5371ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_TRIGGER_NOTIFY, 0, &len);
5381ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
5391ab64890Smrg	return False;
5401ab64890Smrg    _XimFlush(im);
5411ab64890Smrg    buf_size = BUFSIZE;
5421ab64890Smrg    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
5431ab64890Smrg				_XimTriggerNotifyCheck, (XPointer)ic);
5441ab64890Smrg    if(ret_code == XIM_TRUE) {
5451ab64890Smrg	preply = reply;
5461ab64890Smrg    } else if(ret_code == XIM_OVERFLOW) {
5471ab64890Smrg	if(len <= 0) {
5481ab64890Smrg	    preply = reply;
5491ab64890Smrg	} else {
5501ab64890Smrg	    buf_size = len;
5511ab64890Smrg	    preply = (XPointer)Xmalloc(len);
5521ab64890Smrg	    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
5531ab64890Smrg				_XimTriggerNotifyCheck, (XPointer)ic);
5541ab64890Smrg	    if(ret_code != XIM_TRUE) {
5551ab64890Smrg		Xfree(preply);
5561ab64890Smrg		return False;
5571ab64890Smrg	    }
5581ab64890Smrg	}
5591ab64890Smrg    } else {
5601ab64890Smrg	return False;
5611ab64890Smrg    }
5621ab64890Smrg    buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
5631ab64890Smrg    if (*((CARD8 *)preply) == XIM_ERROR) {
5641ab64890Smrg	_XimProcError(im, 0, (XPointer)&buf_s[3]);
5651ab64890Smrg	if(reply != preply)
5661ab64890Smrg	    Xfree(preply);
5671ab64890Smrg	return False;
5681ab64890Smrg    }
5691ab64890Smrg    if(reply != preply)
5701ab64890Smrg	Xfree(preply);
5711ab64890Smrg    return True;
5721ab64890Smrg}
5731ab64890Smrg
5741ab64890SmrgPrivate Bool
5751ab64890Smrg_XimRegCommitInfo(
5761ab64890Smrg    Xic			 ic,
5771ab64890Smrg    char		*string,
5781ab64890Smrg    int			 string_len,
5791ab64890Smrg    KeySym		*keysym,
5801ab64890Smrg    int			 keysym_len)
5811ab64890Smrg{
5821ab64890Smrg    XimCommitInfo	info;
5831ab64890Smrg
5841ab64890Smrg    if (!(info = (XimCommitInfo)Xmalloc(sizeof(XimCommitInfoRec))))
5851ab64890Smrg	return False;
5861ab64890Smrg    info->string	= string;
5871ab64890Smrg    info->string_len	= string_len;
5881ab64890Smrg    info->keysym	= keysym;
5891ab64890Smrg    info->keysym_len	= keysym_len;
5901ab64890Smrg    info->next = ic->private.proto.commit_info;
5911ab64890Smrg    ic->private.proto.commit_info = info;
5921ab64890Smrg    return True;
5931ab64890Smrg}
5941ab64890Smrg
5951ab64890SmrgPrivate void
5961ab64890Smrg_XimUnregCommitInfo(
5971ab64890Smrg    Xic			ic)
5981ab64890Smrg{
5991ab64890Smrg    XimCommitInfo	info;
6001ab64890Smrg
6011ab64890Smrg    if (!(info = ic->private.proto.commit_info))
6021ab64890Smrg	return;
6031ab64890Smrg
6041ab64890Smrg    if (info->string)
6051ab64890Smrg	Xfree(info->string);
6061ab64890Smrg    if (info->keysym)
6071ab64890Smrg	Xfree(info->keysym);
6081ab64890Smrg    ic->private.proto.commit_info = info->next;
6091ab64890Smrg    Xfree(info);
6101ab64890Smrg    return;
6111ab64890Smrg}
6121ab64890Smrg
6131ab64890SmrgPublic void
6141ab64890Smrg_XimFreeCommitInfo(
6151ab64890Smrg    Xic			ic)
6161ab64890Smrg{
6171ab64890Smrg    while (ic->private.proto.commit_info)
6181ab64890Smrg	_XimUnregCommitInfo(ic);
6191ab64890Smrg    return;
6201ab64890Smrg}
6211ab64890Smrg
6221ab64890SmrgPrivate Bool
6231ab64890Smrg_XimProcKeySym(
6241ab64890Smrg    Xic			  ic,
6251ab64890Smrg    CARD32		  sym,
6261ab64890Smrg    KeySym		**xim_keysym,
6271ab64890Smrg    int			 *xim_keysym_len)
6281ab64890Smrg{
6291ab64890Smrg    Xim			 im = (Xim)ic->core.im;
6301ab64890Smrg
6311ab64890Smrg    if (!(*xim_keysym = (KeySym *)Xmalloc(sizeof(KeySym)))) {
6321ab64890Smrg	_XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
6331ab64890Smrg	return False;
6341ab64890Smrg    }
6351ab64890Smrg
6361ab64890Smrg    **xim_keysym = (KeySym)sym;
6371ab64890Smrg    *xim_keysym_len = 1;
6381ab64890Smrg
6391ab64890Smrg    return True;
6401ab64890Smrg}
6411ab64890Smrg
6421ab64890SmrgPrivate Bool
6431ab64890Smrg_XimProcCommit(
6441ab64890Smrg    Xic		  ic,
6451ab64890Smrg    BYTE	 *buf,
6461ab64890Smrg    int		  len,
6471ab64890Smrg    char	**xim_string,
6481ab64890Smrg    int		 *xim_string_len)
6491ab64890Smrg{
6501ab64890Smrg    Xim		 im = (Xim)ic->core.im;
6511ab64890Smrg    char	*string;
6521ab64890Smrg
6531ab64890Smrg    if (!(string = (char *)Xmalloc(len + 1))) {
6541ab64890Smrg	_XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
6551ab64890Smrg	return False;
6561ab64890Smrg    }
6571ab64890Smrg
6581ab64890Smrg    (void)memcpy(string, (char *)buf, len);
6591ab64890Smrg    string[len] = '\0';
6601ab64890Smrg
6611ab64890Smrg    *xim_string = string;
6621ab64890Smrg    *xim_string_len = len;
6631ab64890Smrg    return True;
6641ab64890Smrg}
6651ab64890Smrg
6661ab64890SmrgPrivate Bool
6671ab64890Smrg_XimCommitRecv(
6681ab64890Smrg    Xim		 im,
6691ab64890Smrg    Xic		 ic,
6701ab64890Smrg    XPointer	 buf)
6711ab64890Smrg{
6721ab64890Smrg    CARD16	*buf_s = (CARD16 *)buf;
6731ab64890Smrg    BITMASK16	 flag = buf_s[0];
6741ab64890Smrg    XKeyEvent	 ev;
6751ab64890Smrg    char	*string = NULL;
6761ab64890Smrg    int		 string_len = 0;
6771ab64890Smrg    KeySym	*keysym = NULL;
6781ab64890Smrg    int		 keysym_len = 0;
6791ab64890Smrg
6801ab64890Smrg    if ((flag & XimLookupBoth) == XimLookupChars) {
6811ab64890Smrg	if (!(_XimProcCommit(ic, (BYTE *)&buf_s[2],
6821ab64890Smrg			 		(int)buf_s[1], &string, &string_len)))
6831ab64890Smrg	    return False;
6841ab64890Smrg
6851ab64890Smrg    } else if ((flag & XimLookupBoth) == XimLookupKeySym) {
6861ab64890Smrg	if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len)))
6871ab64890Smrg	    return False;
6881ab64890Smrg
6891ab64890Smrg    } else if ((flag & XimLookupBoth) == XimLookupBoth) {
6901ab64890Smrg	if (!(_XimProcKeySym(ic, *(CARD32 *)&buf_s[2], &keysym, &keysym_len)))
6911ab64890Smrg	    return False;
6921ab64890Smrg
6931ab64890Smrg	if (!(_XimProcCommit(ic, (BYTE *)&buf_s[5],
6946cc2b21fSmrg					(int)buf_s[4], &string, &string_len))) {
6956cc2b21fSmrg	    Xfree(keysym);
6961ab64890Smrg	    return False;
6976cc2b21fSmrg	}
6981ab64890Smrg    }
6991ab64890Smrg
7001ab64890Smrg    if (!(_XimRegCommitInfo(ic, string, string_len, keysym, keysym_len))) {
7011ab64890Smrg	if (string)
7021ab64890Smrg	    Xfree(string);
7031ab64890Smrg	if (keysym)
7041ab64890Smrg	    Xfree(keysym);
7051ab64890Smrg	_XimError(im, ic, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
7061ab64890Smrg	return False;
7071ab64890Smrg    }
7081ab64890Smrg
7091ab64890Smrg    (void)_XimRespSyncReply(ic, flag);
7101ab64890Smrg
7111ab64890Smrg    MARK_FABLICATED(ic);
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
7201ab64890Smrg    XPutBackEvent(im->core.display, (XEvent *)&ev);
7211ab64890Smrg
7221ab64890Smrg    return True;
7231ab64890Smrg}
7241ab64890Smrg
7251ab64890SmrgPublic Bool
7261ab64890Smrg_XimCommitCallback(
7271ab64890Smrg    Xim		 xim,
7281ab64890Smrg    INT16	 len,
7291ab64890Smrg    XPointer	 data,
7301ab64890Smrg    XPointer	 call_data)
7311ab64890Smrg{
7321ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
7331ab64890Smrg    XIMID        imid = buf_s[0];
7341ab64890Smrg    XICID        icid = buf_s[1];
7351ab64890Smrg    Xim		 im = (Xim)call_data;
7361ab64890Smrg    Xic		 ic;
7371ab64890Smrg
7381ab64890Smrg    if ((imid == im->private.proto.imid)
7391ab64890Smrg     && (ic = _XimICOfXICID(im, icid))) {
7401ab64890Smrg	(void)_XimCommitRecv(im, ic, (XPointer)&buf_s[2]);
7411ab64890Smrg	return True;
7421ab64890Smrg    }
7431ab64890Smrg    return False;
7441ab64890Smrg}
7451ab64890Smrg
7461ab64890SmrgPublic void
7471ab64890Smrg_XimProcError(
7481ab64890Smrg    Xim		 im,
7491ab64890Smrg    Xic		 ic,
7501ab64890Smrg    XPointer	 data)
7511ab64890Smrg{
7521ab64890Smrg    return;
7531ab64890Smrg}
7541ab64890Smrg
7551ab64890SmrgPublic Bool
7561ab64890Smrg_XimErrorCallback(
7571ab64890Smrg    Xim		 xim,
7581ab64890Smrg    INT16	 len,
7591ab64890Smrg    XPointer	 data,
7601ab64890Smrg    XPointer	 call_data)
7611ab64890Smrg{
7621ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
7631ab64890Smrg    BITMASK16	 flag = buf_s[2];
7641ab64890Smrg    XIMID        imid;
7651ab64890Smrg    XICID        icid;
7661ab64890Smrg    Xim		 im = (Xim)call_data;
7671ab64890Smrg    Xic		 ic = NULL;
7681ab64890Smrg
7691ab64890Smrg    if (flag & XIM_IMID_VALID) {
7701ab64890Smrg	imid = buf_s[0];
7711ab64890Smrg	if (imid != im->private.proto.imid)
7721ab64890Smrg	    return False;
7731ab64890Smrg    }
7741ab64890Smrg    if (flag & XIM_ICID_VALID) {
7751ab64890Smrg	icid = buf_s[1];
7761ab64890Smrg	if (!(ic = _XimICOfXICID(im, icid)))
7771ab64890Smrg	    return False;
7781ab64890Smrg    }
7791ab64890Smrg    _XimProcError(im, ic, (XPointer)&buf_s[3]);
7801ab64890Smrg
7811ab64890Smrg    return True;
7821ab64890Smrg}
7831ab64890Smrg
7841ab64890SmrgPublic Bool
7851ab64890Smrg_XimError(
7861ab64890Smrg    Xim		 im,
7871ab64890Smrg    Xic		 ic,
7881ab64890Smrg    CARD16	 error_code,
7891ab64890Smrg    INT16	 detail_length,
7901ab64890Smrg    CARD16	 type,
7911ab64890Smrg    char	*detail)
7921ab64890Smrg{
7931ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
7941ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
7951ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
7961ab64890Smrg    INT16	 len = 0;
7971ab64890Smrg
7981ab64890Smrg    buf_s[0] = im->private.proto.imid;	/* imid */
7991ab64890Smrg    buf_s[2] = XIM_IMID_VALID;		/* flag */
8001ab64890Smrg    if (ic) {
8011ab64890Smrg    	buf_s[1] = ic->private.proto.icid;	/* icid */
8021ab64890Smrg	buf_s[2] |= XIM_ICID_VALID;		/* flag */
8031ab64890Smrg    }
8041ab64890Smrg    buf_s[3] = error_code;			/* Error Code */
8051ab64890Smrg    buf_s[4] = detail_length;			/* length of error detail */
8061ab64890Smrg    buf_s[5] = type;				/* type of error detail */
8071ab64890Smrg
8081ab64890Smrg    if (detail_length && detail) {
8091ab64890Smrg	len = detail_length;
8101ab64890Smrg	memcpy((char *)&buf_s[6], detail, len);
8111ab64890Smrg	XIM_SET_PAD(&buf_s[6], len);
8121ab64890Smrg    }
8131ab64890Smrg
8141ab64890Smrg    len += sizeof(CARD16)		/* sizeof imid */
8151ab64890Smrg	 + sizeof(CARD16)		/* sizeof icid */
8161ab64890Smrg	 + sizeof(BITMASK16)		/* sizeof flag */
8171ab64890Smrg	 + sizeof(CARD16)		/* sizeof error_code */
8181ab64890Smrg	 + sizeof(INT16)		/* sizeof length of detail */
8191ab64890Smrg	 + sizeof(CARD16);		/* sizeof type */
8201ab64890Smrg
8211ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_ERROR, 0, &len);
8221ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
8231ab64890Smrg	return False;
8241ab64890Smrg    _XimFlush(im);
8251ab64890Smrg    return True;
8261ab64890Smrg}
8271ab64890Smrg
8281ab64890SmrgPrivate int
8291ab64890Smrg_Ximctsconvert(
8301ab64890Smrg    XlcConv	 conv,
8311ab64890Smrg    char	*from,
8321ab64890Smrg    int		 from_len,
8331ab64890Smrg    char	*to,
8341ab64890Smrg    int		 to_len,
8351ab64890Smrg    Status	*state)
8361ab64890Smrg{
8371ab64890Smrg    int		 from_left;
8381ab64890Smrg    int		 to_left;
8391ab64890Smrg    int		 from_savelen;
8401ab64890Smrg    int		 to_savelen;
8411ab64890Smrg    int		 from_cnvlen;
8421ab64890Smrg    int		 to_cnvlen;
8431ab64890Smrg    char	*from_buf;
8441ab64890Smrg    char	*to_buf;
8451ab64890Smrg    char	 scratchbuf[BUFSIZ];
8461ab64890Smrg    Status	 tmp_state;
8471ab64890Smrg
8481ab64890Smrg    if (!state)
8491ab64890Smrg	state = &tmp_state;
8501ab64890Smrg
8511ab64890Smrg    if (!conv || !from || !from_len) {
8521ab64890Smrg	*state = XLookupNone;
8531ab64890Smrg	return 0;
8541ab64890Smrg    }
8551ab64890Smrg
8561ab64890Smrg    /* Reset the converter.  The CompoundText at 'from' starts in
8571ab64890Smrg       initial state.  */
8581ab64890Smrg    _XlcResetConverter(conv);
8591ab64890Smrg
8601ab64890Smrg    from_left = from_len;
8611ab64890Smrg    to_left = BUFSIZ;
8621ab64890Smrg    from_cnvlen = 0;
8631ab64890Smrg    to_cnvlen = 0;
8641ab64890Smrg    for (;;) {
8651ab64890Smrg	from_buf = &from[from_cnvlen];
8661ab64890Smrg	from_savelen = from_left;
8671ab64890Smrg	to_buf = &scratchbuf[to_cnvlen];
8681ab64890Smrg	to_savelen = to_left;
8691ab64890Smrg	if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
8701ab64890Smrg				 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
8711ab64890Smrg	    *state = XLookupNone;
8721ab64890Smrg	    return 0;
8731ab64890Smrg	}
8741ab64890Smrg	from_cnvlen += (from_savelen - from_left);
8751ab64890Smrg	to_cnvlen += (to_savelen - to_left);
8761ab64890Smrg	if (from_left == 0) {
8771ab64890Smrg	    if (!to_cnvlen) {
8781ab64890Smrg		*state = XLookupNone;
8791ab64890Smrg		return 0;
8801ab64890Smrg           }
8811ab64890Smrg	   break;
8821ab64890Smrg	}
8831ab64890Smrg    }
8841ab64890Smrg
8851ab64890Smrg    if (!to || !to_len || (to_len < to_cnvlen)) {
8861ab64890Smrg       *state = XBufferOverflow;
8871ab64890Smrg    } else {
8881ab64890Smrg       memcpy(to, scratchbuf, to_cnvlen);
8891ab64890Smrg       *state = XLookupChars;
8901ab64890Smrg    }
8911ab64890Smrg    return to_cnvlen;
8921ab64890Smrg}
8931ab64890Smrg
8941ab64890SmrgPublic int
89561b2299dSmrg_Ximctstombs(XIM xim, char *from, int from_len,
89661b2299dSmrg	     char *to, int to_len, Status *state)
8971ab64890Smrg{
8981ab64890Smrg    return _Ximctsconvert(((Xim)xim)->private.proto.ctom_conv,
8991ab64890Smrg			  from, from_len, to, to_len, state);
9001ab64890Smrg}
9011ab64890Smrg
9021ab64890SmrgPublic int
9031ab64890Smrg_Ximctstowcs(
9041ab64890Smrg    XIM		 xim,
9051ab64890Smrg    char	*from,
9061ab64890Smrg    int		 from_len,
9071ab64890Smrg    wchar_t	*to,
9081ab64890Smrg    int		 to_len,
9091ab64890Smrg    Status	*state)
9101ab64890Smrg{
9111ab64890Smrg    Xim		 im = (Xim)xim;
9121ab64890Smrg    XlcConv	 conv = im->private.proto.ctow_conv;
9131ab64890Smrg    int		 from_left;
9141ab64890Smrg    int		 to_left;
9151ab64890Smrg    int		 from_savelen;
9161ab64890Smrg    int		 to_savelen;
9171ab64890Smrg    int		 from_cnvlen;
9181ab64890Smrg    int		 to_cnvlen;
9191ab64890Smrg    char	*from_buf;
9201ab64890Smrg    wchar_t	*to_buf;
9211ab64890Smrg    wchar_t	 scratchbuf[BUFSIZ];
9221ab64890Smrg    Status	 tmp_state;
9231ab64890Smrg
9241ab64890Smrg    if (!state)
9251ab64890Smrg	state = &tmp_state;
9261ab64890Smrg
9271ab64890Smrg    if (!conv || !from || !from_len) {
9281ab64890Smrg	*state = XLookupNone;
9291ab64890Smrg	return 0;
9301ab64890Smrg    }
9311ab64890Smrg
9321ab64890Smrg    /* Reset the converter.  The CompoundText at 'from' starts in
9331ab64890Smrg       initial state.  */
9341ab64890Smrg    _XlcResetConverter(conv);
93561b2299dSmrg
9361ab64890Smrg    from_left = from_len;
9371ab64890Smrg    to_left = BUFSIZ;
9381ab64890Smrg    from_cnvlen = 0;
9391ab64890Smrg    to_cnvlen = 0;
9401ab64890Smrg    for (;;) {
9411ab64890Smrg	from_buf = &from[from_cnvlen];
9421ab64890Smrg       from_savelen = from_left;
9431ab64890Smrg       to_buf = &scratchbuf[to_cnvlen];
9441ab64890Smrg       to_savelen = to_left;
9451ab64890Smrg	if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
9461ab64890Smrg				 (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
9471ab64890Smrg	    *state = XLookupNone;
9481ab64890Smrg	    return 0;
9491ab64890Smrg	}
9501ab64890Smrg	from_cnvlen += (from_savelen - from_left);
9511ab64890Smrg       to_cnvlen += (to_savelen - to_left);
9521ab64890Smrg	if (from_left == 0) {
9531ab64890Smrg           if (!to_cnvlen){
9541ab64890Smrg		*state = XLookupNone;
9551ab64890Smrg               return 0;
9561ab64890Smrg           }
9571ab64890Smrg	    break;
9581ab64890Smrg	}
9591ab64890Smrg    }
9601ab64890Smrg
9611ab64890Smrg    if (!to || !to_len || (to_len < to_cnvlen)) {
9621ab64890Smrg       *state = XBufferOverflow;
9631ab64890Smrg    } else {
9641ab64890Smrg       memcpy(to, scratchbuf, to_cnvlen * sizeof(wchar_t));
9651ab64890Smrg       *state = XLookupChars;
9661ab64890Smrg    }
9671ab64890Smrg    return to_cnvlen;
9681ab64890Smrg}
9691ab64890Smrg
9701ab64890SmrgPublic int
9711ab64890Smrg_Ximctstoutf8(
9721ab64890Smrg    XIM		 xim,
9731ab64890Smrg    char	*from,
9741ab64890Smrg    int		 from_len,
9751ab64890Smrg    char	*to,
9761ab64890Smrg    int		 to_len,
9771ab64890Smrg    Status	*state)
9781ab64890Smrg{
9791ab64890Smrg    return _Ximctsconvert(((Xim)xim)->private.proto.ctoutf8_conv,
9801ab64890Smrg			  from, from_len, to, to_len, state);
9811ab64890Smrg}
9821ab64890Smrg
9831ab64890SmrgPublic int
9841ab64890Smrg_XimProtoMbLookupString(
9851ab64890Smrg    XIC			 xic,
9861ab64890Smrg    XKeyEvent		*ev,
9871ab64890Smrg    char		*buffer,
9881ab64890Smrg    int			 bytes,
9891ab64890Smrg    KeySym		*keysym,
9901ab64890Smrg    Status		*state)
9911ab64890Smrg{
9921ab64890Smrg    Xic			 ic = (Xic)xic;
9931ab64890Smrg    Xim			 im = (Xim)ic->core.im;
9941ab64890Smrg    int			 ret;
9951ab64890Smrg    Status		 tmp_state;
9961ab64890Smrg    XimCommitInfo	 info;
9971ab64890Smrg
9981ab64890Smrg    if (!IS_SERVER_CONNECTED(im))
9991ab64890Smrg	return 0;
10001ab64890Smrg
10011ab64890Smrg    if (!state)
10021ab64890Smrg	state = &tmp_state;
10031ab64890Smrg
10041ab64890Smrg    if ((ev->type == KeyPress) && (ev->keycode == 0)) { /* Filter function */
10051ab64890Smrg	if (!(info = ic->private.proto.commit_info)) {
10061ab64890Smrg	    *state = XLookupNone;
10071ab64890Smrg	    return 0;
10081ab64890Smrg	}
10091ab64890Smrg
10101ab64890Smrg	ret = im->methods->ctstombs((XIM)im, info->string,
10111ab64890Smrg			 	info->string_len, buffer, bytes, state);
10121ab64890Smrg	if (*state == XBufferOverflow)
10131ab64890Smrg            return ret;
10141ab64890Smrg	if (keysym && (info->keysym && *(info->keysym))) {
10151ab64890Smrg	    *keysym = *(info->keysym);
10161ab64890Smrg	    if (*state == XLookupChars)
10171ab64890Smrg		*state = XLookupBoth;
10181ab64890Smrg	    else
10191ab64890Smrg		*state = XLookupKeySym;
10201ab64890Smrg	}
10211ab64890Smrg	_XimUnregCommitInfo(ic);
10221ab64890Smrg
10231ab64890Smrg    } else  if (ev->type == KeyPress) {
10241ab64890Smrg	ret = _XimLookupMBText(ic, ev, buffer, bytes, keysym, NULL);
10251ab64890Smrg	if (ret > 0) {
10261ab64890Smrg           if (ret > bytes)
10271ab64890Smrg               *state = XBufferOverflow;
10281ab64890Smrg           else if (keysym && *keysym != NoSymbol)
10291ab64890Smrg		*state = XLookupBoth;
10301ab64890Smrg	    else
10311ab64890Smrg		*state = XLookupChars;
10321ab64890Smrg	} else {
10331ab64890Smrg	    if (keysym && *keysym != NoSymbol)
10341ab64890Smrg		*state = XLookupKeySym;
10351ab64890Smrg	    else
10361ab64890Smrg		*state = XLookupNone;
10371ab64890Smrg	}
10381ab64890Smrg    } else {
10391ab64890Smrg	*state = XLookupNone;
10401ab64890Smrg	ret = 0;
10411ab64890Smrg    }
10421ab64890Smrg
10431ab64890Smrg    return ret;
10441ab64890Smrg}
10451ab64890Smrg
10461ab64890SmrgPublic int
10471ab64890Smrg_XimProtoWcLookupString(
10481ab64890Smrg    XIC			 xic,
10491ab64890Smrg    XKeyEvent		*ev,
10501ab64890Smrg    wchar_t		*buffer,
10511ab64890Smrg    int			 bytes,
10521ab64890Smrg    KeySym		*keysym,
10531ab64890Smrg    Status		*state)
10541ab64890Smrg{
10551ab64890Smrg    Xic			 ic = (Xic)xic;
10561ab64890Smrg    Xim			 im = (Xim)ic->core.im;
10571ab64890Smrg    int			 ret;
10581ab64890Smrg    Status		 tmp_state;
10591ab64890Smrg    XimCommitInfo	 info;
10601ab64890Smrg
10611ab64890Smrg    if (!IS_SERVER_CONNECTED(im))
10621ab64890Smrg	return 0;
10631ab64890Smrg
10641ab64890Smrg    if (!state)
10651ab64890Smrg	state = &tmp_state;
10661ab64890Smrg
10671ab64890Smrg    if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */
10681ab64890Smrg	if (!(info = ic->private.proto.commit_info)) {
10691ab64890Smrg           *state = XLookupNone;
10701ab64890Smrg	    return 0;
10711ab64890Smrg	}
10721ab64890Smrg
10731ab64890Smrg	ret = im->methods->ctstowcs((XIM)im, info->string,
10741ab64890Smrg			 	info->string_len, buffer, bytes, state);
10751ab64890Smrg	if (*state == XBufferOverflow)
10761ab64890Smrg           return ret;
10771ab64890Smrg	if (keysym && (info->keysym && *(info->keysym))) {
10781ab64890Smrg	    *keysym = *(info->keysym);
10791ab64890Smrg	    if (*state == XLookupChars)
10801ab64890Smrg		*state = XLookupBoth;
10811ab64890Smrg	    else
10821ab64890Smrg		*state = XLookupKeySym;
10831ab64890Smrg	}
10841ab64890Smrg	_XimUnregCommitInfo(ic);
10851ab64890Smrg
10861ab64890Smrg    } else if (ev->type == KeyPress) {
10871ab64890Smrg	ret = _XimLookupWCText(ic, ev, buffer, bytes, keysym, NULL);
10881ab64890Smrg	if (ret > 0) {
10891ab64890Smrg           if (ret > bytes)
10901ab64890Smrg               *state = XBufferOverflow;
10911ab64890Smrg           else if (keysym && *keysym != NoSymbol)
10921ab64890Smrg		*state = XLookupBoth;
10931ab64890Smrg	    else
10941ab64890Smrg		*state = XLookupChars;
10951ab64890Smrg	} else {
10961ab64890Smrg	    if (keysym && *keysym != NoSymbol)
10971ab64890Smrg		*state = XLookupKeySym;
10981ab64890Smrg	    else
10991ab64890Smrg		*state = XLookupNone;
11001ab64890Smrg	}
11011ab64890Smrg    } else {
11021ab64890Smrg	*state = XLookupNone;
11031ab64890Smrg	ret = 0;
11041ab64890Smrg    }
11051ab64890Smrg
11061ab64890Smrg    return ret;
11071ab64890Smrg}
11081ab64890Smrg
11091ab64890SmrgPublic int
11101ab64890Smrg_XimProtoUtf8LookupString(
11111ab64890Smrg    XIC			 xic,
11121ab64890Smrg    XKeyEvent		*ev,
11131ab64890Smrg    char		*buffer,
11141ab64890Smrg    int			 bytes,
11151ab64890Smrg    KeySym		*keysym,
11161ab64890Smrg    Status		*state)
11171ab64890Smrg{
11181ab64890Smrg    Xic			 ic = (Xic)xic;
11191ab64890Smrg    Xim			 im = (Xim)ic->core.im;
11201ab64890Smrg    int			 ret;
11211ab64890Smrg    Status		 tmp_state;
11221ab64890Smrg    XimCommitInfo	 info;
11231ab64890Smrg
11241ab64890Smrg    if (!IS_SERVER_CONNECTED(im))
11251ab64890Smrg	return 0;
11261ab64890Smrg
11271ab64890Smrg    if (!state)
11281ab64890Smrg	state = &tmp_state;
11291ab64890Smrg
11301ab64890Smrg    if (ev->type == KeyPress && ev->keycode == 0) { /* Filter function */
11311ab64890Smrg	if (!(info = ic->private.proto.commit_info)) {
11321ab64890Smrg           *state = XLookupNone;
11331ab64890Smrg	    return 0;
11341ab64890Smrg	}
11351ab64890Smrg
11361ab64890Smrg	ret = im->methods->ctstoutf8((XIM)im, info->string,
11371ab64890Smrg			 	info->string_len, buffer, bytes, state);
11381ab64890Smrg	if (*state == XBufferOverflow)
11391ab64890Smrg           return ret;
11401ab64890Smrg	if (keysym && (info->keysym && *(info->keysym))) {
11411ab64890Smrg	    *keysym = *(info->keysym);
11421ab64890Smrg	    if (*state == XLookupChars)
11431ab64890Smrg		*state = XLookupBoth;
11441ab64890Smrg	    else
11451ab64890Smrg		*state = XLookupKeySym;
11461ab64890Smrg	}
11471ab64890Smrg	_XimUnregCommitInfo(ic);
11481ab64890Smrg
11491ab64890Smrg    } else if (ev->type == KeyPress) {
11501ab64890Smrg	ret = _XimLookupUTF8Text(ic, ev, buffer, bytes, keysym, NULL);
11511ab64890Smrg	if (ret > 0) {
11521ab64890Smrg           if (ret > bytes)
11531ab64890Smrg               *state = XBufferOverflow;
11541ab64890Smrg           else if (keysym && *keysym != NoSymbol)
11551ab64890Smrg		*state = XLookupBoth;
11561ab64890Smrg	    else
11571ab64890Smrg		*state = XLookupChars;
11581ab64890Smrg	} else {
11591ab64890Smrg	    if (keysym && *keysym != NoSymbol)
11601ab64890Smrg		*state = XLookupKeySym;
11611ab64890Smrg	    else
11621ab64890Smrg		*state = XLookupNone;
11631ab64890Smrg	}
11641ab64890Smrg    } else {
11651ab64890Smrg	*state = XLookupNone;
11661ab64890Smrg	ret = 0;
11671ab64890Smrg    }
11681ab64890Smrg
11691ab64890Smrg    return ret;
11701ab64890Smrg}
1171