imDefFlt.c revision eb411b4b
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,
1411ab64890Smrg    XKeyEvent	*ev)
1421ab64890Smrg{
1431ab64890Smrg    Xim		im = (Xim)ic->core.im;
1441ab64890Smrg
145eb411b4bSmrg    if (IS_FABRICATED(im)) {
1461ab64890Smrg	_XimPendingFilter(ic);
147eb411b4bSmrg	UNMARK_FABRICATED(im);
1481ab64890Smrg	return NOTFILTERD;
1491ab64890Smrg    }
1501ab64890Smrg
1511ab64890Smrg    if (IS_NEGLECT_EVENT(ic, KeyPressMask))
1521ab64890Smrg	return FILTERD;
1531ab64890Smrg
1541ab64890Smrg#ifdef XIM_CONNECTABLE
1551ab64890Smrg    if (!IS_IC_CONNECTED(ic)) {
1561ab64890Smrg	if (IS_CONNECTABLE(im)) {
1571ab64890Smrg	    if (_XimConnectServer(im)) {
1581ab64890Smrg		if (!_XimReCreateIC(ic)) {
1591ab64890Smrg		    _XimDelayModeSetAttr(im);
1601ab64890Smrg		    return NOTFILTERD;
1611ab64890Smrg		}
1621ab64890Smrg	    } else {
1631ab64890Smrg		return NOTFILTERD;
1641ab64890Smrg	    }
1651ab64890Smrg	} else {
1661ab64890Smrg	    return NOTFILTERD;
1671ab64890Smrg	}
1681ab64890Smrg    }
1691ab64890Smrg#else
1701ab64890Smrg    if (!IS_IC_CONNECTED(ic))
1711ab64890Smrg	return NOTFILTERD;
1721ab64890Smrg#endif /* XIM_CONNECTABLE */
1731ab64890Smrg
1741ab64890Smrg    if (!IS_FORWARD_EVENT(ic, KeyPressMask)) {
1751ab64890Smrg	if (_XimOnKeysCheck(ic, ev))
1761ab64890Smrg	    return FILTERD;
1771ab64890Smrg	return NOTFILTERD;
1781ab64890Smrg    }
1791ab64890Smrg    if (_XimOffKeysCheck(ic, ev))
1801ab64890Smrg	return FILTERD;
1811ab64890Smrg
1821ab64890Smrg    if (_XimForwardEvent(ic, (XEvent *)ev,
1831ab64890Smrg				IS_SYNCHRONOUS_EVENT(ic, KeyPressMask)))
1841ab64890Smrg	return FILTERD;
1851ab64890Smrg
1861ab64890Smrg    return NOTFILTERD;
1871ab64890Smrg}
1881ab64890Smrg
189eb411b4bSmrgstatic Bool
1901ab64890Smrg_XimFilterKeypress(
1911ab64890Smrg    Display		*d,
1921ab64890Smrg    Window		 w,
1931ab64890Smrg    XEvent		*ev,
1941ab64890Smrg    XPointer		 client_data)
1951ab64890Smrg{
1961ab64890Smrg    return _XimProtoKeypressFilter((Xic)client_data, (XKeyEvent *)ev );
1971ab64890Smrg}
1981ab64890Smrg
199eb411b4bSmrgstatic Bool
2001ab64890Smrg_XimProtoKeyreleaseFilter(
2011ab64890Smrg    Xic		 ic,
2021ab64890Smrg    XKeyEvent	*ev)
2031ab64890Smrg{
2041ab64890Smrg    Xim		im = (Xim)ic->core.im;
2051ab64890Smrg
206eb411b4bSmrg    if (IS_FABRICATED(im)) {
2071ab64890Smrg	_XimPendingFilter(ic);
208eb411b4bSmrg	UNMARK_FABRICATED(im);
2091ab64890Smrg	return NOTFILTERD;
2101ab64890Smrg    }
2111ab64890Smrg
2121ab64890Smrg    if (IS_NEGLECT_EVENT(ic, KeyReleaseMask))
2131ab64890Smrg	return FILTERD;
2141ab64890Smrg
2151ab64890Smrg#ifdef XIM_CONNECTABLE
2161ab64890Smrg    if (!IS_IC_CONNECTED(ic)) {
2171ab64890Smrg	if (IS_CONNECTABLE(im)) {
2181ab64890Smrg	    if (_XimConnectServer(im)) {
2191ab64890Smrg		if (!_XimReCreateIC(ic)) {
2201ab64890Smrg		    _XimDelayModeSetAttr(im);
2211ab64890Smrg		    return NOTFILTERD;
2221ab64890Smrg		}
2231ab64890Smrg	    } else {
2241ab64890Smrg		return NOTFILTERD;
2251ab64890Smrg	    }
2261ab64890Smrg	} else {
2271ab64890Smrg	    return NOTFILTERD;
2281ab64890Smrg	}
2291ab64890Smrg    }
2301ab64890Smrg#else
2311ab64890Smrg    if (!IS_IC_CONNECTED(ic))
2321ab64890Smrg	return NOTFILTERD;
2331ab64890Smrg#endif /* XIM_CONNECTABLE */
2341ab64890Smrg
2351ab64890Smrg    if (!IS_FORWARD_EVENT(ic, KeyReleaseMask)) {
2361ab64890Smrg	if (_XimOnKeysCheck(ic, ev))
2371ab64890Smrg	    return FILTERD;
2381ab64890Smrg	return NOTFILTERD;
2391ab64890Smrg    }
2401ab64890Smrg    if (_XimOffKeysCheck(ic, ev))
2411ab64890Smrg	    return FILTERD;
2421ab64890Smrg
2431ab64890Smrg    if (_XimForwardEvent(ic, (XEvent *)ev,
2441ab64890Smrg				IS_SYNCHRONOUS_EVENT(ic, KeyPressMask)))
2451ab64890Smrg	return FILTERD;
2461ab64890Smrg
2471ab64890Smrg    return NOTFILTERD;
2481ab64890Smrg}
2491ab64890Smrg
250eb411b4bSmrgstatic Bool
2511ab64890Smrg_XimFilterKeyrelease(
2521ab64890Smrg    Display		*d,
2531ab64890Smrg    Window		 w,
2541ab64890Smrg    XEvent		*ev,
2551ab64890Smrg    XPointer		 client_data)
2561ab64890Smrg{
2571ab64890Smrg    return _XimProtoKeyreleaseFilter((Xic)client_data, (XKeyEvent *)ev);
2581ab64890Smrg}
2591ab64890Smrg
260eb411b4bSmrgstatic void
2611ab64890Smrg_XimRegisterKeyPressFilter(
2621ab64890Smrg    Xic		 ic)
2631ab64890Smrg{
2641ab64890Smrg    if (ic->core.focus_window) {
2651ab64890Smrg	if (!(ic->private.proto.registed_filter_event & KEYPRESS_MASK)) {
2661ab64890Smrg	    _XRegisterFilterByType (ic->core.im->core.display,
2671ab64890Smrg				    ic->core.focus_window,
2681ab64890Smrg				    KeyPress, KeyPress,
2691ab64890Smrg				    _XimFilterKeypress,
2701ab64890Smrg				    (XPointer)ic);
2711ab64890Smrg	    ic->private.proto.registed_filter_event |= KEYPRESS_MASK;
2721ab64890Smrg	}
2731ab64890Smrg    }
2741ab64890Smrg    return;
2751ab64890Smrg}
2761ab64890Smrg
277eb411b4bSmrgstatic void
2781ab64890Smrg_XimRegisterKeyReleaseFilter(
2791ab64890Smrg    Xic		 ic)
2801ab64890Smrg{
2811ab64890Smrg    if (ic->core.focus_window) {
2821ab64890Smrg	if (!(ic->private.proto.registed_filter_event & KEYRELEASE_MASK)) {
2831ab64890Smrg	    _XRegisterFilterByType (ic->core.im->core.display,
2841ab64890Smrg				    ic->core.focus_window,
2851ab64890Smrg				    KeyRelease, KeyRelease,
2861ab64890Smrg				    _XimFilterKeyrelease,
2871ab64890Smrg				    (XPointer)ic);
2881ab64890Smrg	    ic->private.proto.registed_filter_event |= KEYRELEASE_MASK;
2891ab64890Smrg	}
2901ab64890Smrg    }
2911ab64890Smrg    return;
2921ab64890Smrg}
2931ab64890Smrg
294eb411b4bSmrgstatic void
2951ab64890Smrg_XimUnregisterKeyPressFilter(
2961ab64890Smrg    Xic		 ic)
2971ab64890Smrg{
2981ab64890Smrg    if (ic->core.focus_window) {
2991ab64890Smrg	if (ic->private.proto.registed_filter_event & KEYPRESS_MASK) {
3001ab64890Smrg	    _XUnregisterFilter (ic->core.im->core.display,
3011ab64890Smrg				ic->core.focus_window,
3021ab64890Smrg				_XimFilterKeypress,
3031ab64890Smrg				(XPointer)ic);
3041ab64890Smrg	    ic->private.proto.registed_filter_event &= ~KEYPRESS_MASK;
3051ab64890Smrg	}
3061ab64890Smrg    }
3071ab64890Smrg    return;
3081ab64890Smrg}
3091ab64890Smrg
310eb411b4bSmrgstatic void
3111ab64890Smrg_XimUnregisterKeyReleaseFilter(
3121ab64890Smrg    Xic		 ic)
3131ab64890Smrg{
3141ab64890Smrg    if (ic->core.focus_window) {
3151ab64890Smrg	if (ic->private.proto.registed_filter_event & KEYRELEASE_MASK) {
3161ab64890Smrg	    _XUnregisterFilter (ic->core.im->core.display,
3171ab64890Smrg				ic->core.focus_window,
3181ab64890Smrg				_XimFilterKeyrelease,
3191ab64890Smrg				(XPointer)ic);
3201ab64890Smrg	    ic->private.proto.registed_filter_event &= ~KEYRELEASE_MASK;
3211ab64890Smrg	}
3221ab64890Smrg    }
3231ab64890Smrg    return;
3241ab64890Smrg}
3251ab64890Smrg
326eb411b4bSmrgvoid
3271ab64890Smrg_XimRegisterFilter(
3281ab64890Smrg    Xic		 ic)
3291ab64890Smrg{
3301ab64890Smrg    _XimRegisterKeyPressFilter(ic);
3311ab64890Smrg    if (IS_FORWARD_EVENT(ic, KeyReleaseMask))
3321ab64890Smrg	_XimRegisterKeyReleaseFilter(ic);
3331ab64890Smrg    return;
3341ab64890Smrg}
3351ab64890Smrg
336eb411b4bSmrgvoid
3371ab64890Smrg_XimUnregisterFilter(
3381ab64890Smrg    Xic		 ic)
3391ab64890Smrg{
3401ab64890Smrg    _XimUnregisterKeyPressFilter(ic);
3411ab64890Smrg    _XimUnregisterKeyReleaseFilter(ic);
3421ab64890Smrg    return;
3431ab64890Smrg}
3441ab64890Smrg
345eb411b4bSmrgvoid
3461ab64890Smrg_XimReregisterFilter(
3471ab64890Smrg    Xic		 ic)
3481ab64890Smrg{
3491ab64890Smrg    if (IS_FORWARD_EVENT(ic, KeyReleaseMask))
3501ab64890Smrg	_XimRegisterKeyReleaseFilter(ic);
3511ab64890Smrg    else
3521ab64890Smrg	_XimUnregisterKeyReleaseFilter(ic);
3531ab64890Smrg
3541ab64890Smrg    return;
3551ab64890Smrg}
3561ab64890Smrg
357eb411b4bSmrgstatic Bool
3581ab64890Smrg_XimFilterServerDestroy(
3591ab64890Smrg    Display		*d,
3601ab64890Smrg    Window		 w,
3611ab64890Smrg    XEvent		*ev,
3621ab64890Smrg    XPointer		 client_data)
3631ab64890Smrg{
3641ab64890Smrg    Xim			 im = (Xim)client_data;
3651ab64890Smrg
3661ab64890Smrg    if (ev->type == DestroyNotify) {
3671ab64890Smrg	UNMARK_SERVER_CONNECTED(im);
3681ab64890Smrg#ifdef XIM_CONNECTABLE
3691ab64890Smrg	if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) {
3701ab64890Smrg	    _XimServerReconectableDestroy();
3711ab64890Smrg	    return True;
3721ab64890Smrg	}
3731ab64890Smrg#endif /* XIM_CONNECTABLE */
3741ab64890Smrg	_XimServerDestroy(im);
3751ab64890Smrg    }
3761ab64890Smrg    return True;
3771ab64890Smrg}
3781ab64890Smrg
379eb411b4bSmrgvoid
3801ab64890Smrg_XimRegisterServerFilter(
3811ab64890Smrg    Xim		 im)
3821ab64890Smrg{
3831ab64890Smrg    if (im->private.proto.im_window) {
3841ab64890Smrg	if (!(im->private.proto.registed_filter_event & DESTROYNOTIFY_MASK)) {
3851ab64890Smrg	    _XRegisterFilterByMask(im->core.display,
3861ab64890Smrg		    im->private.proto.im_window,
3871ab64890Smrg		    StructureNotifyMask,
3881ab64890Smrg		    _XimFilterServerDestroy,
3891ab64890Smrg		    (XPointer)im);
3901ab64890Smrg	    XSelectInput(im->core.display, im->private.proto.im_window,
3911ab64890Smrg			 StructureNotifyMask);
3921ab64890Smrg	    im->private.proto.registed_filter_event |= DESTROYNOTIFY_MASK;
3931ab64890Smrg	}
3941ab64890Smrg    }
3951ab64890Smrg    return;
3961ab64890Smrg}
3971ab64890Smrg
398eb411b4bSmrgvoid
3991ab64890Smrg_XimUnregisterServerFilter(
4001ab64890Smrg    Xim		 im)
4011ab64890Smrg{
4021ab64890Smrg    if (im->private.proto.im_window) {
4031ab64890Smrg	if (im->private.proto.registed_filter_event & DESTROYNOTIFY_MASK) {
4041ab64890Smrg	    _XUnregisterFilter(im->core.display,
4051ab64890Smrg		    im->private.proto.im_window,
4061ab64890Smrg		    _XimFilterServerDestroy,
4071ab64890Smrg		    (XPointer)im);
4081ab64890Smrg	    im->private.proto.registed_filter_event &= ~DESTROYNOTIFY_MASK;
4091ab64890Smrg	}
4101ab64890Smrg    }
4111ab64890Smrg    return;
4121ab64890Smrg}
4131ab64890Smrg
414