diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c index 6da8424b0..53b2f6a42 100644 --- a/Xi/xiproperty.c +++ b/Xi/xiproperty.c @@ -50,7 +50,11 @@ static struct dev_properties char *name; } dev_properties[] = { {0, XI_PROP_ENABLED}, - {0, XATOM_FLOAT} + {0, XATOM_FLOAT}, + {0, ACCEL_PROP_PROFILE_NUMBER}, + {0, ACCEL_PROP_CONSTANT_DECELERATION}, + {0, ACCEL_PROP_ADAPTIVE_DECELERATION}, + {0, ACCEL_PROP_VELOCITY_SCALING} }; static long XIPropHandlerID = 1; diff --git a/dix/devices.c b/dix/devices.c index e5e3832ed..f2410fd5c 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -1319,6 +1319,16 @@ InitPointerAccelerationScheme(DeviceIntPtr dev, val->accelScheme = pointerAccelerationScheme[i]; val->accelScheme.accelData = data; + /* post-init scheme */ + switch(scheme){ + case PtrAccelPredictable: + InitializePredictableAccelerationProperties(dev); + break; + + default: + break; + } + return TRUE; } diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c index 95a7c711b..dcf91dfde 100644 --- a/dix/ptrveloc.c +++ b/dix/ptrveloc.c @@ -29,9 +29,13 @@ #include #include #include +#include +#include #include #include +#include + /***************************************************************************** * Predictable pointer acceleration * @@ -52,8 +56,8 @@ * which returns an acceleration * for a given velocity * - * The profile can be selected by the user (potentially at runtime). - * the classic profile is intended to cleanly perform old-style + * The profile can be selected by the user at runtime. + * The classic profile is intended to cleanly perform old-style * function selection (threshold =/!= 0) * ****************************************************************************/ @@ -137,6 +141,209 @@ AccelerationDefaultCleanup(DeviceIntPtr pDev) } } + +/************************* + * Input property support + ************************/ + +/** + * choose profile + */ +static int +AccelSetProfileProperty(DeviceIntPtr dev, Atom atom, + XIPropertyValuePtr val, BOOL checkOnly) +{ + DeviceVelocityPtr pVel; + int profile, *ptr = &profile; + int rc; + int nelem = 1; + + if (atom != XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER)) + return Success; + + pVel = GetDevicePredictableAccelData(dev); + if (!pVel) + return BadValue; + rc = XIPropToInt(val, &nelem, &ptr); + + if(checkOnly) + { + if (rc) + return rc; + + if (GetAccelerationProfile(pVel, profile) == NULL) + return BadValue; + } else + SetAccelerationProfile(pVel, profile); + + return Success; +} + +static void +AccelInitProfileProperty(DeviceIntPtr dev, DeviceVelocityPtr pVel) +{ + int profile = pVel->statistics.profile_number; + Atom prop_profile_number = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER); + + XIChangeDeviceProperty(dev, prop_profile_number, XA_INTEGER, 32, + PropModeReplace, 1, &profile, FALSE); + XISetDevicePropertyDeletable(dev, prop_profile_number, FALSE); + XIRegisterPropertyHandler(dev, AccelSetProfileProperty, NULL, NULL); +} + +/** + * constant deceleration + */ +static int +AccelSetDecelProperty(DeviceIntPtr dev, Atom atom, + XIPropertyValuePtr val, BOOL checkOnly) +{ + DeviceVelocityPtr pVel; + float v, *ptr = &v; + int rc; + int nelem = 1; + + if (atom != XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION)) + return Success; + + pVel = GetDevicePredictableAccelData(dev); + if (!pVel) + return BadValue; + rc = XIPropToFloat(val, &nelem, &ptr); + + if(checkOnly) + { + if (rc) + return rc; + return (v >= 1.0f) ? Success : BadValue; + } + + if(v >= 1.0f) + pVel->const_acceleration = 1/v; + + return Success; +} + +static void +AccelInitDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr pVel) +{ + float fval = 1.0/pVel->const_acceleration; + Atom prop_const_decel = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION); + XIChangeDeviceProperty(dev, prop_const_decel, + XIGetKnownProperty(XATOM_FLOAT), 32, + PropModeReplace, 1, &fval, FALSE); + XISetDevicePropertyDeletable(dev, prop_const_decel, FALSE); + XIRegisterPropertyHandler(dev, AccelSetDecelProperty, NULL, NULL); +} + + +/** + * adaptive deceleration + */ +static int +AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom, + XIPropertyValuePtr val, BOOL checkOnly) +{ + DeviceVelocityPtr pVel; + float v, *ptr = &v; + int rc; + int nelem = 1; + + if (atom != XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION)) + return Success; + + pVel = GetDevicePredictableAccelData(dev); + if (!pVel) + return BadValue; + rc = XIPropToFloat(val, &nelem, &ptr); + + if(checkOnly) + { + if (rc) + return rc; + return (v >= 1.0f) ? Success : BadValue; + } + + if(v >= 1.0f) + pVel->min_acceleration = 1/v; + + return Success; +} + +static void +AccelInitAdaptDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr pVel) +{ + float fval = 1.0/pVel->min_acceleration; + Atom prop_adapt_decel = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION); + + XIChangeDeviceProperty(dev, prop_adapt_decel, XIGetKnownProperty(XATOM_FLOAT), 32, + PropModeReplace, 1, &fval, FALSE); + XISetDevicePropertyDeletable(dev, prop_adapt_decel, FALSE); + XIRegisterPropertyHandler(dev, AccelSetAdaptDecelProperty, NULL, NULL); +} + + +/** + * velocity scaling + */ +static int +AccelSetScaleProperty(DeviceIntPtr dev, Atom atom, + XIPropertyValuePtr val, BOOL checkOnly) +{ + DeviceVelocityPtr pVel; + float v, *ptr = &v; + int rc; + int nelem = 1; + + if (atom != XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING)) + return Success; + + pVel = GetDevicePredictableAccelData(dev); + if (!pVel) + return BadValue; + rc = XIPropToFloat(val, &nelem, &ptr); + + if (checkOnly) + { + if (rc) + return rc; + + return (v > 0) ? Success : BadValue; + } + + if(v > 0) + pVel->corr_mul = v; + + return Success; +} + +static void +AccelInitScaleProperty(DeviceIntPtr dev, DeviceVelocityPtr pVel) +{ + float fval = pVel->corr_mul; + Atom prop_velo_scale = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING); + + XIChangeDeviceProperty(dev, prop_velo_scale, XIGetKnownProperty(XATOM_FLOAT), 32, + PropModeReplace, 1, &fval, FALSE); + XISetDevicePropertyDeletable(dev, prop_velo_scale, FALSE); + XIRegisterPropertyHandler(dev, AccelSetScaleProperty, NULL, NULL); +} + +BOOL +InitializePredictableAccelerationProperties(DeviceIntPtr device) +{ + DeviceVelocityPtr pVel = GetDevicePredictableAccelData(device); + + if(!pVel) + return FALSE; + + AccelInitProfileProperty(device, pVel); + AccelInitDecelProperty(device, pVel); + AccelInitAdaptDecelProperty(device, pVel); + AccelInitScaleProperty(device, pVel); + return TRUE; +} + /********************* * Filtering logic ********************/ diff --git a/include/ptrveloc.h b/include/ptrveloc.h index e491051e4..096dea847 100644 --- a/include/ptrveloc.h +++ b/include/ptrveloc.h @@ -43,6 +43,7 @@ #define AccelProfilePower 5 #define AccelProfileLinear 6 #define AccelProfileReserved 7 +#define AccelProfileLAST AccelProfileReserved /* fwd */ struct _DeviceVelocityRec; @@ -103,6 +104,9 @@ typedef struct _DeviceVelocityRec { extern _X_EXPORT void InitVelocityData(DeviceVelocityPtr s); +extern _X_EXPORT BOOL +InitializePredictableAccelerationProperties(DeviceIntPtr pDev); + extern _X_EXPORT void InitFilterChain(DeviceVelocityPtr s, float rdecay, float degression, int lutsize, int stages); diff --git a/include/xserver-properties.h b/include/xserver-properties.h index f8aeab65d..1327e5998 100644 --- a/include/xserver-properties.h +++ b/include/xserver-properties.h @@ -33,4 +33,14 @@ /* BOOL. 0 - device disabled, 1 - device enabled */ #define XI_PROP_ENABLED "Device Enabled" +/* Pointer acceleration properties */ +/* INTEGER of any format */ +#define ACCEL_PROP_PROFILE_NUMBER "Device Accel Profile" +/* FLOAT, format 32 */ +#define ACCEL_PROP_CONSTANT_DECELERATION "Device Accel Constant Deceleration" +/* FLOAT, format 32 */ +#define ACCEL_PROP_ADAPTIVE_DECELERATION "Device Accel Adaptive Deceleration" +/* FLOAT, format 32 */ +#define ACCEL_PROP_VELOCITY_SCALING "Device Accel Velocity Scaling" + #endif