예제 #1
0
/**
 * 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;
}
/**
 * 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;
}
예제 #3
0
파일: ptrveloc.c 프로젝트: aosm/X11server
/**
 * Modifies valuators in-place.
 * This version employs a velocity approximation algorithm to
 * enable fine-grained predictable acceleration profiles.
 */
void
acceleratePointerPredictable(
    DeviceIntPtr pDev,
    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) pDev->valuator->accelScheme.accelData;
    float fdx, fdy; /* no need to init */

    if (!num_valuators || !valuators || !velocitydata)
        return;

    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 nonvisible state? */
        if (ProcessVelocityData(velocitydata, dx , dy, evtime)) {
            /* set to center of pixel. makes sense as long as there are no
             * means of passing on sub-pixel values.
             */
            pDev->last.remainder[0] = pDev->last.remainder[1] = 0.5f;
            /* prevent softening (somewhat quirky solution,
            as it depends on the algorithm) */
            velocitydata->last_dx = dx;
            velocitydata->last_dy = dy;
        }

        if (pDev->ptrfeed && pDev->ptrfeed->ctrl.num) {
            /* invoke acceleration profile to determine acceleration */
            mult = ComputeAcceleration (velocitydata,
					pDev->ptrfeed->ctrl.threshold,
					(float)pDev->ptrfeed->ctrl.num /
					(float)pDev->ptrfeed->ctrl.den);

            if(mult != 1.0 || velocitydata->const_acceleration != 1.0) {
                ApplySofteningAndConstantDeceleration( velocitydata,
                                                       dx, dy,
                                                       &fdx, &fdy,
                                                       mult > 1.0);
                if (dx) {
                    pDev->last.remainder[0] = mult * fdx + pDev->last.remainder[0];
                    *px = (int)pDev->last.remainder[0];
                    pDev->last.remainder[0] = pDev->last.remainder[0] - (float)*px;
                }
                if (dy) {
                    pDev->last.remainder[1] = mult * fdy + pDev->last.remainder[1];
                    *py = (int)pDev->last.remainder[1];
                    pDev->last.remainder[1] = pDev->last.remainder[1] - (float)*py;
                }
            }
        }
    }
    /* remember last motion delta (for softening/slow movement treatment) */
    velocitydata->last_dx = dx;
    velocitydata->last_dy = dy;
}