Пример #1
0
bool
CKeyMap::keysToRestoreModifiers(const KeyItem& keyItem, SInt32,
				ModifierToKeys& activeModifiers,
				KeyModifierMask& currentState,
				const ModifierToKeys& desiredModifiers,
				Keystrokes& keystrokes) const
{
	// XXX -- we're not considering modified modifiers here

	ModifierToKeys oldModifiers = activeModifiers;

	// get the pressed modifier buttons before and after
	ButtonToKeyMap oldKeys, newKeys;
	collectButtons(oldModifiers, oldKeys);
	collectButtons(desiredModifiers, newKeys);

	// release unwanted keys
	for (ModifierToKeys::const_iterator i = oldModifiers.begin();
								i != oldModifiers.end(); ++i) {
		KeyButton button = i->second.m_button;
		if (button != keyItem.m_button && newKeys.count(button) == 0) {
			EKeystroke type = kKeystrokeRelease;
			if (i->second.m_lock) {
				type = kKeystrokeUnmodify;
			}
			addKeystrokes(type, i->second,
								activeModifiers, currentState, keystrokes);
		}
	}

	// press wanted keys
	for (ModifierToKeys::const_iterator i = desiredModifiers.begin();
								i != desiredModifiers.end(); ++i) {
		KeyButton button = i->second.m_button;
		if (button != keyItem.m_button && oldKeys.count(button) == 0) {
			EKeystroke type = kKeystrokePress;
			if (i->second.m_lock) {
				type = kKeystrokeModify;
			}
			addKeystrokes(type, i->second,
								activeModifiers, currentState, keystrokes);
		}
	}

	return true;
}
Пример #2
0
void
CKeyState::updateModifierKeyState(KeyButton button,
				const ModifierToKeys& oldModifiers,
				const ModifierToKeys& newModifiers)
{
	// get the pressed modifier buttons before and after
	CKeyMap::ButtonToKeyMap oldKeys, newKeys;
	for (ModifierToKeys::const_iterator i = oldModifiers.begin();
								i != oldModifiers.end(); ++i) {
		oldKeys.insert(std::make_pair(i->second.m_button, &i->second));
	}
	for (ModifierToKeys::const_iterator i = newModifiers.begin();
								i != newModifiers.end(); ++i) {
		newKeys.insert(std::make_pair(i->second.m_button, &i->second));
	}

	// get the modifier buttons that were pressed or released
	CKeyMap::ButtonToKeyMap pressed, released;
	std::set_difference(oldKeys.begin(), oldKeys.end(),
						newKeys.begin(), newKeys.end(),
						std::inserter(released, released.end()),
						ButtonToKeyLess());
	std::set_difference(newKeys.begin(), newKeys.end(),
						oldKeys.begin(), oldKeys.end(),
						std::inserter(pressed, pressed.end()),
						ButtonToKeyLess());

	// update state
	for (CKeyMap::ButtonToKeyMap::const_iterator i = released.begin();
								i != released.end(); ++i) {
		if (i->first != button) {
			m_keys[i->first]          = 0;
			m_syntheticKeys[i->first] = 0;
		}
	}
	for (CKeyMap::ButtonToKeyMap::const_iterator i = pressed.begin();
								i != pressed.end(); ++i) {
		if (i->first != button) {
			m_keys[i->first]          = 1;
			m_syntheticKeys[i->first] = 1;
			m_keyClientData[i->first] = i->second->m_client;
		}
	}
}
Пример #3
0
void
CKeyMap::addKeystrokes(EKeystroke type, const KeyItem& keyItem,
				ModifierToKeys& activeModifiers,
				KeyModifierMask& currentState,
				Keystrokes& keystrokes) const
{
	KeyButton button = keyItem.m_button;
	UInt32 data      = keyItem.m_client;
	switch (type) {
	case kKeystrokePress:
		keystrokes.push_back(Keystroke(button, true, false, data));
		if (keyItem.m_generates != 0) {
			if (!keyItem.m_lock || (currentState & keyItem.m_generates) == 0) {
				// add modifier key and activate modifier
				activeModifiers.insert(std::make_pair(
									keyItem.m_generates, keyItem));
				currentState |= keyItem.m_generates;
			}
			else {
				// deactivate locking modifier
				activeModifiers.erase(keyItem.m_generates);
				currentState &= ~keyItem.m_generates;
			}
		}
		break;
		
	case kKeystrokeRelease:
		keystrokes.push_back(Keystroke(button, false, false, data));
		if (keyItem.m_generates != 0 && !keyItem.m_lock) {
			// remove key from active modifiers
			std::pair<ModifierToKeys::iterator,
						ModifierToKeys::iterator> range =
				activeModifiers.equal_range(keyItem.m_generates);
			for (ModifierToKeys::iterator i = range.first;
								i != range.second; ++i) {
				if (i->second.m_button == button) {
					activeModifiers.erase(i);
					break;
				}
			}

			// if no more keys for this modifier then deactivate modifier
			if (activeModifiers.count(keyItem.m_generates) == 0) {
				currentState &= ~keyItem.m_generates;
			}
		}
		break;
		
	case kKeystrokeRepeat:
		keystrokes.push_back(Keystroke(button, false, true, data));
		keystrokes.push_back(Keystroke(button,  true, true, data));
		// no modifier changes on key repeat
		break;
		
	case kKeystrokeClick:
		keystrokes.push_back(Keystroke(button,  true, false, data));
		keystrokes.push_back(Keystroke(button, false, false, data));
		// no modifier changes on key click
		break;
		
	case kKeystrokeModify:
	case kKeystrokeUnmodify:
		if (keyItem.m_lock) {
			// we assume there's just one button for this modifier
			if (m_halfDuplex.count(button) > 0) {
				if (type == kKeystrokeModify) {
					// turn half-duplex toggle on (press)
					keystrokes.push_back(Keystroke(button,  true, false, data));
				}
				else {
					// turn half-duplex toggle off (release)
					keystrokes.push_back(Keystroke(button, false, false, data));
				}
			}
			else {
				// toggle (click)
				keystrokes.push_back(Keystroke(button,  true, false, data));
				keystrokes.push_back(Keystroke(button, false, false, data));
			}
		}
		else if (type == kKeystrokeModify) {
			// press modifier
			keystrokes.push_back(Keystroke(button, true, false, data));
		}
		else {
			// release all the keys that generate the modifier that are
			// currently down
			std::pair<ModifierToKeys::const_iterator,
						ModifierToKeys::const_iterator> range =
				activeModifiers.equal_range(keyItem.m_generates);
			for (ModifierToKeys::const_iterator i = range.first;
								i != range.second; ++i) {
				keystrokes.push_back(Keystroke(i->second.m_button,
								false, false, i->second.m_client));
			}
		}

		if (type == kKeystrokeModify) {
			activeModifiers.insert(std::make_pair(
								keyItem.m_generates, keyItem));
			currentState |= keyItem.m_generates;
		}
		else {
			activeModifiers.erase(keyItem.m_generates);
			currentState &= ~keyItem.m_generates;
		}
		break;
	}
}