Beispiel #1
0
void XWindow::OnKeyRelease(WindowEventKey *e)
{
    XkbStateRec s;
    Status st = XkbGetState(e->Handle()->display, XkbUseCoreKbd, &s);
    if (st != XkbOD_Success)
        throw new XException("Error getting xkb keyboard state", __FILE__, __LINE__, __func__);

    int shift = (s.mods & ShiftMask) != 0 ? 1 : 0;
    if (shift == 0) shift =  (s.mods & Mod5Mask) != 0 ? 2 : 0;
    //int lock = (s.mods & LockMask) != 0 ? 1 : 0;
    //int ctrl = (s.mods & ControlMask) != 0 ? 1 : 0;
    //int mod1 = (s.mods & Mod1Mask) != 0 ? 1 : 0;
    //int mod2 = (s.mods & Mod2Mask) != 0 ? 1 : 0;
    //int mod3 = (s.mods & Mod3Mask) != 0 ? 1 : 0;
    //int mod4 = (s.mods & Mod4Mask) != 0 ? 1 : 0;
    //int mod5 = (s.mods & Mod5Mask) != 0 ? 1 : 0;
    KeySym keySym = XkbKeycodeToKeysym(e->Handle()->display, e->Handle()->keycode, 0, shift);

    char cadena[10];
    int overflow = 0;
    int nbytes = XkbTranslateKeySym(e->Handle()->display, &keySym, s.mods, cadena, 10, &overflow);
    Text keyText = nbytes > 0 ? cadena : "";

    ControlEventKey kr(*e, KeyCompositionSymbol(keySym, keyText));

    // Key redirection until the focused control catches it
    bool redirected = false;
    for (int i=0; i<controls->Count() && !redirected; i++)
        redirected = (*controls)[i]->OnKeyRelease(&kr);

    DelegationOnKeyRelease().Execute(e);
}
Beispiel #2
0
static void
Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
{
    static unsigned char compose[5];
    static int composing = -2;
    int kind = Kraw;

    int c, len, minmod;
    KeySym k, mk;
    Charfunc f;
    Modifiers md;
    char buf[100] = {0};

    c = 0;
    len = 0;

    /* Translate the keycode into a key symbol. */
    if(e->xany.type != KeyPress)
        return;
    XkbTranslateKeyCode(xkb, (KeyCode)e->xkey.keycode, e->xkey.state, &md, &k);
    XkbTranslateKeySym(e->xany.display, &k, e->xkey.state, buf, sizeof(buf) - 1, &len);

    /* Check to see if it's a specially-handled key first. */
    for (Keymapping *m = keymappings; m; m = m->next){
        KeySym u = NoSymbol;
        KeySym l = NoSymbol;
        XConvertCase(k, &l, &u);

        /* Note that magic bit manipulation here - we want to check that the
         * modifiers that are specified for the binding are all pressed, but
         * we allow other modifiers to be as well. This is because when NumLock
         * is on, it's always added to the modifier mask.
         */
        if (l == m->s || m->s == XK_VoidSymbol){
            if (m->m == 0 || (m->m & ~e->xkey.state) == 0){
                switch (m->c){
                    case Cnone:
                        return;

                    case Cdefault:
                        continue;

                    default:
                        f = ((GwinWidget)w)->gwin.gotchar;
                        if (f)
                            (*f)(m->c, m->k, Tcurrent, 0, 0, m->a);
                        return;
                }
            }
        }
    }

    /*
     * The following song and dance is so we can have our chosen
     * modifier key behave like a compose key, i.e, press and release
     * and then type the compose sequence, like Plan 9.  We have
     * to find out which key is the compose key first though.
     */
    if (IsModifierKey(k) && ((GwinWidget)w)->gwin.compose
            && composing == -2 && modmap) {
        minmod = (((GwinWidget)w)->gwin.compose+2)*keypermod;
        for (c = minmod; c < minmod+keypermod; c++) {
            XtTranslateKeycode(e->xany.display,
                    modmap->modifiermap[c],
                        e->xkey.state, &md, &mk);
            if (k == mk) {
                composing = -1;
                break;
            }
        }
        return;
    }

    /* Handle Multi_key separately, since it isn't a modifier */
    if(k == XK_Multi_key) {
        composing = -1;
        return;
    }

    if(k == NoSymbol || k > 0xff00)
        return;

    /* Check to see if we are in a composition sequence */
    if (!((GwinWidget)w)->gwin.compose && (e->xkey.state & Mod1Mask)
            && composing == -2)
        composing = -1;
    if (composing > -2) {
        compose[++composing] = k;
        if ((*compose == 'X') && (composing > 0)) {
            if ((k < '0') || (k > 'f') ||
                    ((k > '9') && (k < 'a'))) {
                STUFFCOMPOSE();
                c = (uint16_t)k;
                composing = -2;
            } else if (composing == 4) {
                c = unicode(compose);
                if (c == -1) {
                    STUFFCOMPOSE();
                    c = (uint16_t)compose[4];
                }
                composing = -2;
            }
        } else if (composing == 1) {
            c = (int)latin1(compose);
            if (c == -1) {
                STUFFCOMPOSE();
                c = (uint16_t)compose[1];
            }
            composing = -2;
        }
    } else {
        if (composing >= 0) {
            composing++;
            STUFFCOMPOSE();
        }
        c = keysymtoshort(k);
        composing = -2;
    }

    if (composing >= -1)
        return;

    f = ((GwinWidget)w)->gwin.gotchar;
    if(f)
        (*f)(c, kind, Tcurrent, 0, 0, NULL);
}
Beispiel #3
0
void XWindow::OnKeyPress(WindowEventKey *e)
{
    // ********************************************************************
    // Calculate keySym and keyText
    XkbStateRec s;
    Status st = XkbGetState(e->Handle()->display, XkbUseCoreKbd, &s);
    if (st != XkbOD_Success)
        throw new XException("Error getting xkb keyboard state", __FILE__, __LINE__, __func__);

    int shift = (s.mods & ShiftMask) != 0 ? 1 : 0;
    if (shift == 0) shift =  (s.mods & Mod5Mask) != 0 ? 2 : 0;
    //int lock = (s.mods & LockMask) != 0 ? 1 : 0;
    //int ctrl = (s.mods & ControlMask) != 0 ? 1 : 0;
    //int mod1 = (s.mods & Mod1Mask) != 0 ? 1 : 0;
    //int mod2 = (s.mods & Mod2Mask) != 0 ? 1 : 0;
    //int mod3 = (s.mods & Mod3Mask) != 0 ? 1 : 0;
    //int mod4 = (s.mods & Mod4Mask) != 0 ? 1 : 0;
    //int mod5 = (s.mods & Mod5Mask) != 0 ? 1 : 0;
    KeySym keySym = XkbKeycodeToKeysym(e->Handle()->display, e->Handle()->keycode, 0, shift);

    char cadena[10];
    int overflow = 0;
    int nbytes = XkbTranslateKeySym(e->Handle()->display, &keySym, s.mods, cadena, 10, &overflow);
    Text keyText = nbytes > 0 ? cadena : "";


    // ********************************************************************
    // Manage KeyPreview and KeyPress events
    ControlEventKey ek(*e, KeyCompositionSymbol(keySym, keyText));

    // Key preview to every control
    for (int i=0; i<controls->Count(); i++)
        (*controls)[i]->OnKeyPreview(&ek);

    // OnKeyPress until the focused control catches it
    bool redirected = false;
    for (int i=0; i<controls->Count() && !redirected; i++)
        redirected = (*controls)[i]->OnKeyPress(&ek);

    // Noone catched the event?
    if (!redirected) {
        if (keySym == KeySymbols::Tab) {
            // Window focus rotate
            if (!e->PressedShift()) ControlFocusNext();
            else ControlFocusPrevious();
        } else if (keySym == KeySymbols::Return) {
            // Return: Window Accept
        } else if (keySym == KeySymbols::Escape) {
            // Escape: Window Cancel
        } else if (keySym == KeySymbols::Space) {
            // Return: Window Accept
        }
    }

    DelegationOnKeyPress().Execute(e);


    // ********************************************************************
    // Manage KeySymbol event
    bool continueComposing = false;
    Text t = KeyCompositionManager::Default().GetComposedKeySym(*composeKeySymBuffer + keyText, continueComposing);
    *composeKeySymBuffer = continueComposing ? *composeKeySymBuffer + keyText : "";

    // Send Key Symbol Event
    if (!continueComposing) {
        KeyCompositionSymbol symbol(t == keyText ? keySym : 0, t);
        WindowEventKeySymbol weks(symbol);
        OnKeySymbol(&weks);
    }
}
Beispiel #4
0
int
XLookupString (	register XKeyEvent *	event,
		char *			buffer,
		int 			nbytes,
		KeySym *		keysym,
		XComposeStatus *	status)
{
    KeySym	dummy;
    int rtrnLen;
    unsigned int new_mods;
    Display *dpy = event->display;

    if (keysym==NULL)
	keysym= &dummy;
    if (!XkbLookupKeySym(dpy,event->keycode,event->state, &new_mods,keysym))
	return 0;
    new_mods= (event->state&(~new_mods));

    /* find the group where a symbol can be converted to control one */
    if (new_mods&ControlMask && *keysym > 0x7F &&
	(dpy->xkb_info->xlib_ctrls & XkbLC_ControlFallback)) {
	XKeyEvent tmp_ev = *event;
	KeySym tmp_keysym;
	unsigned int tmp_new_mods;
	if (_XkbUnavailable(dpy)) {
            tmp_ev.state= event->state ^ dpy->mode_switch;
            if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state,
                                &tmp_new_mods, &tmp_keysym) &&
                tmp_keysym != NoSymbol && tmp_keysym < 0x80 ) {
                *keysym = tmp_keysym;
            }
        } else {
            int n = XkbKeyNumGroups(dpy->xkb_info->desc, tmp_ev.keycode);
            int i;
            for (i = 0; i < n; i++) {
                if (XkbGroupForCoreState(event->state) == i)
                    continue;
                tmp_ev.state= XkbBuildCoreState(tmp_ev.state, i);
                if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state,
                                     &tmp_new_mods, &tmp_keysym) &&
                    tmp_keysym != NoSymbol && tmp_keysym < 0x80 ) {
                    *keysym = tmp_keysym;
                    new_mods= (event->state&(~tmp_new_mods));
                    break;
                }
            }
        }
    }

