Merge branch 'master' into tablet-support

This commit is contained in:
Peter Hutterer 2015-06-16 13:52:02 +10:00
commit 2b99363a1f
15 changed files with 287 additions and 62 deletions

View file

@ -2,12 +2,24 @@
@page scrolling Scrolling
libinput supports three different types of scrolling methods: @ref
twofinger_scrolling, @ref edge_scrolling and @ref button_scrolling. Some devices
support multiple methods, though only one can be enabled at a time. See
twofinger_scrolling, @ref edge_scrolling and @ref button_scrolling. Some
devices support multiple methods, though only one can be enabled at a time.
As a general overview:
- touchpad devices with physical buttons below the touchpad support edge and
two-finger scrolling
- touchpad devices without physical buttons (@ref clickpad_softbuttons
"clickpads") support two-finger scrolling only
- pointing sticks provide on-button scrolling by default
- mice and other pointing devices support on-button scrolling but it is not
enabled by default
A device may differ from the above based on its capabilities. See
libinput_device_config_scroll_set_method() for documentation on how to
switch methods and libinput_device_config_scroll_get_methods() for
documentation on how to query a device for available scroll methods.
@section horizontal_scrolling Horizontal scrolling
Scroll movements provide vertical and horizontal directions, each
scroll event contains both directions where applicable, see
libinput_event_pointer_get_axis_value(). libinput does not provide separate
@ -55,6 +67,10 @@ a designated button is held down. For example, Lenovo devices provide a
<a href="http://en.wikipedia.org/wiki/Pointing_stick">pointing stick</a> that emulates
scroll events when the trackstick's middle mouse button is held down.
@note On-button scrolling is enabled by default for pointing sticks. This
prevents middle-button dragging; all motion events while the middle button is
down are converted to scroll events.
@image html button-scrolling.svg "Button scrolling"
The button may be changed with

View file

