test: tablet pad tests

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com>
Reviewed-by: Carlos Garnacho <carlosg@gnome.org>
This commit is contained in:
Peter Hutterer 2016-02-05 10:57:37 +10:00
parent 8e17a9ab5c
commit d82cfa1d53
8 changed files with 1002 additions and 1 deletions

View file

@ -48,6 +48,8 @@ liblitest_la_SOURCES = \
litest-device-wacom-cintiq-tablet.c \
litest-device-wacom-cintiq-24hd.c \
litest-device-wacom-intuos-tablet.c \
litest-device-wacom-intuos3-pad.c \
litest-device-wacom-intuos5-pad.c \
litest-device-wacom-isdv4-tablet.c \
litest-device-wacom-touch.c \
litest-device-wacom-intuos-finger.c \
@ -71,6 +73,7 @@ run_tests = \
test-touchpad \
test-touchpad-tap \
test-touchpad-buttons \
test-pad \
test-tablet \
test-device \
test-gestures \
@ -120,6 +123,10 @@ test_tablet_SOURCES = tablet.c
test_tablet_LDADD = $(TEST_LIBS)
test_tablet_LDFLAGS = -static
test_pad_SOURCES = pad.c
test_pad_LDADD = $(TEST_LIBS)
test_pad_LDFLAGS = -static
test_touchpad_SOURCES = touchpad.c
test_touchpad_LDADD = $(TEST_LIBS)
test_touchpad_LDFLAGS = -no-install

View file

