Home | History | Annotate | Line # | Download | only in ximcp
      1 /******************************************************************
      2 
      3               Copyright 1992 by Fuji Xerox Co., Ltd.
      4               Copyright 1992, 1994 by FUJITSU LIMITED
      5 
      6 Permission to use, copy, modify, distribute, and sell this software
      7 and its documentation for any purpose is hereby granted without fee,
      8 provided that the above copyright notice appear in all copies and
      9 that both that copyright notice and this permission notice appear
     10 in supporting documentation, and that the name of Fuji Xerox,
     11 FUJITSU LIMITED not be used in advertising or publicity pertaining
     12 to distribution of the software without specific, written prior
     13 permission. Fuji Xerox, FUJITSU LIMITED make no representations
     14 about the suitability of this software for any purpose.
     15 It is provided "as is" without express or implied warranty.
     16 
     17 FUJI XEROX, FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH
     18 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
     19 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX,
     20 FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
     21 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
     22 OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     23 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     24 PERFORMANCE OF THIS SOFTWARE.
     25 
     26   Author   : Kazunori Nishihara	Fuji Xerox
     27   Modifier : Takashi Fujiwara   FUJITSU LIMITED
     28                                 fujiwara (at) a80.tech.yk.fujitsu.co.jp
     29 
     30 ******************************************************************/
     31 
     32 #ifdef HAVE_CONFIG_H
     33 #include <config.h>
     34 #endif
     35 #include "Xlibint.h"
     36 #include <X11/keysym.h>
     37 #include "Xlcint.h"
     38 #include "Ximint.h"
     39 
     40 Bool
     41 _XimLocalFilter(Display *d, Window w, XEvent *ev, XPointer client_data)
     42 {
     43     Xic		 ic = (Xic)client_data;
     44     KeySym	 keysym;
     45     static char	 buf[256];
     46     static unsigned prevcode = 0, prevstate = 0;
     47     unsigned    currstate;
     48     DefTree	*b = ic->private.local.base.tree;
     49     DTIndex	 t;
     50     Bool	 anymodifier = False;
     51     unsigned char braillePattern = 0;
     52 
     53     if(ev->xkey.keycode == 0)
     54 	return (False);
     55 
     56     XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &keysym, NULL);
     57 
     58     if(keysym >= XK_braille_dot_1 && keysym <= XK_braille_dot_8) {
     59 	if(ev->type == KeyPress) {
     60 	    ic->private.local.brl_pressed |=
     61 		1<<(keysym-XK_braille_dot_1);
     62 	    return(True);
     63 	} else {
     64 	    if(!ic->private.local.brl_committing
     65 		    || ev->xkey.time - ic->private.local.brl_release_start > 300) {
     66 	    	ic->private.local.brl_committing = ic->private.local.brl_pressed;
     67 		ic->private.local.brl_release_start = ev->xkey.time;
     68 	    }
     69 	    ic->private.local.brl_pressed &= ~(1<<(keysym-XK_braille_dot_1));
     70 	    if(!ic->private.local.brl_pressed && ic->private.local.brl_committing) {
     71 		/* Committed a braille pattern, let it go through compose tree */
     72 		keysym = XK_braille_blank | ic->private.local.brl_committing;
     73 		ev->type = KeyPress;
     74 		braillePattern = ic->private.local.brl_committing;
     75 		ic->private.local.brl_committing = 0;
     76 	    } else {
     77 	        return(True);
     78 	    }
     79 	}
     80     }
     81 
     82     if(((Xim)ic->core.im)->private.local.top == 0 )
     83 	goto emit_braille;
     84 
     85     currstate = ev->xkey.state;
     86     if(ev->type == KeyPress) {
     87 	prevcode = ev->xkey.keycode;
     88 	prevstate = currstate;
     89 
     90 	if(IsModifierKey(keysym))
     91 	    return(False);
     92 	prevcode = 0;
     93     } else {
     94 	if(prevcode != ev->xkey.keycode)
     95 	    return False;
     96 
     97 	/* For lookup, we use the state at the time when the key was pressed, */
     98 	/* because this state was not affected by the modifier that is mapped */
     99 	/* to the key. */
    100 	ev->xkey.state = prevstate;
    101 	XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &keysym, NULL);
    102     }
    103 
    104     for(t = ic->private.local.context; t; t = b[t].next) {
    105 	if(IsModifierKey(b[t].keysym))
    106 	    anymodifier = True;
    107 	if(((ev->xkey.state & b[t].modifier_mask) == b[t].modifier) &&
    108 	   (keysym == b[t].keysym))
    109 	    break;
    110     }
    111 
    112     /* Restore the state */
    113     ev->xkey.state = currstate;
    114 
    115     if(t) { /* Matched */
    116 	if(b[t].succession) { /* Intermediate */
    117 	    ic->private.local.context = b[t].succession;
    118 	    return (ev->type == KeyPress);
    119 	} else { /* Terminate (reached to leaf) */
    120 	    ic->private.local.composed = t;
    121 	    ic->private.local.brl_committed = 0;
    122 	    /* return back to client KeyPressEvent keycode == 0 */
    123 	    ev->xkey.keycode = 0;
    124 	    ev->xkey.type = KeyPress;
    125 	    XPutBackEvent(d, ev);
    126 	    if(prevcode){
    127 		/* For modifier key releases, restore the event, as we do not */
    128 		/* filter it.  */
    129 		ev->xkey.type = KeyRelease;
    130 		ev->xkey.keycode = prevcode;
    131 	    }
    132 	    /* initialize internal state for next key sequence */
    133 	    ic->private.local.context = ((Xim)ic->core.im)->private.local.top;
    134 	    return (ev->type == KeyPress);
    135 	}
    136     } else { /* Unmatched */
    137 	/* Unmatched modifier key releases abort matching only in the case that */
    138 	/* there was any modifier that would have matched */
    139 	if((ic->private.local.context == ((Xim)ic->core.im)->private.local.top) ||
    140 	   (ev->type == KeyRelease && !anymodifier)) {
    141 	    goto emit_braille;
    142 	}
    143 	/* Error (Sequence Unmatch occurred) */
    144 	/* initialize internal state for next key sequence */
    145 	ic->private.local.context = ((Xim)ic->core.im)->private.local.top;
    146 	return (ev->type == KeyPress);
    147     }
    148 
    149 emit_braille:
    150     if(braillePattern) {
    151 	/* Braille pattern is not in compose tree, emit alone */
    152 	ic->private.local.brl_committed = braillePattern;
    153 	ic->private.local.composed = 0;
    154 	ev->xkey.keycode = 0;
    155 	_XPutBackEvent(d, ev);
    156 	return(True);
    157     }
    158     return(False);
    159 }
    160