[RFC XI 2.1 - xf86-input-evdev 1/3] Add support for masked valuators
Peter Hutterer
peter.hutterer at who-t.net
Tue Nov 16 22:04:55 PST 2010
On Fri, Nov 12, 2010 at 05:35:11PM -0500, Chase Douglas wrote:
> From: Chase Douglas <chase.douglas at ubuntu.com>
>
> With the X server now supporting masked valuators for XI2, enable
> support in X evdev.
>
> Note that this leaves around a lot of cruft that should be removed, but
> the code allows for backwards compatibility with X servers < 1.10.
>
> Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
> ---
ack in spirit, nack in this form. this leaves too much code duplication
for my liking, so I'd say we just bite the bullet and remove pre-ABI 12
support.
evdev has a whole bunch of fixes on master right now which can probably be
tagged as 2.6.0. then we can go on with the 2.7 work that drops servers
pre-1.10 and just backport patches as needed.
so I'm not merging this patch as-is but I can see the benefits of exposing
the valuator mask api. let me get master into shape first for branching,
then we can re-do this one without the ifdefs.
Cheers,
Peter
> src/emuWheel.c | 6 ++
> src/evdev.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> src/evdev.h | 12 +++-
> 3 files changed, 215 insertions(+), 6 deletions(-)
>
> diff --git a/src/emuWheel.c b/src/emuWheel.c
> index 9a53211..7dc4ba8 100644
> --- a/src/emuWheel.c
> +++ b/src/emuWheel.c
> @@ -120,8 +120,14 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
>
> /* We don't want to intercept real mouse wheel events */
> if(pEv->type == EV_ABS) {
> + int axis = pEvdev->axis_map[pEv->code];
> +#ifdef HAVE_MASKED_VALUATORS
> + oldValue = valuator_mask_get(pEvdev->mask, axis);
> + valuator_mask_set(pEvdev->mask, axis, value);
> +#else
> oldValue = pEvdev->vals[pEvdev->axis_map[pEv->code]];
> pEvdev->vals[pEvdev->axis_map[pEv->code]] = value;
> +#endif
> value -= oldValue; /* make value into a differential measurement */
> }
>
> diff --git a/src/evdev.c b/src/evdev.c
> index 040cfdc..4984019 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -368,6 +368,108 @@ EvdevQueueButtonClicks(InputInfoPtr pInfo, int button, int count)
> }
> }
>
> +#ifdef HAVE_MASKED_VALUATORS
> +/**
> + * Take the valuators and process them accordingly
> + */
> +static void
> +EvdevProcessValuators(InputInfoPtr pInfo)
> +{
> + int tmp;
> + EvdevPtr pEvdev = pInfo->private;
> +
> + /* convert to relative motion for touchpads */
> + if (pEvdev->abs_queued && (pEvdev->flags & EVDEV_RELATIVE_MODE)) {
> + if (pEvdev->proximity) {
> + if (valuator_mask_isset(pEvdev->mask, 0) &&
> + valuator_mask_isset(pEvdev->oldMask, 0))
> + pEvdev->delta[REL_X] = valuator_mask_get(pEvdev->mask, 0) -
> + valuator_mask_get(pEvdev->oldMask, 0);
> + if (valuator_mask_isset(pEvdev->mask, 1) &&
> + valuator_mask_isset(pEvdev->oldMask, 1))
> + pEvdev->delta[REL_Y] = valuator_mask_get(pEvdev->mask, 1) -
> + valuator_mask_get(pEvdev->oldMask, 1);
> + if (valuator_mask_isset(pEvdev->mask, 0))
> + valuator_mask_set(pEvdev->oldMask, 0,
> + valuator_mask_get(pEvdev->mask, 0));
> + if (valuator_mask_isset(pEvdev->mask, 1))
> + valuator_mask_set(pEvdev->oldMask, 1,
> + valuator_mask_get(pEvdev->mask, 1));
> + } else {
> + valuator_mask_zero(pEvdev->oldMask);
> + }
> + valuator_mask_zero(pEvdev->mask);
> + pEvdev->abs_queued = 0;
> + pEvdev->rel_queued = 1;
> + }
> +
> + if (pEvdev->rel_queued) {
> + int i;
> +
> + if (pEvdev->swap_axes) {
> + tmp = pEvdev->delta[REL_X];
> + pEvdev->delta[REL_X] = pEvdev->delta[REL_Y];
> + pEvdev->delta[REL_Y] = tmp;
> + }
> + if (pEvdev->invert_x)
> + pEvdev->delta[REL_X] *= -1;
> + if (pEvdev->invert_y)
> + pEvdev->delta[REL_Y] *= -1;
> +
> + for (i = 0; i < REL_CNT; i++)
> + {
> + int map = pEvdev->axis_map[i];
> + if (pEvdev->delta[i] && map != -1)
> + valuator_mask_set(pEvdev->mask, map, pEvdev->delta[i]);
> + }
> + }
> + /*
> + * Some devices only generate valid abs coords when BTN_TOOL_PEN is
> + * pressed. On wacom tablets, this means that the pen is in
> + * proximity of the tablet. After the pen is removed, BTN_TOOL_PEN is
> + * released, and a (0, 0) absolute event is generated. Checking
> + * pEvdev->proximity here lets us ignore that event. pEvdev is
> + * initialized to 1 so devices that doesn't use this scheme still
> + * just works.
> + */
> + else if (pEvdev->abs_queued && pEvdev->proximity) {
> + int unswapped_x = valuator_mask_get(pEvdev->mask, 0);
> + int unswapped_y = valuator_mask_get(pEvdev->mask, 1);
> + int i;
> +
> + for (i = 0; i <= 1; i++) {
> + int val;
> +
> + if (!valuator_mask_isset(pEvdev->mask, i))
> + continue;
> +
> + val = valuator_mask_get(pEvdev->mask, i);
> +
> + if (pEvdev->swap_axes)
> + val = xf86ScaleAxis((i == 0 ? unswapped_y : unswapped_x),
> + pEvdev->absinfo[i].maximum,
> + pEvdev->absinfo[i].minimum,
> + pEvdev->absinfo[1 - i].maximum,
> + pEvdev->absinfo[1 - i].minimum);
> +
> + if (pEvdev->flags & EVDEV_CALIBRATED)
> + val = xf86ScaleAxis(val, pEvdev->absinfo[i].maximum,
> + pEvdev->absinfo[i].minimum,
> + (i == 0 ? pEvdev->calibration.max_x :
> + pEvdev->calibration.max_y),
> + (i == 0 ? pEvdev->calibration.min_x :
> + pEvdev->calibration.min_y));
> +
> + if ((i == 0 && pEvdev->invert_x) || (i == 1 && pEvdev->invert_y))
> + val = (pEvdev->absinfo[i].maximum - val +
> + pEvdev->absinfo[i].minimum);
> +
> + valuator_mask_set(pEvdev->mask, i, val);
> + }
> + }
> +}
> +
> +#else
> #define ABS_X_VALUE 0x1
> #define ABS_Y_VALUE 0x2
> #define ABS_VALUE 0x4
> @@ -480,6 +582,7 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
> *first_v = 0;
> }
> }
> +#endif
>
> static void
> EvdevProcessProximityEvent(InputInfoPtr pInfo, struct input_event *ev)
> @@ -516,7 +619,11 @@ EvdevProcessProximityState(InputInfoPtr pInfo)
> if (!pEvdev->prox_queued)
> {
> if (pEvdev->abs_queued && !pEvdev->proximity)
> +#ifdef HAVE_MASKED_VALUATORS
> + valuator_mask_copy(pEvdev->proxMask, pEvdev->mask);
> +#else
> pEvdev->abs_prox = pEvdev->abs_queued;
> +#endif
> return 0;
> }
>
> @@ -534,11 +641,20 @@ EvdevProcessProximityState(InputInfoPtr pInfo)
> {
> /* We're about to go into/out of proximity but have no abs events
> * within the EV_SYN. Use the last coordinates we have. */
> +#ifdef HAVE_MASKED_VALUATORS
> + if (!pEvdev->abs_queued &&
> + valuator_mask_num_valuators(pEvdev->proxMask) > 0)
> + {
> + valuator_mask_copy(pEvdev->mask, pEvdev->proxMask);
> + valuator_mask_zero(pEvdev->proxMask);
> + }
> +#else
> if (!pEvdev->abs_queued && pEvdev->abs_prox)
> {
> pEvdev->abs_queued = pEvdev->abs_prox;
> pEvdev->abs_prox = 0;
> }
> +#endif
> }
>
> pEvdev->proximity = prox_state;
> @@ -584,6 +700,9 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
> {
> int value;
> EvdevPtr pEvdev = pInfo->private;
> +#ifdef HAVE_MASKED_VALUATORS
> + int map;
> +#endif
>
> /* Get the signed value, earlier kernels had this as unsigned */
> value = ev->value;
> @@ -616,6 +735,10 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
>
> pEvdev->rel_queued = 1;
> pEvdev->delta[ev->code] += value;
> +#ifdef HAVE_MASKED_VALUATORS
> + map = pEvdev->axis_map[ev->code];
> + valuator_mask_set(pEvdev->mask, map, value);
> +#endif
> break;
> }
> }
> @@ -628,6 +751,7 @@ EvdevProcessAbsoluteMotionEvent(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;
> @@ -642,13 +766,19 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
> if (EvdevWheelEmuFilterMotion(pInfo, ev))
> return;
>
> - pEvdev->vals[pEvdev->axis_map[ev->code]] = value;
> + map = pEvdev->axis_map[ev->code];
> +#ifdef HAVE_MASKED_VALUATORS
> + valuator_mask_set(pEvdev->mask, map, value);
> + pEvdev->abs_queued = 1;
> +#else
> + pEvdev->vals[map] = value;
> if (ev->code == ABS_X)
> pEvdev->abs_queued |= ABS_X_VALUE;
> else if (ev->code == ABS_Y)
> pEvdev->abs_queued |= ABS_Y_VALUE;
> else
> pEvdev->abs_queued |= ABS_VALUE;
> +#endif
> }
>
> /**
> @@ -702,7 +832,11 @@ EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
> EvdevPtr pEvdev = pInfo->private;
>
> if (pEvdev->rel_queued) {
> +#ifdef HAVE_MASKED_VALUATORS
> + xf86PostMotionEventM(pInfo->dev, FALSE, pEvdev->mask);
> +#else
> xf86PostMotionEventP(pInfo->dev, FALSE, first_v, num_v, v + first_v);
> +#endif
> }
> }
>
> @@ -725,7 +859,11 @@ EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
> * just work.
> */
> if (pEvdev->abs_queued && pEvdev->proximity) {
> +#ifdef HAVE_MASKED_VALUATORS
> + xf86PostMotionEventM(pInfo->dev, TRUE, pEvdev->mask);
> +#else
> xf86PostMotionEventP(pInfo->dev, TRUE, first_v, num_v, v + first_v);
> +#endif
> }
> }
>
> @@ -796,7 +934,11 @@ EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
>
> EvdevProcessProximityState(pInfo);
>
> +#ifdef HAVE_MASKED_VALUATORS
> + EvdevProcessValuators(pInfo);
> +#else
> EvdevProcessValuators(pInfo, v, &num_v, &first_v);
> +#endif
>
> EvdevPostProximityEvents(pInfo, TRUE, num_v, first_v, v);
> EvdevPostRelativeMotionEvents(pInfo, num_v, first_v, v);
> @@ -806,6 +948,10 @@ EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
>
> memset(pEvdev->delta, 0, sizeof(pEvdev->delta));
> memset(pEvdev->queue, 0, sizeof(pEvdev->queue));
> +#ifdef HAVE_MASKED_VALUATORS
> + if (pEvdev->mask)
> + valuator_mask_zero(pEvdev->mask);
> +#endif
> pEvdev->num_queue = 0;
> pEvdev->abs_queued = 0;
> pEvdev->rel_queued = 0;
> @@ -1289,8 +1435,19 @@ EvdevAddAbsClass(DeviceIntPtr device)
> }
>
> pEvdev->num_vals = num_axes;
> +#ifdef HAVE_MASKED_VALUATORS
> + if (num_axes > 0) {
> + pEvdev->mask = valuator_mask_new(num_axes);
> + if (!pEvdev->mask)
> + return !Success;
> + pEvdev->oldMask = valuator_mask_new(num_axes);
> + if (!pEvdev->oldMask)
> + goto out;
> + }
> +#else
> memset(pEvdev->vals, 0, num_axes * sizeof(int));
> memset(pEvdev->old_vals, -1, num_axes * sizeof(int));
> +#endif
> atoms = malloc(pEvdev->num_vals * sizeof(Atom));
>
> for (axis = ABS_X; i < MAX_VALUATORS && axis <= ABS_MAX; axis++) {
> @@ -1311,7 +1468,7 @@ EvdevAddAbsClass(DeviceIntPtr device)
> GetMotionHistory,
> #endif
> GetMotionHistorySize(), Absolute))
> - return !Success;
> + goto out;
>
> for (axis = ABS_X; axis <= ABS_MAX; axis++) {
> int axnum = pEvdev->axis_map[axis];
> @@ -1338,7 +1495,9 @@ EvdevAddAbsClass(DeviceIntPtr device)
> #endif
> );
> xf86InitValuatorDefaults(device, axnum);
> +#ifndef HAVE_MASKED_VALUATORS
> pEvdev->old_vals[axnum] = -1;
> +#endif
> }
>
> free(atoms);
> @@ -1348,12 +1507,15 @@ EvdevAddAbsClass(DeviceIntPtr device)
> if (TestBit(proximity_bits[i], pEvdev->key_bitmask))
> {
> InitProximityClassDeviceStruct(device);
> + pEvdev->proxMask = valuator_mask_new(num_axes);
> + if (!pEvdev->proxMask)
> + goto out;
> break;
> }
> }
>
> if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
> - return !Success;
> + goto out;
>
> if (pEvdev->flags & EVDEV_TOUCHPAD)
> pEvdev->flags |= EVDEV_RELATIVE_MODE;
> @@ -1374,6 +1536,17 @@ EvdevAddAbsClass(DeviceIntPtr device)
> }
>
> return Success;
> +
> +out:
> +#ifdef HAVE_MASKED_VALUATORS
> + free(pEvdev->mask);
> + pEvdev->mask = NULL;
> + free(pEvdev->oldMask);
> + pEvdev->oldMask = NULL;
> + free(pEvdev->proxMask);
> + pEvdev->proxMask = NULL;
> +#endif
> + return !Success;
> }
>
> static int
> @@ -1412,7 +1585,15 @@ EvdevAddRelClass(DeviceIntPtr device)
> }
>
> pEvdev->num_vals = num_axes;
> +#ifdef HAVE_MASKED_VALUATORS
> + if (num_axes > 0) {
> + pEvdev->mask = valuator_mask_new(num_axes);
> + if (!pEvdev->mask)
> + return !Success;
> + }
> +#else
> memset(pEvdev->vals, 0, num_axes * sizeof(int));
> +#endif
> atoms = malloc(pEvdev->num_vals * sizeof(Atom));
>
> for (axis = REL_X; i < MAX_VALUATORS && axis <= REL_MAX; axis++)
> @@ -1437,10 +1618,10 @@ EvdevAddRelClass(DeviceIntPtr device)
> GetMotionHistory,
> #endif
> GetMotionHistorySize(), Relative))
> - return !Success;
> + goto out;
>
> if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
> - return !Success;
> + goto out;
>
> for (axis = REL_X; axis <= REL_MAX; axis++)
> {
> @@ -1463,6 +1644,13 @@ EvdevAddRelClass(DeviceIntPtr device)
> free(atoms);
>
> return Success;
> +
> +out:
> +#ifdef HAVE_MASKED_VALUATORS
> + free(pEvdev->mask);
> + pEvdev->mask = NULL;
> +#endif
> + return !Success;
> }
>
> static int
> @@ -1732,6 +1920,9 @@ EvdevProc(DeviceIntPtr device, int what)
> close(pInfo->fd);
> pInfo->fd = -1;
> }
> + free(pEvdev->mask);
> + free(pEvdev->oldMask);
> + free(pEvdev->proxMask);
> EvdevRemoveDevice(pInfo);
> pEvdev->min_maj = 0;
> break;
> @@ -2038,7 +2229,9 @@ EvdevProbe(InputInfoPtr pInfo)
> if (has_lmr || TestBit(BTN_TOOL_FINGER, pEvdev->key_bitmask)) {
> xf86Msg(X_PROBED, "%s: Found absolute touchpad.\n", pInfo->name);
> pEvdev->flags |= EVDEV_TOUCHPAD;
> +#ifndef HAVE_MASKED_VALUATORS
> memset(pEvdev->old_vals, -1, sizeof(int) * pEvdev->num_vals);
> +#endif
> } else {
> xf86Msg(X_PROBED, "%s: Found absolute touchscreen\n", pInfo->name);
> pEvdev->flags |= EVDEV_TOUCHSCREEN;
> diff --git a/src/evdev.h b/src/evdev.h
> index 7c17ca4..bd5cb16 100644
> --- a/src/evdev.h
> +++ b/src/evdev.h
> @@ -76,6 +76,10 @@
> #define HAVE_PROPERTIES 1
> #endif
>
> +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
> +#define HAVE_MASKED_VALUATORS 1
> +#endif
> +
> #ifndef MAX_VALUATORS
> #define MAX_VALUATORS 36
> #endif
> @@ -121,8 +125,15 @@ typedef struct {
>
> int num_vals; /* number of valuators */
> int axis_map[max(ABS_CNT, REL_CNT)]; /* Map evdev <axis> to index */
> +#ifdef HAVE_MASKED_VALUATORS
> + ValuatorMask *mask;
> + ValuatorMask *oldMask;
> + ValuatorMask *proxMask;
> +#else
> int vals[MAX_VALUATORS];
> int old_vals[MAX_VALUATORS]; /* Translate absolute inputs to relative */
> + unsigned int abs_prox; /* valuators posted while out of prox? */
> +#endif
>
> int flags;
> int proximity;
> @@ -133,7 +144,6 @@ typedef struct {
>
> int delta[REL_CNT];
> unsigned int abs_queued, rel_queued, prox_queued;
> - unsigned int abs_prox; /* valuators posted while out of prox? */
>
> /* XKB stuff has to be per-device rather than per-driver */
> #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 5
> --
> 1.7.1
>
More information about the xorg-devel
mailing list