summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnrico Scholz <ensc@ensc.de>2014-01-01 18:53:28 +0100
committerEnrico Scholz <ensc@ensc.de>2014-01-02 20:39:21 +0100
commit2ea089a9c809e8e764e1f4be56f47bbe28f6ba60 (patch)
tree2d146949f86d0d73914662e322f10cf7c3923743
parent2f59b5066e62c81413eb85a5ff59365e0f20c44c (diff)
downloadvdr-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.cc41
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;
}