KEYMAPPER: Rework HardwareInputSet not to allocate all possible inputs

This commit is contained in:
Bastien Bouclet 2020-01-26 12:18:52 +01:00
parent 0995f40677
commit df7ce0c55f
12 changed files with 324 additions and 186 deletions

View file

@ -51,7 +51,7 @@ private:
Array<String> _defaultInputMapping; Array<String> _defaultInputMapping;
public: public:
Action(const char *id, const String &description = ""); Action(const char *id, const String &description);
void setEvent(const Event &evt) { void setEvent(const Event &evt) {
event = evt; event = evt;

View file

@ -23,10 +23,11 @@
#include "backends/keymapper/hardware-input.h" #include "backends/keymapper/hardware-input.h"
#include "backends/keymapper/keymapper.h" #include "backends/keymapper/keymapper.h"
#include "common/tokenizer.h"
namespace Common { namespace Common {
static const KeyTableEntry defaultKeys[] = { const KeyTableEntry defaultKeys[] = {
{"BACKSPACE", KEYCODE_BACKSPACE, "Backspace"}, {"BACKSPACE", KEYCODE_BACKSPACE, "Backspace"},
{"TAB", KEYCODE_TAB, "Tab"}, {"TAB", KEYCODE_TAB, "Tab"},
{"CLEAR", KEYCODE_CLEAR, "Clear"}, {"CLEAR", KEYCODE_CLEAR, "Clear"},
@ -205,100 +206,175 @@ static const KeyTableEntry defaultKeys[] = {
{0, KEYCODE_INVALID, 0} {0, KEYCODE_INVALID, 0}
}; };
// TODO: Add META and NUM_LOCK // TODO: Add NUM_LOCK
static const ModifierTableEntry defaultModifiers[] = { const ModifierTableEntry defaultModifiers[] = {
{ 0, "", "" }, { KBD_CTRL, "C", "Ctrl+" },
{ KBD_CTRL, "C+", "Ctrl+" }, { KBD_SHIFT, "S", "Shift+" },
{ KBD_ALT, "A+", "Alt+" }, { KBD_ALT, "A", "Alt+" },
{ KBD_SHIFT, "S+", "Shift+" }, { KBD_META, "M", "Meta+" },
{ KBD_CTRL | KBD_ALT, "C+A+", "Ctrl+Alt+" }, { 0, nullptr, nullptr }
{ KBD_SHIFT | KBD_CTRL, "S+C+", "Shift+Ctrl+" },
{ KBD_SHIFT | KBD_CTRL | KBD_ALT, "S+C+A+", "Shift+Ctrl+Alt+" },
{ 0, 0, 0 }
}; };
HardwareInputSet::HardwareInputSet(bool useDefault, const KeyTableEntry *keys, const ModifierTableEntry *modifiers) {
if (useDefault)
addHardwareInputs(defaultKeys, defaultModifiers);
if (keys)
addHardwareInputs(keys, modifiers ? modifiers : defaultModifiers);
}
HardwareInputSet::~HardwareInputSet() { HardwareInputSet::~HardwareInputSet() {
for (KeyInputMap::iterator it = _keyInput.begin(); it != _keyInput.end(); ++it)
delete it->_value;
for (CustomInputMap::iterator it = _customInput.begin(); it != _customInput.end(); ++it)
delete it->_value;
} }
const HardwareInput *HardwareInputSet::findHardwareInput(const String &id) const { KeyboardHardwareInputSet::KeyboardHardwareInputSet(const KeyTableEntry *keys, const ModifierTableEntry *modifiers) :
for (KeyInputMap::const_iterator it = _keyInput.begin(); it != _keyInput.end(); ++it) { _keys(keys),
if ((*it)._value->id == id) _modifiers(modifiers) {
return (*it)._value; assert(_keys);
} assert(_modifiers);
for (CustomInputMap::const_iterator it = _customInput.begin(); it != _customInput.end(); ++it) {
if ((*it)._value->id == id)
return (*it)._value;
}
return nullptr;
} }
const HardwareInput *HardwareInputSet::findHardwareInput(const HardwareInputCode code) const { HardwareInput KeyboardHardwareInputSet::findHardwareInput(const String &id) const {
return _customInput[code]; StringTokenizer tokenizer(id, "+");
}
const HardwareInput *HardwareInputSet::findHardwareInput(const KeyState &keystate) const { byte modifierFlags = 0;
return _keyInput[keystate];
}
void HardwareInputSet::addHardwareInputs(const HardwareInputTableEntry inputs[]) { // TODO: Normalize modifier order
for (const HardwareInputTableEntry *entry = inputs; entry->hwId; ++entry) { String fullKeyDesc;
const HardwareInput *existingInput = findHardwareInput(entry->code);
if (existingInput) {
warning("Ignoring hardware input %s (code %d) because an input with the same code is already defined",
entry->desc, entry->code);
continue;
}
existingInput = findHardwareInput(entry->hwId); String token;
if (existingInput) { while (!tokenizer.empty()) {
warning("Ignoring hardware input %s (id %s) because an input with the same id is already defined", token = tokenizer.nextToken();
entry->desc, entry->hwId);
continue;
}
_customInput[entry->code] = new HardwareInput(entry->hwId, entry->code, entry->desc); const ModifierTableEntry *modifier = nullptr;
} for (modifier = _modifiers; modifier->id; modifier++) {
} if (token == modifier->id) {
break;
void HardwareInputSet::addHardwareInputs(const KeyTableEntry keys[], const ModifierTableEntry modifiers[]) {
const KeyTableEntry *key;
const ModifierTableEntry *mod;
for (mod = modifiers; mod->id; mod++) {
for (key = keys; key->hwId; key++) {
String keyId = String::format("%s%s", mod->id, key->hwId);
KeyState keystate = KeyState(key->keycode, 0, mod->flag);
const HardwareInput *existingInput = findHardwareInput(keystate);
if (existingInput) {
warning("Ignoring hardware input %s%s (id %s) because an input with the same keystate is already defined",
keys->desc, mod->desc, keyId.c_str());
continue;
} }
}
existingInput = findHardwareInput(keyId); if (modifier && modifier->id) {
if (existingInput) { modifierFlags |= modifier->flag;
warning("Ignoring hardware input %s%s (id %s) because an input with the same id is already defined", fullKeyDesc += modifier->desc;
keys->desc, mod->desc, keyId.c_str()); } else {
continue; // We reached the end of the modifiers, the token is a keycode
} break;
String fullKeyDesc = String::format("%s%s", mod->desc, key->desc);
_keyInput[keystate] = new HardwareInput(keyId, keystate, fullKeyDesc);
} }
} }
if (!tokenizer.empty()) {
return HardwareInput();
}
const KeyTableEntry *key = nullptr;
for (key = _keys; key->hwId; key++) {
if (token.equals(key->hwId)) {
break;
}
}
if (!key || !key->hwId) {
return HardwareInput();
}
const KeyState keystate = KeyState(key->keycode, 0, modifierFlags);
return HardwareInput(id, keystate, fullKeyDesc + key->desc);
}
HardwareInput KeyboardHardwareInputSet::findHardwareInput(const Event &event) const {
switch (event.type) {
case EVENT_KEYDOWN:
case EVENT_KEYUP: {
const KeyTableEntry *key = nullptr;
for (key = _keys; key->hwId; key++) {
if (event.kbd.keycode == key->keycode) {
break;
}
}
if (!key || !key->hwId) {
return HardwareInput();
}
String id;
String fullKeyDesc;
byte modifierFlags = 0;
for (const ModifierTableEntry *modifier = _modifiers; modifier->id; modifier++) {
if (event.kbd.hasFlags(modifier->flag)) {
id += modifier->id;
id += "+";
fullKeyDesc += modifier->desc;
modifierFlags |= modifier->flag;
}
}
const KeyState keystate = KeyState(key->keycode, 0, modifierFlags);
return HardwareInput(id + key->hwId, keystate, fullKeyDesc + key->desc);
}
default:
return HardwareInput();
}
}
CustomHardwareInputSet::CustomHardwareInputSet(const HardwareInputTableEntry *hardwareEntries) :
_hardwareEntries(hardwareEntries) {
assert(_hardwareEntries);
}
HardwareInput CustomHardwareInputSet::findHardwareInput(const String &id) const {
const HardwareInputTableEntry *hw = nullptr;
for (hw = _hardwareEntries; hw->hwId; hw++) {
if (id.equals(hw->hwId)) {
break;
}
}
if (!hw || !hw->hwId) {
return HardwareInput();
}
return HardwareInput(hw->hwId, hw->code, hw->desc);
}
HardwareInput CustomHardwareInputSet::findHardwareInput(const Event &event) const {
switch (event.type) {
case EVENT_CUSTOM_BACKEND_HARDWARE: {
const HardwareInputTableEntry *hw = nullptr;
for (hw = _hardwareEntries; hw->hwId; hw++) {
if (event.customType == hw->code) {
break;
}
}
if (!hw || !hw->hwId) {
return HardwareInput();
}
return HardwareInput(hw->hwId, hw->code, hw->desc);
}
default:
return HardwareInput();
}
}
CompositeHardwareInputSet::~CompositeHardwareInputSet() {
for (uint i = 0; i < _inputSets.size(); i++) {
delete _inputSets[i];
}
}
HardwareInput CompositeHardwareInputSet::findHardwareInput(const String &id) const {
for (uint i = 0; i < _inputSets.size(); i++) {
HardwareInput hardwareInput = _inputSets[i]->findHardwareInput(id);
if (hardwareInput.type != kHardwareInputTypeInvalid) {
return hardwareInput;
}
}
return HardwareInput();
}
HardwareInput CompositeHardwareInputSet::findHardwareInput(const Event &event) const {
for (uint i = 0; i < _inputSets.size(); i++) {
HardwareInput hardwareInput = _inputSets[i]->findHardwareInput(event);
if (hardwareInput.type != kHardwareInputTypeInvalid) {
return hardwareInput;
}
}
return HardwareInput();
} }
} //namespace Common } //namespace Common

View file

@ -25,16 +25,18 @@
#include "common/scummsys.h" #include "common/scummsys.h"
#include "common/hashmap.h" #include "common/array.h"
#include "common/events.h"
#include "common/keyboard.h" #include "common/keyboard.h"
#include "common/str.h" #include "common/str.h"
#include "common/textconsole.h"
namespace Common { namespace Common {
typedef uint32 HardwareInputCode; typedef uint32 HardwareInputCode;
enum HardwareInputType { enum HardwareInputType {
/** Empty / invalid input type */
kHardwareInputTypeInvalid,
/** Input that sends single events */ /** Input that sends single events */
kHardwareInputTypeGeneric, kHardwareInputTypeGeneric,
/** Input that usually send -up and -down events */ /** Input that usually send -up and -down events */
@ -51,7 +53,8 @@ struct HardwareInput {
/** Human readable description */ /** Human readable description */
String description; String description;
const HardwareInputType type; /** Type tag */
HardwareInputType type;
/** /**
* A platform specific unique identifier for an input event * A platform specific unique identifier for an input event
@ -67,13 +70,19 @@ struct HardwareInput {
*/ */
KeyState key; KeyState key;
HardwareInput(const String &i, HardwareInputCode ic = 0, const String &desc = "") HardwareInput()
: inputCode(0), type(kHardwareInputTypeInvalid) { }
HardwareInput(const String &i, HardwareInputCode ic, const String &desc)
: id(i), inputCode(ic), description(desc), type(kHardwareInputTypeGeneric) { } : id(i), inputCode(ic), description(desc), type(kHardwareInputTypeGeneric) { }
HardwareInput(const String &i, KeyState ky, const String &desc = "") HardwareInput(const String &i, KeyState ky, const String &desc)
: id(i), key(ky), description(desc), type(kHardwareInputTypeKeyboard) { } : id(i), inputCode(0), key(ky), description(desc), type(kHardwareInputTypeKeyboard) { }
}; };
/**
* Entry in a static table of custom backend hardware inputs
*/
struct HardwareInputTableEntry { struct HardwareInputTableEntry {
const char *hwId; const char *hwId;
HardwareInputCode code; HardwareInputCode code;
@ -99,62 +108,95 @@ struct ModifierTableEntry {
}; };
/** /**
* Hash function for KeyState * Interface for querying information about a hardware input device
*/
template<> struct Hash<KeyState>
: public UnaryFunction<KeyState, uint> {
uint operator()(const KeyState &val) const {
return (uint)val.keycode | ((uint)val.flags << 24);
}
};
/**
* Simple class to encapsulate a device's set of HardwareInputs.
* Each device should instantiate this and call addHardwareInput a number of times
* in its constructor to define the device's available keys.
*/ */
class HardwareInputSet { class HardwareInputSet {
public: public:
/**
* Add hardware input keys to the set out of key and modifier tables.
* @param useDefault auto-add the built-in default inputs
* @param keys table of available keys
* @param modifiers table of available modifiers
*/
HardwareInputSet(bool useDefault = false, const KeyTableEntry keys[] = 0, const ModifierTableEntry modifiers[] = 0);
virtual ~HardwareInputSet(); virtual ~HardwareInputSet();
const HardwareInput *findHardwareInput(const String &id) const; /**
* Retrieve a hardware input description from an unique identifier
const HardwareInput *findHardwareInput(const HardwareInputCode code) const; *
* In case no input was found with the specified id, an empty
const HardwareInput *findHardwareInput(const KeyState &keystate) const; * HardwareInput structure is return with the type set to
* kHardwareInputTypeInvalid.
*/
virtual HardwareInput findHardwareInput(const String &id) const = 0;
/** /**
* Add hardware inputs to the set out of a table. * Retrieve a hardware input description from one of the events
* @param inputs table of available inputs * produced when the input is triggered.
*
* In case the specified event is not produced by this device,
* an empty HardwareInput structure is return with the type set to
* kHardwareInputTypeInvalid.
*/ */
void addHardwareInputs(const HardwareInputTableEntry inputs[]); virtual HardwareInput findHardwareInput(const Event &event) const = 0;
};
/** /**
* Add hardware inputs to the set out of key and modifier tables. * A keyboard input device
* @param keys table of available keys *
* @param modifiers table of available modifiers * Describes the keys and key + modifiers combinations as HardwareInputs
*/ */
void addHardwareInputs(const KeyTableEntry keys[], const ModifierTableEntry modifiers[]); class KeyboardHardwareInputSet : public HardwareInputSet {
public:
KeyboardHardwareInputSet(const KeyTableEntry *keys, const ModifierTableEntry *modifiers);
// HardwareInputSet API
HardwareInput findHardwareInput(const String &id) const override;
HardwareInput findHardwareInput(const Event &event) const override;
private: private:
const KeyTableEntry *_keys;
typedef HashMap<KeyState, const HardwareInput *> KeyInputMap; const ModifierTableEntry *_modifiers;
typedef HashMap<HardwareInputCode, const HardwareInput *> CustomInputMap;
KeyInputMap _keyInput;
CustomInputMap _customInput;
}; };
/**
* A custom backend input device
*
* @todo This is currently unused. Perhaps it should be removed.
*/
class CustomHardwareInputSet : public HardwareInputSet {
public:
CustomHardwareInputSet(const HardwareInputTableEntry *hardwareEntries);
// HardwareInputSet API
HardwareInput findHardwareInput(const String &id) const override;
HardwareInput findHardwareInput(const Event &event) const override;
private:
const HardwareInputTableEntry *_hardwareEntries;
};
/**
* A composite input device that delegates to a set of actual input devices.
*/
class CompositeHardwareInputSet : public HardwareInputSet {
public:
~CompositeHardwareInputSet() override;
// HardwareInputSet API
HardwareInput findHardwareInput(const String &id) const override;
HardwareInput findHardwareInput(const Event &event) const override;
/**
* Add an input device to this composite device
*
* Takes ownership of the hardware input set
*/
void addHardwareInputSet(HardwareInputSet *hardwareInputSet);
private:
Array<HardwareInputSet *> _inputSets;
};
/** A standard set of keyboard keys */
extern const KeyTableEntry defaultKeys[];
/** A standard set of keyboard modifiers */
extern const ModifierTableEntry defaultModifiers[];
} // End of namespace Common } // End of namespace Common
#endif // #ifndef COMMON_HARDWARE_KEY_H #endif // #ifndef COMMON_HARDWARE_KEY_H

View file

@ -30,14 +30,13 @@ namespace Common {
InputWatcher::InputWatcher(EventDispatcher *eventDispatcher, Keymapper *keymapper) : InputWatcher::InputWatcher(EventDispatcher *eventDispatcher, Keymapper *keymapper) :
_eventDispatcher(eventDispatcher), _eventDispatcher(eventDispatcher),
_keymapper(keymapper), _keymapper(keymapper),
_watching(false), _watching(false) {
_hwInput(nullptr) {
} }
void InputWatcher::startWatching() { void InputWatcher::startWatching() {
assert(!_watching); assert(!_watching);
assert(!_hwInput); assert(_hwInput.type == kHardwareInputTypeInvalid);
_keymapper->setEnabled(false); _keymapper->setEnabled(false);
_eventDispatcher->registerObserver(this, EventManager::kEventRemapperPriority, false); _eventDispatcher->registerObserver(this, EventManager::kEventRemapperPriority, false);
@ -56,7 +55,7 @@ bool InputWatcher::isWatching() const {
bool InputWatcher::notifyEvent(const Event &event) { bool InputWatcher::notifyEvent(const Event &event) {
assert(_watching); assert(_watching);
assert(!_hwInput); assert(_hwInput.type == kHardwareInputTypeInvalid);
switch (event.type) { switch (event.type) {
case EVENT_KEYDOWN: case EVENT_KEYDOWN:
@ -64,7 +63,7 @@ bool InputWatcher::notifyEvent(const Event &event) {
case EVENT_KEYUP: case EVENT_KEYUP:
case EVENT_CUSTOM_BACKEND_HARDWARE: case EVENT_CUSTOM_BACKEND_HARDWARE:
_hwInput = _keymapper->findHardwareInput(event); _hwInput = _keymapper->findHardwareInput(event);
if (_hwInput) { if (_hwInput.type != kHardwareInputTypeInvalid) {
stopWatching(); stopWatching();
} }
return true; return true;
@ -75,9 +74,9 @@ bool InputWatcher::notifyEvent(const Event &event) {
return false; return false;
} }
const HardwareInput *InputWatcher::checkForCapturedInput() { HardwareInput InputWatcher::checkForCapturedInput() {
const HardwareInput *hwInput = _hwInput; HardwareInput hwInput = _hwInput;
_hwInput = nullptr; _hwInput = HardwareInput();
return hwInput; return hwInput;
} }

View file

@ -25,6 +25,7 @@
#include "common/scummsys.h" #include "common/scummsys.h"
#include "backends/keymapper/hardware-input.h"
#include "common/events.h" #include "common/events.h"
namespace Common { namespace Common {
@ -48,7 +49,7 @@ public:
void stopWatching(); void stopWatching();
bool isWatching() const; bool isWatching() const;
const HardwareInput *checkForCapturedInput(); HardwareInput checkForCapturedInput();
private: private:
bool notifyEvent(const Event &event) override; bool notifyEvent(const Event &event) override;
@ -57,7 +58,7 @@ private:
Keymapper *_keymapper; Keymapper *_keymapper;
bool _watching; bool _watching;
const HardwareInput *_hwInput; HardwareInput _hwInput;
}; };
} // End of namespace Common } // End of namespace Common

View file

@ -55,7 +55,7 @@ void Keymap::addAction(Action *action) {
_actions.push_back(action); _actions.push_back(action);
} }
void Keymap::registerMapping(Action *action, const HardwareInput *hwInput) { void Keymap::registerMapping(Action *action, const HardwareInput &hwInput) {
ActionArray &actionArray = _hwActionMap.getVal(hwInput); ActionArray &actionArray = _hwActionMap.getVal(hwInput);
// Don't allow an input to map to the same action multiple times // Don't allow an input to map to the same action multiple times
@ -87,8 +87,8 @@ void Keymap::resetMapping(Action *action) {
registerMappings(action, hwInputIds); registerMappings(action, hwInputIds);
} }
Array<const HardwareInput *> Keymap::getActionMapping(Action *action) const { Array<HardwareInput> Keymap::getActionMapping(Action *action) const {
Array<const HardwareInput *> inputs; Array<HardwareInput> inputs;
for (HardwareActionMap::iterator itInput = _hwActionMap.begin(); itInput != _hwActionMap.end(); itInput++) { for (HardwareActionMap::iterator itInput = _hwActionMap.begin(); itInput != _hwActionMap.end(); itInput++) {
for (ActionArray::iterator itAction = itInput->_value.begin(); itAction != itInput->_value.end(); itAction++) { for (ActionArray::iterator itAction = itInput->_value.begin(); itAction != itInput->_value.end(); itAction++) {
@ -111,8 +111,20 @@ const Action *Keymap::findAction(const char *id) const {
return nullptr; return nullptr;
} }
const Keymap::ActionArray &Keymap::getMappedActions(const HardwareInput *hardwareInput) const { Keymap::ActionArray Keymap::getMappedActions(const Event &event) const {
return _hwActionMap[hardwareInput]; switch (event.type) {
case EVENT_KEYDOWN:
case EVENT_KEYUP: {
HardwareInput hardwareInput("", event.kbd, "");
return _hwActionMap[hardwareInput];
}
case EVENT_CUSTOM_BACKEND_HARDWARE: {
HardwareInput hardwareInput("", event.customType, "");
return _hwActionMap[hardwareInput];
}
default:
return ActionArray();
}
} }
void Keymap::setConfigDomain(ConfigManager::Domain *configDomain) { void Keymap::setConfigDomain(ConfigManager::Domain *configDomain) {
@ -188,9 +200,9 @@ void Keymap::registerMappings(Action *action, const Array <String> &hwInputIds)
assert(_hardwareInputSet); assert(_hardwareInputSet);
for (uint i = 0; i < hwInputIds.size(); i++) { for (uint i = 0; i < hwInputIds.size(); i++) {
const HardwareInput *hwInput = _hardwareInputSet->findHardwareInput(hwInputIds[i].c_str()); HardwareInput hwInput = _hardwareInputSet->findHardwareInput(hwInputIds[i].c_str());
if (!hwInput) { if (hwInput.type == kHardwareInputTypeInvalid) {
// Silently ignore unknown hardware ids because the current device may not have inputs matching the defaults // Silently ignore unknown hardware ids because the current device may not have inputs matching the defaults
debug(1, "HardwareInput with ID '%s' not known", hwInputIds[i].c_str()); debug(1, "HardwareInput with ID '%s' not known", hwInputIds[i].c_str());
continue; continue;
@ -209,7 +221,7 @@ void Keymap::saveMappings() {
for (ActionArray::const_iterator it = _actions.begin(); it != _actions.end(); it++) { for (ActionArray::const_iterator it = _actions.begin(); it != _actions.end(); it++) {
Action *action = *it; Action *action = *it;
Array<const HardwareInput *> mappedInputs = getActionMapping(action); Array<HardwareInput> mappedInputs = getActionMapping(action);
if (areMappingsIdentical(mappedInputs, action->getDefaultInputMapping())) { if (areMappingsIdentical(mappedInputs, action->getDefaultInputMapping())) {
// If the current mapping is the default, don't write anything to the config manager // If the current mapping is the default, don't write anything to the config manager
@ -224,14 +236,14 @@ void Keymap::saveMappings() {
confValue += " "; confValue += " ";
} }
confValue += mappedInputs[j]->id; confValue += mappedInputs[j].id;
} }
_configDomain->setVal(prefix + action->id, confValue); _configDomain->setVal(prefix + action->id, confValue);
} }
} }
bool Keymap::areMappingsIdentical(const Array<const HardwareInput *> &inputs, const Array<String> &mapping) { bool Keymap::areMappingsIdentical(const Array<HardwareInput> &inputs, const StringArray &mapping) {
if (inputs.size() != mapping.size()) { if (inputs.size() != mapping.size()) {
return false; return false;
} }
@ -241,7 +253,7 @@ bool Keymap::areMappingsIdentical(const Array<const HardwareInput *> &inputs, co
uint foundCount = 0; uint foundCount = 0;
for (uint i = 0; i < inputs.size(); i++) { for (uint i = 0; i < inputs.size(); i++) {
for (uint j = 0; j < mapping.size(); j++) { for (uint j = 0; j < mapping.size(); j++) {
if (inputs[i]->id == mapping[j]) { if (inputs[i].id == mapping[j]) {
foundCount++; foundCount++;
break; break;
} }

View file

@ -25,21 +25,44 @@
#include "common/scummsys.h" #include "common/scummsys.h"
#include "backends/keymapper/hardware-input.h"
#include "common/config-manager.h" #include "common/config-manager.h"
#include "common/func.h" #include "common/func.h"
#include "common/hashmap.h" #include "common/hashmap.h"
#include "common/hash-ptr.h" #include "common/hash-ptr.h"
#include "common/list.h" #include "common/list.h"
#include "common/str-array.h"
namespace Common { namespace Common {
const char *const kStandardActionsKeymapName = "standard-actions"; const char *const kStandardActionsKeymapName = "standard-actions";
class Action; class Action;
class Event;
struct HardwareInput; struct HardwareInput;
class HardwareInputSet; class HardwareInputSet;
class KeymapperDefaultBindings; class KeymapperDefaultBindings;
struct Event_EqualTo {
bool operator()(const HardwareInput& x, const HardwareInput& y) const {
return (x.type == y.type)
&& (x.key == y.key) // TODO: Remove the equality operator from KeyState
&& (x.inputCode == y.inputCode);
}
};
struct Event_Hash {
uint operator()(const HardwareInput& x) const {
uint hash = 7;
hash = 31 * hash + x.type;
hash = 31 * hash + x.key.keycode;
hash = 31 * hash + (x.key.flags & ~KBD_STICKY);
hash = 31 * hash + x.inputCode;
return hash;
}
};
class Keymap { class Keymap {
public: public:
enum KeymapType { enum KeymapType {
@ -62,7 +85,7 @@ public:
* @param key pointer to HardwareInput to map * @param key pointer to HardwareInput to map
* @see Action::mapKey * @see Action::mapKey
*/ */
void registerMapping(Action *action, const HardwareInput *input); void registerMapping(Action *action, const HardwareInput &input);
/** /**
* Unregisters a HardwareInput from the given Action (if one is mapped) * Unregisters a HardwareInput from the given Action (if one is mapped)
@ -80,14 +103,14 @@ public:
/** /**
* Find the hardware input an action is mapped to, if any * Find the hardware input an action is mapped to, if any
*/ */
Array<const HardwareInput *> getActionMapping(Action *action) const; Array<HardwareInput> getActionMapping(Action *action) const;
/** /**
* Find the Actions that a hardware input is mapped to * Find the Actions that a hardware input is mapped to
* @param hardwareInput the input that is mapped to the required Action * @param hardwareInput the input that is mapped to the required Action
* @return an array containing pointers to the actions * @return an array containing pointers to the actions
*/ */
const ActionArray &getMappedActions(const HardwareInput *hardwareInput) const; ActionArray getMappedActions(const Event &event) const;
/** /**
* Adds a new Action to this Map * Adds a new Action to this Map
@ -129,10 +152,10 @@ private:
const Action *findAction(const char *id) const; const Action *findAction(const char *id) const;
void registerMappings(Action *action, const Array<String> &hwInputIds); void registerMappings(Action *action, const StringArray &hwInputIds);
bool areMappingsIdentical(const Array<const HardwareInput *> &inputs, const Array <String> &mapping); bool areMappingsIdentical(const Array<HardwareInput> &inputs, const StringArray &mapping);
typedef HashMap<const HardwareInput *, ActionArray> HardwareActionMap; typedef HashMap<HardwareInput, ActionArray, Event_Hash, Event_EqualTo> HardwareActionMap;
KeymapType _type; KeymapType _type;
String _name; String _name;

View file

@ -56,7 +56,7 @@ void Keymapper::registerHardwareInputSet(HardwareInputSet *inputs) {
if (!inputs) { if (!inputs) {
warning("No hardware input were defined, using defaults"); warning("No hardware input were defined, using defaults");
inputs = new HardwareInputSet(true); inputs = new KeyboardHardwareInputSet(defaultKeys, defaultModifiers);
} }
_hardwareInputs = inputs; _hardwareInputs = inputs;
@ -147,13 +147,6 @@ List<Event> Keymapper::mapEvent(const Event &ev) {
hardcodedEventMapping(ev); hardcodedEventMapping(ev);
const HardwareInput *hwInput = findHardwareInput(ev);
if (!hwInput) {
List<Event> originalEvent;
originalEvent.push_back(ev);
return originalEvent;
}
IncomingEventType incomingEventType = convertToIncomingEventType(ev); IncomingEventType incomingEventType = convertToIncomingEventType(ev);
List<Event> mappedEvents; List<Event> mappedEvents;
@ -169,7 +162,7 @@ List<Event> Keymapper::mapEvent(const Event &ev) {
debug(5, "Keymapper::mapKey keymap: %s", _keymaps[i]->getName().c_str()); debug(5, "Keymapper::mapKey keymap: %s", _keymaps[i]->getName().c_str());
const Keymap::ActionArray &actions = _keymaps[i]->getMappedActions(hwInput); const Keymap::ActionArray &actions = _keymaps[i]->getMappedActions(ev);
for (Keymap::ActionArray::const_iterator it = actions.begin(); it != actions.end(); it++) { for (Keymap::ActionArray::const_iterator it = actions.begin(); it != actions.end(); it++) {
mappedEvents.push_back(executeAction(*it, incomingEventType)); mappedEvents.push_back(executeAction(*it, incomingEventType));
} }
@ -261,16 +254,8 @@ EventType Keymapper::convertStartToEnd(EventType type) {
return result; return result;
} }
const HardwareInput *Keymapper::findHardwareInput(const Event &event) { HardwareInput Keymapper::findHardwareInput(const Event &event) {
switch (event.type) { return _hardwareInputs->findHardwareInput(event);
case EVENT_KEYDOWN:
case EVENT_KEYUP:
return _hardwareInputs->findHardwareInput(event.kbd);
case EVENT_CUSTOM_BACKEND_HARDWARE:
return _hardwareInputs->findHardwareInput(event.customType);
default:
return nullptr;
}
} }
void Keymapper::hardcodedEventMapping(Event ev) { void Keymapper::hardcodedEventMapping(Event ev) {

View file

@ -121,7 +121,7 @@ public:
/** /**
* Return a HardwareInput pointer for the given event * Return a HardwareInput pointer for the given event
*/ */
const HardwareInput *findHardwareInput(const Event &event); HardwareInput findHardwareInput(const Event &event);
void initKeymap(Keymap *keymap, ConfigManager::Domain *domain); void initKeymap(Keymap *keymap, ConfigManager::Domain *domain);

View file

@ -216,8 +216,8 @@ void RemapWidget::handleMouseDown(int x, int y, int button, int clickCount) {
} }
void RemapWidget::handleTickle() { void RemapWidget::handleTickle() {
const HardwareInput *hardwareInput = _remapInputWatcher->checkForCapturedInput(); const HardwareInput hardwareInput = _remapInputWatcher->checkForCapturedInput();
if (hardwareInput) { if (hardwareInput.type != kHardwareInputTypeInvalid) {
_remapKeymap->registerMapping(_remapAction, hardwareInput); _remapKeymap->registerMapping(_remapAction, hardwareInput);
_changes = true; _changes = true;
@ -260,7 +260,7 @@ void RemapWidget::refreshKeymap() {
row.actionText->setLabel(row.action->description); row.actionText->setLabel(row.action->description);
Array<const HardwareInput *> mappedInputs = row.keymap->getActionMapping(row.action); Array<HardwareInput> mappedInputs = row.keymap->getActionMapping(row.action);
String keysLabel; String keysLabel;
for (uint j = 0; j < mappedInputs.size(); j++) { for (uint j = 0; j < mappedInputs.size(); j++) {
@ -268,7 +268,7 @@ void RemapWidget::refreshKeymap() {
keysLabel += ", "; keysLabel += ", ";
} }
keysLabel += mappedInputs[j]->description; keysLabel += mappedInputs[j].description;
} }
if (!keysLabel.empty()) { if (!keysLabel.empty()) {

View file

@ -103,7 +103,3 @@ static const Mod modifiers[] = {
{ KBD_SHIFT | KBD_CTRL | KBD_ALT, "C+A+", "Ctrl+Alt+", true }, { KBD_SHIFT | KBD_CTRL | KBD_ALT, "C+A+", "Ctrl+Alt+", true },
{ 0, 0, 0, false } { 0, 0, 0, false }
}; };
Common::HardwareInputSet *OSystem_LINUXMOTO::getHardwareInputSet() {
return OSystem_SDL::getHardwareInputSet();
}

View file

@ -184,7 +184,11 @@ static const Common::KeyTableEntry maemoKeys[] = {
}; };
Common::HardwareInputSet *OSystem_SDL_Maemo::getHardwareInputSet() { Common::HardwareInputSet *OSystem_SDL_Maemo::getHardwareInputSet() {
return new Common::HardwareInputSet(true, maemoKeys); Common::CompositeHardwareInputSet inputSet = new Common::CompositeHardwareInputSet();
inputSet->addHardwareInputSet(new Common::KeyboardHardwareInputSet(maemoKeys, defaultModifiers));
inputSet->addHardwareInputSet(new Common::KeyboardHardwareInputSet(defaultKeys, defaultModifiers));
return inputSet;
} }
Common::KeymapArray OSystem_SDL_Maemo::getGlobalKeymaps() { Common::KeymapArray OSystem_SDL_Maemo::getGlobalKeymaps() {