mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-05-07 04:58:21 +02:00
Merge branch 'drop-pointer-normalization'
This commit is contained in:
commit
67ebcc3b8a
16 changed files with 244 additions and 43 deletions
|
|
@ -12,10 +12,33 @@ physical movement or 10 millimeters, depending on the sensor. This
|
||||||
affects pointer acceleration in libinput and interpretation of relative
|
affects pointer acceleration in libinput and interpretation of relative
|
||||||
coordinates in callers.
|
coordinates in callers.
|
||||||
|
|
||||||
libinput normalizes all relative input to a physical resolution of
|
libinput does partial normalization of relative input. For devices with a
|
||||||
1000dpi, the same delta from two different devices thus represents the
|
resolution of 1000dpi and higher, motion events are normalized to a default
|
||||||
same physical movement of those two devices (within sensor error
|
of 1000dpi before pointer acceleration is applied. As a result, devices with
|
||||||
margins).
|
1000dpi and above feel the same.
|
||||||
|
|
||||||
|
Devices below 1000dpi are not normalized (normalization of a 1-device unit
|
||||||
|
movement on a 400dpi mouse would cause a 2.5 pixel movement). Instead,
|
||||||
|
libinput applies a dpi-dependent acceleration function. At low speeds, a
|
||||||
|
1-device unit movement usually translates into a 1-pixel movements. As the
|
||||||
|
movement speed increases, acceleration is applied - at high speeds a low-dpi
|
||||||
|
device will roughly feel the same as a higher-dpi mouse.
|
||||||
|
|
||||||
|
This normalization only applies to accelerated coordinates, unaccelerated
|
||||||
|
coordiantes are left in device-units. It is up to the caller to interpret
|
||||||
|
those coordinates correctly.
|
||||||
|
|
||||||
|
@section Normalization of touchpad coordinates
|
||||||
|
|
||||||
|
Touchpads may have a different resolution for the horizontal and vertical
|
||||||
|
axis. Interpreting coordinates from the touchpad without taking resolutino
|
||||||
|
into account results in uneven motion.
|
||||||
|
|
||||||
|
libinput scales unaccelerated touchpad motion do the resolution of the
|
||||||
|
touchpad's x axis, i.e. the unaccelerated value for the y axis is:
|
||||||
|
y = (x / resolution_x) * resolution_y
|
||||||
|
|
||||||
|
@section Setting custom DPI settings
|
||||||
|
|
||||||
Devices usually do not advertise their resolution and libinput relies on
|
Devices usually do not advertise their resolution and libinput relies on
|
||||||
the udev property <b>MOUSE_DPI</b> for this information. This property is usually
|
the udev property <b>MOUSE_DPI</b> for this information. This property is usually
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,7 @@ static void
|
||||||
tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
|
tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
|
||||||
{
|
{
|
||||||
struct normalized_coords delta, unaccel;
|
struct normalized_coords delta, unaccel;
|
||||||
|
struct device_float_coords raw;
|
||||||
|
|
||||||
/* When a clickpad is clicked, combine motion of all active touches */
|
/* When a clickpad is clicked, combine motion of all active touches */
|
||||||
if (tp->buttons.is_clickpad && tp->buttons.state)
|
if (tp->buttons.is_clickpad && tp->buttons.state)
|
||||||
|
|
@ -101,8 +102,11 @@ tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
|
||||||
delta = tp_filter_motion(tp, &unaccel, time);
|
delta = tp_filter_motion(tp, &unaccel, time);
|
||||||
|
|
||||||
if (!normalized_is_zero(delta) || !normalized_is_zero(unaccel)) {
|
if (!normalized_is_zero(delta) || !normalized_is_zero(unaccel)) {
|
||||||
pointer_notify_motion(&tp->device->base, time,
|
raw = tp_unnormalize_for_xaxis(tp, unaccel);
|
||||||
&delta, &unaccel);
|
pointer_notify_motion(&tp->device->base,
|
||||||
|
time,
|
||||||
|
&delta,
|
||||||
|
&raw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,21 @@ tp_normalize_delta(struct tp_dispatch *tp, struct device_float_coords delta)
|
||||||
return normalized;
|
return normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a dpi-normalized set of coordinates, returns a set of coordinates
|
||||||
|
* in the x-axis' coordinate space.
|
||||||
|
*/
|
||||||
|
static inline struct device_float_coords
|
||||||
|
tp_unnormalize_for_xaxis(struct tp_dispatch *tp, struct normalized_coords delta)
|
||||||
|
{
|
||||||
|
struct device_float_coords raw;
|
||||||
|
|
||||||
|
raw.x = delta.x / tp->accel.x_scale_coeff;
|
||||||
|
raw.y = delta.y / tp->accel.x_scale_coeff; /* <--- not a typo */
|
||||||
|
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
struct normalized_coords
|
struct normalized_coords
|
||||||
tp_get_delta(struct tp_touch *t);
|
tp_get_delta(struct tp_touch *t);
|
||||||
|
|
||||||
|
|
|
||||||
25
src/evdev.c
25
src/evdev.c
|
|
@ -281,6 +281,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
|
||||||
struct libinput_seat *seat = base->seat;
|
struct libinput_seat *seat = base->seat;
|
||||||
struct normalized_coords accel, unaccel;
|
struct normalized_coords accel, unaccel;
|
||||||
struct device_coords point;
|
struct device_coords point;
|
||||||
|
struct device_float_coords raw;
|
||||||
|
|
||||||
slot = device->mt.slot;
|
slot = device->mt.slot;
|
||||||
|
|
||||||
|
|
@ -289,6 +290,8 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
|
||||||
return;
|
return;
|
||||||
case EVDEV_RELATIVE_MOTION:
|
case EVDEV_RELATIVE_MOTION:
|
||||||
normalize_delta(device, &device->rel, &unaccel);
|
normalize_delta(device, &device->rel, &unaccel);
|
||||||
|
raw.x = device->rel.x;
|
||||||
|
raw.y = device->rel.y;
|
||||||
device->rel.x = 0;
|
device->rel.x = 0;
|
||||||
device->rel.y = 0;
|
device->rel.y = 0;
|
||||||
|
|
||||||
|
|
@ -305,7 +308,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
|
||||||
if (normalized_is_zero(accel) && normalized_is_zero(unaccel))
|
if (normalized_is_zero(accel) && normalized_is_zero(unaccel))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pointer_notify_motion(base, time, &accel, &unaccel);
|
pointer_notify_motion(base, time, &accel, &raw);
|
||||||
break;
|
break;
|
||||||
case EVDEV_ABSOLUTE_MT_DOWN:
|
case EVDEV_ABSOLUTE_MT_DOWN:
|
||||||
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
||||||
|
|
@ -1407,7 +1410,8 @@ int
|
||||||
evdev_device_init_pointer_acceleration(struct evdev_device *device,
|
evdev_device_init_pointer_acceleration(struct evdev_device *device,
|
||||||
accel_profile_func_t profile)
|
accel_profile_func_t profile)
|
||||||
{
|
{
|
||||||
device->pointer.filter = create_pointer_accelerator_filter(profile);
|
device->pointer.filter = create_pointer_accelerator_filter(profile,
|
||||||
|
device->dpi);
|
||||||
if (!device->pointer.filter)
|
if (!device->pointer.filter)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
@ -1824,6 +1828,19 @@ evdev_configure_mt_device(struct evdev_device *device)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
evdev_init_accel(struct evdev_device *device)
|
||||||
|
{
|
||||||
|
accel_profile_func_t profile;
|
||||||
|
|
||||||
|
if (device->dpi < DEFAULT_MOUSE_DPI)
|
||||||
|
profile = pointer_accel_profile_linear_low_dpi;
|
||||||
|
else
|
||||||
|
profile = pointer_accel_profile_linear;
|
||||||
|
|
||||||
|
return evdev_device_init_pointer_acceleration(device, profile);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
evdev_configure_device(struct evdev_device *device)
|
evdev_configure_device(struct evdev_device *device)
|
||||||
{
|
{
|
||||||
|
|
@ -1919,9 +1936,7 @@ evdev_configure_device(struct evdev_device *device)
|
||||||
udev_tags & EVDEV_UDEV_TAG_POINTINGSTICK) {
|
udev_tags & EVDEV_UDEV_TAG_POINTINGSTICK) {
|
||||||
if (libevdev_has_event_code(evdev, EV_REL, REL_X) &&
|
if (libevdev_has_event_code(evdev, EV_REL, REL_X) &&
|
||||||
libevdev_has_event_code(evdev, EV_REL, REL_Y) &&
|
libevdev_has_event_code(evdev, EV_REL, REL_Y) &&
|
||||||
evdev_device_init_pointer_acceleration(
|
evdev_init_accel(device) == -1)
|
||||||
device,
|
|
||||||
pointer_accel_profile_linear) == -1)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
device->seat_caps |= EVDEV_DEVICE_POINTER;
|
device->seat_caps |= EVDEV_DEVICE_POINTER;
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,6 @@
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
|
||||||
/* The HW DPI rate we normalize to before calculating pointer acceleration */
|
|
||||||
#define DEFAULT_MOUSE_DPI 1000
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The constant (linear) acceleration factor we use to normalize trackpoint
|
* The constant (linear) acceleration factor we use to normalize trackpoint
|
||||||
* deltas before calculating pointer acceleration.
|
* deltas before calculating pointer acceleration.
|
||||||
|
|
|
||||||
63
src/filter.c
63
src/filter.c
|
|
@ -111,6 +111,8 @@ struct pointer_accelerator {
|
||||||
double threshold; /* units/ms */
|
double threshold; /* units/ms */
|
||||||
double accel; /* unitless factor */
|
double accel; /* unitless factor */
|
||||||
double incline; /* incline of the function */
|
double incline; /* incline of the function */
|
||||||
|
|
||||||
|
double dpi_factor;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -262,8 +264,16 @@ accelerator_filter(struct motion_filter *filter,
|
||||||
double velocity; /* units/ms */
|
double velocity; /* units/ms */
|
||||||
double accel_value; /* unitless factor */
|
double accel_value; /* unitless factor */
|
||||||
struct normalized_coords accelerated;
|
struct normalized_coords accelerated;
|
||||||
|
struct normalized_coords unnormalized;
|
||||||
|
double dpi_factor = accel->dpi_factor;
|
||||||
|
|
||||||
feed_trackers(accel, unaccelerated, time);
|
/* For low-dpi mice, use device units, everything else uses
|
||||||
|
1000dpi normalized */
|
||||||
|
dpi_factor = min(1.0, dpi_factor);
|
||||||
|
unnormalized.x = unaccelerated->x * dpi_factor;
|
||||||
|
unnormalized.y = unaccelerated->y * dpi_factor;
|
||||||
|
|
||||||
|
feed_trackers(accel, &unnormalized, time);
|
||||||
velocity = calculate_velocity(accel, time);
|
velocity = calculate_velocity(accel, time);
|
||||||
accel_value = calculate_acceleration(accel,
|
accel_value = calculate_acceleration(accel,
|
||||||
data,
|
data,
|
||||||
|
|
@ -271,10 +281,10 @@ accelerator_filter(struct motion_filter *filter,
|
||||||
accel->last_velocity,
|
accel->last_velocity,
|
||||||
time);
|
time);
|
||||||
|
|
||||||
accelerated.x = accel_value * unaccelerated->x;
|
accelerated.x = accel_value * unnormalized.x;
|
||||||
accelerated.y = accel_value * unaccelerated->y;
|
accelerated.y = accel_value * unnormalized.y;
|
||||||
|
|
||||||
accel->last = *unaccelerated;
|
accel->last = unnormalized;
|
||||||
|
|
||||||
accel->last_velocity = velocity;
|
accel->last_velocity = velocity;
|
||||||
|
|
||||||
|
|
@ -346,7 +356,8 @@ struct motion_filter_interface accelerator_interface = {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct motion_filter *
|
struct motion_filter *
|
||||||
create_pointer_accelerator_filter(accel_profile_func_t profile)
|
create_pointer_accelerator_filter(accel_profile_func_t profile,
|
||||||
|
int dpi)
|
||||||
{
|
{
|
||||||
struct pointer_accelerator *filter;
|
struct pointer_accelerator *filter;
|
||||||
|
|
||||||
|
|
@ -369,13 +380,51 @@ create_pointer_accelerator_filter(accel_profile_func_t profile)
|
||||||
filter->accel = DEFAULT_ACCELERATION;
|
filter->accel = DEFAULT_ACCELERATION;
|
||||||
filter->incline = DEFAULT_INCLINE;
|
filter->incline = DEFAULT_INCLINE;
|
||||||
|
|
||||||
|
filter->dpi_factor = dpi/(double)DEFAULT_MOUSE_DPI;
|
||||||
|
|
||||||
return &filter->base;
|
return &filter->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom acceleration function for mice < 1000dpi.
|
||||||
|
* At slow motion, a single device unit causes a one-pixel movement.
|
||||||
|
* The threshold/max accel depends on the DPI, the smaller the DPI the
|
||||||
|
* earlier we accelerate and the higher the maximum acceleration is. Result:
|
||||||
|
* at low speeds we get pixel-precision, at high speeds we get approx. the
|
||||||
|
* same movement as a high-dpi mouse.
|
||||||
|
*
|
||||||
|
* Note: data fed to this function is in device units, not normalized.
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
pointer_accel_profile_linear_low_dpi(struct motion_filter *filter,
|
||||||
|
void *data,
|
||||||
|
double speed_in, /* in device units */
|
||||||
|
uint64_t time)
|
||||||
|
{
|
||||||
|
struct pointer_accelerator *accel_filter =
|
||||||
|
(struct pointer_accelerator *)filter;
|
||||||
|
|
||||||
|
double s1, s2;
|
||||||
|
double max_accel = accel_filter->accel; /* unitless factor */
|
||||||
|
const double threshold = accel_filter->threshold; /* units/ms */
|
||||||
|
const double incline = accel_filter->incline;
|
||||||
|
double factor;
|
||||||
|
double dpi_factor = accel_filter->dpi_factor;
|
||||||
|
|
||||||
|
max_accel /= dpi_factor;
|
||||||
|
|
||||||
|
s1 = min(1, 0.3 + speed_in * 10);
|
||||||
|
s2 = 1 + (speed_in - threshold * dpi_factor) * incline;
|
||||||
|
|
||||||
|
factor = min(max_accel, s2 > 1 ? s2 : s1);
|
||||||
|
|
||||||
|
return factor;
|
||||||
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
pointer_accel_profile_linear(struct motion_filter *filter,
|
pointer_accel_profile_linear(struct motion_filter *filter,
|
||||||
void *data,
|
void *data,
|
||||||
double speed_in,
|
double speed_in, /* 1000-dpi normalized */
|
||||||
uint64_t time)
|
uint64_t time)
|
||||||
{
|
{
|
||||||
struct pointer_accelerator *accel_filter =
|
struct pointer_accelerator *accel_filter =
|
||||||
|
|
@ -387,7 +436,7 @@ pointer_accel_profile_linear(struct motion_filter *filter,
|
||||||
const double incline = accel_filter->incline;
|
const double incline = accel_filter->incline;
|
||||||
double factor;
|
double factor;
|
||||||
|
|
||||||
s1 = min(1, 0.3 + speed_in * 4);
|
s1 = min(1, 0.3 + speed_in * 10);
|
||||||
s2 = 1 + (speed_in - threshold) * incline;
|
s2 = 1 + (speed_in - threshold) * incline;
|
||||||
|
|
||||||
factor = min(max_accel, s2 > 1 ? s2 : s1);
|
factor = min(max_accel, s2 > 1 ? s2 : s1);
|
||||||
|
|
|
||||||
|
|
@ -58,13 +58,19 @@ typedef double (*accel_profile_func_t)(struct motion_filter *filter,
|
||||||
uint64_t time);
|
uint64_t time);
|
||||||
|
|
||||||
struct motion_filter *
|
struct motion_filter *
|
||||||
create_pointer_accelerator_filter(accel_profile_func_t filter);
|
create_pointer_accelerator_filter(accel_profile_func_t filter,
|
||||||
|
int dpi);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pointer acceleration profiles.
|
* Pointer acceleration profiles.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
double
|
double
|
||||||
|
pointer_accel_profile_linear_low_dpi(struct motion_filter *filter,
|
||||||
|
void *data,
|
||||||
|
double speed_in,
|
||||||
|
uint64_t time);
|
||||||
|
double
|
||||||
pointer_accel_profile_linear(struct motion_filter *filter,
|
pointer_accel_profile_linear(struct motion_filter *filter,
|
||||||
void *data,
|
void *data,
|
||||||
double speed_in,
|
double speed_in,
|
||||||
|
|
|
||||||
|
|
@ -324,7 +324,7 @@ void
|
||||||
pointer_notify_motion(struct libinput_device *device,
|
pointer_notify_motion(struct libinput_device *device,
|
||||||
uint64_t time,
|
uint64_t time,
|
||||||
const struct normalized_coords *delta,
|
const struct normalized_coords *delta,
|
||||||
const struct normalized_coords *unaccel);
|
const struct device_float_coords *raw);
|
||||||
|
|
||||||
void
|
void
|
||||||
pointer_notify_motion_absolute(struct libinput_device *device,
|
pointer_notify_motion_absolute(struct libinput_device *device,
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,9 @@
|
||||||
#define VENDOR_ID_APPLE 0x5ac
|
#define VENDOR_ID_APPLE 0x5ac
|
||||||
#define VENDOR_ID_WACOM 0x56a
|
#define VENDOR_ID_WACOM 0x56a
|
||||||
|
|
||||||
|
/* The HW DPI rate we normalize to before calculating pointer acceleration */
|
||||||
|
#define DEFAULT_MOUSE_DPI 1000
|
||||||
|
|
||||||
void
|
void
|
||||||
set_logging_enabled(int enabled);
|
set_logging_enabled(int enabled);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ struct libinput_event_pointer {
|
||||||
struct libinput_event base;
|
struct libinput_event base;
|
||||||
uint32_t time;
|
uint32_t time;
|
||||||
struct normalized_coords delta;
|
struct normalized_coords delta;
|
||||||
struct normalized_coords delta_unaccel;
|
struct device_float_coords delta_raw;
|
||||||
struct device_coords absolute;
|
struct device_coords absolute;
|
||||||
struct discrete_coords discrete;
|
struct discrete_coords discrete;
|
||||||
uint32_t button;
|
uint32_t button;
|
||||||
|
|
@ -339,7 +339,7 @@ libinput_event_pointer_get_dx_unaccelerated(
|
||||||
0,
|
0,
|
||||||
LIBINPUT_EVENT_POINTER_MOTION);
|
LIBINPUT_EVENT_POINTER_MOTION);
|
||||||
|
|
||||||
return event->delta_unaccel.x;
|
return event->delta_raw.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBINPUT_EXPORT double
|
LIBINPUT_EXPORT double
|
||||||
|
|
@ -351,7 +351,7 @@ libinput_event_pointer_get_dy_unaccelerated(
|
||||||
0,
|
0,
|
||||||
LIBINPUT_EVENT_POINTER_MOTION);
|
LIBINPUT_EVENT_POINTER_MOTION);
|
||||||
|
|
||||||
return event->delta_unaccel.y;
|
return event->delta_raw.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBINPUT_EXPORT double
|
LIBINPUT_EXPORT double
|
||||||
|
|
@ -1130,7 +1130,7 @@ void
|
||||||
pointer_notify_motion(struct libinput_device *device,
|
pointer_notify_motion(struct libinput_device *device,
|
||||||
uint64_t time,
|
uint64_t time,
|
||||||
const struct normalized_coords *delta,
|
const struct normalized_coords *delta,
|
||||||
const struct normalized_coords *unaccel)
|
const struct device_float_coords *raw)
|
||||||
{
|
{
|
||||||
struct libinput_event_pointer *motion_event;
|
struct libinput_event_pointer *motion_event;
|
||||||
|
|
||||||
|
|
@ -1144,7 +1144,7 @@ pointer_notify_motion(struct libinput_device *device,
|
||||||
*motion_event = (struct libinput_event_pointer) {
|
*motion_event = (struct libinput_event_pointer) {
|
||||||
.time = time,
|
.time = time,
|
||||||
.delta = *delta,
|
.delta = *delta,
|
||||||
.delta_unaccel = *unaccel,
|
.delta_raw = *raw,
|
||||||
};
|
};
|
||||||
|
|
||||||
post_device_event(device, time,
|
post_device_event(device, time,
|
||||||
|
|
|
||||||
|
|
@ -462,8 +462,8 @@ libinput_event_pointer_get_time(struct libinput_event_pointer *event);
|
||||||
* If a device employs pointer acceleration, the delta returned by this
|
* If a device employs pointer acceleration, the delta returned by this
|
||||||
* function is the accelerated delta.
|
* function is the accelerated delta.
|
||||||
*
|
*
|
||||||
* Relative motion deltas are normalized to represent those of a device with
|
* Relative motion deltas are to be interpreted as pixel movement of a
|
||||||
* 1000dpi resolution. See @ref motion_normalization for more details.
|
* standardized mouse. See @ref motion_normalization for more details.
|
||||||
*
|
*
|
||||||
* @note It is an application bug to call this function for events other than
|
* @note It is an application bug to call this function for events other than
|
||||||
* @ref LIBINPUT_EVENT_POINTER_MOTION.
|
* @ref LIBINPUT_EVENT_POINTER_MOTION.
|
||||||
|
|
@ -483,8 +483,8 @@ libinput_event_pointer_get_dx(struct libinput_event_pointer *event);
|
||||||
* If a device employs pointer acceleration, the delta returned by this
|
* If a device employs pointer acceleration, the delta returned by this
|
||||||
* function is the accelerated delta.
|
* function is the accelerated delta.
|
||||||
*
|
*
|
||||||
* Relative motion deltas are normalized to represent those of a device with
|
* Relative motion deltas are to be interpreted as pixel movement of a
|
||||||
* 1000dpi resolution. See @ref motion_normalization for more details.
|
* standardized mouse. See @ref motion_normalization for more details.
|
||||||
*
|
*
|
||||||
* @note It is an application bug to call this function for events other than
|
* @note It is an application bug to call this function for events other than
|
||||||
* @ref LIBINPUT_EVENT_POINTER_MOTION.
|
* @ref LIBINPUT_EVENT_POINTER_MOTION.
|
||||||
|
|
@ -501,10 +501,11 @@ libinput_event_pointer_get_dy(struct libinput_event_pointer *event);
|
||||||
* current event. For pointer events that are not of type @ref
|
* current event. For pointer events that are not of type @ref
|
||||||
* LIBINPUT_EVENT_POINTER_MOTION, this function returns 0.
|
* LIBINPUT_EVENT_POINTER_MOTION, this function returns 0.
|
||||||
*
|
*
|
||||||
* Relative unaccelerated motion deltas are normalized to represent those of a
|
* Relative unaccelerated motion deltas are raw device coordinates.
|
||||||
* device with 1000dpi resolution. See @ref motion_normalization for more
|
* Note that these coordinates are subject to the device's native
|
||||||
* details. Note that unaccelerated events are not equivalent to 'raw' events
|
* resolution. Touchpad coordinates represent raw device coordinates in the
|
||||||
* as read from the device.
|
* X resolution of the touchpad. See @ref motion_normalization for more
|
||||||
|
* details.
|
||||||
*
|
*
|
||||||
* @note It is an application bug to call this function for events other than
|
* @note It is an application bug to call this function for events other than
|
||||||
* @ref LIBINPUT_EVENT_POINTER_MOTION.
|
* @ref LIBINPUT_EVENT_POINTER_MOTION.
|
||||||
|
|
@ -522,10 +523,11 @@ libinput_event_pointer_get_dx_unaccelerated(
|
||||||
* current event. For pointer events that are not of type @ref
|
* current event. For pointer events that are not of type @ref
|
||||||
* LIBINPUT_EVENT_POINTER_MOTION, this function returns 0.
|
* LIBINPUT_EVENT_POINTER_MOTION, this function returns 0.
|
||||||
*
|
*
|
||||||
* Relative unaccelerated motion deltas are normalized to represent those of a
|
* Relative unaccelerated motion deltas are raw device coordinates.
|
||||||
* device with 1000dpi resolution. See @ref motion_normalization for more
|
* Note that these coordinates are subject to the device's native
|
||||||
* details. Note that unaccelerated events are not equivalent to 'raw' events
|
* resolution. Touchpad coordinates represent raw device coordinates in the
|
||||||
* as read from the device.
|
* X resolution of the touchpad. See @ref motion_normalization for more
|
||||||
|
* details.
|
||||||
*
|
*
|
||||||
* @note It is an application bug to call this function for events other than
|
* @note It is an application bug to call this function for events other than
|
||||||
* @ref LIBINPUT_EVENT_POINTER_MOTION.
|
* @ref LIBINPUT_EVENT_POINTER_MOTION.
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ liblitest_la_SOURCES = \
|
||||||
litest-logitech-trackball.c \
|
litest-logitech-trackball.c \
|
||||||
litest-mouse.c \
|
litest-mouse.c \
|
||||||
litest-mouse-roccat.c \
|
litest-mouse-roccat.c \
|
||||||
|
litest-mouse-low-dpi.c \
|
||||||
litest-ms-surface-cover.c \
|
litest-ms-surface-cover.c \
|
||||||
litest-protocol-a-touch-screen.c \
|
litest-protocol-a-touch-screen.c \
|
||||||
litest-qemu-usb-tablet.c \
|
litest-qemu-usb-tablet.c \
|
||||||
|
|
|
||||||
75
test/litest-mouse-low-dpi.c
Normal file
75
test/litest-mouse-low-dpi.c
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2015 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "litest.h"
|
||||||
|
#include "litest-int.h"
|
||||||
|
|
||||||
|
static void litest_mouse_setup(void)
|
||||||
|
{
|
||||||
|
struct litest_device *d = litest_create_device(LITEST_MOUSE_LOW_DPI);
|
||||||
|
litest_set_current_device(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct input_id input_id = {
|
||||||
|
.bustype = 0x3,
|
||||||
|
.vendor = 0x1,
|
||||||
|
.product = 0x1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int events[] = {
|
||||||
|
EV_KEY, BTN_LEFT,
|
||||||
|
EV_KEY, BTN_RIGHT,
|
||||||
|
EV_KEY, BTN_MIDDLE,
|
||||||
|
EV_REL, REL_X,
|
||||||
|
EV_REL, REL_Y,
|
||||||
|
EV_REL, REL_WHEEL,
|
||||||
|
-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 Low DPI Mouse*\",\\\n"
|
||||||
|
" ENV{MOUSE_DPI}=\"400@125\"\n"
|
||||||
|
"\n"
|
||||||
|
"LABEL=\"touchpad_end\"";
|
||||||
|
|
||||||
|
struct litest_test_device litest_mouse_low_dpi_device = {
|
||||||
|
.type = LITEST_MOUSE_LOW_DPI,
|
||||||
|
.features = LITEST_RELATIVE | LITEST_BUTTON | LITEST_WHEEL,
|
||||||
|
.shortname = "low-dpi mouse",
|
||||||
|
.setup = litest_mouse_setup,
|
||||||
|
.interface = NULL,
|
||||||
|
|
||||||
|
.name = "Low DPI Mouse",
|
||||||
|
.id = &input_id,
|
||||||
|
.absinfo = NULL,
|
||||||
|
.events = events,
|
||||||
|
.udev_rule = udev_rule,
|
||||||
|
};
|
||||||
|
|
@ -352,6 +352,7 @@ extern struct litest_test_device litest_ms_surface_cover_device;
|
||||||
extern struct litest_test_device litest_logitech_trackball_device;
|
extern struct litest_test_device litest_logitech_trackball_device;
|
||||||
extern struct litest_test_device litest_atmel_hover_device;
|
extern struct litest_test_device litest_atmel_hover_device;
|
||||||
extern struct litest_test_device litest_alps_dualpoint_device;
|
extern struct litest_test_device litest_alps_dualpoint_device;
|
||||||
|
extern struct litest_test_device litest_mouse_low_dpi_device;
|
||||||
|
|
||||||
struct litest_test_device* devices[] = {
|
struct litest_test_device* devices[] = {
|
||||||
&litest_synaptics_clickpad_device,
|
&litest_synaptics_clickpad_device,
|
||||||
|
|
@ -378,6 +379,7 @@ struct litest_test_device* devices[] = {
|
||||||
&litest_logitech_trackball_device,
|
&litest_logitech_trackball_device,
|
||||||
&litest_atmel_hover_device,
|
&litest_atmel_hover_device,
|
||||||
&litest_alps_dualpoint_device,
|
&litest_alps_dualpoint_device,
|
||||||
|
&litest_mouse_low_dpi_device,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@ enum litest_device_type {
|
||||||
LITEST_LOGITECH_TRACKBALL = -23,
|
LITEST_LOGITECH_TRACKBALL = -23,
|
||||||
LITEST_ATMEL_HOVER = -24,
|
LITEST_ATMEL_HOVER = -24,
|
||||||
LITEST_ALPS_DUALPOINT = -25,
|
LITEST_ALPS_DUALPOINT = -25,
|
||||||
|
LITEST_MOUSE_LOW_DPI = -26,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum litest_device_feature {
|
enum litest_device_feature {
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,7 @@ usage(void)
|
||||||
"--maxdx=<double> ... in motion mode only. Stop increasing dx at maxdx\n"
|
"--maxdx=<double> ... in motion mode only. Stop increasing dx at maxdx\n"
|
||||||
"--steps=<double> ... in motion and delta modes only. Increase dx by step each round\n"
|
"--steps=<double> ... in motion and delta modes only. Increase dx by step each round\n"
|
||||||
"--speed=<double> ... accel speed [-1, 1], default 0\n"
|
"--speed=<double> ... accel speed [-1, 1], default 0\n"
|
||||||
|
"--dpi=<int> ... device resolution in DPI (default: 1000)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"If extra arguments are present and mode is not given, mode defaults to 'sequence'\n"
|
"If extra arguments are present and mode is not given, mode defaults to 'sequence'\n"
|
||||||
"and the arguments are interpreted as sequence of delta x coordinates\n"
|
"and the arguments are interpreted as sequence of delta x coordinates\n"
|
||||||
|
|
@ -191,17 +192,17 @@ main(int argc, char **argv)
|
||||||
print_sequence = false;
|
print_sequence = false;
|
||||||
double custom_deltas[1024];
|
double custom_deltas[1024];
|
||||||
double speed = 0.0;
|
double speed = 0.0;
|
||||||
|
int dpi = 1000;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
OPT_MODE = 1,
|
OPT_MODE = 1,
|
||||||
OPT_NEVENTS,
|
OPT_NEVENTS,
|
||||||
OPT_MAXDX,
|
OPT_MAXDX,
|
||||||
OPT_STEP,
|
OPT_STEP,
|
||||||
OPT_SPEED,
|
OPT_SPEED,
|
||||||
|
OPT_DPI,
|
||||||
};
|
};
|
||||||
|
|
||||||
filter = create_pointer_accelerator_filter(pointer_accel_profile_linear);
|
|
||||||
assert(filter != NULL);
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int c;
|
int c;
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
|
|
@ -211,6 +212,7 @@ main(int argc, char **argv)
|
||||||
{"maxdx", 1, 0, OPT_MAXDX },
|
{"maxdx", 1, 0, OPT_MAXDX },
|
||||||
{"step", 1, 0, OPT_STEP },
|
{"step", 1, 0, OPT_STEP },
|
||||||
{"speed", 1, 0, OPT_SPEED },
|
{"speed", 1, 0, OPT_SPEED },
|
||||||
|
{"dpi", 1, 0, OPT_DPI },
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -258,6 +260,9 @@ main(int argc, char **argv)
|
||||||
case OPT_SPEED:
|
case OPT_SPEED:
|
||||||
speed = strtod(optarg, NULL);
|
speed = strtod(optarg, NULL);
|
||||||
break;
|
break;
|
||||||
|
case OPT_DPI:
|
||||||
|
dpi = strtod(optarg, NULL);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
@ -265,6 +270,9 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filter = create_pointer_accelerator_filter(pointer_accel_profile_linear,
|
||||||
|
dpi);
|
||||||
|
assert(filter != NULL);
|
||||||
filter_set_speed(filter, speed);
|
filter_set_speed(filter, speed);
|
||||||
|
|
||||||
if (!isatty(STDIN_FILENO)) {
|
if (!isatty(STDIN_FILENO)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue