mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-05-05 16:58:04 +02:00
Merge branch 'wip/hysteresis-wobbles'
This commit is contained in:
commit
49a8bd3ca7
7 changed files with 123 additions and 11 deletions
|
|
@ -96,7 +96,7 @@ executable('libinput-device-group',
|
||||||
install_dir : udev_dir)
|
install_dir : udev_dir)
|
||||||
executable('libinput-model-quirks',
|
executable('libinput-model-quirks',
|
||||||
'udev/libinput-model-quirks.c',
|
'udev/libinput-model-quirks.c',
|
||||||
dependencies : dep_udev,
|
dependencies : [dep_udev, dep_libevdev],
|
||||||
include_directories : [includes_src, includes_include],
|
include_directories : [includes_src, includes_include],
|
||||||
install : true,
|
install : true,
|
||||||
install_dir : udev_dir)
|
install_dir : udev_dir)
|
||||||
|
|
|
||||||
|
|
@ -130,12 +130,13 @@ fallback_filter_defuzz_touch(struct fallback_dispatch *dispatch,
|
||||||
point = evdev_hysteresis(&slot->point,
|
point = evdev_hysteresis(&slot->point,
|
||||||
&slot->hysteresis_center,
|
&slot->hysteresis_center,
|
||||||
&dispatch->mt.hysteresis_margin);
|
&dispatch->mt.hysteresis_margin);
|
||||||
|
slot->point = point;
|
||||||
|
|
||||||
slot->hysteresis_center = slot->point;
|
if (point.x == slot->hysteresis_center.x &&
|
||||||
if (point.x == slot->point.x && point.y == slot->point.y)
|
point.y == slot->hysteresis_center.y)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
slot->point = point;
|
slot->hysteresis_center = point;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3099,13 +3099,25 @@ tp_init_default_resolution(struct tp_dispatch *tp,
|
||||||
static inline void
|
static inline void
|
||||||
tp_init_hysteresis(struct tp_dispatch *tp)
|
tp_init_hysteresis(struct tp_dispatch *tp)
|
||||||
{
|
{
|
||||||
int res_x, res_y;
|
int xmargin, ymargin;
|
||||||
|
const struct input_absinfo *ax = tp->device->abs.absinfo_x,
|
||||||
|
*ay = tp->device->abs.absinfo_y;
|
||||||
|
|
||||||
res_x = tp->device->abs.absinfo_x->resolution;
|
if (ax->fuzz)
|
||||||
res_y = tp->device->abs.absinfo_y->resolution;
|
xmargin = ax->fuzz;
|
||||||
tp->hysteresis.margin.x = res_x/2;
|
else
|
||||||
tp->hysteresis.margin.y = res_y/2;
|
xmargin = ax->resolution/4;
|
||||||
tp->hysteresis.enabled = false;
|
|
||||||
|
if (ay->fuzz)
|
||||||
|
ymargin = ay->fuzz;
|
||||||
|
else
|
||||||
|
ymargin = ay->resolution/4;
|
||||||
|
|
||||||
|
tp->hysteresis.margin.x = xmargin;
|
||||||
|
tp->hysteresis.margin.y = ymargin;
|
||||||
|
tp->hysteresis.enabled = (ax->fuzz || ay->fuzz);
|
||||||
|
if (tp->hysteresis.enabled)
|
||||||
|
evdev_log_debug(tp->device, "hysteresis enabled\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
39
src/evdev.c
39
src/evdev.c
|
|
@ -1511,6 +1511,7 @@ static void
|
||||||
evdev_extract_abs_axes(struct evdev_device *device)
|
evdev_extract_abs_axes(struct evdev_device *device)
|
||||||
{
|
{
|
||||||
struct libevdev *evdev = device->evdev;
|
struct libevdev *evdev = device->evdev;
|
||||||
|
int fuzz;
|
||||||
|
|
||||||
if (!libevdev_has_event_code(evdev, EV_ABS, ABS_X) ||
|
if (!libevdev_has_event_code(evdev, EV_ABS, ABS_X) ||
|
||||||
!libevdev_has_event_code(evdev, EV_ABS, ABS_Y))
|
!libevdev_has_event_code(evdev, EV_ABS, ABS_Y))
|
||||||
|
|
@ -1518,6 +1519,12 @@ evdev_extract_abs_axes(struct evdev_device *device)
|
||||||
|
|
||||||
if (evdev_fix_abs_resolution(device, ABS_X, ABS_Y))
|
if (evdev_fix_abs_resolution(device, ABS_X, ABS_Y))
|
||||||
device->abs.is_fake_resolution = true;
|
device->abs.is_fake_resolution = true;
|
||||||
|
|
||||||
|
if ((fuzz = evdev_read_fuzz_prop(device, ABS_X)))
|
||||||
|
libevdev_set_abs_fuzz(evdev, ABS_X, fuzz);
|
||||||
|
if ((fuzz = evdev_read_fuzz_prop(device, ABS_Y)))
|
||||||
|
libevdev_set_abs_fuzz(evdev, ABS_Y, fuzz);
|
||||||
|
|
||||||
device->abs.absinfo_x = libevdev_get_abs_info(evdev, ABS_X);
|
device->abs.absinfo_x = libevdev_get_abs_info(evdev, ABS_X);
|
||||||
device->abs.absinfo_y = libevdev_get_abs_info(evdev, ABS_Y);
|
device->abs.absinfo_y = libevdev_get_abs_info(evdev, ABS_Y);
|
||||||
device->abs.dimensions.x = abs(device->abs.absinfo_x->maximum -
|
device->abs.dimensions.x = abs(device->abs.absinfo_x->maximum -
|
||||||
|
|
@ -1535,6 +1542,11 @@ evdev_extract_abs_axes(struct evdev_device *device)
|
||||||
ABS_MT_POSITION_Y))
|
ABS_MT_POSITION_Y))
|
||||||
device->abs.is_fake_resolution = true;
|
device->abs.is_fake_resolution = true;
|
||||||
|
|
||||||
|
if ((fuzz = evdev_read_fuzz_prop(device, ABS_MT_POSITION_X)))
|
||||||
|
libevdev_set_abs_fuzz(evdev, ABS_MT_POSITION_X, fuzz);
|
||||||
|
if ((fuzz = evdev_read_fuzz_prop(device, ABS_MT_POSITION_Y)))
|
||||||
|
libevdev_set_abs_fuzz(evdev, ABS_MT_POSITION_Y, fuzz);
|
||||||
|
|
||||||
device->abs.absinfo_x = libevdev_get_abs_info(evdev, ABS_MT_POSITION_X);
|
device->abs.absinfo_x = libevdev_get_abs_info(evdev, ABS_MT_POSITION_X);
|
||||||
device->abs.absinfo_y = libevdev_get_abs_info(evdev, ABS_MT_POSITION_Y);
|
device->abs.absinfo_y = libevdev_get_abs_info(evdev, ABS_MT_POSITION_Y);
|
||||||
device->abs.dimensions.x = abs(device->abs.absinfo_x->maximum -
|
device->abs.dimensions.x = abs(device->abs.absinfo_x->maximum -
|
||||||
|
|
@ -2170,6 +2182,33 @@ evdev_read_calibration_prop(struct evdev_device *device)
|
||||||
calibration[5]);
|
calibration[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
evdev_read_fuzz_prop(struct evdev_device *device, unsigned int code)
|
||||||
|
{
|
||||||
|
const char *prop;
|
||||||
|
char name[32];
|
||||||
|
int rc;
|
||||||
|
int fuzz = 0;
|
||||||
|
|
||||||
|
rc = snprintf(name, sizeof(name), "LIBINPUT_FUZZ_%02x", code);
|
||||||
|
if (rc == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
prop = udev_device_get_property_value(device->udev_device, name);
|
||||||
|
if (prop == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rc = safe_atoi(prop, &fuzz);
|
||||||
|
if (rc == -1 || fuzz < 0) {
|
||||||
|
evdev_log_bug_libinput(device,
|
||||||
|
"invalid LIBINPUT_FUZZ property value: %s\n",
|
||||||
|
prop);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fuzz;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
||||||
|
|
@ -379,6 +379,9 @@ evdev_init_calibration(struct evdev_device *device,
|
||||||
void
|
void
|
||||||
evdev_read_calibration_prop(struct evdev_device *device);
|
evdev_read_calibration_prop(struct evdev_device *device);
|
||||||
|
|
||||||
|
int
|
||||||
|
evdev_read_fuzz_prop(struct evdev_device *device, unsigned int code);
|
||||||
|
|
||||||
enum switch_reliability
|
enum switch_reliability
|
||||||
evdev_read_switch_reliability_prop(struct evdev_device *device);
|
evdev_read_switch_reliability_prop(struct evdev_device *device);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ KERNEL!="event*", GOTO="libinput_model_quirks_end"
|
||||||
# First, run the program and import the LIBINPUT_MODEL_FIRMWARE_VERSION
|
# First, run the program and import the LIBINPUT_MODEL_FIRMWARE_VERSION
|
||||||
# environment (if any)
|
# environment (if any)
|
||||||
KERNELS=="*input*", \
|
KERNELS=="*input*", \
|
||||||
ENV{ID_INPUT_TOUCHPAD}=="1", \
|
|
||||||
IMPORT{program}="@UDEV_TEST_PATH@libinput-model-quirks %S%p"
|
IMPORT{program}="@UDEV_TEST_PATH@libinput-model-quirks %S%p"
|
||||||
|
|
||||||
# Second, match on anything with that env set and import from the hwdb
|
# Second, match on anything with that env set and import from the hwdb
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libudev.h>
|
#include <libudev.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
|
#include <libevdev/libevdev.h>
|
||||||
|
|
||||||
#include "libinput-util.h"
|
#include "libinput-util.h"
|
||||||
|
|
||||||
|
|
@ -107,6 +108,61 @@ handle_touchpad(struct udev_device *device)
|
||||||
handle_touchpad_synaptics(device);
|
handle_touchpad_synaptics(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For a non-zero fuzz on the x/y axes, print that fuzz as property and
|
||||||
|
* reset the kernel's fuzz to 0.
|
||||||
|
* https://bugs.freedesktop.org/show_bug.cgi?id=105202
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
handle_absfuzz(struct udev_device *device)
|
||||||
|
{
|
||||||
|
const char *devnode;
|
||||||
|
struct libevdev *evdev = NULL;
|
||||||
|
int fd = -1;
|
||||||
|
int rc;
|
||||||
|
unsigned int *code;
|
||||||
|
unsigned int axes[] = {ABS_X,
|
||||||
|
ABS_Y,
|
||||||
|
ABS_MT_POSITION_X,
|
||||||
|
ABS_MT_POSITION_Y};
|
||||||
|
|
||||||
|
devnode = udev_device_get_devnode(device);
|
||||||
|
if (!devnode)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
fd = open(devnode, O_RDWR);
|
||||||
|
if (fd == -1 && errno == EACCES)
|
||||||
|
fd = open(devnode, O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
rc = libevdev_new_from_fd(fd, &evdev);
|
||||||
|
if (rc != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!libevdev_has_event_type(evdev, EV_ABS))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ARRAY_FOR_EACH(axes, code) {
|
||||||
|
struct input_absinfo abs;
|
||||||
|
int fuzz;
|
||||||
|
|
||||||
|
fuzz = libevdev_get_abs_fuzz(evdev, *code);
|
||||||
|
if (!fuzz)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
abs = *libevdev_get_abs_info(evdev, *code);
|
||||||
|
abs.fuzz = 0;
|
||||||
|
libevdev_kernel_set_abs_info(evdev, *code, &abs);
|
||||||
|
|
||||||
|
printf("LIBINPUT_FUZZ_%02x=%d\n", *code, fuzz);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
close(fd);
|
||||||
|
libevdev_free(evdev);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int rc = 1;
|
int rc = 1;
|
||||||
|
|
@ -127,6 +183,8 @@ int main(int argc, char **argv)
|
||||||
if (!device)
|
if (!device)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
handle_absfuzz(device);
|
||||||
|
|
||||||
if (prop_value(device, "ID_INPUT_TOUCHPAD"))
|
if (prop_value(device, "ID_INPUT_TOUCHPAD"))
|
||||||
handle_touchpad(device);
|
handle_touchpad(device);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue