diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2012-06-10 13:21:33 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2012-06-10 13:21:33 +0000 |
commit | 171e929a08098b6c844887adc43879c7579dc15f (patch) | |
tree | 6b4d2e3bc20dbd4dc9a1f031416e66614c53dd21 /xserver/dix/ptrveloc.c | |
parent | 68781b09de2c95b87ea898c4ecf3018dfb4460d2 (diff) |
Update to xserver 1.12.2. tested by naddy@, krw@, mpi@.
Diffstat (limited to 'xserver/dix/ptrveloc.c')
-rw-r--r-- | xserver/dix/ptrveloc.c | 870 |
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); } } } |