[PATCH v2] Input: Add smooth-scrolling support
Peter Hutterer
peter.hutterer at who-t.net
Wed Sep 28 20:28:10 PDT 2011
On Wed, Sep 28, 2011 at 01:30:58AM +0100, Daniel Stone wrote:
> Hi,
>
> On 23 September 2011 02:22, Peter Hutterer <peter.hutterer at who-t.net> wrote:
> > + if (*current_ax != -1 && axnum != *current_ax)
> > + {
> > + ax = &dev->valuator->axes[*current_ax];
> > + if (ax->scroll.type == type &&
> > + (flags & SCROLL_FLAG_PREFERRED) == (ax->scroll.flags & SCROLL_FLAG_PREFERRED))
> > + return FALSE;
> > + }
>
> This will fail if you try to add two non-preferred axes; did you mean
> && instead of ==?
amended
>
> > + info->increment.integral = (int)axis->scroll.increment;
> > + info->increment.frac = (unsigned int)(axis->scroll.increment * (1UL << 32));
> > + info->sourceid = v->sourceid;
>
> This needs the same * (1UL << 16) * (1UL << 16) treatment, I believe.
amended
>
> > @@ -603,8 +604,10 @@ GetMaximumEventsNum(void) {
> > /* One raw event
> > * One device event
> > * One possible device changed event
> > + * Lots of possible separate button scroll events (horiz + vert)
> > + * Lots of possible separate raw button scroll events (horiz + vert)
> > */
> > - return 3;
> > + return 51;
> > }
>
> Hmm, I've seen up to 100 fairly easily.
fwiw, this is still from your original patch. I've amended to 100 now.
> > +static int
> > +emulate_scroll_button_events(InternalEvent *events,
> > + DeviceIntPtr dev,
> > + int axis,
> > + const ValuatorMask *mask,
> > + ValuatorMask *last,
> > + CARD32 ms,
> > + int max_events)
> > +{
> > + AxisInfoPtr ax;
> > + double delta;
> > + double incr;
> > + int num_events = 0;
> > + double total;
> > + int b;
> > +
> > + if (dev->valuator->axes[axis].scroll.type == SCROLL_TYPE_NONE)
> > + return 0;
> > +
> > + if (!valuator_mask_isset(mask, axis))
> > + return 0;
> > +
> > + ax = &dev->valuator->axes[axis];
> > + incr = ax->scroll.increment;
> > +
> > + if (!valuator_mask_isset(last, axis))
> > + {
> > + valuator_mask_set_double(last, axis, valuator_mask_get_double(mask, axis));
> > + return 0;
> > + }
> > +
> > + delta = valuator_mask_get_double(mask, axis) - valuator_mask_get_double(last, axis);
>
> I think this really needs to be:
> delta = valuator_mask_get_double(mask, axis);
> if (valuator_mask_isset(last, axis))
> delta -= valuator_mask_get_double(last, axis);
>
> On the grounds that a single event with a scroll axis with an incr of
> 1.0 and a value of 10.0 should generate 10 scroll button events. But
> with this, we won't generate anything until the second event comes in,
> no?
By the time we get here, we're in absolute coordinates. So what we need to
do is
if (!valuator_mask_isset(last, axis))
valuator_mask_set(last, axis, 0);
This way, the very first event on this axis is handled as you described and
for any future events we're fine.
> > @@ -1193,7 +1288,12 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
> > int buttons, int flags, const ValuatorMask *mask_in)
> > {
> > CARD32 ms = GetTimeInMillis();
> > - int num_events = 0;
> > + int num_events = 0, nev_tmp;
> > + int h_scroll_axis = pDev->valuator->h_scroll_axis;
> > + int v_scroll_axis = pDev->valuator->v_scroll_axis;
> > + ValuatorMask mask;
> > + ValuatorMask scroll;
> > + int i;
> > [...]
> > +
> > + /* Now turn the smooth-scrolling axes back into emulated button presses
> > + * for legacy clients, based on the integer delta between before and now */
> > + for (i = 0; i < valuator_mask_size(&mask); i++) {
> > + if (!valuator_mask_isset(&mask, i))
> > + continue;
> > +
> > + valuator_mask_set_double(&scroll, i, pDev->last.valuators[i]);
>
> Don't you need a valuator_mask_zero(&scroll) before using it?
done.
>
> > + /* fill_pointer_events() generates four events: one normal and one raw
> > + * event each for the emulated button press and release both. */
> > + if (num_events + 4 >= GetMaximumEventsNum())
> > + break;
> > +
> > + nev_tmp = emulate_scroll_button_events(events, pDev, i, &scroll,
> > + pDev->last.scroll, ms,
> > + GetMaximumEventsNum() - num_events);
>
> So with this comment, you should probably either
> s/fill_pointer_events/emulate_scroll_button_events/, or just bin the
> comment and the conditional as well, and have
> emulate_scroll_button_events catch max_events <= 0 and just do
> nothing.
removed the condition because I think strictly speaking we may end up with
some weird delta. So better to loop one time to many (but not generate any
events).
> (I think the comment in emulate_scroll_button_events about
> fill_pointer_events wants revisiting too, strictly speaking.)
>
> Other than that:
> Reviewed-by: Daniel Stone <daniel at fooishbar.org>
thanks. follow-up patch in a minute
Cheers,
Peter
More information about the xorg-devel
mailing list