BOOL InitializePredictableAccelerationProperties(DeviceIntPtr dev) { DeviceVelocityPtr vel = GetDevicePredictableAccelData(dev); if(!vel) return FALSE; AccelInitProfileProperty(dev, vel); AccelInitDecelProperty(dev, vel); AccelInitAdaptDecelProperty(dev, vel); AccelInitScaleProperty(dev, vel); return TRUE; }
/** * Uninit scheme */ 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 * switched often anyway. */ OsBlockSignals(); dev->valuator->accelScheme.AccelSchemeProc = NULL; FreeVelocityData(vel); free(vel); DeletePredictableAccelerationProperties(dev, (PredictableAccelSchemePtr) dev->valuator->accelScheme.accelData); free(dev->valuator->accelScheme.accelData); dev->valuator->accelScheme.accelData = NULL; OsReleaseSignals(); } }
/** * Modifies valuators in-place. * This version employs a velocity approximation algorithm to * enable fine-grained predictable acceleration profiles. */ void acceleratePointerPredictable( DeviceIntPtr dev, ValuatorMask* val, CARD32 evtime) { float fdx, fdy, tmp, mult; /* no need to init */ int dx = 0, dy = 0, tmpi; DeviceVelocityPtr velocitydata = GetDevicePredictableAccelData(dev); Bool soften = TRUE; if (!velocitydata) return; if (velocitydata->statistics.profile_number == AccelProfileNone && velocitydata->const_acceleration == 1.0f) { return; /*we're inactive anyway, so skip the whole thing.*/ } if (valuator_mask_isset(val, 0)) { dx = valuator_mask_get(val, 0); } if (valuator_mask_isset(val, 1)) { dy = valuator_mask_get(val, 1); } if (dx || dy){ /* reset non-visible state? */ if (ProcessVelocityData2D(velocitydata, dx , dy, evtime)) { soften = FALSE; } if (dev->ptrfeed && dev->ptrfeed->ctrl.num) { /* 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) { ApplySofteningAndConstantDeceleration(velocitydata, dx, dy, &fdx, &fdy, (mult > 1.0f) && soften); if (dx) { 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) { 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); } } } /* remember last motion delta (for softening/slow movement treatment) */ velocitydata->last_dx = dx; velocitydata->last_dy = dy; }