[PATCH] dix: if the scroll valuator reaches INT_MAX, reset to 0
Chase Douglas
chase.douglas at canonical.com
Thu Jun 7 07:47:02 PDT 2012
On 06/07/2012 12:00 AM, Peter Hutterer wrote:
> Too much scrolling down may eventually trigger an overflow of the valuator.
> If this happens, reset the valuator to 0 and skip this event for button
> emulation. Clients will have to figure out a way to deal with this, but a
> scroll event from (close to) INT_MAX to 0 is a hint of that it needs to be
> ignored.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
> Not 100% sure if we really need this but it's one of the design issues with
> XI 2.1. Scrolling down is more common, so eventually we may overflow the
> axis. This patch simply resets it to 0 and pretends nothing happened.
>
> We don't have overflow protection on any other relative axis, but they're
> less likely to trigger this. x/y are screen coordinate clipped, we don't
> really have devices with rx/ry, and the wheels and dials are smooth
> scrolling now. So smooth scrolling axes are the only ones in danger of
> triggering this, even though it takes quite some effort to even get close to
> triggering this.
Has someone triggered this? Or did you just think about it :).
> Cheers,
> Peter
>
> dix/getevents.c | 41 +++++++++++++++++++++++++++++++++++------
> 1 file changed, 35 insertions(+), 6 deletions(-)
>
> diff --git a/dix/getevents.c b/dix/getevents.c
> index 32ef225..d343ecf 100644
> --- a/dix/getevents.c
> +++ b/dix/getevents.c
> @@ -35,6 +35,7 @@
> #include <X11/keysym.h>
> #include <X11/Xproto.h>
> #include <math.h>
> +#include <limits.h>
>
> #include "misc.h"
> #include "resource.h"
> @@ -756,6 +757,30 @@ clipAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
> }
> }
>
> +static void
> +add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, double value)
> +{
> + double v;
> +
> + if (!valuator_mask_fetch_double(mask, valuator, &v))
> + return;
> +
> + /* protect against scrolling overflow. INT_MAX for double, because
> + * we'll eventually write this as 32.32 fixed point */
> + if ((value > 0 && v > INT_MAX - value) || (value < 0 && v < INT_MIN - value)) {
> + v = 0;
> +
> + /* reset last.scroll to avoid a button storm */
> + valuator_mask_set_double(dev->last.scroll, valuator, 0);
> + }
> + else
> + v += value;
> + valuator_mask_set_double(mask, valuator, v);
> +
> +
Extra whitespace ^^. I would also add a line between the if..else..
block and the mask setting. It threw me off trying to read what belonged
in the blocks.
> +}
> +
> +
> /**
> * Move the device's pointer by the values given in @valuators.
> *
> @@ -774,13 +799,17 @@ moveRelative(DeviceIntPtr dev, ValuatorMask *mask)
>
> if (!valuator_mask_isset(mask, i))
> continue;
> - val += valuator_mask_get_double(mask, i);
> +
> + add_to_scroll_valuator(dev, mask, i, val);
> +
> /* x & y need to go over the limits to cross screens if the SD
> * isn't currently attached; otherwise, clip to screen bounds. */
> if (valuator_get_mode(dev, i) == Absolute &&
> - ((i != 0 && i != 1) || clip_xy))
> + ((i != 0 && i != 1) || clip_xy)) {
> + val = valuator_mask_get_double(mask, i);
> clipAxis(dev, i, &val);
> - valuator_mask_set_double(mask, i, val);
> + valuator_mask_set_double(mask, i, val);
> + }
> }
> }
>
> @@ -1560,7 +1590,7 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
> * necessary. This only needs to cater for the XIScrollFlagPreferred
> * axis (if more than one scrolling axis is present) */
> if (type == ButtonPress) {
> - double val, adj;
> + double adj;
> int axis;
> int h_scroll_axis = -1;
> int v_scroll_axis = -1;
> @@ -1596,8 +1626,7 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
>
> if (adj != 0.0 && axis != -1) {
> adj *= pDev->valuator->axes[axis].scroll.increment;
> - val = valuator_mask_get_double(&mask, axis) + adj;
> - valuator_mask_set_double(&mask, axis, val);
> + add_to_scroll_valuator(pDev, &mask, axis, adj);
> type = MotionNotify;
> buttons = 0;
> flags |= POINTER_EMULATED;
This looks reasonable to me, but I don't feel knowledgeable enough about
XI 2.1 to know that this solution will really work. I trust you know
what you are doing there.
Reviewed-by: Chase Douglas <chase.douglas at canonical.com>
More information about the xorg-devel
mailing list