diff options
author | Tarek Soliman | 2012-03-01 06:29:44 -0600 |
---|---|---|
committer | Tarek Soliman | 2012-03-02 20:48:50 -0600 |
commit | c0a215282d12872cf32fb24f9067216c0f869b96 (patch) | |
tree | f55b1c3591ebc7c094b78c32f3d714d45e942da7 | |
parent | d12f21b31db2985faeb2e2a6b9b09cd210f82c34 (diff) | |
download | scummvm-rg350-c0a215282d12872cf32fb24f9067216c0f869b96.tar.gz scummvm-rg350-c0a215282d12872cf32fb24f9067216c0f869b96.tar.bz2 scummvm-rg350-c0a215282d12872cf32fb24f9067216c0f869b96.zip |
KEYMAPPER: Add delays for *UP events coming from non-keys
Delayed entries are in a queue where each entry stores how
many milliseconds should pass based on the last entry.
-rw-r--r-- | backends/keymapper/keymapper.cpp | 29 | ||||
-rw-r--r-- | common/EventDispatcher.cpp | 6 | ||||
-rw-r--r-- | common/EventMapper.cpp | 28 | ||||
-rw-r--r-- | common/events.h | 15 |
4 files changed, 70 insertions, 8 deletions
diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp index 99bcb44179..dcb021f2d8 100644 --- a/backends/keymapper/keymapper.cpp +++ b/backends/keymapper/keymapper.cpp @@ -25,9 +25,14 @@ #ifdef ENABLE_KEYMAPPER #include "common/config-manager.h" +#include "common/system.h" namespace Common { +// These magic numbers are provided by fuzzie and WebOS +static const uint32 kDelayKeyboardEventMillis = 250; +static const uint32 kDelayMouseEventMillis = 50; + void Keymapper::Domain::addKeymap(Keymap *map) { iterator it = find(map->getName()); @@ -281,9 +286,9 @@ Action *Keymapper::getAction(const KeyState& key) { List<Event> Keymapper::executeAction(const Action *action, IncomingEventType incomingType) { List<Event> mappedEvents; List<Event>::const_iterator it; - + Event evt; for (it = action->events.begin(); it != action->events.end(); ++it) { - Event evt = Event(*it); + evt = Event(*it); EventType convertedType = convertDownToUp(evt.type); // hardware keys need to send up instead when they are up @@ -294,15 +299,23 @@ List<Event> Keymapper::executeAction(const Action *action, IncomingEventType inc } evt.mouse = _eventMan->getMousePos(); - mappedEvents.push_back(evt); + + // Check if the event is coming from a non-key hardware event + // that is mapped to a key event + if (incomingType == kIncomingNonKey && convertedType != EVENT_INVALID) + // WORKAROUND: Delay the down events coming from non-key hardware events + // with a zero delay. This is to prevent DOWN1 DOWN2 UP1 UP2. + addDelayedEvent(0, evt); + else + 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 + if (incomingType == kIncomingNonKey && convertedType != EVENT_INVALID) { + // WORKAROUND: Delay the up events coming from non-key hardware events + // This is for engines that run scripts that check on key being down evt.type = convertedType; - mappedEvents.push_back(evt); + const uint32 delay = (convertedType == EVENT_KEYUP ? kDelayKeyboardEventMillis : kDelayMouseEventMillis); + addDelayedEvent(delay, evt); } } return mappedEvents; diff --git a/common/EventDispatcher.cpp b/common/EventDispatcher.cpp index 4c7286bbb5..012a2dfce5 100644 --- a/common/EventDispatcher.cpp +++ b/common/EventDispatcher.cpp @@ -60,6 +60,12 @@ void EventDispatcher::dispatch() { } } } + + List<Event> delayedEvents = _mapper->getDelayedEvents(); + for (List<Event>::iterator k = delayedEvents.begin(); k != delayedEvents.end(); ++k) { + const Event delayedEvent = *k; + dispatchEvent(delayedEvent); + } } void EventDispatcher::registerMapper(EventMapper *mapper) { diff --git a/common/EventMapper.cpp b/common/EventMapper.cpp index 0771ecdd89..47db61e472 100644 --- a/common/EventMapper.cpp +++ b/common/EventMapper.cpp @@ -21,6 +21,8 @@ */ #include "common/events.h" + +#include "common/system.h" #include "common/textconsole.h" namespace Common { @@ -61,4 +63,30 @@ List<Event> DefaultEventMapper::mapEvent(const Event &ev, EventSource *source) { } +void DefaultEventMapper::addDelayedEvent(uint32 millis, Event ev) { + if (_delayedEvents.empty()) { + _delayedEffectiveTime = g_system->getMillis() + millis; + millis = 0; + } + DelayedEventsEntry entry = DelayedEventsEntry(millis, ev); + _delayedEvents.push(entry); +} + +List<Event> DefaultEventMapper::getDelayedEvents() { + List<Event> events; + + if (_delayedEvents.empty()) + return events; + + uint32 now = g_system->getMillis(); + + while (!_delayedEvents.empty() && now >= _delayedEffectiveTime) { + DelayedEventsEntry entry = _delayedEvents.pop(); + if (!_delayedEvents.empty()) + _delayedEffectiveTime += _delayedEvents.front().timerOffset; + events.push_back(entry.event); + } + return events; +} + } // namespace Common diff --git a/common/events.h b/common/events.h index 7e411ecce5..7366c51d36 100644 --- a/common/events.h +++ b/common/events.h @@ -232,12 +232,27 @@ public: * Map an incoming event to one or more action events */ virtual List<Event> mapEvent(const Event &ev, EventSource *source) = 0; + + virtual List<Event> getDelayedEvents() = 0; }; class DefaultEventMapper : public EventMapper { public: + DefaultEventMapper() : _delayedEvents(), _delayedEffectiveTime(0) {} // EventMapper interface virtual List<Event> mapEvent(const Event &ev, EventSource *source); + virtual List<Event> getDelayedEvents(); +protected: + virtual void addDelayedEvent(uint32 millis, Event ev); + + struct DelayedEventsEntry { + const uint32 timerOffset; + const Event event; + DelayedEventsEntry(const uint32 offset, const Event ev) : timerOffset(offset), event(ev) { } + }; + + Queue<DelayedEventsEntry> _delayedEvents; + uint32 _delayedEffectiveTime; }; /** |