diff options
Diffstat (limited to 'backends/keymapper/keymapper.cpp')
-rw-r--r-- | backends/keymapper/keymapper.cpp | 149 |
1 files changed, 111 insertions, 38 deletions
diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp index 4742886207..99bcb44179 100644 --- a/backends/keymapper/keymapper.cpp +++ b/backends/keymapper/keymapper.cpp @@ -54,7 +54,7 @@ Keymap *Keymapper::Domain::getKeymap(const String& name) { } Keymapper::Keymapper(EventManager *evtMgr) - : _eventMan(evtMgr), _enabled(true), _hardwareInputs(0) { + : _eventMan(evtMgr), _enabled(true), _remapping(false), _hardwareInputs(0), _actionToRemap(0) { ConfigManager::Domain *confDom = ConfMan.getDomain(ConfigManager::kKeymapperDomain); _globalDomain.setConfigDomain(confDom); @@ -183,13 +183,16 @@ List<Event> Keymapper::mapEvent(const Event &ev, EventSource *source) { if (source && !source->allowMapping()) { return DefaultEventMapper::mapEvent(ev, source); } - List<Event> mappedEvents; - if (ev.type == Common::EVENT_KEYDOWN) + if (_remapping) + mappedEvents = remap(ev); + else if (ev.type == Common::EVENT_KEYDOWN) mappedEvents = mapKeyDown(ev.kbd); else if (ev.type == Common::EVENT_KEYUP) mappedEvents = mapKeyUp(ev.kbd); + else if (ev.type == Common::EVENT_CUSTOM_BACKEND_HARDWARE) + mappedEvents = mapNonKey(ev.customType); if (!mappedEvents.empty()) return mappedEvents; @@ -197,6 +200,13 @@ List<Event> Keymapper::mapEvent(const Event &ev, EventSource *source) { return DefaultEventMapper::mapEvent(ev, source); } +void Keymapper::startRemappingMode(Action *actionToRemap) { + assert(!_remapping); + + _remapping = true; + _actionToRemap = actionToRemap; +} + List<Event> Keymapper::mapKeyDown(const KeyState& key) { return mapKey(key, true); } @@ -236,7 +246,30 @@ List<Event> Keymapper::mapKey(const KeyState& key, bool keyDown) { if (!action) return List<Event>(); - return executeAction(action, keyDown); + return executeAction(action, keyDown ? kIncomingKeyDown : kIncomingKeyUp); +} + + +List<Event> Keymapper::mapNonKey(const HardwareInputCode code) { + if (!_enabled || _activeMaps.empty()) + return List<Event>(); + + Action *action = 0; + + // Search for nonkey in active keymap stack + for (int i = _activeMaps.size() - 1; i >= 0; --i) { + MapRecord mr = _activeMaps[i]; + debug(5, "Keymapper::mapKey keymap: %s", mr.keymap->getName().c_str()); + action = mr.keymap->getMappedAction(code); + + if (action || !mr.transparent) + break; + } + + if (!action) + return List<Event>(); + + return executeAction(action); } Action *Keymapper::getAction(const KeyState& key) { @@ -245,52 +278,57 @@ Action *Keymapper::getAction(const KeyState& key) { return action; } -List<Event> Keymapper::executeAction(const Action *action, bool keyDown) { +List<Event> Keymapper::executeAction(const Action *action, IncomingEventType incomingType) { List<Event> mappedEvents; List<Event>::const_iterator it; for (it = action->events.begin(); it != action->events.end(); ++it) { - Event evt = *it; - - switch (evt.type) { - case EVENT_KEYDOWN: - if (!keyDown) evt.type = EVENT_KEYUP; - break; - case EVENT_KEYUP: - if (keyDown) evt.type = EVENT_KEYDOWN; - break; - case EVENT_LBUTTONDOWN: - if (!keyDown) evt.type = EVENT_LBUTTONUP; - break; - case EVENT_LBUTTONUP: - if (keyDown) evt.type = EVENT_LBUTTONDOWN; - break; - case EVENT_RBUTTONDOWN: - if (!keyDown) evt.type = EVENT_RBUTTONUP; - break; - case EVENT_RBUTTONUP: - if (keyDown) evt.type = EVENT_RBUTTONDOWN; - break; - case EVENT_MBUTTONDOWN: - if (!keyDown) evt.type = EVENT_MBUTTONUP; - break; - case EVENT_MBUTTONUP: - if (keyDown) evt.type = EVENT_MBUTTONDOWN; - break; - case EVENT_MAINMENU: - if (!keyDown) evt.type = EVENT_MAINMENU; - break; - default: - // don't deliver other events on key up - if (!keyDown) continue; + Event evt = Event(*it); + EventType convertedType = convertDownToUp(evt.type); + + // hardware keys need to send up instead when they are up + if (incomingType == kIncomingKeyUp) { + if (convertedType == EVENT_INVALID) + continue; // don't send any non-down-converted events on up they were already sent on down + evt.type = convertedType; } evt.mouse = _eventMan->getMousePos(); mappedEvents.push_back(evt); + + // non-keys need to send up as well + // TODO: implement a way to add a delay + if (incomingType == kIncomingNonKey) { + if (convertedType == EVENT_INVALID) + continue; // don't send any non-down-converted events on up they were already sent on down + evt.type = convertedType; + mappedEvents.push_back(evt); + } } return mappedEvents; } +EventType Keymapper::convertDownToUp(EventType type) { + EventType result = EVENT_INVALID; + switch (type) { + case EVENT_KEYDOWN: + result = EVENT_KEYUP; + break; + case EVENT_LBUTTONDOWN: + result = EVENT_LBUTTONUP; + break; + case EVENT_RBUTTONDOWN: + result = EVENT_RBUTTONUP; + break; + case EVENT_MBUTTONDOWN: + result = EVENT_MBUTTONUP; + break; + default: + break; + } + return result; +} + const HardwareInput *Keymapper::findHardwareInput(const KeyState& key) { return (_hardwareInputs) ? _hardwareInputs->findHardwareInput(key) : 0; } @@ -299,6 +337,41 @@ const HardwareInput *Keymapper::findHardwareInput(const HardwareInputCode code) return (_hardwareInputs) ? _hardwareInputs->findHardwareInput(code) : 0; } +List<Event> Keymapper::remap(const Event &ev) { + assert(_remapping); + assert(_actionToRemap); + + List<Event> list; + + const HardwareInput *hwInput = 0; + Event mappedEvent; + + switch (ev.type) { + case EVENT_KEYDOWN: + // eat the event by returning an event invalid + mappedEvent.type = EVENT_INVALID; + list.push_back(mappedEvent); + break; + case EVENT_KEYUP: + hwInput = findHardwareInput(ev.kbd); + break; + case EVENT_CUSTOM_BACKEND_HARDWARE: + hwInput = findHardwareInput(ev.customType); + break; + default: + break; + } + if (hwInput) { + _actionToRemap->mapInput(hwInput); + _actionToRemap->getParent()->saveMappings(); + _remapping = false; + _actionToRemap = 0; + mappedEvent.type = EVENT_GUI_REMAP_COMPLETE_ACTION; + list.push_back(mappedEvent); + } + return list; +} + } // End of namespace Common #endif // #ifdef ENABLE_KEYMAPPER |