[PATCH libinput] Add libinput_device_keyboard_has_key()

Peter Hutterer peter.hutterer at who-t.net
Tue Apr 21 21:44:58 PDT 2015


Similar to libinput_device_pointer_has_button(), this function returns whether
a given device has a specific keycode.

This enables a caller to determine if the device is really a keyboard (check
for KEY_A-KEY_Z) or just a media key device (check for KEY_PLAY or somesuch),
depending on the context required.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
Had a deja-vu implementing this, I thought this already existed.

 src/evdev.c      |  9 +++++++++
 src/evdev.h      |  3 +++
 src/libinput.c   |  6 ++++++
 src/libinput.h   | 16 ++++++++++++++++
 src/libinput.sym |  5 +++++
 test/keyboard.c  | 20 ++++++++++++++++++++
 6 files changed, 59 insertions(+)

diff --git a/src/evdev.c b/src/evdev.c
index 1a7282d..e254afd 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -2115,6 +2115,15 @@ evdev_device_has_button(struct evdev_device *device, uint32_t code)
 	return libevdev_has_event_code(device->evdev, EV_KEY, code);
 }
 
+int
+evdev_device_has_key(struct evdev_device *device, uint32_t code)
+{
+	if (!(device->seat_caps & EVDEV_DEVICE_KEYBOARD))
+		return -1;
+
+	return libevdev_has_event_code(device->evdev, EV_KEY, code);
+}
+
 static inline bool
 evdev_is_scrolling(const struct evdev_device *device,
 		   enum libinput_pointer_axis axis)
diff --git a/src/evdev.h b/src/evdev.h
index 9b1dcc3..0c94e3e 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -309,6 +309,9 @@ evdev_device_get_size(struct evdev_device *device,
 int
 evdev_device_has_button(struct evdev_device *device, uint32_t code);
 
+int
+evdev_device_has_key(struct evdev_device *device, uint32_t code);
+
 double
 evdev_device_transform_x(struct evdev_device *device,
 			 double x,
diff --git a/src/libinput.c b/src/libinput.c
index 7dcf296..5ef7edf 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -1547,6 +1547,12 @@ libinput_device_pointer_has_button(struct libinput_device *device, uint32_t code
 	return evdev_device_has_button((struct evdev_device *)device, code);
 }
 
+LIBINPUT_EXPORT int
+libinput_device_keyboard_has_key(struct libinput_device *device, uint32_t code)
+{
+	return evdev_device_has_key((struct evdev_device *)device, code);
+}
+
 LIBINPUT_EXPORT struct libinput_event *
 libinput_event_device_notify_get_base_event(struct libinput_event_device_notify *event)
 {
diff --git a/src/libinput.h b/src/libinput.h
index b4b373e..2719956 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -1711,6 +1711,22 @@ libinput_device_pointer_has_button(struct libinput_device *device, uint32_t code
 /**
  * @ingroup device
  *
+ * Check if a @ref LIBINPUT_DEVICE_CAP_KEYBOARD device has a key with the
+ * given code (see linux/input.h).
+ *
+ * @param device A current input device
+ * @param code Key code to check for, e.g. <i>KEY_ESc</i>
+ *
+ * @return 1 if the device supports this key code, 0 if it does not, -1
+ * on error.
+ */
+int
+libinput_device_keyboard_has_key(struct libinput_device *device,
+				 uint32_t code);
+
+/**
+ * @ingroup device
+ *
  * Increase the refcount of the device group. A device group will be freed
  * whenever the refcount reaches 0. This may happen during
  * libinput_dispatch() if all devices of this group were removed from the
diff --git a/src/libinput.sym b/src/libinput.sym
index 431870f..9c11174 100644
--- a/src/libinput.sym
+++ b/src/libinput.sym
@@ -135,3 +135,8 @@ global:
 	libinput_device_config_middle_emulation_is_available;
 	libinput_device_config_middle_emulation_set_enabled;
 } LIBINPUT_0.12.0;
+
+LIBINPUT_0.15.0 {
+global:
+	libinput_device_keyboard_has_key;
+} LIBINPUT_0.14.0;
diff --git a/test/keyboard.c b/test/keyboard.c
index cb7ad52..a477cfb 100644
--- a/test/keyboard.c
+++ b/test/keyboard.c
@@ -290,12 +290,32 @@ START_TEST(keyboard_key_auto_release)
 }
 END_TEST
 
+START_TEST(keyboard_has_key)
+{
+	struct litest_device *dev = litest_current_device();
+	struct libinput_device *device = dev->libinput_device;
+	unsigned int code;
+	int evdev_has, libinput_has;
+
+	ck_assert(libinput_device_has_capability(
+					 device,
+					 LIBINPUT_DEVICE_CAP_KEYBOARD));
+
+	for (code = 0; code < KEY_CNT; code++) {
+		evdev_has = libevdev_has_event_code(dev->evdev, EV_KEY, code);
+		libinput_has = libinput_device_keyboard_has_key(device, code);
+		ck_assert_int_eq(evdev_has, libinput_has);
+	}
+}
+END_TEST
+
 int
 main(int argc, char **argv)
 {
 	litest_add_no_device("keyboard:seat key count", keyboard_seat_key_count);
 	litest_add_no_device("keyboard:key counting", keyboard_ignore_no_pressed_release);
 	litest_add_no_device("keyboard:key counting", keyboard_key_auto_release);
+	litest_add("keyboard:keys", keyboard_has_key, LITEST_KEYS, LITEST_ANY);
 
 	return litest_run(argc, argv);
 }
-- 
2.3.5



More information about the wayland-devel mailing list