From: Chase Douglas <[email protected]> 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 <[email protected]> --- 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
