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. - Horizontal scrolling is always reported on the REL_HWHEEL axis, ignoring a REL_DIAL axis present in hardware. 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); + 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) % 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