Compare commits

...

22 commits
main ... 1.5.4

Author SHA1 Message Date
Peter Hutterer
73b39cee3b configure.ac: libinput 1.5.4
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-01-13 17:39:11 +10:00
Peter Hutterer
089ab53e8a udev: mark Asus X555LAB as touchpad with visible marker
https://bugs.freedesktop.org/show_bug.cgi?id=99200

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 72e01485c0)
2017-01-13 10:45:18 +10:00
Peter Hutterer
aee85d3d42 touchpad: add a model tag to mark touchpads with visible marker
We used to mark dell touchpads this way but let's make this more generic.
Nothing else used the dell touchpad model flag, so we can simply replace it.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 43ba2dbb30)
2017-01-13 10:45:17 +10:00
Peter Hutterer
0e820d466f Remove a couple of double semicolons
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 7b3e583abe)
2017-01-13 10:45:17 +10:00
Peter Hutterer
fd7c27c8b8 tools: add allowed range to --set-speed help output
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 16bf0deb23)
2017-01-13 10:45:17 +10:00
Peter Hutterer
0a910a8ae6 gestures: if fingers don't move, force a gesture by finger position
If the fingers rest on the touchpad without moving for a timeout, switch to
pinch or swipe based on the finger position. We already switched to two-finger
scrolling based on the timeout, now we also do so for 3 and 4 finger gestures.
This gives us better reaction to small movements.

This also fixes previously unreachable code: the test for the finger position
required at least 3 fingers down but was within a condition that ensured only
2 fingers were down. This was introduced in 11917061fe.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit af1e6c08ac)
2017-01-13 10:45:17 +10:00
Peter Hutterer
a89619d792 touchpad: if an external touchpad and keyboard share a VID/PID assume dwt
This requires to expand the blacklisting to be a bit more specific so we don't
initialize dwt config on devices that won't need it.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 0a82d2fa39)
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-01-13 10:45:17 +10:00
Peter Hutterer
6b1428eccd test: use the udev property to check for external/internal touchpads
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit b69cfccdca)
2017-01-13 10:45:17 +10:00
Peter Hutterer
c58268e0c2 test: mark the magic trackpad as external in udev
This should be handled by a udev rule in systemd/hwdb but that rule doesn't
apply to virtual devices.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 5307051386)
2017-01-13 10:45:17 +10:00
Peter Hutterer
3211a8a23c tools: add some extra help output about the expected input data
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit d1d3ea4d06)
2016-12-21 13:10:17 +10:00
Peter Hutterer
12b7ba7086 tools: support --help in the ptraccel-debug tool
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit f545cfa923)
2016-12-21 13:10:08 +10:00
Peter Hutterer
4e48547047 libinput 1.5.3
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-12-07 14:23:46 +10:00
Peter Hutterer
9835acf7c7 touchpad: sync BTN_TOOL_FINGER state on init
The Elantech touchpad on my Asus Vivobook doesn't release BTN_TOOL_FINGER on
up. If the touchpad was used before libinput initializes, the kernel filters
the event because its state is already set. We never receive it and keep
ignoring all events until the first switch to BTN_TOOL_DOUBLETAP and back.

On touchpad init sync the BTN_TOOL_FINGER state and set it accordingly. This
is the only event that can be legitimately down on init. We don't care about
BTN_TOUCH because ignoring an ongoing touch on init is generally a good idea
and we can ignore any multifinger gesture as well.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 5552a6f145)
2016-12-06 17:39:04 +10:00
Peter Hutterer
2d2b38aec4 touchpad: add a quirk for the HP Pavilion dm4
This touchpad has cursor jumps for 2-finger scrolling that also affects the
single-finger emulation. So disable any multitouch bits on this device and
disallow the 2-finger scroll method. This still allows for 2-finger
tapping/clicking.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 996b845d68)
2016-12-06 17:39:04 +10:00
Peter Hutterer
8e6d3301b8 evdev: use safe_atod to convert the matrix values
Avoids parsing issues when we're in different locales

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 98793f6b43)
2016-12-06 17:39:04 +10:00
Peter Hutterer
5181be6cbc util: add a helper function to split a string into substrings
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 33100fe88d)
2016-12-06 17:39:04 +10:00
Peter Hutterer
ed4d674ca2 util: add safe_atod for locale-independent conversion
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit d6020d7ab2)
2016-12-06 17:39:04 +10:00
Peter Hutterer
bfff1ab3ef path: read the calibration prop on startup
We were reading this property in the udev backend, but not in the path
backend.

Reported-by: Thomas Olszak <olszak.tomasz@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 21f0e2e3b7)
2016-12-06 17:39:03 +10:00
Peter Hutterer
84c12a8a63 evdev: move reading the calibration prop into a helper function
No functional changes.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 50e4a1fada)
2016-12-06 17:39:03 +10:00
Peter Hutterer
690dd44121 util: if errno is nonzero, exit early from safe_atoi
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 13428f5d82)
2016-12-06 17:39:03 +10:00
Peter Hutterer
59d1ed9466 util: fix include order
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 4a5dcbf69b)
2016-12-06 17:39:03 +10:00
Peter Hutterer
67a875d752 util: fix indentation for safe_atoi
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 3168d86223)
2016-12-06 17:39:03 +10:00
25 changed files with 796 additions and 81 deletions

View file

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

View file

@ -569,10 +569,8 @@ tp_init_softbuttons(struct tp_dispatch *tp,
* *
* On touchpads with visible markings we reduce the size of the * On touchpads with visible markings we reduce the size of the
* middle button since users have a visual guide. * middle button since users have a visual guide.
*
* All Dell touchpads appear to have a middle marker.
*/ */
if (tp->device->model_flags & EVDEV_MODEL_DELL_TOUCHPAD) { if (tp->device->model_flags & EVDEV_MODEL_TOUCHPAD_VISIBLE_MARKER) {
mm.x = width/2 - 5; /* 10mm wide */ mm.x = width/2 - 5; /* 10mm wide */
edges = evdev_device_mm_to_units(device, &mm); edges = evdev_device_mm_to_units(device, &mm);
mb_le = edges.x; mb_le = edges.x;

View file

@ -331,21 +331,23 @@ tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time)
int yres = tp->device->abs.absinfo_y->resolution; int yres = tp->device->abs.absinfo_y->resolution;
int vert_distance; int vert_distance;
/* for two-finger gestures, if the fingers stay unmoving for a if (time > (tp->gesture.initial_time + DEFAULT_GESTURE_2FG_SCROLL_TIMEOUT)) {
* while, assume (slow) scroll */ /* for two-finger gestures, if the fingers stay unmoving for a
if (tp->gesture.finger_count == 2) { * while, assume (slow) scroll */
if (time > (tp->gesture.initial_time + DEFAULT_GESTURE_2FG_SCROLL_TIMEOUT)) { if (tp->gesture.finger_count == 2) {
tp_gesture_set_scroll_buildup(tp); tp_gesture_set_scroll_buildup(tp);
return GESTURE_STATE_SCROLL; return GESTURE_STATE_SCROLL;
} }
/* Else check if one finger is > 20mm below the others */ /* for 3+ finger gestures, check if one finger is > 20mm
below the others */
vert_distance = abs(first->point.y - second->point.y); vert_distance = abs(first->point.y - second->point.y);
if (vert_distance > 20 * yres && if (vert_distance > 20 * yres &&
tp->gesture.finger_count > 2 &&
tp->gesture.enabled) { tp->gesture.enabled) {
tp_gesture_init_pinch(tp); tp_gesture_init_pinch(tp);
return GESTURE_STATE_PINCH; return GESTURE_STATE_PINCH;
} else {
return GESTURE_STATE_SWIPE;
} }
} }

