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