diff options
Diffstat (limited to 'nx-X11/lib/modules/im/ximcp/imLcFlt.c')
-rw-r--r-- | nx-X11/lib/modules/im/ximcp/imLcFlt.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/nx-X11/lib/modules/im/ximcp/imLcFlt.c b/nx-X11/lib/modules/im/ximcp/imLcFlt.c new file mode 100644 index 000000000..50f4c252a --- /dev/null +++ b/nx-X11/lib/modules/im/ximcp/imLcFlt.c @@ -0,0 +1,157 @@ +/****************************************************************** + + Copyright 1992 by Fuji Xerox Co., Ltd. + Copyright 1992, 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 Fuji Xerox, +FUJITSU LIMITED not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. Fuji Xerox, FUJITSU LIMITED make no representations +about the suitability of this software for any purpose. +It is provided "as is" without express or implied warranty. + +FUJI XEROX, FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX, +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 : Kazunori Nishihara Fuji Xerox + Modifier : Takashi Fujiwara FUJITSU LIMITED + fujiwara@a80.tech.yk.fujitsu.co.jp + +******************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "Xlibint.h" +#include <nx-X11/keysym.h> +#include "Xlcint.h" +#include "Ximint.h" + +Bool +_XimLocalFilter(Display *d, Window w, XEvent *ev, XPointer client_data) +{ + Xic ic = (Xic)client_data; + KeySym keysym; + static char buf[256]; + static unsigned prevcode = 0, prevstate = 0; + unsigned currstate; + DefTree *b = ic->private.local.base.tree; + DTIndex t; + Bool braille = False, anymodifier = False; + + if(ev->xkey.keycode == 0) + return (False); + + XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &keysym, NULL); + + if(keysym >= XK_braille_dot_1 && keysym <= XK_braille_dot_8) { + if(ev->type == KeyPress) { + ic->private.local.brl_pressed |= + 1<<(keysym-XK_braille_dot_1); + return(True); + } else { + if(!ic->private.local.brl_committing + || ev->xkey.time - ic->private.local.brl_release_start > 300) { + ic->private.local.brl_committing = ic->private.local.brl_pressed; + ic->private.local.brl_release_start = ev->xkey.time; + } + ic->private.local.brl_pressed &= ~(1<<(keysym-XK_braille_dot_1)); + if(!ic->private.local.brl_pressed && ic->private.local.brl_committing) { + /* Commited a braille pattern, let it go through compose tree */ + keysym = XK_braille_blank | ic->private.local.brl_committing; + ev->type = KeyPress; + braille = True; + } else { + return(True); + } + } + } + + if(((Xim)ic->core.im)->private.local.top == 0 ) + goto emit_braille; + + currstate = ev->xkey.state; + if(ev->type == KeyPress) { + prevcode = ev->xkey.keycode; + prevstate = currstate; + + if(IsModifierKey(keysym)) + return(False); + prevcode = 0; + } else { + if(prevcode != ev->xkey.keycode) + return False; + + /* For lookup, we use the state at the time when the key was pressed, */ + /* because this state was not affected by the modifier that is mapped */ + /* to the key. */ + ev->xkey.state = prevstate; + XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &keysym, NULL); + } + + for(t = ic->private.local.context; t; t = b[t].next) { + if(IsModifierKey(b[t].keysym)) + anymodifier = True; + if(((ev->xkey.state & b[t].modifier_mask) == b[t].modifier) && + (keysym == b[t].keysym)) + break; + } + + /* Restore the state */ + ev->xkey.state = currstate; + + if(t) { /* Matched */ + if(b[t].succession) { /* Intermediate */ + ic->private.local.context = b[t].succession; + return (ev->type == KeyPress); + } else { /* Terminate (reached to leaf) */ + ic->private.local.composed = t; + ic->private.local.brl_committed = 0; + /* return back to client KeyPressEvent keycode == 0 */ + ev->xkey.keycode = 0; + ev->xkey.type = KeyPress; + XPutBackEvent(d, ev); + if(prevcode){ + /* For modifier key releases, restore the event, as we do not */ + /* filter it. */ + ev->xkey.type = KeyRelease; + ev->xkey.keycode = prevcode; + } + /* initialize internal state for next key sequence */ + ic->private.local.context = ((Xim)ic->core.im)->private.local.top; + return (ev->type == KeyPress); + } + } else { /* Unmatched */ + /* Unmatched modifier key releases abort matching only in the case that */ + /* there was any modifier that would have matched */ + if((ic->private.local.context == ((Xim)ic->core.im)->private.local.top) || + (ev->type == KeyRelease && !anymodifier)) { + goto emit_braille; + } + /* Error (Sequence Unmatch occured) */ + /* initialize internal state for next key sequence */ + ic->private.local.context = ((Xim)ic->core.im)->private.local.top; + return (ev->type == KeyPress); + } + +emit_braille: + if(braille) { + /* Braille pattern is not in compose tree, emit alone */ + ic->private.local.brl_committed = ic->private.local.brl_committing; + ic->private.local.composed = 0; + ev->xkey.keycode = 0; + _XPutBackEvent(d, ev); + return(True); + } + return(False); +} |