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 "Xutil.h"
351ab64890Smrg#include "Xlcint.h"
361ab64890Smrg#include "Ximint.h"
371ab64890Smrg
38eb411b4bSmrgstatic long
391ab64890Smrg_XimTriggerCheck(
401ab64890Smrg    Xim			 im,
411ab64890Smrg    XKeyEvent		*ev,
421ab64890Smrg    INT32		 len,
431ab64890Smrg    CARD32		*keylist)
441ab64890Smrg{
451ab64890Smrg    register long	 i;
461ab64890Smrg    KeySym	 	 keysym;
471ab64890Smrg    CARD32	 	 buf32[BUFSIZE/4];
481ab64890Smrg    char	 	*buf = (char *)buf32;
491ab64890Smrg    int			 modifier;
501ab64890Smrg    int			 modifier_mask;
511ab64890Smrg    CARD32		 min_len = sizeof(CARD32)   /* sizeof keysym */
521ab64890Smrg				 + sizeof(CARD32)   /* sizeof modifier */
531ab64890Smrg				 + sizeof(CARD32);  /* sizeof modifier mask */
541ab64890Smrg
551ab64890Smrg    XLookupString(ev, buf, BUFSIZE, &keysym, NULL);
561ab64890Smrg    if (!keysym)
571ab64890Smrg	return -1;
581ab64890Smrg
591ab64890Smrg    for (i = 0; len >= min_len; i += 3, len -= min_len) {
601ab64890Smrg	modifier      = keylist[i + 1];
611ab64890Smrg	modifier_mask = keylist[i + 2];
621ab64890Smrg	if (((KeySym)keylist[i] == keysym)
631ab64890Smrg	 && ((ev->state & modifier_mask) == modifier))
641ab64890Smrg	    return i;
651ab64890Smrg    }
661ab64890Smrg    return -1;
671ab64890Smrg}
681ab64890Smrg
69eb411b4bSmrgstatic long
701ab64890Smrg_XimTriggerOnCheck(
711ab64890Smrg    Xim		 im,
721ab64890Smrg    XKeyEvent	*ev)
731ab64890Smrg{
741ab64890Smrg    return _XimTriggerCheck(im, ev, (INT32)im->private.proto.im_onkeylist[0],
751ab64890Smrg					&im->private.proto.im_onkeylist[1]);
761ab64890Smrg}
771ab64890Smrg
78eb411b4bSmrgstatic long
791ab64890Smrg_XimTriggerOffCheck(
801ab64890Smrg    Xim		 im,
811ab64890Smrg    XKeyEvent	*ev)
821ab64890Smrg{
831ab64890Smrg    return _XimTriggerCheck(im, ev, (INT32)im->private.proto.im_offkeylist[0],
841ab64890Smrg					&im->private.proto.im_offkeylist[1]);
851ab64890Smrg}
861ab64890Smrg
87eb411b4bSmrgstatic Bool
881ab64890Smrg_XimOnKeysCheck(
891ab64890Smrg    Xic		 ic,
901ab64890Smrg    XKeyEvent	*ev)
911ab64890Smrg{
921ab64890Smrg    Xim		 im = (Xim)ic->core.im;
931ab64890Smrg    long	 idx;
941ab64890Smrg
951ab64890Smrg    if (IS_DYNAMIC_EVENT_FLOW(ic->core.im) &&
961ab64890Smrg	    im->private.proto.im_onkeylist &&
971ab64890Smrg	    im->private.proto.im_onkeylist[0]) {
981ab64890Smrg	if ((idx = _XimTriggerOnCheck(im, ev)) >= 0) {
991ab64890Smrg	    (void)_XimTriggerNotify(im, ic, 0, (CARD32)idx); /* Trigger on */
1001ab64890Smrg	    return True;
1011ab64890Smrg	}
1021ab64890Smrg    }
1031ab64890Smrg    return False;
1041ab64890Smrg}
1051ab64890Smrg
106eb411b4bSmrgstatic Bool
1071ab64890Smrg_XimOffKeysCheck(
1081ab64890Smrg    Xic		 ic,
1091ab64890Smrg    XKeyEvent	*ev)
1101ab64890Smrg{
1111ab64890Smrg    Xim		 im = (Xim)ic->core.im;
1121ab64890Smrg    long	 idx;
1131ab64890Smrg
1141ab64890Smrg    if (IS_DYNAMIC_EVENT_FLOW(ic->core.im) &&
1151ab64890Smrg	    im->private.proto.im_offkeylist &&
1161ab64890Smrg	    im->private.proto.im_offkeylist[0]) {
1171ab64890Smrg	if ((idx = _XimTriggerOffCheck(im, ev)) >= 0) {
1181ab64890Smrg	    _XimTriggerNotify(im, ic, 1, (CARD32)idx); /* Trigger off */
1191ab64890Smrg	    return True;
1201ab64890Smrg	}
1211ab64890Smrg    }
1221ab64890Smrg    return False;
1231ab64890Smrg}
1241ab64890Smrg
125eb411b4bSmrgstatic void
1261ab64890Smrg_XimPendingFilter(
1271ab64890Smrg    Xic	 	 ic)
1281ab64890Smrg{
1291ab64890Smrg    Xim          im = (Xim)ic->core.im;
1301ab64890Smrg
131eb411b4bSmrg    if (IS_NEED_SYNC_REPLY(im)) {
1321ab64890Smrg	(void)_XimProcSyncReply(im, ic);
133eb411b4bSmrg	UNMARK_NEED_SYNC_REPLY(im);
1341ab64890Smrg    }
1351ab64890Smrg    return;
1361ab64890Smrg}
1371ab64890Smrg
138eb411b4bSmrgstatic Bool
1391ab64890Smrg_XimProtoKeypressFilter(
1401ab64890Smrg    Xic		 ic,
1413b4ba46cSmrg    XKeyEvent	*ev,
1423b4ba46cSmrg    Window	 w)
1431ab64890Smrg{
1441ab64890Smrg    Xim		im = (Xim)ic->core.im;
1451ab64890Smrg
1463b4ba46cSmrg    if (_XimIsFabricatedSerial(im, ev)) {
1471ab64890Smrg	_XimPendingFilter(ic);
1483b4ba46cSmrg	_XimUnfabricateSerial(im, ic, ev);
1491ab64890Smrg	return NOTFILTERD;
1501ab64890Smrg    }
1513b4ba46cSmrg    /* w=0 is used for _XimIsFabricatedSerial() only */
1523b4ba46cSmrg    if (!w)
1533b4ba46cSmrg	return NOTFILTERD;
1541ab64890Smrg
1551ab64890Smrg    if (IS_NEGLECT_EVENT(ic, KeyPressMask))
1561ab64890Smrg	return FILTERD;
1571ab64890Smrg
1581ab64890Smrg#ifdef XIM_CONNECTABLE
1591ab64890Smrg    if (!IS_IC_CONNECTED(ic)) {
1601ab64890Smrg	if (IS_CONNECTABLE(im)) {
1611ab64890Smrg	    if (_XimConnectServer(im)) {
1621ab64890Smrg		if (!_XimReCreateIC(ic)) {
1631ab64890Smrg		    _XimDelayModeSetAttr(im);
1641ab64890Smrg		    return NOTFILTERD;
1651ab64890Smrg		}
1661ab64890Smrg	    } else {
1671ab64890Smrg		return NOTFILTERD;
1681ab64890Smrg	    }
1691ab64890Smrg	} else {
1701ab64890Smrg	    return NOTFILTERD;
1711ab64890Smrg	}
1721ab64890Smrg    }
1731ab64890Smrg#else
1741ab64890Smrg    if (!IS_IC_CONNECTED(ic))
1751ab64890Smrg	return NOTFILTERD;
1761ab64890Smrg#endif /* XIM_CONNECTABLE */
1771ab64890Smrg
1781ab64890Smrg    if (!IS_FORWARD_EVENT(ic, KeyPressMask)) {
1791ab64890Smrg	if (_XimOnKeysCheck(ic, ev))
1801ab64890Smrg	    return FILTERD;
1811ab64890Smrg	return NOTFILTERD;
1821ab64890Smrg    }
1831ab64890Smrg    if (_XimOffKeysCheck(ic, ev))
1841ab64890Smrg	return FILTERD;
1851ab64890Smrg
1861ab64890Smrg    if (_XimForwardEvent(ic, (XEvent *)ev,
1871ab64890Smrg				IS_SYNCHRONOUS_EVENT(ic, KeyPressMask)))
1881ab64890Smrg	return FILTERD;
1891ab64890Smrg
1901ab64890Smrg    return NOTFILTERD;
1911ab64890Smrg}
1921ab64890Smrg
193eb411b4bSmrgstatic Bool
1941ab64890Smrg_XimFilterKeypress(
1951ab64890Smrg    Display		*d,
1961ab64890Smrg    Window		 w,
1971ab64890Smrg    XEvent		*ev,
1981ab64890Smrg    XPointer		 client_data)
1991ab64890Smrg{
2003b4ba46cSmrg    return _XimProtoKeypressFilter((Xic)client_data, (XKeyEvent *)ev, w);
2011ab64890Smrg}
2021ab64890Smrg
203eb411b4bSmrgstatic Bool
2041ab64890Smrg_XimProtoKeyreleaseFilter(
2051ab64890Smrg    Xic		 ic,
2063b4ba46cSmrg    XKeyEvent	*ev,
2073b4ba46cSmrg    Window	 w)
2081ab64890Smrg{
2091ab64890Smrg    Xim		im = (Xim)ic->core.im;
2101ab64890Smrg
2113b4ba46cSmrg    if (_XimIsFabricatedSerial(im, ev)) {
2121ab64890Smrg	_XimPendingFilter(ic);
2133b4ba46cSmrg	_XimUnfabricateSerial(im, ic, ev);
2141ab64890Smrg	return NOTFILTERD;
2151ab64890Smrg    }
2163b4ba46cSmrg    /* w=0 is used for _XimIsFabricatedSerial() only */
2173b4ba46cSmrg    if (!w)
2183b4ba46cSmrg	return NOTFILTERD;
2191ab64890Smrg
2201ab64890Smrg    if (IS_NEGLECT_EVENT(ic, KeyReleaseMask))
2211ab64890Smrg	return FILTERD;
2221ab64890Smrg
2231ab64890Smrg#ifdef XIM_CONNECTABLE
2241ab64890Smrg    if (!IS_IC_CONNECTED(ic)) {
2251ab64890Smrg	if (IS_CONNECTABLE(im)) {
2261ab64890Smrg	    if (_XimConnectServer(im)) {
2271ab64890Smrg		if (!_XimReCreateIC(ic)) {
2281ab64890Smrg		    _XimDelayModeSetAttr(im);
2291ab64890Smrg		    return NOTFILTERD;
2301ab64890Smrg		}
2311ab64890Smrg	    } else {
2321ab64890Smrg		return NOTFILTERD;
2331ab64890Smrg	    }
2341ab64890Smrg	} else {
2351ab64890Smrg	    return NOTFILTERD;
2361ab64890Smrg	}
2371ab64890Smrg    }
2381ab64890Smrg#else
2391ab64890Smrg    if (!IS_IC_CONNECTED(ic))
2401ab64890Smrg	return NOTFILTERD;
2411ab64890Smrg#endif /* XIM_CONNECTABLE */
2421ab64890Smrg
2431ab64890Smrg    if (!IS_FORWARD_EVENT(ic, KeyReleaseMask)) {
2441ab64890Smrg	if (_XimOnKeysCheck(ic, ev))
2451ab64890Smrg	    return FILTERD;
2461ab64890Smrg	return NOTFILTERD;
2471ab64890Smrg    }
2481ab64890Smrg    if (_XimOffKeysCheck(ic, ev))
2491ab64890Smrg	    return FILTERD;
2501ab64890Smrg
2511ab64890Smrg    if (_XimForwardEvent(ic, (XEvent *)ev,
2521ab64890Smrg				IS_SYNCHRONOUS_EVENT(ic, KeyPressMask)))
2531ab64890Smrg	return FILTERD;
2541ab64890Smrg
2551ab64890Smrg    return NOTFILTERD;
2561ab64890Smrg}
2571ab64890Smrg
258eb411b4bSmrgstatic Bool
2591ab64890Smrg_XimFilterKeyrelease(
2601ab64890Smrg    Display		*d,
2611ab64890Smrg    Window		 w,
2621ab64890Smrg    XEvent		*ev,
2631ab64890Smrg    XPointer		 client_data)
2641ab64890Smrg{
2653b4ba46cSmrg    return _XimProtoKeyreleaseFilter((Xic)client_data, (XKeyEvent *)ev, w);
2661ab64890Smrg}
2671ab64890Smrg
268eb411b4bSmrgstatic void
2691ab64890Smrg_XimRegisterKeyPressFilter(
2701ab64890Smrg    Xic		 ic)
2711ab64890Smrg{
2721ab64890Smrg    if (ic->core.focus_window) {
2731ab64890Smrg	if (!(ic->private.proto.registed_filter_event & KEYPRESS_MASK)) {
2743b4ba46cSmrg	    _XRegisterFilterByType (ic->core.im->core.display,
2753b4ba46cSmrg				    0,
2763b4ba46cSmrg				    KeyPress, KeyPress,
2773b4ba46cSmrg				    _XimFilterKeypress,
2783b4ba46cSmrg				    (XPointer)ic);
2791ab64890Smrg	    _XRegisterFilterByType (ic->core.im->core.display,
2801ab64890Smrg				    ic->core.focus_window,
2811ab64890Smrg				    KeyPress, KeyPress,
2821ab64890Smrg				    _XimFilterKeypress,
2831ab64890Smrg				    (XPointer)ic);
2841ab64890Smrg	    ic->private.proto.registed_filter_event |= KEYPRESS_MASK;
2851ab64890Smrg	}
2861ab64890Smrg    }
2871ab64890Smrg    return;
2881ab64890Smrg}
2891ab64890Smrg
290eb411b4bSmrgstatic void
2911ab64890Smrg_XimRegisterKeyReleaseFilter(
2921ab64890Smrg    Xic		 ic)
2931ab64890Smrg{
2941ab64890Smrg    if (ic->core.focus_window) {
2951ab64890Smrg	if (!(ic->private.proto.registed_filter_event & KEYRELEASE_MASK)) {
2963b4ba46cSmrg	    _XRegisterFilterByType (ic->core.im->core.display,
2973b4ba46cSmrg				    0,
2983b4ba46cSmrg				    KeyRelease, KeyRelease,
2993b4ba46cSmrg				    _XimFilterKeyrelease,
3003b4ba46cSmrg				    (XPointer)ic);
3011ab64890Smrg	    _XRegisterFilterByType (ic->core.im->core.display,
3021ab64890Smrg				    ic->core.focus_window,
3031ab64890Smrg				    KeyRelease, KeyRelease,
3041ab64890Smrg				    _XimFilterKeyrelease,
3051ab64890Smrg				    (XPointer)ic);
3061ab64890Smrg	    ic->private.proto.registed_filter_event |= KEYRELEASE_MASK;
3071ab64890Smrg	}
3081ab64890Smrg    }
3091ab64890Smrg    return;
3101ab64890Smrg}
3111ab64890Smrg
312eb411b4bSmrgstatic void
3131ab64890Smrg_XimUnregisterKeyPressFilter(
3141ab64890Smrg    Xic		 ic)
3151ab64890Smrg{
3161ab64890Smrg    if (ic->core.focus_window) {
3171ab64890Smrg	if (ic->private.proto.registed_filter_event & KEYPRESS_MASK) {
3181ab64890Smrg	    _XUnregisterFilter (ic->core.im->core.display,
3191ab64890Smrg				ic->core.focus_window,
3201ab64890Smrg				_XimFilterKeypress,
3211ab64890Smrg				(XPointer)ic);
3223b4ba46cSmrg	    _XUnregisterFilter (ic->core.im->core.display,
3233b4ba46cSmrg				0,
3243b4ba46cSmrg				_XimFilterKeypress,
3253b4ba46cSmrg				(XPointer)ic);
3261ab64890Smrg	    ic->private.proto.registed_filter_event &= ~KEYPRESS_MASK;
3271ab64890Smrg	}
3281ab64890Smrg    }
3291ab64890Smrg    return;
3301ab64890Smrg}
3311ab64890Smrg
332eb411b4bSmrgstatic void
3331ab64890Smrg_XimUnregisterKeyReleaseFilter(
3341ab64890Smrg    Xic		 ic)
3351ab64890Smrg{
3361ab64890Smrg    if (ic->core.focus_window) {
3371ab64890Smrg	if (ic->private.proto.registed_filter_event & KEYRELEASE_MASK) {
3381ab64890Smrg	    _XUnregisterFilter (ic->core.im->core.display,
3391ab64890Smrg				ic->core.focus_window,
3401ab64890Smrg				_XimFilterKeyrelease,
3411ab64890Smrg				(XPointer)ic);
3423b4ba46cSmrg	    _XUnregisterFilter (ic->core.im->core.display,
3433b4ba46cSmrg				0,
3443b4ba46cSmrg				_XimFilterKeyrelease,
3453b4ba46cSmrg				(XPointer)ic);
3461ab64890Smrg	    ic->private.proto.registed_filter_event &= ~KEYRELEASE_MASK;
3471ab64890Smrg	}
3481ab64890Smrg    }
3491ab64890Smrg    return;
3501ab64890Smrg}
3511ab64890Smrg
352eb411b4bSmrgvoid
3531ab64890Smrg_XimRegisterFilter(
3541ab64890Smrg    Xic		 ic)
3551ab64890Smrg{
3561ab64890Smrg    _XimRegisterKeyPressFilter(ic);
3571ab64890Smrg    if (IS_FORWARD_EVENT(ic, KeyReleaseMask))
3581ab64890Smrg	_XimRegisterKeyReleaseFilter(ic);
3591ab64890Smrg    return;
3601ab64890Smrg}
3611ab64890Smrg
362eb411b4bSmrgvoid
3631ab64890Smrg_XimUnregisterFilter(
3641ab64890Smrg    Xic		 ic)
3651ab64890Smrg{
3661ab64890Smrg    _XimUnregisterKeyPressFilter(ic);
3671ab64890Smrg    _XimUnregisterKeyReleaseFilter(ic);
3681ab64890Smrg    return;
3691ab64890Smrg}
3701ab64890Smrg
371eb411b4bSmrgvoid
3721ab64890Smrg_XimReregisterFilter(
3731ab64890Smrg    Xic		 ic)
3741ab64890Smrg{
3751ab64890Smrg    if (IS_FORWARD_EVENT(ic, KeyReleaseMask))
3761ab64890Smrg	_XimRegisterKeyReleaseFilter(ic);
3771ab64890Smrg    else
3781ab64890Smrg	_XimUnregisterKeyReleaseFilter(ic);
3791ab64890Smrg
3801ab64890Smrg    return;
3811ab64890Smrg}
3821ab64890Smrg
383eb411b4bSmrgstatic Bool
3841ab64890Smrg_XimFilterServerDestroy(
3851ab64890Smrg    Display		*d,
3861ab64890Smrg    Window		 w,
3871ab64890Smrg    XEvent		*ev,
3881ab64890Smrg    XPointer		 client_data)
3891ab64890Smrg{
3901ab64890Smrg    Xim			 im = (Xim)client_data;
3911ab64890Smrg
3921ab64890Smrg    if (ev->type == DestroyNotify) {
3931ab64890Smrg	UNMARK_SERVER_CONNECTED(im);
3941ab64890Smrg#ifdef XIM_CONNECTABLE
3951ab64890Smrg	if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
3961ab64890Smrg	    _XimServerReconectableDestroy();
3971ab64890Smrg	    return True;
3981ab64890Smrg	}
3991ab64890Smrg#endif /* XIM_CONNECTABLE */
4001ab64890Smrg	_XimServerDestroy(im);
4011ab64890Smrg    }
4021ab64890Smrg    return True;
4031ab64890Smrg}
4041ab64890Smrg
405eb411b4bSmrgvoid
4061ab64890Smrg_XimRegisterServerFilter(
4071ab64890Smrg    Xim		 im)
4081ab64890Smrg{
4091ab64890Smrg    if (im->private.proto.im_window) {
4101ab64890Smrg	if (!(im->private.proto.registed_filter_event & DESTROYNOTIFY_MASK)) {
4111ab64890Smrg	    _XRegisterFilterByMask(im->core.display,
4121ab64890Smrg		    im->private.proto.im_window,
4131ab64890Smrg		    StructureNotifyMask,
4141ab64890Smrg		    _XimFilterServerDestroy,
4151ab64890Smrg		    (XPointer)im);
4161ab64890Smrg	    XSelectInput(im->core.display, im->private.proto.im_window,
4171ab64890Smrg			 StructureNotifyMask);
4181ab64890Smrg	    im->private.proto.registed_filter_event |= DESTROYNOTIFY_MASK;
4191ab64890Smrg	}
4201ab64890Smrg    }
4211ab64890Smrg    return;
4221ab64890Smrg}
4231ab64890Smrg
424eb411b4bSmrgvoid
4251ab64890Smrg_XimUnregisterServerFilter(
4261ab64890Smrg    Xim		 im)
4271ab64890Smrg{
4281ab64890Smrg    if (im->private.proto.im_window) {
4291ab64890Smrg	if (im->private.proto.registed_filter_event & DESTROYNOTIFY_MASK) {
4301ab64890Smrg	    _XUnregisterFilter(im->core.display,
4311ab64890Smrg		    im->private.proto.im_window,
4321ab64890Smrg		    _XimFilterServerDestroy,
4331ab64890Smrg		    (XPointer)im);
4341ab64890Smrg	    im->private.proto.registed_filter_event &= ~DESTROYNOTIFY_MASK;
4351ab64890Smrg	}
4361ab64890Smrg    }
4371ab64890Smrg    return;
4381ab64890Smrg}
4391ab64890Smrg
440