View file

@ -1450,12 +1450,14 @@ static bool
tp_dwt_device_is_blacklisted(struct evdev_device *device) tp_dwt_device_is_blacklisted(struct evdev_device *device)
{ {
unsigned int bus = libevdev_get_id_bustype(device->evdev); unsigned int bus = libevdev_get_id_bustype(device->evdev);
unsigned int vendor_id = libevdev_get_id_vendor(device->evdev);
/* evemu will set the right bus type */ /* evemu will set the right bus type */
if (bus == BUS_VIRTUAL) if (bus == BUS_VIRTUAL || bus == BUS_BLUETOOTH)
return true; return true;
if (device->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD) /* Wacom doesn't have devices that need dwt */
if (vendor_id == VENDOR_ID_WACOM)
return true; return true;
return false; return false;
@ -1469,11 +1471,18 @@ tp_want_dwt(struct evdev_device *touchpad,
bus_kbd = libevdev_get_id_bustype(keyboard->evdev); bus_kbd = libevdev_get_id_bustype(keyboard->evdev);
unsigned int vendor_tp = evdev_device_get_id_vendor(touchpad); unsigned int vendor_tp = evdev_device_get_id_vendor(touchpad);
unsigned int vendor_kbd = evdev_device_get_id_vendor(keyboard); unsigned int vendor_kbd = evdev_device_get_id_vendor(keyboard);
unsigned int product_tp = evdev_device_get_id_product(touchpad);
unsigned int product_kbd = evdev_device_get_id_product(keyboard);
if (tp_dwt_device_is_blacklisted(touchpad) || if (tp_dwt_device_is_blacklisted(touchpad) ||
tp_dwt_device_is_blacklisted(keyboard)) tp_dwt_device_is_blacklisted(keyboard))
return false; return false;
/* External touchpads with the same vid/pid as the keyboard are
considered a happy couple */
if (touchpad->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD)
return vendor_tp == vendor_kbd && product_tp == product_kbd;
/* If the touchpad is on serio, the keyboard is too, so ignore any /* If the touchpad is on serio, the keyboard is too, so ignore any
other devices */ other devices */
if (bus_tp == BUS_I8042 && bus_kbd != bus_tp) if (bus_tp == BUS_I8042 && bus_kbd != bus_tp)
@ -1795,8 +1804,12 @@ tp_init_slots(struct tp_dispatch *tp,
* If three fingers are set down in the same frame, one slot has the * 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. * coordinates 0/0 and may not get updated for several frames.
* See https://bugzilla.redhat.com/show_bug.cgi?id=1295073 * See https://bugzilla.redhat.com/show_bug.cgi?id=1295073
*
* The HP Pavilion DM4 touchpad has random jumps in slots, including
* for single-finger movement. See fdo bug 91135
*/ */
if (tp->semi_mt) { if (tp->semi_mt ||
device->model_flags & EVDEV_MODEL_HP_PAVILION_DM4_TOUCHPAD) {
tp->num_slots = 1; tp->num_slots = 1;
tp->slot = 0; tp->slot = 0;
tp->has_mt = false; tp->has_mt = false;
@ -1825,6 +1838,14 @@ tp_init_slots(struct tp_dispatch *tp,
for (i = 1; i < tp->num_slots; i++) for (i = 1; i < tp->num_slots; i++)
tp_sync_touch(tp, device, &tp->touches[i], i); tp_sync_touch(tp, device, &tp->touches[i], i);
/* Some touchpads don't reset BTN_TOOL_FINGER on touch up and only
* change to/from it when BTN_TOOL_DOUBLETAP is set. This causes us
* to ignore the first touches events until a two-finger gesture is
* performed.
*/
if (libevdev_get_event_value(device->evdev, EV_KEY, BTN_TOOL_FINGER))
tp_fake_finger_set(tp, BTN_TOOL_FINGER, 1);
return true; return true;
} }
@ -1899,6 +1920,12 @@ tp_scroll_get_methods(struct tp_dispatch *tp)
{ {
uint32_t methods = LIBINPUT_CONFIG_SCROLL_EDGE; uint32_t methods = LIBINPUT_CONFIG_SCROLL_EDGE;
/* Any movement with more than one finger has random cursor
* jumps. Don't allow for 2fg scrolling on this device, see
* fdo bug 91135 */
if (tp->device->model_flags & EVDEV_MODEL_HP_PAVILION_DM4_TOUCHPAD)
return LIBINPUT_CONFIG_SCROLL_EDGE;
if (tp->ntouches >= 2) if (tp->ntouches >= 2)
methods |= LIBINPUT_CONFIG_SCROLL_2FG; methods |= LIBINPUT_CONFIG_SCROLL_2FG;

View file

@ -2174,12 +2174,13 @@ evdev_read_model_flags(struct evdev_device *device)
MODEL(CYAPA), MODEL(CYAPA),
MODEL(HP_STREAM11_TOUCHPAD), MODEL(HP_STREAM11_TOUCHPAD),
MODEL(LENOVO_T450_TOUCHPAD), MODEL(LENOVO_T450_TOUCHPAD),
MODEL(DELL_TOUCHPAD), MODEL(TOUCHPAD_VISIBLE_MARKER),
MODEL(TRACKBALL), MODEL(TRACKBALL),
MODEL(APPLE_MAGICMOUSE), MODEL(APPLE_MAGICMOUSE),
MODEL(HP8510_TOUCHPAD), MODEL(HP8510_TOUCHPAD),
MODEL(HP6910_TOUCHPAD), MODEL(HP6910_TOUCHPAD),
MODEL(HP_ZBOOK_STUDIO_G3), MODEL(HP_ZBOOK_STUDIO_G3),
MODEL(HP_PAVILION_DM4_TOUCHPAD),
#undef MODEL #undef MODEL
{ "ID_INPUT_TRACKBALL", EVDEV_MODEL_TRACKBALL }, { "ID_INPUT_TRACKBALL", EVDEV_MODEL_TRACKBALL },
{ NULL, EVDEV_MODEL_DEFAULT }, { NULL, EVDEV_MODEL_DEFAULT },
@ -2975,6 +2976,51 @@ evdev_device_calibrate(struct evdev_device *device,
matrix_mult(&device->abs.calibration, &transform, &scale); matrix_mult(&device->abs.calibration, &transform, &scale);
} }
void
evdev_read_calibration_prop(struct evdev_device *device)
{
const char *calibration_values;
float calibration[6];
int idx;
char **strv;
calibration_values =
udev_device_get_property_value(device->udev_device,
"LIBINPUT_CALIBRATION_MATRIX");
if (calibration_values == NULL)
return;
if (!device->abs.absinfo_x || !device->abs.absinfo_y)
return;
strv = strv_from_string(calibration_values, " ");
if (!strv)
return;
for (idx = 0; idx < 6; idx++) {
double v;
if (strv[idx] == NULL || !safe_atod(strv[idx], &v)) {
strv_free(strv);
return;
}
calibration[idx] = v;
}
strv_free(strv);
evdev_device_set_default_calibration(device, calibration);
log_info(evdev_libinput_context(device),
"Applying calibration: %f %f %f %f %f %f\n",
calibration[0],
calibration[1],
calibration[2],
calibration[3],
calibration[4],
calibration[5]);
}
bool bool
evdev_device_has_capability(struct evdev_device *device, evdev_device_has_capability(struct evdev_device *device,
enum libinput_device_capability capability) enum libinput_device_capability capability)

View file

@ -116,12 +116,13 @@ enum evdev_device_model {
EVDEV_MODEL_CYAPA = (1 << 15), EVDEV_MODEL_CYAPA = (1 << 15),
EVDEV_MODEL_HP_STREAM11_TOUCHPAD = (1 << 16), EVDEV_MODEL_HP_STREAM11_TOUCHPAD = (1 << 16),
EVDEV_MODEL_LENOVO_T450_TOUCHPAD= (1 << 17), EVDEV_MODEL_LENOVO_T450_TOUCHPAD= (1 << 17),
EVDEV_MODEL_DELL_TOUCHPAD = (1 << 18), EVDEV_MODEL_TOUCHPAD_VISIBLE_MARKER = (1 << 18),
EVDEV_MODEL_TRACKBALL = (1 << 19), EVDEV_MODEL_TRACKBALL = (1 << 19),
EVDEV_MODEL_APPLE_MAGICMOUSE = (1 << 20), EVDEV_MODEL_APPLE_MAGICMOUSE = (1 << 20),
EVDEV_MODEL_HP8510_TOUCHPAD = (1 << 21), EVDEV_MODEL_HP8510_TOUCHPAD = (1 << 21),
EVDEV_MODEL_HP6910_TOUCHPAD = (1 << 22), EVDEV_MODEL_HP6910_TOUCHPAD = (1 << 22),
EVDEV_MODEL_HP_ZBOOK_STUDIO_G3 = (1 << 23), EVDEV_MODEL_HP_ZBOOK_STUDIO_G3 = (1 << 23),
EVDEV_MODEL_HP_PAVILION_DM4_TOUCHPAD = (1 << 24),
}; };
struct mt_slot { struct mt_slot {
@ -337,6 +338,9 @@ void
evdev_init_calibration(struct evdev_device *device, evdev_init_calibration(struct evdev_device *device,
struct libinput_device_config_calibration *calibration); struct libinput_device_config_calibration *calibration);
void
evdev_read_calibration_prop(struct evdev_device *device);
void void
evdev_device_init_pointer_acceleration(struct evdev_device *device, evdev_device_init_pointer_acceleration(struct evdev_device *device,
struct motion_filter *filter); struct motion_filter *filter);

View file

@ -248,21 +248,10 @@ parse_mouse_wheel_click_angle_property(const char *prop)
double double
parse_trackpoint_accel_property(const char *prop) parse_trackpoint_accel_property(const char *prop)
{ {
locale_t c_locale;
double accel; double accel;
char *endp;
/* Create a "C" locale to force strtod to use '.' as separator */ if (!safe_atod(prop, &accel))
c_locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0); accel = 0.0;
if (c_locale == (locale_t)0)
return 0.0;
accel = strtod_l(prop, &endp, c_locale);
freelocale(c_locale);
if (*endp != '\0')
return 0.0;
return accel; return accel;
} }
@ -296,3 +285,85 @@ parse_dimension_property(const char *prop, size_t *w, size_t *h)
*h = (size_t)y; *h = (size_t)y;
return true; return true;
} }
/**
* Return the next word in a string pointed to by state before the first
* separator character. Call repeatedly to tokenize a whole string.
*
* @param state Current state
* @param len String length of the word returned
* @param separators List of separator characters
*
* @return The first word in *state, NOT null-terminated
*/
static const char *
next_word(const char **state, size_t *len, const char *separators)
{
const char *next = *state;
size_t l;
if (!*next)
return NULL;
next += strspn(next, separators);
if (!*next) {
*state = next;
return NULL;
}
l = strcspn(next, separators);
*state = next + l;
*len = l;
return next;
}
/**
* Return a null-terminated string array with the tokens in the input
* string, e.g. "one two\tthree" with a separator list of " \t" will return
* an array [ "one", "two", "three", NULL ].
*
* Use strv_free() to free the array.
*
* @param in Input string
* @param separators List of separator characters
*
* @return A null-terminated string array or NULL on errors
*/
char **
strv_from_string(const char *in, const char *separators)
{
const char *s, *word;
char **strv = NULL;
int nelems = 0, idx;
size_t l;
assert(in != NULL);
s = in;
while ((word = next_word(&s, &l, separators)) != NULL)
nelems++;
if (nelems == 0)
return NULL;
nelems++; /* NULL-terminated */
strv = zalloc(nelems * sizeof *strv);
if (!strv)
return NULL;
idx = 0;
s = in;
while ((word = next_word(&s, &l, separators)) != NULL) {
char *copy = strndup(word, l);
if (!copy) {
strv_free(strv);
return NULL;
}
strv[idx++] = copy;
}
return strv;
}

View file

@ -28,18 +28,21 @@
#include "config.h" #include "config.h"
#include <assert.h> #include <assert.h>
#include <unistd.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <locale.h>
#include <math.h> #include <math.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#include "libinput.h" #include "libinput.h"
#define VENDOR_ID_APPLE 0x5ac #define VENDOR_ID_APPLE 0x5ac
#define VENDOR_ID_CHICONY 0x4f2
#define VENDOR_ID_LOGITECH 0x46d #define VENDOR_ID_LOGITECH 0x46d
#define VENDOR_ID_WACOM 0x56a #define VENDOR_ID_WACOM 0x56a
#define VENDOR_ID_SYNAPTICS_SERIAL 0x002 #define VENDOR_ID_SYNAPTICS_SERIAL 0x002
@ -407,20 +410,69 @@ us2ms(uint64_t us)
static inline bool static inline bool
safe_atoi(const char *str, int *val) safe_atoi(const char *str, int *val)
{ {
char *endptr; char *endptr;
long v; long v;
v = strtol(str, &endptr, 10); errno = 0;
if (str == endptr) v = strtol(str, &endptr, 10);
return false; if (errno > 0)
if (*str != '\0' && *endptr != '\0') return false;
return false; if (str == endptr)
return false;
if (*str != '\0' && *endptr != '\0')
return false;
if (v > INT_MAX || v < INT_MIN) if (v > INT_MAX || v < INT_MIN)
return false; return false;
*val = v; *val = v;
return true; return true;
}
static inline bool
safe_atod(const char *str, double *val)
{
char *endptr;
double v;
locale_t c_locale;
/* Create a "C" locale to force strtod to use '.' as separator */
c_locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
if (c_locale == (locale_t)0)
return false;
errno = 0;
v = strtod_l(str, &endptr, c_locale);
freelocale(c_locale);
if (errno > 0)
return false;
if (str == endptr)
return false;
if (*str != '\0' && *endptr != '\0')
return false;
if (isnan(v) || isinf(v))
return false;
*val = v;
return true;
}
char **strv_from_string(const char *string, const char *separator);
static inline void
strv_free(char **strv) {
char **s = strv;
if (!strv)
return;
while (*s != NULL) {
free(*s);
*s = (char*)0x1; /* detect use-after-free */
s++;
}
free (strv);
} }
#endif /* LIBINPUT_UTIL_H */ #endif /* LIBINPUT_UTIL_H */

View file

@ -1555,7 +1555,7 @@ libinput_init(struct libinput *libinput,
assert(interface->open_restricted != NULL); assert(interface->open_restricted != NULL);
assert(interface->close_restricted != NULL); assert(interface->close_restricted != NULL);
libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC);; libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (libinput->epoll_fd < 0) if (libinput->epoll_fd < 0)
return -1; return -1;

View file

@ -171,6 +171,8 @@ path_device_enable(struct path_input *input,
goto out; goto out;
} }
evdev_read_calibration_prop(device);
out: out:
free(seat_name); free(seat_name);
free(seat_logical_name); free(seat_logical_name);

View file

@ -51,8 +51,6 @@ device_added(struct udev_device *udev_device,
struct evdev_device *device; struct evdev_device *device;
const char *devnode; const char *devnode;
const char *device_seat, *output_name; const char *device_seat, *output_name;
const char *calibration_values;
float calibration[6];
struct udev_seat *seat; struct udev_seat *seat;
device_seat = udev_device_get_property_value(udev_device, "ID_SEAT"); device_seat = udev_device_get_property_value(udev_device, "ID_SEAT");
@ -94,29 +92,7 @@ device_added(struct udev_device *udev_device,
return 0; return 0;
} }
calibration_values = evdev_read_calibration_prop(device);
udev_device_get_property_value(udev_device,
"LIBINPUT_CALIBRATION_MATRIX");
if (device->abs.absinfo_x && device->abs.absinfo_y &&
calibration_values && sscanf(calibration_values,
"%f %f %f %f %f %f",
&calibration[0],
&calibration[1],
&calibration[2],
&calibration[3],
&calibration[4],
&calibration[5]) == 6) {
evdev_device_set_default_calibration(device, calibration);
log_info(&input->base,
"Applying calibration: %f %f %f %f %f %f\n",
calibration[0],
calibration[1],
calibration[2],
calibration[3],
calibration[4],
calibration[5]);
}
output_name = udev_device_get_property_value(udev_device, "WL_OUTPUT"); output_name = udev_device_get_property_value(udev_device, "WL_OUTPUT");
if (output_name) if (output_name)

View file

@ -13,6 +13,8 @@ noinst_LTLIBRARIES = liblitest.la
liblitest_la_SOURCES = \ liblitest_la_SOURCES = \
litest.h \ litest.h \
litest-int.h \ litest-int.h \
litest-device-acer-hawaii-keyboard.c \
litest-device-acer-hawaii-touchpad.c \
litest-device-alps-semi-mt.c \ litest-device-alps-semi-mt.c \
litest-device-alps-dualpoint.c \ litest-device-alps-dualpoint.c \
litest-device-anker-mouse-kbd.c \ litest-device-anker-mouse-kbd.c \

View file

@ -61,6 +61,22 @@ START_TEST(device_sendevents_config_invalid)
} }
END_TEST END_TEST
static inline bool
touchpad_is_external(struct litest_device *dev)
{
struct udev_device *udev_device;
const char *prop;
bool is_external;
udev_device = libinput_device_get_udev_device(dev->libinput_device);
prop = udev_device_get_property_value(udev_device,
"ID_INPUT_TOUCHPAD_INTEGRATION");
is_external = prop && streq(prop, "external");
udev_device_unref(udev_device);
return is_external;
}
START_TEST(device_sendevents_config_touchpad) START_TEST(device_sendevents_config_touchpad)
{ {
struct litest_device *dev = litest_current_device(); struct litest_device *dev = litest_current_device();
@ -71,7 +87,7 @@ START_TEST(device_sendevents_config_touchpad)
/* The wacom devices in the test suite are external */ /* The wacom devices in the test suite are external */
if (libevdev_get_id_vendor(dev->evdev) != VENDOR_ID_WACOM && if (libevdev_get_id_vendor(dev->evdev) != VENDOR_ID_WACOM &&
libevdev_get_id_bustype(dev->evdev) != BUS_BLUETOOTH) !touchpad_is_external(dev))
expected |= expected |=
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE; LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
@ -91,7 +107,7 @@ START_TEST(device_sendevents_config_touchpad_superset)
/* The wacom devices in the test suite are external */ /* The wacom devices in the test suite are external */
if (libevdev_get_id_vendor(dev->evdev) == VENDOR_ID_WACOM || if (libevdev_get_id_vendor(dev->evdev) == VENDOR_ID_WACOM ||
libevdev_get_id_bustype(dev->evdev) == BUS_BLUETOOTH) touchpad_is_external(dev))
return; return;
device = dev->libinput_device; device = dev->libinput_device;

View file

@ -0,0 +1,208 @@
/*
* Copyright © 2016 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.
*/
#include "config.h"
#include "litest.h"
#include "litest-int.h"
static void litest_keyboard_setup(void)
{
struct litest_device *d = litest_create_device(LITEST_ACER_HAWAII_KEYBOARD);
litest_set_current_device(d);
}
static struct input_id input_id = {
.bustype = 0x3,
.vendor = 0x4f2,
.product = 0x1558,
};
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_LINEFEED,
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_MACRO,
EV_KEY, KEY_MUTE,
EV_KEY, KEY_VOLUMEDOWN,
EV_KEY, KEY_VOLUMEUP,
EV_KEY, KEY_POWER,
EV_KEY, KEY_KPEQUAL,
EV_KEY, KEY_KPPLUSMINUS,
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_MENU,
EV_KEY, KEY_CALC,
EV_KEY, KEY_SETUP,
EV_KEY, KEY_SLEEP,
EV_KEY, KEY_WAKEUP,
EV_KEY, KEY_SCREENLOCK,
EV_KEY, KEY_DIRECTION,
EV_KEY, KEY_CYCLEWINDOWS,
EV_KEY, KEY_MAIL,
EV_KEY, KEY_BOOKMARKS,
EV_KEY, KEY_COMPUTER,
EV_KEY, KEY_BACK,
EV_KEY, KEY_FORWARD,
EV_KEY, KEY_NEXTSONG,
EV_KEY, KEY_PLAYPAUSE,
EV_KEY, KEY_PREVIOUSSONG,
EV_KEY, KEY_STOPCD,
EV_KEY, KEY_HOMEPAGE,
EV_KEY, KEY_REFRESH,
EV_KEY, KEY_F14,
EV_KEY, KEY_F15,
EV_KEY, KEY_SEARCH,
EV_KEY, KEY_MEDIA,
EV_KEY, KEY_FN,
-1, -1,
};
struct litest_test_device litest_acer_hawaii_keyboard_device = {
.type = LITEST_ACER_HAWAII_KEYBOARD,
.features = LITEST_KEYS,
.shortname = "hawaii-keyboard",
.setup = litest_keyboard_setup,
.interface = NULL,
.name = "Chicony ACER Hawaii Keyboard",
.id = &input_id,
.events = events,
.absinfo = NULL,
};

View file

@ -0,0 +1,113 @@
/*
* Copyright © 2016 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.
*/
#include "config.h"
#include "litest.h"
#include "litest-int.h"
static void
litest_touchpad_setup(void)
{
struct litest_device *d = litest_create_device(LITEST_ACER_HAWAII_TOUCHPAD);
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 = 0x3,
.vendor = 0x4f2,
.product = 0x1558,
};
static int events[] = {
EV_KEY, BTN_LEFT,
EV_KEY, BTN_TOOL_FINGER,
EV_KEY, BTN_TOOL_QUINTTAP,
EV_KEY, BTN_TOUCH,
EV_KEY, BTN_TOOL_DOUBLETAP,
EV_KEY, BTN_TOOL_TRIPLETAP,
EV_KEY, BTN_TOOL_QUADTAP,
INPUT_PROP_MAX, INPUT_PROP_POINTER,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1, -1,
};
static struct input_absinfo absinfo[] = {
{ ABS_X, 0, 1151, 0, 0, 12 },
{ ABS_Y, 0, 738, 0, 0, 14 },
{ ABS_MT_SLOT, 0, 14, 0, 0, 0 },
{ ABS_MT_POSITION_X, 0, 1151, 0, 0, 12 },
{ ABS_MT_POSITION_Y, 0, 738, 0, 0, 14 },
{ ABS_MT_TRACKING_ID, 0, 65535, 0, 0, 0 },
{ .value = -1 }
};
static const char udev_rule[] =
"ACTION==\"remove\", GOTO=\"touchpad_end\"\n"
"KERNEL!=\"event*\", GOTO=\"touchpad_end\"\n"
"ENV{ID_INPUT_TOUCHPAD}==\"\", GOTO=\"touchpad_end\"\n"
"\n"
"ATTRS{name}==\"litest Chicony ACER Hawaii Keyboard Touchpad\","
" ENV{ID_INPUT_TOUCHPAD_INTEGRATION}=\"external\"\n"
"\n"
"LABEL=\"touchpad_end\"";
struct litest_test_device litest_acer_hawaii_touchpad_device = {
.type = LITEST_ACER_HAWAII_TOUCHPAD,
.features = LITEST_TOUCHPAD | LITEST_CLICKPAD | LITEST_BUTTON,
.shortname = "hawaii-touchpad",
.setup = litest_touchpad_setup,
.interface = &interface,
.name = "Chicony ACER Hawaii Keyboard Touchpad",
.id = &input_id,
.events = events,
.absinfo = absinfo,
.udev_rule = udev_rule,
};

View file

@ -108,7 +108,7 @@ static const char udev_rule[] =
"ENV{ID_INPUT_TOUCHPAD}==\"\", GOTO=\"touchpad_end\"\n" "ENV{ID_INPUT_TOUCHPAD}==\"\", GOTO=\"touchpad_end\"\n"
"\n" "\n"
"ATTRS{name}==\"litest AlpsPS/2 ALPS DualPoint TouchPad\"," "ATTRS{name}==\"litest AlpsPS/2 ALPS DualPoint TouchPad\","
" ENV{LIBINPUT_MODEL_DELL_TOUCHPAD}=\"1\"\n" " ENV{LIBINPUT_MODEL_TOUCHPAD_VISIBLE_MARKER}=\"1\"\n"
"\n" "\n"
"LABEL=\"touchpad_end\""; "LABEL=\"touchpad_end\"";

View file

@ -95,6 +95,16 @@ static int events[] = {
-1, -1 -1, -1
}; };
static const char udev_rule[] =
"ACTION==\"remove\", GOTO=\"touchpad_end\"\n"
"KERNEL!=\"event*\", GOTO=\"touchpad_end\"\n"
"ENV{ID_INPUT_TOUCHPAD}==\"\", GOTO=\"touchpad_end\"\n"
"\n"
"ATTRS{name}==\"litest Apple Wireless Trackpad\","
" ENV{ID_INPUT_TOUCHPAD_INTEGRATION}=\"external\"\n"
"\n"
"LABEL=\"touchpad_end\"";
struct litest_test_device litest_magicpad_device = { struct litest_test_device litest_magicpad_device = {
.type = LITEST_MAGIC_TRACKPAD, .type = LITEST_MAGIC_TRACKPAD,
.features = LITEST_TOUCHPAD | LITEST_CLICKPAD | .features = LITEST_TOUCHPAD | LITEST_CLICKPAD |
@ -107,4 +117,5 @@ struct litest_test_device litest_magicpad_device = {
.id = &input_id, .id = &input_id,
.events = events, .events = events,
.absinfo = absinfo, .absinfo = absinfo,
.udev_rule = udev_rule,
}; };

View file

@ -94,7 +94,7 @@ static const char udev_rule[] =
"ENV{ID_INPUT_TOUCHPAD}==\"\", GOTO=\"touchpad_end\"\n" "ENV{ID_INPUT_TOUCHPAD}==\"\", GOTO=\"touchpad_end\"\n"
"\n" "\n"
"ATTRS{name}==\"litest DLL0704:01 06CB:76AD Touchpad\"," "ATTRS{name}==\"litest DLL0704:01 06CB:76AD Touchpad\","
" ENV{LIBINPUT_MODEL_DELL_TOUCHPAD}=\"1\"\n" " ENV{LIBINPUT_MODEL_TOUCHPAD_VISIBLE_MARKER}=\"1\"\n"
"\n" "\n"
"LABEL=\"touchpad_end\""; "LABEL=\"touchpad_end\"";

View file

@ -406,6 +406,8 @@ extern struct litest_test_device litest_wacom_cintiq_13hdt_pen_device;
extern struct litest_test_device litest_wacom_cintiq_13hdt_pad_device; extern struct litest_test_device litest_wacom_cintiq_13hdt_pad_device;
extern struct litest_test_device litest_wacom_hid4800_tablet_device; extern struct litest_test_device litest_wacom_hid4800_tablet_device;
extern struct litest_test_device litest_mouse_wheel_click_count_device; extern struct litest_test_device litest_mouse_wheel_click_count_device;
extern struct litest_test_device litest_acer_hawaii_keyboard_device;
extern struct litest_test_device litest_acer_hawaii_touchpad_device;
struct litest_test_device* devices[] = { struct litest_test_device* devices[] = {
&litest_synaptics_clickpad_device, &litest_synaptics_clickpad_device,
@ -463,6 +465,8 @@ struct litest_test_device* devices[] = {
&litest_wacom_cintiq_13hdt_pad_device, &litest_wacom_cintiq_13hdt_pad_device,
&litest_wacom_hid4800_tablet_device, &litest_wacom_hid4800_tablet_device,
&litest_mouse_wheel_click_count_device, &litest_mouse_wheel_click_count_device,
&litest_acer_hawaii_keyboard_device,
&litest_acer_hawaii_touchpad_device,
NULL, NULL,
}; };

View file

@ -225,6 +225,8 @@ enum litest_device_type {
LITEST_WACOM_CINTIQ_13HDT_FINGER, LITEST_WACOM_CINTIQ_13HDT_FINGER,
LITEST_WACOM_HID4800_PEN, LITEST_WACOM_HID4800_PEN,
LITEST_MOUSE_WHEEL_CLICK_COUNT, LITEST_MOUSE_WHEEL_CLICK_COUNT,
LITEST_ACER_HAWAII_KEYBOARD,
LITEST_ACER_HAWAII_TOUCHPAD,
}; };
enum litest_device_feature { enum litest_device_feature {

View file

@ -861,6 +861,99 @@ START_TEST(time_conversion)
} }
END_TEST END_TEST
struct atod_test {
char *str;
bool success;
double val;
};
START_TEST(safe_atod_test)
{
struct atod_test tests[] = {
{ "10", true, 10 },
{ "20", true, 20 },
{ "-1", true, -1 },
{ "2147483647", true, 2147483647 },
{ "-2147483648", true, -2147483648 },
{ "4294967295", true, 4294967295 },
{ "0x0", true, 0 },
{ "0x10", true, 0x10 },
{ "0xaf", true, 0xaf },
{ "x80", false, 0 },
{ "0.0", true, 0.0 },
{ "0.1", true, 0.1 },
{ "1.2", true, 1.2 },
{ "-324.9", true, -324.9 },
{ "9324.9", true, 9324.9 },
{ "NAN", false, 0 },
{ "INFINITY", false, 0 },
{ "-10x10", false, 0 },
{ "1x-99", false, 0 },
{ "", false, 0 },
{ "abd", false, 0 },
{ "xabd", false, 0 },
{ "0x0x", false, 0 },
{ NULL, false, 0 }
};
double v;
bool success;
for (int i = 0; tests[i].str != NULL; i++) {
v = 0xad;
success = safe_atod(tests[i].str, &v);
ck_assert(success == tests[i].success);
if (success)
ck_assert_int_eq(v, tests[i].val);
else
ck_assert_int_eq(v, 0xad);
}
}
END_TEST
struct strsplit_test {
const char *string;
const char *delim;
const char *results[10];
};
START_TEST(strsplit_test)
{
struct strsplit_test tests[] = {
{ "one two three", " ", { "one", "two", "three", NULL } },
{ "one", " ", { "one", NULL } },
{ "one two ", " ", { "one", "two", NULL } },
{ "one two", " ", { "one", "two", NULL } },
{ " one two", " ", { "one", "two", NULL } },
{ "one", "\t \r", { "one", NULL } },
{ "one two three", " t", { "one", "wo", "hree", NULL } },
{ " one two three", "te", { " on", " ", "wo ", "hr", NULL } },
{ "one", "ne", { "o", NULL } },
{ "onene", "ne", { "o", NULL } },
{ NULL, NULL, { NULL }}
};
struct strsplit_test *t = tests;
while (t->string) {
char **strv;
int idx = 0;
strv = strv_from_string(t->string, t->delim);
while (t->results[idx]) {
ck_assert_str_eq(t->results[idx], strv[idx]);
idx++;
}
ck_assert_ptr_eq(strv[idx], NULL);
strv_free(strv);
t++;
}
/* Special cases */
ck_assert_ptr_eq(strv_from_string("", " "), NULL);
ck_assert_ptr_eq(strv_from_string(" ", " "), NULL);
ck_assert_ptr_eq(strv_from_string(" ", " "), NULL);
ck_assert_ptr_eq(strv_from_string("oneoneone", "one"), NULL);
}
END_TEST
static int open_restricted_leak(const char *path, int flags, void *data) static int open_restricted_leak(const char *path, int flags, void *data)
{ {
return *(int*)data; return *(int*)data;
@ -988,6 +1081,8 @@ litest_setup_tests_misc(void)
litest_add_no_device("misc:parser", wheel_click_count_parser); litest_add_no_device("misc:parser", wheel_click_count_parser);
litest_add_no_device("misc:parser", trackpoint_accel_parser); litest_add_no_device("misc:parser", trackpoint_accel_parser);
litest_add_no_device("misc:parser", dimension_prop_parser); litest_add_no_device("misc:parser", dimension_prop_parser);
litest_add_no_device("misc:parser", safe_atod_test);
litest_add_no_device("misc:parser", strsplit_test);
litest_add_no_device("misc:time", time_conversion); litest_add_no_device("misc:time", time_conversion);
litest_add_no_device("misc:fd", fd_no_event_leak); litest_add_no_device("misc:fd", fd_no_event_leak);

View file

@ -2079,7 +2079,7 @@ START_TEST(touchpad_hover_down_up)
litest_hover_start(dev, 0, 50, 50); litest_hover_start(dev, 0, 50, 50);
litest_hover_start(dev, 1, 50, 50); litest_hover_start(dev, 1, 50, 50);
litest_touch_down(dev, 2, 50, 50); litest_touch_down(dev, 2, 50, 50);
litest_pop_event_frame(dev);; litest_pop_event_frame(dev);
litest_assert_empty_queue(li); litest_assert_empty_queue(li);
@ -2088,7 +2088,7 @@ START_TEST(touchpad_hover_down_up)
litest_hover_move(dev, 0, 55, 55); litest_hover_move(dev, 0, 55, 55);
litest_hover_end(dev, 1); litest_hover_end(dev, 1);
litest_touch_up(dev, 2); litest_touch_up(dev, 2);
litest_pop_event_frame(dev);; litest_pop_event_frame(dev);
litest_assert_empty_queue(li); litest_assert_empty_queue(li);
@ -2112,14 +2112,14 @@ START_TEST(touchpad_hover_2fg_noevent)
litest_push_event_frame(dev); litest_push_event_frame(dev);
litest_hover_start(dev, 0, 25, 25); litest_hover_start(dev, 0, 25, 25);
litest_hover_start(dev, 1, 50, 50); litest_hover_start(dev, 1, 50, 50);
litest_pop_event_frame(dev);; litest_pop_event_frame(dev);
litest_hover_move_two_touches(dev, 25, 25, 50, 50, 50, 50, 10, 0); litest_hover_move_two_touches(dev, 25, 25, 50, 50, 50, 50, 10, 0);
litest_push_event_frame(dev); litest_push_event_frame(dev);
litest_hover_end(dev, 0); litest_hover_end(dev, 0);
litest_hover_end(dev, 1); litest_hover_end(dev, 1);
litest_pop_event_frame(dev);; litest_pop_event_frame(dev);
litest_assert_empty_queue(li); litest_assert_empty_queue(li);
} }
@ -2137,19 +2137,19 @@ START_TEST(touchpad_hover_2fg_1fg_down)
litest_push_event_frame(dev); litest_push_event_frame(dev);
litest_hover_start(dev, 0, 25, 25); litest_hover_start(dev, 0, 25, 25);
litest_touch_down(dev, 1, 50, 50); litest_touch_down(dev, 1, 50, 50);
litest_pop_event_frame(dev);; litest_pop_event_frame(dev);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
litest_push_event_frame(dev); litest_push_event_frame(dev);
litest_hover_move(dev, 0, 25 + 5 * i, 25 + 5 * i); litest_hover_move(dev, 0, 25 + 5 * i, 25 + 5 * i);
litest_touch_move(dev, 1, 50 + 5 * i, 50 - 5 * i); litest_touch_move(dev, 1, 50 + 5 * i, 50 - 5 * i);
litest_pop_event_frame(dev);; litest_pop_event_frame(dev);
} }
litest_push_event_frame(dev); litest_push_event_frame(dev);
litest_hover_end(dev, 0); litest_hover_end(dev, 0);
litest_touch_up(dev, 1); litest_touch_up(dev, 1);
litest_pop_event_frame(dev);; litest_pop_event_frame(dev);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
} }
@ -2501,6 +2501,9 @@ dwt_init_paired_keyboard(struct libinput *li,
if (libevdev_get_id_vendor(touchpad->evdev) == VENDOR_ID_APPLE) if (libevdev_get_id_vendor(touchpad->evdev) == VENDOR_ID_APPLE)
which = LITEST_APPLE_KEYBOARD; which = LITEST_APPLE_KEYBOARD;
if (libevdev_get_id_vendor(touchpad->evdev) == VENDOR_ID_CHICONY)
which = LITEST_ACER_HAWAII_KEYBOARD;
return litest_add_device(li, which); return litest_add_device(li, which);
} }
@ -3774,6 +3777,45 @@ START_TEST(touchpad_dwt_apple)
} }
END_TEST END_TEST
START_TEST(touchpad_dwt_acer_hawaii)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *keyboard, *hawaii_keyboard;
struct libinput *li = touchpad->libinput;
ck_assert(has_disable_while_typing(touchpad));
/* Only the hawaii 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);
hawaii_keyboard = litest_add_device(li, LITEST_ACER_HAWAII_KEYBOARD);
litest_drain_events(li);
litest_keyboard_key(hawaii_keyboard, KEY_A, true);
litest_keyboard_key(hawaii_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(hawaii_keyboard);
}
END_TEST
static int static int
has_thumb_detect(struct litest_device *dev) has_thumb_detect(struct litest_device *dev)
{ {
@ -4365,6 +4407,29 @@ START_TEST(touchpad_slot_swap)
} }
END_TEST END_TEST
START_TEST(touchpad_finger_always_down)
{
struct litest_device *dev = litest_current_device();
struct libinput *li;
/* Set BTN_TOOL_FINGER before a new context is initialized */
litest_event(dev, EV_KEY, BTN_TOOL_FINGER, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
li = litest_create_context();
libinput_path_add_device(li,
libevdev_uinput_get_devnode(dev->uinput));
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_touch_move_to(dev, 0, 50, 50, 70, 50, 10, 0);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
libinput_unref(li);
}
END_TEST
START_TEST(touchpad_time_usec) START_TEST(touchpad_time_usec)
{ {
struct litest_device *dev = litest_current_device(); struct litest_device *dev = litest_current_device();
@ -4727,6 +4792,7 @@ litest_setup_tests_touchpad(void)
litest_add("touchpad:dwt", touchpad_dwt_enable_before_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("touchpad:dwt", touchpad_dwt_enable_during_tap, LITEST_TOUCHPAD, LITEST_ANY);
litest_add_for_device("touchpad:dwt", touchpad_dwt_apple, LITEST_BCM5974); litest_add_for_device("touchpad:dwt", touchpad_dwt_apple, LITEST_BCM5974);
litest_add_for_device("touchpad:dwt", touchpad_dwt_acer_hawaii, LITEST_ACER_HAWAII_TOUCHPAD);
litest_add("touchpad:thumb", touchpad_thumb_begin_no_motion, LITEST_CLICKPAD, LITEST_ANY); 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); litest_add("touchpad:thumb", touchpad_thumb_update_no_motion, LITEST_CLICKPAD, LITEST_ANY);
@ -4742,6 +4808,7 @@ litest_setup_tests_touchpad(void)
litest_add_for_device("touchpad:bugs", touchpad_tool_tripletap_touch_count, LITEST_SYNAPTICS_TOPBUTTONPAD); litest_add_for_device("touchpad:bugs", touchpad_tool_tripletap_touch_count, LITEST_SYNAPTICS_TOPBUTTONPAD);
litest_add_for_device("touchpad:bugs", touchpad_slot_swap, LITEST_SYNAPTICS_TOPBUTTONPAD); litest_add_for_device("touchpad:bugs", touchpad_slot_swap, LITEST_SYNAPTICS_TOPBUTTONPAD);
litest_add_for_device("touchpad:bugs", touchpad_finger_always_down, LITEST_SYNAPTICS_TOPBUTTONPAD);
litest_add("touchpad:time", touchpad_time_usec, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:time", touchpad_time_usec, LITEST_TOUCHPAD, LITEST_ANY);

View file

@ -181,6 +181,9 @@ usage(void)
"If stdin is a pipe, mode defaults to 'sequence' and the pipe is read \n" "If stdin is a pipe, mode defaults to 'sequence' and the pipe is read \n"
"for delta coordinates\n" "for delta coordinates\n"
"\n" "\n"
"Delta coordinates passed into this tool must be in dpi as\n"
"specified by the --dpi argument\n"
"\n"
"Output best viewed with gnuplot. See output for gnuplot commands\n"); "Output best viewed with gnuplot. See output for gnuplot commands\n");
} }
@ -202,7 +205,8 @@ main(int argc, char **argv)
accel_profile_func_t profile = NULL; accel_profile_func_t profile = NULL;
enum { enum {
OPT_MODE = 1, OPT_HELP = 1,
OPT_MODE,
OPT_NEVENTS, OPT_NEVENTS,
OPT_MAXDX, OPT_MAXDX,
OPT_STEP, OPT_STEP,
@ -215,6 +219,7 @@ main(int argc, char **argv)
int c; int c;
int option_index = 0; int option_index = 0;
static struct option long_options[] = { static struct option long_options[] = {
{"help", 0, 0, OPT_HELP },
{"mode", 1, 0, OPT_MODE }, {"mode", 1, 0, OPT_MODE },
{"nevents", 1, 0, OPT_NEVENTS }, {"nevents", 1, 0, OPT_NEVENTS },
{"maxdx", 1, 0, OPT_MAXDX }, {"maxdx", 1, 0, OPT_MAXDX },
@ -231,6 +236,10 @@ main(int argc, char **argv)
break; break;
switch (c) { switch (c) {
case OPT_HELP:
usage();
exit(0);
break;
case OPT_MODE: case OPT_MODE:
if (streq(optarg, "accel")) if (streq(optarg, "accel"))
print_accel = true; print_accel = true;

View file

@ -102,7 +102,7 @@ tools_usage()
"--set-scroll-method=[none|twofinger|edge|button] ... set the desired scroll method\n" "--set-scroll-method=[none|twofinger|edge|button] ... set the desired scroll method\n"
"--set-scroll-button=BTN_MIDDLE ... set the button to the given button code\n" "--set-scroll-button=BTN_MIDDLE ... set the button to the given button code\n"
"--set-profile=[adaptive|flat].... set pointer acceleration profile\n" "--set-profile=[adaptive|flat].... set pointer acceleration profile\n"
"--set-speed=<value>.... set pointer acceleration speed\n" "--set-speed=<value>.... set pointer acceleration speed (allowed range [-1, 1]) \n"
"--set-tap-map=[lrm|lmr] ... set button mapping for tapping\n" "--set-tap-map=[lrm|lmr] ... set button mapping for tapping\n"
"\n" "\n"
"These options apply to all applicable devices, if a feature\n" "These options apply to all applicable devices, if a feature\n"

View file

@ -41,6 +41,12 @@ libinput:name:*Apple Inc. Apple Internal Keyboard*:dmi:*
libinput:mouse:input:b0005v05ACp030D* libinput:mouse:input:b0005v05ACp030D*
LIBINPUT_MODEL_APPLE_MAGICMOUSE=1 LIBINPUT_MODEL_APPLE_MAGICMOUSE=1
##########################################
# Asus
##########################################
libinput:name:*ETPS/2 Elantech Touchpad*:dmi:*svnASUSTeKCOMPUTERINC.:pnX555LAB:*
LIBINPUT_MODEL_TOUCHPAD_VISIBLE_MARKER=1
########################################## ##########################################
# Cyborg # Cyborg
########################################## ##########################################
@ -53,7 +59,7 @@ libinput:mouse:input:b0003v06A3p0CD5*
########################################## ##########################################
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnDellInc.:* libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnDellInc.:*
libinput:name:* Touchpad:dmi:*svnDellInc.:* libinput:name:* Touchpad:dmi:*svnDellInc.:*
LIBINPUT_MODEL_DELL_TOUCHPAD=1 LIBINPUT_MODEL_TOUCHPAD_VISIBLE_MARKER=1
########################################## ##########################################
# Elantech # Elantech
@ -99,6 +105,10 @@ libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnHewlett-Packard:*pnHPCompaq6910
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnHewlett-Packard:*pnHPCompaq8510w* libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnHewlett-Packard:*pnHPCompaq8510w*
LIBINPUT_MODEL_HP8510_TOUCHPAD=1 LIBINPUT_MODEL_HP8510_TOUCHPAD=1
# HP Pavillion dm4
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnHewlett-Packard:*pnHPPaviliondm4NotebookPC*
LIBINPUT_MODEL_HP_PAVILION_DM4_TOUCHPAD=1
# HP Stream 11 # HP Stream 11
libinput:name:SYN1EDE:00 06CB:7442:dmi:*svnHewlett-Packard:pnHPStreamNotebookPC11* libinput:name:SYN1EDE:00 06CB:7442:dmi:*svnHewlett-Packard:pnHPStreamNotebookPC11*
LIBINPUT_MODEL_HP_STREAM11_TOUCHPAD=1 LIBINPUT_MODEL_HP_STREAM11_TOUCHPAD=1