mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-27 04:30:06 +01:00
Parse the MOUSE_WHEEL_CLICK_ANGLE udev property if present
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Jonas Ådahl <jadahl@gmail.com>
This commit is contained in:
parent
2708be27b2
commit
c35885e87d
6 changed files with 97 additions and 4 deletions
|
|
@ -23,6 +23,10 @@ context. Defaults to "default".</dd>
|
|||
<dd>HW resolution and sampling frequency of a relative pointer device.
|
||||
See @ref motion_normalization for details.
|
||||
</dd>
|
||||
<dt>MOUSE_WHEEL_CLICK_ANGLE</dt>
|
||||
<dd>The angle in degrees for each click on a mouse wheel. See
|
||||
libinput_pointer_get_axis_source() for details.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
Below is an example udev rule to assign "seat1" to a device from vendor
|
||||
|
|
|
|||
29
src/evdev.c
29
src/evdev.c
|
|
@ -577,7 +577,7 @@ evdev_process_relative(struct evdev_device *device,
|
|||
time,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
|
||||
LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
|
||||
-1 * e->value * DEFAULT_WHEEL_CLICK_ANGLE);
|
||||
-1 * e->value * device->scroll.wheel_click_angle);
|
||||
break;
|
||||
case REL_HWHEEL:
|
||||
evdev_flush_pending_event(device, time);
|
||||
|
|
@ -586,7 +586,7 @@ evdev_process_relative(struct evdev_device *device,
|
|||
time,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
|
||||
LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
|
||||
e->value * DEFAULT_WHEEL_CLICK_ANGLE);
|
||||
e->value * device->scroll.wheel_click_angle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1239,6 +1239,29 @@ evdev_tag_device(struct evdev_device *device)
|
|||
device->udev_device);
|
||||
}
|
||||
|
||||
static inline int
|
||||
evdev_read_wheel_click_prop(struct evdev_device *device)
|
||||
{
|
||||
struct libinput *libinput = device->base.seat->libinput;
|
||||
const char *prop;
|
||||
int angle = DEFAULT_WHEEL_CLICK_ANGLE;
|
||||
|
||||
prop = udev_device_get_property_value(device->udev_device,
|
||||
"MOUSE_WHEEL_CLICK_ANGLE");
|
||||
if (prop) {
|
||||
angle = parse_mouse_wheel_click_angle_property(prop);
|
||||
if (!angle) {
|
||||
log_error(libinput,
|
||||
"Mouse wheel click angle '%s' is present but invalid,"
|
||||
"using %d degrees instead\n",
|
||||
device->devname,
|
||||
DEFAULT_WHEEL_CLICK_ANGLE);
|
||||
angle = DEFAULT_WHEEL_CLICK_ANGLE;
|
||||
}
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
static inline int
|
||||
evdev_read_dpi_prop(struct evdev_device *device)
|
||||
{
|
||||
|
|
@ -1568,6 +1591,8 @@ evdev_device_create(struct libinput_seat *seat,
|
|||
device->devname = libevdev_get_name(device->evdev);
|
||||
device->scroll.threshold = 5.0; /* Default may be overridden */
|
||||
device->scroll.direction = 0;
|
||||
device->scroll.wheel_click_angle =
|
||||
evdev_read_wheel_click_prop(device);
|
||||
device->dpi = evdev_read_dpi_prop(device);
|
||||
/* at most 5 SYN_DROPPED log-messages per 30s */
|
||||
ratelimit_init(&device->syn_drop_limit, 30ULL * 1000, 5);
|
||||
|
|
|
|||
|
|
@ -119,6 +119,9 @@ struct evdev_device {
|
|||
/* set during device init if we want natural scrolling,
|
||||
* used at runtime to enable/disable the feature */
|
||||
bool natural_scrolling_enabled;
|
||||
|
||||
/* angle per REL_WHEEL click in degrees */
|
||||
int wheel_click_angle;
|
||||
} scroll;
|
||||
|
||||
enum evdev_event_type pending_event;
|
||||
|
|
|
|||
|
|
@ -171,3 +171,33 @@ parse_mouse_dpi_property(const char *prop)
|
|||
}
|
||||
return dpi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to parse the MOUSE_WHEEL_CLICK_ANGLE property from udev.
|
||||
* Property is of the form:
|
||||
* MOUSE_WHEEL_CLICK_ANGLE=<integer>
|
||||
* Where the number indicates the degrees travelled for each click.
|
||||
*
|
||||
* We skip preceding whitespaces and parse the first number seen. If
|
||||
* multiple numbers are specified, we ignore those.
|
||||
*
|
||||
* @param prop The value of the udev property (without the MOUSE_WHEEL_CLICK_ANGLE=)
|
||||
* @return The angle of the wheel (may be negative) or 0 on error.
|
||||
*/
|
||||
int
|
||||
parse_mouse_wheel_click_angle_property(const char *prop)
|
||||
{
|
||||
int angle = 0,
|
||||
nread = 0;
|
||||
|
||||
while(*prop != 0 && *prop == ' ')
|
||||
prop++;
|
||||
|
||||
sscanf(prop, "%d%n", &angle, &nread);
|
||||
if (nread == 0 || angle == 0 || abs(angle) > 360)
|
||||
return 0;
|
||||
if (prop[nread] != ' ' && prop[nread] != '\0')
|
||||
return 0;
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,5 +297,6 @@ void ratelimit_init(struct ratelimit *r, uint64_t ival_ms, unsigned int burst);
|
|||
enum ratelimit_state ratelimit_test(struct ratelimit *r);
|
||||
|
||||
int parse_mouse_dpi_property(const char *prop);
|
||||
int parse_mouse_wheel_click_angle_property(const char *prop);
|
||||
|
||||
#endif /* LIBINPUT_UTIL_H */
|
||||
|
|
|
|||
34
test/misc.c
34
test/misc.c
|
|
@ -531,7 +531,7 @@ END_TEST
|
|||
|
||||
struct parser_test {
|
||||
char *tag;
|
||||
int expected_dpi;
|
||||
int expected_value;
|
||||
};
|
||||
|
||||
START_TEST(dpi_parser)
|
||||
|
|
@ -565,7 +565,36 @@ START_TEST(dpi_parser)
|
|||
|
||||
for (i = 0; tests[i].tag != NULL; i++) {
|
||||
dpi = parse_mouse_dpi_property(tests[i].tag);
|
||||
ck_assert_int_eq(dpi, tests[i].expected_dpi);
|
||||
ck_assert_int_eq(dpi, tests[i].expected_value);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(wheel_click_parser)
|
||||
{
|
||||
struct parser_test tests[] = {
|
||||
{ "1", 1 },
|
||||
{ "10", 10 },
|
||||
{ "-12", -12 },
|
||||
{ "360", 360 },
|
||||
{ "66 ", 66 },
|
||||
{ " 100 ", 100 },
|
||||
|
||||
{ "0", 0 },
|
||||
{ "-0", 0 },
|
||||
{ "a", 0 },
|
||||
{ "10a", 0 },
|
||||
{ "10-", 0 },
|
||||
{ "sadfasfd", 0 },
|
||||
{ "361", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
int i, angle;
|
||||
|
||||
for (i = 0; tests[i].tag != NULL; i++) {
|
||||
angle = parse_mouse_wheel_click_angle_property(tests[i].tag);
|
||||
ck_assert_int_eq(angle, tests[i].expected_value);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -582,6 +611,7 @@ int main (int argc, char **argv) {
|
|||
litest_add_no_device("misc:matrix", matrix_helpers);
|
||||
litest_add_no_device("misc:ratelimit", ratelimit_helpers);
|
||||
litest_add_no_device("misc:dpi parser", dpi_parser);
|
||||
litest_add_no_device("misc:wheel click parser", wheel_click_parser);
|
||||
|
||||
return litest_run(argc, argv);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue