[PATCH libinput 2/2] tablet: Add libinput_tool_has_axis() and tests
Stephen Chandler Paul
thatslyude at gmail.com
Wed Aug 6 21:09:23 PDT 2014
Signed-off-by: Stephen Chandler Paul <thatslyude at gmail.com>
---
src/evdev-tablet.c | 42 +++++++++++++++++++++++++++++++
src/evdev-tablet.h | 1 +
src/libinput-private.h | 1 +
src/libinput.c | 7 ++++++
src/libinput.h | 26 +++++++++++++++++++
test/tablet.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 145 insertions(+)
diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 6ae6844..f56d7f4 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -298,6 +298,40 @@ tablet_get_tool(struct tablet_dispatch *tablet,
.refcount = 1,
};
+ /* Determine the axis capabilities of the tool. Here's a break
+ * down of the heuristics used here:
+ * - The Wacom art pen supports all of the extra axes, along
+ * with rotation
+ * - All of normal pens and the airbrush support all of the
+ * extra axes if the tablet can report them
+ * - All of the mouse like devices don't really report any of
+ * the extra axes except for rotation.
+ * (as of writing this comment, rotation isn't supported, so you
+ * won't see the mouse or art pen here)
+ */
+ switch (type) {
+ case LIBINPUT_TOOL_PEN:
+ case LIBINPUT_TOOL_ERASER:
+ case LIBINPUT_TOOL_PENCIL:
+ case LIBINPUT_TOOL_BRUSH:
+ case LIBINPUT_TOOL_AIRBRUSH:
+ if (bit_is_set(tablet->axis_caps,
+ LIBINPUT_TOOL_AXIS_FLAG_PRESSURE))
+ set_bit(tool->axis_caps,
+ LIBINPUT_TOOL_AXIS_FLAG_PRESSURE);
+ if (bit_is_set(tablet->axis_caps,
+ LIBINPUT_TOOL_AXIS_FLAG_DISTANCE))
+ set_bit(tool->axis_caps,
+ LIBINPUT_TOOL_AXIS_FLAG_DISTANCE);
+ if (bit_is_set(tablet->axis_caps,
+ LIBINPUT_TOOL_AXIS_FLAG_TILT))
+ set_bit(tool->axis_caps,
+ LIBINPUT_TOOL_AXIS_FLAG_TILT);
+ break;
+ default:
+ break;
+ }
+
list_insert(tool_list, &tool->link);
}
@@ -507,6 +541,14 @@ tablet_init(struct tablet_dispatch *tablet,
tablet->current_tool_type = LIBINPUT_TOOL_NONE;
list_init(&tablet->tool_list);
+ if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_PRESSURE))
+ set_bit(tablet->axis_caps, LIBINPUT_TOOL_AXIS_FLAG_PRESSURE);
+ if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_DISTANCE))
+ set_bit(tablet->axis_caps, LIBINPUT_TOOL_AXIS_FLAG_DISTANCE);
+ if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_TILT_X) &&
+ libevdev_has_event_code(device->evdev, EV_ABS, ABS_TILT_Y))
+ set_bit(tablet->axis_caps, LIBINPUT_TOOL_AXIS_FLAG_TILT);
+
tablet_mark_all_axes_changed(tablet, device);
return 0;
diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
index d16aef3..be2d09a 100644
--- a/src/evdev-tablet.h
+++ b/src/evdev-tablet.h
@@ -49,6 +49,7 @@ struct tablet_dispatch {
unsigned char status;
unsigned char changed_axes[NCHARS(LIBINPUT_TABLET_AXIS_CNT)];
double axes[LIBINPUT_TABLET_AXIS_CNT];
+ unsigned char axis_caps[NCHARS(LIBINPUT_TOOL_AXIS_FLAG_CNT)];
/* Only used for tablets that don't report serial numbers */
struct list tool_list;
diff --git a/src/libinput-private.h b/src/libinput-private.h
index 8187564..bdef330 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -108,6 +108,7 @@ struct libinput_tool {
struct list link;
uint32_t serial;
enum libinput_tool_type type;
+ unsigned char axis_caps[NCHARS(LIBINPUT_TOOL_AXIS_FLAG_CNT)];
int refcount;
void *user_data;
};
diff --git a/src/libinput.c b/src/libinput.c
index 68187d8..560fedd 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -599,6 +599,13 @@ libinput_tool_get_serial(struct libinput_tool *tool)
return tool->serial;
}
+LIBINPUT_EXPORT int
+libinput_tool_has_axis(struct libinput_tool *tool,
+ enum libinput_tool_axis_flag axis)
+{
+ return bit_is_set(tool->axis_caps, axis);
+}
+
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 1d4952b..63c5ad3 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -214,6 +214,19 @@ enum libinput_tool_type {
};
/**
+ * @ingroup device
+ *
+ * A series of flags for representing which kinds of axes a tablet tool can
+ * support.
+ */
+enum libinput_tool_axis_flag {
+ LIBINPUT_TOOL_AXIS_FLAG_PRESSURE = 0,
+ LIBINPUT_TOOL_AXIS_FLAG_DISTANCE = 1,
+ LIBINPUT_TOOL_AXIS_FLAG_TILT = 2,
+ LIBINPUT_TOOL_AXIS_FLAG_CNT = 3,
+};
+
+/**
* @ingroup base
*
* Event type for events returned by libinput_get_event().
@@ -1010,6 +1023,19 @@ libinput_tool_ref(struct libinput_tool *tool);
/**
* @ingroup event_tablet
*
+ * Return whether or not a tablet tool supports the specified axis
+ *
+ * @param tool The tool to check the axis capabilities of
+ * @param axis The axis to check for support
+ * @return Whether or not the axis is supported
+ */
+int
+libinput_tool_has_axis(struct libinput_tool *tool,
+ enum libinput_tool_axis_flag axis);
+
+/**
+ * @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/test/tablet.c b/test/tablet.c
index 60a4240..d4624a5 100644
--- a/test/tablet.c
+++ b/test/tablet.c
@@ -758,10 +758,78 @@ START_TEST(tools_without_serials)
}
END_TEST
+START_TEST(tool_capabilities)
+{
+ struct libinput *li = litest_create_context();
+ struct litest_device *intuos;
+ struct litest_device *bamboo;
+ struct libinput_event *event;
+
+ /* The axis capabilities of a tool can differ depending on the type of
+ * tablet the tool is being used with */
+ bamboo = litest_create_device_with_overrides(LITEST_WACOM_BAMBOO,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ intuos = litest_create_device_with_overrides(LITEST_WACOM_INTUOS,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+
+ litest_event(bamboo, EV_KEY, BTN_TOOL_PEN, 1);
+ litest_event(bamboo, EV_SYN, SYN_REPORT, 0);
+
+ libinput_dispatch(li);
+ while ((event = libinput_get_event(li))) {
+ if (libinput_event_get_type(event) ==
+ LIBINPUT_EVENT_TABLET_PROXIMITY_IN) {
+ struct libinput_event_tablet *t =
+ libinput_event_get_tablet_event(event);
+ struct libinput_tool *tool =
+ libinput_event_tablet_get_tool(t);
+
+ ck_assert(libinput_tool_has_axis(
+ tool, LIBINPUT_TOOL_AXIS_FLAG_PRESSURE));
+ ck_assert(!libinput_tool_has_axis(
+ tool, LIBINPUT_TOOL_AXIS_FLAG_TILT));
+ ck_assert(libinput_tool_has_axis(
+ tool, LIBINPUT_TOOL_AXIS_FLAG_DISTANCE));
+ }
+
+ libinput_event_destroy(event);
+ }
+
+ litest_event(intuos, EV_KEY, BTN_TOOL_PEN, 1);
+ litest_event(intuos, EV_SYN, SYN_REPORT, 0);
+
+ while ((event = libinput_get_event(li))) {
+ if (libinput_event_get_type(event) ==
+ LIBINPUT_EVENT_TABLET_PROXIMITY_IN) {
+ struct libinput_event_tablet *t =
+ libinput_event_get_tablet_event(event);
+ struct libinput_tool *tool =
+ libinput_event_tablet_get_tool(t);
+
+ ck_assert(libinput_tool_has_axis(
+ tool, LIBINPUT_TOOL_AXIS_FLAG_PRESSURE));
+ ck_assert(libinput_tool_has_axis(
+ tool, LIBINPUT_TOOL_AXIS_FLAG_DISTANCE));
+ ck_assert(libinput_tool_has_axis(
+ tool, LIBINPUT_TOOL_AXIS_FLAG_TILT));
+ }
+
+ libinput_event_destroy(event);
+ }
+}
+END_TEST
+
int
main(int argc, char **argv)
{
litest_add("tablet:tool", tool_ref, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
+ litest_add_no_device("tablet:tool", tool_capabilities);
litest_add("tablet:tool_serial", tool_serial, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
litest_add("tablet:tool_serial", serial_changes_tool, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
litest_add("tablet:tool_serial", invalid_serials, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
--
1.8.5.5
More information about the wayland-devel
mailing list