void
CKeyState::fakeKeyRepeat(
				KeyID id, KeyModifierMask mask,
				SInt32 count, KeyButton serverID)
{
	serverID &= kButtonMask;

	// if we haven't seen this button go down then ignore it
	KeyButton oldLocalID = m_serverKeys[serverID];
	if (oldLocalID == 0) {
		return;
	}

	// get keys for key repeat
	Keystrokes keys;
	ModifierToKeys oldActiveModifiers = m_activeModifiers;
	const CKeyMap::KeyItem* keyItem =
		m_keyMap.mapKey(keys, id, pollActiveGroup(),
								m_activeModifiers, m_mask, mask, true);
	if (keyItem == NULL) {
		return;
	}
	KeyButton localID = (KeyButton)(keyItem->m_button & kButtonMask);
	if (localID == 0) {
		return;
	}

	// if the KeyButton for the auto-repeat is not the same as for the
	// initial press then mark the initial key as released and the new
	// key as pressed.  this can happen when we auto-repeat after a
	// dead key.  for example, a dead accent followed by 'a' will
	// generate an 'a with accent' followed by a repeating 'a'.  the
	// KeyButtons for the two KeyIDs might be different.
	if (localID != oldLocalID) {
		// replace key up with previous KeyButton but leave key down
		// alone so it uses the new KeyButton.
		for (Keystrokes::iterator index = keys.begin();
								index != keys.end(); ++index) {
			if (index->m_type == Keystroke::kButton &&
				index->m_data.m_button.m_button == localID) {
				index->m_data.m_button.m_button = oldLocalID;
				break;
			}
		}

		// note that old key is now up
		--m_keys[oldLocalID];
		--m_syntheticKeys[oldLocalID];

		// note keys down
		updateModifierKeyState(localID, oldActiveModifiers, m_activeModifiers);
		++m_keys[localID];
		++m_syntheticKeys[localID];
		m_keyClientData[localID] = keyItem->m_client;
		m_serverKeys[serverID]   = localID;
	}

	// generate key events
	fakeKeys(keys, count);
}
Exemple #2
0
void
KeyState::fakeKeyDown(KeyID id, KeyModifierMask mask, KeyButton serverID)
{
    // if this server key is already down then this is probably a
    // mis-reported autorepeat.
    serverID &= kButtonMask;
    if (m_serverKeys[serverID] != 0) {
        fakeKeyRepeat(id, mask, 1, serverID);
        return;
    }

    // ignore certain keys
    if (isIgnoredKey(id, mask)) {
        LOG((CLOG_DEBUG1 "ignored key %04x %04x", id, mask));
        return;
    }

    // get keys for key press
    Keystrokes keys;
    ModifierToKeys oldActiveModifiers = m_activeModifiers;
    const barrier::KeyMap::KeyItem* keyItem =
        m_keyMap.mapKey(keys, id, pollActiveGroup(), m_activeModifiers,
                                getActiveModifiersRValue(), mask, false);
    if (keyItem == NULL) {
        // a media key won't be mapped on mac, so we need to fake it in a
        // special way
        if (id == kKeyAudioDown || id == kKeyAudioUp ||
            id == kKeyAudioMute || id == kKeyAudioPlay ||
            id == kKeyAudioPrev || id == kKeyAudioNext ||
            id == kKeyBrightnessDown || id == kKeyBrightnessUp
            ) {
            LOG((CLOG_DEBUG1 "emulating media key"));
            fakeMediaKey(id);
        }
        
        return;
    }
    
    KeyButton localID = (KeyButton)(keyItem->m_button & kButtonMask);
    updateModifierKeyState(localID, oldActiveModifiers, m_activeModifiers);
    if (localID != 0) {
        // note keys down
        ++m_keys[localID];
        ++m_syntheticKeys[localID];
        m_keyClientData[localID] = keyItem->m_client;
        m_serverKeys[serverID]   = localID;
    }

    // generate key events
    fakeKeys(keys, 1);
}
void
CKeyState::fakeKeyDown(KeyID id, KeyModifierMask mask, KeyButton serverID)
{
	// ignore key if serverID is bogus
	serverID &= kButtonMask;
	if (serverID == 0) {
		LOG((CLOG_DEBUG1 "ignored fake key for %04x with serverID of 0", id));
		return;
	}

	// if this server key is already down then this is probably a
	// mis-reported autorepeat.
	if (m_serverKeys[serverID] != 0) {
		fakeKeyRepeat(id, mask, 1, serverID);
		return;
	}

	// ignore certain keys
	if (isIgnoredKey(id, mask)) {
		LOG((CLOG_DEBUG1 "ignored key %04x %04x", id, mask));
		return;
	}

	// get keys for key press
	Keystrokes keys;
	ModifierToKeys oldActiveModifiers = m_activeModifiers;
	const CKeyMap::KeyItem* keyItem =
		m_keyMap.mapKey(keys, id, pollActiveGroup(),
								m_activeModifiers, m_mask, mask, false);
	if (keyItem == NULL) {
		return;
	}
	KeyButton localID = (KeyButton)(keyItem->m_button & kButtonMask);
	if (localID != 0) {
		// note keys down
		updateModifierKeyState(localID, oldActiveModifiers, m_activeModifiers);
		++m_keys[localID];
		++m_syntheticKeys[localID];
		m_keyClientData[localID] = keyItem->m_client;
		m_serverKeys[serverID]   = localID;
	}

	// generate key events
	fakeKeys(keys, 1);
}