Compare commits

...

25 commits
main ... 1.1.8

Author SHA1 Message Date
Peter Hutterer
a341942d7e configure.ac: libinput 1.1.8
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-02-18 11:16:14 +10:00
Peter Hutterer
86bd9bad66 touchpad: move the tapping exclusion zone to the top edge of the button
We previously used the half-way mark of the touchpad's y axis to decide where
to ignore tapping. Move this down to the top edge of the software buttons
instead. Users may tap with a finger in the software button areas, on the rest
of the touchpad it's unlikely that they tap within 5% of the edge.

On touchpads with physical buttons or if clickfinger is enabled, the
no-tapping zone extends to the bottom of the touchpad. This required splitting
the tests into clickfinger, softbuttons and hardbuttons.

https://bugs.freedesktop.org/show_bug.cgi?id=93947

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 79139ebcd1)
2016-02-18 11:15:56 +10:00
Peter Hutterer
fb0f8c6221 touchpad: add synaptics semi-mt devices to those needing hysteresis
https://bugs.freedesktop.org/show_bug.cgi?id=94097

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit d6b889852a)
2016-02-18 11:15:50 +10:00
Peter Hutterer
ecb286fa82 configure.ac: libinput 1.1.7
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-02-10 08:22:50 +10:00
Peter Hutterer
e013b7fef8 touchpad: init a default hysteresis for ALPS rushmore touchpads
https://bugs.freedesktop.org/show_bug.cgi?id=90590

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 07420eec05)
2016-02-10 08:22:02 +10:00
Peter Hutterer
23b506f318 udev: fix ALPS firmware detection
The firmware version is in id.version, not id.model which is always
PSMOUSE_ALPS for ALPS devices.

The various fw versions are listed in <kernel>/drivers/input/mouse/alps.h and
are all hex numbers. Version 8 is actually 0x800, change the match
accordingly.

Expected side-effect: earlier versions of ALPS touchpads now lose their
(erroneous) size assignment.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 1f304763b4)
2016-02-10 08:22:01 +10:00
Peter Hutterer
216c6aae54 touchpad: fix dwt disabling while a key is still down
If dwt is disabled on the commandline, e.g. by setting an xinput property it
may be disabled before the release event comes in. This caused the timer to
refresh indefinitely since the key state mask was still on for that key.
Always updating the key state mask (even when dwt is disabled) fixes that.

If a key is held down while dwt is disabled, this can still cause a indefinite
timer refresh, so in the timer func, check if dwt is enabled before refreshing
the timer.

https://bugs.freedesktop.org/show_bug.cgi?id=94015

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 0e87dc9af2)
2016-02-10 08:21:59 +10:00
Peter Hutterer
b09856aea8 configure.ac: libinput 1.1.6
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-02-05 12:37:00 +10:00
Peter Hutterer
7196f5101e touchpad: if we have a serio keyboard, override any previous dwt pairing
If a USB keyboard like the YubiKey is found before the internal keyboard, it
will be paired with the touchpad when it is seen. The internal keyboard is
seen later bug ignored because we already have a keyboard paired with the
touchpad.

This is obviously wrong. For now, give priority to serio keyboards, and
override existing dwt pairings with the new keyboard.

https://bugs.freedesktop.org/show_bug.cgi?id=93983

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 0b0150e08d)
2016-02-05 12:37:00 +10:00
Peter Hutterer
f0bb4b0e8c touchpad: while a key is held down, don't disable dwt
If a key enables dwt and is held down when the timeout expires, re-issue the
timeout.

There is a corner case where dwt may not work as expected:
1. key down and held down
2. dwt timer expires, dwt is re-issued
3. touch starts
4. key is released
5. dwt timer expires
6. touch now starts moving the pointer

This is an effect of the smart touch detection. A touch starting after the
last key press is released for pointer motion once dwt turns off again. This
is what happens in the above case, the dwt timer expiring is the last virtual
key press. This is a corner case and likely hard to trigger by a real user.

https://bugs.freedesktop.org/show_bug.cgi?id=93984

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit b27f04689e)
2016-02-05 12:36:59 +10:00
Peter Hutterer
54759c81b5 touchpad: drop motion hysteresis by default
Some older touchpad devices jitter a fair bit when a finger is resting on the
touchpad. That's why the hysteresis was introduced in the synaptics driver
back in 2011. However, the default value of the hysteresis in the synaptics
driver ended up being 0, even though the code looks like it's using a fraction
of the touchpad diagonal. When the hysteresis code was ported to libinput it
was eventually set to 0.5mm.

Turns out this is still too high and tiny finger motions are either
nonreactive or quite jumpy, making it hard to select small targets. Drop the
default hysteresis by reducing its margin to 0, but leave it in place for
those devices where we need them (e.g. the cyapa touchpads).

https://bugs.freedesktop.org/show_bug.cgi?id=93503

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 6e0553ab5553d63fa737c1739cfa86fbeee9f641)
2016-02-05 12:36:59 +10:00
Peter Hutterer
2e02d94e2b test: fix leaking libevdev fd
This was the reason for the valgrind test case failures whenever we
accumulated too many tests (see 9c2afae1 and 2a110104). The cause was simply
that we ran out of fds which caused libevdev to fail the scandir() searching
for the event node. That resulted in a NULL devnode and an abort in litest.

Close the fd before freeing the evdev device.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit a84bf167a3)
2016-02-05 12:36:59 +10:00
Peter Hutterer
92933e79f8 evdev: disable the mode button on the Cyborg RAT 5
This button sends a release N, press N+1 on each press, cycling through the
three event codes supported. This causes a stuck button since the current mode
is never released.

Long-term this better served by a set of switches that toggle accordingly, for
now disable the button codes.

https://bugs.freedesktop.org/show_bug.cgi?id=92127

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit e19d5d228c)
2016-02-05 12:36:59 +10:00
Peter Hutterer
d06ed108b0 gestures: average motion by active touches, not moved touches
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit b6f59d0e3b)
2016-02-05 12:36:59 +10:00
Peter Hutterer
815af6dec8 test: exclude semi-mt devices from the normal 2fg scroll test
We have a specific semi-mt 2fg scroll test for those.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit c352a50295)
2016-02-05 12:36:59 +10:00
Peter Hutterer
dcd48bb3b3 test: run pinch gesture tests for 2-slot touchpads
Some of the 2-slot touchpads don't do gestures though (e.g. semi-mt) so skip
those.

And change the movement granularity for the pinch and spread tests so we stay
under one degree angle for lower-resolution touchpads too.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit ff2ee2c681)
2016-02-05 12:36:59 +10:00
Peter Hutterer
7cce284063 test: fix compiler warning
litest-selftest.c: In function ‘litest_ptr_eq_notrigger’:
litest-selftest.c:172:10: warning: initialization makes integer from pointer
without a cast [-Wint-conversion]
  int c = NULL;
          ^
litest-selftest.c:173:10: warning: initialization makes integer from pointer
without a cast [-Wint-conversion]
  int d = NULL;
          ^

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 82335b0ab9)
2016-02-04 14:21:10 +10:00
Peter Hutterer
c18f62da14 configure.ac: libinput 1.1.5
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-01-25 14:19:36 +10:00
Peter Hutterer
53b021a1da touchpad: disable gestures for single-finger touchpads
No point trying to detect pinch gestures if we only have one set of
coordinates. This makes two-finger scrolling on ST touchpads more reactive.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 28205d6f29)
2016-01-25 13:38:55 +10:00
Peter Hutterer
983a8ec4c2 touchpad: disable MT for all semi-mt devices
Synaptics, Elantech and Alps semi-mt devices all have issues with reporting
correct MT data, even the bounding box which semi-mt devices are supposed to
report is wrong.

Synaptics devices have massive jumps with two fingers down. Elantech devices
may open slots without coordinate data. Alps devices may send 0/0 coordinates
as initial slot position.

All these may be addressable with specific quirks, but the actual benefit is
largely restricted to better palm detection (though even with quirks this is
unlikely to work) and support for pinch gestures (again, lack of coordinates
makes supporting those hard anyway).

Elantech: https://bugs.freedesktop.org/show_bug.cgi?id=93583
Alps: https://bugzilla.redhat.com/show_bug.cgi?id=1295073

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 342bc51016)
2016-01-25 13:38:55 +10:00
Peter Hutterer
ea3f1c2131 test: when moving 2 fingers, move them in the same frame
More accurate representation of what we actually want to do. Plus it avoids
weird test case failures in semi-mt where we always pick the t/l and b/r
touches for the bounding box. That is the proper behavior for semi-mt, but
it's not for the tests where we expect simultaneous finger movement.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit d19307f20d)
2016-01-25 13:38:55 +10:00
Peter Hutterer
fd278a2eda touchpad: disable MT for elantech semi-mt touchpads
When three fingers are set down on the touchpad, one finger tends to get a 0/0
coordinate, triggering palm detection in the upper left corner. Handle this
like the jumping semi-mt touchpads and disable MT handling and instead
just rely on the x/y axis and the BTN_TOOL_* events.

https://bugs.freedesktop.org/show_bug.cgi?id=93583

This kernel patch is required:
https://lkml.org/lkml/2016/1/11/171

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 556aac04b5)
2016-01-25 13:29:16 +10:00
Peter Hutterer
17f742dcd3 doc: add section names to motion normalization subheaders
Otherwise the first word is used as section header and discarded from the
output.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 41cc9053dd)
2016-01-25 13:29:12 +10:00
Peter Hutterer
65f6cd9c6e evdev: only reject devices with missing MT x/y if they're MT devices
A fake MT device may have ABS_MT_POSITION_X but not Y. In this case we don't
care, because we don't handle those axes anyway.

http://bugs.freedesktop.org/show_bug.cgi?id=93474

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 988cfda42c)
2016-01-25 13:29:07 +10:00
Caibin Chen
9dab84fe92 touchpad: fix DWT pairing for Macbook Pro 2015
Label internal keyboards through the udev hwdb and only pair the internal
(usb) Apple touchpads with those keyboards labelled as such.

https://bugs.freedesktop.org/show_bug.cgi?id=93367

Co-authored-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit b3f11180e3)
2016-01-25 13:29:02 +10:00
24 changed files with 1590 additions and 137 deletions

View file

@ -2,7 +2,7 @@ AC_PREREQ([2.64])
m4_define([libinput_major_version], [1])
m4_define([libinput_minor_version], [1])
m4_define([libinput_micro_version], [4])
m4_define([libinput_micro_version], [8])
m4_define([libinput_version],
[libinput_major_version.libinput_minor_version.libinput_micro_version])
@ -31,7 +31,7 @@ AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz])
# b) If interfaces have been changed or added, but binary compatibility has
# been preserved, change to C+1:0:A+1
# c) If the interface is the same as the previous version, change to C:R+1:A
LIBINPUT_LT_VERSION=16:4:6
LIBINPUT_LT_VERSION=16:8:6
AC_SUBST(LIBINPUT_LT_VERSION)
AM_SILENT_RULES([yes])

View file

@ -28,7 +28,7 @@ This normalization only applies to accelerated coordinates, unaccelerated
coordinates are left in device-units. It is up to the caller to interpret
those coordinates correctly.
@section Normalization of touchpad coordinates
@section motion_normalization_touchpad Normalization of touchpad coordinates
Touchpads may have a different resolution for the horizontal and vertical
axis. Interpreting coordinates from the touchpad without taking resolution
@ -38,7 +38,7 @@ libinput scales unaccelerated touchpad motion to the resolution of the
touchpad's x axis, i.e. the unaccelerated value for the y axis is:
y = (x / resolution_x) * resolution_y
@section Setting custom DPI settings
@section motion_normalization_customization Setting custom DPI settings
Devices usually do not advertise their resolution and libinput relies on
the udev property <b>MOUSE_DPI</b> for this information. This property is usually

View file

@ -48,15 +48,19 @@ static struct normalized_coords
tp_get_touches_delta(struct tp_dispatch *tp, bool average)
{
struct tp_touch *t;
unsigned int i, nchanged = 0;
unsigned int i, nactive = 0;
struct normalized_coords normalized;
struct normalized_coords delta = {0.0, 0.0};
for (i = 0; i < tp->num_slots; i++) {
t = &tp->touches[i];
if (tp_touch_active(tp, t) && t->dirty) {
nchanged++;
if (!tp_touch_active(tp, t))
continue;
nactive++;
if (t->dirty) {
normalized = tp_get_delta(t);
delta.x += normalized.x;
@ -64,11 +68,11 @@ tp_get_touches_delta(struct tp_dispatch *tp, bool average)
}
}
if (!average || nchanged == 0)
if (!average || nactive == 0)
return delta;
delta.x /= nchanged;
delta.y /= nchanged;
delta.x /= nactive;
delta.y /= nactive;
return delta;
}
@ -184,18 +188,7 @@ tp_gesture_get_direction(struct tp_dispatch *tp, struct tp_touch *touch)
{
struct normalized_coords normalized;
struct device_float_coords delta;
double move_threshold;
/*
* Semi-mt touchpads have somewhat inaccurate coordinates when
* 2 fingers are down, so use a slightly larger threshold.
* Elantech semi-mt touchpads are accurate enough though.
*/
if (tp->semi_mt &&
(tp->device->model_flags & EVDEV_MODEL_ELANTECH_TOUCHPAD) == 0)
move_threshold = TP_MM_TO_DPI_NORMALIZED(4);
else
move_threshold = TP_MM_TO_DPI_NORMALIZED(1);
double move_threshold = TP_MM_TO_DPI_NORMALIZED(1);
delta = device_delta(touch->point, touch->gesture.initial);
@ -221,11 +214,7 @@ tp_gesture_get_pinch_info(struct tp_dispatch *tp,
delta = device_delta(first->point, second->point);
normalized = tp_normalize_delta(tp, delta);
*distance = normalized_length(normalized);
if (!tp->semi_mt)
*angle = atan2(normalized.y, normalized.x) * 180.0 / M_PI;
else
*angle = 0.0;
*angle = atan2(normalized.y, normalized.x) * 180.0 / M_PI;
*center = device_average(first->point, second->point);
}
@ -260,6 +249,9 @@ tp_gesture_twofinger_handle_state_none(struct tp_dispatch *tp, uint64_t time)
first->gesture.initial = first->point;
second->gesture.initial = second->point;
if (!tp->gesture.enabled)
return GESTURE_2FG_STATE_SCROLL;
return GESTURE_2FG_STATE_UNKNOWN;
}
@ -297,7 +289,7 @@ tp_gesture_twofinger_handle_state_unknown(struct tp_dispatch *tp, uint64_t time)
((dir2 & 0x80) && (dir1 & 0x01))) {
tp_gesture_set_scroll_buildup(tp);
return GESTURE_2FG_STATE_SCROLL;
} else if (tp->gesture.enabled) {
} else {
tp_gesture_get_pinch_info(tp,
&tp->gesture.initial_distance,
&tp->gesture.angle,
@ -317,16 +309,7 @@ tp_gesture_twofinger_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG)
return GESTURE_2FG_STATE_SCROLL;
/* On some semi-mt models slot 0 is more accurate, so for semi-mt
* we only use slot 0. */
if (tp->semi_mt) {
if (!tp->touches[0].dirty)
return GESTURE_2FG_STATE_SCROLL;
delta = tp_get_delta(&tp->touches[0]);
} else {
delta = tp_get_average_touches_delta(tp);
}
delta = tp_get_average_touches_delta(tp);
/* scroll is not accelerated */
delta = tp_filter_motion_unaccelerated(tp, &delta, time);
@ -568,10 +551,10 @@ tp_gesture_handle_state(struct tp_dispatch *tp, uint64_t time)
int
tp_init_gesture(struct tp_dispatch *tp)
{
if (tp->device->model_flags & EVDEV_MODEL_JUMPING_SEMI_MT)
tp->gesture.enabled = false;
else
tp->gesture.enabled = true;
/* two-finger scrolling is always enabled, this flag just
* decides whether we detect pinch. semi-mt devices are too
* unreliable to do pinch gestures. */
tp->gesture.enabled = !tp->semi_mt && tp->num_slots > 1;
tp->gesture.twofinger_state = GESTURE_2FG_STATE_NONE;

View file

@ -530,9 +530,9 @@ tp_palm_tap_is_palm(struct tp_dispatch *tp, struct tp_touch *t)
t->point.x < tp->palm.right_edge)
return false;
/* We're inside the left/right palm edge and in the northern half of
* the touchpad - this tap is a palm */
if (t->point.y < tp->palm.vert_center) {
/* We're inside the left/right palm edge and not in one of the
* software button areas */
if (t->point.y < tp->buttons.bottom_area.top_edge) {
log_debug(tp_libinput_context(tp),
"palm: palm-tap detected\n");
return true;
@ -1185,6 +1185,16 @@ tp_keyboard_timeout(uint64_t now, void *data)
{
struct tp_dispatch *tp = data;
if (tp->dwt.dwt_enabled &&
long_any_bit_set(tp->dwt.key_mask,
ARRAY_LENGTH(tp->dwt.key_mask))) {
libinput_timer_set(&tp->dwt.keyboard_timer,
now + DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2);
tp->dwt.keyboard_last_press_time = now;
log_debug(tp_libinput_context(tp), "palm: keyboard timeout refresh\n");
return;
}
tp_tap_resume(tp, now);
tp->dwt.keyboard_active = false;
@ -1229,23 +1239,27 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
struct tp_dispatch *tp = data;
struct libinput_event_keyboard *kbdev;
unsigned int timeout;
if (!tp->dwt.dwt_enabled)
return;
unsigned int key;
if (event->type != LIBINPUT_EVENT_KEYBOARD_KEY)
return;
kbdev = libinput_event_get_keyboard_event(event);
key = libinput_event_keyboard_get_key(kbdev);
/* Only trigger the timer on key down. */
if (libinput_event_keyboard_get_key_state(kbdev) !=
LIBINPUT_KEY_STATE_PRESSED)
LIBINPUT_KEY_STATE_PRESSED) {
long_clear_bit(tp->dwt.key_mask, key);
return;
}
if (!tp->dwt.dwt_enabled)
return;
/* modifier keys don't trigger disable-while-typing so things like
* ctrl+zoom or ctrl+click are possible */
if (tp_key_ignore_for_dwt(libinput_event_keyboard_get_key(kbdev)))
if (tp_key_ignore_for_dwt(key))
return;
if (!tp->dwt.keyboard_active) {
@ -1259,6 +1273,7 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
}
tp->dwt.keyboard_last_press_time = time;
long_set_bit(tp->dwt.key_mask, key);
libinput_timer_set(&tp->dwt.keyboard_timer,
time + timeout);
}
@ -1285,6 +1300,8 @@ tp_want_dwt(struct evdev_device *touchpad,
{
unsigned int bus_tp = libevdev_get_id_bustype(touchpad->evdev),
bus_kbd = libevdev_get_id_bustype(keyboard->evdev);
unsigned int vendor_tp = evdev_device_get_id_vendor(touchpad);
unsigned int vendor_kbd = evdev_device_get_id_vendor(keyboard);
if (tp_dwt_device_is_blacklisted(touchpad) ||
tp_dwt_device_is_blacklisted(keyboard))
@ -1295,12 +1312,51 @@ tp_want_dwt(struct evdev_device *touchpad,
if (bus_tp == BUS_I8042 && bus_kbd != bus_tp)
return false;
/* For Apple touchpads, always use its internal keyboard */
if (vendor_tp == VENDOR_ID_APPLE) {
return vendor_kbd == vendor_tp &&
keyboard->model_flags &
EVDEV_MODEL_APPLE_INTERNAL_KEYBOARD;
}
/* everything else we don't really know, so we have to assume
they go together */
return true;
}
static void
tp_dwt_pair_keyboard(struct evdev_device *touchpad,
struct evdev_device *keyboard)
{
struct tp_dispatch *tp = (struct tp_dispatch*)touchpad->dispatch;
unsigned int bus_kbd = libevdev_get_id_bustype(keyboard->evdev);
if (!tp_want_dwt(touchpad, keyboard))
return;
/* If we already have a keyboard paired, override it if the new one
* is a serio device. Otherwise keep the current one */
if (tp->dwt.keyboard) {
if (bus_kbd != BUS_I8042)
return;
memset(tp->dwt.key_mask, 0, sizeof(tp->dwt.key_mask));
libinput_device_remove_event_listener(&tp->dwt.keyboard_listener);
}
libinput_device_add_event_listener(&keyboard->base,
&tp->dwt.keyboard_listener,
tp_keyboard_event, tp);
tp->dwt.keyboard = keyboard;
tp->dwt.keyboard_active = false;
log_debug(touchpad->base.seat->libinput,
"palm: dwt activated with %s<->%s\n",
touchpad->devname,
keyboard->devname);
}
static void
tp_interface_device_added(struct evdev_device *device,
struct evdev_device *added_device)
@ -1325,20 +1381,8 @@ tp_interface_device_added(struct evdev_device *device,
tp_trackpoint_event, tp);
}
if (added_device->tags & EVDEV_TAG_KEYBOARD &&
tp->dwt.keyboard == NULL &&
tp_want_dwt(device, added_device)) {
log_debug(tp_libinput_context(tp),
"palm: dwt activated with %s<->%s\n",
device->devname,
added_device->devname);
libinput_device_add_event_listener(&added_device->base,
&tp->dwt.keyboard_listener,
tp_keyboard_event, tp);
tp->dwt.keyboard = added_device;
tp->dwt.keyboard_active = false;
}
if (added_device->tags & EVDEV_TAG_KEYBOARD)
tp_dwt_pair_keyboard(device, added_device);
if (tp->sendevents.current_mode !=
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
@ -1478,16 +1522,22 @@ tp_init_slots(struct tp_dispatch *tp,
tp->semi_mt = libevdev_has_property(device->evdev, INPUT_PROP_SEMI_MT);
/* This device has a terrible resolution when two fingers are down,
/* Semi-mt devices are not reliable for true multitouch data, so we
* simply pretend they're single touch touchpads with BTN_TOOL bits.
* Synaptics:
* Terrible resolution when two fingers are down,
* causing scroll jumps. The single-touch emulation ABS_X/Y is
* accurate but the ABS_MT_POSITION touchpoints report the bounding
* box and that causes jumps. So we simply pretend it's a single
* touch touchpad with the BTN_TOOL bits.
* See https://bugzilla.redhat.com/show_bug.cgi?id=1235175 for an
* explanation.
* box and that causes jumps. See https://bugzilla.redhat.com/1235175
* Elantech:
* On three-finger taps/clicks, one slot doesn't get a coordinate
* assigned. See https://bugs.freedesktop.org/show_bug.cgi?id=93583
* Alps:
* If three fingers are set down in the same frame, one slot has the
* coordinates 0/0 and may not get updated for several frames.
* See https://bugzilla.redhat.com/show_bug.cgi?id=1295073
*/
if (tp->semi_mt &&
(device->model_flags & EVDEV_MODEL_JUMPING_SEMI_MT)) {
if (tp->semi_mt) {
tp->num_slots = 1;
tp->slot = 0;
tp->has_mt = false;
@ -1762,14 +1812,12 @@ static int
tp_init_palmdetect(struct tp_dispatch *tp,
struct evdev_device *device)
{
int width, height;
int width;
tp->palm.right_edge = INT_MAX;
tp->palm.left_edge = INT_MIN;
tp->palm.vert_center = INT_MIN;
width = device->abs.dimensions.x;
height = device->abs.dimensions.y;
/* Wacom doesn't have internal touchpads,
* Apple touchpads are always big enough to warrant palm detection */
@ -1784,7 +1832,6 @@ tp_init_palmdetect(struct tp_dispatch *tp,
/* palm edges are 5% of the width on each side */
tp->palm.right_edge = device->abs.absinfo_x->maximum - width * 0.05;
tp->palm.left_edge = device->abs.absinfo_x->minimum + width * 0.05;
tp->palm.vert_center = device->abs.absinfo_y->minimum + height/2;
tp->palm.monitor_trackpoint = true;
@ -1925,13 +1972,41 @@ tp_init_default_resolution(struct tp_dispatch *tp,
return 0;
}
static inline void
tp_init_hysteresis(struct tp_dispatch *tp)
{
int res_x, res_y;
if (tp->device->model_flags & EVDEV_MODEL_CYAPA)
goto want_hysteresis;
if (tp->device->model_flags & EVDEV_MODEL_ALPS_RUSHMORE)
goto want_hysteresis;
if (tp->semi_mt &&
(tp->device->model_flags & EVDEV_MODEL_SYNAPTICS_SERIAL_TOUCHPAD))
goto want_hysteresis;
tp->hysteresis_margin.x = 0;
tp->hysteresis_margin.y = 0;
return;
want_hysteresis:
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;
return;
}
static int
tp_init(struct tp_dispatch *tp,
struct evdev_device *device)
{
int width, height;
double diagonal;
int res_x, res_y;
tp->base.interface = &tp_interface;
tp->device = device;
@ -1945,8 +2020,6 @@ tp_init(struct tp_dispatch *tp,
if (tp_init_slots(tp, device) != 0)
return -1;
res_x = tp->device->abs.absinfo_x->resolution;
res_y = tp->device->abs.absinfo_y->resolution;
width = device->abs.dimensions.x;
height = device->abs.dimensions.y;
diagonal = sqrt(width*width + height*height);
@ -1955,8 +2028,7 @@ tp_init(struct tp_dispatch *tp,
EV_ABS,
ABS_MT_DISTANCE);
tp->hysteresis_margin.x = res_x/2;
tp->hysteresis_margin.y = res_y/2;
tp_init_hysteresis(tp);
if (tp_init_accel(tp, diagonal) != 0)
return -1;

View file

@ -320,7 +320,6 @@ struct tp_dispatch {
struct {
int32_t right_edge; /* in device coordinates */
int32_t left_edge; /* in device coordinates */
int32_t vert_center; /* in device coordinates */
bool trackpoint_active;
struct libinput_event_listener trackpoint_listener;
@ -342,6 +341,7 @@ struct tp_dispatch {
struct libinput_event_listener keyboard_listener;
struct libinput_timer keyboard_timer;
struct evdev_device *keyboard;
unsigned long key_mask[NLONGS(KEY_CNT)];
uint64_t keyboard_last_press_time;
} dwt;

View file

@ -1662,6 +1662,10 @@ evdev_read_model_flags(struct evdev_device *device)
{ "LIBINPUT_MODEL_SYNAPTICS_SERIAL_TOUCHPAD", EVDEV_MODEL_SYNAPTICS_SERIAL_TOUCHPAD },
{ "LIBINPUT_MODEL_JUMPING_SEMI_MT", EVDEV_MODEL_JUMPING_SEMI_MT },
{ "LIBINPUT_MODEL_ELANTECH_TOUCHPAD", EVDEV_MODEL_ELANTECH_TOUCHPAD },
{ "LIBINPUT_MODEL_APPLE_INTERNAL_KEYBOARD", EVDEV_MODEL_APPLE_INTERNAL_KEYBOARD },
{ "LIBINPUT_MODEL_CYBORG_RAT", EVDEV_MODEL_CYBORG_RAT },
{ "LIBINPUT_MODEL_CYAPA", EVDEV_MODEL_CYAPA },
{ "LIBINPUT_MODEL_ALPS_RUSHMORE", EVDEV_MODEL_ALPS_RUSHMORE },
{ NULL, EVDEV_MODEL_DEFAULT },
};
const struct model_map *m = model_map;
@ -1868,7 +1872,8 @@ evdev_reject_device(struct evdev_device *device)
libevdev_has_event_code(evdev, EV_REL, REL_Y))
return -1;
if (libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_X) ^
if (!evdev_is_fake_mt_device(device) &&
libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_X) ^
libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_Y))
return -1;
@ -2213,6 +2218,39 @@ evdev_drain_fd(int fd)
}
}
static inline void
evdev_pre_configure_model_quirks(struct evdev_device *device)
{
/* The Cyborg RAT has a mode button that cycles through event codes.
* On press, we get a release for the current mode and a press for the
* next mode:
* E: 0.000001 0004 0004 589833 # EV_MSC / MSC_SCAN 589833
* E: 0.000001 0001 0118 0000 # EV_KEY / (null) 0
* E: 0.000001 0004 0004 589834 # EV_MSC / MSC_SCAN 589834
* E: 0.000001 0001 0119 0001 # EV_KEY / (null) 1
* E: 0.000001 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +0ms
* E: 0.705000 0004 0004 589834 # EV_MSC / MSC_SCAN 589834
* E: 0.705000 0001 0119 0000 # EV_KEY / (null) 0
* E: 0.705000 0004 0004 589835 # EV_MSC / MSC_SCAN 589835
* E: 0.705000 0001 011a 0001 # EV_KEY / (null) 1
* E: 0.705000 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +705ms
* E: 1.496995 0004 0004 589833 # EV_MSC / MSC_SCAN 589833
* E: 1.496995 0001 0118 0001 # EV_KEY / (null) 1
* E: 1.496995 0004 0004 589835 # EV_MSC / MSC_SCAN 589835
* E: 1.496995 0001 011a 0000 # EV_KEY / (null) 0
* E: 1.496995 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +791ms
*
* https://bugs.freedesktop.org/show_bug.cgi?id=92127
*
* Disable the event codes to avoid stuck buttons.
*/
if(device->model_flags & EVDEV_MODEL_CYBORG_RAT) {
libevdev_disable_event_code(device->evdev, EV_KEY, 0x118);
libevdev_disable_event_code(device->evdev, EV_KEY, 0x119);
libevdev_disable_event_code(device->evdev, EV_KEY, 0x11a);
}
}
struct evdev_device *
evdev_device_create(struct libinput_seat *seat,
struct udev_device *udev_device)
@ -2282,6 +2320,8 @@ evdev_device_create(struct libinput_seat *seat,
matrix_init_identity(&device->abs.usermatrix);
matrix_init_identity(&device->abs.default_calibration);
evdev_pre_configure_model_quirks(device);
if (evdev_configure_device(device) == -1)
goto err;

View file

@ -108,6 +108,10 @@ enum evdev_device_model {
EVDEV_MODEL_JUMPING_SEMI_MT = (1 << 10),
EVDEV_MODEL_ELANTECH_TOUCHPAD = (1 << 11),
EVDEV_MODEL_LENOVO_X220_TOUCHPAD_FW81 = (1 << 12),
EVDEV_MODEL_APPLE_INTERNAL_KEYBOARD = (1 << 13),
EVDEV_MODEL_CYBORG_RAT = (1 << 14),
EVDEV_MODEL_CYAPA = (1 << 15),
EVDEV_MODEL_ALPS_RUSHMORE = (1 << 16),
};
struct mt_slot {

View file

@ -25,6 +25,7 @@
#ifndef LIBINPUT_UTIL_H
#define LIBINPUT_UTIL_H
#include <assert.h>
#include <unistd.h>
#include <math.h>
#include <stdarg.h>
@ -38,6 +39,7 @@
#define VENDOR_ID_APPLE 0x5ac
#define VENDOR_ID_WACOM 0x56a
#define VENDOR_ID_SYNAPTICS_SERIAL 0x002
#define PRODUCT_ID_APPLE_KBD_TOUCHPAD 0x273
#define PRODUCT_ID_SYNAPTICS_SERIAL 0x007
/* The HW DPI rate we normalize to before calculating pointer acceleration */
@ -145,6 +147,19 @@ long_set_bit_state(unsigned long *array, int bit, int state)
long_clear_bit(array, bit);
}
static inline int
long_any_bit_set(unsigned long *array, size_t size)
{
unsigned long i;
assert(size > 0);
for (i = 0; i < size; i++)
if (array[i] != 0)
return 1;
return 0;
}
struct matrix {
float val[3][3]; /* [row][col] */
};

View file

@ -15,9 +15,12 @@ liblitest_la_SOURCES = \
litest-int.h \
litest-device-alps-semi-mt.c \
litest-device-alps-dualpoint.c \
litest-device-anker-mouse-kbd.c \
litest-device-apple-internal-keyboard.c \
litest-device-asus-rog-gladius.c \
litest-device-atmel-hover.c \
litest-device-bcm5974.c \
litest-device-cyborg-rat-5.c \
litest-device-elantech-touchpad.c \
litest-device-generic-singletouch.c \
litest-device-keyboard.c \
@ -34,6 +37,7 @@ liblitest_la_SOURCES = \
litest-device-qemu-usb-tablet.c \
litest-device-synaptics.c \
litest-device-synaptics-hover.c \
litest-device-synaptics-i2c.c \
litest-device-synaptics-st.c \
litest-device-synaptics-t440.c \
litest-device-synaptics-x1-carbon-3rd.c \
@ -44,6 +48,7 @@ liblitest_la_SOURCES = \
litest-device-wheel-only.c \
litest-device-xen-virtual-pointer.c \
litest-device-vmware-virtual-usb-mouse.c \
litest-device-yubikey.c \
litest.c
liblitest_la_LIBADD = $(top_builddir)/src/libinput-util.la
liblitest_la_CFLAGS = $(AM_CFLAGS) \

View file

@ -1254,6 +1254,67 @@ START_TEST(device_abs_rel)
}
END_TEST
START_TEST(device_quirks_no_abs_mt_y)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *event;
struct libinput_event_pointer *pev;
int code;
litest_drain_events(li);
litest_event(dev, EV_REL, REL_HWHEEL, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
event = libinput_get_event(li);
pev = litest_is_axis_event(event,
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
LIBINPUT_POINTER_AXIS_SOURCE_WHEEL);
libinput_event_destroy(libinput_event_pointer_get_base_event(pev));
for (code = ABS_MISC + 1; code < ABS_MAX; code++) {
litest_event(dev, EV_ABS, code, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_empty_queue(li);
}
}
END_TEST
START_TEST(device_quirks_cyborg_rat_mode_button)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
struct libinput *li = dev->libinput;
ck_assert(!libinput_device_pointer_has_button(device, 0x118));
ck_assert(!libinput_device_pointer_has_button(device, 0x119));
ck_assert(!libinput_device_pointer_has_button(device, 0x11a));
litest_drain_events(li);
litest_event(dev, EV_KEY, 0x118, 0);
litest_event(dev, EV_KEY, 0x119, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_empty_queue(li);
litest_event(dev, EV_KEY, 0x119, 0);
litest_event(dev, EV_KEY, 0x11a, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_empty_queue(li);
litest_event(dev, EV_KEY, 0x11a, 0);
litest_event(dev, EV_KEY, 0x118, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_empty_queue(li);
}
END_TEST
void
litest_setup_tests(void)
{
@ -1308,4 +1369,7 @@ litest_setup_tests(void)
litest_add_no_device("device:invalid rel events", device_touchpad_rel);
litest_add_no_device("device:invalid rel events", device_touch_rel);
litest_add_no_device("device:invalid rel events", device_abs_rel);
litest_add_for_device("device:quirks", device_quirks_no_abs_mt_y, LITEST_ANKER_MOUSE_KBD);
litest_add_for_device("device:quirks", device_quirks_cyborg_rat_mode_button, LITEST_CYBORG_RAT);
}

View file

@ -34,7 +34,7 @@ START_TEST(gestures_cap)
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
if (litest_is_synaptics_semi_mt(dev))
if (libevdev_has_property(dev->evdev, INPUT_PROP_SEMI_MT))
ck_assert(!libinput_device_has_capability(device,
LIBINPUT_DEVICE_CAP_GESTURE));
else
@ -180,7 +180,9 @@ START_TEST(gestures_pinch)
{ -30, 30 },
};
if (libevdev_get_num_slots(dev->evdev) < 3)
if (libevdev_get_num_slots(dev->evdev) < 2 ||
!libinput_device_has_capability(dev->libinput_device,
LIBINPUT_DEVICE_CAP_GESTURE))
return;
dir_x = cardinals[cardinal][0];
@ -195,13 +197,13 @@ START_TEST(gestures_pinch)
for (i = 0; i < 8; i++) {
litest_push_event_frame(dev);
if (dir_x > 0.0)
dir_x -= 3;
dir_x -= 2;
else if (dir_x < 0.0)
dir_x += 3;
dir_x += 2;
if (dir_y > 0.0)
dir_y -= 3;
dir_y -= 2;
else if (dir_y < 0.0)
dir_y += 3;
dir_y += 2;
litest_touch_move(dev,
0,
50 + dir_x,
@ -269,17 +271,19 @@ START_TEST(gestures_spread)
double scale, oldscale;
double angle;
int cardinals[8][2] = {
{ 0, 1 },
{ 1, 1 },
{ 1, 0 },
{ 1, -1 },
{ 0, -1 },
{ -1, -1 },
{ -1, 0 },
{ -1, 1 },
{ 0, 30 },
{ 30, 30 },
{ 30, 0 },
{ 30, -30 },
{ 0, -30 },
{ -30, -30 },
{ -30, 0 },
{ -30, 30 },
};
if (libevdev_get_num_slots(dev->evdev) < 3)
if (libevdev_get_num_slots(dev->evdev) < 2 ||
!libinput_device_has_capability(dev->libinput_device,
LIBINPUT_DEVICE_CAP_GESTURE))
return;
dir_x = cardinals[cardinal][0];

View file

@ -0,0 +1,225 @@
/*
* Copyright © 2015 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "litest.h"
#include "litest-int.h"
/* Recording from https://bugs.freedesktop.org/show_bug.cgi?id=93474
* This is the keyboard device for this mouse.
*/
static void litest_anker_mouse_kbd_setup(void)
{
struct litest_device *d = litest_create_device(LITEST_ANKER_MOUSE_KBD);
litest_set_current_device(d);
}
static struct input_id input_id = {
.bustype = 0x3,
.vendor = 0x4d9,
.product = 0xfa50,
};
static int events[] = {
EV_REL, REL_HWHEEL,
EV_KEY, KEY_ESC,
EV_KEY, KEY_KPMINUS,
EV_KEY, KEY_KPPLUS,
EV_KEY, KEY_UP,
EV_KEY, KEY_PAGEUP,
EV_KEY, KEY_LEFT,
EV_KEY, KEY_RIGHT,
EV_KEY, KEY_END,
EV_KEY, KEY_DOWN,
EV_KEY, KEY_PAGEDOWN,
EV_KEY, KEY_INSERT,
EV_KEY, KEY_DELETE,
EV_KEY, KEY_MUTE,
EV_KEY, KEY_VOLUMEDOWN,
EV_KEY, KEY_VOLUMEUP,
EV_KEY, KEY_POWER,
EV_KEY, KEY_PAUSE,
EV_KEY, KEY_STOP,
EV_KEY, KEY_PROPS,
EV_KEY, KEY_UNDO,
EV_KEY, KEY_COPY,
EV_KEY, KEY_OPEN,
EV_KEY, KEY_PASTE,
EV_KEY, KEY_FIND,
EV_KEY, KEY_CUT,
EV_KEY, KEY_HELP,
EV_KEY, KEY_MENU,
EV_KEY, KEY_CALC,
EV_KEY, KEY_SLEEP,
EV_KEY, KEY_WAKEUP,
EV_KEY, KEY_FILE,
EV_KEY, KEY_WWW,
EV_KEY, KEY_COFFEE,
EV_KEY, KEY_MAIL,
EV_KEY, KEY_BOOKMARKS,
EV_KEY, KEY_BACK,
EV_KEY, KEY_FORWARD,
EV_KEY, KEY_EJECTCD,
EV_KEY, KEY_NEXTSONG,
EV_KEY, KEY_PLAYPAUSE,
EV_KEY, KEY_PREVIOUSSONG,
EV_KEY, KEY_STOPCD,
EV_KEY, KEY_RECORD,
EV_KEY, KEY_REWIND,
EV_KEY, KEY_PHONE,
EV_KEY, KEY_CONFIG,
EV_KEY, KEY_HOMEPAGE,
EV_KEY, KEY_REFRESH,
EV_KEY, KEY_EXIT,
EV_KEY, KEY_EDIT,
EV_KEY, KEY_SCROLLUP,
EV_KEY, KEY_SCROLLDOWN,
EV_KEY, KEY_NEW,
EV_KEY, KEY_REDO,
EV_KEY, KEY_CLOSE,
EV_KEY, KEY_PLAY,
EV_KEY, KEY_FASTFORWARD,
EV_KEY, KEY_BASSBOOST,
EV_KEY, KEY_PRINT,
EV_KEY, KEY_CAMERA,
EV_KEY, KEY_CHAT,
EV_KEY, KEY_SEARCH,
EV_KEY, KEY_FINANCE,
EV_KEY, KEY_BRIGHTNESSDOWN,
EV_KEY, KEY_BRIGHTNESSUP,
EV_KEY, KEY_KBDILLUMTOGGLE,
EV_KEY, KEY_SAVE,
EV_KEY, KEY_DOCUMENTS,
EV_KEY, KEY_UNKNOWN,
EV_KEY, KEY_VIDEO_NEXT,
EV_KEY, KEY_BRIGHTNESS_AUTO,
EV_KEY, BTN_0,
EV_KEY, KEY_SELECT,
EV_KEY, KEY_GOTO,
EV_KEY, KEY_INFO,
EV_KEY, KEY_PROGRAM,
EV_KEY, KEY_PVR,
EV_KEY, KEY_SUBTITLE,
EV_KEY, KEY_ZOOM,
EV_KEY, KEY_KEYBOARD,
EV_KEY, KEY_PC,
EV_KEY, KEY_TV,
EV_KEY, KEY_TV2,
EV_KEY, KEY_VCR,
EV_KEY, KEY_VCR2,
EV_KEY, KEY_SAT,
EV_KEY, KEY_CD,
EV_KEY, KEY_TAPE,
EV_KEY, KEY_TUNER,
EV_KEY, KEY_PLAYER,
EV_KEY, KEY_DVD,
EV_KEY, KEY_AUDIO,
EV_KEY, KEY_VIDEO,
EV_KEY, KEY_MEMO,
EV_KEY, KEY_CALENDAR,
EV_KEY, KEY_RED,
EV_KEY, KEY_GREEN,
EV_KEY, KEY_YELLOW,
EV_KEY, KEY_BLUE,
EV_KEY, KEY_CHANNELUP,
EV_KEY, KEY_CHANNELDOWN,
EV_KEY, KEY_LAST,
EV_KEY, KEY_NEXT,
EV_KEY, KEY_RESTART,
EV_KEY, KEY_SLOW,
EV_KEY, KEY_SHUFFLE,
EV_KEY, KEY_PREVIOUS,
EV_KEY, KEY_VIDEOPHONE,
EV_KEY, KEY_GAMES,
EV_KEY, KEY_ZOOMIN,
EV_KEY, KEY_ZOOMOUT,
EV_KEY, KEY_ZOOMRESET,
EV_KEY, KEY_WORDPROCESSOR,
EV_KEY, KEY_EDITOR,
EV_KEY, KEY_SPREADSHEET,
EV_KEY, KEY_GRAPHICSEDITOR,
EV_KEY, KEY_PRESENTATION,
EV_KEY, KEY_DATABASE,
EV_KEY, KEY_NEWS,
EV_KEY, KEY_VOICEMAIL,
EV_KEY, KEY_ADDRESSBOOK,
EV_KEY, KEY_MESSENGER,
EV_KEY, KEY_DISPLAYTOGGLE,
EV_KEY, KEY_SPELLCHECK,
EV_KEY, KEY_LOGOFF,
EV_KEY, KEY_MEDIA_REPEAT,
EV_KEY, KEY_IMAGES,
EV_KEY, KEY_BUTTONCONFIG,
EV_KEY, KEY_TASKMANAGER,
EV_KEY, KEY_JOURNAL,
EV_KEY, KEY_CONTROLPANEL,
EV_KEY, KEY_APPSELECT,
EV_KEY, KEY_SCREENSAVER,
EV_KEY, KEY_VOICECOMMAND,
EV_KEY, KEY_BRIGHTNESS_MIN,
EV_KEY, KEY_BRIGHTNESS_MAX,
EV_KEY, KEY_KBDINPUTASSIST_PREV,
EV_KEY, KEY_KBDINPUTASSIST_NEXT,
EV_KEY, KEY_KBDINPUTASSIST_PREVGROUP,
EV_KEY, KEY_KBDINPUTASSIST_NEXTGROUP,
EV_KEY, KEY_KBDINPUTASSIST_ACCEPT,
EV_KEY, KEY_KBDINPUTASSIST_CANCEL,
EV_MSC, MSC_SCAN,
-1 , -1,
};
static struct input_absinfo absinfo[] = {
{ ABS_VOLUME, 0, 4096, 0, 0, 0 },
{ ABS_MISC, 0, 255, 0, 0, 0 },
{ 0x29, 0, 255, 0, 0, 0 },
{ 0x2a, 0, 255, 0, 0, 0 },
{ 0x2b, 0, 255, 0, 0, 0 },
{ 0x2c, 0, 255, 0, 0, 0 },
{ 0x2d, 0, 255, 0, 0, 0 },
{ 0x2e, 0, 255, 0, 0, 0 },
{ ABS_MT_SLOT, 0, 255, 0, 0, 0 },
{ ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0, 0 },
{ ABS_MT_TOUCH_MINOR, 0, 255, 0, 0, 0 },
{ ABS_MT_WIDTH_MINOR, 0, 255, 0, 0, 0 },
{ ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0, 0 },
{ ABS_MT_ORIENTATION, 0, 255, 0, 0, 0 },
{ ABS_MT_POSITION_X, 0, 255, 0, 0, 0 },
{ .value = -1 },
};
struct litest_test_device litest_anker_mouse_kbd_device = {
.type = LITEST_ANKER_MOUSE_KBD,
.features = LITEST_KEYS | LITEST_WHEEL,
.shortname = "anker_kbd",
.setup = litest_anker_mouse_kbd_setup,
.interface = NULL,
.name = "USB Laser Game Mouse",
.id = &input_id,
.absinfo = absinfo,
.events = events,
};

View file

@ -0,0 +1,239 @@
/*
* Copyright © 2015 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "litest.h"
#include "litest-int.h"
static void litest_apple_keyboard_setup(void)
{
struct litest_device *d = litest_create_device(LITEST_APPLE_KEYBOARD);
litest_set_current_device(d);
}
static struct input_id input_id = {
.bustype = 0x3,
.vendor = 0x5ac,
.product = 0x273,
};
static int events[] = {
EV_KEY, KEY_ESC,
EV_KEY, KEY_1,
EV_KEY, KEY_2,
EV_KEY, KEY_3,
EV_KEY, KEY_4,
EV_KEY, KEY_5,
EV_KEY, KEY_6,
EV_KEY, KEY_7,
EV_KEY, KEY_8,
EV_KEY, KEY_9,
EV_KEY, KEY_0,
EV_KEY, KEY_MINUS,
EV_KEY, KEY_EQUAL,
EV_KEY, KEY_BACKSPACE,
EV_KEY, KEY_TAB,
EV_KEY, KEY_Q,
EV_KEY, KEY_W,
EV_KEY, KEY_E,
EV_KEY, KEY_R,
EV_KEY, KEY_T,
EV_KEY, KEY_Y,
EV_KEY, KEY_U,
EV_KEY, KEY_I,
EV_KEY, KEY_O,
EV_KEY, KEY_P,
EV_KEY, KEY_LEFTBRACE,
EV_KEY, KEY_RIGHTBRACE,
EV_KEY, KEY_ENTER,
EV_KEY, KEY_LEFTCTRL,
EV_KEY, KEY_A,
EV_KEY, KEY_S,
EV_KEY, KEY_D,
EV_KEY, KEY_F,
EV_KEY, KEY_G,
EV_KEY, KEY_H,
EV_KEY, KEY_J,
EV_KEY, KEY_K,
EV_KEY, KEY_L,
EV_KEY, KEY_SEMICOLON,
EV_KEY, KEY_APOSTROPHE,
EV_KEY, KEY_GRAVE,
EV_KEY, KEY_LEFTSHIFT,
EV_KEY, KEY_BACKSLASH,
EV_KEY, KEY_Z,
EV_KEY, KEY_X,
EV_KEY, KEY_C,
EV_KEY, KEY_V,
EV_KEY, KEY_B,
EV_KEY, KEY_N,
EV_KEY, KEY_M,
EV_KEY, KEY_COMMA,
EV_KEY, KEY_DOT,
EV_KEY, KEY_SLASH,
EV_KEY, KEY_RIGHTSHIFT,
EV_KEY, KEY_KPASTERISK,
EV_KEY, KEY_LEFTALT,
EV_KEY, KEY_SPACE,
EV_KEY, KEY_CAPSLOCK,
EV_KEY, KEY_F1,
EV_KEY, KEY_F2,
EV_KEY, KEY_F3,
EV_KEY, KEY_F4,
EV_KEY, KEY_F5,
EV_KEY, KEY_F6,
EV_KEY, KEY_F7,
EV_KEY, KEY_F8,
EV_KEY, KEY_F9,
EV_KEY, KEY_F10,
EV_KEY, KEY_NUMLOCK,
EV_KEY, KEY_SCROLLLOCK,
EV_KEY, KEY_KP7,
EV_KEY, KEY_KP8,
EV_KEY, KEY_KP9,
EV_KEY, KEY_KPMINUS,
EV_KEY, KEY_KP4,
EV_KEY, KEY_KP5,
EV_KEY, KEY_KP6,
EV_KEY, KEY_KPPLUS,
EV_KEY, KEY_KP1,
EV_KEY, KEY_KP2,
EV_KEY, KEY_KP3,
EV_KEY, KEY_KP0,
EV_KEY, KEY_KPDOT,
EV_KEY, KEY_ZENKAKUHANKAKU,
EV_KEY, KEY_102ND,
EV_KEY, KEY_F11,
EV_KEY, KEY_F12,
EV_KEY, KEY_RO,
EV_KEY, KEY_KATAKANA,
EV_KEY, KEY_HIRAGANA,
EV_KEY, KEY_HENKAN,
EV_KEY, KEY_KATAKANAHIRAGANA,
EV_KEY, KEY_MUHENKAN,
EV_KEY, KEY_KPJPCOMMA,
EV_KEY, KEY_KPENTER,
EV_KEY, KEY_RIGHTCTRL,
EV_KEY, KEY_KPSLASH,
EV_KEY, KEY_SYSRQ,
EV_KEY, KEY_RIGHTALT,
EV_KEY, KEY_HOME,
EV_KEY, KEY_UP,
EV_KEY, KEY_PAGEUP,
EV_KEY, KEY_LEFT,
EV_KEY, KEY_RIGHT,
EV_KEY, KEY_END,
EV_KEY, KEY_DOWN,
EV_KEY, KEY_PAGEDOWN,
EV_KEY, KEY_INSERT,
EV_KEY, KEY_DELETE,
EV_KEY, KEY_MUTE,
EV_KEY, KEY_VOLUMEDOWN,
EV_KEY, KEY_VOLUMEUP,
EV_KEY, KEY_POWER,
EV_KEY, KEY_KPEQUAL,
EV_KEY, KEY_PAUSE,
EV_KEY, KEY_SCALE,
EV_KEY, KEY_KPCOMMA,
EV_KEY, KEY_HANGEUL,
EV_KEY, KEY_HANJA,
EV_KEY, KEY_YEN,
EV_KEY, KEY_LEFTMETA,
EV_KEY, KEY_RIGHTMETA,
EV_KEY, KEY_COMPOSE,
EV_KEY, KEY_STOP,
EV_KEY, KEY_AGAIN,
EV_KEY, KEY_PROPS,
EV_KEY, KEY_UNDO,
EV_KEY, KEY_FRONT,
EV_KEY, KEY_COPY,
EV_KEY, KEY_OPEN,
EV_KEY, KEY_PASTE,
EV_KEY, KEY_FIND,
EV_KEY, KEY_CUT,
EV_KEY, KEY_HELP,
EV_KEY, KEY_CALC,
EV_KEY, KEY_SLEEP,
EV_KEY, KEY_WWW,
EV_KEY, KEY_COFFEE,
EV_KEY, KEY_BACK,
EV_KEY, KEY_FORWARD,
EV_KEY, KEY_EJECTCD,
EV_KEY, KEY_NEXTSONG,
EV_KEY, KEY_PLAYPAUSE,
EV_KEY, KEY_PREVIOUSSONG,
EV_KEY, KEY_STOPCD,
EV_KEY, KEY_REWIND,
EV_KEY, KEY_REFRESH,
EV_KEY, KEY_EDIT,
EV_KEY, KEY_SCROLLUP,
EV_KEY, KEY_SCROLLDOWN,
EV_KEY, KEY_KPLEFTPAREN,
EV_KEY, KEY_KPRIGHTPAREN,
EV_KEY, KEY_F13,
EV_KEY, KEY_F14,
EV_KEY, KEY_F15,
EV_KEY, KEY_F16,
EV_KEY, KEY_F17,
EV_KEY, KEY_F18,
EV_KEY, KEY_F19,
EV_KEY, KEY_F20,
EV_KEY, KEY_F21,
EV_KEY, KEY_F22,
EV_KEY, KEY_F23,
EV_KEY, KEY_F24,
EV_KEY, KEY_DASHBOARD,
EV_KEY, KEY_FASTFORWARD,
EV_KEY, KEY_BRIGHTNESSDOWN,
EV_KEY, KEY_BRIGHTNESSUP,
EV_KEY, KEY_SWITCHVIDEOMODE,
EV_KEY, KEY_KBDILLUMTOGGLE,
EV_KEY, KEY_KBDILLUMDOWN,
EV_KEY, KEY_KBDILLUMUP,
EV_KEY, KEY_UNKNOWN,
EV_KEY, KEY_FN,
EV_MSC, MSC_SCAN,
EV_LED, LED_NUML,
EV_LED, LED_CAPSL,
EV_LED, LED_SCROLLL,
EV_LED, LED_COMPOSE,
EV_LED, LED_KANA,
-1, -1
};
struct litest_test_device litest_apple_keyboard_device = {
.type = LITEST_APPLE_KEYBOARD,
.features = LITEST_KEYS,
.shortname = "apple_keyboard",
.setup = litest_apple_keyboard_setup,
.interface = NULL,
.name = "Apple Inc. Apple Internal Keyboard / Trackpad",
.id = &input_id,
.events = events,
.absinfo = NULL,
};

View file

@ -0,0 +1,71 @@
/*
* Copyright © 2013 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "litest.h"
#include "litest-int.h"
static void litest_cyborg_rat_setup(void)
{
struct litest_device *d = litest_create_device(LITEST_CYBORG_RAT);
litest_set_current_device(d);
}
static struct input_id input_id = {
.bustype = 0x3,
.vendor = 0x6a3,
.product = 0xcd5,
};
static int events[] = {
EV_KEY, BTN_LEFT,
EV_KEY, BTN_RIGHT,
EV_KEY, BTN_MIDDLE,
EV_KEY, BTN_SIDE,
EV_KEY, BTN_EXTRA,
EV_KEY, BTN_FORWARD,
EV_KEY, BTN_TASK,
EV_KEY, 0x118,
EV_KEY, 0x119,
EV_KEY, 0x11a,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_REL, REL_WHEEL,
-1 , -1,
};
struct litest_test_device litest_cyborg_rat_device = {
.type = LITEST_CYBORG_RAT,
.features = LITEST_RELATIVE | LITEST_BUTTON | LITEST_WHEEL,
.shortname = "cyborg_rat",
.setup = litest_cyborg_rat_setup,
.interface = NULL,
.name = "Saitek Cyborg R.A.T.5 Mouse",
.id = &input_id,
.absinfo = NULL,
.events = events,
};

View file

@ -0,0 +1,102 @@
/*
* Copyright © 2015 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "litest.h"
#include "litest-int.h"
static void
litest_synaptics_i2c_setup(void)
{
struct litest_device *d = litest_create_device(LITEST_SYNAPTICS_I2C);
litest_set_current_device(d);
}
static struct input_event down[] = {
{ .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_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 },
};
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_SYN, .code = SYN_REPORT, .value = 0 },
{ .type = -1, .code = -1 },
};
static struct litest_device_interface interface = {
.touch_down_events = down,
.touch_move_events = move,
};
static struct input_id input_id = {
.bustype = 0x18,
.vendor = 0x6cb,
.product = 0x76ad,
};
static int events[] = {
EV_KEY, BTN_LEFT,
EV_KEY, BTN_TOOL_FINGER,
EV_KEY, BTN_TOUCH,
EV_KEY, BTN_TOOL_DOUBLETAP,
EV_KEY, BTN_TOOL_TRIPLETAP,
INPUT_PROP_MAX, INPUT_PROP_POINTER,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1, -1,
};
static struct input_absinfo absinfo[] = {
{ ABS_X, 0, 1216, 0, 0, 12 },
{ ABS_Y, 0, 680, 0, 0, 12 },
{ ABS_MT_SLOT, 0, 1, 0, 0, 0 },
{ ABS_MT_POSITION_X, 0, 1216, 0, 0, 12 },
{ ABS_MT_POSITION_Y, 0, 680, 0, 0, 12 },
{ ABS_MT_TRACKING_ID, 0, 65535, 0, 0, 0 },
{ .value = -1 }
};
struct litest_test_device litest_synaptics_i2c_device = {
.type = LITEST_SYNAPTICS_I2C,
.features = LITEST_TOUCHPAD | LITEST_CLICKPAD | LITEST_BUTTON,
.shortname = "synaptics-i2c",
.setup = litest_synaptics_i2c_setup,
.interface = &interface,
.name = "DLL0704:01 06CB:76AD Touchpad",
.id = &input_id,
.events = events,
.absinfo = absinfo,
};

View file

@ -0,0 +1,169 @@
/*
* Copyright © 2014 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "litest.h"
#include "litest-int.h"
static void litest_yubikey_setup(void)
{
struct litest_device *d = litest_create_device(LITEST_YUBIKEY);
litest_set_current_device(d);
}
static struct input_id input_id = {
.bustype = 0x3,
.vendor = 0x1050,
.product = 0x10,
};
static int events[] = {
EV_KEY, KEY_ESC,
EV_KEY, KEY_1,
EV_KEY, KEY_2,
EV_KEY, KEY_3,
EV_KEY, KEY_4,
EV_KEY, KEY_5,
EV_KEY, KEY_6,
EV_KEY, KEY_7,
EV_KEY, KEY_8,
EV_KEY, KEY_9,
EV_KEY, KEY_0,
EV_KEY, KEY_MINUS,
EV_KEY, KEY_EQUAL,
EV_KEY, KEY_BACKSPACE,
EV_KEY, KEY_TAB,
EV_KEY, KEY_Q,
EV_KEY, KEY_W,
EV_KEY, KEY_E,
EV_KEY, KEY_R,
EV_KEY, KEY_T,
EV_KEY, KEY_Y,
EV_KEY, KEY_U,
EV_KEY, KEY_I,
EV_KEY, KEY_O,
EV_KEY, KEY_P,
EV_KEY, KEY_LEFTBRACE,
EV_KEY, KEY_RIGHTBRACE,
EV_KEY, KEY_ENTER,
EV_KEY, KEY_LEFTCTRL,
EV_KEY, KEY_A,
EV_KEY, KEY_S,
EV_KEY, KEY_D,
EV_KEY, KEY_F,
EV_KEY, KEY_G,
EV_KEY, KEY_H,
EV_KEY, KEY_J,
EV_KEY, KEY_K,
EV_KEY, KEY_L,
EV_KEY, KEY_SEMICOLON,
EV_KEY, KEY_APOSTROPHE,
EV_KEY, KEY_GRAVE,
EV_KEY, KEY_LEFTSHIFT,
EV_KEY, KEY_BACKSLASH,
EV_KEY, KEY_Z,
EV_KEY, KEY_X,
EV_KEY, KEY_C,
EV_KEY, KEY_V,
EV_KEY, KEY_B,
EV_KEY, KEY_N,
EV_KEY, KEY_M,
EV_KEY, KEY_COMMA,
EV_KEY, KEY_DOT,
EV_KEY, KEY_SLASH,
EV_KEY, KEY_RIGHTSHIFT,
EV_KEY, KEY_KPASTERISK,
EV_KEY, KEY_LEFTALT,
EV_KEY, KEY_SPACE,
EV_KEY, KEY_CAPSLOCK,
EV_KEY, KEY_F1,
EV_KEY, KEY_F2,
EV_KEY, KEY_F3,
EV_KEY, KEY_F4,
EV_KEY, KEY_F5,
EV_KEY, KEY_F6,
EV_KEY, KEY_F7,
EV_KEY, KEY_F8,
EV_KEY, KEY_F9,
EV_KEY, KEY_F10,
EV_KEY, KEY_NUMLOCK,
EV_KEY, KEY_SCROLLLOCK,
EV_KEY, KEY_KP7,
EV_KEY, KEY_KP8,
EV_KEY, KEY_KP9,
EV_KEY, KEY_KPMINUS,
EV_KEY, KEY_KP4,
EV_KEY, KEY_KP5,
EV_KEY, KEY_KP6,
EV_KEY, KEY_KPPLUS,
EV_KEY, KEY_KP1,
EV_KEY, KEY_KP2,
EV_KEY, KEY_KP3,
EV_KEY, KEY_KP0,
EV_KEY, KEY_KPDOT,
EV_KEY, KEY_102ND,
EV_KEY, KEY_F11,
EV_KEY, KEY_F12,
EV_KEY, KEY_KPENTER,
EV_KEY, KEY_RIGHTCTRL,
EV_KEY, KEY_KPSLASH,
EV_KEY, KEY_SYSRQ,
EV_KEY, KEY_RIGHTALT,
EV_KEY, KEY_HOME,
EV_KEY, KEY_UP,
EV_KEY, KEY_PAGEUP,
EV_KEY, KEY_LEFT,
EV_KEY, KEY_RIGHT,
EV_KEY, KEY_END,
EV_KEY, KEY_DOWN,
EV_KEY, KEY_PAGEDOWN,
EV_KEY, KEY_INSERT,
EV_KEY, KEY_DELETE,
EV_KEY, KEY_PAUSE,
EV_KEY, KEY_LEFTMETA,
EV_KEY, KEY_RIGHTMETA,
EV_KEY, KEY_COMPOSE,
EV_LED, LED_NUML,
EV_LED, LED_CAPSL,
EV_LED, LED_SCROLLL,
EV_LED, LED_COMPOSE,
EV_LED, LED_KANA,
-1, -1,
};
struct litest_test_device litest_yubikey_device = {
.type = LITEST_YUBIKEY,
.features = LITEST_KEYS,
.shortname = "yubikey",
.setup = litest_yubikey_setup,
.interface = NULL,
.name = "Yubico Yubico Yubikey II",
.id = &input_id,
.events = events,
.absinfo = NULL,
};

View file

@ -169,8 +169,8 @@ START_TEST(litest_ptr_eq_notrigger)
int v = 10;
int *a = &v;
int *b = &v;
int c = NULL;
int d = NULL;
int *c = NULL;
int *d = NULL;
litest_assert_ptr_eq(a, b);
litest_assert_ptr_eq(c, d);

View file

@ -367,6 +367,11 @@ extern struct litest_test_device litest_magicpad_device;
extern struct litest_test_device litest_elantech_touchpad_device;
extern struct litest_test_device litest_mouse_gladius_device;
extern struct litest_test_device litest_mouse_wheel_click_angle_device;
extern struct litest_test_device litest_apple_keyboard_device;
extern struct litest_test_device litest_anker_mouse_kbd_device;
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;
struct litest_test_device* devices[] = {
&litest_synaptics_clickpad_device,
@ -400,6 +405,11 @@ struct litest_test_device* devices[] = {
&litest_elantech_touchpad_device,
&litest_mouse_gladius_device,
&litest_mouse_wheel_click_angle_device,
&litest_apple_keyboard_device,
&litest_anker_mouse_kbd_device,
&litest_cyborg_rat_device,
&litest_yubikey_device,
&litest_synaptics_i2c_device,
NULL,
};
@ -1234,6 +1244,7 @@ litest_delete_device(struct litest_device *d)
libinput_path_remove_device(d->libinput_device);
if (d->owns_context)
libinput_unref(d->libinput);
close(libevdev_get_fd(d->evdev));
libevdev_free(d->evdev);
libevdev_uinput_destroy(d->uinput);
free(d->private);
@ -1496,18 +1507,22 @@ litest_touch_move_two_touches(struct litest_device *d,
int steps, int sleep_ms)
{
for (int i = 0; i < steps - 1; i++) {
litest_push_event_frame(d);
litest_touch_move(d, 0, x0 + dx / steps * i,
y0 + dy / steps * i);
litest_touch_move(d, 1, x1 + dx / steps * i,
y1 + dy / steps * i);
litest_pop_event_frame(d);
if (sleep_ms) {
libinput_dispatch(d->libinput);
msleep(sleep_ms);
}
libinput_dispatch(d->libinput);
}
litest_push_event_frame(d);
litest_touch_move(d, 0, x0 + dx, y0 + dy);
litest_touch_move(d, 1, x1 + dx, y1 + dy);
litest_pop_event_frame(d);
}
void

View file

@ -144,6 +144,11 @@ enum litest_device_type {
LITEST_ELANTECH_TOUCHPAD = -30,
LITEST_MOUSE_GLADIUS = -31,
LITEST_MOUSE_WHEEL_CLICK_ANGLE = -32,
LITEST_APPLE_KEYBOARD = -33,
LITEST_ANKER_MOUSE_KBD = -34,
LITEST_CYBORG_RAT = -41,
LITEST_YUBIKEY = -42,
LITEST_SYNAPTICS_I2C = -43,
};
enum litest_device_feature {
@ -550,16 +555,6 @@ litest_enable_buttonareas(struct litest_device *dev)
litest_assert_int_eq(status, expected);
}
static inline int
litest_is_synaptics_semi_mt(struct litest_device *dev)
{
struct libevdev *evdev = dev->evdev;
return libevdev_has_property(evdev, INPUT_PROP_SEMI_MT) &&
libevdev_get_id_vendor(evdev) == 0x2 &&
libevdev_get_id_product(evdev) == 0x7;
}
static inline void
litest_enable_drag_lock(struct libinput_device *device)
{

View file

@ -241,7 +241,7 @@ START_TEST(touchpad_1fg_multitap_n_drag_2fg)
int range = _i,
ntaps;
if (litest_is_synaptics_semi_mt(dev))
if (libevdev_has_property(dev->evdev, INPUT_PROP_SEMI_MT))
return;
litest_enable_tap(dev->libinput_device);

View file

@ -1031,7 +1031,7 @@ START_TEST(touchpad_palm_detect_no_palm_moving_into_edges)
}
END_TEST
START_TEST(touchpad_palm_detect_tap)
START_TEST(touchpad_palm_detect_tap_hardbuttons)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
@ -1051,7 +1051,38 @@ START_TEST(touchpad_palm_detect_tap)
litest_touch_up(dev, 0);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 5, 90);
litest_touch_down(dev, 0, 5, 99);
litest_touch_up(dev, 0);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 95, 99);
litest_touch_up(dev, 0);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(touchpad_palm_detect_tap_softbuttons)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (!touchpad_has_palm_detect_size(dev))
return;
litest_enable_tap(dev->libinput_device);
litest_enable_buttonareas(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 95, 5);
litest_touch_up(dev, 0);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 5, 5);
litest_touch_up(dev, 0);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 5, 99);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_LEFT,
@ -1061,7 +1092,7 @@ START_TEST(touchpad_palm_detect_tap)
LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 95, 90);
litest_touch_down(dev, 0, 95, 99);
litest_touch_up(dev, 0);
litest_assert_button_event(li,
BTN_LEFT,
@ -1073,6 +1104,37 @@ START_TEST(touchpad_palm_detect_tap)
}
END_TEST
START_TEST(touchpad_palm_detect_tap_clickfinger)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (!touchpad_has_palm_detect_size(dev))
return;
litest_enable_tap(dev->libinput_device);
litest_enable_clickfinger(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 95, 5);
litest_touch_up(dev, 0);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 5, 5);
litest_touch_up(dev, 0);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 5, 99);
litest_touch_up(dev, 0);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 95, 99);
litest_touch_up(dev, 0);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(touchpad_left_handed)
{
struct litest_device *dev = litest_current_device();
@ -2282,6 +2344,18 @@ has_disable_while_typing(struct litest_device *device)
return libinput_device_config_dwt_is_available(device->libinput_device);
}
static inline struct litest_device *
dwt_init_paired_keyboard(struct libinput *li,
struct litest_device *touchpad)
{
enum litest_device_type which = LITEST_KEYBOARD;
if (libevdev_get_id_vendor(touchpad->evdev) == VENDOR_ID_APPLE)
which = LITEST_APPLE_KEYBOARD;
return litest_add_device(li, which);
}
START_TEST(touchpad_dwt)
{
struct litest_device *touchpad = litest_current_device();
@ -2291,7 +2365,7 @@ START_TEST(touchpad_dwt)
if (!has_disable_while_typing(touchpad))
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2324,6 +2398,106 @@ START_TEST(touchpad_dwt)
}
END_TEST
START_TEST(touchpad_dwt_update_keyboard)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *keyboard, *yubikey;
struct libinput *li = touchpad->libinput;
if (!has_disable_while_typing(touchpad))
return;
litest_disable_tap(touchpad->libinput_device);
/* Yubikey is initialized first */
yubikey = litest_add_device(li, LITEST_YUBIKEY);
litest_drain_events(li);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
litest_keyboard_key(keyboard, KEY_A, false);
libinput_dispatch(li);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
/* within timeout - no events */
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
litest_timeout_dwt_short();
libinput_dispatch(li);
/* after timeout - motion events*/
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
litest_delete_device(keyboard);
litest_delete_device(yubikey);
}
END_TEST
START_TEST(touchpad_dwt_update_keyboard_with_state)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *keyboard, *yubikey;
struct libinput *li = touchpad->libinput;
if (!has_disable_while_typing(touchpad))
return;
litest_disable_tap(touchpad->libinput_device);
/* Yubikey is initialized first */
yubikey = litest_add_device(li, LITEST_YUBIKEY);
litest_drain_events(li);
litest_keyboard_key(yubikey, KEY_A, true);
litest_keyboard_key(yubikey, KEY_A, false);
litest_keyboard_key(yubikey, KEY_A, true);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
litest_keyboard_key(yubikey, KEY_A, false);
litest_keyboard_key(yubikey, KEY_A, true);
litest_drain_events(li);
/* yubikey still has A down */
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_drain_events(li);
/* expected repairing, dwt should be disabled */
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
/* release remaining key */
litest_keyboard_key(yubikey, KEY_A, false);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
litest_delete_device(keyboard);
litest_delete_device(yubikey);
}
END_TEST
START_TEST(touchpad_dwt_enable_touch)
{
struct litest_device *touchpad = litest_current_device();
@ -2333,7 +2507,7 @@ START_TEST(touchpad_dwt_enable_touch)
if (!has_disable_while_typing(touchpad))
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2371,7 +2545,7 @@ START_TEST(touchpad_dwt_touch_hold)
if (!has_disable_while_typing(touchpad))
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2408,7 +2582,7 @@ START_TEST(touchpad_dwt_key_hold)
if (!has_disable_while_typing(touchpad))
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2426,6 +2600,145 @@ START_TEST(touchpad_dwt_key_hold)
}
END_TEST
START_TEST(touchpad_dwt_key_hold_timeout)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *keyboard;
struct libinput *li = touchpad->libinput;
if (!has_disable_while_typing(touchpad))
return;
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
libinput_dispatch(li);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
litest_timeout_dwt_long();
libinput_dispatch(li);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
litest_keyboard_key(keyboard, KEY_A, false);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
/* key is up, but still within timeout */
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
/* expire timeout */
litest_timeout_dwt_long();
libinput_dispatch(li);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
litest_touch_up(touchpad, 0);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
litest_delete_device(keyboard);
}
END_TEST
START_TEST(touchpad_dwt_key_hold_timeout_existing_touch_cornercase)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *keyboard;
struct libinput *li = touchpad->libinput;
if (!has_disable_while_typing(touchpad))
return;
/* Note: this tests for the current behavior of a cornercase, and
* the behaviour is essentially a bug. If this test fails it may be
* because the buggy behavior was fixed.
*/
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
libinput_dispatch(li);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
litest_timeout_dwt_long();
libinput_dispatch(li);
/* Touch starting after re-issuing the dwt timeout */
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
litest_assert_empty_queue(li);
litest_keyboard_key(keyboard, KEY_A, false);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
/* key is up, but still within timeout */
litest_touch_move_to(touchpad, 0, 70, 50, 50, 50, 5, 1);
litest_assert_empty_queue(li);
/* Expire dwt timeout. Because the touch started after re-issuing
* the last timeout, it looks like the touch started after the last
* key press. Such touches are enabled for pointer motion by
* libinput when dwt expires.
* This is buggy behavior and not what a user would typically
* expect. But it's hard to trigger in real life too.
*/
litest_timeout_dwt_long();
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
litest_touch_up(touchpad, 0);
/* If the below check for motion event fails because no events are
* in the pipe, the buggy behavior was fixed and this test case
* can be removed */
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
litest_delete_device(keyboard);
}
END_TEST
START_TEST(touchpad_dwt_key_hold_timeout_existing_touch)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *keyboard;
struct libinput *li = touchpad->libinput;
if (!has_disable_while_typing(touchpad))
return;
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
libinput_dispatch(li);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
libinput_dispatch(li);
litest_timeout_dwt_long();
libinput_dispatch(li);
litest_assert_empty_queue(li);
litest_keyboard_key(keyboard, KEY_A, false);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
/* key is up, but still within timeout */
litest_touch_move_to(touchpad, 0, 70, 50, 50, 50, 5, 1);
litest_assert_empty_queue(li);
/* expire timeout, but touch started before release */
litest_timeout_dwt_long();
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
litest_delete_device(keyboard);
}
END_TEST
START_TEST(touchpad_dwt_type)
{
struct litest_device *touchpad = litest_current_device();
@ -2436,7 +2749,7 @@ START_TEST(touchpad_dwt_type)
if (!has_disable_while_typing(touchpad))
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2474,7 +2787,7 @@ START_TEST(touchpad_dwt_type_short_timeout)
if (!has_disable_while_typing(touchpad))
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2511,7 +2824,7 @@ START_TEST(touchpad_dwt_tap)
if (!has_disable_while_typing(touchpad))
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_enable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2541,7 +2854,7 @@ START_TEST(touchpad_dwt_tap_drag)
if (!has_disable_while_typing(touchpad))
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_enable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2575,7 +2888,7 @@ START_TEST(touchpad_dwt_click)
if (!has_disable_while_typing(touchpad))
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2608,7 +2921,7 @@ START_TEST(touchpad_dwt_edge_scroll)
litest_enable_edge_scroll(touchpad);
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
@ -2655,7 +2968,7 @@ START_TEST(touchpad_dwt_edge_scroll_interrupt)
litest_enable_edge_scroll(touchpad);
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_drain_events(li);
litest_touch_down(touchpad, 0, 99, 20);
@ -2779,7 +3092,7 @@ START_TEST(touchpad_dwt_disabled)
disable_dwt(touchpad);
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2808,7 +3121,7 @@ START_TEST(touchpad_dwt_disable_during_touch)
enable_dwt(touchpad);
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2843,7 +3156,7 @@ START_TEST(touchpad_dwt_disable_before_touch)
enable_dwt(touchpad);
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2863,6 +3176,72 @@ START_TEST(touchpad_dwt_disable_before_touch)
}
END_TEST
START_TEST(touchpad_dwt_disable_during_key_release)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *keyboard;
struct libinput *li = touchpad->libinput;
if (!has_disable_while_typing(touchpad))
return;
enable_dwt(touchpad);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
disable_dwt(touchpad);
libinput_dispatch(li);
litest_keyboard_key(keyboard, KEY_A, false);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
/* touch down during timeout, wait, should generate events */
litest_touch_down(touchpad, 0, 50, 50);
libinput_dispatch(li);
litest_timeout_dwt_long();
litest_touch_move_to(touchpad, 0, 70, 50, 50, 50, 10, 1);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
litest_delete_device(keyboard);
}
END_TEST
START_TEST(touchpad_dwt_disable_during_key_hold)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *keyboard;
struct libinput *li = touchpad->libinput;
if (!has_disable_while_typing(touchpad))
return;
enable_dwt(touchpad);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
disable_dwt(touchpad);
libinput_dispatch(li);
/* touch down during timeout, wait, should generate events */
litest_touch_down(touchpad, 0, 50, 50);
libinput_dispatch(li);
litest_timeout_dwt_long();
litest_touch_move_to(touchpad, 0, 70, 50, 50, 50, 10, 1);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
litest_delete_device(keyboard);
}
END_TEST
START_TEST(touchpad_dwt_enable_during_touch)
{
struct litest_device *touchpad = litest_current_device();
@ -2874,7 +3253,7 @@ START_TEST(touchpad_dwt_enable_during_touch)
disable_dwt(touchpad);
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2908,7 +3287,7 @@ START_TEST(touchpad_dwt_enable_before_touch)
disable_dwt(touchpad);
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
@ -2939,7 +3318,7 @@ START_TEST(touchpad_dwt_enable_during_tap)
litest_enable_tap(touchpad->libinput_device);
disable_dwt(touchpad);
keyboard = litest_add_device(li, LITEST_KEYBOARD);
keyboard = dwt_init_paired_keyboard(li, touchpad);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
@ -2964,6 +3343,46 @@ START_TEST(touchpad_dwt_enable_during_tap)
litest_delete_device(keyboard);
}
END_TEST
START_TEST(touchpad_dwt_apple)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *keyboard, *apple_keyboard;
struct libinput *li = touchpad->libinput;
ck_assert(has_disable_while_typing(touchpad));
/* Only the apple keyboard can trigger DWT */
keyboard = litest_add_device(li, LITEST_KEYBOARD);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
litest_keyboard_key(keyboard, KEY_A, false);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
apple_keyboard = litest_add_device(li, LITEST_APPLE_KEYBOARD);
litest_drain_events(li);
litest_keyboard_key(apple_keyboard, KEY_A, true);
litest_keyboard_key(apple_keyboard, KEY_A, false);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
libinput_dispatch(li);
litest_assert_empty_queue(li);
litest_delete_device(keyboard);
litest_delete_device(apple_keyboard);
}
END_TEST
static int
has_thumb_detect(struct litest_device *dev)
{
@ -3547,7 +3966,7 @@ litest_setup_tests(void)
litest_add("touchpad:motion", touchpad_1fg_motion, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:motion", touchpad_2fg_no_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:scroll", touchpad_2fg_scroll, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:scroll", touchpad_2fg_scroll, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("touchpad:scroll", touchpad_2fg_scroll_diagonal, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("touchpad:scroll", touchpad_2fg_scroll_slow_distance, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:scroll", touchpad_2fg_scroll_return_to_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
@ -3576,7 +3995,9 @@ litest_setup_tests(void)
litest_add("touchpad:palm", touchpad_palm_detect_palm_becomes_pointer, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:palm", touchpad_palm_detect_palm_stays_palm, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:palm", touchpad_palm_detect_no_palm_moving_into_edges, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:palm", touchpad_palm_detect_tap, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:palm", touchpad_palm_detect_tap_hardbuttons, LITEST_TOUCHPAD, LITEST_CLICKPAD);
litest_add("touchpad:palm", touchpad_palm_detect_tap_softbuttons, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:palm", touchpad_palm_detect_tap_clickfinger, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:palm", touchpad_no_palm_detect_at_edge_for_edge_scrolling, LITEST_TOUCHPAD, LITEST_CLICKPAD);
litest_add("touchpad:left-handed", touchpad_left_handed, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_CLICKPAD);
@ -3614,9 +4035,14 @@ litest_setup_tests(void)
litest_add_ranged("touchpad:state", touchpad_initial_state, LITEST_TOUCHPAD, LITEST_ANY, &axis_range);
litest_add("touchpad:dwt", touchpad_dwt, LITEST_TOUCHPAD, LITEST_ANY);
litest_add_for_device("touchpad:dwt", touchpad_dwt_update_keyboard, LITEST_SYNAPTICS_I2C);
litest_add_for_device("touchpad:dwt", touchpad_dwt_update_keyboard_with_state, LITEST_SYNAPTICS_I2C);
litest_add("touchpad:dwt", touchpad_dwt_enable_touch, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_touch_hold, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_key_hold, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_key_hold_timeout, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_key_hold_timeout_existing_touch, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_key_hold_timeout_existing_touch_cornercase, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_type, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_type_short_timeout, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_tap, LITEST_TOUCHPAD, LITEST_ANY);
@ -3629,9 +4055,12 @@ litest_setup_tests(void)
litest_add("touchpad:dwt", touchpad_dwt_disabled, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_disable_during_touch, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_disable_before_touch, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_disable_during_key_release, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_disable_during_key_hold, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_enable_during_touch, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_enable_before_touch, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_enable_during_tap, LITEST_TOUCHPAD, LITEST_ANY);
litest_add_for_device("touchpad:dwt", touchpad_dwt_apple, LITEST_BCM5974);
litest_add("touchpad:thumb", touchpad_thumb_begin_no_motion, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:thumb", touchpad_thumb_update_no_motion, LITEST_CLICKPAD, LITEST_ANY);

View file

@ -22,10 +22,14 @@ libinput:name:*AlpsPS/2 ALPS DualPoint TouchPad:dmi:*
libinput:name:*AlpsPS/2 ALPS GlidePoint:dmi:*
LIBINPUT_MODEL_ALPS_TOUCHPAD=1
libinput:name:*AlpsPS/2 ALPS DualPoint TouchPad:fwversion:8
libinput:name:*AlpsPS/2 ALPS GlidePoint:fwversion:8
libinput:name:*AlpsPS/2 ALPS DualPoint TouchPad:fwversion:800
libinput:name:*AlpsPS/2 ALPS GlidePoint:fwversion:800
LIBINPUT_ATTR_SIZE_HINT=100x55
libinput:name:*AlpsPS/2 ALPS DualPoint TouchPad:fwversion:310
libinput:name:*AlpsPS/2 ALPS GlidePoint:fwversion:310
LIBINPUT_MODEL_ALPS_RUSHMORE=1
##########################################
# Apple
##########################################
@ -34,6 +38,16 @@ libinput:touchpad:input:b0005v05ACp*
LIBINPUT_MODEL_APPLE_TOUCHPAD=1
LIBINPUT_ATTR_SIZE_HINT=104x75
libinput:name:*Apple Inc. Apple Internal Keyboard*:dmi:*
LIBINPUT_MODEL_APPLE_INTERNAL_KEYBOARD=1
##########################################
# Cyborg
##########################################
# Saitek Cyborg R.A.T.5 Mouse
libinput:mouse:input:b0003v06A3p0CD5*
LIBINPUT_MODEL_CYBORG_RAT=1
##########################################
# Elantech
##########################################
@ -63,6 +77,9 @@ 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
libinput:name:Cypress APA Trackpad (cyapa):dmi:*
LIBINPUT_MODEL_CYAPA=1
##########################################
# LENOVO
##########################################

View file

@ -29,6 +29,10 @@ KERNELS=="*input*", \
ENV{ID_INPUT_TOUCHPAD}=="1", \
IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:touchpad:"
# libinput:mouse:<modalias>
ENV{ID_INPUT_MOUSE}=="1", \
IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:mouse:"
# libinput:name:<name>:dmi:<dmi string>
KERNELS=="input*", \
IMPORT{builtin}="hwdb 'libinput:name:$attr{name}:$attr{[dmi/id]modalias}'"

View file

@ -63,9 +63,9 @@ handle_touchpad_alps(struct udev_device *device)
if (sscanf(product, "%x/%x/%x/%x", &bus, &vid, &pid, &version) != 4)
return;
/* ALPS' firmware version is the PID */
if (pid)
printf("LIBINPUT_MODEL_FIRMWARE_VERSION=%d\n", pid);
/* ALPS' firmware version is the version */
if (version)
printf("LIBINPUT_MODEL_FIRMWARE_VERSION=%x\n", version);
}
static void