aboutsummaryrefslogtreecommitdiff
path: root/backends/keymapper/keymap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/keymapper/keymap.cpp')
-rw-r--r--backends/keymapper/keymap.cpp40
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