示例#1
0
unsigned
XkbKeysymToModifiers(Display *dpy,KeySym ks)
{
    XkbDescRec *xkb;
    register int i,j;
    register KeySym *pSyms;
    CARD8 mods;

    if (_XkbUnavailable(dpy))
	return _XKeysymToModifiers(dpy,ks);
    _XkbCheckPendingRefresh(dpy,dpy->xkb_info);

    if (_XkbNeedModmap(dpy->xkb_info)&&(!_XkbComputeModmap(dpy)))
	return _XKeysymToModifiers(dpy,ks);

    xkb= dpy->xkb_info->desc;
    mods= 0;
    for (i = xkb->min_key_code; i <= (int)xkb->max_key_code; i++) {
	pSyms= XkbKeySymsPtr(xkb,i);
	for (j=XkbKeyNumSyms(xkb,i)-1;j>=0;j--) {
	    if (pSyms[j]==ks) {
		mods|= xkb->map->modmap[i];
		break;
	    }
	}
    }
    return mods;
}
static int
check_modmap_change_slave(ClientPtr client, DeviceIntPtr master,
                          DeviceIntPtr slave, CARD8 *modmap)
{
    XkbDescPtr master_xkb, slave_xkb;
    int i, j;

    if (!slave->key || !master->key)
        return 0;

    master_xkb = master->key->xkbInfo->desc;
    slave_xkb = slave->key->xkbInfo->desc;

    /* Ignore devices with a clearly different keymap. */
    if (slave_xkb->min_key_code != master_xkb->min_key_code ||
        slave_xkb->max_key_code != master_xkb->max_key_code)
        return 0;

    for (i = 0; i < MAP_LENGTH; i++) {
        if (!modmap[i])
            continue;

        /* If we have different symbols for any modifier on an
         * extended keyboard, ignore the whole remap request. */
        for (j = 0;
             j < XkbKeyNumSyms(slave_xkb, i) &&
              j < XkbKeyNumSyms(master_xkb, i);
             j++)
            if (XkbKeySymsPtr(slave_xkb, i)[j] != XkbKeySymsPtr(master_xkb, i)[j])
                return 0;
    }

    if (check_modmap_change(client, slave, modmap) != Success)
        return 0;

    return 1;
}
示例#3
0
static CARD32
AccessXSlowKeyExpire(OsTimerPtr timer,CARD32 now,pointer arg)
{
    DeviceIntPtr	keybd;
    XkbSrvInfoPtr	xkbi;
    XkbDescPtr	xkb;
    XkbControlsPtr	ctrls;

    keybd= 	(DeviceIntPtr)arg;
    xkbi= 	keybd->key->xkbInfo;
    xkb= 	xkbi->desc;
    ctrls= 	xkb->ctrls;
    if (xkbi->slowKey!=0) {
        xkbAccessXNotify ev;
        KeySym *sym= XkbKeySymsPtr(xkb,xkbi->slowKey);
        ev.detail= XkbAXN_SKAccept;
        ev.keycode= xkbi->slowKey;
        ev.slowKeysDelay= ctrls->slow_keys_delay;
        ev.debounceDelay= ctrls->debounce_delay;
        XkbSendAccessXNotify(keybd,&ev);
        if (XkbAX_NeedFeedback(ctrls,XkbAX_SKAcceptFBMask))
            XkbDDXAccessXBeep(keybd,_BEEP_SLOW_ACCEPT,XkbSlowKeysMask);
        AccessXKeyboardEvent(keybd,KeyPress,xkbi->slowKey,False);
        /* check for magic sequences */
        if ((ctrls->enabled_ctrls&XkbAccessXKeysMask) &&
                ((sym[0]==XK_Shift_R)||(sym[0]==XK_Shift_L)))
            xkbi->shiftKeyCount++;

        /* Start repeating if necessary.  Stop autorepeating if the user
         * presses a non-modifier key that doesn't autorepeat.
         */
        if (keybd->kbdfeed->ctrl.autoRepeat &&
                ((xkbi->slowKey != xkbi->mouseKey) || (!xkbi->mouseKeysAccel)) &&
                (ctrls->enabled_ctrls&XkbRepeatKeysMask)) {
            if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats,xkbi->slowKey)) {
                xkbi->repeatKey = xkbi->slowKey;
                xkbi->repeatKeyTimer= TimerSet(xkbi->repeatKeyTimer,
                                               0, ctrls->repeat_delay,
                                               AccessXRepeatKeyExpire, (pointer)keybd);
            }
        }
    }
    return 0;
}
示例#4
0
/* Stolen from libX11 */
static Bool
XkbTranslateKeyCode(register XkbDescPtr xkb, KeyCode key,
                    register unsigned int mods, unsigned int *mods_rtrn,
                    KeySym *keysym_rtrn)
{
	XkbKeyTypeRec *type;
	int col,nKeyGroups;
	unsigned preserve,effectiveGroup;
	KeySym *syms;

	if (mods_rtrn!=NULL)
		*mods_rtrn = 0;

	nKeyGroups= XkbKeyNumGroups(xkb,key);
	if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) {
		if (keysym_rtrn!=NULL)
			*keysym_rtrn = NoSymbol;
		return False;
	}

	syms = XkbKeySymsPtr(xkb,key);

	/* find the offset of the effective group */
	col = 0;
	effectiveGroup= XkbGroupForCoreState(mods);
	if ( effectiveGroup>=nKeyGroups ) {
		unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
		switch (XkbOutOfRangeGroupAction(groupInfo)) {
		default:
			effectiveGroup %= nKeyGroups;
			break;
		case XkbClampIntoRange:
			effectiveGroup = nKeyGroups-1;
			break;
		case XkbRedirectIntoRange:
			effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
			if (effectiveGroup>=nKeyGroups)
				effectiveGroup= 0;
			break;
		}
	}
	col= effectiveGroup*XkbKeyGroupsWidth(xkb,key);
	type = XkbKeyKeyType(xkb,key,effectiveGroup);

	preserve= 0;
	if (type->map) { /* find the column (shift level) within the group */
		register int i;
		register XkbKTMapEntryPtr entry;
		for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
			if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) {
				col+= entry->level;
				if (type->preserve)
					preserve= type->preserve[i].mask;
				break;
			}
		}
	}

	if (keysym_rtrn!=NULL)
		*keysym_rtrn= syms[col];
	if (mods_rtrn)
		*mods_rtrn= type->mods.mask&(~preserve);

	return (syms[col]!=NoSymbol);
}
示例#5
0
KeyCode vncAddKeysym(KeySym keysym, unsigned state)
{
	DeviceIntPtr master;
	XkbDescPtr xkb;
	unsigned int key;

	XkbEventCauseRec cause;
	XkbChangesRec changes;

	int types[1];
	KeySym *syms;
	KeySym upper, lower;

	master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT);
	xkb = master->key->xkbInfo->desc;
	for (key = xkb->max_key_code; key >= xkb->min_key_code; key--) {
		if (XkbKeyNumGroups(xkb, key) == 0)
			break;
	}

	if (key < xkb->min_key_code)
		return 0;

	memset(&changes, 0, sizeof(changes));
	memset(&cause, 0, sizeof(cause));

	XkbSetCauseUnknown(&cause);

	/*
	 * Tools like xkbcomp get confused if there isn't a name
	 * assigned to the keycode we're trying to use.
	 */
	if (xkb->names && xkb->names->keys &&
	    (xkb->names->keys[key].name[0] == '\0')) {
		xkb->names->keys[key].name[0] = 'I';
		xkb->names->keys[key].name[1] = '0' + (key / 100) % 10;
		xkb->names->keys[key].name[2] = '0' + (key /  10) % 10;
		xkb->names->keys[key].name[3] = '0' + (key /   1) % 10;

		changes.names.changed |= XkbKeyNamesMask;
		changes.names.first_key = key;
		changes.names.num_keys = 1;
	}

	/* FIXME: Verify that ONE_LEVEL/ALPHABETIC isn't screwed up */

	/*
	 * For keysyms that are affected by Lock, we are better off
	 * using ALPHABETIC rather than ONE_LEVEL as the latter
	 * generally cannot produce lower case when Lock is active.
	 */
	XkbConvertCase(keysym, &lower, &upper);
	if (upper == lower)
		types[XkbGroup1Index] = XkbOneLevelIndex;
	else
		types[XkbGroup1Index] = XkbAlphabeticIndex;

	XkbChangeTypesOfKey(xkb, key, 1, XkbGroup1Mask, types, &changes.map);

	syms = XkbKeySymsPtr(xkb,key);
	if (upper == lower)
		syms[0] = keysym;
	else {
		syms[0] = lower;
		syms[1] = upper;
	}

	changes.map.changed |= XkbKeySymsMask;
	changes.map.first_key_sym = key;
	changes.map.num_key_syms = 1;

	XkbSendNotification(master, &changes, &cause);

	return key;
}
示例#6
0
Bool
AccessXFilterReleaseEvent(	register xEvent *	xE,
                            register DeviceIntPtr	keybd,
                            int			count)
{
    XkbSrvInfoPtr	xkbi = keybd->key->xkbInfo;
    XkbControlsPtr	ctrls = xkbi->desc->ctrls;
    KeyCode		key = xE->u.u.detail;
    Bool		ignoreKeyEvent = FALSE;

    /* Don't transmit the KeyRelease if BounceKeys is on and
     * this is the release of a key that was ignored due to
     * BounceKeys.
     */
    if (ctrls->enabled_ctrls & XkbBounceKeysMask) {
        if ((key!=xkbi->mouseKey)&&(!BitIsOn(keybd->key->down,key)))
            ignoreKeyEvent = TRUE;
        xkbi->inactiveKey= key;
        xkbi->bounceKeysTimer= TimerSet(xkbi->bounceKeysTimer, 0,
                                        ctrls->debounce_delay,
                                        AccessXBounceKeyExpire, (pointer)keybd);
    }

    /* Don't transmit the KeyRelease if SlowKeys is turned on and
     * the user didn't hold the key long enough.  We know we passed
     * the key if the down bit was set by CoreProcessKeyboadEvent.
     */
    if (ctrls->enabled_ctrls & XkbSlowKeysMask) {
        xkbAccessXNotify	ev;
        unsigned		beep_type;
        ev.keycode= key;
        ev.slowKeysDelay= ctrls->slow_keys_delay;
        ev.debounceDelay= ctrls->debounce_delay;
        if (BitIsOn(keybd->key->down,key) | (xkbi->mouseKey == key)) {
            ev.detail= XkbAXN_SKRelease;
            beep_type= _BEEP_SLOW_RELEASE;
        }
        else {
            ev.detail= XkbAXN_SKReject;
            beep_type= _BEEP_SLOW_REJECT;
            ignoreKeyEvent = TRUE;
        }
        XkbSendAccessXNotify(keybd,&ev);
        if (XkbAX_NeedFeedback(ctrls,XkbAX_SKRejectFBMask)) {
            XkbDDXAccessXBeep(keybd,beep_type,XkbSlowKeysMask);
        }
        if (xkbi->slowKey==key)
            xkbi->slowKey= 0;
    }

    /* Stop Repeating if the user releases the key that is currently
     * repeating.
     */
    if (xkbi->repeatKey==key) {
        xkbi->repeatKey= 0;
    }

    if ((ctrls->enabled_ctrls&XkbAccessXTimeoutMask)&&(ctrls->ax_timeout>0)) {
        xkbi->lastPtrEventTime= 0;
        xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0,
                                 ctrls->ax_timeout*1000,
                                 AccessXTimeoutExpire, (pointer)keybd);
        xkbi->krgTimerActive= _ALL_TIMEOUT_TIMER;
    }
    else if (xkbi->krgTimerActive!=_OFF_TIMER) {
        xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 0, NULL, NULL);
        xkbi->krgTimerActive= _OFF_TIMER;
    }

    /* Keep track of how many times the Shift key has been pressed.
     * If it has been pressed and released 5 times in a row, toggle
     * the state of StickyKeys.
     */
    if ((!ignoreKeyEvent)&&(xkbi->shiftKeyCount)) {
        KeySym *pSym= XkbKeySymsPtr(xkbi->desc,key);
        if ((pSym[0]!=XK_Shift_L)&&(pSym[0]!=XK_Shift_R)) {
            xkbi->shiftKeyCount= 0;
        }
        else if (xkbi->shiftKeyCount>=5) {
            xkbControlsNotify cn;
            cn.keycode = key;
            cn.eventType = KeyPress;
            cn.requestMajor = 0;
            cn.requestMinor = 0;
            if (ctrls->enabled_ctrls & XkbStickyKeysMask)
                AccessXStickyKeysTurnOff(keybd,&cn);
            else
                AccessXStickyKeysTurnOn(keybd,&cn);
            xkbi->shiftKeyCount= 0;
        }
    }

    if (!ignoreKeyEvent)
        XkbProcessKeyboardEvent(xE,keybd,count);
    return ignoreKeyEvent;

} /* AccessXFilterReleaseEvent */
示例#7
0
Bool
AccessXFilterPressEvent(	register xEvent *	xE,
                            register DeviceIntPtr	keybd,
                            int			count)
{
    XkbSrvInfoPtr	xkbi = keybd->key->xkbInfo;
    XkbControlsPtr	ctrls = xkbi->desc->ctrls;
    Bool		ignoreKeyEvent = FALSE;
    KeyCode		key = xE->u.u.detail;
    KeySym *	sym = XkbKeySymsPtr(xkbi->desc,key);

    if (ctrls->enabled_ctrls&XkbAccessXKeysMask) {
        /* check for magic sequences */
        if ((sym[0]==XK_Shift_R)||(sym[0]==XK_Shift_L)) {
            if (XkbAX_NeedFeedback(ctrls,XkbAX_SlowWarnFBMask)) {
                xkbi->krgTimerActive = _KRG_WARN_TIMER;
                xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 4000,
                                         AccessXKRGExpire, (pointer)keybd);
            }
            else {
                xkbi->krgTimerActive = _KRG_TIMER;
                xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 8000,
                                         AccessXKRGExpire, (pointer)keybd);
            }
            if (!(ctrls->enabled_ctrls & XkbSlowKeysMask)) {
                CARD32 now= GetTimeInMillis();
                if ((now-xkbi->lastShiftEventTime)>15000)
                    xkbi->shiftKeyCount= 1;
                else xkbi->shiftKeyCount++;
                xkbi->lastShiftEventTime= now;
            }
        }
        else {
            if (xkbi->krgTimerActive) {
                xkbi->krgTimer= TimerSet(xkbi->krgTimer,0, 0, NULL, NULL);
                xkbi->krgTimerActive= _OFF_TIMER;
            }
        }
    }

    /* Don't transmit the KeyPress if SlowKeys is turned on;
     * The wakeup handler will synthesize one for us if the user
     * has held the key long enough.
     */
    if (ctrls->enabled_ctrls & XkbSlowKeysMask) {
        xkbAccessXNotify	ev;
        /* If key was already pressed, ignore subsequent press events
         * from the server's autorepeat
         */
        if(xkbi->slowKey == key)
            return TRUE;
        ev.detail= XkbAXN_SKPress;
        ev.keycode= key;
        ev.slowKeysDelay= ctrls->slow_keys_delay;
        ev.debounceDelay= ctrls->debounce_delay;
        XkbSendAccessXNotify(keybd,&ev);
        if (XkbAX_NeedFeedback(ctrls,XkbAX_SKPressFBMask))
            XkbDDXAccessXBeep(keybd,_BEEP_SLOW_PRESS,XkbSlowKeysMask);
        xkbi->slowKey= key;
        xkbi->slowKeysTimer = TimerSet(xkbi->slowKeysTimer,
                                       0, ctrls->slow_keys_delay,
                                       AccessXSlowKeyExpire, (pointer)keybd);
        ignoreKeyEvent = TRUE;
    }

    /* Don't transmit the KeyPress if BounceKeys is turned on
     * and the user pressed the same key within a given time period
     * from the last release.
     */
    else if ((ctrls->enabled_ctrls & XkbBounceKeysMask) &&
             (key == xkbi->inactiveKey)) {
        if (XkbAX_NeedFeedback(ctrls,XkbAX_BKRejectFBMask))
            XkbDDXAccessXBeep(keybd,_BEEP_BOUNCE_REJECT,XkbBounceKeysMask);
        ignoreKeyEvent = TRUE;
    }

    /* Start repeating if necessary.  Stop autorepeating if the user
     * presses a non-modifier key that doesn't autorepeat.
     */
    if (XkbDDXUsesSoftRepeat(keybd)) {
        if ((keybd->kbdfeed->ctrl.autoRepeat) &&
                ((ctrls->enabled_ctrls&(XkbSlowKeysMask|XkbRepeatKeysMask))==
                 XkbRepeatKeysMask)) {
            if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats,key) &&
                    !keybd->key->modifierMap[key]) {
#ifdef DEBUG
                if (xkbDebugFlags&0x10)
                    ErrorF("Starting software autorepeat...\n");
#endif
                xkbi->repeatKey = key;
                xkbi->repeatKeyTimer= TimerSet(xkbi->repeatKeyTimer,
                                               0, ctrls->repeat_delay,
                                               AccessXRepeatKeyExpire, (pointer)keybd);
            }
        }
    }

    /* Check for two keys being pressed at the same time.  This section
     * essentially says the following:
     *
     *	If StickyKeys is on, and a modifier is currently being held down,
     *  and one of the following is true:  the current key is not a modifier
     *  or the currentKey is a modifier, but not the only modifier being
     *  held down, turn StickyKeys off if the TwoKeys off ctrl is set.
     */
    if ((ctrls->enabled_ctrls & XkbStickyKeysMask) &&
            (xkbi->state.base_mods!=0) &&
            (XkbAX_NeedOption(ctrls,XkbAX_TwoKeysMask))) {
        xkbControlsNotify cn;
        cn.keycode = key;
        cn.eventType = KeyPress;
        cn.requestMajor = 0;
        cn.requestMinor = 0;
        AccessXStickyKeysTurnOff(keybd,&cn);
    }

    if (!ignoreKeyEvent)
        XkbProcessKeyboardEvent(xE,keybd,count);
    return ignoreKeyEvent;
} /* AccessXFilterPressEvent */
示例#8
0
Bool
XkbTranslateKeyCode(	register XkbDescPtr	xkb,
			KeyCode 		key,
			register unsigned int 	mods,
			unsigned int *		mods_rtrn,
			KeySym *		keysym_rtrn)
{
    XkbKeyTypeRec *type;
    int col,nKeyGroups;
    unsigned preserve,effectiveGroup;
    KeySym *syms;

    if (mods_rtrn!=NULL)
	*mods_rtrn = 0;

    nKeyGroups= XkbKeyNumGroups(xkb,key);
    if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) {
	if (keysym_rtrn!=NULL)
	    *keysym_rtrn = NoSymbol;
	return False;
    }

    syms = XkbKeySymsPtr(xkb,key);

    /* find the offset of the effective group */
    col = 0;
    effectiveGroup= XkbGroupForCoreState(mods);
    if ( effectiveGroup>=nKeyGroups ) {
	unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
	switch (XkbOutOfRangeGroupAction(groupInfo)) {
	    default:
		effectiveGroup %= nKeyGroups;
		break;
	    case XkbClampIntoRange:
		effectiveGroup = nKeyGroups-1;
		break;
	    case XkbRedirectIntoRange:
		effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
		if (effectiveGroup>=nKeyGroups)
		    effectiveGroup= 0;
		break;
	}
    }
    col= effectiveGroup*XkbKeyGroupsWidth(xkb,key);
    type = XkbKeyKeyType(xkb,key,effectiveGroup);

    preserve= 0;
    if (type->map) { /* find the column (shift level) within the group */
	register int i;
	register XkbKTMapEntryPtr entry;
	for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
	    if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) {
		col+= entry->level;
		if (type->preserve)
		    preserve= type->preserve[i].mask;
		break;
	    }
	}
    }

    if (keysym_rtrn!=NULL)
	*keysym_rtrn= syms[col];
    if (mods_rtrn) {
	*mods_rtrn= type->mods.mask&(~preserve);
	/* The Motif VTS doesn't get the help callback called if help
	 * is bound to Shift+<whatever>, and it appears as though it
	 * is XkbTranslateKeyCode that is causing the problem.  The
	 * core X version of XTranslateKey always OR's in ShiftMask
	 * and LockMask for mods_rtrn, so this "fix" keeps this behavior
	 * and solves the VTS problem.
	 */
	if ((xkb->dpy)&&(xkb->dpy->xkb_info)&&
	    (xkb->dpy->xkb_info->xlib_ctrls&XkbLC_AlwaysConsumeShiftAndLock)) {
	    *mods_rtrn|= (ShiftMask|LockMask);
	}
    }
    return (syms[col]!=NoSymbol);
}