diff options
Diffstat (limited to 'xorg-server/dix/ptrveloc.c')
-rw-r--r-- | xorg-server/dix/ptrveloc.c | 699 |
1 files changed, 330 insertions, 369 deletions
diff --git a/xorg-server/dix/ptrveloc.c b/xorg-server/dix/ptrveloc.c index 1ba531c96..fb5f19d69 100644 --- a/xorg-server/dix/ptrveloc.c +++ b/xorg-server/dix/ptrveloc.c @@ -71,8 +71,9 @@ /* fwds */ int -SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); + SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); static double + SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double threshold, double acc); static PointerAccelerationProfileFunc @@ -90,7 +91,7 @@ DeletePredictableAccelerationProperties(DeviceIntPtr, #ifdef PTRACCEL_DEBUGGING #define DebugAccelF ErrorF #else -#define DebugAccelF(...) /* */ +#define DebugAccelF(...) /* */ #endif /******************************** @@ -108,11 +109,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; @@ -121,26 +122,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)); @@ -156,7 +158,6 @@ InitPredictableAccelerationScheme(DeviceIntPtr dev, return TRUE; } - /** * Uninit scheme */ @@ -164,6 +165,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 @@ -174,14 +176,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 ************************/ @@ -206,15 +209,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; } @@ -251,15 +254,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; } @@ -267,16 +269,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 */ @@ -297,15 +299,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; } @@ -313,16 +314,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 */ @@ -343,16 +346,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; } @@ -363,20 +365,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)); @@ -392,9 +396,8 @@ InitializePredictableAccelerationProperties( } BOOL -DeletePredictableAccelerationProperties( - DeviceIntPtr dev, - PredictableAccelSchemePtr scheme) +DeletePredictableAccelerationProperties(DeviceIntPtr dev, + PredictableAccelSchemePtr scheme) { DeviceVelocityPtr vel; Atom prop; @@ -429,26 +432,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), @@ -461,32 +465,34 @@ 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 */ + dir = UNDEFINED; /* shouldn't happen */ + } + else { /* compute angle and set appropriate flags */ double r; int i1, i2; @@ -502,13 +508,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); } @@ -526,19 +532,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); + /* 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; @@ -547,7 +556,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)] @@ -560,9 +568,10 @@ static inline void 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.0; @@ -581,13 +590,15 @@ FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t) * This assumes linear motion. */ static double -CalcTracker(const MotionTracker *tracker, int cur_t){ +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 @@ -598,71 +609,79 @@ CalcTracker(const MotionTracker *tracker, int cur_t){ * @return The tracker's velocity or 0 if the above conditions are unmet */ static double -QueryTrackers(DeviceVelocityPtr vel, int cur_t){ +QueryTrackers(DeviceVelocityPtr vel, int cur_t) +{ int offset, dir = UNDEFINED, used_offset = -1, age_ms; + /* initial velocity: a low-offset, valid velocity */ double initial_velocity = 0, result = 0, velocity_diff; - double velocity_factor = vel->corr_mul * vel->const_acceleration; /* premultiply */ + 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); - 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; - } + 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){ + if (used_offset >= 0) { #ifdef PTRACCEL_DEBUGGING - 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; @@ -676,11 +695,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t){ * return true if non-visible state reset is suggested */ BOOL -ProcessVelocityData2D( - DeviceVelocityPtr vel, - double dx, - double dy, - int time) +ProcessVelocityData2D(DeviceVelocityPtr vel, double dx, double dy, int time) { double velocity; @@ -704,15 +719,14 @@ ApplySimpleSoftening(double prev_delta, double delta) double result = delta; if (delta < -1.0 || delta > 1.0) { - if (delta > prev_delta) - result -= 0.5; - else if (delta < prev_delta) - result += 0.5; + 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. * @@ -720,10 +734,7 @@ ApplySimpleSoftening(double prev_delta, double delta) * @param[in,out] fdx Delta Y, modified in-place. */ static void -ApplySoftening( - DeviceVelocityPtr vel, - double* fdx, - double* fdy) +ApplySoftening(DeviceVelocityPtr vel, double *fdx, double *fdy) { if (vel->use_softening) { *fdx = ApplySimpleSoftening(vel->last_dx, *fdx); @@ -742,19 +753,18 @@ ApplyConstantDeceleration(DeviceVelocityPtr vel, double *fdx, double *fdy) * compute the acceleration for given velocity and enforce min_acceleartion */ double -BasicComputeAcceleration( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - double velocity, - double threshold, - double acc){ +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; } @@ -764,47 +774,48 @@ BasicComputeAcceleration( * current velocity, last velocity and 4 times the average between the two. */ static double -ComputeAcceleration( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - double threshold, - double acc){ +ComputeAcceleration(DeviceIntPtr dev, + DeviceVelocityPtr vel, double threshold, double acc) +{ double result; - if(vel->velocity <= 0){ - DebugAccelF("(dix ptracc) profile skipped\n"); + 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 ****************************************/ @@ -813,45 +824,30 @@ ComputeAcceleration( * Polynomial function similar previous one, but with f(1) = 1 */ static double -PolynomialAccelerationProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - double velocity, - double ignored, - double acc) +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 double -ClassicProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - double velocity, - double threshold, - double acc) +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 @@ -861,16 +857,13 @@ ClassicProfile( * In effect, min_acceleration mimics const_acceleration in this profile. */ static double -PowerProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - double velocity, - double threshold, - double acc) +PowerProfile(DeviceIntPtr dev, + DeviceVelocityPtr vel, + double velocity, double threshold, double acc) { 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; @@ -878,7 +871,6 @@ PowerProfile( return (pow(acc, vel_dist)) * vel->min_acceleration; } - /** * just a smooth function in [0..1] -> [0..1] * - point symmetry at 0.5 @@ -887,28 +879,25 @@ PowerProfile( * - smoothness C1 (Cinf if you dare to ignore endpoints) */ static inline double -CalcPenumbralGradient(double x){ +CalcPenumbralGradient(double x) +{ x *= 2.0f; x -= 1.0f; - return 0.5f + (x * sqrt(1.0 - 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 double -SimpleSmoothProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - double velocity, - double threshold, - double acc) +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; @@ -916,118 +905,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 double -SmoothLinearProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - double velocity, - double threshold, - double acc) +SmoothLinearProfile(DeviceIntPtr dev, + DeviceVelocityPtr vel, + double velocity, double threshold, double acc) { 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 double -SmoothLimitedProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - double velocity, - double threshold, - double acc) +SmoothLimitedProfile(DeviceIntPtr dev, + DeviceVelocityPtr vel, + double velocity, double threshold, double acc) { 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 double -LinearProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - double velocity, - double threshold, - double acc) +LinearProfile(DeviceIntPtr dev, + DeviceVelocityPtr vel, + double velocity, double threshold, double acc) { return acc * velocity; } static double -NoProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - double velocity, - double threshold, - double acc) +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; } } @@ -1042,15 +1015,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); @@ -1065,7 +1037,6 @@ SetAccelerationProfile( * driver interaction **********************************************/ - /** * device-specific profile * @@ -1076,12 +1047,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; } /** @@ -1089,21 +1059,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; } @@ -1118,10 +1087,7 @@ GetDevicePredictableAccelData( * enable fine-grained predictable acceleration profiles. */ void -acceleratePointerPredictable( - DeviceIntPtr dev, - ValuatorMask* val, - CARD32 evtime) +acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime) { double dx = 0, dy = 0; DeviceVelocityPtr velocitydata = GetDevicePredictableAccelData(dev); @@ -1132,7 +1098,7 @@ acceleratePointerPredictable( 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)) { @@ -1145,7 +1111,7 @@ acceleratePointerPredictable( 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; } @@ -1153,12 +1119,12 @@ acceleratePointerPredictable( double mult; /* invoke acceleration profile to determine acceleration */ - mult = ComputeAcceleration (dev, velocitydata, - dev->ptrfeed->ctrl.threshold, - (double)dev->ptrfeed->ctrl.num / - (double)dev->ptrfeed->ctrl.den); + 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 || velocitydata->const_acceleration != 1.0f) { if (mult > 1.0f && soften) ApplySoftening(velocitydata, &dx, &dy); ApplyConstantDeceleration(velocitydata, &dx, &dy); @@ -1177,17 +1143,13 @@ 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) { double mult = 0.0, tmpf; double dx = 0.0, dy = 0.0; @@ -1208,23 +1170,22 @@ acceleratePointerLightweight( if (dev->ptrfeed->ctrl.threshold) { 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); + tmpf = (dx * (double) (dev->ptrfeed->ctrl.num)) / + (double) (dev->ptrfeed->ctrl.den); valuator_mask_set_double(val, 0, tmpf); } if (dy != 0.0) { - tmpf = (dy * (double)(dev->ptrfeed->ctrl.num)) / - (double)(dev->ptrfeed->ctrl.den); + tmpf = (dy * (double) (dev->ptrfeed->ctrl.num)) / + (double) (dev->ptrfeed->ctrl.den); valuator_mask_set_double(val, 1, tmpf); } } } else { - mult = pow(dx * dx + dy * dy, - ((double)(dev->ptrfeed->ctrl.num) / - (double)(dev->ptrfeed->ctrl.den) - 1.0) / - 2.0) / 2.0; + 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) |