/** * 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) { double dx = 0, dy = 0; DeviceVelocityPtr velocitydata = GetDevicePredictableAccelData(dev); Bool soften = TRUE; 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.*/ } if (valuator_mask_isset(val, 0)) { dx = valuator_mask_get_double(val, 0); } if (valuator_mask_isset(val, 1)) { dy = valuator_mask_get_double(val, 1); } if (dx != 0.0 || dy != 0.0) { /* reset non-visible state? */ if (ProcessVelocityData2D(velocitydata, dx , dy, evtime)) { soften = FALSE; } if (dev->ptrfeed && dev->ptrfeed->ctrl.num) { 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); if(mult != 1.0f || velocitydata->const_acceleration != 1.0f) { if (mult > 1.0f && soften) 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); } } } /* remember last motion delta (for softening/slow movement treatment) */ velocitydata->last_dx = dx; velocitydata->last_dy = dy; }
/** * 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; }
/** * Modifies valuators in-place. * This version employs a velocity approximation algorithm to * enable fine-grained predictable acceleration profiles. */ void acceleratePointerPredictable( DeviceIntPtr dev, int first_valuator, int num_valuators, int *valuators, int evtime) { float mult = 0.0; int dx = 0, dy = 0; int *px = NULL, *py = NULL; DeviceVelocityPtr velocitydata = (DeviceVelocityPtr) dev->valuator->accelScheme.accelData; float fdx, fdy, tmp; /* no need to init */ Bool soften = TRUE; if (!num_valuators || !valuators || !velocitydata) return; if (velocitydata->statistics.profile_number == AccelProfileNone && velocitydata->const_acceleration == 1.0f) { return; /*we're inactive anyway, so skip the whole thing.*/ } if (first_valuator == 0) { dx = valuators[0]; px = &valuators[0]; } if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) { dy = valuators[1 - first_valuator]; py = &valuators[1 - first_valuator]; } 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.0 || velocitydata->const_acceleration != 1.0) { ApplySofteningAndConstantDeceleration( velocitydata, dx, dy, &fdx, &fdy, (mult > 1.0) && 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. */ *px = lrintf(tmp); dev->last.remainder[0] = tmp - (float)*px; } if (dy) { tmp = mult * fdy + dev->last.remainder[1]; *py = lrintf(tmp); dev->last.remainder[1] = tmp - (float)*py; } 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; }