@ -31,7 +31,6 @@
#include "evdev-mt-touchpad.h"
#define DEFAULT_BUTTON_MOTION_THRESHOLD 0.02 /* 2% of size */
#define DEFAULT_BUTTON_ENTER_TIMEOUT 100 /* ms */
#define DEFAULT_BUTTON_LEAVE_TIMEOUT 300 /* ms */
@ -709,11 +708,19 @@ tp_init_buttons(struct tp_dispatch *tp,
absinfo_x = device->abs.absinfo_x;
absinfo_y = device->abs.absinfo_y;
width = abs(absinfo_x->maximum - absinfo_x->minimum);
height = abs(absinfo_y->maximum - absinfo_y->minimum);
diagonal = sqrt(width*width + height*height);
tp->buttons.motion_dist = diagonal * DEFAULT_BUTTON_MOTION_THRESHOLD;
/* pinned-finger motion threshold, see tp_unpin_finger.
The MAGIC for resolution-less touchpads ends up as 2% of the diagonal */
if (device->abs.fake_resolution) {
const int BUTTON_MOTION_MAGIC = 0.007;
width = abs(absinfo_x->maximum - absinfo_x->minimum);
height = abs(absinfo_y->maximum - absinfo_y->minimum);
diagonal = sqrt(width*width + height*height);
tp->buttons.motion_dist.x_scale_coeff = diagonal * BUTTON_MOTION_MAGIC;
tp->buttons.motion_dist.y_scale_coeff = diagonal * BUTTON_MOTION_MAGIC;
} else {
tp->buttons.motion_dist.x_scale_coeff = 1.0/absinfo_x->resolution;
tp->buttons.motion_dist.y_scale_coeff = 1.0/absinfo_y->resolution;
}
tp->buttons.config_method.get_methods = tp_button_config_click_get_methods;
tp->buttons.config_method.set_method = tp_button_config_click_set_method;

View file

@ -431,17 +431,15 @@ tp_unpin_finger(struct tp_dispatch *tp, struct tp_touch *t)
return;
xdist = abs(t->point.x - t->pinned.center.x);
xdist *= tp->buttons.motion_dist.x_scale_coeff;
ydist = abs(t->point.y - t->pinned.center.y);
ydist *= tp->buttons.motion_dist.y_scale_coeff;
if (xdist * xdist + ydist * ydist >=
tp->buttons.motion_dist * tp->buttons.motion_dist) {
/* 3mm movement -> unpin */
if (vector_length(xdist, ydist) >= 3.0) {
t->pinned.is_pinned = false;
return;
}
/* The finger may slowly drift, adjust the center */
t->pinned.center.x = t->point.x + t->pinned.center.x / 2;
t->pinned.center.y = t->point.y + t->pinned.center.y / 2;
}
static void
@ -666,6 +664,7 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
struct tp_touch *t;
struct tp_touch *first = tp_get_touch(tp, 0);
unsigned int i;
bool restart_filter = false;
tp_process_fake_touches(tp, time);
tp_unhover_touches(tp, time);
@ -692,8 +691,14 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
tp_motion_history_push(t);
tp_unpin_finger(tp, t);
if (t->state == TOUCH_BEGIN)
restart_filter = true;
}
if (restart_filter)
filter_restart(tp->device->pointer.filter, tp, time);
tp_button_handle_state(tp, time);
tp_edge_scroll_handle_state(tp, time);
@ -1150,7 +1155,7 @@ evdev_tag_touchpad(struct evdev_device *device,
*/
bustype = libevdev_get_id_bustype(device->evdev);
if (bustype == BUS_USB) {
if (libevdev_get_id_vendor(device->evdev) == VENDOR_ID_APPLE)
if (device->model == EVDEV_MODEL_APPLE_TOUCHPAD)
device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
} else if (bustype != BUS_BLUETOOTH)
device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
@ -1389,7 +1394,6 @@ tp_init_palmdetect(struct tp_dispatch *tp,
struct evdev_device *device)
{
int width, height;
unsigned int vendor_id;
tp->palm.right_edge = INT_MAX;
tp->palm.left_edge = INT_MIN;
@ -1400,13 +1404,11 @@ tp_init_palmdetect(struct tp_dispatch *tp,
height = abs(device->abs.absinfo_y->maximum -
device->abs.absinfo_y->minimum);
vendor_id = evdev_device_get_id_vendor(device);
/* Wacom doesn't have internal touchpads,
* Apple touchpads are always big enough to warrant palm detection */
if (vendor_id == VENDOR_ID_WACOM) {
if (device->model == EVDEV_MODEL_WACOM_TOUCHPAD) {
return 0;
} else if (vendor_id != VENDOR_ID_APPLE) {
} else if (device->model != EVDEV_MODEL_APPLE_TOUCHPAD) {
/* We don't know how big the touchpad is */
if (device->abs.absinfo_x->resolution == 1)
return 0;
@ -1489,10 +1491,18 @@ tp_init(struct tp_dispatch *tp,
EV_ABS,
ABS_MT_DISTANCE);
tp->hysteresis_margin.x =
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
tp->hysteresis_margin.y =
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
if (device->abs.fake_resolution) {
tp->hysteresis_margin.x =
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
tp->hysteresis_margin.y =
diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
} else {
int res_x = tp->device->abs.absinfo_x->resolution,
res_y = tp->device->abs.absinfo_y->resolution;
tp->hysteresis_margin.x = res_x/2;
tp->hysteresis_margin.y = res_y/2;
}
if (tp_init_accel(tp, diagonal) != 0)
return -1;

View file

@ -223,7 +223,10 @@ struct tp_dispatch {
bool click_pending;
uint32_t state;
uint32_t old_state;
uint32_t motion_dist; /* for pinned touches */
struct {
double x_scale_coeff;
double y_scale_coeff;
} motion_dist; /* for pinned touches */
unsigned int active; /* currently active button, for release event */
bool active_is_topbutton; /* is active a top button? */

View file

@ -1514,6 +1514,8 @@ evdev_read_model(struct evdev_device *device)
{ "LIBINPUT_MODEL_SYSTEM76_GALAGO", EVDEV_MODEL_SYSTEM76_GALAGO },
{ "LIBINPUT_MODEL_SYSTEM76_KUDU", EVDEV_MODEL_SYSTEM76_KUDU },
{ "LIBINPUT_MODEL_CLEVO_W740SU", EVDEV_MODEL_CLEVO_W740SU },
{ "LIBINPUT_MODEL_APPLE_TOUCHPAD", EVDEV_MODEL_APPLE_TOUCHPAD },
{ "LIBINPUT_MODEL_WACOM_TOUCHPAD", EVDEV_MODEL_WACOM_TOUCHPAD },
{ NULL, EVDEV_MODEL_DEFAULT },
};
const struct model_map *m = model_map;

View file

@ -104,6 +104,8 @@ enum evdev_device_model {
EVDEV_MODEL_SYSTEM76_GALAGO,
EVDEV_MODEL_SYSTEM76_KUDU,
EVDEV_MODEL_CLEVO_W740SU,
EVDEV_MODEL_APPLE_TOUCHPAD,
EVDEV_MODEL_WACOM_TOUCHPAD,
};
struct mt_slot {

View file

@ -32,6 +32,9 @@ struct motion_filter_interface {
struct motion_filter *filter,
const struct normalized_coords *unaccelerated,
void *data, uint64_t time);
void (*restart)(struct motion_filter *filter,
void *data,
uint64_t time);
void (*destroy)(struct motion_filter *filter);
bool (*set_speed)(struct motion_filter *filter,
double speed);

View file

@ -43,6 +43,13 @@ filter_dispatch(struct motion_filter *filter,
return filter->interface->filter(filter, unaccelerated, data, time);
}
void
filter_restart(struct motion_filter *filter,
void *data, uint64_t time)
{
filter->interface->restart(filter, data, time);
}
void
filter_destroy(struct motion_filter *filter)
{
@ -273,6 +280,29 @@ accelerator_filter(struct motion_filter *filter,
return accelerated;
}
static void
accelerator_restart(struct motion_filter *filter,
void *data,
uint64_t time)
{
struct pointer_accelerator *accel =
(struct pointer_accelerator *) filter;
unsigned int offset;
struct pointer_tracker *tracker;
for (offset = 1; offset < NUM_POINTER_TRACKERS; offset++) {
tracker = tracker_by_offset(accel, offset);
tracker->time = 0;
tracker->dir = 0;
tracker->delta.x = 0;
tracker->delta.y = 0;
}
tracker = tracker_by_offset(accel, 0);
tracker->time = time;
tracker->dir = UNDEFINED_DIRECTION;
}
static void
accelerator_destroy(struct motion_filter *filter)
{
@ -309,6 +339,7 @@ accelerator_set_speed(struct motion_filter *filter,
struct motion_filter_interface accelerator_interface = {
accelerator_filter,
accelerator_restart,
accelerator_destroy,
accelerator_set_speed,
};
@ -354,7 +385,7 @@ pointer_accel_profile_linear(struct motion_filter *filter,
const double threshold = accel_filter->threshold; /* units/ms */
const double incline = accel_filter->incline;
s1 = min(1, speed_in * 5);
s1 = min(1, 0.3 + speed_in * 4);
s2 = 1 + (speed_in - threshold) * incline;
return min(max_accel, s2 > 1 ? s2 : s1);

View file

@ -37,6 +37,11 @@ struct normalized_coords
filter_dispatch(struct motion_filter *filter,
const struct normalized_coords *unaccelerated,
void *data, uint64_t time);
void
filter_restart(struct motion_filter *filter,
void *data, uint64_t time);
void
filter_destroy(struct motion_filter *filter);

View file

@ -308,4 +308,10 @@ int parse_mouse_dpi_property(const char *prop);
int parse_mouse_wheel_click_angle_property(const char *prop);
double parse_trackpoint_accel_property(const char *prop);
static inline double
vector_length(double x, double y)
{
return sqrt(x * x + y * y);
}
#endif /* LIBINPUT_UTIL_H */

View file

@ -42,7 +42,9 @@ liblitest_la_SOURCES = \
litest-vmware-virtual-usb-mouse.c \
litest.c
liblitest_la_LIBADD = $(top_builddir)/src/libinput-util.la
liblitest_la_CFLAGS = $(AM_CFLAGS)
liblitest_la_CFLAGS = $(AM_CFLAGS) \
-DLIBINPUT_UDEV_RULES_FILE="\"$(abs_top_srcdir)/udev/90-libinput-model-quirks.rules\"" \
-DLIBINPUT_UDEV_HWDB_FILE="\"$(abs_top_srcdir)/udev/90-libinput-model-quirks.hwdb\""
if HAVE_LIBUNWIND
liblitest_la_LIBADD += $(LIBUNWIND_LIBS) -ldl
liblitest_la_CFLAGS += $(LIBUNWIND_CFLAGS)
@ -119,9 +121,13 @@ test_device_LDADD = $(TEST_LIBS)
test_device_LDFLAGS = -no-install
test_litest_selftest_SOURCES = litest-selftest.c litest.c litest-int.h litest.h
test_litest_selftest_CFLAGS = -DLITEST_DISABLE_BACKTRACE_LOGGING -DLITEST_NO_MAIN
test_litest_selftest_CFLAGS = -DLITEST_DISABLE_BACKTRACE_LOGGING -DLITEST_NO_MAIN $(liblitest_la_CFLAGS)
test_litest_selftest_LDADD = $(TEST_LIBS)
test_litest_selftest_LDFLAGS = -no-install
if HAVE_LIBUNWIND
test_litest_selftest_LDADD += $(LIBUNWIND_LIBS) -ldl
test_litest_selftest_CFLAGS += $(LIBUNWIND_CFLAGS)
endif
# build-test only
test_build_pedantic_c99_SOURCES = build-pedantic.c

View file

@ -40,6 +40,7 @@
#include <unistd.h>
#include "linux/input.h"
#include <sys/ptrace.h>
#include <sys/sendfile.h>
#include <sys/timerfd.h>
#include <sys/wait.h>
@ -49,6 +50,9 @@
#define UDEV_RULES_D "/run/udev/rules.d"
#define UDEV_RULE_PREFIX "99-litest-"
#define UDEV_HWDB_D "/etc/udev/hwdb.d"
#define UDEV_COMMON_RULE_FILE UDEV_RULES_D "/91-litest-model-quirks.rules"
#define UDEV_COMMON_HWDB_FILE UDEV_HWDB_D "/91-litest-model-quirks-REMOVEME.hwdb"
static int in_debugger = -1;
static int verbose = 0;
@ -56,13 +60,15 @@ const char *filter_test = NULL;
const char *filter_device = NULL;
const char *filter_group = NULL;
static inline void litest_remove_model_quirks(void);
/* defined for the litest selftest */
#ifndef LITEST_DISABLE_BACKTRACE_LOGGING
#define litest_log(...) fprintf(stderr, __VA_ARGS__)
#define litest_vlog(format_, args_) vfprintf(stderr, format_, args_)
#else
#define litest_log(...) /* __VA_ARGS__ */
#define litest_vlog(...) /* __VA_ARGS__ */
#define litest_log(...) { /* __VA_ARGS__ */ }
#define litest_vlog(...) { /* __VA_ARGS__ */ }
#endif
#ifdef HAVE_LIBUNWIND
@ -382,28 +388,40 @@ struct litest_test_device* devices[] = {
static struct list all_tests;
static inline void
litest_system(const char *command)
{
int ret;
ret = system(command);
if (ret == -1) {
litest_abort_msg("Failed to execute: %s", command);
} else if (WIFEXITED(ret)) {
if (WEXITSTATUS(ret))
litest_abort_msg("'%s' failed with %d",
command,
WEXITSTATUS(ret));
} else if (WIFSIGNALED(ret)) {
litest_abort_msg("'%s' terminated with signal %d",
command,
WTERMSIG(ret));
}
}
static void
litest_reload_udev_rules(void)
{
int ret = system("udevadm control --reload-rules");
if (ret == -1) {
litest_abort_msg("Failed to execute: udevadm");
} else if (WIFEXITED(ret)) {
if (WEXITSTATUS(ret))
litest_abort_msg("udevadm failed with %d",
WEXITSTATUS(ret));
} else if (WIFSIGNALED(ret)) {
litest_abort_msg("udevadm terminated with signal %d",
WTERMSIG(ret));
}
litest_system("udevadm control --reload-rules");
litest_system("udevadm hwdb --update");
}
static int
litest_udev_rule_filter(const struct dirent *entry)
{
return strncmp(entry->d_name,
UDEV_RULE_PREFIX,
strlen(UDEV_RULE_PREFIX)) == 0;
return strneq(entry->d_name,
UDEV_RULE_PREFIX,
strlen(UDEV_RULE_PREFIX));
}
static void
@ -438,6 +456,7 @@ litest_drop_udev_rules(void)
}
free(entries);
litest_remove_model_quirks();
litest_reload_udev_rules();
}
@ -881,21 +900,70 @@ merge_events(const int *orig, const int *override)
return events;
}
static inline void
litest_copy_file(const char *dest, const char *src, const char *header)
{
int in, out;
out = open(dest, O_CREAT|O_WRONLY, 0644);
litest_assert_int_gt(out, -1);
if (header)
write(out, header, strlen(header));
in = open(src, O_RDONLY);
litest_assert_int_gt(in, -1);
/* lazy, just check for error and empty file copy */
litest_assert_int_gt(sendfile(out, in, NULL, 4096), 0);
close(out);
close(in);
}
static inline void
litest_install_model_quirks(void)
{
litest_copy_file(UDEV_COMMON_RULE_FILE, LIBINPUT_UDEV_RULES_FILE, NULL);
litest_copy_file(UDEV_COMMON_HWDB_FILE,
LIBINPUT_UDEV_HWDB_FILE,
"#################################################################\n"
"# WARNING: REMOVE THIS FILE\n"
"# This is the run-time hwdb file for the libinput test suite and\n"
"# should be removed on exit. If the test-suite is not currently \n"
"# running, remove this file and update your hwdb: \n"
"# sudo udevadm hwdb --update\n"
"#################################################################\n\n");
}
static inline void
litest_remove_model_quirks(void)
{
unlink(UDEV_COMMON_RULE_FILE);
unlink(UDEV_COMMON_HWDB_FILE);
}
static char *
litest_init_udev_rules(struct litest_test_device *dev)
{
int rc;
FILE *f;
char *path;
if (!dev->udev_rule)
return NULL;
char *path = NULL;
rc = mkdir(UDEV_RULES_D, 0755);
if (rc == -1 && errno != EEXIST)
ck_abort_msg("Failed to create udev rules directory (%s)\n",
strerror(errno));
rc = mkdir(UDEV_HWDB_D, 0755);
if (rc == -1 && errno != EEXIST)
ck_abort_msg("Failed to create udev hwdb directory (%s)\n",
strerror(errno));
litest_install_model_quirks();
/* device-specific udev rules */
if (!dev->udev_rule)
goto out;
rc = xasprintf(&path,
"%s/%s%s.rules",
UDEV_RULES_D,
@ -911,6 +979,7 @@ litest_init_udev_rules(struct litest_test_device *dev)
litest_assert_int_ge(fputs(dev->udev_rule, f), 0);
fclose(f);
out:
litest_reload_udev_rules();
return path;
@ -950,6 +1019,7 @@ litest_create(enum litest_device_type which,
if ((*dev)->create) {
(*dev)->create(d);
if (abs_override || events_override) {
litest_remove_model_quirks();
if (udev_file)
unlink(udev_file);
litest_abort_msg("Custom create cannot be overridden");
@ -1128,6 +1198,7 @@ litest_delete_device(struct litest_device *d)
return;
if (d->udev_rule_file) {
litest_remove_model_quirks();
unlink(d->udev_rule_file);
free(d->udev_rule_file);
d->udev_rule_file = NULL;

View file

@ -2153,6 +2153,53 @@ START_TEST(clickpad_click_n_drag)
}
END_TEST
START_TEST(clickpad_finger_pin)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libevdev *evdev = dev->evdev;
const struct input_absinfo *abs;
abs = libevdev_get_abs_info(evdev, ABS_MT_POSITION_X);
ck_assert_notnull(abs);
if (abs->resolution == 0)
return;
litest_drain_events(li);
/* make sure the movement generates pointer events when
not pinned */
litest_touch_down(dev, 0, 50, 50);
litest_touch_move_to(dev, 0, 50, 50, 52, 52, 10, 1);
litest_touch_move_to(dev, 0, 52, 52, 48, 48, 10, 1);
litest_touch_move_to(dev, 0, 48, 48, 50, 50, 10, 1);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
litest_button_click(dev, BTN_LEFT, true);
litest_drain_events(li);
litest_touch_move_to(dev, 0, 50, 50, 52, 52, 10, 1);
litest_touch_move_to(dev, 0, 52, 52, 48, 48, 10, 1);
litest_touch_move_to(dev, 0, 48, 48, 50, 50, 10, 1);
litest_assert_empty_queue(li);
litest_button_click(dev, BTN_LEFT, false);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_BUTTON);
/* still pinned after release */
litest_touch_move_to(dev, 0, 50, 50, 52, 52, 10, 1);
litest_touch_move_to(dev, 0, 52, 52, 48, 48, 10, 1);
litest_touch_move_to(dev, 0, 48, 48, 50, 50, 10, 1);
litest_assert_empty_queue(li);
/* move to unpin */
litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10, 1);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
}
END_TEST
START_TEST(clickpad_softbutton_left)
{
struct litest_device *dev = litest_current_device();
@ -5144,6 +5191,7 @@ litest_setup_tests(void)
litest_add("touchpad:click", touchpad_btn_left, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_CLICKPAD);
litest_add("touchpad:click", clickpad_btn_left, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:click", clickpad_click_n_drag, LITEST_CLICKPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:click", clickpad_finger_pin, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:softbutton", clickpad_softbutton_left, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add("touchpad:softbutton", clickpad_softbutton_right, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);

View file

@ -15,6 +15,13 @@
#
# Sort by brand, model
##########################################
# Apple
##########################################
libinput:touchpad:input:b0003v05ACp*
libinput:touchpad:input:b0005v05ACp*
LIBINPUT_MODEL_APPLE_TOUCHPAD=1
##########################################
# Google
##########################################
@ -23,18 +30,18 @@
# extrapolated from the chromiumos touchad-tests repo
# https://chromium.googlesource.com/chromiumos/platform/touchpad-tests
libinput:name:Cypress APA Trackpad (cyapa):dmi:*pnFalco:pvr*
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*pn*Mario*:
libinput:name:Cypress APA Trackpad (cyapa):dmi:*pn*Butterfly*:
libinput:name:Cypress APA Trackpad (cyapa):dmi:*pn*Peppy*:
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*pn*ZGB*:
libinput:name:Cypress APA Trackpad (cyapa):dmi:*pn*Parrot*:
libinput:name:Cypress APA Trackpad (cyapa):dmi:*bvn*coreboot*:pn*Leon*:
libinput:name:Cypress APA Trackpad (cyapa):dmi:*bvn*coreboot*:pn*Falco*:
libinput:name:Cypress APA Trackpad (cyapa):dmi:*bvn*coreboot*:pn*Wolf*:
libinput:name:Cypress APA Trackpad (cyapa):dmi:*svn*GOOGLE*:pn*Link*:
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*pn*Alex*:
libinput:name:Cypress APA Trackpad (cyapa):dmi:*svn*SAMSUNG*:pn*Lumpy*:
libinput:name:Atmel maXTouch Touchpad:dmi:*svn*GOOGLE*:pn*Samus*:
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*pn*Mario*
libinput:name:Cypress APA Trackpad (cyapa):dmi:*pn*Butterfly*
libinput:name:Cypress APA Trackpad (cyapa):dmi:*pn*Peppy*
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*pn*ZGB*
libinput:name:Cypress APA Trackpad (cyapa):dmi:*pn*Parrot*
libinput:name:Cypress APA Trackpad (cyapa):dmi:*bvn*coreboot*:pn*Leon*
libinput:name:Cypress APA Trackpad (cyapa):dmi:*bvn*coreboot*:pn*Falco*
libinput:name:Cypress APA Trackpad (cyapa):dmi:*bvn*coreboot*:pn*Wolf*
libinput:name:Cypress APA Trackpad (cyapa):dmi:*svn*GOOGLE*:pn*Link*
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*pn*Alex*
libinput:name:Cypress APA Trackpad (cyapa):dmi:*svn*SAMSUNG*:pn*Lumpy*
libinput:name:Atmel maXTouch Touchpad:dmi:*svn*GOOGLE*:pn*Samus*
LIBINPUT_MODEL_CHROMEBOOK=1
##########################################
@ -64,3 +71,9 @@ libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnSystem76*pvrgalu1*
# Kudu Professional
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnSystem76*pvrkudp1*
LIBINPUT_MODEL_SYSTEM76_KUDU=1
##########################################
# Wacom
##########################################
libinput:touchpad:input:b0003v056Ap*
LIBINPUT_MODEL_WACOM_TOUCHPAD=1

View file

@ -13,8 +13,9 @@ KERNEL!="event*", GOTO="libinput_model_quirks_end"
# hwdb matches:
#
# libinput:<modalias>
IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:", \
# libinput:touchpad:<modalias>
ENV{ID_INPUT_TOUCHPAD}=="1", \
IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:touchpad:", \
GOTO="libinput_model_quirks_end"
# libinput:name:<name>:dmi:<dmi string>
@ -22,4 +23,5 @@ KERNELS=="input*", \
IMPORT{builtin}="hwdb 'libinput:name:$attr{name}:$attr{[dmi/id]modalias}'", \
GOTO="libinput_model_quirks_end"
LABEL="libinput_model_quirks_end"