summaryrefslogtreecommitdiff
path: root/xserver/dix/ptrveloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'xserver/dix/ptrveloc.c')
-rw-r--r--xserver/dix/ptrveloc.c870
1 files changed, 394 insertions, 476 deletions
diff --git a/xserver/dix/ptrveloc.c b/xserver/dix/ptrveloc.c
index dfccf1581..acbb479c1 100644
--- a/xserver/dix/ptrveloc.c
+++ b/xserver/dix/ptrveloc.c
@@ -62,10 +62,11 @@
/* fwds */
int
-SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
-static float
-SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, float velocity,
- float threshold, float acc);
+ SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
+static double
+
+SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity,
+ double threshold, double acc);
static PointerAccelerationProfileFunc
GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
static BOOL
@@ -81,7 +82,7 @@ DeletePredictableAccelerationProperties(DeviceIntPtr,
#ifdef PTRACCEL_DEBUGGING
#define DebugAccelF ErrorF
#else
-#define DebugAccelF(...) /* */
+#define DebugAccelF(...) /* */
#endif
/********************************
@@ -99,11 +100,11 @@ InitVelocityData(DeviceVelocityPtr vel)
{
memset(vel, 0, sizeof(DeviceVelocityRec));
- vel->corr_mul = 10.0; /* dots per 10 milisecond should be usable */
- vel->const_acceleration = 1.0; /* no acceleration/deceleration */
+ vel->corr_mul = 10.0; /* dots per 10 milisecond should be usable */
+ vel->const_acceleration = 1.0; /* no acceleration/deceleration */
vel->reset_time = 300;
vel->use_softening = 1;
- vel->min_acceleration = 1.0; /* don't decelerate */
+ vel->min_acceleration = 1.0; /* don't decelerate */
vel->max_rel_diff = 0.2;
vel->max_diff = 1.0;
vel->initial_range = 2;
@@ -112,26 +113,27 @@ InitVelocityData(DeviceVelocityPtr vel)
InitTrackers(vel, 16);
}
-
/**
* Clean up DeviceVelocityRec
*/
void
-FreeVelocityData(DeviceVelocityPtr vel){
+FreeVelocityData(DeviceVelocityPtr vel)
+{
free(vel->tracker);
SetAccelerationProfile(vel, PROFILE_UNINITIALIZE);
}
-
/**
* Init predictable scheme
*/
Bool
InitPredictableAccelerationScheme(DeviceIntPtr dev,
- ValuatorAccelerationPtr protoScheme) {
+ ValuatorAccelerationPtr protoScheme)
+{
DeviceVelocityPtr vel;
ValuatorAccelerationRec scheme;
PredictableAccelSchemePtr schemeData;
+
scheme = *protoScheme;
vel = calloc(1, sizeof(DeviceVelocityRec));
schemeData = calloc(1, sizeof(PredictableAccelSchemeRec));
@@ -147,7 +149,6 @@ InitPredictableAccelerationScheme(DeviceIntPtr dev,
return TRUE;
}
-
/**
* Uninit scheme
*/
@@ -155,6 +156,7 @@ void
AccelerationDefaultCleanup(DeviceIntPtr dev)
{
DeviceVelocityPtr vel = GetDevicePredictableAccelData(dev);
+
if (vel) {
/* the proper guarantee would be that we're not inside of
* AccelSchemeProc(), but that seems impossible. Schemes don't get
@@ -165,14 +167,15 @@ AccelerationDefaultCleanup(DeviceIntPtr dev)
FreeVelocityData(vel);
free(vel);
DeletePredictableAccelerationProperties(dev,
- (PredictableAccelSchemePtr) dev->valuator->accelScheme.accelData);
+ (PredictableAccelSchemePtr)
+ dev->valuator->accelScheme.
+ accelData);
free(dev->valuator->accelScheme.accelData);
dev->valuator->accelScheme.accelData = NULL;
OsReleaseSignals();
}
}
-
/*************************
* Input property support
************************/
@@ -197,15 +200,15 @@ AccelSetProfileProperty(DeviceIntPtr dev, Atom atom,
return BadValue;
rc = XIPropToInt(val, &nelem, &ptr);
- if(checkOnly)
- {
+ if (checkOnly) {
if (rc)
return rc;
if (GetAccelerationProfile(vel, profile) == NULL)
return BadValue;
- } else
- SetAccelerationProfile(vel, profile);
+ }
+ else
+ SetAccelerationProfile(vel, profile);
return Success;
}
@@ -242,15 +245,14 @@ AccelSetDecelProperty(DeviceIntPtr dev, Atom atom,
return BadValue;
rc = XIPropToFloat(val, &nelem, &ptr);
- if(checkOnly)
- {
+ if (checkOnly) {
if (rc)
return rc;
- return (v >= 1.0f) ? Success : BadValue;
+ return (v >= 1.0f) ? Success : BadValue;
}
- if(v >= 1.0f)
- vel->const_acceleration = 1/v;
+ if (v >= 1.0f)
+ vel->const_acceleration = 1 / v;
return Success;
}
@@ -258,16 +260,16 @@ AccelSetDecelProperty(DeviceIntPtr dev, Atom atom,
static long
AccelInitDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
{
- float fval = 1.0/vel->const_acceleration;
- Atom prop_const_decel = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
+ float fval = 1.0 / vel->const_acceleration;
+ Atom prop_const_decel =
+ XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
XIChangeDeviceProperty(dev, prop_const_decel,
- XIGetKnownProperty(XATOM_FLOAT), 32,
- PropModeReplace, 1, &fval, FALSE);
+ XIGetKnownProperty(XATOM_FLOAT), 32, PropModeReplace,
+ 1, &fval, FALSE);
XISetDevicePropertyDeletable(dev, prop_const_decel, FALSE);
return XIRegisterPropertyHandler(dev, AccelSetDecelProperty, NULL, NULL);
}
-
/**
* adaptive deceleration
*/
@@ -288,15 +290,14 @@ AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom,
return BadValue;
rc = XIPropToFloat(val, &nelem, &ptr);
- if(checkOnly)
- {
+ if (checkOnly) {
if (rc)
return rc;
- return (v >= 1.0f) ? Success : BadValue;
+ return (v >= 1.0f) ? Success : BadValue;
}
- if(v >= 1.0f)
- veloc->min_acceleration = 1/v;
+ if (v >= 1.0f)
+ veloc->min_acceleration = 1 / v;
return Success;
}
@@ -304,16 +305,18 @@ AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom,
static long
AccelInitAdaptDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
{
- float fval = 1.0/vel->min_acceleration;
- Atom prop_adapt_decel = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
+ float fval = 1.0 / vel->min_acceleration;
+ Atom prop_adapt_decel =
+ XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
- XIChangeDeviceProperty(dev, prop_adapt_decel, XIGetKnownProperty(XATOM_FLOAT), 32,
- PropModeReplace, 1, &fval, FALSE);
+ XIChangeDeviceProperty(dev, prop_adapt_decel,
+ XIGetKnownProperty(XATOM_FLOAT), 32, PropModeReplace,
+ 1, &fval, FALSE);
XISetDevicePropertyDeletable(dev, prop_adapt_decel, FALSE);
- return XIRegisterPropertyHandler(dev, AccelSetAdaptDecelProperty, NULL, NULL);
+ return XIRegisterPropertyHandler(dev, AccelSetAdaptDecelProperty, NULL,
+ NULL);
}
-
/**
* velocity scaling
*/
@@ -334,16 +337,15 @@ AccelSetScaleProperty(DeviceIntPtr dev, Atom atom,
return BadValue;
rc = XIPropToFloat(val, &nelem, &ptr);
- if (checkOnly)
- {
+ if (checkOnly) {
if (rc)
return rc;
return (v > 0) ? Success : BadValue;
}
- if(v > 0)
- vel->corr_mul = v;
+ if (v > 0)
+ vel->corr_mul = v;
return Success;
}
@@ -354,20 +356,22 @@ AccelInitScaleProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
float fval = vel->corr_mul;
Atom prop_velo_scale = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
- XIChangeDeviceProperty(dev, prop_velo_scale, XIGetKnownProperty(XATOM_FLOAT), 32,
- PropModeReplace, 1, &fval, FALSE);
+ XIChangeDeviceProperty(dev, prop_velo_scale,
+ XIGetKnownProperty(XATOM_FLOAT), 32, PropModeReplace,
+ 1, &fval, FALSE);
XISetDevicePropertyDeletable(dev, prop_velo_scale, FALSE);
return XIRegisterPropertyHandler(dev, AccelSetScaleProperty, NULL, NULL);
}
static BOOL
-InitializePredictableAccelerationProperties(
- DeviceIntPtr dev,
- DeviceVelocityPtr vel,
- PredictableAccelSchemePtr schemeData)
+InitializePredictableAccelerationProperties(DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ PredictableAccelSchemePtr
+ schemeData)
{
int num_handlers = 4;
- if(!vel)
+
+ if (!vel)
return FALSE;
schemeData->prop_handlers = calloc(num_handlers, sizeof(long));
@@ -383,9 +387,8 @@ InitializePredictableAccelerationProperties(
}
BOOL
-DeletePredictableAccelerationProperties(
- DeviceIntPtr dev,
- PredictableAccelSchemePtr scheme)
+DeletePredictableAccelerationProperties(DeviceIntPtr dev,
+ PredictableAccelSchemePtr scheme)
{
DeviceVelocityPtr vel;
Atom prop;
@@ -420,26 +423,27 @@ DeletePredictableAccelerationProperties(
void
InitTrackers(DeviceVelocityPtr vel, int ntracker)
{
- if(ntracker < 1){
- ErrorF("(dix ptracc) invalid number of trackers\n");
- return;
+ if (ntracker < 1) {
+ ErrorF("(dix ptracc) invalid number of trackers\n");
+ return;
}
free(vel->tracker);
- vel->tracker = (MotionTrackerPtr)calloc(ntracker, sizeof(MotionTracker));
+ vel->tracker = (MotionTrackerPtr) calloc(ntracker, sizeof(MotionTracker));
vel->num_tracker = ntracker;
}
enum directions {
- N = (1 << 0),
- NE = (1 << 1),
- E = (1 << 2),
- SE = (1 << 3),
- S = (1 << 4),
- SW = (1 << 5),
- W = (1 << 6),
- NW = (1 << 7),
+ N = (1 << 0),
+ NE = (1 << 1),
+ E = (1 << 2),
+ SE = (1 << 3),
+ S = (1 << 4),
+ SW = (1 << 5),
+ W = (1 << 6),
+ NW = (1 << 7),
UNDEFINED = 0xFF
};
+
/**
* return a bit field of possible directions.
* There's no reason against widening to more precise directions (<45 degrees),
@@ -452,40 +456,38 @@ enum directions {
* this movement.
*/
static int
-DoGetDirection(int dx, int dy){
+DoGetDirection(int dx, int dy)
+{
int dir = 0;
/* on insignificant mickeys, flag 135 degrees */
- if(abs(dx) < 2 && abs(dy) < 2){
+ if (abs(dx) < 2 && abs(dy) < 2) {
/* first check diagonal cases */
- if(dx > 0 && dy > 0)
+ if (dx > 0 && dy > 0)
dir = E | SE | S;
- else if(dx > 0 && dy < 0)
- dir = N | NE | E;
- else if(dx < 0 && dy < 0)
- dir = W | NW | N;
- else if(dx < 0 && dy > 0)
- dir = W | SW | S;
+ else if (dx > 0 && dy < 0)
+ dir = N | NE | E;
+ else if (dx < 0 && dy < 0)
+ dir = W | NW | N;
+ else if (dx < 0 && dy > 0)
+ dir = W | SW | S;
/* check axis-aligned directions */
- else if(dx > 0)
- dir = NE | E | SE;
- else if(dx < 0)
- dir = NW | W | SW;
- else if(dy > 0)
- dir = SE | S | SW;
- else if(dy < 0)
- dir = NE | N | NW;
+ else if (dx > 0)
+ dir = NE | E | SE;
+ else if (dx < 0)
+ dir = NW | W | SW;
+ else if (dy > 0)
+ dir = SE | S | SW;
+ else if (dy < 0)
+ dir = NE | N | NW;
else
- dir = UNDEFINED; /* shouldn't happen */
- } else { /* compute angle and set appropriate flags */
- float r;
+ dir = UNDEFINED; /* shouldn't happen */
+ }
+ else { /* compute angle and set appropriate flags */
+ double r;
int i1, i2;
-#ifdef _ISOC99_SOURCE
- r = atan2f(dy, dx);
-#else
r = atan2(dy, dx);
-#endif
/* find direction.
*
* Add 360° to avoid r become negative since C has no well-defined
@@ -497,13 +499,13 @@ DoGetDirection(int dx, int dy){
* But we add extra 90° to match up with our N, S, etc. defines up
* there, rest stays the same.
*/
- r = (r+(M_PI*2.5))/(M_PI/4);
+ r = (r + (M_PI * 2.5)) / (M_PI / 4);
/* this intends to flag 2 directions (45 degrees),
* except on very well-aligned mickeys. */
- i1 = (int)(r+0.1) % 8;
- i2 = (int)(r+0.9) % 8;
- if(i1 < 0 || i1 > 7 || i2 < 0 || i2 > 7)
- dir = UNDEFINED; /* shouldn't happen */
+ i1 = (int) (r + 0.1) % 8;
+ i2 = (int) (r + 0.9) % 8;
+ if (i1 < 0 || i1 > 7 || i2 < 0 || i2 > 7)
+ dir = UNDEFINED; /* shouldn't happen */
else
dir = (1 << i1 | 1 << i2);
}
@@ -521,20 +523,22 @@ DoGetDirection(int dx, int dy){
* this movement.
*/
static int
-GetDirection(int dx, int dy){
+GetDirection(int dx, int dy)
+{
static int cache[DIRECTION_CACHE_SIZE][DIRECTION_CACHE_SIZE];
int dir;
- if (abs(dx) <= DIRECTION_CACHE_RANGE &&
- abs(dy) <= DIRECTION_CACHE_RANGE) {
- /* cacheable */
- dir = cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy];
- if(dir == 0) {
- dir = DoGetDirection(dx, dy);
- cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy] = dir;
- }
- }else{
- /* non-cacheable */
- dir = DoGetDirection(dx, dy);
+
+ if (abs(dx) <= DIRECTION_CACHE_RANGE && abs(dy) <= DIRECTION_CACHE_RANGE) {
+ /* cacheable */
+ dir = cache[DIRECTION_CACHE_RANGE + dx][DIRECTION_CACHE_RANGE + dy];
+ if (dir == 0) {
+ dir = DoGetDirection(dx, dy);
+ cache[DIRECTION_CACHE_RANGE + dx][DIRECTION_CACHE_RANGE + dy] = dir;
+ }
+ }
+ else {
+ /* non-cacheable */
+ dir = DoGetDirection(dx, dy);
}
return dir;
@@ -543,7 +547,6 @@ GetDirection(int dx, int dy){
#undef DIRECTION_CACHE_RANGE
#undef DIRECTION_CACHE_SIZE
-
/* convert offset (age) to array index */
#define TRACKER_INDEX(s, d) (((s)->num_tracker + (s)->cur_tracker - (d)) % (s)->num_tracker)
#define TRACKER(s, d) &(s)->tracker[TRACKER_INDEX(s,d)]
@@ -553,16 +556,17 @@ GetDirection(int dx, int dy){
* 0/0 and set it as the current one.
*/
static inline void
-FeedTrackers(DeviceVelocityPtr vel, int dx, int dy, int cur_t)
+FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t)
{
int n;
- for(n = 0; n < vel->num_tracker; n++){
- vel->tracker[n].dx += dx;
- vel->tracker[n].dy += dy;
+
+ for (n = 0; n < vel->num_tracker; n++) {
+ vel->tracker[n].dx += dx;
+ vel->tracker[n].dy += dy;
}
n = (vel->cur_tracker + 1) % vel->num_tracker;
- vel->tracker[n].dx = 0;
- vel->tracker[n].dy = 0;
+ vel->tracker[n].dx = 0.0;
+ vel->tracker[n].dy = 0.0;
vel->tracker[n].time = cur_t;
vel->tracker[n].dir = GetDirection(dx, dy);
DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n",
@@ -576,14 +580,16 @@ FeedTrackers(DeviceVelocityPtr vel, int dx, int dy, int cur_t)
* velocity scaling.
* This assumes linear motion.
*/
-static float
-CalcTracker(const MotionTracker *tracker, int cur_t){
- float dist = sqrt(tracker->dx * tracker->dx + tracker->dy * tracker->dy);
+static double
+CalcTracker(const MotionTracker * tracker, int cur_t)
+{
+ double dist = sqrt(tracker->dx * tracker->dx + tracker->dy * tracker->dy);
int dtime = cur_t - tracker->time;
- if(dtime > 0)
- return dist / dtime;
+
+ if (dtime > 0)
+ return dist / dtime;
else
- return 0;/* synonymous for NaN, since we're not C99 */
+ return 0; /* synonymous for NaN, since we're not C99 */
}
/* find the most plausible velocity. That is, the most distant
@@ -593,74 +599,82 @@ CalcTracker(const MotionTracker *tracker, int cur_t){
*
* @return The tracker's velocity or 0 if the above conditions are unmet
*/
-static float
-QueryTrackers(DeviceVelocityPtr vel, int cur_t){
+static double
+QueryTrackers(DeviceVelocityPtr vel, int cur_t)
+{
int offset, dir = UNDEFINED, used_offset = -1, age_ms;
+
/* initial velocity: a low-offset, valid velocity */
- float initial_velocity = 0, result = 0, velocity_diff;
- float velocity_factor = vel->corr_mul * vel->const_acceleration; /* premultiply */
+ double initial_velocity = 0, result = 0, velocity_diff;
+ double velocity_factor = vel->corr_mul * vel->const_acceleration; /* premultiply */
+
/* loop from current to older data */
- for(offset = 1; offset < vel->num_tracker; offset++){
- MotionTracker *tracker = TRACKER(vel, offset);
- float tracker_velocity;
-
- age_ms = cur_t - tracker->time;
-
- /* bail out if data is too old and protect from overrun */
- if (age_ms >= vel->reset_time || age_ms < 0) {
- DebugAccelF("(dix prtacc) query: tracker too old\n");
- break;
- }
-
- /*
- * this heuristic avoids using the linear-motion velocity formula
- * in CalcTracker() on motion that isn't exactly linear. So to get
- * even more precision we could subdivide as a final step, so possible
- * non-linearities are accounted for.
- */
- dir &= tracker->dir;
- if(dir == 0){ /* we've changed octant of movement (e.g. NE → NW) */
- DebugAccelF("(dix prtacc) query: no longer linear\n");
- /* instead of breaking it we might also inspect the partition after,
- * but actual improvement with this is probably rare. */
- break;
- }
-
- tracker_velocity = CalcTracker(tracker, cur_t) * velocity_factor;
-
- if ((initial_velocity == 0 || offset <= vel->initial_range) && tracker_velocity != 0) {
- /* set initial velocity and result */
- result = initial_velocity = tracker_velocity;
- used_offset = offset;
- } else if (initial_velocity != 0 && tracker_velocity != 0) {
- velocity_diff = fabs(initial_velocity - tracker_velocity);
-
- if (velocity_diff > vel->max_diff &&
- velocity_diff/(initial_velocity + tracker_velocity) >= vel->max_rel_diff) {
- /* we're not in range, quit - it won't get better. */
- DebugAccelF("(dix prtacc) query: tracker too different:"
- " old %2.2f initial %2.2f diff: %2.2f\n",
- tracker_velocity, initial_velocity, velocity_diff);
- break;
- }
- /* we're in range with the initial velocity,
- * so this result is likely better
- * (it contains more information). */
- result = tracker_velocity;
- used_offset = offset;
- }
+ for (offset = 1; offset < vel->num_tracker; offset++) {
+ MotionTracker *tracker = TRACKER(vel, offset);
+ double tracker_velocity;
+
+ age_ms = cur_t - tracker->time;
+
+ /* bail out if data is too old and protect from overrun */
+ if (age_ms >= vel->reset_time || age_ms < 0) {
+ DebugAccelF("(dix prtacc) query: tracker too old\n");
+ break;
+ }
+
+ /*
+ * this heuristic avoids using the linear-motion velocity formula
+ * in CalcTracker() on motion that isn't exactly linear. So to get
+ * even more precision we could subdivide as a final step, so possible
+ * non-linearities are accounted for.
+ */
+ dir &= tracker->dir;
+ if (dir == 0) { /* we've changed octant of movement (e.g. NE → NW) */
+ DebugAccelF("(dix prtacc) query: no longer linear\n");
+ /* instead of breaking it we might also inspect the partition after,
+ * but actual improvement with this is probably rare. */
+ break;
+ }
+
+ tracker_velocity = CalcTracker(tracker, cur_t) * velocity_factor;
+
+ if ((initial_velocity == 0 || offset <= vel->initial_range) &&
+ tracker_velocity != 0) {
+ /* set initial velocity and result */
+ result = initial_velocity = tracker_velocity;
+ used_offset = offset;
+ }
+ else if (initial_velocity != 0 && tracker_velocity != 0) {
+ velocity_diff = fabs(initial_velocity - tracker_velocity);
+
+ if (velocity_diff > vel->max_diff &&
+ velocity_diff / (initial_velocity + tracker_velocity) >=
+ vel->max_rel_diff) {
+ /* we're not in range, quit - it won't get better. */
+ DebugAccelF("(dix prtacc) query: tracker too different:"
+ " old %2.2f initial %2.2f diff: %2.2f\n",
+ tracker_velocity, initial_velocity, velocity_diff);
+ break;
+ }
+ /* we're in range with the initial velocity,
+ * so this result is likely better
+ * (it contains more information). */
+ result = tracker_velocity;
+ used_offset = offset;
+ }
}
- if(offset == vel->num_tracker){
- DebugAccelF("(dix prtacc) query: last tracker in effect\n");
- used_offset = vel->num_tracker-1;
+ if (offset == vel->num_tracker) {
+ DebugAccelF("(dix prtacc) query: last tracker in effect\n");
+ used_offset = vel->num_tracker - 1;
}
+ if (used_offset >= 0) {
#ifdef PTRACCEL_DEBUGGING
- if(used_offset >= 0){
- MotionTracker *tracker = TRACKER(vel, used_offset);
- DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n",
- used_offset, tracker->dx, tracker->dy, cur_t - tracker->time);
- }
+ MotionTracker *tracker = TRACKER(vel, used_offset);
+
+ DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n",
+ used_offset, tracker->dx, tracker->dy,
+ cur_t - tracker->time);
#endif
+ }
return result;
}
@@ -672,13 +686,9 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t){
* return true if non-visible state reset is suggested
*/
BOOL
-ProcessVelocityData2D(
- DeviceVelocityPtr vel,
- int dx,
- int dy,
- int time)
+ProcessVelocityData2D(DeviceVelocityPtr vel, double dx, double dy, int time)
{
- float velocity;
+ double velocity;
vel->last_velocity = vel->velocity;
@@ -694,21 +704,20 @@ ProcessVelocityData2D(
* this flattens significant ( > 1) mickeys a little bit for more steady
* constant-velocity response
*/
-static inline float
-ApplySimpleSoftening(int prev_delta, int delta)
+static inline double
+ApplySimpleSoftening(double prev_delta, double delta)
{
- float result = delta;
+ double result = delta;
- if (delta < -1 || delta > 1) {
- if (delta > prev_delta)
- result -= 0.5;
- else if (delta < prev_delta)
- result += 0.5;
+ if (delta < -1.0 || delta > 1.0) {
+ if (delta > prev_delta)
+ result -= 0.5;
+ else if (delta < prev_delta)
+ result += 0.5;
}
return result;
}
-
/**
* Soften the delta based on previous deltas stored in vel.
*
@@ -716,10 +725,7 @@ ApplySimpleSoftening(int prev_delta, int delta)
* @param[in,out] fdx Delta Y, modified in-place.
*/
static void
-ApplySoftening(
- DeviceVelocityPtr vel,
- float* fdx,
- float* fdy)
+ApplySoftening(DeviceVelocityPtr vel, double *fdx, double *fdy)
{
if (vel->use_softening) {
*fdx = ApplySimpleSoftening(vel->last_dx, *fdx);
@@ -728,7 +734,7 @@ ApplySoftening(
}
static void
-ApplyConstantDeceleration(DeviceVelocityPtr vel, float *fdx, float *fdy)
+ApplyConstantDeceleration(DeviceVelocityPtr vel, double *fdx, double *fdy)
{
*fdx *= vel->const_acceleration;
*fdy *= vel->const_acceleration;
@@ -737,20 +743,19 @@ ApplyConstantDeceleration(DeviceVelocityPtr vel, float *fdx, float *fdy)
/*
* compute the acceleration for given velocity and enforce min_acceleartion
*/
-float
-BasicComputeAcceleration(
- DeviceIntPtr dev,
- DeviceVelocityPtr vel,
- float velocity,
- float threshold,
- float acc){
-
- float result;
+double
+BasicComputeAcceleration(DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ double velocity, double threshold, double acc)
+{
+
+ double result;
+
result = vel->Profile(dev, vel, velocity, threshold, acc);
/* enforce min_acceleration */
if (result < vel->min_acceleration)
- result = vel->min_acceleration;
+ result = vel->min_acceleration;
return result;
}
@@ -759,48 +764,49 @@ BasicComputeAcceleration(
* If the velocity has changed, an average is taken of 6 velocity factors:
* current velocity, last velocity and 4 times the average between the two.
*/
-static float
-ComputeAcceleration(
- DeviceIntPtr dev,
- DeviceVelocityPtr vel,
- float threshold,
- float acc){
- float result;
-
- if(vel->velocity <= 0){
- DebugAccelF("(dix ptracc) profile skipped\n");
+static double
+ComputeAcceleration(DeviceIntPtr dev,
+ DeviceVelocityPtr vel, double threshold, double acc)
+{
+ double result;
+
+ if (vel->velocity <= 0) {
+ DebugAccelF("(dix ptracc) profile skipped\n");
/*
* If we have no idea about device velocity, don't pretend it.
*/
- return 1;
+ 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. */
- result = BasicComputeAcceleration(
- dev, vel, vel->velocity, threshold, acc);
- result += BasicComputeAcceleration(
- dev, vel, vel->last_velocity, threshold, acc);
- result += 4.0f * BasicComputeAcceleration(dev, vel,
- (vel->last_velocity + vel->velocity) / 2,
- threshold, acc);
- result /= 6.0f;
- DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n",
- vel->velocity, vel->last_velocity, result);
- }else{
- result = BasicComputeAcceleration(dev, vel,
- vel->velocity, threshold, acc);
- DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
- vel->velocity, res);
+ 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. */
+ result =
+ BasicComputeAcceleration(dev, vel, vel->velocity, threshold, acc);
+ result +=
+ BasicComputeAcceleration(dev, vel, vel->last_velocity, threshold,
+ acc);
+ result +=
+ 4.0f * BasicComputeAcceleration(dev, vel,
+ (vel->last_velocity +
+ vel->velocity) / 2, threshold,
+ acc);
+ result /= 6.0f;
+ DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n",
+ vel->velocity, vel->last_velocity, result);
+ }
+ else {
+ result = BasicComputeAcceleration(dev, vel,
+ vel->velocity, threshold, acc);
+ DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
+ vel->velocity, res);
}
return result;
}
-
/*****************************************
* Acceleration functions and profiles
****************************************/
@@ -808,46 +814,31 @@ ComputeAcceleration(
/**
* Polynomial function similar previous one, but with f(1) = 1
*/
-static float
-PolynomialAccelerationProfile(
- DeviceIntPtr dev,
- DeviceVelocityPtr vel,
- float velocity,
- float ignored,
- float acc)
+static double
+PolynomialAccelerationProfile(DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ double velocity, double ignored, double acc)
{
- return pow(velocity, (acc - 1.0) * 0.5);
+ return pow(velocity, (acc - 1.0) * 0.5);
}
-
/**
* returns acceleration for velocity.
* This profile selects the two functions like the old scheme did
*/
-static float
-ClassicProfile(
- DeviceIntPtr dev,
- DeviceVelocityPtr vel,
- float velocity,
- float threshold,
- float acc)
+static double
+ClassicProfile(DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ double velocity, double threshold, double acc)
{
if (threshold > 0) {
- return SimpleSmoothProfile (dev,
- vel,
- velocity,
- threshold,
- acc);
- } else {
- return PolynomialAccelerationProfile (dev,
- vel,
- velocity,
- 0,
- acc);
+ return SimpleSmoothProfile(dev, vel, velocity, threshold, acc);
+ }
+ else {
+ return PolynomialAccelerationProfile(dev, vel, velocity, 0, acc);
}
}
-
/**
* Power profile
* This has a completely smooth transition curve, i.e. no jumps in the
@@ -856,17 +847,14 @@ ClassicProfile(
* This has the expense of overall response dependency on min-acceleration.
* In effect, min_acceleration mimics const_acceleration in this profile.
*/
-static float
-PowerProfile(
- DeviceIntPtr dev,
- DeviceVelocityPtr vel,
- float velocity,
- float threshold,
- float acc)
+static double
+PowerProfile(DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ double velocity, double threshold, double acc)
{
- float vel_dist;
+ double vel_dist;
- acc = (acc-1.0) * 0.1f + 1.0; /* without this, acc of 2 is unuseable */
+ acc = (acc - 1.0) * 0.1f + 1.0; /* without this, acc of 2 is unuseable */
if (velocity <= threshold)
return vel->min_acceleration;
@@ -874,7 +862,6 @@ PowerProfile(
return (pow(acc, vel_dist)) * vel->min_acceleration;
}
-
/**
* just a smooth function in [0..1] -> [0..1]
* - point symmetry at 0.5
@@ -882,29 +869,26 @@ PowerProfile(
* - starts faster than a sinoid
* - smoothness C1 (Cinf if you dare to ignore endpoints)
*/
-static inline float
-CalcPenumbralGradient(float x){
+static inline double
+CalcPenumbralGradient(double x)
+{
x *= 2.0f;
x -= 1.0f;
- return 0.5f + (x * sqrt(1.0f - x*x) + asin(x))/M_PI;
+ return 0.5f + (x * sqrt(1.0 - x * x) + asin(x)) / M_PI;
}
-
/**
* acceleration function similar to classic accelerated/unaccelerated,
* but with smooth transition in between (and towards zero for adaptive dec.).
*/
-static float
-SimpleSmoothProfile(
- DeviceIntPtr dev,
- DeviceVelocityPtr vel,
- float velocity,
- float threshold,
- float acc)
+static double
+SimpleSmoothProfile(DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ double velocity, double threshold, double acc)
{
- if(velocity < 1.0f)
- return CalcPenumbralGradient(0.5 + velocity*0.5) * 2.0f - 1.0f;
- if(threshold < 1.0f)
+ if (velocity < 1.0f)
+ return CalcPenumbralGradient(0.5 + velocity * 0.5) * 2.0f - 1.0f;
+ if (threshold < 1.0f)
threshold = 1.0f;
if (velocity <= threshold)
return 1;
@@ -912,118 +896,102 @@ SimpleSmoothProfile(
if (velocity >= acc)
return acc;
else
- return 1.0f + (CalcPenumbralGradient(velocity/acc) * (acc - 1.0f));
+ return 1.0f + (CalcPenumbralGradient(velocity / acc) * (acc - 1.0f));
}
-
/**
* This profile uses the first half of the penumbral gradient as a start
* and then scales linearly.
*/
-static float
-SmoothLinearProfile(
- DeviceIntPtr dev,
- DeviceVelocityPtr vel,
- float velocity,
- float threshold,
- float acc)
+static double
+SmoothLinearProfile(DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ double velocity, double threshold, double acc)
{
- float res, nv;
+ double res, nv;
- if(acc > 1.0f)
- acc -= 1.0f; /*this is so acc = 1 is no acceleration */
+ if (acc > 1.0f)
+ acc -= 1.0f; /*this is so acc = 1 is no acceleration */
else
return 1.0f;
nv = (velocity - threshold) * acc * 0.5f;
- if(nv < 0){
+ if (nv < 0) {
res = 0;
- }else if(nv < 2){
- res = CalcPenumbralGradient(nv*0.25f)*2.0f;
- }else{
+ }
+ else if (nv < 2) {
+ res = CalcPenumbralGradient(nv * 0.25f) * 2.0f;
+ }
+ else {
nv -= 2.0f;
res = nv * 2.0f / M_PI /* steepness of gradient at 0.5 */
- + 1.0f; /* gradient crosses 2|1 */
+ + 1.0f; /* gradient crosses 2|1 */
}
res += vel->min_acceleration;
return res;
}
-
/**
* From 0 to threshold, the response graduates smoothly from min_accel to
* acceleration. Beyond threshold it is exactly the specified acceleration.
*/
-static float
-SmoothLimitedProfile(
- DeviceIntPtr dev,
- DeviceVelocityPtr vel,
- float velocity,
- float threshold,
- float acc)
+static double
+SmoothLimitedProfile(DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ double velocity, double threshold, double acc)
{
- float res;
+ double res;
- if(velocity >= threshold || threshold == 0.0f)
- return acc;
+ if (velocity >= threshold || threshold == 0.0f)
+ return acc;
- velocity /= threshold; /* should be [0..1[ now */
+ velocity /= threshold; /* should be [0..1[ now */
res = CalcPenumbralGradient(velocity) * (acc - vel->min_acceleration);
return vel->min_acceleration + res;
}
-
-static float
-LinearProfile(
- DeviceIntPtr dev,
- DeviceVelocityPtr vel,
- float velocity,
- float threshold,
- float acc)
+static double
+LinearProfile(DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ double velocity, double threshold, double acc)
{
return acc * velocity;
}
-static float
-NoProfile(
- DeviceIntPtr dev,
- DeviceVelocityPtr vel,
- float velocity,
- float threshold,
- float acc)
+static double
+NoProfile(DeviceIntPtr dev,
+ DeviceVelocityPtr vel, double velocity, double threshold, double acc)
{
return 1.0f;
}
static PointerAccelerationProfileFunc
-GetAccelerationProfile(
- DeviceVelocityPtr vel,
- int profile_num)
+GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num)
{
- switch(profile_num){
- case AccelProfileClassic:
- return ClassicProfile;
- case AccelProfileDeviceSpecific:
- return vel->deviceSpecificProfile;
- case AccelProfilePolynomial:
- return PolynomialAccelerationProfile;
- case AccelProfileSmoothLinear:
- return SmoothLinearProfile;
- case AccelProfileSimple:
- return SimpleSmoothProfile;
- case AccelProfilePower:
- return PowerProfile;
- case AccelProfileLinear:
- return LinearProfile;
- case AccelProfileSmoothLimited:
- return SmoothLimitedProfile;
- case AccelProfileNone:
- return NoProfile;
- default:
- return NULL;
+ switch (profile_num) {
+ case AccelProfileClassic:
+ return ClassicProfile;
+ case AccelProfileDeviceSpecific:
+ return vel->deviceSpecificProfile;
+ case AccelProfilePolynomial:
+ return PolynomialAccelerationProfile;
+ case AccelProfileSmoothLinear:
+ return SmoothLinearProfile;
+ case AccelProfileSimple:
+ return SimpleSmoothProfile;
+ case AccelProfilePower:
+ return PowerProfile;
+ case AccelProfileLinear:
+ return LinearProfile;
+ case AccelProfileSmoothLimited:
+ return SmoothLimitedProfile;
+ case AccelProfileNone:
+ return NoProfile;
+ default:
+ return NULL;
}
}
@@ -1038,15 +1006,14 @@ GetAccelerationProfile(
* returns FALSE if profile number is unavailable, TRUE otherwise.
*/
int
-SetAccelerationProfile(
- DeviceVelocityPtr vel,
- int profile_num)
+SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num)
{
PointerAccelerationProfileFunc profile;
+
profile = GetAccelerationProfile(vel, profile_num);
- if(profile == NULL && profile_num != PROFILE_UNINITIALIZE)
- return FALSE;
+ if (profile == NULL && profile_num != PROFILE_UNINITIALIZE)
+ return FALSE;
/* Here one could free old profile-private data */
free(vel->profile_private);
@@ -1061,7 +1028,6 @@ SetAccelerationProfile(
* driver interaction
**********************************************/
-
/**
* device-specific profile
*
@@ -1072,12 +1038,11 @@ SetAccelerationProfile(
* Users may override or choose it.
*/
void
-SetDeviceSpecificAccelerationProfile(
- DeviceVelocityPtr vel,
- PointerAccelerationProfileFunc profile)
+SetDeviceSpecificAccelerationProfile(DeviceVelocityPtr vel,
+ PointerAccelerationProfileFunc profile)
{
- if(vel)
- vel->deviceSpecificProfile = profile;
+ if (vel)
+ vel->deviceSpecificProfile = profile;
}
/**
@@ -1085,21 +1050,20 @@ SetDeviceSpecificAccelerationProfile(
* the predictable acceleration scheme is not in effect.
*/
DeviceVelocityPtr
-GetDevicePredictableAccelData(
- DeviceIntPtr dev)
+GetDevicePredictableAccelData(DeviceIntPtr dev)
{
- /*sanity check*/
- if(!dev){
- ErrorF("[dix] accel: DeviceIntPtr was NULL");
- return NULL;
+ /*sanity check */
+ if (!dev) {
+ ErrorF("[dix] accel: DeviceIntPtr was NULL");
+ return NULL;
}
- if( dev->valuator &&
- dev->valuator->accelScheme.AccelSchemeProc ==
- acceleratePointerPredictable &&
- dev->valuator->accelScheme.accelData != NULL){
+ if (dev->valuator &&
+ dev->valuator->accelScheme.AccelSchemeProc ==
+ acceleratePointerPredictable &&
+ dev->valuator->accelScheme.accelData != NULL) {
- return ((PredictableAccelSchemePtr)
- dev->valuator->accelScheme.accelData)->vel;
+ return ((PredictableAccelSchemePtr)
+ dev->valuator->accelScheme.accelData)->vel;
}
return NULL;
}
@@ -1114,77 +1078,54 @@ GetDevicePredictableAccelData(
* enable fine-grained predictable acceleration profiles.
*/
void
-acceleratePointerPredictable(
- DeviceIntPtr dev,
- ValuatorMask* val,
- CARD32 evtime)
+acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
{
- int dx = 0, dy = 0, tmpi;
+ double dx = 0, dy = 0;
DeviceVelocityPtr velocitydata = GetDevicePredictableAccelData(dev);
Bool soften = TRUE;
- if (!velocitydata)
+ if (valuator_mask_num_valuators(val) == 0 || !velocitydata)
return;
if (velocitydata->statistics.profile_number == AccelProfileNone &&
velocitydata->const_acceleration == 1.0f) {
- return; /*we're inactive anyway, so skip the whole thing.*/
+ return; /*we're inactive anyway, so skip the whole thing. */
}
if (valuator_mask_isset(val, 0)) {
- dx = valuator_mask_get(val, 0);
+ dx = valuator_mask_get_double(val, 0);
}
if (valuator_mask_isset(val, 1)) {
- dy = valuator_mask_get(val, 1);
+ dy = valuator_mask_get_double(val, 1);
}
- if (dx || dy){
+ if (dx != 0.0 || dy != 0.0) {
/* reset non-visible state? */
- if (ProcessVelocityData2D(velocitydata, dx , dy, evtime)) {
+ if (ProcessVelocityData2D(velocitydata, dx, dy, evtime)) {
soften = FALSE;
}
if (dev->ptrfeed && dev->ptrfeed->ctrl.num) {
- float mult;
+ double mult;
/* invoke acceleration profile to determine acceleration */
- mult = ComputeAcceleration (dev, velocitydata,
- dev->ptrfeed->ctrl.threshold,
- (float)dev->ptrfeed->ctrl.num /
- (float)dev->ptrfeed->ctrl.den);
-
- if(mult != 1.0f || velocitydata->const_acceleration != 1.0f) {
- float fdx = dx,
- fdy = dy;
+ mult = ComputeAcceleration(dev, velocitydata,
+ dev->ptrfeed->ctrl.threshold,
+ (double) dev->ptrfeed->ctrl.num /
+ (double) dev->ptrfeed->ctrl.den);
+ if (mult != 1.0f || velocitydata->const_acceleration != 1.0f) {
if (mult > 1.0f && soften)
- ApplySoftening(velocitydata, &fdx, &fdy);
- ApplyConstantDeceleration(velocitydata, &fdx, &fdy);
-
- /* Calculate the new delta (with accel) and drop it back
- * into the valuator masks */
- if (dx) {
- float tmp;
- tmp = mult * fdx + dev->last.remainder[0];
- /* Since it may not be apparent: lrintf() does not offer
- * strong statements about rounding; however because we
- * process each axis conditionally, there's no danger
- * of a toggling remainder. Its lack of guarantees likely
- * makes it faster on the average target. */
- tmpi = lrintf(tmp);
- valuator_mask_set(val, 0, tmpi);
- dev->last.remainder[0] = tmp - (float)tmpi;
- }
- if (dy) {
- float tmp;
- tmp = mult * fdy + dev->last.remainder[1];
- tmpi = lrintf(tmp);
- valuator_mask_set(val, 1, tmpi);
- dev->last.remainder[1] = tmp - (float)tmpi;
- }
- DebugAccelF("pos (%i | %i) remainders x: %.3f y: %.3f delta x:%.3f y:%.3f\n",
- *px, *py, dev->last.remainder[0], dev->last.remainder[1], fdx, fdy);
+ ApplySoftening(velocitydata, &dx, &dy);
+ ApplyConstantDeceleration(velocitydata, &dx, &dy);
+
+ if (dx != 0.0)
+ valuator_mask_set_double(val, 0, mult * dx);
+ if (dy != 0.0)
+ valuator_mask_set_double(val, 1, mult * dy);
+ DebugAccelF("pos (%i | %i) delta x:%.3f y:%.3f\n", mult * dx,
+ mult * dy);
}
}
}
@@ -1193,20 +1134,16 @@ acceleratePointerPredictable(
velocitydata->last_dy = dy;
}
-
-
/**
* Originally a part of xf86PostMotionEvent; modifies valuators
* in-place. Retained mostly for embedded scenarios.
*/
void
-acceleratePointerLightweight(
- DeviceIntPtr dev,
- ValuatorMask* val,
- CARD32 ignored)
+acceleratePointerLightweight(DeviceIntPtr dev,
+ ValuatorMask *val, CARD32 ignored)
{
- float mult = 0.0, tmpf;
- int dx = 0, dy = 0, tmpi;
+ double mult = 0.0, tmpf;
+ double dx = 0.0, dy = 0.0;
if (valuator_mask_isset(val, 0)) {
dx = valuator_mask_get(val, 0);
@@ -1216,53 +1153,34 @@ acceleratePointerLightweight(
dy = valuator_mask_get(val, 1);
}
- if (!dx && !dy)
+ if (valuator_mask_num_valuators(val) == 0)
return;
if (dev->ptrfeed && dev->ptrfeed->ctrl.num) {
/* modeled from xf86Events.c */
if (dev->ptrfeed->ctrl.threshold) {
- if ((abs(dx) + abs(dy)) >= dev->ptrfeed->ctrl.threshold) {
- tmpf = ((float)dx *
- (float)(dev->ptrfeed->ctrl.num)) /
- (float)(dev->ptrfeed->ctrl.den) +
- dev->last.remainder[0];
- if (dx) {
- tmpi = (int) tmpf;
- valuator_mask_set(val, 0, tmpi);
- dev->last.remainder[0] = tmpf - (float)tmpi;
+ if ((fabs(dx) + fabs(dy)) >= dev->ptrfeed->ctrl.threshold) {
+ if (dx != 0.0) {
+ tmpf = (dx * (double) (dev->ptrfeed->ctrl.num)) /
+ (double) (dev->ptrfeed->ctrl.den);
+ valuator_mask_set_double(val, 0, tmpf);
}
- tmpf = ((float)dy *
- (float)(dev->ptrfeed->ctrl.num)) /
- (float)(dev->ptrfeed->ctrl.den) +
- dev->last.remainder[1];
- if (dy) {
- tmpi = (int) tmpf;
- valuator_mask_set(val, 1, tmpi);
- dev->last.remainder[1] = tmpf - (float)tmpi;
+ if (dy != 0.0) {
+ tmpf = (dy * (double) (dev->ptrfeed->ctrl.num)) /
+ (double) (dev->ptrfeed->ctrl.den);
+ valuator_mask_set_double(val, 1, tmpf);
}
}
}
else {
- mult = pow((float)dx * (float)dx + (float)dy * (float)dy,
- ((float)(dev->ptrfeed->ctrl.num) /
- (float)(dev->ptrfeed->ctrl.den) - 1.0) /
- 2.0) / 2.0;
- if (dx) {
- tmpf = mult * (float)dx +
- dev->last.remainder[0];
- tmpi = (int) tmpf;
- valuator_mask_set(val, 0, tmpi);
- dev->last.remainder[0] = tmpf - (float)tmpi;
- }
- if (dy) {
- tmpf = mult * (float)dy +
- dev->last.remainder[1];
- tmpi = (int)tmpf;
- valuator_mask_set(val, 1, tmpi);
- dev->last.remainder[1] = tmpf - (float)tmpi;
- }
+ mult = pow(dx * dx + dy * dy,
+ ((double) (dev->ptrfeed->ctrl.num) /
+ (double) (dev->ptrfeed->ctrl.den) - 1.0) / 2.0) / 2.0;
+ if (dx != 0.0)
+ valuator_mask_set_double(val, 0, mult * dx);
+ if (dy != 0.0)
+ valuator_mask_set_double(val, 1, mult * dy);
}
}
}