summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Chandler Paul <thatslyude@gmail.com>2014-08-07 22:02:22 -0400
committerPeter Hutterer <peter.hutterer@who-t.net>2014-08-08 13:12:53 +1000
commita0c9f1224e26731ae1393c625cf262a11d49db89 (patch)
treea928830421b408c28318d2e73d90f57f6bb14758
parent142cc66880a806fcd6667eeda30ed41769765379 (diff)
tablet: Add libinput_tool_has_axis() and tests
Because the axes that tool reports can change depending on the tool in use, we want to be able to provide functionality to determine which axes each tool can support. Signed-off-by: Stephen Chandler Paul <thatslyude@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--src/evdev-tablet.c47
-rw-r--r--src/evdev-tablet.h1
-rw-r--r--src/libinput-private.h1
-rw-r--r--src/libinput.c7
-rw-r--r--src/libinput.h13
-rw-r--r--test/tablet.c76
6 files changed, 145 insertions, 0 deletions
diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 15f0663b..a63b734a 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -302,6 +302,44 @@ 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_TABLET_AXIS_PRESSURE))
+ set_bit(tool->axis_caps,
+ LIBINPUT_TABLET_AXIS_PRESSURE);
+ if (bit_is_set(tablet->axis_caps,
+ LIBINPUT_TABLET_AXIS_DISTANCE))
+ set_bit(tool->axis_caps,
+ LIBINPUT_TABLET_AXIS_DISTANCE);
+ if (bit_is_set(tablet->axis_caps,
+ LIBINPUT_TABLET_AXIS_TILT_X))
+ set_bit(tool->axis_caps,
+ LIBINPUT_TABLET_AXIS_TILT_X);
+ if (bit_is_set(tablet->axis_caps,
+ LIBINPUT_TABLET_AXIS_TILT_Y))
+ set_bit(tool->axis_caps,
+ LIBINPUT_TABLET_AXIS_TILT_Y);
+ break;
+ default:
+ break;
+ }
+
list_insert(tool_list, &tool->link);
}
@@ -510,12 +548,21 @@ static int
tablet_init(struct tablet_dispatch *tablet,
struct evdev_device *device)
{
+ enum libinput_tablet_axis axis;
+
tablet->base.interface = &tablet_interface;
tablet->device = device;
tablet->status = TABLET_NONE;
tablet->current_tool_type = LIBINPUT_TOOL_NONE;
list_init(&tablet->tool_list);
+ for (axis = 0; axis < LIBINPUT_TABLET_AXIS_CNT; axis++) {
+ if (libevdev_has_event_code(device->evdev,
+ EV_ABS,
+ axis_to_evcode(axis)))
+ set_bit(tablet->axis_caps, axis);
+ }
+
tablet_mark_all_axes_changed(tablet, device);
return 0;
diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
index adc3aa4a..cb375771 100644
--- a/src/evdev-tablet.h
+++ b/src/evdev-tablet.h
@@ -48,6 +48,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_TABLET_AXIS_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 81875644..369bb8f3 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_TABLET_AXIS_CNT)];
int refcount;
void *user_data;
};
diff --git a/src/libinput.c b/src/libinput.c
index 68187d8c..e52527be 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_tablet_axis 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 1d4952b0..ed56c0bb 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -1010,6 +1010,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_tablet_axis 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 3617a8be..e1fb60d2 100644
--- a/test/tablet.c
+++ b/test/tablet.c
@@ -770,10 +770,86 @@ 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_TABLET_AXIS_PRESSURE));
+ ck_assert(libinput_tool_has_axis(tool,
+ LIBINPUT_TABLET_AXIS_DISTANCE));
+ ck_assert(!libinput_tool_has_axis(tool,
+ LIBINPUT_TABLET_AXIS_TILT_X));
+ ck_assert(!libinput_tool_has_axis(tool,
+ LIBINPUT_TABLET_AXIS_TILT_Y));
+ }
+
+ 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_TABLET_AXIS_PRESSURE));
+ ck_assert(libinput_tool_has_axis(tool,
+ LIBINPUT_TABLET_AXIS_DISTANCE));
+ ck_assert(libinput_tool_has_axis(tool,
+ LIBINPUT_TABLET_AXIS_TILT_X));
+ ck_assert(libinput_tool_has_axis(tool,
+ LIBINPUT_TABLET_AXIS_TILT_Y));
+ }
+
+ libinput_event_destroy(event);
+ }
+
+ litest_delete_device(bamboo);
+ litest_delete_device(intuos);
+ libinput_unref(li);
+}
+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);