#ifdef USE_OWN_COMPOSE
    if ( status ) {
	static int been_here= 0;
	if ( !been_here ) {
	    XimCompInitTables();
	    been_here = 1;
	}
	if ( !XimCompLegalStatus(status) ) {
	    status->compose_ptr = NULL;
	    status->chars_matched = 0;
	}
	if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL)) ||
		XimCompIsComposeKey(*keysym,event->keycode,status) ) {
	    XimCompRtrn rtrn;

	    switch (XimCompProcessSym(status,*keysym,&rtrn)) {
		case XIM_COMP_IGNORE:
		    break;
		case XIM_COMP_IN_PROGRESS:
		    if ( keysym!=NULL )
			*keysym = NoSymbol;
#ifndef NO_COMPOSE_LED
		    if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) {
			XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
						True,True,False,NULL);
		    }
#endif
		    return 0;
		case XIM_COMP_FAIL:
		{
		    static Atom _ComposeFail= None;
		    int n = 0, len= 0;
#ifndef NO_COMPOSE_LED
		    if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) {
			XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
						True,False,False,NULL);
		    }
#endif
#ifndef NO_BELL_ON_COMPOSE_FAIL
		    if (dpy->xkb_info->xlib_ctrls&XkbLC_BeepOnComposeFail) {
			if (_ComposeFail==None)
			    _ComposeFail= XInternAtom(dpy,"ComposeFail",0);
			XkbBell(dpy,event->window,0,_ComposeFail);
		    }
