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