diff options
Diffstat (limited to 'backends/keymapper')
-rw-r--r-- | backends/keymapper/action.cpp | 21 | ||||
-rw-r--r-- | backends/keymapper/action.h | 8 | ||||
-rw-r--r-- | backends/keymapper/hardware-key.h | 108 | ||||
-rw-r--r-- | backends/keymapper/keymap.cpp | 30 | ||||
-rw-r--r-- | backends/keymapper/keymap.h | 19 | ||||
-rw-r--r-- | backends/keymapper/keymapper.cpp | 9 | ||||
-rw-r--r-- | backends/keymapper/keymapper.h | 9 | ||||
-rw-r--r-- | backends/keymapper/remap-dialog.cpp | 22 | ||||
-rw-r--r-- | backends/keymapper/types.h | 1 |
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 |