KEYMAPPER: Rework HardwareInputSet not to allocate all possible inputs
This commit is contained in:
parent
0995f40677
commit
df7ce0c55f
12 changed files with 324 additions and 186 deletions
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue