xserver: Branch 'master' - 5 commits

Peter Hutterer whot at kemper.freedesktop.org
Sun Aug 3 22:47:40 PDT 2008


 config/hal.c                   |   49 ++++++++++---
 dix/ptrveloc.c                 |  153 ++++++++++++++++++++++++++++++++---------
 hw/xfree86/common/xf86Xinput.c |    4 -
 include/ptrveloc.h             |    4 -
 4 files changed, 168 insertions(+), 42 deletions(-)

New commits:
commit 3c6a9c531f673b7a0cb9ca01860b4dbe79686363
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Aug 1 15:52:07 2008 +0930

    config: protect against potential out-of-bounds indexing.

diff --git a/config/hal.c b/config/hal.c
index a954af9..3e0ff08 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -260,7 +260,7 @@ device_added(LibHalContext *hal_ctx, const char *udi)
                      * Since we can't predict the order in which the keys
                      * arrive, we need to store them.
                      */
-                    if ((tmp = strcasestr(psi_key, "xkb")))
+                    if ((tmp = strcasestr(psi_key, "xkb")) && strlen(tmp) >= 4)
                     {
                         if (!strcasecmp(&tmp[3], "layout"))
                         {
@@ -298,6 +298,7 @@ device_added(LibHalContext *hal_ctx, const char *udi)
                 {
                     /* server 1.4 had xkb_options as strlist. */
                     if ((tmp = strcasestr(psi_key, "xkb")) &&
+                        (strlen(tmp) >= 4) &&
                         (!strcasecmp(&tmp[3], "options")) &&
                         (tmp_val = get_prop_string_array(hal_ctx, udi, psi_key)))
                     {
@@ -312,7 +313,7 @@ device_added(LibHalContext *hal_ctx, const char *udi)
                 /* only support strings for all values */
                 tmp_val = get_prop_string(hal_ctx, udi, psi_key);
 
-                if (tmp_val){
+                if (tmp_val && strlen(psi_key) >= sizeof(LIBHAL_XKB_PROP_KEY)) {
 
                     tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1];
 
@@ -342,7 +343,7 @@ device_added(LibHalContext *hal_ctx, const char *udi)
                 {
                     /* server 1.4 had xkb options as strlist */
                     tmp_val = get_prop_string_array(hal_ctx, udi, psi_key);
-                    if (tmp_val)
+                    if (tmp_val && strlen(psi_key) >= sizeof(LIBHAL_XKB_PROP_KEY))
                     {
                         tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1];
                         if (!strcasecmp(tmp, ".options") && (!xkb_opts.options))
commit 92c51b183c2ff06361dad7f918daed6577ba4935
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Aug 1 14:24:54 2008 +0930

    config: support type strlist for XkbOptions property.
    
    For backwards compatibility with server 1.4.

diff --git a/config/hal.c b/config/hal.c
index a9451b7..a954af9 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -132,9 +132,6 @@ get_prop_string(LibHalContext *hal_ctx, const char *udi, const char *name)
     return ret;
 }
 
-/* this function is no longer used... keep it here in case its needed in
- * the future. */
-#if 0
 static char *
 get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop)
 {
@@ -168,7 +165,6 @@ get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop)
 
     return ret;
 }
-#endif
 
 static void
 device_added(LibHalContext *hal_ctx, const char *udi)
@@ -250,12 +246,12 @@ device_added(LibHalContext *hal_ctx, const char *udi)
 
             /* normal options first (input.x11_options.<propname>) */
             if (!strncasecmp(psi_key, LIBHAL_PROP_KEY, sizeof(LIBHAL_PROP_KEY)-1)){
+                char* tmp;
 
                 /* only support strings for all values */
                 tmp_val = get_prop_string(hal_ctx, udi, psi_key);
 
                 if (tmp_val){
-                    char* tmp;
 
                     /* xkb needs special handling. HAL specs include
                      * input.xkb.xyz options, but the x11-input.fdi specifies
@@ -298,14 +294,25 @@ device_added(LibHalContext *hal_ctx, const char *udi)
                         add_option(&options, psi_key + sizeof(LIBHAL_PROP_KEY)-1, tmp_val);
                         xfree(tmp_val);
                     }
+                } else
+                {
+                    /* server 1.4 had xkb_options as strlist. */
+                    if ((tmp = strcasestr(psi_key, "xkb")) &&
+                        (!strcasecmp(&tmp[3], "options")) &&
+                        (tmp_val = get_prop_string_array(hal_ctx, udi, psi_key)))
+                    {
+                        if (xkb_opts.options)
+                            xfree(xkb_opts.options);
+                        xkb_opts.options = strdup(tmp_val);
+                    }
                 }
             } else if (!strncasecmp(psi_key, LIBHAL_XKB_PROP_KEY, sizeof(LIBHAL_XKB_PROP_KEY)-1)){
+                char* tmp;
 
                 /* only support strings for all values */
                 tmp_val = get_prop_string(hal_ctx, udi, psi_key);
 
                 if (tmp_val){
-                    char* tmp;
 
                     tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1];
 
@@ -331,6 +338,16 @@ device_added(LibHalContext *hal_ctx, const char *udi)
                             xkb_opts.options = strdup(tmp_val);
                     }
                     xfree(tmp_val);
+                } else
+                {
+                    /* server 1.4 had xkb options as strlist */
+                    tmp_val = get_prop_string_array(hal_ctx, udi, psi_key);
+                    if (tmp_val)
+                    {
+                        tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1];
+                        if (!strcasecmp(tmp, ".options") && (!xkb_opts.options))
+                            xkb_opts.options = strdup(tmp_val);
+                    }
                 }
             }
         }
commit 35b14519b4a3158592a089170ec039bbc219603e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jul 29 12:59:57 2008 +0930

    config: add parsing for input.x11_options.XkbOptions. #16874
    
    X.Org Bug 16874 <http://bugs.freedesktop.org/show_bug.cgi?id=16784>

diff --git a/config/hal.c b/config/hal.c
index b6d7402..a9451b7 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2007 Daniel Stone
+ * Copyright © 2007 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"),
@@ -54,6 +55,7 @@ struct xkb_options {
     char* model;
     char* rules;
     char* variant;
+    char* options;
 };
 
 
@@ -284,6 +286,11 @@ device_added(LibHalContext *hal_ctx, const char *udi)
                             if (xkb_opts.variant)
                                 xfree(xkb_opts.variant);
                             xkb_opts.variant = strdup(tmp_val);
+                        } else if (!strcasecmp(&tmp[3], "options"))
+                        {
+                            if (xkb_opts.options)
+                                xfree(xkb_opts.options);
+                            xkb_opts.options = strdup(tmp_val);
                         }
                     } else
                     {
@@ -318,6 +325,10 @@ device_added(LibHalContext *hal_ctx, const char *udi)
                     {
                         if (!xkb_opts.model)
                             xkb_opts.model = strdup(tmp_val);
+                    } else if (!strcasecmp(tmp, "options"))
+                    {
+                        if (!xkb_opts.options)
+                            xkb_opts.options = strdup(tmp_val);
                     }
                     xfree(tmp_val);
                 }
@@ -338,6 +349,8 @@ device_added(LibHalContext *hal_ctx, const char *udi)
         add_option(&options, "xkb_variant", xkb_opts.variant);
     if (xkb_opts.model)
         add_option(&options, "xkb_model", xkb_opts.model);
+    if (xkb_opts.options)
+        add_option(&options, "xkb_options", xkb_opts.options);
 
     /* this isn't an error, but how else do you output something that the user can see? */
     LogMessage(X_INFO, "config/hal: Adding input device %s\n", name);
@@ -379,6 +392,8 @@ unwind:
         xfree(xkb_opts.model);
     if (xkb_opts.variant)
         xfree(xkb_opts.variant);
+    if (xkb_opts.options)
+        xfree(xkb_opts.options);
 
     dbus_error_free(&error);
 
commit d762c08aebe3b7e8c88e2e7a6fcf66057a21b403
Author: Simon Thum <simon.thum at gmx.de>
Date:   Mon Jul 28 14:07:48 2008 +0200

    dix: export driver-side functions for acceleration
    
    also add additional safety for accel driver api
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 70057e9..64b1c35 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -695,7 +695,7 @@ LinearProfile(
  * would be a good place, since FreeVelocityData() also calls this with -1.
  * returns FALSE (0) if profile number is unavailable.
  */
-int
+_X_EXPORT int
 SetAccelerationProfile(
     DeviceVelocityPtr s,
     int profile_num)
@@ -744,6 +744,11 @@ SetAccelerationProfile(
     return TRUE;
 }
 
+/**********************************************
+ * driver interaction
+ **********************************************/
+
+
 /**
  * device-specific profile
  *
@@ -753,7 +758,7 @@ SetAccelerationProfile(
  * it should do init/uninit in the driver (ie. with DEVICE_INIT and friends).
  * Users may override or choose it.
  */
-extern void
+_X_EXPORT void
 SetDeviceSpecificAccelerationProfile(
         DeviceVelocityPtr s,
         PointerAccelerationProfileFunc profile)
@@ -766,11 +771,15 @@ SetDeviceSpecificAccelerationProfile(
  * Use this function to obtain a DeviceVelocityPtr for a device. Will return NULL if
  * the predictable acceleration scheme is not in effect.
  */
-DeviceVelocityPtr
+_X_EXPORT DeviceVelocityPtr
 GetDevicePredictableAccelData(
 	DeviceIntPtr pDev)
 {
     /*sanity check*/
+    if(!pDev){
+	ErrorF("[dix] accel: DeviceIntPtr was NULL");
+	return NULL;
+    }
     if( pDev->valuator &&
 	pDev->valuator->accelScheme.AccelSchemeProc ==
 	    acceleratePointerPredictable &&
commit 18e9fd69fe01298d825b46415b9c6bd86c75dfe5
Author: Simon Thum <simon.thum at gmx.de>
Date:   Tue Jul 29 10:07:43 2008 +0200

    dix: use average of pointer accel profile
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 21a2eca..70057e9 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -73,7 +73,8 @@ InitFilterChain(DeviceVelocityPtr s, float rdecay, float degression,
 void
 CleanupFilterChain(DeviceVelocityPtr s);
 static float
-SimpleSmoothProfile(DeviceVelocityPtr pVel, float threshold, float acc);
+SimpleSmoothProfile(DeviceVelocityPtr pVel, float velocity,
+                    float threshold, float acc);
 
 
 /********************************
@@ -88,6 +89,7 @@ InitVelocityData(DeviceVelocityPtr s)
 {
     s->lrm_time = 0;
     s->velocity  = 0;
+    s->last_velocity = 0;
     s->corr_mul = 10.0;      /* dots per 10 milisecond should be usable */
     s->const_acceleration = 1.0;   /* no acceleration/deceleration  */
     s->reset_time = 300;
@@ -97,6 +99,7 @@ InitVelocityData(DeviceVelocityPtr s)
     s->use_softening = 1;
     s->min_acceleration = 1.0; /* don't decelerate */
     s->coupling = 0.25;
+    s->average_accel = TRUE;
     s->profile_private = NULL;
     memset(&s->statistics, 0, sizeof(s->statistics));
     memset(&s->filters, 0, sizeof(s->filters));
@@ -163,7 +166,7 @@ InitFilterChain(DeviceVelocityPtr s, float rdecay, float progression, int stages
 	rdecay /= progression;
     }
     /* release again. Should the input loop be threaded, we also need
-     * memory release here (in princliple).
+     * memory release here (in principle).
      */
     OsReleaseSignals();
 }
@@ -330,10 +333,14 @@ ProcessVelocityData(
     float cvelocity;
 
     int diff = time - s->lrm_time;
-    int cur_ax = GetAxis(dx, dy);
-    int last_ax = GetAxis(s->last_dx, s->last_dy);
+    int cur_ax, last_ax;
     short reset = (diff >= s->reset_time);
 
+    /* remember last round's result */
+    s->last_velocity = s->velocity;
+    cur_ax = GetAxis(dx, dy);
+    last_ax = GetAxis(s->last_dx, s->last_dy);
+
     if(cur_ax != last_ax && cur_ax != -1 && last_ax != -1 && !reset){
         /* correct for the error induced when diagonal movements are
            reported as alternating axis mickeys */
@@ -368,15 +375,22 @@ ProcessVelocityData(
     if (diff == 0)
         diff = 1; /* prevent div-by-zero, though it shouldn't happen anyway*/
 
-    /* translate velocity to dots/ms (somewhat untractable in integers,
+    /* translate velocity to dots/ms (somewhat intractable in integers,
        so we multiply by some per-device adjustable factor) */
     cvelocity = cvelocity * s->corr_mul / (float)diff;
 
     /* short-circuit: when nv-reset the rest can be skipped */
     if(reset == TRUE){
+	/*
+	 * we don't really have a velocity here, since diff includes inactive
+	 * time. This is dealt with in ComputeAcceleration.
+	 */
 	StuffFilterChain(s, cvelocity);
-	s->velocity = cvelocity;
+	s->velocity = s->last_velocity = cvelocity;
 	s->last_reset = TRUE;
+#ifdef PTRACCEL_DEBUGGING
+        ErrorF("(dix ptracc) non-visible state reset\n");
+#endif
 	return TRUE;
     }
 
@@ -388,6 +402,9 @@ ProcessVelocityData(
 	 * stuff that into the filter chain.
 	 */
 	s->last_reset = FALSE;
+#ifdef PTRACCEL_DEBUGGING
+        ErrorF("(dix ptracc) after-reset vel:%.3f\n", cvelocity);
+#endif
 	StuffFilterChain(s, cvelocity);
 	s->velocity = cvelocity;
 	return FALSE;
@@ -448,6 +465,72 @@ ApplySofteningAndConstantDeceleration(
     *fdy *= s->const_acceleration;
 }
 
+/*
+ * compute the acceleration for given velocity and enforce min_acceleartion
+ */
+static float
+BasicComputeAcceleration(
+    DeviceVelocityPtr pVel,
+    float velocity,
+    float threshold,
+    float acc){
+
+    float result;
+    result = pVel->Profile(pVel, velocity, threshold, acc);
+
+    /* enforce min_acceleration */
+    if (result < pVel->min_acceleration)
+	result = pVel->min_acceleration;
+    return result;
+}
+
+/**
+ * Compute acceleration. Takes into account averaging, nv-reset, etc.
+ */
+static float
+ComputeAcceleration(
+    DeviceVelocityPtr vel,
+    float threshold,
+    float acc){
+    float res;
+
+    if(vel->last_reset){
+#ifdef PTRACCEL_DEBUGGING
+        ErrorF("(dix ptracc) profile skipped\n");
+#endif
+        /*
+         * This is intended to override the first estimate of a stroke,
+         * which is too low (see ProcessVelocityData). 1 should make sure
+         * the mickey is seen on screen.
+         */
+	return 1;
+    }
+
+    if(vel->average_accel && vel->velocity != vel->last_velocity){
+	/* use simpson's rule to average acceleration between
+	 * current and previous velocity.
+	 * Though being the more natural choice, it causes a minor delay
+	 * in comparison, so it can be disabled. */
+	res = BasicComputeAcceleration(vel, vel->velocity, threshold, acc);
+	res += BasicComputeAcceleration(vel, vel->last_velocity, threshold, acc);
+	res += 4.0f * BasicComputeAcceleration(vel,
+	                   (vel->last_velocity + vel->velocity) / 2,
+	                   threshold, acc);
+	res /= 6.0f;
+#ifdef PTRACCEL_DEBUGGING
+        ErrorF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n",
+               vel->velocity, vel->last_velocity, res);
+#endif
+        return res;
+    }else{
+	res = BasicComputeAcceleration(vel, vel->velocity, threshold, acc);
+#ifdef PTRACCEL_DEBUGGING
+        ErrorF("(dix ptracc) profile sample [%.2f] is %.3f\n",
+               vel->velocity, res);
+#endif
+	return res;
+    }
+}
 
 
 /*****************************************
@@ -460,10 +543,11 @@ ApplySofteningAndConstantDeceleration(
 static float
 PolynomialAccelerationProfile(
     DeviceVelocityPtr pVel,
+    float velocity,
     float ignored,
     float acc)
 {
-   return pow(pVel->velocity, (acc - 1.0) * 0.5);
+   return pow(velocity, (acc - 1.0) * 0.5);
 }
 
 
@@ -474,15 +558,18 @@ PolynomialAccelerationProfile(
 static float
 ClassicProfile(
     DeviceVelocityPtr pVel,
+    float velocity,
     float threshold,
     float acc)
 {
     if (threshold) {
 	return SimpleSmoothProfile (pVel,
+	                            velocity,
                                     threshold,
                                     acc);
     } else {
 	return PolynomialAccelerationProfile (pVel,
+	                                      velocity,
                                               0,
                                               acc);
     }
@@ -500,6 +587,7 @@ ClassicProfile(
 static float
 PowerProfile(
     DeviceVelocityPtr pVel,
+    float velocity,
     float threshold,
     float acc)
 {
@@ -507,9 +595,9 @@ PowerProfile(
 
     acc = (acc-1.0) * 0.1f + 1.0; /* without this, acc of 2 is unuseable */
 
-    if (pVel->velocity <= threshold)
+    if (velocity <= threshold)
         return pVel->min_acceleration;
-    vel_dist = pVel->velocity - threshold;
+    vel_dist = velocity - threshold;
     return (pow(acc, vel_dist)) * pVel->min_acceleration;
 }
 
@@ -536,10 +624,10 @@ CalcPenumbralGradient(float x){
 static float
 SimpleSmoothProfile(
     DeviceVelocityPtr pVel,
+    float velocity,
     float threshold,
     float acc)
 {
-    float velocity = pVel->velocity;
     if(velocity < 1.0f)
         return CalcPenumbralGradient(0.5 + velocity*0.5) * 2.0f - 1.0f;
     if(threshold < 1.0f)
@@ -561,6 +649,7 @@ SimpleSmoothProfile(
 static float
 SmoothLinearProfile(
     DeviceVelocityPtr pVel,
+    float velocity,
     float threshold,
     float acc)
 {
@@ -571,7 +660,7 @@ SmoothLinearProfile(
     else
         return 1.0f;
 
-    nv = (pVel->velocity - threshold) * acc * 0.5f;
+    nv = (velocity - threshold) * acc * 0.5f;
 
     if(nv < 0){
         res = 0;
@@ -590,10 +679,11 @@ SmoothLinearProfile(
 static float
 LinearProfile(
     DeviceVelocityPtr pVel,
+    float velocity,
     float threshold,
     float acc)
 {
-    return acc * pVel->velocity;
+    return acc * velocity;
 }
 
 
@@ -730,7 +820,9 @@ acceleratePointerPredictable(
     if (dx || dy){
         /* reset nonvisible state? */
         if (ProcessVelocityData(velocitydata, dx , dy, evtime)) {
-            /* set to center of pixel */
+            /* set to center of pixel. makes sense as long as there are no
+             * means of passing on sub-pixel values.
+             */
             pDev->last.remainder[0] = pDev->last.remainder[1] = 0.5f;
             /* prevent softening (somewhat quirky solution,
             as it depends on the algorithm) */
@@ -740,22 +832,10 @@ acceleratePointerPredictable(
 
         if (pDev->ptrfeed && pDev->ptrfeed->ctrl.num) {
             /* invoke acceleration profile to determine acceleration */
-            mult = velocitydata->Profile(velocitydata,
-                                pDev->ptrfeed->ctrl.threshold,
-                                (float)pDev->ptrfeed->ctrl.num /
-                                (float)pDev->ptrfeed->ctrl.den);
-
-#ifdef PTRACCEL_DEBUGGING
-            ErrorF("(dix ptracc) resulting speed multiplier : %.3f\n", mult);
-#endif
-            /* enforce min_acceleration */
-            if (mult < velocitydata->min_acceleration) {
-#ifdef PTRACCEL_DEBUGGING
-                ErrorF("(dix ptracc) enforced min multiplier : %.3f\n",
-                        velocitydata->min_acceleration);
-#endif
-                mult = velocitydata->min_acceleration;
-	    }
+            mult = ComputeAcceleration (velocitydata,
+					pDev->ptrfeed->ctrl.threshold,
+					(float)pDev->ptrfeed->ctrl.num /
+					(float)pDev->ptrfeed->ctrl.den);
 
             if(mult != 1.0 || velocitydata->const_acceleration != 1.0) {
                 ApplySofteningAndConstantDeceleration( velocitydata,
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index ea4dbba..4ef7530 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -150,6 +150,8 @@ ProcessVelocityConfiguration(char* devname, pointer list, DeviceVelocityPtr s){
     s->use_softening = xf86SetBoolOption(list, "Softening",
                                          s->const_acceleration == 1.0);
 
+    s->average_accel = xf86SetBoolOption(list, "AccelerationProfileAveraging", TRUE);
+
     s->reset_time = xf86SetIntOption(list, "VelocityReset", 300);
 
     tempf = xf86SetRealOption(list, "ExpectedRate", 0);
@@ -214,7 +216,7 @@ ApplyAccelerationSettings(DeviceIntPtr dev){
         /* process special configuration */
         switch(scheme){
             case PtrAccelPredictable:
-                pVel = (DeviceVelocityPtr) dev->valuator->accelScheme.accelData;
+                pVel = GetDevicePredictableAccelData(dev);
                 ProcessVelocityConfiguration (local->name, local->options,
                                               pVel);
                 break;
diff --git a/include/ptrveloc.h b/include/ptrveloc.h
index 2d42dda..384f9a6 100644
--- a/include/ptrveloc.h
+++ b/include/ptrveloc.h
@@ -53,7 +53,7 @@ struct _DeviceVelocityRec;
  */
 typedef float (*PointerAccelerationProfileFunc)
               (struct _DeviceVelocityRec* /*pVel*/,
-               float /*threshold*/, float /*acc*/);
+               float /*velocity*/, float /*threshold*/, float /*acc*/);
 
 /**
  * a filter stage contains the data for adaptive IIR filtering.
@@ -78,6 +78,7 @@ typedef struct _FilterStage {
 typedef struct _DeviceVelocityRec {
     FilterStage filters[MAX_VELOCITY_FILTERS];
     float   velocity;       /* velocity as guessed by algorithm */
+    float   last_velocity;  /* previous velocity estimate */
     int     lrm_time;       /* time the last motion event was processed  */
     int     last_dx, last_dy; /* last motion delta */
     int     last_diff;      /* last time-difference */
@@ -88,6 +89,7 @@ typedef struct _DeviceVelocityRec {
     short   reset_time;     /* config: reset non-visible state after # ms */
     short   use_softening;  /* config: use softening of mouse values */
     float   coupling;       /* config: max. divergence before coupling */
+    Bool    average_accel;  /* config: average acceleration over velocity */
     PointerAccelerationProfileFunc Profile;
     PointerAccelerationProfileFunc deviceSpecificProfile;
     void*   profile_private;/* extended data, see  SetAccelerationProfile() */


More information about the xorg-commit mailing list