...
 
Commits (41)
This diff is collapsed.
#!/bin/bash
set -e
set -x
export DEBIAN_FRONTEND=noninteractive
apt-get install -y software-properties-common
add-apt-repository universe
apt-get update
apt-get -y upgrade
apt-get install -y $@
#!/bin/bash
# build container
set -o xtrace
TAG=$1
cat > /etc/containers/storage.conf <<EOF
[storage]
driver = "vfs"
EOF
buildcntr1=$(buildah from --quiet golang:alpine)
buildmnt1=$(buildah mount $buildcntr1)
buildah run $buildcntr1 apk add --update \
--no-cache \
--repository http://dl-3.alpinelinux.org/alpine/edge/testing/ \
bash git make gcc musl-dev glib-dev ostree-dev \
bats bzip2 python3-dev \
gpgme-dev linux-headers btrfs-progs-dev \
libselinux-dev lvm2-dev libseccomp-dev
# build runc
buildah run $buildcntr1 go get github.com/opencontainers/runc
buildah config --workingdir /go/src/github.com/opencontainers/runc/ $buildcntr1
buildah run $buildcntr1 bash -c 'make'
buildah run $buildcntr1 bash -c 'make install'
# build skopeo
buildah run $buildcntr1 git clone --depth 1 --branch master https://github.com/containers/skopeo /go/src/github.com/containers/skopeo
buildah config --workingdir /go/src/github.com/containers/skopeo/ $buildcntr1
buildah run $buildcntr1 bash -c 'make binary-local'
# build libpod
buildah run $buildcntr1 git clone --depth 1 --branch master https://github.com/containers/libpod /go/src/github.com/containers/libpod
buildah config --workingdir /go/src/github.com/containers/libpod/ $buildcntr1
buildah run $buildcntr1 bash -c 'make install.tools'
buildah run $buildcntr1 bash -c 'make'
buildah run $buildcntr1 bash -c 'make install'
# build buildah
buildah run $buildcntr1 git clone --depth 1 --branch master https://github.com/containers/buildah /go/src/github.com/containers/buildah
buildah config --workingdir /go/src/github.com/containers/buildah/ $buildcntr1
buildah run $buildcntr1 bash -c 'make install.tools'
buildah run $buildcntr1 bash -c 'make'
buildah run $buildcntr1 bash -c 'make install'
# build conmon
buildah run $buildcntr1 git clone --depth 1 --branch master https://github.com/kubernetes-sigs/cri-o /go/src/github.com/kubernetes-sigs/cri-o
buildah config --workingdir /go/src/github.com/kubernetes-sigs/cri-o/ $buildcntr1
buildah run $buildcntr1 bash -c 'make install.tools'
buildah run $buildcntr1 bash -c 'make'
buildah run $buildcntr1 bash -c 'make install'
buildcntr2=$(buildah from --quiet alpine:latest)
buildmnt2=$(buildah mount $buildcntr2)
buildah run $buildcntr2 apk add --update \
--no-cache \
--repository http://dl-3.alpinelinux.org/alpine/edge/testing/ \
bash jq curl glib gpgme ostree lvm2 libselinux libseccomp \
iptables ip6tables
cp $buildmnt1/usr/local/sbin/runc $buildmnt2/usr/sbin/runc
cp $buildmnt1/go/src/github.com/containers/skopeo/skopeo $buildmnt2/usr/bin/skopeo
cp $buildmnt1/usr/local/bin/podman $buildmnt2/usr/bin/podman
cp $buildmnt1/usr/local/bin/buildah $buildmnt2/usr/bin/buildah
cp $buildmnt1/usr/local/bin/crio $buildmnt2/usr/bin/crio
mkdir $buildmnt2/usr/libexec/crio
cp $buildmnt1/usr/local/libexec/crio/conmon $buildmnt2/usr/libexec/crio/conmon
cp $buildmnt1/usr/local/libexec/crio/pause $buildmnt2/usr/libexec/crio/pause
mkdir $buildmnt2/etc/containers
cat > $buildmnt2/etc/containers/registries.conf <<EOF
# This is a system-wide configuration file used to
# keep track of registries for various container backends.
# It adheres to TOML format and does not support recursive
# lists of registries.
# The default location for this configuration file is /etc/containers/registries.conf.
# The only valid categories are: 'registries.search', 'registries.insecure',
# and 'registries.block'.
[registries.search]
registries = ['docker.io', 'registry.fedoraproject.org', 'quay.io', 'registry.centos.org']
# If you need to access insecure registries, add the registry's fully-qualified name.
# An insecure registry is one that does not have a valid SSL certificate or only does HTTP.
[registries.insecure]
registries = []
# If you need to block pull access from a registry, uncomment the section below
# and add the registries fully-qualified name.
#
# Docker only
[registries.block]
registries = []
EOF
cat > $buildmnt2/etc/containers/policy.json <<EOF
{
"default": [
{
"type": "insecureAcceptAnything"
}
],
"transports":
{
"docker-daemon":
{
"": [{"type":"insecureAcceptAnything"}]
}
}
}
EOF
cat > $buildmnt2/etc/containers/storage.conf <<EOF
# This file is is the configuration file for all tools
# that use the containers/storage library.
# See man 5 containers-storage.conf for more information
# The "container storage" table contains all of the server options.
[storage]
# Default Storage Driver
driver = "vfs"
EOF
buildah unmount $buildcntr2
buildah commit --quiet $buildcntr2 $TAG
#clean up build
buildah rm $buildcntr1 $buildcntr2
......@@ -10,18 +10,33 @@ dd {
}
.title .ingroups {
font-size: 200%;
font-size: 50%;
}
h1 {
font-size: 300%;
background-image: none;
background-color: #D6E5FF;
padding-left: 10px;
font-size: 150%;
color: #354C7B;
background: none;
border-bottom: 1px solid #879ECB;
font-size: 150%;
font-weight: normal;
padding-top: 8px;
padding-bottom: 8px;
padding-left: 0px;
width: 100%;
}
h2 {
font-size: 200%;
font-size: 120%;
color: #354C7B;
background: none;
border-bottom: 1px solid #879ECB;
font-size: 150%;
font-weight: normal;
padding-top: 8px;
padding-bottom: 8px;
padding-left: 0px;
width: 100%;
}
.sm-dox li {
......@@ -73,6 +88,10 @@ h2 {
background-color: #F0F0F0;
}
div.header {
border: none;
}
td.fieldname {
font-family: 'Roboto Mono', monospace;
}
......@@ -94,3 +113,8 @@ a {
color: #2873b0;
}
.navpath ul {
background-image: none;
background-color: #F0F0F0;
}
......@@ -183,3 +183,6 @@ AttrEventCodeDisable=EV_ABS;BTN_STYLUS;EV_KEY:0x123;
Disables the evdev event type/code tuples on the device. Entries may be
a named event type, or a named event code, or a named event type with a
hexadecimal event code, separated by a single colon.
AttrPointingStickIntegration=internal|external
Indicates the integration of the pointing stick. This is a string enum.
Only needed for external pointing sticks. These are rare.
......@@ -24,7 +24,7 @@ The most common tools used are:
- ``libinput quirks``: show quirks assigned to a device, see
:ref:`here <libinput-quirks>`
Most the tools must be run as root to have access to the kernel's
Most of the tools must be run as root to have access to the kernel's
``/dev/input/event*`` device files.
.. _libinput-list-devices:
......@@ -69,7 +69,7 @@ The above listing shows example output for a touchpad. The
default configuration for this device, for options that have more than a
binary state all available options are listed, with the default one prefixed
with an asterisk (``*``). In the example above, the default click method is
button-areas but clickinger is available.
button-areas but clickfinger is available.
.. note:: This tool is intended for human-consumption and may change its output
at any time.
......
......@@ -27,6 +27,9 @@ required for a touchpad device and how to add the required
change at any time**. Users are advised to :ref:`report a bug <reporting_bugs>`
with the updated pressure ranges when testing has completed.
.. note:: Most distributions ship ``libinput measure`` in a separate
``libinput-utils`` package.
Use the ``libinput measure touchpad-pressure`` tool provided by libinput.
This tool will search for your touchpad device and print some pressure
statistics, including whether a touch is/was considered logically down.
......@@ -124,6 +127,9 @@ required for a touchpad device and how to add the required
change at any time**. Users are advised to :ref:`report a bug <reporting_bugs>`
with the updated pressure ranges when testing has completed.
.. note:: Most distributions ship ``libinput measure`` in a separate
``libinput-utils`` package.
Use the ``libinput measure touch-size`` tool provided by libinput.
This tool will search for your touchpad device and print some touch size
statistics, including whether a touch is/was considered logically down.
......
project('libinput', 'c',
version : '1.13.0',
version : '1.13.4',
license : 'MIT/Expat',
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
meson_version : '>= 0.41.0')
......@@ -259,8 +259,8 @@ quirks_data = [
'quirks/30-vendor-microsoft.quirks',
'quirks/30-vendor-razer.quirks',
'quirks/30-vendor-synaptics.quirks',
'quirks/30-vendor-wacom.quirks',
'quirks/30-vendor-vmware.quirks',
'quirks/30-vendor-wacom.quirks',
'quirks/50-system-acer.quirks',
'quirks/50-system-apple.quirks',
'quirks/50-system-asus.quirks',
......@@ -271,8 +271,13 @@ quirks_data = [
'quirks/50-system-hp.quirks',
'quirks/50-system-lenovo.quirks',
'quirks/50-system-system76.quirks',
'quirks/50-system-toshiba.quirks',
]
test('quirks-in-meson.build',
find_program('quirks/test-quirks-in-meson.build.sh'),
args : [meson.source_root()])
config_h.set_quoted('LIBINPUT_QUIRKS_FILES', ':'.join(quirks_data))
config_h.set_quoted('LIBINPUT_QUIRKS_SRCDIR', dir_src_quirks)
......
......@@ -39,3 +39,9 @@ MatchUdevType=mouse
MatchVendor=0x17EF
MatchProduct=0x6049
ModelLenovoScrollPoint=1
[IBM USB Travel Keyboard with Ultra Nav Mouse]
MatchUdevType=pointingstick
MatchVendor=0x04B3
MatchProduct=0x301E
AttrTrackpointMultiplier=1.50
......@@ -14,6 +14,14 @@ MatchVendor=0x05AC
MatchBus=bluetooth
MatchUdevType=touchpad
ModelAppleTouchpad=1
AttrTouchSizeRange=150:130
[Apple Touchpads Bluetooth (new vendor ID)]
MatchVendor=0x004C
MatchBus=bluetooth
MatchUdevType=touchpad
ModelAppleTouchpad=1
AttrTouchSizeRange=150:130
[Apple Internal Keyboard]
MatchName=*Apple Inc. Apple Internal Keyboard*
......
......@@ -41,3 +41,9 @@ MatchDMIModalias=dmi:*svnHP:pnHPSpectrex360Convertible15-bl1XX:*
AttrPressureRange=55:40
AttrThumbPressureThreshold=90
AttrPalmPressureThreshold=100
[HP Spectre x360 Convertible 13-ap0xxx]
MatchUdevType=tablet
MatchName=ELAN2514:00 04F3:2812
MatchDMIModalias=dmi:*svnHP:pnHPSpectrex360Convertible13-ap0xxx:*
ModelTabletNoProximityOut=1
......@@ -20,6 +20,11 @@ MatchName=Synaptics tm2964-001
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT440p*
ModelLenovoT450Touchpad=1
[Lenovo T480 Trackpoint]
MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT480:*
AttrTrackpointMultiplier=0.4
[Lenovo T480s Touchpad]
MatchName=Elan Touchpad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT480s*
......@@ -40,6 +45,11 @@ MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX20??:*
AttrTrackpointMultiplier=1.25
[Lenovo X230 Trackpoint]
MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX230:*
AttrTrackpointMultiplier=0.25
[Lenovo P50 Touchpad]
MatchName=SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadP50*:
......@@ -76,13 +86,20 @@ MatchName=*TPPS/2 Elan TrackPoint*
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX1Carbon6th*
AttrTrackpointMultiplier=0.4
[Lenovo ThinkPad Compact USB Keyboard with TrackPoint]
[Lenovo ThinkPad Compact USB Keyboard with TrackPoint (keyboard)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x6047
AttrKeyboardIntegration=external
[Lenovo ThinkPad Compact USB Keyboard with TrackPoint (trackpoint)]
MatchUdevType=pointingstick
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x6047
AttrPointingStickIntegration=external
# Lenovo Thinkpad Yoga (not the consumer versions) disables the keyboard
# mechanically. We must not disable the keyboard because some keys are
# still accessible on the screen and volume rocker.
......@@ -92,6 +109,11 @@ MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPad*Yoga*:*
ModelTabletModeNoSuspend=1
[Lenovo X1 Yoga Trackpoint 1st gen]
MatchName=*TPPS/2 IBM TrackPoint
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX1Yoga1st:*
AttrTrackpointMultiplier=1.25
# Lenovo Carbon X1 6th gen (RMI4 only, PS/2 is broken on this device,
# sends bogus ABS_MT_TOOL_TYPE events for MT_TOOL_PALM
[Lenovo Carbon X1 6th gen]
......
#!/bin/bash -e
pushd "$1" > /dev/null
diff -u1 <(grep -o 'quirks/.*\.quirks' meson.build) <(ls quirks/*.quirks)
popd > /dev/null
......@@ -311,7 +311,7 @@ fallback_flush_mt_down(struct fallback_dispatch *dispatch,
if (seat_slot == -1)
return false;
seat->slot_map |= 1 << seat_slot;
seat->slot_map |= bit(seat_slot);
point = slot->point;
slot->hysteresis_center = point;
evdev_transform_absolute(device, &point);
......@@ -374,7 +374,7 @@ fallback_flush_mt_up(struct fallback_dispatch *dispatch,
if (seat_slot == -1)
return false;
seat->slot_map &= ~(1 << seat_slot);
seat->slot_map &= ~bit(seat_slot);
touch_notify_touch_up(base, time, slot_idx, seat_slot);
......@@ -402,7 +402,7 @@ fallback_flush_mt_cancel(struct fallback_dispatch *dispatch,
if (seat_slot == -1)
return false;
seat->slot_map &= ~(1 << seat_slot);
seat->slot_map &= ~bit(seat_slot);
touch_notify_touch_cancel(base, time, slot_idx, seat_slot);
......@@ -434,7 +434,7 @@ fallback_flush_st_down(struct fallback_dispatch *dispatch,
if (seat_slot == -1)
return false;
seat->slot_map |= 1 << seat_slot;
seat->slot_map |= bit(seat_slot);
point = dispatch->abs.point;
evdev_transform_absolute(device, &point);
......@@ -484,7 +484,7 @@ fallback_flush_st_up(struct fallback_dispatch *dispatch,
if (seat_slot == -1)
return false;
seat->slot_map &= ~(1 << seat_slot);
seat->slot_map &= ~bit(seat_slot);
touch_notify_touch_up(base, time, -1, seat_slot);
......@@ -509,7 +509,7 @@ fallback_flush_st_cancel(struct fallback_dispatch *dispatch,
if (seat_slot == -1)
return false;
seat->slot_map &= ~(1 << seat_slot);
seat->slot_map &= ~bit(seat_slot);
touch_notify_touch_cancel(base, time, -1, seat_slot);
......@@ -1382,8 +1382,8 @@ fallback_tablet_mode_switch_event(uint64_t time,
}
static void
fallback_keyboard_pair_tablet_mode(struct evdev_device *keyboard,
struct evdev_device *tablet_mode_switch)
fallback_pair_tablet_mode(struct evdev_device *keyboard,
struct evdev_device *tablet_mode_switch)
{
struct fallback_dispatch *dispatch =
fallback_dispatch(keyboard->dispatch);
......@@ -1391,8 +1391,12 @@ fallback_keyboard_pair_tablet_mode(struct evdev_device *keyboard,
if ((keyboard->tags & EVDEV_TAG_EXTERNAL_KEYBOARD))
return;
if ((keyboard->tags &
(EVDEV_TAG_TRACKPOINT|EVDEV_TAG_INTERNAL_KEYBOARD)) == 0)
if ((keyboard->tags & EVDEV_TAG_TRACKPOINT)) {
if (keyboard->tags & EVDEV_TAG_EXTERNAL_MOUSE)
return;
/* This filters out all internal keyboard-like devices (Video
* Switch) */
} else if ((keyboard->tags & EVDEV_TAG_INTERNAL_KEYBOARD) == 0)
return;
if (evdev_device_has_model_quirk(keyboard,
......@@ -1429,7 +1433,7 @@ fallback_interface_device_added(struct evdev_device *device,
struct evdev_device *added_device)
{
fallback_lid_pair_keyboard(device, added_device);
fallback_keyboard_pair_tablet_mode(device, added_device);
fallback_pair_tablet_mode(device, added_device);
}
static void
......
......@@ -797,7 +797,7 @@ tp_click_get_default_method(struct tp_dispatch *tp)
if (!tp->buttons.is_clickpad)
return LIBINPUT_CONFIG_CLICK_METHOD_NONE;
else if (libevdev_get_id_vendor(tp->device->evdev) == VENDOR_ID_APPLE)
else if (evdev_device_has_model_quirk(device, QUIRK_MODEL_APPLE_TOUCHPAD))
return LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
return LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
......
......@@ -28,6 +28,10 @@
#include <stdbool.h>
#include <limits.h>
#if HAVE_LIBWACOM
#include <libwacom/libwacom.h>
#endif
#include "quirks.h"
#include "evdev-mt-touchpad.h"
......@@ -464,6 +468,30 @@ tp_get_delta(struct tp_touch *t)
return delta;
}
static inline int32_t
rotated(struct tp_dispatch *tp, unsigned int code, int value)
{
const struct input_absinfo *absinfo;
if (!tp->device->left_handed.enabled ||
!tp->left_handed.rotate)
return value;
switch (code) {
case ABS_X:
case ABS_MT_POSITION_X:
absinfo = tp->device->abs.absinfo_x;
break;
case ABS_Y:
case ABS_MT_POSITION_Y:
absinfo = tp->device->abs.absinfo_y;
break;
default:
abort();
}
return absinfo->maximum - (value - absinfo->minimum);
}
static void
tp_process_absolute(struct tp_dispatch *tp,
const struct input_event *e,
......@@ -476,7 +504,7 @@ tp_process_absolute(struct tp_dispatch *tp,
evdev_device_check_abs_axis_range(tp->device,
e->code,
e->value);
t->point.x = e->value;
t->point.x = rotated(tp, e->code, e->value);
t->time = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
......@@ -485,7 +513,7 @@ tp_process_absolute(struct tp_dispatch *tp,
evdev_device_check_abs_axis_range(tp->device,
e->code,
e->value);
t->point.y = e->value;
t->point.y = rotated(tp, e->code, e->value);
t->time = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
......@@ -536,7 +564,7 @@ tp_process_absolute_st(struct tp_dispatch *tp,
evdev_device_check_abs_axis_range(tp->device,
e->code,
e->value);
t->point.x = e->value;
t->point.x = rotated(tp, e->code, e->value);
t->time = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
......@@ -545,7 +573,7 @@ tp_process_absolute_st(struct tp_dispatch *tp,
evdev_device_check_abs_axis_range(tp->device,
e->code,
e->value);
t->point.y = e->value;
t->point.y = rotated(tp, e->code, e->value);
t->time = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
......@@ -3700,11 +3728,80 @@ tp_change_to_left_handed(struct evdev_device *device)
device->left_handed.enabled = device->left_handed.want_enabled;
}
static bool
tp_init_left_handed_rotation(struct tp_dispatch *tp,
struct evdev_device *device)
{
bool rotate = false;
#if HAVE_LIBWACOM
WacomDeviceDatabase *db;
WacomDevice **devices = NULL,
**d;
WacomDevice *dev;
uint32_t vid = evdev_device_get_id_vendor(device),
pid = evdev_device_get_id_product(device);
db = libwacom_database_new();
if (!db) {
evdev_log_info(device,
"Failed to initialize libwacom context.\n");
goto out;
}
/* Check if we have a device with the same vid/pid. If not,
we need to loop through all devices and check their paired
device. */
dev = libwacom_new_from_usbid(db, vid, pid, NULL);
if (dev) {
rotate = libwacom_is_reversible(dev);
libwacom_destroy(dev);
goto out;
}
devices = libwacom_list_devices_from_database(db, NULL);
if (!devices)
goto out;
d = devices;
while(*d) {
const WacomMatch *paired;
paired = libwacom_get_paired_device(*d);
if (paired &&
libwacom_match_get_vendor_id(paired) == vid &&
libwacom_match_get_product_id(paired) == pid) {
rotate = libwacom_is_reversible(dev);
break;
}
d++;
}
free(devices);
out:
if (db)
libwacom_database_destroy(db);
#endif
return rotate;
}
static void
tp_init_left_handed(struct tp_dispatch *tp,
struct evdev_device *device)
{
bool want_left_handed = true;
if (device->model_flags & EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON)
want_left_handed = false;
if (want_left_handed)
evdev_init_left_handed(device, tp_change_to_left_handed);
tp->left_handed.rotate = tp_init_left_handed_rotation(tp, device);
}
struct evdev_dispatch *
evdev_mt_touchpad_create(struct evdev_device *device)
{
struct tp_dispatch *tp;
bool want_left_handed = true;
evdev_tag_touchpad(device, device->udev_device);
......@@ -3723,10 +3820,7 @@ evdev_mt_touchpad_create(struct evdev_device *device)
tp->sendevents.config.get_mode = tp_sendevents_get_mode;
tp->sendevents.config.get_default_mode = tp_sendevents_get_default_mode;
if (device->model_flags & EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON)
want_left_handed = false;
if (want_left_handed)
evdev_init_left_handed(device, tp_change_to_left_handed);
tp_init_left_handed(tp, device);
return &tp->base;
}
......@@ -485,6 +485,11 @@ struct tp_dispatch {
struct libinput_event_listener listener;
struct evdev_device *tablet_mode_switch;
} tablet_mode_switch;
struct {
/* true if the axes need rotation when left-handed is on*/
bool rotate;
} left_handed;
};
static inline struct tp_dispatch*
......
......@@ -50,7 +50,7 @@
#endif
#define DEFAULT_WHEEL_CLICK_ANGLE 15
#define DEFAULT_BUTTON_SCROLL_TIMEOUT ms2us(38)
#define DEFAULT_BUTTON_SCROLL_TIMEOUT ms2us(200)
enum evdev_device_udev_tags {
EVDEV_UDEV_TAG_INPUT = bit(0),
......@@ -387,10 +387,34 @@ static void
evdev_tag_trackpoint(struct evdev_device *device,
struct udev_device *udev_device)
{
if (libevdev_has_property(device->evdev,
INPUT_PROP_POINTING_STICK) ||
parse_udev_flag(device, udev_device, "ID_INPUT_POINTINGSTICK"))
device->tags |= EVDEV_TAG_TRACKPOINT;
struct quirks_context *quirks;
struct quirks *q;
char *prop;
if (!libevdev_has_property(device->evdev,
INPUT_PROP_POINTING_STICK) &&
!parse_udev_flag(device, udev_device, "ID_INPUT_POINTINGSTICK"))
return;
device->tags |= EVDEV_TAG_TRACKPOINT;
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
if (q && quirks_get_string(q, QUIRK_ATTR_TRACKPOINT_INTEGRATION, &prop)) {
if (streq(prop, "internal")) {
/* noop, this is the default anyway */
} else if (streq(prop, "external")) {
device->tags |= EVDEV_TAG_EXTERNAL_MOUSE;
evdev_log_info(device,
"is an external pointing stick\n");
} else {
evdev_log_info(device,
"tagged with unknown value %s\n",
prop);
}
}
quirks_unref(q);
}
static inline void
......
This diff is collapsed.
......@@ -261,6 +261,7 @@ quirk_get_name(enum quirk q)
case QUIRK_ATTR_PALM_SIZE_THRESHOLD: return "AttrPalmSizeThreshold";
case QUIRK_ATTR_LID_SWITCH_RELIABILITY: return "AttrLidSwitchReliability";
case QUIRK_ATTR_KEYBOARD_INTEGRATION: return "AttrKeyboardIntegration";
case QUIRK_ATTR_TRACKPOINT_INTEGRATION: return "AttrPointingStickIntegration";
case QUIRK_ATTR_TPKBCOMBO_LAYOUT: return "AttrTPKComboLayout";
case QUIRK_ATTR_PRESSURE_RANGE: return "AttrPressureRange";
case QUIRK_ATTR_PALM_PRESSURE_THRESHOLD: return "AttrPalmPressureThreshold";
......@@ -661,6 +662,13 @@ parse_attr(struct quirks_context *ctx,
p->type = PT_STRING;
p->value.s = safe_strdup(value);
rc = true;
} else if (streq(key, quirk_get_name(QUIRK_ATTR_TRACKPOINT_INTEGRATION))) {
p->id = QUIRK_ATTR_TRACKPOINT_INTEGRATION;
if (!streq(value, "internal") && !streq(value, "external"))
goto out;
p->type = PT_STRING;
p->value.s = safe_strdup(value);
rc = true;
} else if (streq(key, quirk_get_name(QUIRK_ATTR_TPKBCOMBO_LAYOUT))) {
p->id = QUIRK_ATTR_TPKBCOMBO_LAYOUT;
if (!streq(value, "below"))
......@@ -1227,6 +1235,7 @@ match_fill_udev_type(struct match *m,
{ "ID_INPUT_TABLET_PAD", UDEV_TABLET_PAD },
{ "ID_INPUT_JOYSTICK", UDEV_JOYSTICK },
{ "ID_INPUT_KEYBOARD", UDEV_KEYBOARD },
{ "ID_INPUT_KEY", UDEV_KEYBOARD },
};
struct ut_map *map;
......
......@@ -96,6 +96,7 @@ enum quirk {
QUIRK_ATTR_PALM_SIZE_THRESHOLD,
QUIRK_ATTR_LID_SWITCH_RELIABILITY,
QUIRK_ATTR_KEYBOARD_INTEGRATION,
QUIRK_ATTR_TRACKPOINT_INTEGRATION,
QUIRK_ATTR_TPKBCOMBO_LAYOUT,
QUIRK_ATTR_PRESSURE_RANGE,
QUIRK_ATTR_PALM_PRESSURE_THRESHOLD,
......
......@@ -71,8 +71,10 @@ static struct input_id input_id = {
};
static int events[] = {
EV_KEY, BTN_TOOL_FINGER,
EV_KEY, BTN_TOUCH,
INPUT_PROP_MAX, INPUT_PROP_DIRECT,
EV_KEY, BTN_TOOL_DOUBLETAP,
INPUT_PROP_MAX, INPUT_PROP_POINTER,
-1, -1,
};
......@@ -87,7 +89,7 @@ static const char udev_rule[] =
TEST_DEVICE("wacom-bamboo-2fg-finger",
.type = LITEST_WACOM_BAMBOO_2FG_FINGER,
.features = LITEST_TOUCH,
.features = LITEST_TOUCHPAD,
.interface = &interface,
.name = "Wacom Bamboo 2F 4x5 Finger",
......
......@@ -112,7 +112,7 @@ static const char udev_rule[] =
"\n"
"LABEL=\"rule_end\"";
TEST_DEVICE("wacom-finger",
TEST_DEVICE("wacom-intuos5-finger",
.type = LITEST_WACOM_FINGER,
.features = LITEST_TOUCHPAD,
.interface = &interface,
......
......@@ -100,7 +100,7 @@ static const char udev_rule[] =
"\n"
"LABEL=\"pad_end\"";
TEST_DEVICE("wacom-pad",
TEST_DEVICE("wacom-intuos5-pad",
.type = LITEST_WACOM_INTUOS5_PAD,
.features = LITEST_TABLET_PAD | LITEST_RING,
.interface = &interface,
......
......@@ -151,7 +151,7 @@ static const char udev_rule[] =
"\n"
"LABEL=\"rule_end\"";
TEST_DEVICE("wacom-intuos-tablet",
TEST_DEVICE("wacom-intuos5-tablet",
.type = LITEST_WACOM_INTUOS,
.features = LITEST_TABLET | LITEST_DISTANCE | LITEST_TOOL_SERIAL | LITEST_TILT | LITEST_TOOL_MOUSE | LITEST_HOVER,
.interface = &interface,
......
......@@ -3640,7 +3640,7 @@ litest_timeout_softbuttons(void)
void
litest_timeout_buttonscroll(void)
{
msleep(45);
msleep(300);
}
void
......
......@@ -173,6 +173,7 @@ START_TEST(gestures_swipe_3fg_btntool)
};
if (libevdev_get_num_slots(dev->evdev) > 2 ||
!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP) ||
!libinput_device_has_capability(dev->libinput_device,
LIBINPUT_DEVICE_CAP_GESTURE))
return;
......
......@@ -1204,6 +1204,39 @@ START_TEST(quirks_parse_string_attr)
}
END_TEST
START_TEST(quirks_parse_integration_attr)
{
struct litest_device *dev = litest_current_device();
char *do_not_use; /* freed before we can use it */
bool
rc = test_attr_parse(dev,
QUIRK_ATTR_KEYBOARD_INTEGRATION,
"internal",
(qparsefunc)quirks_get_string,
&do_not_use);
ck_assert(rc);
rc = test_attr_parse(dev,
QUIRK_ATTR_KEYBOARD_INTEGRATION,
"external",
(qparsefunc)quirks_get_string,
&do_not_use);
ck_assert(rc);
rc = test_attr_parse(dev,
QUIRK_ATTR_TRACKPOINT_INTEGRATION,
"internal",
(qparsefunc)quirks_get_string,
&do_not_use);
ck_assert(rc);
rc = test_attr_parse(dev,
QUIRK_ATTR_TRACKPOINT_INTEGRATION,
"external",
(qparsefunc)quirks_get_string,
&do_not_use);
ck_assert(rc);
}
END_TEST
START_TEST(quirks_model_one)
{
struct litest_device *dev = litest_current_device();
......@@ -1432,6 +1465,7 @@ TEST_COLLECTION(quirks)
litest_add_for_device("quirks:parsing", quirks_parse_uint_attr, LITEST_MOUSE);
litest_add_for_device("quirks:parsing", quirks_parse_double_attr, LITEST_MOUSE);
litest_add_for_device("quirks:parsing", quirks_parse_string_attr, LITEST_MOUSE);
litest_add_for_device("quirks:parsing", quirks_parse_integration_attr, LITEST_MOUSE);
litest_add_for_device("quirks:model", quirks_model_one, LITEST_MOUSE);
litest_add_for_device("quirks:model", quirks_model_zero, LITEST_MOUSE);
......
......@@ -936,8 +936,8 @@ START_TEST(touchpad_2fg_tap_n_drag_3fg_btntool)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (libevdev_get_abs_maximum(dev->evdev,
ABS_MT_SLOT) > 2)
if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) > 2 ||
!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP))
return;
litest_enable_tap(dev->libinput_device);
......@@ -1676,7 +1676,8 @@ START_TEST(touchpad_3fg_tap_pressure_btntool)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) >= 2)
if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) >= 2 ||
!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP))
return;
/* libinput doesn't export when it uses pressure detection, so we
......@@ -1736,8 +1737,9 @@ START_TEST(touchpad_3fg_tap_hover_btntool)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) >= 2)
return;
if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) >= 2 ||
!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP))
return;
/* libinput doesn't export when it uses pressure detection, so we
* need to reconstruct this here. Specifically, semi-mt devices are
......@@ -1789,8 +1791,8 @@ START_TEST(touchpad_3fg_tap_btntool)
enum libinput_config_tap_button_map map = _i; /* ranged test */
unsigned int button = 0;
if (libevdev_get_abs_maximum(dev->evdev,
ABS_MT_SLOT) > 2)
if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) > 2 ||
!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP))
return;
litest_enable_tap(dev->libinput_device);
......@@ -1839,8 +1841,8 @@ START_TEST(touchpad_3fg_tap_btntool_inverted)
enum libinput_config_tap_button_map map = _i; /* ranged test */
unsigned int button = 0;
if (libevdev_get_abs_maximum(dev->evdev,
ABS_MT_SLOT) > 2)
if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) > 2 ||
!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP))
return;
litest_enable_tap(dev->libinput_device);
......@@ -1889,8 +1891,8 @@ START_TEST(touchpad_3fg_tap_btntool_pointerjump)
enum libinput_config_tap_button_map map = _i; /* ranged test */
unsigned int button = 0;
if (libevdev_get_abs_maximum(dev->evdev,
ABS_MT_SLOT) > 2)
if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) > 2 ||
!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_TRIPLETAP))
return;
litest_enable_tap(dev->libinput_device);
......
......@@ -2096,6 +2096,7 @@ START_TEST(touchpad_palm_clickfinger_size_2fg)
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(touchpad_left_handed)
{
struct litest_device *dev = litest_current_device();
......@@ -2430,6 +2431,64 @@ START_TEST(touchpad_left_handed_clickpad_delayed)
}
END_TEST
static inline bool
touchpad_has_rotation(struct libevdev *evdev)
{
return libevdev_get_id_vendor(evdev) == VENDOR_ID_WACOM;
}
START_TEST(touchpad_left_handed_rotation)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *d = dev->libinput_device;
struct libinput *li = dev->libinput;
enum libinput_config_status status;
struct libinput_event *event;
struct libinput_event_pointer *p;
bool rotate = touchpad_has_rotation(dev->evdev);
if (!libinput_device_config_left_handed_is_available(d))
return;
status = libinput_device_config_left_handed_set(d, 1);
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
litest_drain_events(li);
litest_touch_down(dev, 0, 20, 80);
litest_touch_move_to(dev, 0, 20, 80, 80, 20, 20);
litest_touch_up(dev, 0);
libinput_dispatch(li);
event = libinput_get_event(li);
ck_assert_notnull(event);
do {
double x, y, ux, uy;
p = litest_is_motion_event(event);
x = libinput_event_pointer_get_dx(p);
y = libinput_event_pointer_get_dy(p);
ux = libinput_event_pointer_get_dx_unaccelerated(p);
uy = libinput_event_pointer_get_dy_unaccelerated(p);
if (rotate) {
ck_assert_double_lt(x, 0);
ck_assert_double_gt(y, 0);
ck_assert_double_lt(ux, 0);
ck_assert_double_gt(uy, 0);
} else {
ck_assert_double_gt(x, 0);
ck_assert_double_lt(y, 0);
ck_assert_double_gt(ux, 0);
ck_assert_double_lt(uy, 0);
}
libinput_event_destroy(event);
} while ((event = libinput_get_event(li)));
}
END_TEST
static void
hover_continue(struct litest_device *dev, unsigned int slot,
int x, int y)
......@@ -7010,6 +7069,7 @@ TEST_COLLECTION(touchpad)
litest_add("touchpad:left-handed", touchpad_left_handed_tapping_2fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:left-handed", touchpad_left_handed_delayed, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_CLICKPAD);
litest_add("touchpad:left-handed", touchpad_left_handed_clickpad_delayed, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
litest_add("touchpad:left-handed", touchpad_left_handed_rotation, LITEST_TOUCHPAD, LITEST_ANY);
/* Semi-MT hover tests aren't generic, they only work on this device and
* ignore the semi-mt capability (it doesn't matter for the tests) */
......
......@@ -31,6 +31,13 @@
...
fun:g_malloc0
}
{
<g_get_language_names_malloc>
Memcheck:Leak
fun:malloc
...
fun:g_get_language_names_with_category
}
{
libunwind:msync_uninitialized_bytes
Memcheck:Param
......
......@@ -229,7 +229,7 @@ print_evdev_event(struct record_context *ctx, struct input_event *ev)
snprintf(desc,
sizeof(desc),
"%s / %-20s %4d%s",
"%s / %-20s %6d%s",
tname,
cname,
ev->value,
......@@ -237,7 +237,7 @@ print_evdev_event(struct record_context *ctx, struct input_event *ev)
}
iprintf(ctx,
"- [%3lu, %6u, %3d, %3d, %5d] # %s\n",
"- [%3lu, %6u, %3d, %3d, %6d] # %s\n",
ev->time.tv_sec,
(unsigned int)ev->time.tv_usec,
ev->type,
......
......@@ -54,7 +54,7 @@ class TestLibinputTool(unittest.TestCase):
# never get rc 2 (invalid usage)
self.assertIn(rc, [0, 1])
def run_command_unrecognised_option(self, args):
def run_command_unrecognized_option(self, args):
rc, stdout, stderr = self.run_command(args)
self.assertEqual(rc, 2)
self.assertTrue(stdout.startswith('Usage') or stdout == '')
......@@ -66,7 +66,7 @@ class TestLibinputTool(unittest.TestCase):
self.assertTrue(stdout.startswith('Usage') or stdout == '')
self.assertIn('requires an argument', stderr)
def run_command_unrecognised_tool(self, args):
def run_command_unrecognized_tool(self, args):
rc, stdout, stderr = self.run_command(args)
self.assertEqual(rc, 2)
self.assertTrue(stdout.startswith('Usage') or stdout == '')
......@@ -89,16 +89,16 @@ class TestLibinputCommand(TestLibinputTool):
self.assertEqual(stderr, '')
def test_invalid_arguments(self):
self.run_command_unrecognised_option(['--banana'])
self.run_command_unrecognised_option(['--foo'])
self.run_command_unrecognised_option(['--quiet'])
self.run_command_unrecognised_option(['--verbose'])
self.run_command_unrecognised_option(['--quiet', 'foo'])
self.run_command_unrecognized_option(['--banana'])
self.run_command_unrecognized_option(['--foo'])
self.run_command_unrecognized_option(['--quiet'])
self.run_command_unrecognized_option(['--verbose'])
self.run_command_unrecognized_option(['--quiet', 'foo'])
def test_invalid_tools(self):
self.run_command_unrecognised_tool(['foo'])
self.run_command_unrecognised_tool(['debug'])
self.run_command_unrecognised_tool(['foo', '--quiet'])
self.run_command_unrecognized_tool(['foo'])
self.run_command_unrecognized_tool(['debug'])
self.run_command_unrecognized_tool(['foo', '--quiet'])
class TestToolWithOptions(object):
......@@ -183,9 +183,9 @@ class TestDebugEvents(TestToolWithOptions, TestLibinputTool):
self.assertEqual(rc, 0)
def test_invalid_arguments(self):
self.run_command_unrecognised_option(['--banana'])
self.run_command_unrecognised_option(['--foo'])
self.run_command_unrecognised_option(['--version'])
self.run_command_unrecognized_option(['--banana'])
self.run_command_unrecognized_option(['--foo'])
self.run_command_unrecognized_option(['--version'])
class TestDebugGUI(TestToolWithOptions, TestLibinputTool):
......@@ -201,10 +201,10 @@ class TestDebugGUI(TestToolWithOptions, TestLibinputTool):
self.assertEqual(rc, 0)
def test_invalid_arguments(self):
self.run_command_unrecognised_option(['--quiet'])
self.run_command_unrecognised_option(['--banana'])
self.run_command_unrecognised_option(['--foo'])
self.run_command_unrecognised_option(['--version'])
self.run_command_unrecognized_option(['--quiet'])
self.run_command_unrecognized_option(['--banana'])
self.run_command_unrecognized_option(['--foo'])
self.run_command_unrecognized_option(['--version'])
if __name__ == '__main__':
......