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