aboutsummaryrefslogtreecommitdiff
path: root/backends/keymapper
diff options
context:
space:
mode:
Diffstat (limited to 'backends/keymapper')
-rw-r--r--backends/keymapper/action.cpp21
-rw-r--r--backends/keymapper/action.h8
-rw-r--r--backends/keymapper/hardware-key.h108
-rw-r--r--backends/keymapper/keymap.cpp30
-rw-r--r--backends/keymapper/keymap.h19
-rw-r--r--backends/keymapper/keymapper.cpp9
-rw-r--r--backends/keymapper/keymapper.h9
-rw-r--r--backends/keymapper/remap-dialog.cpp22
-rw-r--r--backends/keymapper/types.h1
9 files changed, 187 insertions, 40 deletions
diff --git a/backends/keymapper/action.cpp b/backends/keymapper/action.cpp
index 3feb593f19..4633f20df3 100644
--- a/backends/keymapper/action.cpp
+++ b/backends/keymapper/action.cpp
@@ -32,9 +32,9 @@
namespace Common {
Action::Action(Keymap *boss, const char *i, String des, ActionType typ,
- KeyType prefKey, int pri, int flg)
+ KeyType prefKey, int pri)
: _boss(boss), description(des), type(typ), preferredKey(prefKey),
- priority(pri), flags(flg), _hwKey(0) {
+ priority(pri), _hwKey(0) {
assert(i);
assert(_boss);
@@ -43,14 +43,21 @@ Action::Action(Keymap *boss, const char *i, String des, ActionType typ,
_boss->addAction(this);
}
-void Action::mapKey(const HardwareKey *key) {
+void Action::mapKey(const HardwareKey *key, byte flags) {
if (_hwKey)
+ {
_boss->unregisterMapping(this);
+ delete _hwKey;
+ }
- _hwKey = key;
-
- if (_hwKey)
- _boss->registerMapping(this, _hwKey);
+ if (key) {
+ _hwKey = new HardwareKey(*key);
+ if (flags)
+ _hwKey->key.flags = flags & _hwKey->modMask;
+ if (_hwKey)
+ _boss->registerMapping(this, _hwKey);
+ } else
+ _hwKey = NULL;
}
const HardwareKey *Action::getMappedKey() const {
diff --git a/backends/keymapper/action.h b/backends/keymapper/action.h
index 31576e2960..c78a526414 100644
--- a/backends/keymapper/action.h
+++ b/backends/keymapper/action.h
@@ -54,19 +54,17 @@ struct Action {
ActionType type;
KeyType preferredKey;
int priority;
- int group;
- int flags;
private:
/** Hardware key that is mapped to this Action */
- const HardwareKey *_hwKey;
+ HardwareKey *_hwKey;
Keymap *_boss;
public:
Action(Keymap *boss, const char *id, String des = "",
ActionType typ = kGenericActionType,
KeyType prefKey = kGenericKeyType,
- int pri = 0, int flg = 0 );
+ int pri = 0);
void addEvent(const Event &evt) {
events.push_back(evt);
@@ -105,7 +103,7 @@ public:
return _boss;
}
- void mapKey(const HardwareKey *key);
+ void mapKey(const HardwareKey *key, byte flags = 0);
const HardwareKey *getMappedKey() const;
};
diff --git a/backends/keymapper/hardware-key.h b/backends/keymapper/hardware-key.h
index 8ddeada51e..70168def2d 100644
--- a/backends/keymapper/hardware-key.h
+++ b/backends/keymapper/hardware-key.h
@@ -31,12 +31,47 @@
#ifdef ENABLE_KEYMAPPER
#include "backends/keymapper/types.h"
+#include "common/str.h"
+#include "common/keyboard.h"
+#include "common/list.h"
+#include "common/util.h"
namespace Common {
#define HWKEY_ID_SIZE (30)
+
+// Structure for describing specific key+modifier combos mapped to actions,
+// to allow for modifiers to work properly without having to define the whole
+// hardware key set an additional time for each possible modifier combination
+struct ActionKey {
+ KeyCode keycode;
+ byte flags;
+
+ ActionKey () {
+ keycode = KEYCODE_INVALID;
+ flags = 0;
+ }
+
+ ActionKey (const KeyState &key) {
+ keycode = key.keycode;
+ flags = key.flags;
+ }
+
+
+ ActionKey (KeyCode ky, byte f) {
+ keycode = ky;
+ flags = f;
+ }
+
+ bool operator ==(const ActionKey &x) const {
+ return keycode == x.keycode && flags == x.flags;
+ }
+
+};
+
+
/**
* Describes an available hardware key
*/
@@ -51,19 +86,45 @@ struct HardwareKey {
* The KeyState that is generated by the back-end
* when this hardware key is pressed.
*/
- KeyState key;
+ ActionKey key;
KeyType type;
ActionType preferredAction;
- HardwareKey(const char *i, KeyState ky = KeyState(), String desc = "",
+ // Mask of modifiers that can possibly apply to this key.
+ byte modMask;
+
+ HardwareKey(const char *i, ActionKey ky = ActionKey(), String desc = "", byte mods = ~0,
KeyType typ = kGenericKeyType, ActionType prefAct = kGenericActionType)
- : key(ky), description(desc), type(typ), preferredAction(prefAct) {
+ : key(ky), description(desc), type(typ), preferredAction(prefAct), modMask(mods) {
assert(i);
strncpy(hwKeyId, i, HWKEY_ID_SIZE);
}
};
+/**
+* Describes an available hardware modifier
+*/
+struct HardwareMod {
+ /** unique id used for saving/loading to config */
+ char hwModId[HWKEY_ID_SIZE];
+
+ /** Human readable description */
+ String description;
+
+ /**
+ * The modifier flags that are generated by the
+ * back-end when this modifier key is pressed.
+ */
+ byte modFlags;
+
+ HardwareMod(const char *i, byte mf, String desc = "")
+ : modFlags(mf), description(desc) {
+ assert(i);
+ strncpy(hwModId, i, HWKEY_ID_SIZE);
+ }
+};
+
/**
* Simple class to encapsulate a device's set of HardwareKeys.
@@ -80,6 +141,11 @@ public:
delete *it;
}
+ void addHardwareMod(HardwareMod *mod) {
+ checkForMod(mod);
+ _mods.push_back(mod);
+ }
+
void addHardwareKey(HardwareKey *key) {
checkForKey(key);
_keys.push_back(key);
@@ -95,11 +161,31 @@ public:
return 0;
}
- const HardwareKey *findHardwareKey(const KeyState& keystate) const {
+ const HardwareKey *findHardwareKey(const ActionKey& keystate) const {
List<const HardwareKey*>::const_iterator it;
for (it = _keys.begin(); it != _keys.end(); it++) {
- if ((*it)->key == keystate)
+ if ((*it)->key.keycode == keystate.keycode)
+ return (*it);
+ }
+ return 0;
+ }
+
+ const HardwareMod *findHardwareMod(const char *id) const {
+ List<const HardwareMod*>::const_iterator it;
+
+ for (it = _mods.begin(); it != _mods.end(); it++) {
+ if (strncmp((*it)->hwModId, id, HWKEY_ID_SIZE) == 0)
+ return (*it);
+ }
+ return 0;
+ }
+
+ const HardwareMod *findHardwareMod(const ActionKey& keystate) const {
+ List<const HardwareMod*>::const_iterator it;
+
+ for (it = _mods.begin(); it != _mods.end(); it++) {
+ if ((*it)->modFlags == keystate.flags)
return (*it);
}
return 0;
@@ -127,7 +213,19 @@ private:
}
}
+ void checkForMod(HardwareMod *mod) {
+ List<const HardwareMod*>::iterator it;
+
+ for (it = _mods.begin(); it != _mods.end(); it++) {
+ if (strncmp((*it)->hwModId, mod->hwModId, HWKEY_ID_SIZE) == 0)
+ error("Error adding HardwareMod '%s' - id of %s already in use!", mod->description.c_str(), mod->hwModId);
+ else if ((*it)->modFlags == mod->modFlags)
+ error("Error adding HardwareMod '%s' - modFlags already in use!", mod->description.c_str());
+ }
+ }
+
List<const HardwareKey*> _keys;
+ List<const HardwareMod*> _mods;
};
diff --git a/backends/keymapper/keymap.cpp b/backends/keymapper/keymap.cpp
index 95b64f88e7..f082640f2c 100644
--- a/backends/keymapper/keymap.cpp
+++ b/backends/keymapper/keymap.cpp
@@ -60,7 +60,7 @@ void Keymap::addAction(Action *action) {
}
void Keymap::registerMapping(Action *action, const HardwareKey *hwKey) {
- HashMap<KeyState, Action*>::iterator it;
+ HashMap<ActionKey, Action*>::iterator it;
it = _keymap.find(hwKey->key);
@@ -105,8 +105,8 @@ const Action *Keymap::findAction(const char *id) const {
return 0;
}
-Action *Keymap::getMappedAction(const KeyState& ks) const {
- HashMap<KeyState, Action*>::iterator it;
+Action *Keymap::getMappedAction(const ActionKey& ks) const {
+ HashMap<ActionKey, Action*>::iterator it;
it = _keymap.find(ks);
@@ -127,6 +127,10 @@ void Keymap::loadMappings(const HardwareKeySet *hwKeys) {
ConfigManager::Domain::iterator it;
String prefix = KEYMAP_KEY_PREFIX + _name + "_";
+ uint32 modId = 0;
+ char hwId[HWKEY_ID_SIZE+1];
+ memset(hwId,0,HWKEY_ID_SIZE+1);
+
for (it = _configDomain->begin(); it != _configDomain->end(); it++) {
const String& key = it->_key;
@@ -145,15 +149,15 @@ void Keymap::loadMappings(const HardwareKeySet *hwKeys) {
continue;
}
- const HardwareKey *hwKey = hwKeys->findHardwareKey(it->_value.c_str());
+ sscanf(it->_value.c_str(),"%d,%s",&modId,hwId);
+ const HardwareKey *hwKey = hwKeys->findHardwareKey(hwId);
if (!hwKey) {
warning("HardwareKey with ID %s not known", it->_value.c_str());
_configDomain->erase(key);
continue;
}
-
- ua->mapKey(hwKey);
+ ua->mapKey(hwKey,modId);
}
}
@@ -171,13 +175,19 @@ void Keymap::saveMappings() {
String actId((*it)->id, (*it)->id + actIdLen);
char hwId[HWKEY_ID_SIZE+1];
-
memset(hwId, 0, HWKEY_ID_SIZE+1);
+ char modId[4];
+ memset(modId, 0, 4);
+
if ((*it)->getMappedKey()) {
memcpy(hwId, (*it)->getMappedKey()->hwKeyId, HWKEY_ID_SIZE);
+ sprintf(modId,"%d",(*it)->getMappedKey()->key.flags);
}
- _configDomain->setVal(prefix + actId, hwId);
+ String val = modId;
+ val += ',';
+ val += hwId;
+ _configDomain->setVal(prefix + actId, val);
}
}
@@ -230,7 +240,7 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) {
// First mapping pass:
// - Match if a key's preferred action type is the same as the action's
- // type, or vice versa.
+ // type, or vice versa.
// - Priority is given to:
// - keys that match action types over key types.
// - keys that have not been used by parent maps.
@@ -323,7 +333,7 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) {
}
}
-Action *Keymap::getParentMappedAction(KeyState key) {
+Action *Keymap::getParentMappedAction(const ActionKey &key) {
if (_parent) {
Action *act = _parent->getMappedAction(key);
diff --git a/backends/keymapper/keymap.h b/backends/keymapper/keymap.h
index 615fd9097d..f4ad8d110d 100644
--- a/backends/keymapper/keymap.h
+++ b/backends/keymapper/keymap.h
@@ -36,6 +36,7 @@
#include "common/keyboard.h"
#include "common/list.h"
#include "backends/keymapper/action.h"
+#include "backends/keymapper/hardware-key.h"
namespace Common {
@@ -53,6 +54,17 @@ template<> struct Hash<KeyState>
}
};
+/**
+ * Hash function for ActionKey
+ */
+template<> struct Hash<ActionKey>
+ : public UnaryFunction<ActionKey, uint> {
+
+ uint operator()(const ActionKey &val) const {
+ return (uint)val.keycode | ((uint)val.flags << 24);
+ }
+};
+
class Keymap {
public:
Keymap(const String& name, Keymap *parent = 0) : _name(name), _parent(parent) {}
@@ -77,7 +89,7 @@ public:
* @param key the key that is mapped to the required Action
* @return a pointer to the Action or 0 if no
*/
- Action *getMappedAction(const KeyState& ks) const;
+ Action *getMappedAction(const ActionKey& ks) const;
void setConfigDomain(ConfigManager::Domain *dom);
@@ -90,7 +102,6 @@ public:
/**
* Save this keymap's mappings to the config manager
* @note Changes are *not* flushed to disk, to do so call ConfMan.flushToDisk()
- * @note Changes are *not* flushed to disk, to do so call ConfMan.flushToDisk()
*/
void saveMappings();
@@ -136,12 +147,12 @@ private:
void internalMapKey(Action *action, HardwareKey *hwKey);
- Action *getParentMappedAction(KeyState key);
+ Action *getParentMappedAction(const ActionKey &key);
String _name;
Keymap *_parent;
List<Action*> _actions;
- HashMap<KeyState, Action*> _keymap;
+ HashMap<ActionKey, Action*> _keymap;
ConfigManager::Domain *_configDomain;
};
diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp
index c0c454168c..704affb3fe 100644
--- a/backends/keymapper/keymapper.cpp
+++ b/backends/keymapper/keymapper.cpp
@@ -190,7 +190,6 @@ bool Keymapper::mapKey(const KeyState& key, bool keyDown) {
return false;
Action *action = 0;
-
if (keyDown) {
// Search for key in active keymap stack
for (int i = _activeMaps.size() - 1; i >= 0; --i) {
@@ -205,7 +204,7 @@ bool Keymapper::mapKey(const KeyState& key, bool keyDown) {
if (action)
_keysDown[key] = action;
} else {
- HashMap<KeyState, Action*>::iterator it = _keysDown.find(key);
+ HashMap<ActionKey, Action*>::iterator it = _keysDown.find(key);
if (it != _keysDown.end()) {
action = it->_value;
@@ -268,10 +267,14 @@ void Keymapper::executeAction(const Action *action, bool keyDown) {
}
}
-const HardwareKey *Keymapper::findHardwareKey(const KeyState& key) {
+const HardwareKey *Keymapper::findHardwareKey(const ActionKey& key) {
return (_hardwareKeys) ? _hardwareKeys->findHardwareKey(key) : 0;
}
+const HardwareMod *Keymapper::findHardwareMod(const ActionKey& key) {
+ return (_hardwareKeys) ? _hardwareKeys->findHardwareMod(key) : 0;
+}
+
} // end of namespace Common
#endif // #ifdef ENABLE_KEYMAPPER
diff --git a/backends/keymapper/keymapper.h b/backends/keymapper/keymapper.h
index f492882ca2..24c76fb09f 100644
--- a/backends/keymapper/keymapper.h
+++ b/backends/keymapper/keymapper.h
@@ -168,7 +168,12 @@ public:
/**
* Return a HardwareKey pointer for the given key state
*/
- const HardwareKey *findHardwareKey(const KeyState& key);
+ const HardwareKey *findHardwareKey(const ActionKey& key);
+
+ /**
+ * Return a HardwareMod pointer for the given key state
+ */
+ const HardwareMod *findHardwareMod(const ActionKey& key);
Domain& getGlobalDomain() { return _globalDomain; }
Domain& getGameDomain() { return _gameDomain; }
@@ -193,7 +198,7 @@ private:
bool _enabled;
Stack<MapRecord> _activeMaps;
- HashMap<KeyState, Action*> _keysDown;
+ HashMap<ActionKey, Action*> _keysDown;
};
diff --git a/backends/keymapper/remap-dialog.cpp b/backends/keymapper/remap-dialog.cpp
index 0440acdd0a..0a93785c08 100644
--- a/backends/keymapper/remap-dialog.cpp
+++ b/backends/keymapper/remap-dialog.cpp
@@ -240,11 +240,12 @@ void RemapDialog::handleKeyUp(Common::KeyState state) {
if (_activeRemapAction) {
const HardwareKey *hwkey = _keymapper->findHardwareKey(state);
- debug(0, "Key: %d, %d (%c), %x", state.keycode, state.ascii, (state.ascii ? state.ascii : ' '), state.flags);
+ debug( "Key: %d, %d (%c), %x", state.keycode, state.ascii, (state.ascii ? state.ascii : ' '), state.flags);
if (hwkey) {
- _activeRemapAction->mapKey(hwkey);
+ _activeRemapAction->mapKey(hwkey,state.flags);
_activeRemapAction->getParent()->saveMappings();
+
_changes = true;
stopRemapping();
}
@@ -359,8 +360,21 @@ void RemapDialog::refreshKeymap() {
const HardwareKey *mappedKey = info.action->getMappedKey();
if (mappedKey)
- widg.keyButton->setLabel(mappedKey->description);
- else
+ {
+ Common::String description = "";
+ if (mappedKey->key.flags)
+ {
+ byte flags = mappedKey->key.flags;
+ if (flags & KBD_CTRL)
+ description += "Ctrl+";
+ if (flags & KBD_SHIFT)
+ description += "Shift+";
+ if (flags & KBD_ALT)
+ description += "Alt+";
+ }
+ description += mappedKey->description;
+ widg.keyButton->setLabel(description);
+ } else
widg.keyButton->setLabel("-");
widg.actionText->setVisible(true);
diff --git a/backends/keymapper/types.h b/backends/keymapper/types.h
index 7ad4c0e538..3cce79ee9a 100644
--- a/backends/keymapper/types.h
+++ b/backends/keymapper/types.h
@@ -43,6 +43,7 @@ enum KeyType {
kTriggerRightKeyType,
kStartKeyType,
kSelectKeyType,
+ kModiferKeyType,
/* ... */
kKeyTypeMax