From 0d0f94db0128e0b60ec755e857387450a5eadfe0 Mon Sep 17 00:00:00 2001 From: Thomas Hindoe Paaboel Andersen Date: Tue, 20 Jan 2015 00:44:40 +0100 Subject: [PATCH] Add "Resolution" option for mice to the evdev driver It can be used to scale the resolution of a mouse to that of a 1000 DPI mouse. This can be useful to make high resolution mice less sensitive without turning off acceleration. The target of 1000 DPI is used as the same default is used in libinput. If the option is not set no scaling will be done. https://bugs.freedesktop.org/show_bug.cgi?id=88134 Signed-off-by: Thomas Hindoe Paaboel Andersen --- man/evdev.man | 6 ++++++ src/evdev.c | 26 +++++++++++++++++++------- src/evdev.h | 3 +++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/man/evdev.man b/man/evdev.man index 06613fc..e70ae1f 100644 --- a/man/evdev.man +++ b/man/evdev.man @@ -238,6 +238,12 @@ Default: "1". Property: "Evdev Scrolling Distance". .BI "Option \*qDialDelta\*q \*q" integer \*q The amount of motion considered one unit of turning the dial. Default: "1". Property: "Evdev Scrolling Distance". +.TP 7 +.BI "Option \*qResolution\*q \*q" integer \*q +Sets the resolution of the device in dots per inch. The resolution is used +to scale relative motion events from mouse devices to 1000 DPI resolution. This +can be used to make high resolution mice less sensitive without turning off +acceleration. If set to 0 no scaling will be performed. Default: "0". .SH SUPPORTED PROPERTIES The following properties are provided by the diff --git a/src/evdev.c b/src/evdev.c index da25b56..9092612 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -25,6 +25,7 @@ * Adam Jackson (ajax@redhat.com) * Peter Hutterer (peter.hutterer@redhat.com) * Oliver McFadden (oliver.mcfadden@nokia.com) + * Thomas H.P. Andersen (phomes@gmail.com) */ #ifdef HAVE_CONFIG_H @@ -432,35 +433,40 @@ EvdevProcessValuators(InputInfoPtr pInfo) /* Apply transformations on relative coordinates */ if (pEvdev->rel_queued) { - int deltaX = 0, deltaY = 0; + double deltaX = 0, deltaY = 0; if (valuator_mask_isset(pEvdev->rel_vals, REL_X)) - deltaX = valuator_mask_get(pEvdev->rel_vals, REL_X); + deltaX = valuator_mask_get_double(pEvdev->rel_vals, REL_X); if (valuator_mask_isset(pEvdev->rel_vals, REL_Y)) - deltaY = valuator_mask_get(pEvdev->rel_vals, REL_Y); + deltaY = valuator_mask_get_double(pEvdev->rel_vals, REL_Y); if (pEvdev->swap_axes) { - int tmp = deltaX; + double tmp = deltaX; deltaX = deltaY; deltaY = tmp; } + if (pEvdev->resolution > 0) { + deltaX *= DEFAULT_MOUSE_DPI / pEvdev->resolution; + deltaY *= DEFAULT_MOUSE_DPI / pEvdev->resolution; + } + if (pEvdev->invert_x) deltaX *= -1; if (pEvdev->invert_y) deltaY *= -1; if (deltaX) - valuator_mask_set(pEvdev->rel_vals, REL_X, deltaX); + valuator_mask_set_double(pEvdev->rel_vals, REL_X, deltaX); else valuator_mask_unset(pEvdev->rel_vals, REL_X); if (deltaY) - valuator_mask_set(pEvdev->rel_vals, REL_Y, deltaY); + valuator_mask_set_double(pEvdev->rel_vals, REL_Y, deltaY); else valuator_mask_unset(pEvdev->rel_vals, REL_Y); - Evdev3BEmuProcessRelMotion(pInfo, deltaX, deltaY); + Evdev3BEmuProcessRelMotion(pInfo, trunc(deltaX), trunc(deltaY)); } /* @@ -2293,6 +2299,12 @@ EvdevProbe(InputInfoPtr pInfo) pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE); pEvdev->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE); + pEvdev->resolution = xf86SetIntOption(pInfo->options, "Resolution", 0); + if (pEvdev->resolution < 0) { + xf86IDrvMsg(pInfo, X_ERROR, "Resolution must be a positive number"); + pEvdev->resolution = 0; + } + str = xf86CheckStrOption(pInfo->options, "Calibration", NULL); if (str) { num_calibration = sscanf(str, "%d %d %d %d", diff --git a/src/evdev.h b/src/evdev.h index 0f71d78..d37b6e0 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -97,6 +97,8 @@ /* Number of longs needed to hold the given number of bits */ #define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS) +#define DEFAULT_MOUSE_DPI 1000.0 + /* Function key mode */ enum fkeymode { FKEYMODE_UNKNOWN = 0, @@ -170,6 +172,7 @@ typedef struct { BOOL swap_axes; BOOL invert_x; BOOL invert_y; + int resolution; unsigned int abs_queued, rel_queued, prox_queued; -- 2.4.3