diff options
Diffstat (limited to 'libX11/modules/im/ximcp/imDefFlt.c')
-rw-r--r-- | libX11/modules/im/ximcp/imDefFlt.c | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/libX11/modules/im/ximcp/imDefFlt.c b/libX11/modules/im/ximcp/imDefFlt.c new file mode 100644 index 000000000..ccf3ba348 --- /dev/null +++ b/libX11/modules/im/ximcp/imDefFlt.c @@ -0,0 +1,420 @@ +/* $Xorg: imDefFlt.c,v 1.4 2000/08/17 19:45:11 cpqbld Exp $ */ +/****************************************************************** + + Copyright 1992, 1993, 1994 by FUJITSU LIMITED + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and +that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of FUJITSU LIMITED +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. +FUJITSU LIMITED makes no representations about the suitability of +this software for any purpose. +It is provided "as is" without express or implied warranty. + +FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + + Author: Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + +******************************************************************/ +/* $XFree86: xc/lib/X11/imDefFlt.c,v 1.4 2001/01/17 19:41:51 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/Xatom.h> +#define NEED_EVENTS +#include "Xlibint.h" +#include "Xutil.h" +#include "Xlcint.h" +#include "Ximint.h" + +Private long +_XimTriggerCheck( + Xim im, + XKeyEvent *ev, + INT32 len, + CARD32 *keylist) +{ + register long i; + KeySym keysym; + CARD32 buf32[BUFSIZE/4]; + char *buf = (char *)buf32; + int modifier; + int modifier_mask; + CARD32 min_len = sizeof(CARD32) /* sizeof keysym */ + + sizeof(CARD32) /* sizeof modifier */ + + sizeof(CARD32); /* sizeof modifier mask */ + + XLookupString(ev, buf, BUFSIZE, &keysym, NULL); + if (!keysym) + return -1; + + for (i = 0; len >= min_len; i += 3, len -= min_len) { + modifier = keylist[i + 1]; + modifier_mask = keylist[i + 2]; + if (((KeySym)keylist[i] == keysym) + && ((ev->state & modifier_mask) == modifier)) + return i; + } + return -1; +} + +Private long +_XimTriggerOnCheck( + Xim im, + XKeyEvent *ev) +{ + return _XimTriggerCheck(im, ev, (INT32)im->private.proto.im_onkeylist[0], + &im->private.proto.im_onkeylist[1]); +} + +Private long +_XimTriggerOffCheck( + Xim im, + XKeyEvent *ev) +{ + return _XimTriggerCheck(im, ev, (INT32)im->private.proto.im_offkeylist[0], + &im->private.proto.im_offkeylist[1]); +} + +Private Bool +_XimOnKeysCheck( + Xic ic, + XKeyEvent *ev) +{ + Xim im = (Xim)ic->core.im; + long idx; + + if (IS_DYNAMIC_EVENT_FLOW(ic->core.im) && + im->private.proto.im_onkeylist && + im->private.proto.im_onkeylist[0]) { + if ((idx = _XimTriggerOnCheck(im, ev)) >= 0) { + (void)_XimTriggerNotify(im, ic, 0, (CARD32)idx); /* Trigger on */ + return True; + } + } + return False; +} + +Private Bool +_XimOffKeysCheck( + Xic ic, + XKeyEvent *ev) +{ + Xim im = (Xim)ic->core.im; + long idx; + + if (IS_DYNAMIC_EVENT_FLOW(ic->core.im) && + im->private.proto.im_offkeylist && + im->private.proto.im_offkeylist[0]) { + if ((idx = _XimTriggerOffCheck(im, ev)) >= 0) { + _XimTriggerNotify(im, ic, 1, (CARD32)idx); /* Trigger off */ + return True; + } + } + return False; +} + +Private void +_XimPendingFilter( + Xic ic) +{ + Xim im = (Xim)ic->core.im; + + if (IS_NEED_SYNC_REPLY(ic)) { + (void)_XimProcSyncReply(im, ic); + UNMARK_NEED_SYNC_REPLY(ic); + } + return; +} + +Private Bool +_XimProtoKeypressFilter( + Xic ic, + XKeyEvent *ev) +{ +#ifdef XIM_CONNECTABLE + Xim im = (Xim)ic->core.im; +#endif + + if (IS_FABLICATED(ic)) { + _XimPendingFilter(ic); + UNMARK_FABLICATED(ic); + return NOTFILTERD; + } + + if (IS_NEGLECT_EVENT(ic, KeyPressMask)) + return FILTERD; + +#ifdef XIM_CONNECTABLE + if (!IS_IC_CONNECTED(ic)) { + if (IS_CONNECTABLE(im)) { + if (_XimConnectServer(im)) { + if (!_XimReCreateIC(ic)) { + _XimDelayModeSetAttr(im); + return NOTFILTERD; + } + } else { + return NOTFILTERD; + } + } else { + return NOTFILTERD; + } + } +#else + if (!IS_IC_CONNECTED(ic)) + return NOTFILTERD; +#endif /* XIM_CONNECTABLE */ + + if (!IS_FORWARD_EVENT(ic, KeyPressMask)) { + if (_XimOnKeysCheck(ic, ev)) + return FILTERD; + return NOTFILTERD; + } + if (_XimOffKeysCheck(ic, ev)) + return FILTERD; + + if (_XimForwardEvent(ic, (XEvent *)ev, + IS_SYNCHRONOUS_EVENT(ic, KeyPressMask))) + return FILTERD; + + return NOTFILTERD; +} + +Private Bool +_XimFilterKeypress( + Display *d, + Window w, + XEvent *ev, + XPointer client_data) +{ + return _XimProtoKeypressFilter((Xic)client_data, (XKeyEvent *)ev ); +} + +Private Bool +_XimProtoKeyreleaseFilter( + Xic ic, + XKeyEvent *ev) +{ +#ifdef XIM_CONNECTABLE + Xim im = (Xim)ic->core.im; +#endif + + if (IS_FABLICATED(ic)) { + _XimPendingFilter(ic); + UNMARK_FABLICATED(ic); + return NOTFILTERD; + } + + if (IS_NEGLECT_EVENT(ic, KeyReleaseMask)) + return FILTERD; + +#ifdef XIM_CONNECTABLE + if (!IS_IC_CONNECTED(ic)) { + if (IS_CONNECTABLE(im)) { + if (_XimConnectServer(im)) { + if (!_XimReCreateIC(ic)) { + _XimDelayModeSetAttr(im); + return NOTFILTERD; + } + } else { + return NOTFILTERD; + } + } else { + return NOTFILTERD; + } + } +#else + if (!IS_IC_CONNECTED(ic)) + return NOTFILTERD; +#endif /* XIM_CONNECTABLE */ + + if (!IS_FORWARD_EVENT(ic, KeyReleaseMask)) { + if (_XimOnKeysCheck(ic, ev)) + return FILTERD; + return NOTFILTERD; + } + if (_XimOffKeysCheck(ic, ev)) + return FILTERD; + + if (_XimForwardEvent(ic, (XEvent *)ev, + IS_SYNCHRONOUS_EVENT(ic, KeyPressMask))) + return FILTERD; + + return NOTFILTERD; +} + +Private Bool +_XimFilterKeyrelease( + Display *d, + Window w, + XEvent *ev, + XPointer client_data) +{ + return _XimProtoKeyreleaseFilter((Xic)client_data, (XKeyEvent *)ev); +} + +Private void +_XimRegisterKeyPressFilter( + Xic ic) +{ + if (ic->core.focus_window) { + if (!(ic->private.proto.registed_filter_event & KEYPRESS_MASK)) { + _XRegisterFilterByType (ic->core.im->core.display, + ic->core.focus_window, + KeyPress, KeyPress, + _XimFilterKeypress, + (XPointer)ic); + ic->private.proto.registed_filter_event |= KEYPRESS_MASK; + } + } + return; +} + +Private void +_XimRegisterKeyReleaseFilter( + Xic ic) +{ + if (ic->core.focus_window) { + if (!(ic->private.proto.registed_filter_event & KEYRELEASE_MASK)) { + _XRegisterFilterByType (ic->core.im->core.display, + ic->core.focus_window, + KeyRelease, KeyRelease, + _XimFilterKeyrelease, + (XPointer)ic); + ic->private.proto.registed_filter_event |= KEYRELEASE_MASK; + } + } + return; +} + +Private void +_XimUnregisterKeyPressFilter( + Xic ic) +{ + if (ic->core.focus_window) { + if (ic->private.proto.registed_filter_event & KEYPRESS_MASK) { + _XUnregisterFilter (ic->core.im->core.display, + ic->core.focus_window, + _XimFilterKeypress, + (XPointer)ic); + ic->private.proto.registed_filter_event &= ~KEYPRESS_MASK; + } + } + return; +} + +Private void +_XimUnregisterKeyReleaseFilter( + Xic ic) +{ + if (ic->core.focus_window) { + if (ic->private.proto.registed_filter_event & KEYRELEASE_MASK) { + _XUnregisterFilter (ic->core.im->core.display, + ic->core.focus_window, + _XimFilterKeyrelease, + (XPointer)ic); + ic->private.proto.registed_filter_event &= ~KEYRELEASE_MASK; + } + } + return; +} + +Public void +_XimRegisterFilter( + Xic ic) +{ + _XimRegisterKeyPressFilter(ic); + if (IS_FORWARD_EVENT(ic, KeyReleaseMask)) + _XimRegisterKeyReleaseFilter(ic); + return; +} + +Public void +_XimUnregisterFilter( + Xic ic) +{ + _XimUnregisterKeyPressFilter(ic); + _XimUnregisterKeyReleaseFilter(ic); + return; +} + +Public void +_XimReregisterFilter( + Xic ic) +{ + if (IS_FORWARD_EVENT(ic, KeyReleaseMask)) + _XimRegisterKeyReleaseFilter(ic); + else + _XimUnregisterKeyReleaseFilter(ic); + + return; +} + +Private Bool +_XimFilterServerDestroy( + Display *d, + Window w, + XEvent *ev, + XPointer client_data) +{ + Xim im = (Xim)client_data; + + if (ev->type == DestroyNotify) { + UNMARK_SERVER_CONNECTED(im); +#ifdef XIM_CONNECTABLE + if (!IS_SERVER_CONNECTED(im) && IS_RECONNECTABLE(im)) { + _XimServerReconectableDestroy(); + return True; + } +#endif /* XIM_CONNECTABLE */ + _XimServerDestroy(im); + } + return True; +} + +Public void +_XimRegisterServerFilter( + Xim im) +{ + if (im->private.proto.im_window) { + if (!(im->private.proto.registed_filter_event & DESTROYNOTIFY_MASK)) { + _XRegisterFilterByMask(im->core.display, + im->private.proto.im_window, + StructureNotifyMask, + _XimFilterServerDestroy, + (XPointer)im); + XSelectInput(im->core.display, im->private.proto.im_window, + StructureNotifyMask); + im->private.proto.registed_filter_event |= DESTROYNOTIFY_MASK; + } + } + return; +} + +Public void +_XimUnregisterServerFilter( + Xim im) +{ + if (im->private.proto.im_window) { + if (im->private.proto.registed_filter_event & DESTROYNOTIFY_MASK) { + _XUnregisterFilter(im->core.display, + im->private.proto.im_window, + _XimFilterServerDestroy, + (XPointer)im); + im->private.proto.registed_filter_event &= ~DESTROYNOTIFY_MASK; + } + } + return; +} + |