Commit bab71753 authored by Florent Revest's avatar Florent Revest

mce: Unlock with a single tap (longer than 200ms)

parent 306de072
From 4f9811142bfa2435b13561726721f4e9a85da0fb Mon Sep 17 00:00:00 2001
From: Florent Revest <revestflo@gmail.com>
Date: Fri, 9 Jun 2017 16:02:28 +0200
Subject: [PATCH] [event-input] Double-tap emulation: Adapts the state machine
for a single tap to unlock (longer than 200ms to avoid involuntary touch)
---
event-input.c | 96 +++++++++++++----------------------------------------------
1 file changed, 20 insertions(+), 76 deletions(-)
diff --git a/event-input.c b/event-input.c
index 8114f46..c1c3c97 100644
--- a/event-input.c
+++ b/event-input.c
@@ -240,11 +240,7 @@ static evin_evdevtype_t evin_evdevtype_from_info (evin_evdevinfo_
#ifdef ENABLE_DOUBLETAP_EMULATION
-/** Maximum time betweem 1st click and 2nd release, in milliseconds */
-# define EVIN_DOUBLETAP_TIME_LIMIT 500
-
-/** Maximum distance between 1st and 2nd clicks, in pixels */
-# define EVIN_DOUBLETAP_DISTANCE_LIMIT 100
+# define EVIN_DOUBLETAP_MIN_TIME 200
/** History data for emulating double tap */
typedef struct
@@ -252,20 +248,13 @@ typedef struct
/** Timestamp from ending EV_SYN event */
struct timeval dt_time;
- /** X coordinate accumulated from relative movements */
- int dt_x;
-
- /** Y coordinate accumulated from relative movements */
- int dt_y;
-
/** Bitmask for accumulating touch points */
int dt_click;
} evin_doubletap_t;
static void evin_doubletap_gconf_changed_cb (GConfClient *const client, const guint id, GConfEntry *const entry, gpointer const data);
-static int evin_doubletap_within_time_limit (const evin_doubletap_t *e1, const evin_doubletap_t *e2);
-static int evin_doubletap_within_dist_limit (const evin_doubletap_t *e1, const evin_doubletap_t *e2);
+static int evin_doubletap_more_than_min_time (const evin_doubletap_t *e1, const evin_doubletap_t *e2);
static int evin_doubletap_active_touch_points (const evin_doubletap_t *e);
@@ -1493,21 +1482,21 @@ evin_doubletap_gconf_changed_cb(GConfClient *const client, const guint id,
}
}
-/** Check if two double tap history points are close enough in time
+/** Check if a tap is long enough
*
- * @param e1 event data from the 1st click
- * @param e2 event data from the 2nd release
+ * @param e1 event data from the click
+ * @param e2 event data from the release
*
- * @return TRUE if e1 and e2 times are valid and close enough,
+ * @return TRUE if e1 and e2 times are valid and far enough,
* or FALSE otherwise
*/
static int
-evin_doubletap_within_time_limit(const evin_doubletap_t *e1, const evin_doubletap_t *e2)
+evin_doubletap_more_than_min_time(const evin_doubletap_t *e1, const evin_doubletap_t *e2)
{
static const struct timeval limit =
{
- .tv_sec = (EVIN_DOUBLETAP_TIME_LIMIT / 1000),
- .tv_usec = (EVIN_DOUBLETAP_TIME_LIMIT % 1000) * 1000,
+ .tv_sec = (EVIN_DOUBLETAP_MIN_TIME / 1000),
+ .tv_usec = (EVIN_DOUBLETAP_MIN_TIME % 1000) * 1000,
};
struct timeval delta;
@@ -1517,24 +1506,7 @@ evin_doubletap_within_time_limit(const evin_doubletap_t *e1, const evin_doubleta
return 0;
timersub(&e2->dt_time, &e1->dt_time, &delta);
- return timercmp(&delta, &limit, <);
-}
-
-/** Check if two double tap history points are close enough in pixels
- *
- * @param e1 event data from the 1st click
- * @param e2 event data from the 2nd click
- *
- * @return TRUE if e1 and e2 positions are close enough, or FALSE otherwise
- */
-static int
-evin_doubletap_within_dist_limit(const evin_doubletap_t *e1, const evin_doubletap_t *e2)
-{
- int x = e2->dt_x - e1->dt_x;
- int y = e2->dt_y - e1->dt_y;
- int r = EVIN_DOUBLETAP_DISTANCE_LIMIT;
-
- return (x*x + y*y) < (r*r);
+ return timercmp(&delta, &limit, >);
}
/** Accumulator steps for counting touch/mouse click events separately
@@ -1596,35 +1568,22 @@ evin_doubletap_active_touch_points(const evin_doubletap_t *e)
static int
evin_doubletap_emulate(const struct input_event *eve)
{
- static evin_doubletap_t hist[4]; // click/release ring buffer
+ static evin_doubletap_t hist[2]; // click/release ring buffer
static unsigned i0 = 0; // current position
- static int x_accum = 0; // x delta accumulator
- static int y_accum = 0; // y delta accumulator
static bool skip_syn = true; // flag: ignore SYN_REPORT
int result = FALSE; // assume: no doubletap
- unsigned i1, i2, i3; // 3 last positions
+ unsigned i1; // last position
switch( eve->type ) {
- case EV_REL:
- /* Accumulate X/Y position */
- switch( eve->code ) {
- case REL_X: x_accum += eve->value; break;
- case REL_Y: y_accum += eve->value; break;
- default: break;
- }
- break;
-
case EV_KEY:
switch( eve->code ) {
case BTN_MOUSE:
- /* Store click/release and position */
+ /* Store click/release */
if( eve->value )
hist[i0].dt_click += SEEN_EVENT_MOUSE;
- hist[i0].dt_x = x_accum;
- hist[i0].dt_y = y_accum;
/* We have a mouse click to process */
skip_syn = false;
@@ -1662,11 +1621,7 @@ evin_doubletap_emulate(const struct input_event *eve)
skip_syn = false;
break;
case ABS_MT_POSITION_X:
- hist[i0].dt_x = eve->value;
- skip_syn = false;
- break;
case ABS_MT_POSITION_Y:
- hist[i0].dt_y = eve->value;
skip_syn = false;
break;
default:
@@ -1696,35 +1651,24 @@ evin_doubletap_emulate(const struct input_event *eve)
hist[i0].dt_time = eve->time;
/* Last event before current */
- i1 = (i0 + 3) & 3;
+ i1 = (i0 + 1) & 1;
int tp0 = evin_doubletap_active_touch_points(hist+i0);
int tp1 = evin_doubletap_active_touch_points(hist+i1);
- if( tp0 != tp1 ) {
- /* 2nd and 3rd last events before current */
- i2 = (i0 + 2) & 3;
- i3 = (i0 + 1) & 3;
-
- int tp2 = evin_doubletap_active_touch_points(hist+i2);
- int tp3 = evin_doubletap_active_touch_points(hist+i3);
-
- /* Release after click after release after click,
- * within the time and distance limits */
- if( tp0 == 0 && tp1 == 1 && tp2 == 0 && tp3 == 1 &&
- evin_doubletap_within_time_limit(&hist[i3], &hist[i0]) &&
- evin_doubletap_within_dist_limit(&hist[i3], &hist[i1]) ) {
+ /* Release after click */
+ if( tp0 != tp1) {
+ if( tp0 == 0 && tp1 == 1 &&
+ evin_doubletap_more_than_min_time(&hist[i1], &hist[i0]) ) {
/* Reached DOUBLETAP state */
result = TRUE;
- /* Reset history, so that triple click
- * will not produce 2 double taps etc */
+ /* Reset history */
memset(hist, 0, sizeof hist);
- x_accum = y_accum = 0;
}
/* Move to the next slot */
- i0 = (i0 + 1) & 3;
+ i0 = (i0 + 1) & 1;
}
/* Reset the current position in the ring buffer */
--
2.7.4
......@@ -7,6 +7,7 @@ SRC_URI = "git://git.merproject.org/mer-core/mce.git;protocol=https \
file://0001-Fixes_build.patch \
file://0002-Display-Sets-default-brightness-to-100.patch \
file://0003-Display-Sets-dimming-timeout-to-10-sec-and-blanking-.patch \
file://0001-event-input-Double-tap-emulation-Adapts-the-state-ma.patch \
file://mce.service"
SRCREV = "ad535db76b7443febaf4f97328eb1968a3f1d8cc"
PR = "r1"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment