diff options
author | Enrico Scholz <ensc@ensc.de> | 2014-01-01 18:53:28 +0100 |
---|---|---|
committer | Enrico Scholz <ensc@ensc.de> | 2014-01-02 20:39:21 +0100 |
commit | 2ea089a9c809e8e764e1f4be56f47bbe28f6ba60 (patch) | |
tree | 2d146949f86d0d73914662e322f10cf7c3923743 | |
parent | 2f59b5066e62c81413eb85a5ff59365e0f20c44c (diff) | |
download | vdr-plugin-inputdev-2ea089a9c809e8e764e1f4be56f47bbe28f6ba60.tar.gz vdr-plugin-inputdev-2ea089a9c809e8e764e1f4be56f47bbe28f6ba60.tar.bz2 |
added quirk to ignore key events which are happening too fast
some remote controls generate events too fast resp. do not implement the
autorepeat feature; check whether configured delay has been passed
before delivering the event.
Signed-off-by: Enrico Scholz <ensc@ensc.de>
-rw-r--r-- | inputdev.cc | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/inputdev.cc b/inputdev.cc index 68ffa90..7a37d66 100644 --- a/inputdev.cc +++ b/inputdev.cc @@ -206,6 +206,10 @@ private: unsigned long modifiers_; unsigned int orig_rate_[2]; + struct timeval repeat_rate_; + unsigned int last_key_val_; + struct timeval next_key_tm_; + cInputDevice(cInputDevice const &); cInputDevice & operator = (cInputDevice const &); @@ -462,6 +466,9 @@ bool cInputDevice::start(int efd) orig_rate_[1] = 0; } + repeat_rate_.tv_sec = (orig_rate_[1] / 1000); + repeat_rate_.tv_usec = (orig_rate_[1] % 1000) * 1000; + rc = epoll_ctl(efd, EPOLL_CTL_ADD, fd_, &ev); if (rc < 0) { esyslog("%s: epoll_ctl(ADD, <%s>) failed: %s\n", @@ -540,6 +547,22 @@ void cInputDevice::handle_pollin(void) // ignore events which are no valid key events return; + if (quirks_.broken_repeat && !Time::is_null(repeat_rate_) && + ev.value == 1) { + if (last_key_val_ == ev.code && + Time::compare(next_key_tm_, ev.time) > 0) { + dsyslog("%s: %s received key too fast\n", + controller_.plugin_name(), get_dev_path()); + + // same key arrived faster than configured by + // EVIOCSREP; ignore it + return; + } + + last_key_val_ = ev.code; + Time::add(next_key_tm_, ev.time, repeat_rate_); + } + if (0) dsyslog("%s: event{%s}=[%lu.%06u, %02x, %04x, %d]\n", controller_.plugin_name(), get_dev_path(), @@ -676,9 +699,27 @@ bool cInputDevice::set_repeat_rate(unsigned int delay_ms, esyslog("%s: %s failed to set repeat rate: %s\n", controller_.plugin_name(), get_dev_path(), strerror(errno)); + + repeat_rate_.tv_sec = 0; + repeat_rate_.tv_usec = 0; + return false; } + rc = ioctl(fd_, EVIOCGREP, rep); + if (rc >= 0) { + isyslog("%s: %s has repeat rate setting of [%u,%u]\n", + controller_.plugin_name(), get_dev_path(), + rep[0], rep[1]); + + // todo: handle this as an error? + + rate_ms = rep[1]; + } + + repeat_rate_.tv_sec = (rate_ms / 1000); + repeat_rate_.tv_usec = (rate_ms % 1000) * 1000; + return true; } |