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
371ab64890Smrg/*
381ab64890Smrg * index of extensions
391ab64890Smrg */
401ab64890Smrg
411ab64890Smrg#define	XIM_EXT_SET_EVENT_MASK_IDX	0
421ab64890Smrg#ifdef EXT_FORWARD
431ab64890Smrg#define	XIM_EXT_FORWARD_KEYEVENT_IDX	1
441ab64890Smrg#endif
451ab64890Smrg#ifdef EXT_MOVE
461ab64890Smrg#define	XIM_EXT_MOVE_IDX		2
471ab64890Smrg#endif
481ab64890Smrg
491ab64890Smrgtypedef struct	_XIM_QueryExtRec {
501ab64890Smrg    Bool	 is_support;
511ab64890Smrg    const char	*name;
521ab64890Smrg    int		 name_len;
531ab64890Smrg    CARD16	 major_opcode;
541ab64890Smrg    CARD16	 minor_opcode;
551ab64890Smrg    int		 idx;
561ab64890Smrg} XIM_QueryExtRec;
571ab64890Smrg
58eb411b4bSmrgstatic XIM_QueryExtRec	extensions[] = {
591ab64890Smrg	{False, "XIM_EXT_SET_EVENT_MASK", 0, 0, 0,
6061b2299dSmrg					XIM_EXT_SET_EVENT_MASK_IDX},
611ab64890Smrg#ifdef EXT_FORWARD
621ab64890Smrg	{False, "XIM_EXT_FORWARD_KEYEVENT", 0, 0, 0,
631ab64890Smrg					XIM_EXT_FORWARD_KEYEVENT_IDX},
641ab64890Smrg#endif
651ab64890Smrg#ifdef EXT_MOVE
661ab64890Smrg	{False, "XIM_EXT_MOVE", 0, 0, 0, XIM_EXT_MOVE_IDX},
671ab64890Smrg#endif
681ab64890Smrg	{False, NULL, 0, 0, 0, 0}		/* dummy */
691ab64890Smrg};
701ab64890Smrg
71eb411b4bSmrgstatic int
721ab64890Smrg_XimIsSupportExt(
731ab64890Smrg    int		 idx)
741ab64890Smrg{
751ab64890Smrg    register int i;
761ab64890Smrg    int		 n = XIMNumber(extensions) - 1;
771ab64890Smrg
781ab64890Smrg    for (i = 0; i < n; i++) {
791ab64890Smrg	if (extensions[i].idx == idx) {
801ab64890Smrg	    if (extensions[i].is_support)
811ab64890Smrg		return i;
821ab64890Smrg	    else
831ab64890Smrg		break;
841ab64890Smrg	}
851ab64890Smrg    }
861ab64890Smrg    return -1;
871ab64890Smrg}
881ab64890Smrg
89eb411b4bSmrgstatic Bool
901ab64890Smrg_XimProcExtSetEventMask(
911ab64890Smrg    Xim		 im,
921ab64890Smrg    Xic		 ic,
931ab64890Smrg    XPointer	 buf)
941ab64890Smrg{
951ab64890Smrg    EVENTMASK	*buf_l = (EVENTMASK *)buf;
961ab64890Smrg    EVENTMASK	 select_mask = _XimGetWindowEventmask(ic);
971ab64890Smrg
981ab64890Smrg    ic->private.proto.filter_event_mask      = buf_l[0];
991ab64890Smrg    ic->private.proto.intercept_event_mask   = buf_l[1];
1001ab64890Smrg    ic->private.proto.select_event_mask      = buf_l[2];
1011ab64890Smrg    ic->private.proto.forward_event_mask     = buf_l[3];
1021ab64890Smrg    ic->private.proto.synchronous_event_mask = buf_l[4];
1031ab64890Smrg
1041ab64890Smrg    select_mask &= ~ic->private.proto.intercept_event_mask;
1051ab64890Smrg						/* deselected event mask */
1061ab64890Smrg    select_mask |= ic->private.proto.select_event_mask;
1071ab64890Smrg						/* selected event mask */
1081ab64890Smrg    XSelectInput(im->core.display, ic->core.focus_window, select_mask);
1091ab64890Smrg    _XimReregisterFilter(ic);
1101ab64890Smrg
1111ab64890Smrg    if (!(_XimProcSyncReply(im, ic)))
1121ab64890Smrg	return False;
1131ab64890Smrg    return True;
1141ab64890Smrg}
1151ab64890Smrg
116eb411b4bSmrgstatic Bool
1171ab64890Smrg_XimExtSetEventMaskCallback(
1181ab64890Smrg    Xim		 xim,
1191ab64890Smrg    INT16	 len,
1201ab64890Smrg    XPointer	 data,
1211ab64890Smrg    XPointer	 call_data)
1221ab64890Smrg{
1231ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
1241ab64890Smrg    XIMID	 imid = buf_s[0];
1251ab64890Smrg    XICID	 icid = buf_s[1];
1261ab64890Smrg    Xim		 im = (Xim)call_data;
1271ab64890Smrg    Xic		 ic;
1281ab64890Smrg
1291ab64890Smrg    if ((imid == im->private.proto.imid)
1301ab64890Smrg     && (ic = _XimICOfXICID(im, icid))) {
1311ab64890Smrg	(void)_XimProcExtSetEventMask(im, ic, (XPointer)&buf_s[2]);
1321ab64890Smrg	return True;
1331ab64890Smrg    }
1341ab64890Smrg    return False;
1351ab64890Smrg}
1361ab64890Smrg
1371ab64890Smrg#ifdef EXT_FORWARD
138eb411b4bSmrgstatic Bool
1391ab64890Smrg_XimProcExtForwardKeyEvent(
1401ab64890Smrg    Xim		 im,
1411ab64890Smrg    Xic		 ic,
1421ab64890Smrg    XPointer	 buf)
1431ab64890Smrg{
1441ab64890Smrg    CARD8	*buf_b = (CARD8 *)buf;
1451ab64890Smrg    CARD16	*buf_s = (CARD16 *)buf;
1461ab64890Smrg    CARD32	*buf_l = (CARD32 *)buf;
1471ab64890Smrg    XEvent	 ev;
1481ab64890Smrg    XKeyEvent	*kev = (XKeyEvent *)&ev;
1491ab64890Smrg
1501ab64890Smrg    bzero(&ev, sizeof(XEvent));
1511ab64890Smrg    kev->send_event	= False;
1521ab64890Smrg    kev->display	= im->core.display;
1531ab64890Smrg    kev->serial		= buf_s[1];		/* sequence number */
1541ab64890Smrg    kev->type		= buf_b[4] & 0x7f;	/* xEvent.u.u.type */
1551ab64890Smrg    kev->keycode	= buf_b[5];		/* Keycode */
1561ab64890Smrg    kev->state		= buf_s[3];		/* state */
1571ab64890Smrg    kev->time		= buf_l[2];		/* time */
1581ab64890Smrg
1591ab64890Smrg    XPutBackEvent(im->core.display, &ev);
1601ab64890Smrg
1611ab64890Smrg    _XimRespSyncReply(ic, buf_s[0]);
162eb411b4bSmrg    MARK_FABRICATED(im);
1631ab64890Smrg
1641ab64890Smrg    return True;
1651ab64890Smrg}
1661ab64890Smrg
167eb411b4bSmrgstatic Bool
1681ab64890Smrg_XimExtForwardKeyEventCallback(
1691ab64890Smrg    Xim		 xim,
1701ab64890Smrg    INT16	 len,
1711ab64890Smrg    XPointer	 data,
1721ab64890Smrg    XPointer	 call_data)
1731ab64890Smrg{
1741ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
1751ab64890Smrg    XIMID	 imid = buf_s[0];
1761ab64890Smrg    XICID	 icid = buf_s[1];
1771ab64890Smrg    Xim		 im = (Xim)call_data;
1781ab64890Smrg    Xic		 ic;
1791ab64890Smrg
1801ab64890Smrg    if ((imid == im->private.proto.imid)
1811ab64890Smrg     && (ic = _XimICOfXICID(im, icid))) {
1821ab64890Smrg	(void)_XimProcExtForwardKeyEvent(im, ic, (XPointer)&buf_s[2]);
1831ab64890Smrg	return True;
1841ab64890Smrg    }
1851ab64890Smrg    return False;
1861ab64890Smrg}
1871ab64890Smrg
188eb411b4bSmrgstatic Bool
1891ab64890Smrg_XimExtForwardKeyEventCheck(
1901ab64890Smrg    Xim          im,
1911ab64890Smrg    INT16        len,
1921ab64890Smrg    XPointer	 data,
1931ab64890Smrg    XPointer     arg)
1941ab64890Smrg{
1951ab64890Smrg    Xic		 ic  = (Xic)arg;
1961ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
1971ab64890Smrg    CARD8	 major_opcode = *((CARD8 *)data);
1981ab64890Smrg    CARD8	 minor_opcode = *((CARD8 *)data + 1);
1991ab64890Smrg    XIMID	 imid = buf_s[0];
2001ab64890Smrg    XICID	 icid = buf_s[1];
2011ab64890Smrg
2021ab64890Smrg    if ((major_opcode == XIM_SYNC_REPLY)
2031ab64890Smrg     && (minor_opcode == 0)
2041ab64890Smrg     && (imid == im->private.proto.imid)
2051ab64890Smrg     && (icid == ic->private.proto.icid))
2061ab64890Smrg    if ((major_opcode == XIM_ERROR)
2071ab64890Smrg     && (minor_opcode == 0)
2081ab64890Smrg     && (buf_s[2] & XIM_IMID_VALID)
2091ab64890Smrg     && (imid == im->private.proto.imid)
2101ab64890Smrg     && (buf_s[2] & XIM_ICID_VALID)
2111ab64890Smrg     && (icid == ic->private.proto.icid))
2121ab64890Smrg	return True;
2131ab64890Smrg    return False;
2141ab64890Smrg}
2151ab64890Smrg
216eb411b4bSmrgBool
2171ab64890Smrg_XimExtForwardKeyEvent(
2181ab64890Smrg    Xic		 ic,
2191ab64890Smrg    XKeyEvent	*ev,
2201ab64890Smrg    Bool	 sync)
2211ab64890Smrg{
2221ab64890Smrg    Xim		 im = (Xim) ic->core.im;
2231ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
2241ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
22561b2299dSmrg    CARD8	*buf_b = &buf[XIM_HEADER_SIZE];
2261ab64890Smrg    CARD16	*buf_s = (CARD16 *)buf_b;
2271ab64890Smrg    CARD32	*buf_l = (CARD32 *)buf_b;
2281ab64890Smrg    CARD32	 reply32[BUFSIZE/4];
2291ab64890Smrg    char	*reply = (char *)reply32;
2301ab64890Smrg    XPointer	preply;
2311ab64890Smrg    int		buf_size;
2321ab64890Smrg    int		ret_code;
2331ab64890Smrg    INT16	len;
2341ab64890Smrg    int		idx;
2351ab64890Smrg
2361ab64890Smrg    if ((idx = _XimIsSupportExt(XIM_EXT_FORWARD_KEYEVENT_IDX)) < 0)
2371ab64890Smrg	return False;
2381ab64890Smrg
2391ab64890Smrg    buf_s[0] = im->private.proto.imid;		/* imid */
2401ab64890Smrg    buf_s[1] = ic->private.proto.icid;		/* icid */
2411ab64890Smrg    buf_s[2] = sync ? XimSYNCHRONUS : 0;	/* flag */
2421ab64890Smrg    buf_s[3] = (CARD16)(((XAnyEvent *)ev)->serial & ((unsigned long) 0xffff));
2431ab64890Smrg						/* sequence number */
2441ab64890Smrg    buf_b[8] = ev->type;			/* xEvent.u.u.type */
2451ab64890Smrg    buf_b[9] = ev->keycode;			/* keycode */
2461ab64890Smrg    buf_s[5] = ev->state;			/* state */
2471ab64890Smrg    buf_l[3] = ev->time;			/* time */
2481ab64890Smrg    len = sizeof(CARD16)			/* sizeof imid */
2491ab64890Smrg	+ sizeof(CARD16)			/* sizeof icid */
2501ab64890Smrg	+ sizeof(BITMASK16)			/* sizeof flag */
2511ab64890Smrg	+ sizeof(CARD16)			/* sizeof sequence number */
2521ab64890Smrg	+ sizeof(BYTE)				/* sizeof xEvent.u.u.type */
2531ab64890Smrg	+ sizeof(BYTE)				/* sizeof keycode */
2541ab64890Smrg	+ sizeof(CARD16)			/* sizeof state */
2551ab64890Smrg	+ sizeof(CARD32);			/* sizeof time */
2561ab64890Smrg
2571ab64890Smrg    _XimSetHeader((XPointer)buf,
2581ab64890Smrg		extensions[idx].major_opcode,
2591ab64890Smrg		extensions[idx].minor_opcode, &len);
2601ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
2611ab64890Smrg	return False;
2621ab64890Smrg    _XimFlush(im);
2631ab64890Smrg    if (sync) {
2641ab64890Smrg    	buf_size = BUFSIZE;
2651ab64890Smrg    	ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
2661ab64890Smrg    				_XimExtForwardKeyEventCheck, (XPointer)ic);
2671ab64890Smrg    	if(ret_code == XIM_TRUE) {
2681ab64890Smrg    	    preply = reply;
2691ab64890Smrg    	} else if(ret_code == XIM_OVERFLOW) {
2701ab64890Smrg    	    if(len <= 0) {
2711ab64890Smrg    		preply = reply;
2721ab64890Smrg    	    } else {
2731ab64890Smrg    		buf_sizex = len;
274818534a1Smrg		preply = Xmalloc(buf_size);
2751ab64890Smrg    		ret_code = _XimRead(im, &len, preply, buf_size,
2761ab64890Smrg    				_XimExtForwardKeyEventCheck, (XPointer)ic);
2771ab64890Smrg    		if(ret_code != XIM_TRUE) {
2781ab64890Smrg		    Xfree(preply);
2791ab64890Smrg    		    return False;
2801ab64890Smrg		}
2811ab64890Smrg    	    }
2821ab64890Smrg    	} else
2831ab64890Smrg	    return False;
2841ab64890Smrg    	buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
2851ab64890Smrg    	if (*((CARD8 *)preply) == XIM_ERROR) {
2861ab64890Smrg	    _XimProcError(im, 0, (XPointer)&buf_s[3]);
2871ab64890Smrg    	    if(reply != preply)
2881ab64890Smrg    		Xfree(preply);
2891ab64890Smrg	    return False;
2901ab64890Smrg	}
2911ab64890Smrg    	if(reply != preply)
2921ab64890Smrg    	    Xfree(preply);
2931ab64890Smrg    }
2941ab64890Smrg    return True;
2951ab64890Smrg}
2961ab64890Smrg#endif /* EXT_FORWARD */
2971ab64890Smrg
298eb411b4bSmrgstatic int
2991ab64890Smrg_XimCheckExtensionListSize(void)
3001ab64890Smrg{
3011ab64890Smrg    register int i;
3021ab64890Smrg    int		 len;
3031ab64890Smrg    int		 total = 0;
3041ab64890Smrg    int		 n = XIMNumber(extensions) - 1;
3051ab64890Smrg
3061ab64890Smrg    for (i = 0; i < n; i++) {
3071ab64890Smrg	len = strlen(extensions[i].name);
3081ab64890Smrg	extensions[i].name_len = len;
3091ab64890Smrg	len += sizeof(BYTE);
3101ab64890Smrg	total += len;
3111ab64890Smrg    }
3121ab64890Smrg    return total;
3131ab64890Smrg}
3141ab64890Smrg
315eb411b4bSmrgstatic void
3161ab64890Smrg_XimSetExtensionList(
3171ab64890Smrg    CARD8	*buf)
3181ab64890Smrg{
3191ab64890Smrg    register int i;
3201ab64890Smrg    int		 len;
3211ab64890Smrg    int		 n = XIMNumber(extensions) - 1;
3221ab64890Smrg
3231ab64890Smrg    for (i = 0; i < n; i++) {
3241ab64890Smrg	len = extensions[i].name_len;
3251ab64890Smrg	buf[0] = (BYTE)len;
3261ab64890Smrg	(void)strcpy((char *)&buf[1], extensions[i].name);
3271ab64890Smrg	len += sizeof(BYTE);
3281ab64890Smrg	buf += len;
3291ab64890Smrg    }
3301ab64890Smrg    return;
3311ab64890Smrg}
3321ab64890Smrg
333eb411b4bSmrgstatic unsigned int
3341ab64890Smrg_XimCountNumberOfExtension(
3351ab64890Smrg    INT16	 total,
3361ab64890Smrg    CARD8	*ext)
3371ab64890Smrg{
3381ab64890Smrg    unsigned int n;
3391ab64890Smrg    INT16	 len;
3401ab64890Smrg    INT16	 min_len = sizeof(CARD8)
3411ab64890Smrg			 + sizeof(CARD8)
3421ab64890Smrg			 + sizeof(INT16);
3431ab64890Smrg
3441ab64890Smrg    n = 0;
3451ab64890Smrg    while (total > min_len) {
3461ab64890Smrg	len = *((INT16 *)(&ext[2]));
3471ab64890Smrg	len += (min_len + XIM_PAD(len));
3481ab64890Smrg	total -= len;
3491ab64890Smrg	ext += len;
3501ab64890Smrg	n++;
3511ab64890Smrg    }
3521ab64890Smrg    return n;
3531ab64890Smrg}
3541ab64890Smrg
355eb411b4bSmrgstatic Bool
3561ab64890Smrg_XimParseExtensionList(
3571ab64890Smrg    Xim			 im,
3581ab64890Smrg    CARD16		*data)
3591ab64890Smrg{
3601ab64890Smrg    int			 num = XIMNumber(extensions) - 1;
3611ab64890Smrg    unsigned int	 n;
3621ab64890Smrg    CARD8		*buf;
3631ab64890Smrg    register int	 i;
3641ab64890Smrg    register int	 j;
3651ab64890Smrg    INT16		 len;
3661ab64890Smrg
3671ab64890Smrg    if (!(n = _XimCountNumberOfExtension(data[0], (CARD8 *)&data[1])))
3681ab64890Smrg	return True;
3691ab64890Smrg
3702d67cb4fSmrg    buf = (CARD8 *)&data[1];
3711ab64890Smrg    for (i = 0; i < n; i++) {
3721ab64890Smrg	len = *((INT16 *)(&buf[2]));
3731ab64890Smrg	for (j = 0; j < num; j++) {
3741ab64890Smrg	    if (!(strncmp(extensions[j].name, (char *)&buf[4], len))) {
3751ab64890Smrg		extensions[j].major_opcode = buf[0];
3761ab64890Smrg		extensions[j].minor_opcode = buf[1];
3771ab64890Smrg		extensions[j].is_support   = True;
3781ab64890Smrg		break;
3791ab64890Smrg	    }
3801ab64890Smrg	}
3811ab64890Smrg	len += sizeof(CARD8)		/* sizeof major_opcode */
3821ab64890Smrg	     + sizeof(CARD8)		/* sizeof minor_opcode */
3831ab64890Smrg	     + sizeof(INT16)		/* sizeof length */
3841ab64890Smrg	     + XIM_PAD(len);		/* sizeof pad */
38561b2299dSmrg	buf += len;
3861ab64890Smrg    }
3871ab64890Smrg
3881ab64890Smrg    return True;
3891ab64890Smrg}
3901ab64890Smrg
391eb411b4bSmrgstatic Bool
3921ab64890Smrg_XimQueryExtensionCheck(
3931ab64890Smrg    Xim          im,
3941ab64890Smrg    INT16        len,
3951ab64890Smrg    XPointer	 data,
3961ab64890Smrg    XPointer     arg)
3971ab64890Smrg{
3981ab64890Smrg    CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
3991ab64890Smrg    CARD8	 major_opcode = *((CARD8 *)data);
4001ab64890Smrg    CARD8	 minor_opcode = *((CARD8 *)data + 1);
4011ab64890Smrg    XIMID	 imid = buf_s[0];
4021ab64890Smrg
4031ab64890Smrg    if ((major_opcode == XIM_QUERY_EXTENSION_REPLY)
4041ab64890Smrg     && (minor_opcode == 0)
4051ab64890Smrg     && (imid == im->private.proto.imid))
4061ab64890Smrg	return True;
4071ab64890Smrg    if ((major_opcode == XIM_ERROR)
4081ab64890Smrg     && (minor_opcode == 0)
4091ab64890Smrg     && (buf_s[2] & XIM_IMID_VALID)
4101ab64890Smrg     && (imid == im->private.proto.imid))
4111ab64890Smrg	return True;
4121ab64890Smrg    return False;
4131ab64890Smrg}
4141ab64890Smrg
415eb411b4bSmrgBool
4161ab64890Smrg_XimExtension(
4171ab64890Smrg    Xim		 im)
4181ab64890Smrg{
4191ab64890Smrg    CARD8	*buf;
4201ab64890Smrg    CARD16	*buf_s;
4211ab64890Smrg    int		 buf_len;
4221ab64890Smrg    INT16	 len;
4231ab64890Smrg    CARD32	 reply32[BUFSIZE/4];
4241ab64890Smrg    char	*reply = (char *)reply32;
4251ab64890Smrg    XPointer	 preply;
4261ab64890Smrg    int		 buf_size;
4271ab64890Smrg    int		 ret_code;
4281ab64890Smrg    int		 idx;
4291ab64890Smrg
4301ab64890Smrg    if (!(len = _XimCheckExtensionListSize()))
4311ab64890Smrg	return True;
4321ab64890Smrg
4331ab64890Smrg    buf_len = XIM_HEADER_SIZE
4341ab64890Smrg	    + sizeof(CARD16)
4351ab64890Smrg	    + sizeof(INT16)
4361ab64890Smrg	    + len
4371ab64890Smrg	    + XIM_PAD(len);
4381ab64890Smrg
439818534a1Smrg    if (!(buf = Xmalloc(buf_len)))
4401ab64890Smrg	return False;
4411ab64890Smrg    buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
4421ab64890Smrg
4431ab64890Smrg    buf_s[0] = im->private.proto.imid;	/* imid */
4441ab64890Smrg    buf_s[1] = len;			/* length of Extensions */
4451ab64890Smrg    _XimSetExtensionList((CARD8 *)&buf_s[2]);
4461ab64890Smrg					/* extensions supported */
4471ab64890Smrg    XIM_SET_PAD(&buf_s[2], len);	/* pad */
4481ab64890Smrg    len += sizeof(CARD16)		/* sizeof imid */
4491ab64890Smrg	 + sizeof(INT16);		/* sizeof length of extensions */
4501ab64890Smrg
4511ab64890Smrg    _XimSetHeader((XPointer)buf, XIM_QUERY_EXTENSION, 0, &len);
4521ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf))) {
4531ab64890Smrg        XFree(buf);
4541ab64890Smrg	return False;
4551ab64890Smrg    }
4561ab64890Smrg    XFree(buf);
4571ab64890Smrg    _XimFlush(im);
4581ab64890Smrg    buf_size = BUFSIZE;
4591ab64890Smrg    ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
4601ab64890Smrg    					_XimQueryExtensionCheck, 0);
4611ab64890Smrg    if(ret_code == XIM_TRUE) {
4621ab64890Smrg    	preply = reply;
4631ab64890Smrg    } else if(ret_code == XIM_OVERFLOW) {
4641ab64890Smrg    	if(len <= 0) {
4651ab64890Smrg    	    preply = reply;
4661ab64890Smrg    	} else {
4671ab64890Smrg    	    buf_size = len;
468818534a1Smrg	    preply = Xmalloc(buf_size);
4693b4ba46cSmrg    	    ret_code = _XimRead(im, &len, preply, buf_size,
4701ab64890Smrg    					_XimQueryExtensionCheck, 0);
4711ab64890Smrg    	    if(ret_code != XIM_TRUE) {
4721ab64890Smrg		Xfree(preply);
4731ab64890Smrg    		return False;
4741ab64890Smrg	    }
4751ab64890Smrg    	}
4761ab64890Smrg    } else
4771ab64890Smrg	return False;
4781ab64890Smrg    buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
4791ab64890Smrg    if (*((CARD8 *)preply) == XIM_ERROR) {
4801ab64890Smrg	_XimProcError(im, 0, (XPointer)&buf_s[3]);
4811ab64890Smrg    	if(reply != preply)
4821ab64890Smrg    	    Xfree(preply);
4831ab64890Smrg	return False;
4841ab64890Smrg    }
4851ab64890Smrg
4861ab64890Smrg    if (!(_XimParseExtensionList(im, &buf_s[1]))) {
4871ab64890Smrg    	if(reply != preply)
4881ab64890Smrg    	    Xfree(preply);
4891ab64890Smrg	return False;
4901ab64890Smrg    }
4911ab64890Smrg    if(reply != preply)
4921ab64890Smrg    	Xfree(preply);
4931ab64890Smrg
4941ab64890Smrg    if ((idx = _XimIsSupportExt(XIM_EXT_SET_EVENT_MASK_IDX)) >= 0)
4951ab64890Smrg	_XimRegProtoIntrCallback(im,
4961ab64890Smrg	 	extensions[idx].major_opcode,
4971ab64890Smrg	 	extensions[idx].minor_opcode,
4981ab64890Smrg		_XimExtSetEventMaskCallback, (XPointer)im);
4991ab64890Smrg#ifdef EXT_FORWARD
5001ab64890Smrg    if ((idx = _XimIsSupportExt(XIM_EXT_FORWARD_KEYEVENT_IDX)) >= 0)
5011ab64890Smrg	_XimRegProtoIntrCallback(im,
5021ab64890Smrg		extensions[idx].major_opcode,
5031ab64890Smrg		extensions[idx].minor_opcode,
5041ab64890Smrg		_XimExtForwardKeyEventCallback, (XPointer)im);
5051ab64890Smrg#endif
5061ab64890Smrg
5071ab64890Smrg    return True;
5081ab64890Smrg}
5091ab64890Smrg
5101ab64890Smrg#ifdef EXT_MOVE
5111ab64890Smrg/* flag of ExtenArgCheck */
5121ab64890Smrg#define	EXT_XNSPOTLOCATION	(1L<<0)
5131ab64890Smrg
5141ab64890Smrg/* macro for ExtenArgCheck */
5151ab64890Smrg#define SET_EXT_XNSPOTLOCATION(flag) (flag |= EXT_XNSPOTLOCATION)
5161ab64890Smrg#define IS_EXT_XNSPOTLOCATION(flag)  (flag & EXT_XNSPOTLOCATION)
5171ab64890Smrg
5181ab64890Smrg/* length of XPoint attribute */
5191ab64890Smrg#define	XIM_Xpoint_length	12
5201ab64890Smrg
521eb411b4bSmrgstatic Bool
5221ab64890Smrg_XimExtMove(
5231ab64890Smrg    Xim		 im,
5241ab64890Smrg    Xic		 ic,
5251ab64890Smrg    CARD16	 x,
5261ab64890Smrg    CARD16	 y)
5271ab64890Smrg{
5281ab64890Smrg    CARD32	 buf32[BUFSIZE/4];
5291ab64890Smrg    CARD8	*buf = (CARD8 *)buf32;
5301ab64890Smrg    CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
5311ab64890Smrg    INT16	 len;
5321ab64890Smrg    int		idx;
5331ab64890Smrg
5341ab64890Smrg    if ((idx = _XimIsSupportExt(XIM_EXT_MOVE_IDX)) < 0)
5351ab64890Smrg	return False;
5361ab64890Smrg
5371ab64890Smrg    buf_s[0] = im->private.proto.imid;	/* imid */
5381ab64890Smrg    buf_s[1] = ic->private.proto.icid;	/* icid */
5391ab64890Smrg    buf_s[2] = x;			/* X */
5401ab64890Smrg    buf_s[3] = y;			/* Y */
5411ab64890Smrg    len = sizeof(CARD16)		/* sizeof imid */
5421ab64890Smrg	+ sizeof(CARD16)		/* sizeof icid */
5431ab64890Smrg	+ sizeof(INT16)			/* sizeof X */
5441ab64890Smrg	+ sizeof(INT16);		/* sizeof Y */
5451ab64890Smrg
5461ab64890Smrg    _XimSetHeader((XPointer)buf, extensions[idx].major_opcode,
5471ab64890Smrg			extensions[idx].minor_opcode, &len);
5481ab64890Smrg    if (!(_XimWrite(im, len, (XPointer)buf)))
5491ab64890Smrg	return False;
5501ab64890Smrg    _XimFlush(im);
5511ab64890Smrg    return True;
5521ab64890Smrg}
5531ab64890Smrg
554eb411b4bSmrgBITMASK32
5551ab64890Smrg_XimExtenArgCheck(
5561ab64890Smrg    XIMArg	*arg)
5571ab64890Smrg{
5581ab64890Smrg    CARD32	flag = 0L;
5591ab64890Smrg    if (!strcmp(arg->name, XNSpotLocation))
5601ab64890Smrg	SET_EXT_XNSPOTLOCATION(flag);
5611ab64890Smrg    return flag;
5621ab64890Smrg}
5631ab64890Smrg
564eb411b4bSmrgBool
5651ab64890Smrg_XimExtenMove(
5661ab64890Smrg    Xim		 im,
5671ab64890Smrg    Xic		 ic,
5681ab64890Smrg    CARD32	 flag,
5691ab64890Smrg    CARD16	*buf,
5701ab64890Smrg    INT16	 length)
5711ab64890Smrg{
5721ab64890Smrg    if ((IS_EXT_XNSPOTLOCATION(flag)) && (length == XIM_Xpoint_length))
5731ab64890Smrg	return _XimExtMove(im, ic, buf[4], buf[5]);
5741ab64890Smrg    return False;
5751ab64890Smrg}
5761ab64890Smrg#endif /* EXT_MOVE */
577