#endif
		    for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
			if ( nbytes-len > 0 ) {
			    len+= XkbTranslateKeySym(dpy,&rtrn.sym[n],new_mods,
							buffer+len,nbytes-len,
							NULL);
			}
		    }
		    if ( keysym!=NULL ) {
			if ( n==1 )	*keysym = rtrn.sym[0];
			else		*keysym = NoSymbol;
		    }
		    return len;
		}
		case XIM_COMP_SUCCEED:
		{
		    int len,n = 0;

#ifndef NO_COMPOSE_LED
		    if ( dpy->xkb_info->xlib_ctrls&XkbLC_ComposeLED ) {
			XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
						True,False,False,NULL);
		    }
#endif
		    *keysym = rtrn.matchSym;
		    if ( rtrn.str[0]!='\0' ) {
			strncpy(buffer,rtrn.str,nbytes-1);
			buffer[nbytes-1]= '\0';
			len = (int)strlen(buffer);
		    }
		    else {
			len = XkbTranslateKeySym(dpy,keysym,new_mods,
							buffer,nbytes,
							NULL);
		    }
		    for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
			if ( nbytes-len > 0 ) {
			    len+= XkbTranslateKeySym(dpy,&rtrn.sym[n],
							event->state,
							buffer+len,nbytes-len,
							NULL);
			}
		    }
		    return len;
		}
	    }
	}
    }
#endif

    /* We *should* use the new_mods (which does not contain any modifiers */
    /* that were used to compute the symbol here, but pre-XKB XLookupString */
    /* did not and we have to remain compatible.  Sigh. */
    if (_XkbUnavailable(dpy) ||
	(dpy->xkb_info->xlib_ctrls&XkbLC_ConsumeLookupMods)==0)
	new_mods= event->state;

    rtrnLen= XkbLookupKeyBinding(dpy,*keysym,new_mods,buffer,nbytes,NULL);
    if (rtrnLen>0)
	return rtrnLen;

    return XkbTranslateKeySym(dpy,keysym,new_mods,buffer,nbytes,NULL);
}