summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2014-08-28 14:13:38 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2014-09-04 07:23:34 +1000
commit90d19302306f49722e210227b2fb5161e6f51880 (patch)
treed2f13496bf612a31dc9d4ef5df648d3c5095c571
parent96e60a4ea242d2decf109835981ae186cc36f642 (diff)
eventcomm: ensure we're on the same clock as the server
Default on evdev devices is CLOCK_REALTIME. If that clock falls behind the server's CLOCK_MONOTONIC, motion after a clickpad click may be delayed by the difference in the clocks. In detail: When the timer func is triggered, GetTimeInMillis() which is CLOCK_MONOTONIC, is stored as hwState->millis. The eventcomm backend uses struct input_event time (CLOCK_REALTIME). When we read events from the device, if the evdev time is less than the server time, the fix for (#48777) sets the current event time to hwState->millis. Until the evdev time overtakes that stored time, all events have the hwState->millis time. If during that time a clickpad triggers a physical click, clickpad_click_millis is set to hwState->millis + the ignore-motion timeout. Thus, all motion is ignored until the event time overtakes that stored time. The whole issue is further enhanced by us unconditionally setting the timer func if we get any events, which is a separate issue anyway. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r--src/eventcomm.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/eventcomm.c b/src/eventcomm.c
index 845f547..4a646af 100644
--- a/src/eventcomm.c
+++ b/src/eventcomm.c
@@ -39,6 +39,7 @@
#include <dirent.h>
#include <string.h>
#include <stdio.h>
+#include <time.h>
#include "synproto.h"
#include "synapticsstr.h"
#include <xf86.h>
@@ -88,6 +89,8 @@ struct eventcomm_proto_data {
struct libevdev *evdev;
enum libevdev_read_flag read_flag;
+
+ int have_monotonic_clock;
};
#ifdef HAVE_LIBEVDEV_DEVICE_LOG_FUNCS
@@ -234,6 +237,7 @@ EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters * para)
SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private;
struct eventcomm_proto_data *proto_data =
(struct eventcomm_proto_data *) priv->proto_data;
+ int ret;
if (libevdev_get_fd(proto_data->evdev) != -1) {
struct input_event ev;
@@ -253,7 +257,6 @@ EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters * para)
if (para->grab_event_device) {
/* Try to grab the event device so that data don't leak to /dev/input/mice */
- int ret;
ret = libevdev_grab(proto_data->evdev, LIBEVDEV_GRAB);
if (ret < 0) {
@@ -265,6 +268,9 @@ EventDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters * para)
proto_data->need_grab = FALSE;
+ ret = libevdev_set_clock_id(proto_data->evdev, CLOCK_MONOTONIC);
+ proto_data->have_monotonic_clock = (ret == 0);
+
InitializeTouch(pInfo);
return TRUE;
@@ -682,7 +688,10 @@ EventReadHwState(InputInfoPtr pInfo,
switch (ev.code) {
case SYN_REPORT:
hw->numFingers = count_fingers(pInfo, comm);
- hw->millis = 1000 * ev.time.tv_sec + ev.time.tv_usec / 1000;
+ if (proto_data->have_monotonic_clock)
+ hw->millis = 1000 * ev.time.tv_sec + ev.time.tv_usec / 1000;
+ else
+ hw->millis = GetTimeInMillis();
SynapticsCopyHwState(hwRet, hw);
return TRUE;
}