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 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); }