diff --git a/test/litest-int.h b/test/litest-int.h index b515b6c3..19e6e68d 100644 --- a/test/litest-int.h +++ b/test/litest-int.h @@ -23,19 +23,52 @@ #if HAVE_CONFIG_H #include "config.h" #endif +#include #ifndef LITEST_INT_H #define LITEST_INT_H #include "litest.h" +/* Use as designater for litest to change the value */ +#define LITEST_AUTO_ASSIGN INT_MIN + struct litest_test_device { enum litest_device_type type; enum litest_device_feature features; const char *shortname; void (*setup)(void); /* test fixture, used by check */ void (*teardown)(void); /* test fixture, used by check */ - + /** + * If create is non-NULL it will be called to initialize the device. + * For such devices, no overrides are possible. If create is NULL, + * the information in name, id, events, absinfo is used to + * create the device instead. + */ void (*create)(struct litest_device *d); + + /** + * The device name. Only used when create is NULL. + */ + const char *name; + /** + * The device id. Only used when create is NULL. + */ + const struct input_id *id; + /** + * List of event type/code tuples, terminated with -1, e.g. + * EV_REL, REL_X, EV_KEY, BTN_LEFT, -1 + * Special tuple is INPUT_PROP_MAX, to set. + * + * Any EV_ABS codes in this list will be initialized with a default + * axis range. + */ + int *events; + /** + * List of abs codes to enable, with absinfo.value determining the + * code to set. List must be terminated with absinfo.value -1 + */ + struct input_absinfo *absinfo; + struct litest_device_interface *interface; }; struct litest_device_interface { @@ -43,6 +76,18 @@ struct litest_device_interface { void (*touch_move)(struct litest_device *d, unsigned int slot, int x, int y); void (*touch_up)(struct litest_device *d, unsigned int slot); + /** + * Set of of events to execute on touch down, terminated by a .type + * and .code value of -1. If the event value is LITEST_AUTO_ASSIGN, + * it will be automatically assigned by the framework (valid for x, + * y, tracking id and slot). + * + * These events are only used if touch_down is NULL. + */ + struct input_event *touch_down_events; + struct input_event *touch_move_events; + struct input_event *touch_up_events; + int min[2]; int max[2]; }; diff --git a/test/litest-synaptics.c b/test/litest-synaptics.c index c960db2d..f2208582 100644 --- a/test/litest-synaptics.c +++ b/test/litest-synaptics.c @@ -34,105 +34,78 @@ void litest_synaptics_clickpad_setup(void) litest_set_current_device(d); } -void -litest_synaptics_clickpad_touch_down(struct litest_device *d, - unsigned int slot, - int x, int y) -{ - static int tracking_id; - struct input_event *ev; - struct input_event down[] = { - { .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 }, - { .type = EV_KEY, .code = BTN_TOUCH, .value = 1 }, - { .type = EV_ABS, .code = ABS_X, .value = x }, - { .type = EV_ABS, .code = ABS_Y, .value = y }, - { .type = EV_ABS, .code = ABS_PRESSURE, .value = 30 }, - { .type = EV_ABS, .code = ABS_MT_SLOT, .value = slot }, - { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = ++tracking_id }, - { .type = EV_ABS, .code = ABS_MT_POSITION_X, .value = x }, - { .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = y }, - { .type = EV_SYN, .code = SYN_REPORT, .value = 0 }, - }; - - down[2].value = litest_scale(d, ABS_X, x); - down[3].value = litest_scale(d, ABS_Y, y); - down[7].value = litest_scale(d, ABS_X, x); - down[8].value = litest_scale(d, ABS_Y, y); - - ARRAY_FOR_EACH(down, ev) - litest_event(d, ev->type, ev->code, ev->value); -} - -void -litest_synaptics_clickpad_move(struct litest_device *d, - unsigned int slot, - int x, int y) -{ - struct input_event *ev; - struct input_event move[] = { - { .type = EV_ABS, .code = ABS_MT_SLOT, .value = slot }, - { .type = EV_ABS, .code = ABS_X, .value = x }, - { .type = EV_ABS, .code = ABS_Y, .value = y }, - { .type = EV_ABS, .code = ABS_MT_POSITION_X, .value = x }, - { .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = y }, - { .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 }, - { .type = EV_KEY, .code = BTN_TOUCH, .value = 1 }, - { .type = EV_SYN, .code = SYN_REPORT, .value = 0 }, - }; - - move[1].value = litest_scale(d, ABS_X, x); - move[2].value = litest_scale(d, ABS_Y, y); - move[3].value = litest_scale(d, ABS_X, x); - move[4].value = litest_scale(d, ABS_Y, y); - - ARRAY_FOR_EACH(move, ev) - litest_event(d, ev->type, ev->code, ev->value); -} - -static struct litest_device_interface interface = { - .touch_down = litest_synaptics_clickpad_touch_down, - .touch_move = litest_synaptics_clickpad_move, +static struct input_event down[] = { + { .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 }, + { .type = EV_KEY, .code = BTN_TOUCH, .value = 1 }, + { .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 = 30 }, + { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_MT_POSITION_X, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_SYN, .code = SYN_REPORT, .value = 0 }, + { .type = -1, .code = -1 }, }; -void -litest_create_synaptics_clickpad(struct litest_device *d) -{ - struct input_absinfo abs[] = { - { ABS_X, 1472, 5472, 75 }, - { ABS_Y, 1408, 4448, 129 }, - { ABS_PRESSURE, 0, 255, 0 }, - { ABS_TOOL_WIDTH, 0, 15, 0 }, - { ABS_MT_SLOT, 0, 1, 0 }, - { ABS_MT_POSITION_X, 1472, 5472, 75 }, - { ABS_MT_POSITION_Y, 1408, 4448, 129 }, - { ABS_MT_TRACKING_ID, 0, 65535, 0 }, - { ABS_MT_PRESSURE, 0, 255, 0 }, - { .value = -1 }, - }; - struct input_id id = { - .bustype = 0x11, - .vendor = 0x2, - .product = 0x11, - }; +static struct input_event move[] = { + { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN }, + { .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_MT_POSITION_X, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_KEY, .code = BTN_TOOL_FINGER, .value = 1 }, + { .type = EV_KEY, .code = BTN_TOUCH, .value = 1 }, + { .type = EV_SYN, .code = SYN_REPORT, .value = 0 }, + { .type = -1, .code = -1 }, +}; - d->interface = &interface; - d->uinput = litest_create_uinput_abs_device("SynPS/2 Synaptics TouchPad", &id, - abs, - EV_KEY, BTN_LEFT, - EV_KEY, BTN_TOOL_FINGER, - EV_KEY, BTN_TOOL_QUINTTAP, - EV_KEY, BTN_TOUCH, - EV_KEY, BTN_TOOL_DOUBLETAP, - EV_KEY, BTN_TOOL_TRIPLETAP, - EV_KEY, BTN_TOOL_QUADTAP, - -1, -1); -} +static struct litest_device_interface interface = { + .touch_down_events = down, + .touch_move_events = move, +}; + +static struct input_id input_id = { + .bustype = 0x11, + .vendor = 0x2, + .product = 0x11, +}; + +static int events[] = { + EV_KEY, BTN_LEFT, + EV_KEY, BTN_TOOL_FINGER, + EV_KEY, BTN_TOOL_QUINTTAP, + EV_KEY, BTN_TOUCH, + EV_KEY, BTN_TOOL_DOUBLETAP, + EV_KEY, BTN_TOOL_TRIPLETAP, + EV_KEY, BTN_TOOL_QUADTAP, + -1, -1, +}; + +static struct input_absinfo absinfo[] = { + { ABS_X, 1472, 5472, 75 }, + { ABS_Y, 1408, 4448, 129 }, + { ABS_PRESSURE, 0, 255, 0 }, + { ABS_TOOL_WIDTH, 0, 15, 0 }, + { ABS_MT_SLOT, 0, 1, 0 }, + { ABS_MT_POSITION_X, 1472, 5472, 75 }, + { ABS_MT_POSITION_Y, 1408, 4448, 129 }, + { ABS_MT_TRACKING_ID, 0, 65535, 0 }, + { ABS_MT_PRESSURE, 0, 255, 0 }, + { .value = -1 } +}; struct litest_test_device litest_synaptics_clickpad_device = { .type = LITEST_SYNAPTICS_CLICKPAD, .features = LITEST_TOUCHPAD | LITEST_CLICKPAD | LITEST_BUTTON, .shortname = "synaptics", .setup = litest_synaptics_clickpad_setup, - .teardown = litest_generic_device_teardown, - .create = litest_create_synaptics_clickpad, + .teardown = NULL, + .create = NULL, + .interface = &interface, + + .name = "SynPS/2 Synaptics TouchPad", + .id = &input_id, + .events = events, + .absinfo = absinfo, }; diff --git a/test/litest.c b/test/litest.c index 67679522..e31a2e4d 100644 --- a/test/litest.c +++ b/test/litest.c @@ -342,7 +342,15 @@ litest_create_device(enum litest_device_type which) dev = devices; while (*dev) { if ((*dev)->type == which) { - (*dev)->create(d); + if ((*dev)->create) + (*dev)->create(d); + else { + d->uinput = litest_create_uinput_device_from_description((*dev)->name, + (*dev)->id, + (*dev)->absinfo, + (*dev)->events); + d->interface = (*dev)->interface; + } break; } dev++; @@ -368,10 +376,12 @@ litest_create_device(enum litest_device_type which) ck_assert(d->libinput_device != NULL); libinput_device_ref(d->libinput_device); - d->interface->min[ABS_X] = libevdev_get_abs_minimum(d->evdev, ABS_X); - d->interface->max[ABS_X] = libevdev_get_abs_maximum(d->evdev, ABS_X); - d->interface->min[ABS_Y] = libevdev_get_abs_minimum(d->evdev, ABS_Y); - d->interface->max[ABS_Y] = libevdev_get_abs_maximum(d->evdev, ABS_Y); + if (d->interface) { + d->interface->min[ABS_X] = libevdev_get_abs_minimum(d->evdev, ABS_X); + d->interface->max[ABS_X] = libevdev_get_abs_maximum(d->evdev, ABS_X); + d->interface->min[ABS_Y] = libevdev_get_abs_minimum(d->evdev, ABS_Y); + d->interface->max[ABS_Y] = libevdev_get_abs_maximum(d->evdev, ABS_Y); + } return d; } @@ -410,10 +420,54 @@ litest_event(struct litest_device *d, unsigned int type, libevdev_uinput_write_event(d->uinput, type, code, value); } +static int +auto_assign_value(struct litest_device *d, + const struct input_event *ev, + int slot, int x, int y) +{ + static int tracking_id; + int value = ev->value; + + if (value != LITEST_AUTO_ASSIGN || ev->type != EV_ABS) + return value; + + switch (ev->code) { + case ABS_X: + case ABS_MT_POSITION_X: + value = litest_scale(d, ABS_X, x); + break; + case ABS_Y: + case ABS_MT_POSITION_Y: + value = litest_scale(d, ABS_Y, y); + break; + case ABS_MT_TRACKING_ID: + value = ++tracking_id; + break; + case ABS_MT_SLOT: + value = slot; + break; + } + + return value; +} + + void litest_touch_down(struct litest_device *d, unsigned int slot, int x, int y) { - d->interface->touch_down(d, slot, x, y); + struct input_event *ev; + + if (d->interface->touch_down) { + d->interface->touch_down(d, slot, x, y); + return; + } + + ev = d->interface->touch_down_events; + while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) { + int value = auto_assign_value(d, ev, slot, x, y); + litest_event(d, ev->type, ev->code, value); + ev++; + } } void @@ -421,23 +475,43 @@ litest_touch_up(struct litest_device *d, unsigned int slot) { struct input_event *ev; struct input_event up[] = { - { .type = EV_ABS, .code = ABS_MT_SLOT, .value = slot }, + { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN }, { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 }, { .type = EV_SYN, .code = SYN_REPORT, .value = 0 }, + { .type = -1, .code = -1 } }; if (d->interface->touch_up) { d->interface->touch_up(d, slot); - } else { - ARRAY_FOR_EACH(up, ev) - litest_event(d, ev->type, ev->code, ev->value); + return; + } else if (d->interface->touch_up_events) { + ev = d->interface->touch_up_events; + } else + ev = up; + + while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) { + int value = auto_assign_value(d, ev, slot, 0, 0); + litest_event(d, ev->type, ev->code, value); + ev++; } } void litest_touch_move(struct litest_device *d, unsigned int slot, int x, int y) { - d->interface->touch_move(d, slot, x, y); + struct input_event *ev; + + if (d->interface->touch_move) { + d->interface->touch_move(d, slot, x, y); + return; + } + + ev = d->interface->touch_move_events; + while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) { + int value = auto_assign_value(d, ev, slot, x, y); + litest_event(d, ev->type, ev->code, value); + ev++; + } } void @@ -492,11 +566,11 @@ litest_drain_events(struct libinput *li) } } -static struct libevdev_uinput * -litest_create_uinput_abs_device_v(const char *name, - struct input_id *id, - const struct input_absinfo *abs, - va_list args) +struct libevdev_uinput * +litest_create_uinput_device_from_description(const char *name, + const struct input_id *id, + const struct input_absinfo *abs, + const int *events) { struct libevdev_uinput *uinput; struct libevdev *dev; @@ -528,8 +602,9 @@ litest_create_uinput_abs_device_v(const char *name, abs++; } - while ((type = va_arg(args, int)) != -1 && - (code = va_arg(args, int)) != -1) { + while (events && + (type = *events++) != -1 && + (code = *events++) != -1) { if (type == INPUT_PROP_MAX) { rc = libevdev_enable_property(dev, code); } else { @@ -551,6 +626,30 @@ litest_create_uinput_abs_device_v(const char *name, return uinput; } +static struct libevdev_uinput * +litest_create_uinput_abs_device_v(const char *name, + struct input_id *id, + const struct input_absinfo *abs, + va_list args) +{ + int events[KEY_MAX * 2 + 2]; /* increase this if not sufficient */ + int *event = events; + int type, code; + + while ((type = va_arg(args, int)) != -1 && + (code = va_arg(args, int)) != -1) { + *event++ = type; + *event++ = code; + ck_assert(event < &events[ARRAY_LENGTH(events) - 2]); + } + + *event++ = -1; + *event++ = -1; + + return litest_create_uinput_device_from_description(name, id, + abs, events); +} + struct libevdev_uinput * litest_create_uinput_abs_device(const char *name, struct input_id *id, diff --git a/test/litest.h b/test/litest.h index 75c517c4..7a3ed643 100644 --- a/test/litest.h +++ b/test/litest.h @@ -73,6 +73,11 @@ void litest_add_no_device(const char *name, void *func); int litest_run(int argc, char **argv); struct litest_device * litest_create_device(enum litest_device_type which); +struct libevdev_uinput * +litest_create_uinput_device_from_description(const char *name, + const struct input_id *id, + const struct input_absinfo *abs, + const int *events); struct litest_device *litest_current_device(void); void litest_delete_device(struct litest_device *d); int litest_handle_events(struct litest_device *d);