touchpad: add a struct for handling physical button event state changes
authorPeter Hutterer <peter.hutterer@who-t.net>
Fri, 7 Feb 2014 03:59:38 +0000 (13:59 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Mon, 24 Mar 2014 04:56:40 +0000 (14:56 +1000)
On ClickPads (touchpads without phys. middle/right buttons) it is important to
know whether a physical click is queued up. The finger position or number of
fingers decide which button event to send.

This isn't currently used, we still just send the button number at the moment.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
src/evdev-mt-touchpad.c
src/evdev-mt-touchpad.h

index 1d34df88a873af1751d71a501a05ec60b23236a2..e25997df5f62e6e0cc5872331c1c38d899ebd392 100644 (file)
@@ -230,16 +230,20 @@ tp_process_key(struct tp_dispatch *tp,
               const struct input_event *e,
               uint32_t time)
 {
+       uint32_t mask;
+
        switch (e->code) {
                case BTN_LEFT:
                case BTN_MIDDLE:
                case BTN_RIGHT:
-                       pointer_notify_button(
-                               &tp->device->base,
-                               time,
-                               e->code,
-                               e->value ? LIBINPUT_POINTER_BUTTON_STATE_PRESSED :
-                                          LIBINPUT_POINTER_BUTTON_STATE_RELEASED);
+                       mask = 1 << (e->code - BTN_LEFT);
+                       if (e->value) {
+                               tp->buttons.state |= mask;
+                               tp->queued |= TOUCHPAD_EVENT_BUTTON_PRESS;
+                       } else {
+                               tp->buttons.state &= ~mask;
+                               tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE;
+                       }
                        break;
        }
 }
@@ -275,6 +279,8 @@ tp_post_process_state(struct tp_dispatch *tp, uint32_t time)
                t->dirty = false;
        }
 
+       tp->buttons.old_state = tp->buttons.state;
+
        tp->queued = TOUCHPAD_EVENT_NONE;
 }
 
@@ -316,6 +322,40 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint32_t time)
                                    li_fixed_from_double(dy));
 }
 
+static void
+tp_post_button_events(struct tp_dispatch *tp, uint32_t time)
+{
+       uint32_t current, old, button;
+
+       if ((tp->queued &
+               (TOUCHPAD_EVENT_BUTTON_PRESS|TOUCHPAD_EVENT_BUTTON_RELEASE)) == 0)
+                               return;
+
+       current = tp->buttons.state;
+       old = tp->buttons.old_state;
+       button = BTN_LEFT;
+
+       while (current || old) {
+               enum libinput_pointer_button_state state;
+
+               if ((current & 0x1) ^ (old & 0x1)) {
+                       if (!!(current & 0x1))
+                               state = LIBINPUT_POINTER_BUTTON_STATE_PRESSED;
+                       else
+                               state = LIBINPUT_POINTER_BUTTON_STATE_RELEASED;
+
+                       pointer_notify_button(&tp->device->base,
+                                             time,
+                                             button,
+                                             state);
+               }
+
+               button++;
+               current >>= 1;
+               old >>= 1;
+       }
+}
+
 static void
 tp_post_events(struct tp_dispatch *tp, uint32_t time)
 {
@@ -342,6 +382,8 @@ tp_post_events(struct tp_dispatch *tp, uint32_t time)
                        time,
                        li_fixed_from_double(dx),
                        li_fixed_from_double(dy));
+
+       tp_post_button_events(tp, time);
 }
 
 static void
index 52ad3ab0a24e6a9e489b3e1a57e9da47adfe6b05..d12647deee2d308a4052f06dac8f0052f70247a5 100644 (file)
@@ -91,6 +91,11 @@ struct tp_dispatch {
                double max_factor;
        } accel;
 
+       struct {
+               uint32_t state;
+               uint32_t old_state;
+       } buttons;                              /* physical buttons */
+
        enum touchpad_event queued;
 };