@ -0,0 +1,117 @@
/*
* Copyright © 2016 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "litest.h"
#include "litest-int.h"
static void
litest_wacom_intuos3_pad_setup(void)
{
struct litest_device *d = litest_create_device(LITEST_WACOM_INTUOS3_PAD);
litest_set_current_device(d);
}
static struct input_event down[] = {
{ .type = -1, .code = -1 },
};
static struct input_event move[] = {
{ .type = -1, .code = -1 },
};
static struct input_event strip_start[] = {
{ .type = EV_ABS, .code = ABS_RX, .value = LITEST_AUTO_ASSIGN },
{ .type = EV_ABS, .code = ABS_MISC, .value = 15 },
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
{ .type = -1, .code = -1 },
} ;
static struct input_event strip_change[] = {
{ .type = EV_ABS, .code = ABS_RX, .value = LITEST_AUTO_ASSIGN },
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
{ .type = -1, .code = -1 },
} ;
static struct input_event strip_end[] = {
{ .type = EV_ABS, .code = ABS_RX, .value = 0 },
{ .type = EV_ABS, .code = ABS_MISC, .value = 0 },
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
{ .type = -1, .code = -1 },
} ;
static struct litest_device_interface interface = {
.touch_down_events = down,
.touch_move_events = move,
.pad_strip_start_events = strip_start,
.pad_strip_change_events = strip_change,
.pad_strip_end_events = strip_end,
};
static struct input_absinfo absinfo[] = {
{ ABS_X, 0, 1, 0, 0, 0 },
{ ABS_Y, 0, 1, 0, 0, 0 },
{ ABS_RX, 0, 4096, 0, 0, 0 },
{ ABS_MISC, 0, 0, 0, 0, 0 },
{ .value = -1 },
};
static struct input_id input_id = {
.bustype = 0x3,
.vendor = 0x56a,
.product = 0xb7,
};
static int events[] = {
EV_KEY, BTN_0,
EV_KEY, BTN_1,
EV_KEY, BTN_2,
EV_KEY, BTN_3,
EV_KEY, BTN_STYLUS,
-1, -1,
};
static const char udev_rule[] =
"ACTION==\"remove\", GOTO=\"pad_end\"\n"
"KERNEL!=\"event*\", GOTO=\"pad_end\"\n"
"\n"
"ATTRS{name}==\"litest Wacom Intuos3 4x6 Pad*\",\\\n"
" ENV{ID_INPUT_TABLET_PAD}=\"1\"\n"
"\n"
"LABEL=\"pad_end\"";
struct litest_test_device litest_wacom_intuos3_pad_device = {
.type = LITEST_WACOM_INTUOS3_PAD,
.features = LITEST_TABLET_PAD | LITEST_STRIP,
.shortname = "wacom-intuos3-pad",
.setup = litest_wacom_intuos3_pad_setup,
.interface = &interface,
.name = "Wacom Intuos3 4x6 Pad",
.id = &input_id,
.events = events,
.absinfo = absinfo,
.udev_rule = udev_rule,
};

View file

@ -0,0 +1,122 @@
/*
* Copyright © 2016 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "litest.h"
#include "litest-int.h"
static void
litest_wacom_intuos5_pad_setup(void)
{
struct litest_device *d = litest_create_device(LITEST_WACOM_INTUOS5_PAD);
litest_set_current_device(d);
}
static struct input_event down[] = {
{ .type = -1, .code = -1 },
};
static struct input_event move[] = {
{ .type = -1, .code = -1 },
};
static struct input_event ring_start[] = {
{ .type = EV_ABS, .code = ABS_WHEEL, .value = LITEST_AUTO_ASSIGN },
{ .type = EV_ABS, .code = ABS_MISC, .value = 15 },
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
{ .type = -1, .code = -1 },
} ;
static struct input_event ring_change[] = {
{ .type = EV_ABS, .code = ABS_WHEEL, .value = LITEST_AUTO_ASSIGN },
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
{ .type = -1, .code = -1 },
} ;
static struct input_event ring_end[] = {
{ .type = EV_ABS, .code = ABS_WHEEL, .value = 0 },
{ .type = EV_ABS, .code = ABS_MISC, .value = 0 },
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
{ .type = -1, .code = -1 },
} ;
static struct litest_device_interface interface = {
.touch_down_events = down,
.touch_move_events = move,
.pad_ring_start_events = ring_start,
.pad_ring_change_events = ring_change,
.pad_ring_end_events = ring_end,
};
static struct input_absinfo absinfo[] = {
{ ABS_X, 0, 1, 0, 0, 0 },
{ ABS_Y, 0, 1, 0, 0, 0 },
{ ABS_WHEEL, 0, 71, 0, 0, 0 },
{ ABS_MISC, 0, 0, 0, 0, 10 },
{ .value = -1 },
};
static struct input_id input_id = {
.bustype = 0x3,
.vendor = 0x56a,
.product = 0x27,
};
static int events[] = {
EV_KEY, BTN_0,
EV_KEY, BTN_1,
EV_KEY, BTN_2,
EV_KEY, BTN_3,
EV_KEY, BTN_4,
EV_KEY, BTN_5,
EV_KEY, BTN_6,
EV_KEY, BTN_7,
EV_KEY, BTN_8,
EV_KEY, BTN_STYLUS,
-1, -1,
};
static const char udev_rule[] =
"ACTION==\"remove\", GOTO=\"pad_end\"\n"
"KERNEL!=\"event*\", GOTO=\"pad_end\"\n"
"\n"
"ATTRS{name}==\"litest Wacom Intuos5 touch M Pad*\",\\\n"
" ENV{ID_INPUT_TABLET_PAD}=\"1\"\n"
"\n"
"LABEL=\"pad_end\"";
struct litest_test_device litest_wacom_intuos5_pad_device = {
.type = LITEST_WACOM_INTUOS5_PAD,
.features = LITEST_TABLET_PAD | LITEST_RING,
.shortname = "wacom-pad",
.setup = litest_wacom_intuos5_pad_setup,
.interface = &interface,
.name = "Wacom Intuos5 touch M Pad",
.id = &input_id,
.events = events,
.absinfo = absinfo,
.udev_rule = udev_rule,
};

View file

@ -105,6 +105,22 @@ struct litest_device_interface {
struct input_event *tablet_proximity_out_events;
struct input_event *tablet_motion_events;
/**
* Pad events, LITEST_AUTO_ASSIGN is allowed on event values
* for ABS_WHEEL
*/
struct input_event *pad_ring_start_events;
struct input_event *pad_ring_change_events;
struct input_event *pad_ring_end_events;
/**
* Pad events, LITEST_AUTO_ASSIGN is allowed on event values
* for ABS_RX
*/
struct input_event *pad_strip_start_events;
struct input_event *pad_strip_change_events;
struct input_event *pad_strip_end_events;
int min[2]; /* x/y axis minimum */
int max[2]; /* x/y axis maximum */
};

