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); }
void CKeyState::fakeAllKeysUp() { Keystrokes keys; for (KeyButton i = 0; i < IKeyState::kNumButtons; ++i) { if (m_syntheticKeys[i] > 0) { keys.push_back(Keystroke(i, false, false, m_keyClientData[i])); m_keys[i] = 0; m_syntheticKeys[i] = 0; } } fakeKeys(keys, 1); }
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::fakeAllKeysUp() { Keystrokes keys; for (KeyButton i = 0; i < IKeyState::kNumButtons; ++i) { if (m_syntheticKeys[i] > 0) { keys.push_back(Keystroke(i, false, false, m_keyClientData[i])); m_keys[i] = 0; m_syntheticKeys[i] = 0; } } fakeKeys(keys, 1); memset(&m_serverKeys, 0, sizeof(m_serverKeys)); m_activeModifiers.clear(); m_mask = pollActiveModifiers(); }
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); }
bool KeyState::fakeKeyUp(KeyButton serverID) { // if we haven't seen this button go down then ignore it KeyButton localID = m_serverKeys[serverID & kButtonMask]; if (localID == 0) { return false; } // get the sequence of keys to simulate key release Keystrokes keys; keys.push_back(Keystroke(localID, false, false, m_keyClientData[localID])); // note keys down --m_keys[localID]; --m_syntheticKeys[localID]; m_serverKeys[serverID] = 0; // check if this is a modifier ModifierToKeys::iterator i = m_activeModifiers.begin(); while (i != m_activeModifiers.end()) { if (i->second.m_button == localID && !i->second.m_lock) { // modifier is no longer down KeyModifierMask mask = i->first; ModifierToKeys::iterator tmp = i; ++i; m_activeModifiers.erase(tmp); if (m_activeModifiers.count(mask) == 0) { // no key for modifier is down so deactivate modifier m_mask &= ~mask; LOG((CLOG_DEBUG1 "new state %04x", m_mask)); } } else { ++i; } } // generate key events fakeKeys(keys, 1); return true; }