[PATCH libinput 16/26] tablet: add support for libinput_tool_has_button

Peter Hutterer peter.hutterer at who-t.net
Mon Feb 23 22:21:19 PST 2015


libwacom can tell us how many buttons we have per stylus, so we map those into
BTN_STYLUS and BTN_STYLUS2.
BTN_TOUCH is set on all styli.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-tablet.c     | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/libinput-private.h |  1 +
 src/libinput.c         | 10 +++++++
 src/libinput.h         | 15 +++++++++++
 src/libinput.sym       |  1 +
 5 files changed, 100 insertions(+)

diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 85bdcd7..ced9207 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -382,6 +382,51 @@ copy_axis_cap(const struct tablet_dispatch *tablet,
 		set_bit(tool->axis_caps, axis);
 }
 
+static inline void
+copy_button_cap(const struct tablet_dispatch *tablet,
+		struct libinput_tool *tool,
+		uint32_t button)
+{
+	struct libevdev *evdev = tablet->device->evdev;
+	if (libevdev_has_event_code(evdev, EV_KEY, button))
+		set_bit(tool->buttons, button);
+}
+
+static void
+tool_set_bits_from_libwacom(const struct tablet_dispatch *tablet,
+			    struct libinput_tool *tool)
+{
+#if HAVE_LIBWACOM
+	WacomDeviceDatabase *db;
+	const WacomStylus *s = NULL;
+	int code;
+
+	db = libwacom_database_new();
+	if (!db)
+		goto out;
+	s = libwacom_stylus_get_for_id(db, tool->tool_id);
+	if (!s)
+		goto out;
+
+	if (libwacom_stylus_get_type(s) == WSTYLUS_PUCK) {
+		for (code = BTN_LEFT;
+		     code < BTN_LEFT + libwacom_stylus_get_num_buttons(s);
+		     code++)
+			copy_button_cap(tablet, tool, code);
+	} else {
+		if (libwacom_stylus_get_num_buttons(s) >= 2)
+			copy_button_cap(tablet, tool, BTN_STYLUS2);
+		if (libwacom_stylus_get_num_buttons(s) >= 1)
+			copy_button_cap(tablet, tool, BTN_STYLUS);
+		copy_button_cap(tablet, tool, BTN_TOUCH);
+	}
+
+out:
+	if (db)
+		libwacom_database_destroy(db);
+#endif
+}
+
 static void
 tool_set_bits(const struct tablet_dispatch *tablet,
 	      struct libinput_tool *tool)
@@ -413,6 +458,34 @@ tool_set_bits(const struct tablet_dispatch *tablet,
 	default:
 		break;
 	}
+
+#if HAVE_LIBWACOM
+	tool_set_bits_from_libwacom(tablet, tool);
+#else
+	/* If we don't have libwacom, copy all pen-related ones from the
+	   tablet vs all mouse-related ones */
+	switch (type) {
+	case LIBINPUT_TOOL_PEN:
+	case LIBINPUT_TOOL_BRUSH:
+	case LIBINPUT_TOOL_AIRBRUSH:
+	case LIBINPUT_TOOL_PENCIL:
+	case LIBINPUT_TOOL_ERASER:
+		copy_button_cap(tablet, tool, BTN_STYLUS);
+		copy_button_cap(tablet, tool, BTN_STYLUS2);
+		copy_button_cap(tablet, tool, BTN_TOUCH);
+		break;
+	case LIBINPUT_TOOL_MOUSE:
+	case LIBINPUT_TOOL_LENS:
+		copy_button_cap(tablet, tool, BTN_LEFT);
+		copy_button_cap(tablet, tool, BTN_MIDDLE);
+		copy_button_cap(tablet, tool, BTN_RIGHT);
+		copy_button_cap(tablet, tool, BTN_SIDE);
+		copy_button_cap(tablet, tool, BTN_EXTRA);
+		break;
+	default:
+		break;
+	}
+#endif
 }
 
 static struct libinput_tool *
diff --git a/src/libinput-private.h b/src/libinput-private.h
index b2dc406..9f32655 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -191,6 +191,7 @@ struct libinput_tool {
 	uint32_t tool_id;
 	enum libinput_tool_type type;
 	unsigned char axis_caps[NCHARS(LIBINPUT_TABLET_AXIS_MAX + 1)];
+	unsigned char buttons[NCHARS(KEY_MAX) + 1];
 	int refcount;
 	void *user_data;
 };
diff --git a/src/libinput.c b/src/libinput.c
index b165c59..5ed3ffc 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -681,6 +681,16 @@ libinput_tool_has_axis(struct libinput_tool *tool,
 	return bit_is_set(tool->axis_caps, axis);
 }
 
+LIBINPUT_EXPORT int
+libinput_tool_has_button(struct libinput_tool *tool,
+			 uint32_t code)
+{
+	if (NCHARS(code) > sizeof(tool->buttons))
+		return 0;
+
+	return bit_is_set(tool->buttons, code);
+}
+
 LIBINPUT_EXPORT void
 libinput_tool_set_user_data(struct libinput_tool *tool,
 			    void *user_data)
diff --git a/src/libinput.h b/src/libinput.h
index f746671..02b2c11 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -1244,6 +1244,21 @@ libinput_tool_has_axis(struct libinput_tool *tool,
 /**
  * @ingroup event_tablet
  *
+ * Check if a tablet tool has a button with the
+ * passed-in code (see linux/input.h).
+ *
+ * @param tool A tablet tool
+ * @param code button code to check for
+ *
+ * @return 1 if the tool supports this button code, 0 if it does not
+ */
+int
+libinput_tool_has_button(struct libinput_tool *tool,
+		         uint32_t code);
+
+/**
+ * @ingroup event_tablet
+ *
  * Decrement the ref count of tool by one. When the ref count of tool reaches 0,
  * the memory allocated for tool will be freed.
  *
diff --git a/src/libinput.sym b/src/libinput.sym
index 5561478..e674226 100644
--- a/src/libinput.sym
+++ b/src/libinput.sym
@@ -159,6 +159,7 @@ LIBINPUT_TABLET_SUPPORT {
 	libinput_tool_get_tool_id;
 	libinput_tool_get_type;
 	libinput_tool_get_user_data;
+	libinput_tool_has_button;
 	libinput_tool_has_axis;
 	libinput_tool_ref;
 	libinput_tool_set_user_data;
-- 
2.1.0



More information about the wayland-devel mailing list