[PATCH evdev 3/3] Allow relative scroll valuators on absolute devices
Peter Hutterer
peter.hutterer at who-t.net
Wed Mar 28 17:09:52 PDT 2012
Special-case REL_WHEEL, REL_HWHEEL and REL_DIAL to add scroll valuators
for those axes on top of the absolute axes.
REL_* and ABS_* overlap, so we need to offset the REL_* axes to avoid
overwriting a potential ABS_* mapping. REL_* axes mappings are stored after
the last absolute axis detected, for purely relative devices that offset is
simply 0.
This isn't needed before smooth-scrolling support as REL_WHEEL and friends
are special-cased in EvdevProcessRelativeMotionEvent, north of the first
hunk in this patch.
https://bugzilla.redhat.com/show_bug.cgi?id=805902
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
src/evdev.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
src/evdev.h | 3 +-
2 files changed, 99 insertions(+), 6 deletions(-)
diff --git a/src/evdev.c b/src/evdev.c
index 7848c9d..91e314d 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -864,7 +864,9 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
#endif
default:
/* Ignore EV_REL events if we never set up for them. */
- if (!(pEvdev->flags & EVDEV_RELATIVE_EVENTS))
+ if (!(pEvdev->flags & EVDEV_RELATIVE_EVENTS) &&
+ ev->code != REL_WHEEL && ev->code != REL_DIAL &&
+ ev->code != REL_HWHEEL)
return;
/* Handle mouse wheel emulation */
@@ -873,7 +875,7 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
pEvdev->rel_queued = 1;
pEvdev->delta[ev->code] += value;
- map = pEvdev->axis_map[ev->code];
+ map = pEvdev->axis_map[ev->code + pEvdev->rel_offset];
valuator_mask_set(pEvdev->vals, map, value);
break;
}
@@ -1396,7 +1398,7 @@ is_blacklisted_axis(int axis)
static int
-EvdevAddAbsValuatorClass(DeviceIntPtr device)
+EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
{
InputInfoPtr pInfo;
EvdevPtr pEvdev;
@@ -1444,6 +1446,20 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
}
}
#endif
+
+#ifdef HAVE_SMOOTH_SCROLLING
+ if (want_scroll_axes && EvdevBitIsSet(pEvdev->bitmask, EV_REL))
+ {
+ pEvdev->rel_offset = num_axes;
+ if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL))
+ num_axes++;
+ if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL))
+ num_axes++;
+ if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL))
+ num_axes++;
+ }
+#endif
+
if (num_axes + num_mt_axes > MAX_VALUATORS) {
xf86IDrvMsg(pInfo, X_WARNING, "found %d axes, limiting to %d.\n", num_axes, MAX_VALUATORS);
num_axes = MAX_VALUATORS;
@@ -1532,6 +1548,33 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
EvdevInitAxesLabels(pEvdev, Absolute, pEvdev->num_vals + num_mt_axes, atoms);
+#ifdef HAVE_SMOOTH_SCROLLING
+ if (want_scroll_axes)
+ {
+ int mapping = pEvdev->rel_offset;
+ int axis;
+
+ if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL))
+ {
+ axis = pEvdev->rel_offset + REL_HWHEEL;
+ pEvdev->axis_map[axis] = mapping++;
+ EvdevInitOneAxisLabel(pEvdev, axis, rel_labels, REL_HWHEEL, atoms);
+ }
+ if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL))
+ {
+ axis = pEvdev->rel_offset + REL_DIAL;
+ pEvdev->axis_map[axis] = mapping++;
+ EvdevInitOneAxisLabel(pEvdev, axis, rel_labels, REL_DIAL, atoms);
+ }
+ if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL))
+ {
+ axis = pEvdev->rel_offset + REL_WHEEL;
+ pEvdev->axis_map[axis] = mapping++;
+ EvdevInitOneAxisLabel(pEvdev, axis, rel_labels, REL_WHEEL, atoms);
+ }
+ }
+#endif
+
if (!InitValuatorClassDeviceStruct(device, num_axes + num_mt_axes, atoms,
GetMotionHistorySize(), Absolute)) {
xf86IDrvMsg(pInfo, X_ERROR, "failed to initialize valuator class device.\n");
@@ -1623,6 +1666,51 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
}
#endif
+#ifdef HAVE_SMOOTH_SCROLLING
+ if (want_scroll_axes)
+ {
+ int axidx;
+ if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL))
+ {
+ axidx = pEvdev->rel_offset + REL_WHEEL;
+ xf86InitValuatorAxisStruct(device,
+ pEvdev->axis_map[axidx],
+ atoms[pEvdev->axis_map[axidx]],
+ NO_AXIS_LIMITS, NO_AXIS_LIMITS,
+ 0, 0, 0, Relative);
+ SetScrollValuator(device, pEvdev->axis_map[axidx],
+ SCROLL_TYPE_VERTICAL, -1.0,
+ SCROLL_FLAG_PREFERRED);
+ }
+
+ if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL))
+ {
+ axidx = pEvdev->rel_offset + REL_HWHEEL;
+ xf86InitValuatorAxisStruct(device,
+ pEvdev->axis_map[axidx],
+ atoms[pEvdev->axis_map[axidx]],
+ NO_AXIS_LIMITS, NO_AXIS_LIMITS,
+ 0, 0, 0, Relative);
+ SetScrollValuator(device, pEvdev->axis_map[axidx],
+ SCROLL_TYPE_HORIZONTAL, 1.0,
+ SCROLL_FLAG_NONE);
+ }
+
+ if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL))
+ {
+ axidx = pEvdev->rel_offset + REL_DIAL;
+ xf86InitValuatorAxisStruct(device,
+ pEvdev->axis_map[axidx],
+ atoms[pEvdev->axis_map[axidx]],
+ NO_AXIS_LIMITS, NO_AXIS_LIMITS,
+ 0, 0, 0, Relative);
+ SetScrollValuator(device, pEvdev->axis_map[axidx],
+ SCROLL_TYPE_HORIZONTAL, 1.0,
+ SCROLL_FLAG_NONE);
+ }
+ }
+#endif
+
free(atoms);
for (i = 0; i < ArrayLength(proximity_bits); i++)
@@ -1852,12 +1940,16 @@ static void
EvdevInitAnyValuators(DeviceIntPtr device, EvdevPtr pEvdev)
{
InputInfoPtr pInfo = device->public.devicePrivate;
+ int rel_success = FALSE;
if (pEvdev->flags & EVDEV_RELATIVE_EVENTS &&
EvdevAddRelValuatorClass(device) == Success)
+ {
+ rel_success = TRUE;
xf86IDrvMsg(pInfo, X_INFO, "initialized for relative axes.\n");
+ }
if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS &&
- EvdevAddAbsValuatorClass(device) == Success)
+ EvdevAddAbsValuatorClass(device, !rel_success) == Success)
xf86IDrvMsg(pInfo, X_INFO, "initialized for absolute axes.\n");
}
@@ -1866,7 +1958,7 @@ EvdevInitAbsValuators(DeviceIntPtr device, EvdevPtr pEvdev)
{
InputInfoPtr pInfo = device->public.devicePrivate;
- if (EvdevAddAbsValuatorClass(device) == Success) {
+ if (EvdevAddAbsValuatorClass(device, TRUE) == Success) {
xf86IDrvMsg(pInfo, X_INFO,"initialized for absolute axes.\n");
} else {
xf86IDrvMsg(pInfo, X_ERROR,"failed to initialize for absolute axes.\n");
diff --git a/src/evdev.h b/src/evdev.h
index 309b215..cca5cbe 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -153,7 +153,8 @@ typedef struct {
int grabDevice; /* grab the event device? */
int num_vals; /* number of valuators */
- int axis_map[max(ABS_CNT, REL_CNT)]; /* Map evdev <axis> to index */
+ int axis_map[ABS_CNT + REL_CNT]; /* Map evdev <axis> to index */
+ int rel_offset; /* offset for relative axes in absolute device */
ValuatorMask *vals; /* new values coming in */
ValuatorMask *old_vals; /* old values for calculating relative motion */
ValuatorMask *prox; /* last values set while not in proximity */
--
1.7.7.6
More information about the xorg-devel
mailing list