diff options
Diffstat (limited to 'backends/keymapper/keymap.cpp')
-rw-r--r-- | backends/keymapper/keymap.cpp | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/backends/keymapper/keymap.cpp b/backends/keymapper/keymap.cpp index 4cb6b7f518..13be1ad8bc 100644 --- a/backends/keymapper/keymap.cpp +++ b/backends/keymapper/keymap.cpp @@ -35,8 +35,10 @@ namespace Common { Keymap::Keymap(const Keymap& km) : _actions(km._actions), _keymap(), _configDomain(0) { List<Action*>::iterator it; + for (it = _actions.begin(); it != _actions.end(); it++) { const HardwareKey *hwKey = (*it)->getMappedKey(); + if (hwKey) { _keymap[hwKey->key] = *it; } @@ -45,6 +47,7 @@ Keymap::Keymap(const Keymap& km) : _actions(km._actions), _keymap(), _configDoma Keymap::~Keymap() { List<Action*>::iterator it; + for (it = _actions.begin(); it != _actions.end(); it++) delete *it; } @@ -52,12 +55,15 @@ Keymap::~Keymap() { void Keymap::addAction(Action *action) { if (findAction(action->id)) error("Action with id %s already in KeyMap!", action->id); + _actions.push_back(action); } void Keymap::registerMapping(Action *action, const HardwareKey *hwKey) { HashMap<KeyState, Action*>::iterator it; + it = _keymap.find(hwKey->key); + // if key is already mapped to a different action then un-map it if (it != _keymap.end() && action != it->_value) { it->_value->mapKey(0); @@ -68,6 +74,7 @@ void Keymap::registerMapping(Action *action, const HardwareKey *hwKey) { void Keymap::unregisterMapping(Action *action) { const HardwareKey *hwKey = action->getMappedKey(); + if (hwKey) { _keymap.erase(hwKey->key); } @@ -79,6 +86,7 @@ Action *Keymap::getAction(const char *id) { Action *Keymap::findAction(const char *id) { List<Action*>::iterator it; + for (it = _actions.begin(); it != _actions.end(); it++) { if (strncmp((*it)->id, id, ACTION_ID_SIZE) == 0) return *it; @@ -88,16 +96,20 @@ Action *Keymap::findAction(const char *id) { const Action *Keymap::findAction(const char *id) const { List<Action*>::const_iterator it; + for (it = _actions.begin(); it != _actions.end(); it++) { if (strncmp((*it)->id, id, ACTION_ID_SIZE) == 0) return *it; } + return 0; } Action *Keymap::getMappedAction(const KeyState& ks) const { HashMap<KeyState, Action*>::iterator it; + it = _keymap.find(ks); + if (it == _keymap.end()) return 0; else @@ -109,25 +121,32 @@ void Keymap::setConfigDomain(ConfigManager::Domain *dom) { } void Keymap::loadMappings(const HardwareKeySet *hwKeys) { - if (!_configDomain) return; + if (!_configDomain) + return; + ConfigManager::Domain::iterator it; String prefix = KEYMAP_KEY_PREFIX + _name + "_"; + for (it = _configDomain->begin(); it != _configDomain->end(); it++) { const String& key = it->_key; + if (!key.hasPrefix(prefix.c_str())) continue; // parse Action ID const char *actionId = key.c_str() + prefix.size(); Action *ua = getAction(actionId); + if (!ua) { warning("'%s' keymap does not contain Action with ID %s", _name.c_str(), actionId); _configDomain->erase(key); + continue; } const HardwareKey *hwKey = hwKeys->findHardwareKey(it->_value.c_str()); + if (!hwKey) { warning("HardwareKey with ID %s not known", it->_value.c_str()); _configDomain->erase(key); @@ -141,14 +160,20 @@ void Keymap::loadMappings(const HardwareKeySet *hwKeys) { void Keymap::saveMappings() { if (!_configDomain) return; + List<Action*>::const_iterator it; String prefix = KEYMAP_KEY_PREFIX + _name + "_"; + for (it = _actions.begin(); it != _actions.end(); it++) { uint actIdLen = strlen((*it)->id); + actIdLen = (actIdLen > ACTION_ID_SIZE) ? ACTION_ID_SIZE : actIdLen; + String actId((*it)->id, (*it)->id + actIdLen); char hwId[HWKEY_ID_SIZE+1]; + memset(hwId, 0, HWKEY_ID_SIZE+1); + if ((*it)->getMappedKey()) { memcpy(hwId, (*it)->getMappedKey()->hwKeyId, HWKEY_ID_SIZE); } @@ -160,6 +185,7 @@ bool Keymap::isComplete(const HardwareKeySet *hwKeys) { List<Action*>::iterator it; bool allMapped = true; uint numberMapped = 0; + for (it = _actions.begin(); it != _actions.end(); it++) { if ((*it)->getMappedKey()) { numberMapped++; @@ -167,6 +193,7 @@ bool Keymap::isComplete(const HardwareKeySet *hwKeys) { allMapped = false; } } + return allMapped || (numberMapped == hwKeys->size()); } @@ -184,9 +211,11 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) { // Remove actions and keys from local lists that have already been mapped. actIt = actions.begin(); + while (actIt != actions.end()) { Action *act = *actIt; const HardwareKey *key = act->getMappedKey(); + if (key) { keys.remove(key); actIt = actions.erase(actIt); @@ -212,13 +241,16 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) { // to these higher priority skipped actions. uint skipped = 0; actIt = actions.begin(); + while (actIt != actions.end() && skipped < keys.size()) { selectedKey = keys.end(); int matchRank = 0; Action *act = *actIt; + for (keyIt = keys.begin(); keyIt != keys.end(); ++keyIt) { if ((*keyIt)->preferredAction == act->type && act->type != kGenericActionType) { Action *parentAct = getParentMappedAction((*keyIt)->key); + if (!parentAct) { selectedKey = keyIt; break; @@ -228,6 +260,7 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) { } } else if ((*keyIt)->type == act->preferredKey && act->preferredKey != kGenericKeyType && matchRank < 2) { Action *parentAct = getParentMappedAction((*keyIt)->key); + if (!parentAct) { selectedKey = keyIt; matchRank = 2; @@ -258,11 +291,14 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) { // - is guaranteed to match a key if they are not all used up for (actIt = actions.begin(); actIt != actions.end(); ++actIt) { selectedKey = keys.end(); + int matchRank = 0; int lowestPriority = 0; Action *act = *actIt; + for (keyIt = keys.begin(); keyIt != keys.end(); ++keyIt) { Action *parentAct = getParentMappedAction((*keyIt)->key); + if (!parentAct) { selectedKey = keyIt; break; @@ -277,6 +313,7 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) { } } } + if (selectedKey != keys.end()) { act->mapKey(*selectedKey); keys.erase(selectedKey); @@ -289,6 +326,7 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) { Action *Keymap::getParentMappedAction(KeyState key) { if (_parent) { Action *act = _parent->getMappedAction(key); + if (act) return act; else |