#include "litest.h"
#include "litest-int.h"
-static struct input_event proximity_in[] = {
+static struct input_event proximity_in_events[] = {
{ .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
{ .type = EV_ABS, .code = ABS_PRESSURE, .value = LITEST_AUTO_ASSIGN },
{ .type = -1, .code = -1 },
};
-static struct input_event proximity_out[] = {
+static struct input_event proximity_out_events[] = {
{ .type = EV_KEY, .code = LITEST_BTN_TOOL_AUTO, .value = 0 },
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
{ .type = -1, .code = -1 },
};
-static struct input_event motion[] = {
+static struct input_event motion_events[] = {
{ .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN },
{ .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN },
{ .type = EV_ABS, .code = ABS_PRESSURE, .value = LITEST_AUTO_ASSIGN },
{ .type = -1, .code = -1 },
};
+static bool
+proximity_in(struct litest_device *d,
+ unsigned int tool_type,
+ double x, double y,
+ struct axis_replacement *axes)
+{
+ /* nothing special needed for the pen tool, so let litest handle
+ * this */
+ if (tool_type == BTN_TOOL_PEN)
+ return false;
+
+ /* a non-pen tool requires the pen to be in proximity as well. */
+ x = litest_scale(d, ABS_X, x);
+ y = litest_scale(d, ABS_Y, y);
+ litest_event(d, EV_ABS, ABS_X, x);
+ litest_event(d, EV_ABS, ABS_X, y);
+ litest_event(d, EV_KEY, BTN_TOOL_PEN, 1);
+ litest_event(d, EV_SYN, SYN_REPORT, 0);
+
+ /* litest will append the proximity_in_events if we return false,
+ * including the right tool event */
+ return false;
+}
+
+static bool
+proximity_out(struct litest_device *d, unsigned int tool_type)
+{
+ /* a non-pen tool requires the pen to go out of proximity as well.
+ * litest will append the proximity_out_events if we return false
+ */
+ if (tool_type != BTN_TOOL_PEN)
+ litest_event(d, EV_KEY, BTN_TOOL_PEN, 0);
+
+ return false;
+}
+
static int
get_axis_default(struct litest_device *d, unsigned int evcode, int32_t *value)
{
}
static struct litest_device_interface interface = {
- .tablet_proximity_in_events = proximity_in,
- .tablet_proximity_out_events = proximity_out,
- .tablet_motion_events = motion,
+ .tablet_proximity_in_events = proximity_in_events,
+ .tablet_proximity_out_events = proximity_out_events,
+ .tablet_motion_events = motion_events,
+ .tablet_proximity_in = proximity_in,
+ .tablet_proximity_out = proximity_out,
.get_axis_default = get_axis_default,
};
.version = 0x100,
};
+/* Note: this tablet is one that sets both BTN_TOOL_PEN and BTN_TOOL_RUBBER,
+ * see https://gitlab.freedesktop.org/libinput/libinput/-/issues/259
+ * The one in the issue isn't the exact same model, but only the pid and x/y
+ * axis max differs differs.
+ */
static int events[] = {
EV_KEY, BTN_TOOL_PEN,
EV_KEY, BTN_TOOL_RUBBER,
{
struct input_event *ev;
+ /* If the test device overrides proximity_in and says it didn't
+ * handle the event, let's continue normally */
+ if (d->interface->tablet_proximity_in &&
+ d->interface->tablet_proximity_in(d, d->interface->tool_type, x, y, axes))
+ return;
+
ev = d->interface->tablet_proximity_in_events;
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
int value;
{
struct input_event *ev;
+ /* If the test device overrides proximity_out and says it didn't
+ * handle the event, let's continue normally */
+ if (d->interface->tablet_proximity_out &&
+ d->interface->tablet_proximity_out(d, d->interface->tool_type))
+ return;
+
ev = d->interface->tablet_proximity_out_events;
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
int value;
litest_drain_events(li);
for (tt = types; tt->code != -1; tt++) {
+ enum libinput_tablet_tool_type type;
+
if (!libevdev_has_event_code(dev->evdev,
EV_KEY,
tt->code))
t = litest_is_tablet_event(event,
LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
tool = libinput_event_tablet_tool_get_tool(t);
+ type = libinput_tablet_tool_get_type(tool);
+
+ /* Devices with doubled-up tool bits send the pen
+ * in-prox and immediately out-of-prox before the real tool
+ * type. Drop those two and continue with what we expect is
+ * the real prox in event */
+ if (tt->type != LIBINPUT_TABLET_TOOL_TYPE_PEN &&
+ type == LIBINPUT_TABLET_TOOL_TYPE_PEN) {
+ libinput_event_destroy(event);
+ event = libinput_get_event(li);
+ t = litest_is_tablet_event(event,
+ LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
+ libinput_event_destroy(event);
+ event = libinput_get_event(li);
+ t = litest_is_tablet_event(event,
+ LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
+ tool = libinput_event_tablet_tool_get_tool(t);
+ type = libinput_tablet_tool_get_type(tool);
+ }
- ck_assert_int_eq(libinput_tablet_tool_get_type(tool),
- tt->type);
+ ck_assert_int_eq(type, tt->type);
libinput_event_destroy(event);
litest_assert_empty_queue(li);