On Tue, Oct 04, 2011 at 09:53:56PM +0200, Max Schwarz wrote: > This adds support for the new smooth-scrolling valuator system to > the wheel emulation code. > > Caveats: > - Enabling wheel emulation at runtime does not work if the device > does not provide the necessary axes already.
you could make the support compiled in, but not compiled _out_. so even if you HAVE_SMOOTH_SCROLLING, the old bits are ready to go when enabled. if no smooth scrolling axis is otherwise present on the device, just post button events as previously. > - Horizontal scrolling is always reported on the REL_HWHEEL axis, > ignoring a REL_DIAL axis present in hardware. REL_DIAL is set up as vertical axis by default anyway. > > Signed-off-by: Max Schwarz <m...@x-quadraht.de> > --- > Resend, my E-Mail client ate the patch... > > src/emuWheel.c | 19 ++++++++++++++++++- > src/evdev.c | 34 +++++++++++++++++++++++++++------- > src/evdev.h | 4 +++- > 3 files changed, 48 insertions(+), 9 deletions(-) > > diff --git a/src/emuWheel.c b/src/emuWheel.c > index ae894fa..0439a5b 100644 > --- a/src/emuWheel.c > +++ b/src/emuWheel.c > @@ -167,9 +167,13 @@ static int > EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value) > { > EvdevPtr pEvdev = (EvdevPtr)pInfo->private; > + int rc = 0; > +#ifndef HAVE_SMOOTH_SCROLLING > int button; > int inertia; > - int rc = 0; > +#else > + double v; > +#endif > > /* if this axis has not been configured, just eat the motion */ > if (!axis->up_button) > @@ -177,6 +181,7 @@ EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr > axis, int value) > > axis->traveled_distance += value; > > +#ifndef HAVE_SMOOTH_SCROLLING > if (axis->traveled_distance < 0) { > button = axis->up_button; > inertia = -pEvdev->emulateWheel.inertia; > @@ -192,6 +197,14 @@ EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr > axis, int value) > rc++; > } > return rc; > +#else > + /* Inject relative valuator delta */ > + v = -((double)axis->traveled_distance) / pEvdev->emulateWheel.inertia; > + EvdevInjectRelativeMotion(pEvdev, axis->code, v); > + axis->traveled_distance = 0; > + xf86IDrvMsg(pInfo, X_ERROR, "rel motion: %f\n", v); this should be removed in the final version > + return 1; > +#endif > } > > /* Handle button mapping here to avoid code duplication, > @@ -322,6 +335,10 @@ EvdevWheelEmuPreInit(InputInfoPtr pInfo) > pEvdev->emulateWheel.X.traveled_distance = 0; > pEvdev->emulateWheel.Y.traveled_distance = 0; > > + /* Used to inject smooth scrolling events */ > + pEvdev->emulateWheel.X.code = REL_HWHEEL; > + pEvdev->emulateWheel.Y.code = REL_WHEEL; > + > xf86IDrvMsg(pInfo, X_CONFIG, > "EmulateWheelButton: %d, " > "EmulateWheelInertia: %d, " > diff --git a/src/evdev.c b/src/evdev.c > index 2281206..9559758 100644 > --- a/src/evdev.c > +++ b/src/evdev.c > @@ -362,7 +362,7 @@ EvdevProcessValuators(InputInfoPtr pInfo) > { > int tmp; > EvdevPtr pEvdev = pInfo->private; > - int *delta = pEvdev->delta; > + double *delta = pEvdev->delta; > > /* convert to relative motion for touchpads */ > if (pEvdev->abs_queued && (pEvdev->flags & EVDEV_RELATIVE_MODE)) { > @@ -413,7 +413,7 @@ EvdevProcessValuators(InputInfoPtr pInfo) > { > int map = pEvdev->axis_map[i]; > if (pEvdev->delta[i] && map != -1) > - valuator_mask_set(pEvdev->vals, map, pEvdev->delta[i]); > + valuator_mask_set_double(pEvdev->vals, map, pEvdev- > >delta[i]); > } > } > /* > @@ -586,7 +586,6 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, > struct > input_event *ev) > { > int value; > EvdevPtr pEvdev = pInfo->private; > - int map; > > /* Get the signed value, earlier kernels had this as unsigned */ > value = ev->value; > @@ -618,15 +617,25 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, > struct input_event *ev) > if (EvdevWheelEmuFilterMotion(pInfo, ev)) > return; > > - pEvdev->rel_queued = 1; > - pEvdev->delta[ev->code] += value; > - map = pEvdev->axis_map[ev->code]; > - valuator_mask_set(pEvdev->vals, map, value); > + EvdevInjectRelativeMotion(pEvdev, ev->code, value); > break; > } > } > > /** > + * Inject a relative motion on a valuator axis. > + **/ > +void > +EvdevInjectRelativeMotion(EvdevPtr pEvdev, int axis_code, double delta) > +{ > + int map = pEvdev->axis_map[axis_code]; > + > + pEvdev->rel_queued = 1; > + pEvdev->delta[axis_code] += delta; > + valuator_mask_set_double(pEvdev->vals, map, delta); > +} > + > +/** > * Take the absolute motion input event and process it accordingly. > */ > static void > @@ -896,6 +905,7 @@ EvdevReadInput(InputInfoPtr pInfo) > } > > #define TestBit(bit, array) ((array[(bit) / LONG_BITS]) & (1L << ((bit) % > LONG_BITS))) > +#define evdev_SetBit(bit, array) ((array[(bit) / LONG_BITS]) |= (1L << > ((bit) Can we use the server's BitIsOn (inputstr.h), SetBit, etc here instead of relying on our own macros with name conflicts? Cheers, Peter > % LONG_BITS))) > > static void > EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl) > @@ -1099,6 +1109,16 @@ EvdevAddRelValuatorClass(DeviceIntPtr device) > if (!TestBit(EV_REL, pEvdev->bitmask)) > goto out; > > +#ifdef HAVE_SMOOTH_SCROLLING > + /* If wheel emulation is enabled, we need to report virtual axes */ > + if (pEvdev->emulateWheel.enabled) { > + if(pEvdev->emulateWheel.X.up_button) > + evdev_SetBit(REL_HWHEEL, pEvdev->rel_bitmask); > + if(pEvdev->emulateWheel.Y.up_button) > + evdev_SetBit(REL_WHEEL, pEvdev->rel_bitmask); > + } > +#endif > + > num_axes = EvdevCountBits(pEvdev->rel_bitmask, NLONGS(REL_MAX)); > if (num_axes < 1) > goto out; > diff --git a/src/evdev.h b/src/evdev.h > index b2e2f42..d15f823 100644 > --- a/src/evdev.h > +++ b/src/evdev.h > @@ -101,6 +101,7 @@ typedef struct { > int up_button; > int down_button; > int traveled_distance; > + int code; /* REL_WHEEL or REL_HWHEEL */ > } WheelAxis, *WheelAxisPtr; > > /* Event queue used to defer keyboard/button events until EV_SYN time. */ > @@ -135,7 +136,7 @@ typedef struct { > BOOL invert_x; > BOOL invert_y; > > - int delta[REL_CNT]; > + double delta[REL_CNT]; > unsigned int abs_queued, rel_queued, prox_queued; > > /* XKB stuff has to be per-device rather than per-driver */ > @@ -223,6 +224,7 @@ void EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, > int > num_v, int first_v, > void EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int num_v, int > first_v, > int v[MAX_VALUATORS]); > unsigned int EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code); > +void EvdevInjectRelativeMotion(EvdevPtr pEvdev, int axis_code, double delta); > > /* Middle Button emulation */ > int EvdevMBEmuTimer(InputInfoPtr); > -- > 1.7.4.1 > _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel