[PATCH evdev] Added Sensitivity option

Yann Kaiser epsy46 at free.fr
Thu Dec 31 08:31:42 PST 2009


Evdev now multiplies movement on each axis with a new Sensitivity option
(property "Evdev Sensitivity"). It keeps the fractional part of the computed
movement for next event, in order to prevent slow movements from being
discarded in high mouse dpi/low sensitivity combinations.

Signed-off-by: Yann Kaiser <epsy46 at free.fr>
---
 include/evdev-properties.h |    4 ++++
 man/evdev.man              |    7 +++++++
 src/evdev.c                |   26 ++++++++++++++++++++++++++
 src/evdev.h                |    2 ++
 4 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/include/evdev-properties.h b/include/evdev-properties.h
index 7df2876..e1593fe 100644
--- a/include/evdev-properties.h
+++ b/include/evdev-properties.h
@@ -62,6 +62,10 @@
 /* CARD32, 4 values [minx, maxx, miny, maxy], or no values for unset */
 #define EVDEV_PROP_CALIBRATION "Evdev Axis Calibration"
 
+/* Constant pointer speed multiplier */
+/* FLOAT */
+#define EVDEV_PROP_SENS "Evdev Sensitivity"
+
 /* Swap x and y axis. */
 /* BOOL */
 #define EVDEV_PROP_SWAP_AXES "Evdev Axes Swap"
diff --git a/man/evdev.man b/man/evdev.man
index 4771167..bfa5fd4 100644
--- a/man/evdev.man
+++ b/man/evdev.man
@@ -159,6 +159,10 @@ originally reported by the kernel (e.g. touchscreens). The scaling to the
 custom coordinate system is done in-driver and the X server is unaware of
 the transformation. Property: "Evdev Axis Calibration".
 .TP 7
+.BI "Option \*qSensitivity\*q \*q" Double \*q
+Constant multiplier to the mouse movement. Default: 1.0. Property: "Evdev
+Sensitivity".
+.TP 7
 .BI "Option \*qSwapAxes\*q \*q" Bool \*q
 Swap x/y axes. Default: off. Property: "Evdev Axes Swap".
 .TP 7
@@ -205,6 +209,9 @@ value.
 .BI "Evdev Middle Button Timeout"
 1 16-bit positive value.
 .TP 7
+.BI "Evdev Sensitivity"
+1 16-bit positive value.
+.TP 7
 .BI "Evdev Wheel Emulation"
 1 boolean value (8 bit, 0 or 1).
 .TP 7
diff --git a/src/evdev.c b/src/evdev.c
index 7e65c69..cbd4fdb 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -129,6 +129,7 @@ static Atom prop_calibration = 0;
 static Atom prop_swap = 0;
 static Atom prop_axis_label = 0;
 static Atom prop_btn_label = 0;
+static Atom prop_sens = 0;
 #endif
 
 /* All devices the evdev driver has allocated and knows about.
@@ -359,6 +360,7 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
     }
 
     if (pEvdev->rel) {
+        float delta_real;
         int first = REL_CNT, last = 0;
         int i;
 
@@ -375,6 +377,11 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
         for (i = 0; i < REL_CNT; i++)
         {
             int map = pEvdev->axis_map[i];
+
+            delta_real = pEvdev->delta[i] * pEvdev->sens + pEvdev->delta_rest[i];
+            pEvdev->delta[i] = floor(delta_real);
+            pEvdev->delta_rest[i] = delta_real - pEvdev->delta[i];
+
             if (map != -1)
             {
                 v[map] = pEvdev->delta[i];
@@ -1396,6 +1403,7 @@ EvdevInitRelClass(DeviceIntPtr device, EvdevPtr pEvdev)
     if (EvdevAddRelClass(device) == Success) {
 
         xf86Msg(X_INFO,"%s: initialized for relative axes.\n", device->name);
+        xf86Msg(X_CONFIG,"%s: using a sensitivity of: %lf.\n", device->name, pEvdev->sens);
 
         if (has_abs_axes) {
 
@@ -2022,6 +2030,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
     pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE);
     pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
     pEvdev->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE);
+    pEvdev->sens = xf86SetRealOption(pInfo->options, "Sensitivity", 1.0);
 
     str = xf86CheckStrOption(pInfo->options, "Calibration", NULL);
     if (str) {
@@ -2455,6 +2464,16 @@ EvdevInitProperty(DeviceIntPtr dev)
 
         XISetDevicePropertyDeletable(dev, prop_swap, FALSE);
 
+        prop_sens = MakeAtom(EVDEV_PROP_SENS,
+                strlen(EVDEV_PROP_SENS), TRUE);
+
+        rc = XIChangeDeviceProperty(dev, prop_sens, XIGetKnownProperty(XATOM_FLOAT), 32,
+                PropModeReplace, 1, &pEvdev->sens, FALSE);
+        if (rc != Success)
+            return;
+
+        XISetDevicePropertyDeletable(dev, prop_sens, FALSE);
+
 #ifdef HAVE_LABELS
         /* Axis labelling */
         if ((pEvdev->num_vals > 0) && (prop_axis_label = XIGetKnownProperty(AXIS_LABEL_PROP)))
@@ -2514,6 +2533,13 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
 
         if (!checkonly)
             pEvdev->swap_axes = *((BOOL*)val->data);
+    } else if (atom == prop_sens)
+    {
+        if(val->format != 32 || val->type != XIGetKnownProperty(XATOM_FLOAT) || val->size != 1)
+            return BadMatch;
+
+        if (!checkonly)
+            pEvdev->sens = *((float*)val->data);
     } else if (atom == prop_axis_label || atom == prop_btn_label)
         return BadAccess; /* Axis/Button labels can't be changed */
 
diff --git a/src/evdev.h b/src/evdev.h
index 95d00db..dd9574a 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -114,8 +114,10 @@ typedef struct {
     BOOL swap_axes;
     BOOL invert_x;
     BOOL invert_y;
+    float sens;
 
     int delta[REL_CNT];
+    float delta_rest[REL_CNT];   /* non-integer complement to delta */
     unsigned int abs, rel;
 
     /* XKB stuff has to be per-device rather than per-driver */
-- 
1.6.5.7



More information about the xorg-devel mailing list