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