Propagate EV_REL events up in input stack
As we want xf86-input-cmt to drive mice in addition to touchpads, EV_REL
events have to be propagated up.
BUG=chromium-os:29435
TEST=add debug output in gestures, and see it receives EV_REL events
Change-Id: I0d134077882725ba6399ea47743bdb8ea2d5a051
Reviewed-on: https://gerrit.chromium.org/gerrit/36514
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
Commit-Ready: Che-Liang Chiou <clchiou@chromium.org>
Tested-by: Che-Liang Chiou <clchiou@chromium.org>
diff --git a/src/libevdev_event.c b/src/libevdev_event.c
index 9e8841c..11576e3 100644
--- a/src/libevdev_event.c
+++ b/src/libevdev_event.c
@@ -33,8 +33,9 @@
#endif
+static void Event_Clear_Ev_Rel_State(EvdevPtr);
-static void Event_Syn(EvdevPtr, struct input_event*);
+static bool Event_Syn(EvdevPtr, struct input_event*);
static void Event_Syn_Report(EvdevPtr, struct input_event*);
static void Event_Syn_MT_Report(EvdevPtr, struct input_event*);
@@ -44,6 +45,8 @@
static void Event_Abs_MT(EvdevPtr, struct input_event*);
static void Event_Abs_Update_Pressure(EvdevPtr, struct input_event*);
+static void Event_Rel(EvdevPtr, struct input_event*);
+
static void Event_Get_Time(struct timeval*, bool);
/**
@@ -222,6 +225,16 @@
break;
}
break;
+ case EV_REL:
+ switch (code) {
+ CASE_RETURN(REL_X);
+ CASE_RETURN(REL_Y);
+ CASE_RETURN(REL_WHEEL);
+ CASE_RETURN(REL_HWHEEL);
+ default:
+ break;
+ }
+ break;
case EV_KEY:
switch (code) {
CASE_RETURN(BTN_LEFT);
@@ -373,6 +386,9 @@
Event_Get_Time(&device->after_sync_time, device->info.is_monotonic);
+ /* Initialize EV_REL event state */
+ Event_Clear_Ev_Rel_State(device);
+
LOG_WARNING(device, "Event_Sync_State: before %ld.%ld after %ld.%ld\n",
device->before_sync_time.tv_sec,
device->before_sync_time.tv_usec,
@@ -421,7 +437,7 @@
}
/**
- * Process Input Events
+ * Process Input Events. It returns TRUE if SYN_DROPPED detected.
*/
bool
Event_Process(EvdevPtr device, struct input_event* ev)
@@ -430,10 +446,7 @@
switch (ev->type) {
case EV_SYN:
- if (ev->code == SYN_DROPPED)
- return true;
- Event_Syn(device, ev);
- break;
+ return Event_Syn(device, ev);
case EV_KEY:
Event_Key(device, ev);
@@ -443,6 +456,10 @@
Event_Abs(device, ev);
break;
+ case EV_REL:
+ Event_Rel(device, ev);
+ break;
+
default:
break;
}
@@ -484,10 +501,37 @@
fclose(fp);
}
+/**
+ * Clear EV_REL event state. This function should be called after a EV_SYN
+ * event is processed because EV_REL event state is not accumulative.
+ */
static void
+Event_Clear_Ev_Rel_State(EvdevPtr device)
+{
+ EventStatePtr evstate;
+
+ evstate = device->evstate;
+ evstate->rel_x = 0;
+ evstate->rel_y = 0;
+ evstate->rel_wheel = 0;
+ evstate->rel_hwheel = 0;
+}
+
+/**
+ * Process EV_SYN events. It returns TRUE if SYN_DROPPED detected.
+ */
+static bool
Event_Syn(EvdevPtr device, struct input_event* ev)
{
switch (ev->code) {
+ case SYN_DROPPED:
+ /*
+ * Technically we don't need to call Event_Clear_Ev_Rel_State() here
+ * because when SYN_DROPPED is detected, Event_Sync_State() will be
+ * called and Event_Sync_State() will call Event_Clear_Ev_Rel_State()
+ * to re-initialize EV_REL event state.
+ */
+ return true;
case SYN_REPORT:
Event_Syn_Report(device, ev);
break;
@@ -495,6 +539,7 @@
Event_Syn_MT_Report(device, ev);
break;
}
+ return false;
}
static void
@@ -504,6 +549,8 @@
device->syn_report(device->syn_report_udata, evstate, &ev->time);
MT_Print_Slots(device);
+
+ Event_Clear_Ev_Rel_State(device);
}
static void
@@ -572,3 +619,24 @@
MT_Slot_Value_Set(slot, ev->code, ev->value);
}
+
+static void
+Event_Rel(EvdevPtr device, struct input_event* ev)
+{
+ EventStatePtr evstate = device->evstate;
+
+ switch (ev->code) {
+ case REL_X:
+ evstate->rel_x = ev->value;
+ break;
+ case REL_Y:
+ evstate->rel_y = ev->value;
+ break;
+ case REL_WHEEL:
+ evstate->rel_wheel = ev->value;
+ break;
+ case REL_HWHEEL:
+ evstate->rel_hwheel = ev->value;
+ break;
+ }
+}