summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2014-12-12 10:31:12 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2015-01-16 07:39:59 +1000
commit99cb9087224a8e7b0b988b13d391a54524eec61c (patch)
tree8b855f24ecce19197d81761a5697d7d938b94c66
parentc8dc81b48f856c467f38af85288cd82a2384d0b7 (diff)
touchpad: factor out fake finger handling
We need this for determining hovering touches on some semi-mt touchpads. This makes the fake_touches mask use bit 0 for BTN_TOUCH, and the other bits for BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, etc. BTN_TOUCH is independent of the rest, the others are mutually exclusive in the kernel. Since the mask isn't a straightforward bitmask anymore, abstract it all through helper functions. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r--src/evdev-mt-touchpad.c72
-rw-r--r--src/evdev-mt-touchpad.h7
2 files changed, 59 insertions, 20 deletions
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 34b107e2..406ac39a 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -135,6 +135,57 @@ tp_get_touch(struct tp_dispatch *tp, unsigned int slot)
return &tp->touches[slot];
}
+static inline unsigned int
+tp_fake_finger_count(struct tp_dispatch *tp)
+{
+ unsigned int fake_touches, nfake_touches;
+
+ /* don't count BTN_TOUCH */
+ fake_touches = tp->fake_touches >> 1;
+ nfake_touches = 0;
+ while (fake_touches) {
+ nfake_touches++;
+ fake_touches >>= 1;
+ }
+
+ return nfake_touches;
+}
+
+static inline bool
+tp_fake_finger_is_touching(struct tp_dispatch *tp)
+{
+ return tp->fake_touches & 0x1;
+}
+
+static inline void
+tp_fake_finger_set(struct tp_dispatch *tp,
+ unsigned int code,
+ bool is_press)
+{
+ unsigned int shift;
+
+ switch (code) {
+ case BTN_TOUCH:
+ shift = 0;
+ break;
+ case BTN_TOOL_FINGER:
+ shift = 1;
+ break;
+ case BTN_TOOL_DOUBLETAP:
+ case BTN_TOOL_TRIPLETAP:
+ case BTN_TOOL_QUADTAP:
+ shift = code - BTN_TOOL_DOUBLETAP + 2;
+ break;
+ default:
+ return;
+ }
+
+ if (is_press)
+ tp->fake_touches |= 1 << shift;
+ else
+ tp->fake_touches &= ~(0x1 << shift);
+}
+
static inline void
tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
{
@@ -253,30 +304,13 @@ tp_process_fake_touch(struct tp_dispatch *tp,
uint64_t time)
{
struct tp_touch *t;
- unsigned int fake_touches;
unsigned int nfake_touches;
unsigned int i, start;
- unsigned int shift;
-
- if (e->code != BTN_TOUCH &&
- (e->code < BTN_TOOL_DOUBLETAP || e->code > BTN_TOOL_QUADTAP))
- return;
-
- shift = e->code == BTN_TOUCH ? 0 : (e->code - BTN_TOOL_DOUBLETAP + 1);
- if (e->value)
- tp->fake_touches |= 1 << shift;
- else
- tp->fake_touches &= ~(0x1 << shift);
+ tp_fake_finger_set(tp, e->code, e->value != 0);
- fake_touches = tp->fake_touches;
- nfake_touches = 0;
- while (fake_touches) {
- nfake_touches++;
- fake_touches >>= 1;
- }
+ nfake_touches = tp_fake_finger_count(tp);
- /* For single touch tps we use BTN_TOUCH for begin / end of touch 0 */
start = tp->has_mt ? tp->real_touches : 0;
for (i = start; i < tp->ntouches; i++) {
t = tp_get_touch(tp, i);
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 5807f08c..1e6152ae 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -197,7 +197,12 @@ struct tp_dispatch {
unsigned int real_touches; /* number of slots */
unsigned int ntouches; /* no slots inc. fakes */
struct tp_touch *touches; /* len == ntouches */
- unsigned int fake_touches; /* fake touch mask */
+ /* bit 0: BTN_TOUCH
+ * bit 1: BTN_TOOL_FINGER
+ * bit 2: BTN_TOOL_DOUBLETAP
+ * ...
+ */
+ unsigned int fake_touches;
struct {
int32_t margin_x;