View file

@ -379,6 +379,8 @@ extern struct litest_test_device litest_cyborg_rat_device;
extern struct litest_test_device litest_yubikey_device;
extern struct litest_test_device litest_synaptics_i2c_device;
extern struct litest_test_device litest_wacom_cintiq_24hd_device;
extern struct litest_test_device litest_wacom_intuos3_pad_device;
extern struct litest_test_device litest_wacom_intuos5_pad_device;
struct litest_test_device* devices[] = {
&litest_synaptics_clickpad_device,
@ -424,6 +426,8 @@ struct litest_test_device* devices[] = {
&litest_yubikey_device,
&litest_synaptics_i2c_device,
&litest_wacom_cintiq_24hd_device,
&litest_wacom_intuos3_pad_device,
&litest_wacom_intuos5_pad_device,
NULL,
};
@ -1809,6 +1813,15 @@ litest_scale_axis(const struct litest_device *d,
return (abs->maximum - abs->minimum) * val/100.0 + abs->minimum;
}
static inline int
litest_scale_range(int min, int max, double val)
{
litest_assert_int_ge((int)val, 0);
litest_assert_int_le((int)val, 100);
return (max - min) * val/100.0 + min;
}
int
litest_scale(const struct litest_device *d, unsigned int axis, double val)
{
@ -1819,12 +1832,120 @@ litest_scale(const struct litest_device *d, unsigned int axis, double val)
if (axis <= ABS_Y) {
min = d->interface->min[axis];
max = d->interface->max[axis];
return (max - min) * val/100.0 + min;
return litest_scale_range(min, max, val);
} else {
return litest_scale_axis(d, axis, val);
}
}
static inline int
auto_assign_pad_value(struct litest_device *dev,
struct input_event *ev,
double value)
{
const struct input_absinfo *abs;
if (ev->value != LITEST_AUTO_ASSIGN ||
ev->type != EV_ABS)
return value;
abs = libevdev_get_abs_info(dev->evdev, ev->code);
litest_assert_notnull(abs);
if (ev->code == ABS_RX || ev->code == ABS_RY) {
double min = abs->minimum != 0 ? log2(abs->minimum) : 0,
max = abs->maximum != 0 ? log2(abs->maximum) : 0;
/* Value 0 is reserved for finger up, so a value of 0% is
* actually 1 */
if (value == 0.0) {
return 1;
} else {
value = litest_scale_range(min, max, value);
return pow(2, value);
}
} else {
return litest_scale_range(abs->minimum, abs->maximum, value);
}
}
void
litest_pad_ring_start(struct litest_device *d, double value)
{
struct input_event *ev;
ev = d->interface->pad_ring_start_events;
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
value = auto_assign_pad_value(d, ev, value);
litest_event(d, ev->type, ev->code, value);
ev++;
}
}
void
litest_pad_ring_change(struct litest_device *d, double value)
{
struct input_event *ev;
ev = d->interface->pad_ring_change_events;
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
value = auto_assign_pad_value(d, ev, value);
litest_event(d, ev->type, ev->code, value);
ev++;
}
}
void
litest_pad_ring_end(struct litest_device *d)
{
struct input_event *ev;
ev = d->interface->pad_ring_end_events;
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
litest_event(d, ev->type, ev->code, ev->value);
ev++;
}
}
void
litest_pad_strip_start(struct litest_device *d, double value)
{
struct input_event *ev;
ev = d->interface->pad_strip_start_events;
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
value = auto_assign_pad_value(d, ev, value);
litest_event(d, ev->type, ev->code, value);
ev++;
}
}
void
litest_pad_strip_change(struct litest_device *d, double value)
{
struct input_event *ev;
ev = d->interface->pad_strip_change_events;
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
value = auto_assign_pad_value(d, ev, value);
litest_event(d, ev->type, ev->code, value);
ev++;
}
}
void
litest_pad_strip_end(struct litest_device *d)
{
struct input_event *ev;
ev = d->interface->pad_strip_end_events;
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
litest_event(d, ev->type, ev->code, ev->value);
ev++;
}
}
void
litest_wait_for_event(struct libinput *li)
{
@ -1981,6 +2102,7 @@ litest_print_event(struct libinput_event *event)
{
struct libinput_event_pointer *p;
struct libinput_event_tablet_tool *t;
struct libinput_event_tablet_pad *pad;
struct libinput_device *dev;
enum libinput_event_type type;
double x, y;
@ -2042,6 +2164,26 @@ litest_print_event(struct libinput_event *event)
libinput_event_tablet_tool_get_button(t),
libinput_event_tablet_tool_get_button_state(t));
break;
case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
pad = libinput_event_get_tablet_pad_event(event);
fprintf(stderr, "button %d state %d",
libinput_event_tablet_pad_get_button_number(pad),
libinput_event_tablet_pad_get_button_state(pad));
break;
case LIBINPUT_EVENT_TABLET_PAD_RING:
pad = libinput_event_get_tablet_pad_event(event);
fprintf(stderr, "ring %d position %.2f source %d",
libinput_event_tablet_pad_get_ring_number(pad),
libinput_event_tablet_pad_get_ring_position(pad),
libinput_event_tablet_pad_get_ring_source(pad));
break;
case LIBINPUT_EVENT_TABLET_PAD_STRIP:
pad = libinput_event_get_tablet_pad_event(event);
fprintf(stderr, "strip %d position %.2f source %d",
libinput_event_tablet_pad_get_ring_number(pad),
libinput_event_tablet_pad_get_ring_position(pad),
libinput_event_tablet_pad_get_ring_source(pad));
break;
default:
break;
}
@ -2463,6 +2605,81 @@ void litest_assert_tablet_proximity_event(struct libinput *li,
libinput_event_destroy(event);
}
struct libinput_event_tablet_pad *
litest_is_pad_button_event(struct libinput_event *event,
unsigned int button,
enum libinput_button_state state)
{
struct libinput_event_tablet_pad *p;
enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_BUTTON;
litest_assert(event != NULL);
litest_assert_int_eq(libinput_event_get_type(event), type);
p = libinput_event_get_tablet_pad_event(event);
litest_assert(p != NULL);
litest_assert_int_eq(libinput_event_tablet_pad_get_button_number(p),
button);
return p;
}
struct libinput_event_tablet_pad *
litest_is_pad_ring_event(struct libinput_event *event,
unsigned int number,
enum libinput_tablet_pad_ring_axis_source source)
{
struct libinput_event_tablet_pad *p;
enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_RING;
litest_assert(event != NULL);
litest_assert_int_eq(libinput_event_get_type(event), type);
p = libinput_event_get_tablet_pad_event(event);
litest_assert_int_eq(libinput_event_tablet_pad_get_ring_number(p),
number);
litest_assert_int_eq(libinput_event_tablet_pad_get_ring_source(p),
source);
return p;
}
struct libinput_event_tablet_pad *
litest_is_pad_strip_event(struct libinput_event *event,
unsigned int number,
enum libinput_tablet_pad_strip_axis_source source)
{
struct libinput_event_tablet_pad *p;
enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_STRIP;
litest_assert(event != NULL);
litest_assert_int_eq(libinput_event_get_type(event), type);
p = libinput_event_get_tablet_pad_event(event);
litest_assert_int_eq(libinput_event_tablet_pad_get_strip_number(p),
number);
litest_assert_int_eq(libinput_event_tablet_pad_get_strip_source(p),
source);
return p;
}
void
litest_assert_pad_button_event(struct libinput *li,
unsigned int button,
enum libinput_button_state state)
{
struct libinput_event *event;
struct libinput_event_tablet_pad *pev;
litest_wait_for_event(li);
event = libinput_get_event(li);
pev = litest_is_pad_button_event(event, button, state);
libinput_event_destroy(libinput_event_tablet_pad_get_base_event(pev));
}
void
litest_assert_scroll(struct libinput *li,
enum libinput_pointer_axis axis,

View file

@ -196,6 +196,8 @@ enum litest_device_type {
LITEST_YUBIKEY = -42,
LITEST_SYNAPTICS_I2C = -43,
LITEST_WACOM_CINTIQ_24HD = -44,
LITEST_WACOM_INTUOS3_PAD = -45,
LITEST_WACOM_INTUOS5_PAD = -46,
};
enum litest_device_feature {
@ -222,6 +224,9 @@ enum litest_device_feature {
LITEST_DISTANCE = 1 << 18,
LITEST_TOOL_SERIAL = 1 << 19,
LITEST_TILT = 1 << 20,
LITEST_TABLET_PAD = 1 << 21,
LITEST_RING = 1 << 22,
LITEST_STRIP = 1 << 23,
};
struct litest_device {
@ -439,6 +444,24 @@ litest_tablet_motion(struct litest_device *d,
int x, int y,
struct axis_replacement *axes);
void
litest_pad_ring_start(struct litest_device *d, double value);
void
litest_pad_ring_change(struct litest_device *d, double value);
void
litest_pad_ring_end(struct litest_device *d);
void
litest_pad_strip_start(struct litest_device *d, double value);
void
litest_pad_strip_change(struct litest_device *d, double value);
void
litest_pad_strip_end(struct litest_device *d);
void
litest_hover_start(struct litest_device *d,
unsigned int slot,
@ -525,6 +548,19 @@ struct libinput_event_tablet_tool *
litest_is_tablet_event(struct libinput_event *event,
enum libinput_event_type type);
struct libinput_event_tablet_pad *
litest_is_pad_button_event(struct libinput_event *event,
unsigned int button,
enum libinput_button_state state);
struct libinput_event_tablet_pad *
litest_is_pad_ring_event(struct libinput_event *event,
unsigned int number,
enum libinput_tablet_pad_ring_axis_source source);
struct libinput_event_tablet_pad *
litest_is_pad_strip_event(struct libinput_event *event,
unsigned int number,
enum libinput_tablet_pad_strip_axis_source source);
void
litest_assert_button_event(struct libinput *li,
unsigned int button,
@ -548,6 +584,10 @@ void
litest_assert_tablet_proximity_event(struct libinput *li,
enum libinput_tablet_tool_proximity_state state);
void
litest_assert_pad_button_event(struct libinput *li,
unsigned int button,
enum libinput_button_state state);
struct libevdev_uinput *
litest_create_uinput_device(const char *name,
struct input_id *id,

View file

@ -134,6 +134,7 @@ START_TEST(event_conversion_device_notify)
ck_assert(libinput_event_get_touch_event(event) == NULL);
ck_assert(libinput_event_get_gesture_event(event) == NULL);
ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
litest_restore_log_handler(li);
}
@ -190,6 +191,7 @@ START_TEST(event_conversion_pointer)
ck_assert(libinput_event_get_touch_event(event) == NULL);
ck_assert(libinput_event_get_gesture_event(event) == NULL);
ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
litest_restore_log_handler(li);
}
libinput_event_destroy(event);
@ -240,6 +242,7 @@ START_TEST(event_conversion_pointer_abs)
ck_assert(libinput_event_get_touch_event(event) == NULL);
ck_assert(libinput_event_get_gesture_event(event) == NULL);
ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
litest_restore_log_handler(li);
}
libinput_event_destroy(event);
@ -283,6 +286,7 @@ START_TEST(event_conversion_key)
ck_assert(libinput_event_get_touch_event(event) == NULL);
ck_assert(libinput_event_get_gesture_event(event) == NULL);
ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
litest_restore_log_handler(li);
}
libinput_event_destroy(event);
@ -333,6 +337,7 @@ START_TEST(event_conversion_touch)
ck_assert(libinput_event_get_keyboard_event(event) == NULL);
ck_assert(libinput_event_get_gesture_event(event) == NULL);
ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
litest_restore_log_handler(li);
}
libinput_event_destroy(event);
@ -381,6 +386,7 @@ START_TEST(event_conversion_gesture)
ck_assert(libinput_event_get_pointer_event(event) == NULL);
ck_assert(libinput_event_get_keyboard_event(event) == NULL);
ck_assert(libinput_event_get_touch_event(event) == NULL);
ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
litest_restore_log_handler(li);
}
libinput_event_destroy(event);
@ -427,6 +433,50 @@ START_TEST(event_conversion_tablet)
ck_assert(libinput_event_get_pointer_event(event) == NULL);
ck_assert(libinput_event_get_keyboard_event(event) == NULL);
ck_assert(libinput_event_get_touch_event(event) == NULL);
ck_assert(libinput_event_get_tablet_pad_event(event) == NULL);
litest_restore_log_handler(li);
}
libinput_event_destroy(event);
}
ck_assert_int_gt(events, 0);
}
END_TEST
START_TEST(event_conversion_tablet_pad)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *event;
int events = 0;
litest_button_click(dev, BTN_0, true);
litest_pad_ring_start(dev, 10);
litest_pad_ring_end(dev);
libinput_dispatch(li);
while ((event = libinput_get_event(li))) {
enum libinput_event_type type;
type = libinput_event_get_type(event);
if (type >= LIBINPUT_EVENT_TABLET_PAD_BUTTON &&
type <= LIBINPUT_EVENT_TABLET_PAD_STRIP) {
struct libinput_event_tablet_pad *p;
struct libinput_event *base;
p = libinput_event_get_tablet_pad_event(event);
base = libinput_event_tablet_pad_get_base_event(p);
ck_assert(event == base);
events++;
litest_disable_log_handler(li);
ck_assert(libinput_event_get_device_notify_event(event) == NULL);
ck_assert(libinput_event_get_pointer_event(event) == NULL);
ck_assert(libinput_event_get_keyboard_event(event) == NULL);
ck_assert(libinput_event_get_touch_event(event) == NULL);
ck_assert(libinput_event_get_tablet_tool_event(event) == NULL);
litest_restore_log_handler(li);
}
libinput_event_destroy(event);
@ -895,6 +945,7 @@ litest_setup_tests(void)
litest_add_for_device("events:conversion", event_conversion_touch, LITEST_WACOM_TOUCH);
litest_add_for_device("events:conversion", event_conversion_gesture, LITEST_BCM5974);
litest_add_for_device("events:conversion", event_conversion_tablet, LITEST_WACOM_CINTIQ);
litest_add_for_device("events:conversion", event_conversion_tablet_pad, LITEST_WACOM_INTUOS5_PAD);
litest_add_no_device("bitfield_helpers", bitfield_helpers);
litest_add_no_device("context:refcount", context_ref_counting);

431
test/pad.c Normal file
View file

@ -0,0 +1,431 @@
/*
* Copyright © 2016 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the copyright holders not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. The copyright holders make
* no representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <config.h>
#include <check.h>
#include <errno.h>
#include <fcntl.h>
#include <libinput.h>
#include <unistd.h>
#include <stdbool.h>
#include "libinput-util.h"
#include "litest.h"
START_TEST(pad_cap)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
ck_assert(libinput_device_has_capability(device,
LIBINPUT_DEVICE_CAP_TABLET_PAD));
}
END_TEST
START_TEST(pad_no_cap)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
ck_assert(!libinput_device_has_capability(device,
LIBINPUT_DEVICE_CAP_TABLET_PAD));
}
END_TEST
START_TEST(pad_num_buttons)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
unsigned int code;
unsigned int nbuttons = 0;
for (code = BTN_0; code < KEY_MAX; code++) {
/* BTN_STYLUS is set for compatibility reasons but not
* actually hooked up */
if (code == BTN_STYLUS)
continue;
if (libevdev_has_event_code(dev->evdev, EV_KEY, code))
nbuttons++;
}
ck_assert_int_eq(libinput_device_tablet_pad_get_num_buttons(device),
nbuttons);
}
END_TEST
START_TEST(pad_button)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
unsigned int code;
unsigned int expected_number = 0;
struct libinput_event *ev;
struct libinput_event_tablet_pad *pev;
litest_drain_events(li);
for (code = BTN_LEFT; code < KEY_MAX; code++) {
if (!libevdev_has_event_code(dev->evdev, EV_KEY, code))
continue;
litest_button_click(dev, code, 1);
litest_button_click(dev, code, 0);
libinput_dispatch(li);
switch (code) {
case BTN_STYLUS:
litest_assert_empty_queue(li);
continue;
default:
break;
}
ev = libinput_get_event(li);
pev = litest_is_pad_button_event(ev,
expected_number,
LIBINPUT_BUTTON_STATE_PRESSED);
ev = libinput_event_tablet_pad_get_base_event(pev);
libinput_event_destroy(ev);
ev = libinput_get_event(li);
pev = litest_is_pad_button_event(ev,
expected_number,
LIBINPUT_BUTTON_STATE_RELEASED);
ev = libinput_event_tablet_pad_get_base_event(pev);
libinput_event_destroy(ev);
expected_number++;
}
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(pad_has_ring)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
int nrings;
nrings = libinput_device_tablet_pad_get_num_rings(device);
ck_assert_int_ge(nrings, 1);
}
END_TEST
START_TEST(pad_ring)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *ev;
struct libinput_event_tablet_pad *pev;
int val;
double degrees, expected;
litest_pad_ring_start(dev, 10);
litest_drain_events(li);
/* Wacom's 0 value is at 275 degrees */
expected = 270;
for (val = 0; val < 100; val += 10) {
litest_pad_ring_change(dev, val);
libinput_dispatch(li);
ev = libinput_get_event(li);
pev = litest_is_pad_ring_event(ev,
0,
LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER);
degrees = libinput_event_tablet_pad_get_ring_position(pev);
ck_assert_double_ge(degrees, 0.0);
ck_assert_double_lt(degrees, 360.0);
/* rounding errors, mostly caused by small physical range */
ck_assert_double_ge(degrees, expected - 2);
ck_assert_double_le(degrees, expected + 2);
libinput_event_destroy(ev);
expected = fmod(degrees + 36, 360);
}
litest_pad_ring_end(dev);
}
END_TEST
START_TEST(pad_ring_finger_up)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *ev;
struct libinput_event_tablet_pad *pev;
double degrees;
litest_pad_ring_start(dev, 10);
litest_drain_events(li);
litest_pad_ring_end(dev);
libinput_dispatch(li);
ev = libinput_get_event(li);
pev = litest_is_pad_ring_event(ev,
0,
LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER);
degrees = libinput_event_tablet_pad_get_ring_position(pev);
ck_assert_double_eq(degrees, -1.0);
libinput_event_destroy(ev);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(pad_has_strip)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
int nstrips;
nstrips = libinput_device_tablet_pad_get_num_strips(device);
ck_assert_int_ge(nstrips, 1);
}
END_TEST
START_TEST(pad_strip)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *ev;
struct libinput_event_tablet_pad *pev;
int val;
double pos, expected;
litest_pad_strip_start(dev, 10);
litest_drain_events(li);
expected = 0;
/* 9.5 works with the generic axis scaling without jumping over a
* value. */
for (val = 0; val < 100; val += 9.5) {
litest_pad_strip_change(dev, val);
libinput_dispatch(li);
ev = libinput_get_event(li);
pev = litest_is_pad_strip_event(ev,
0,
LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER);
pos = libinput_event_tablet_pad_get_strip_position(pev);
ck_assert_double_ge(pos, 0.0);
ck_assert_double_lt(pos, 1.0);
/* rounding errors, mostly caused by small physical range */
ck_assert_double_ge(pos, expected - 0.02);
ck_assert_double_le(pos, expected + 0.02);
libinput_event_destroy(ev);
expected = pos + 0.08;
}
litest_pad_strip_change(dev, 100);
libinput_dispatch(li);
ev = libinput_get_event(li);
pev = litest_is_pad_strip_event(ev,
0,
LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER);
pos = libinput_event_tablet_pad_get_strip_position(pev);
ck_assert_double_eq(pos, 1.0);
libinput_event_destroy(ev);
litest_pad_strip_end(dev);
}
END_TEST
START_TEST(pad_strip_finger_up)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *ev;
struct libinput_event_tablet_pad *pev;
double pos;
litest_pad_strip_start(dev, 10);
litest_drain_events(li);
litest_pad_strip_end(dev);
libinput_dispatch(li);
ev = libinput_get_event(li);
pev = litest_is_pad_strip_event(ev,
0,
LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER);
pos = libinput_event_tablet_pad_get_strip_position(pev);
ck_assert_double_eq(pos, -1.0);
libinput_event_destroy(ev);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(pad_left_handed_default)
{
#if HAVE_LIBWACOM
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
enum libinput_config_status status;
ck_assert(libinput_device_config_left_handed_is_available(device));
ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
0);
ck_assert_int_eq(libinput_device_config_left_handed_get(device),
0);
status = libinput_device_config_left_handed_set(dev->libinput_device, 1);
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
ck_assert_int_eq(libinput_device_config_left_handed_get(device),
1);
ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
0);
status = libinput_device_config_left_handed_set(dev->libinput_device, 0);
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
ck_assert_int_eq(libinput_device_config_left_handed_get(device),
0);
ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
0);
#endif
}
END_TEST
START_TEST(pad_no_left_handed)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
enum libinput_config_status status;
ck_assert(!libinput_device_config_left_handed_is_available(device));
ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
0);
ck_assert_int_eq(libinput_device_config_left_handed_get(device),
0);
status = libinput_device_config_left_handed_set(dev->libinput_device, 1);
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
ck_assert_int_eq(libinput_device_config_left_handed_get(device),
0);
ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
0);
status = libinput_device_config_left_handed_set(dev->libinput_device, 0);
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
ck_assert_int_eq(libinput_device_config_left_handed_get(device),
0);
ck_assert_int_eq(libinput_device_config_left_handed_get_default(device),
0);
}
END_TEST
START_TEST(pad_left_handed_ring)
{
#if HAVE_LIBWACOM
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *ev;
struct libinput_event_tablet_pad *pev;
int val;
double degrees, expected;
libinput_device_config_left_handed_set(dev->libinput_device, 1);
litest_pad_ring_start(dev, 10);
litest_drain_events(li);
/* Wacom's 0 value is at 275 degrees -> 90 in left-handed mode*/
expected = 90;
for (val = 0; val < 100; val += 10) {
litest_pad_ring_change(dev, val);
libinput_dispatch(li);
ev = libinput_get_event(li);
pev = litest_is_pad_ring_event(ev,
0,
LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER);
degrees = libinput_event_tablet_pad_get_ring_position(pev);
ck_assert_double_ge(degrees, 0.0);
ck_assert_double_lt(degrees, 360.0);
/* rounding errors, mostly caused by small physical range */
ck_assert_double_ge(degrees, expected - 2);
ck_assert_double_le(degrees, expected + 2);
libinput_event_destroy(ev);
expected = fmod(degrees + 36, 360);
}
litest_pad_ring_end(dev);
#endif
}
END_TEST
void
litest_setup_tests(void)
{
litest_add("pad:cap", pad_cap, LITEST_TABLET_PAD, LITEST_ANY);
litest_add("pad:cap", pad_no_cap, LITEST_ANY, LITEST_TABLET_PAD);
litest_add("pad:button", pad_num_buttons, LITEST_TABLET_PAD, LITEST_ANY);
litest_add("pad:button", pad_button, LITEST_TABLET_PAD, LITEST_ANY);
litest_add("pad:ring", pad_has_ring, LITEST_RING, LITEST_ANY);
litest_add("pad:ring", pad_ring, LITEST_RING, LITEST_ANY);
litest_add("pad:ring", pad_ring_finger_up, LITEST_RING, LITEST_ANY);
litest_add("pad:strip", pad_has_strip, LITEST_STRIP, LITEST_ANY);
litest_add("pad:strip", pad_strip, LITEST_STRIP, LITEST_ANY);
litest_add("pad:strip", pad_strip_finger_up, LITEST_STRIP, LITEST_ANY);
litest_add_for_device("pad:left_handed", pad_left_handed_default, LITEST_WACOM_INTUOS5_PAD);
litest_add_for_device("pad:left_handed", pad_no_left_handed, LITEST_WACOM_INTUOS3_PAD);
litest_add_for_device("pad:left_handed", pad_left_handed_ring, LITEST_WACOM_INTUOS5_PAD);
/* None of the current strip tablets are left-handed */
}