summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>2013-01-06 13:37:38 +0100
committerEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>2013-01-06 13:40:21 +0100
commit197ccb2e1ccfc9108fe857edbded75b65191ab10 (patch)
treee227e7290a7f015a30c01d84e82587b8d424128c
parent30b1f3ae49c63e8e96ef04f692910cac77d44901 (diff)
downloadvdr-plugin-inputdev-197ccb2e1ccfc9108fe857edbded75b65191ab10.tar.gz
vdr-plugin-inputdev-197ccb2e1ccfc9108fe857edbded75b65191ab10.tar.bz2
added support for setting repeat rate
-rw-r--r--inputdev.cc81
-rw-r--r--inputdev.h6
2 files changed, 84 insertions, 3 deletions
diff --git a/inputdev.cc b/inputdev.cc
index 3db8d76..40db486 100644
--- a/inputdev.cc
+++ b/inputdev.cc
@@ -179,10 +179,15 @@ private:
class MagicState magic_state_;
unsigned long modifiers_;
+ unsigned int orig_rate_[2];
cInputDevice(cInputDevice const &);
cInputDevice & operator = (cInputDevice const &);
+ bool has_orig_repeate_rate(void) const {
+ return orig_rate_[0] != 0 && orig_rate_[1] != 0;
+ }
+
public:
// the vdr list implementation requires knowledge about the containing
// list when unlinking a object :(
@@ -210,6 +215,9 @@ public:
char const *get_description(void) const { return description_; }
char const *get_dev_path(void) const { return dev_path_; }
+ bool set_repeat_rate(unsigned int delay_ms,
+ unsigned int rate_ms);
+
void dump(void) const;
static uint64_t generate_code(uint16_t type, uint16_t code,
@@ -223,6 +231,8 @@ cInputDevice::cInputDevice(cInputDeviceController &controller,
controller_(controller), dev_path_(dev_path), fd_(-1), dev_t_(0),
modifiers_(0), container(NULL)
{
+ orig_rate_[0] = 0;
+ orig_rate_[1] = 0;
}
cInputDevice::~cInputDevice()
@@ -400,6 +410,14 @@ bool cInputDevice::start(int efd)
goto err;
}
+ rc = ioctl(fd_, EVIOCGREP, orig_rate_);
+ if (rc < 0) {
+ isyslog("%s: %s does not support setup of repeat rate\n",
+ controller_.plugin_name(), dev_path);
+ orig_rate_[0] = 0;
+ orig_rate_[1] = 0;
+ }
+
rc = epoll_ctl(efd, EPOLL_CTL_ADD, fd_, &ev);
if (rc < 0) {
esyslog("%s: epoll_ctl(ADD, <%s>) failed: %s\n",
@@ -415,6 +433,12 @@ err:
void cInputDevice::stop(int efd)
{
+ // ignore errors here; there is not very much which can be done in
+ // this situation. Errors will also happen when devices disconnects
+ // and fd_ refers to a non existing device then.
+ if (orig_rate_[0] != 0 && orig_rate_[1] != 0)
+ ioctl(fd_, EVIOCSREP, orig_rate_);
+
ioctl(fd_, EVIOCGRAB, 0);
epoll_ctl(efd, EPOLL_CTL_DEL, fd_, NULL);
}
@@ -566,10 +590,34 @@ void cInputDevice::handle_pollin(void)
}
}
+bool cInputDevice::set_repeat_rate(unsigned int delay_ms,
+ unsigned int rate_ms)
+{
+ unsigned int rep[2] = { delay_ms, rate_ms };
+ int rc;
+
+ if (!has_orig_repeate_rate()) {
+ dsyslog("%s: %s skipping setup of repeat rate because original one is unknown\n",
+ controller_.plugin_name(), get_dev_path());
+ return true; // no error
+ }
+
+ rc = ioctl(fd_, EVIOCSREP, rep);
+ if (rc < 0) {
+ esyslog("%s: %s failed to set repeat rate: %s\n",
+ controller_.plugin_name(), get_dev_path(),
+ strerror(errno));
+ return false;
+ }
+
+ return true;
+}
+
// ===========================
cInputDeviceController::cInputDeviceController(cPlugin &p)
- : cRemote("inputdev"), plugin_(p), fd_udev_(-1), fd_epoll_(-1)
+ : cRemote("inputdev"), plugin_(p), fd_udev_(-1), fd_epoll_(-1),
+ repeat_delay_ms_(500), repeat_rate_ms_(1000)
{
fd_alive_[0] = -1;
fd_alive_[1] = -1;
@@ -872,16 +920,43 @@ bool cInputDeviceController::add_device(char const *dev_name)
dev->container = &devices_;
}
- if (dev != NULL && !dev->start(fd_epoll_)) {
+ if (dev == NULL) {
+ res = false;
+ } else if (!dev->start(fd_epoll_)) {
res = false;
remove_device(dev);
} else {
- res = dev != NULL;
+ dev->set_repeat_rate(repeat_delay_ms_, repeat_rate_ms_);
+ res = true;
}
return res;
}
+bool cInputDeviceController::set_repeat_rate(unsigned int delay_ms,
+ unsigned int rate_ms)
+{
+ bool success = true;
+
+ cMutexLock lock(&dev_mutex_);
+ for (cInputDevice *i = devices_.First(); i; i = devices_.Next(i))
+ success &= i->set_repeat_rate(delay_ms, rate_ms);
+
+ if (!success) {
+ esyslog("%s: failed to set repeat parameters [%u, %u]\n",
+ plugin_name(), delay_ms, rate_ms);
+ // \todo: rewind already done setup?
+ } else {
+ isyslog("%s: set repeat parameters [%u, %u]\n",
+ plugin_name(), delay_ms, rate_ms);
+ repeat_delay_ms_ = delay_ms;
+ repeat_rate_ms_ = rate_ms;
+ }
+
+ return success;
+}
+
+
void cInputDeviceController::dump_active_devices(void)
{
cMutexLock lock(&dev_mutex_);
diff --git a/inputdev.h b/inputdev.h
index 5d4a2ed..7fbfff0 100644
--- a/inputdev.h
+++ b/inputdev.h
@@ -43,6 +43,9 @@ private:
cMutex dev_mutex_;
+ unsigned int repeat_delay_ms_;
+ unsigned int repeat_rate_ms_;
+
cInputDeviceController(cInputDeviceController const &);
bool open_generic(int fd_udev);
@@ -76,6 +79,9 @@ public:
void remove_device(char const *dev);
void remove_device(class cInputDevice *dev);
+ bool set_repeat_rate(unsigned int delay_ms,
+ unsigned int rate_ms);
+
static void close(int &fd);
bool Put(uint64_t Code, bool Repeat, bool Release) {