Ejemplo n.º 1
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;
	}
}