[PATCH libinput 2/4] evdev: Keep track of button/key press count per device

Jonas Ådahl jadahl at gmail.com
Sun Jul 27 14:28:29 PDT 2014


Keep track of the number of times a given button or key is pressed on a
device. For regular mouse devices or keyboard devices, such a count will
never exceed 1, but counting button presses could help when button
presses with the same code can originate from different sources. One could
for example implement overlapping tap-drags with button presses by
having them deal with their own life-time independently, sorting out
when the user should receive button presses or not depending on the
pressed count.

Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
---
 src/evdev-mt-touchpad-buttons.c | 30 +++++++++++++------------
 src/evdev-mt-touchpad-tap.c     |  8 +++----
 src/evdev.c                     | 49 +++++++++++++++++++++++++++++++++++++----
 src/evdev.h                     | 13 +++++++++++
 4 files changed, 78 insertions(+), 22 deletions(-)

diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index fe33d0b..8a28054 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -606,11 +606,12 @@ tp_post_clickfinger_buttons(struct tp_dispatch *tp, uint64_t time)
 		state = LIBINPUT_BUTTON_STATE_RELEASED;
 	}
 
-	if (button)
-		pointer_notify_button(&tp->device->base,
-				      time,
-				      button,
-				      state);
+	if (button) {
+		evdev_pointer_notify_button(tp->device,
+					    time,
+					    button,
+					    state);
+	}
 	return 1;
 }
 
@@ -632,10 +633,10 @@ tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
 			else
 				state = LIBINPUT_BUTTON_STATE_RELEASED;
 
-			pointer_notify_button(&tp->device->base,
-					      time,
-					      button,
-					      state);
+			evdev_pointer_notify_button(tp->device,
+						    time,
+						    button,
+						    state);
 		}
 
 		button++;
@@ -707,11 +708,12 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
 
 	tp->buttons.click_pending = false;
 
-	if (button)
-		pointer_notify_button(&tp->device->base,
-				      time,
-				      button,
-				      state);
+	if (button) {
+		evdev_pointer_notify_button(tp->device,
+					    time,
+					    button,
+					    state);
+	}
 	return 1;
 }
 
diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c
index 6008507..64801a8 100644
--- a/src/evdev-mt-touchpad-tap.c
+++ b/src/evdev-mt-touchpad-tap.c
@@ -113,10 +113,10 @@ tp_tap_notify(struct tp_dispatch *tp,
 		return;
 	}
 
-	pointer_notify_button(&tp->device->base,
-			      time,
-			      button,
-			      state);
+	evdev_pointer_notify_button(tp->device,
+				    time,
+				    button,
+				    state);
 }
 
 static void
diff --git a/src/evdev.c b/src/evdev.c
index 0f4874c..f656a5e 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -59,6 +59,47 @@ is_key_pressed(struct evdev_device *device, int code)
 	return long_bit_is_set(device->key_mask, code);
 }
 
+static int
+update_key_pressed_count(struct evdev_device *device, int code, int pressed)
+{
+	assert(code >= 0 && code < KEY_CNT);
+
+	if (pressed) {
+		return ++device->key_count[code];
+	} else {
+		assert(device->key_count[code] > 0);
+		return --device->key_count[code];
+	}
+}
+
+void
+evdev_keyboard_notify_key(struct evdev_device *device,
+			  uint32_t time,
+			  int key,
+			  enum libinput_key_state state)
+{
+	int pressed_count;
+
+	pressed_count = update_key_pressed_count(device, key, state);
+
+	if ((state && pressed_count == 1) || (!state && pressed_count == 0))
+		keyboard_notify_key(&device->base, time, key, state);
+}
+
+void
+evdev_pointer_notify_button(struct evdev_device *device,
+			    uint32_t time,
+			    int button,
+			    enum libinput_button_state state)
+{
+	int pressed_count;
+
+	pressed_count = update_key_pressed_count(device, button, state);
+
+	if ((state && pressed_count == 1) || (!state && pressed_count == 0))
+		pointer_notify_button(&device->base, time, button, state);
+}
+
 void
 evdev_device_led_update(struct evdev_device *device, enum libinput_led leds)
 {
@@ -341,16 +382,16 @@ evdev_process_key(struct evdev_device *device,
 	case EVDEV_KEY_TYPE_NONE:
 		break;
 	case EVDEV_KEY_TYPE_KEY:
-		keyboard_notify_key(
-			&device->base,
+		evdev_keyboard_notify_key(
+			device,
 			time,
 			e->code,
 			e->value ? LIBINPUT_KEY_STATE_PRESSED :
 				   LIBINPUT_KEY_STATE_RELEASED);
 		break;
 	case EVDEV_KEY_TYPE_BUTTON:
-		pointer_notify_button(
-			&device->base,
+		evdev_pointer_notify_button(
+			device,
 			time,
 			e->code,
 			e->value ? LIBINPUT_BUTTON_STATE_PRESSED :
diff --git a/src/evdev.h b/src/evdev.h
index f71d387..1819ae8 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -96,6 +96,7 @@ struct evdev_device {
 	} pointer;
 
 	unsigned long key_mask[NLONGS(KEY_CNT)];
+	uint8_t key_count[KEY_CNT];
 };
 
 #define EVDEV_UNHANDLED_DEVICE ((struct evdev_device *) 1)
@@ -175,6 +176,18 @@ evdev_device_transform_y(struct evdev_device *device,
 			 uint32_t height);
 
 void
+evdev_keyboard_notify_key(struct evdev_device *device,
+			  uint32_t time,
+			  int key,
+			  enum libinput_key_state state);
+
+void
+evdev_pointer_notify_button(struct evdev_device *device,
+			    uint32_t time,
+			    int button,
+			    enum libinput_button_state state);
+
+void
 evdev_device_remove(struct evdev_device *device);
 
 void
-- 
1.8.5.1



More information about the wayland-devel mailing list