diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2014-09-20 12:39:59 +0200 |
---|---|---|
committer | David Herrmann <dh.herrmann@gmail.com> | 2014-09-22 14:27:02 +0200 |
commit | 89febb631a4710992cd41e402a643451b19c11a7 (patch) | |
tree | 8f384d1763306f241d0f605be9beead2f5450e96 /src/libsystemd-terminal | |
parent | 6022343476982439dfc2e06bf54db78a0c8c6bff (diff) |
terminal: forward evdev RESYNC events to linked devices
Whenever we resync an evdev device (or disable it), we should send RESYNC
events to the linked upper layers. This allows to disable key-repeat and
assume some events got dropped.
Diffstat (limited to 'src/libsystemd-terminal')
-rw-r--r-- | src/libsystemd-terminal/idev-evdev.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/libsystemd-terminal/idev-evdev.c b/src/libsystemd-terminal/idev-evdev.c index 25ac849b8d..719e18c316 100644 --- a/src/libsystemd-terminal/idev-evdev.c +++ b/src/libsystemd-terminal/idev-evdev.c @@ -102,7 +102,16 @@ static void idev_evdev_name(char *out, dev_t devnum) { sprintf(out, "evdev/%u:%u", major(devnum), minor(devnum)); } -static int idev_evdev_raise(idev_evdev *evdev, struct input_event *event) { +static int idev_evdev_feed_resync(idev_evdev *evdev) { + idev_data data = { + .type = IDEV_DATA_RESYNC, + .resync = evdev->resync, + }; + + return idev_element_feed(&evdev->element, &data); +} + +static int idev_evdev_feed_evdev(idev_evdev *evdev, struct input_event *event) { idev_data data = { .type = IDEV_DATA_EVDEV, .resync = evdev->resync, @@ -156,7 +165,6 @@ static int idev_evdev_io(idev_evdev *evdev) { * case we cannot keep up with the kernel. * TODO: Make sure libevdev always reports SYN_DROPPED to us, regardless * whether any event was synced afterwards. - * TODO: Forward SYN_DROPPED to attached devices. */ flags = LIBEVDEV_READ_FLAG_NORMAL; @@ -191,7 +199,7 @@ static int idev_evdev_io(idev_evdev *evdev) { } else if (r == LIBEVDEV_READ_STATUS_SYNC) { if (evdev->resync) { /* sync-event */ - r = idev_evdev_raise(evdev, &ev); + r = idev_evdev_feed_evdev(evdev, &ev); if (r != 0) { error = r; break; @@ -200,10 +208,15 @@ static int idev_evdev_io(idev_evdev *evdev) { /* start of sync */ evdev->resync = true; flags = LIBEVDEV_READ_FLAG_SYNC; + r = idev_evdev_feed_resync(evdev); + if (r != 0) { + error = r; + break; + } } } else { /* normal event */ - r = idev_evdev_raise(evdev, &ev); + r = idev_evdev_feed_evdev(evdev, &ev); if (r != 0) { error = r; break; @@ -288,6 +301,7 @@ static void idev_evdev_disable(idev_evdev *evdev) { return; evdev->running = false; + idev_evdev_feed_resync(evdev); sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_OFF); sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_OFF); } |