touchpad: factor out fake finger handling
authorPeter Hutterer <peter.hutterer@who-t.net>
Fri, 12 Dec 2014 00:31:12 +0000 (10:31 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Thu, 15 Jan 2015 21:39:59 +0000 (07:39 +1000)
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>
src/evdev-mt-touchpad.c
src/evdev-mt-touchpad.h

index 34b107e2725f4ec8f2ea9e3c4ca3c46d067ec224..406ac39ac73bd813975960204d1bd7842935d3dd 100644 (file)
@@ -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);
index 5807f08c498701dac33612cdaf2e5230d346ec27..1e6152aedcb939ccf4ccb185794a6fb930cc2164 100644 (file)
@@ -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;