Compare commits

..

7 Commits

Author SHA1 Message Date
Peter Hutterer
cb3b023783 evdev 2.9.1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-11-26 09:23:39 +10:00
Peter Hutterer
124eff9ba2 Remove three unused #defines
Obsolete since 768c25a99b

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-11-07 13:41:06 +10:00
Éric Brunet
605047613c Don't pass superfluous arguments to EvdevPost*Events
The functions EvdevPostProximityEvents, EvdevPostRelativeMotionEvents,
EvdevPostAbsoluteMotionEvents and EvdevPostQueuedEvents are only called
by EvdevProcessSyncEvent. These functions take as arguments an array of
valuators which is set by EvdevProcessSyncEvent to contain ... nothing.
This patch changes the prototype of the four functions, their definitions
and the way they are called  to remove the useless array of valuators.

Signed-off-by: Éric Brunet <Eric.Brunet@lps.ens.fr>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-09-29 11:18:16 +10:00
Peter Hutterer
3ee98d0b7f Drop some unused #defines
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-08-29 13:14:56 +10:00
Peter Hutterer
977588d24a If only IgnoreRelativeAxes is set, init like a normal relative device
In the current code, if only IgnoreRelativeAxes is set, the code would go on
and force absolute axes to initialize even if the relative axes were
successfully initialized.

Evdev gives precedence to relative axes anyway, initializing absolute axes if
the relative axes failed. Thus, if we explicitely want relative axes but leave
the abs axes as-is, proceed as normal.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-08-18 10:02:00 +10:00
Peter Hutterer
291b60172d Fix axis initialization for devices with abs x/y and rel scrollwheels
The Xen Virtual Pointer device has ABS_X, ABS_Y and REL_WHEEL. If smooth
scrolling is detected, the current code would first initialize relative axes
for scrolling and immediately overwrite those axes when the abs valuators are
written out.

This patch fixes the default case only, in the case of a device setting the
two Ignore*Axis options both to "off", the axes are still overwritten. The
wheels will work, other axes only if the same number of abs axes exists. And
it keeps the current memory leak too, but it's marked with a FIXME now.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-08-18 10:02:00 +10:00
Peter Hutterer
8ce06c96e4 Make the slot-state per slot
The previous approach only had the slot state for the current slot. If we
changed slots, that means we lost the information if the slot was ever
initialized. If the ABS_MT_TRACKING_ID was never received, the slot would
still update and try to send events (which the server refused with a warning).

Avoid this by having a per-slot state and a dirty bit that tells us if the
current slot updated at all. If we don't get the tracking ID, leave the slot
empty and refuse any further events from that touch.

This quashes the various "unable to find touch point 0" warnings caused if a
touchpoint starts before the device is enabled.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Walter Harms <wharms@bfs.de>
2014-08-18 10:01:47 +10:00
3 changed files with 115 additions and 102 deletions

View File

@@ -23,7 +23,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-input-evdev],
[2.9.0],
[2.9.1],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
[xf86-input-evdev])
AC_CONFIG_SRCDIR([Makefile.am])

View File

@@ -71,12 +71,6 @@
#define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
#define MIN_KEYCODE 8
#define GLYPHS_PER_KEY 2
#define AltMask Mod1Mask
#define NumLockMask Mod2Mask
#define AltLangMask Mod3Mask
#define KanaMask Mod4Mask
#define ScrollLockMask Mod5Mask
#define CAPSFLAG 1
#define NUMFLAG 2
@@ -687,28 +681,38 @@ EvdevProcessTouch(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
int type;
int slot = pEvdev->cur_slot;
if (pEvdev->cur_slot < 0 || !pEvdev->mt_mask)
if (slot < 0 || !pEvdev->mt_mask)
return;
/* If the ABS_MT_SLOT is the first event we get after EV_SYN, skip this */
if (pEvdev->slot_state == SLOTSTATE_EMPTY)
if (!pEvdev->slots[slot].dirty)
return;
if (pEvdev->slot_state == SLOTSTATE_CLOSE)
type = XI_TouchEnd;
else if (pEvdev->slot_state == SLOTSTATE_OPEN)
type = XI_TouchBegin;
else
type = XI_TouchUpdate;
switch(pEvdev->slots[slot].state)
{
case SLOTSTATE_EMPTY:
return;
case SLOTSTATE_CLOSE:
type = XI_TouchEnd;
pEvdev->slots[slot].state = SLOTSTATE_EMPTY;
break;
case SLOTSTATE_OPEN:
type = XI_TouchBegin;
pEvdev->slots[slot].state = SLOTSTATE_UPDATE;
break;
case SLOTSTATE_UPDATE:
default:
type = XI_TouchUpdate;
break;
}
EvdevSwapAbsValuators(pEvdev, pEvdev->mt_mask);
EvdevApplyCalibration(pEvdev, pEvdev->mt_mask);
EvdevQueueTouchEvent(pInfo, pEvdev->cur_slot, pEvdev->mt_mask, type);
pEvdev->slot_state = SLOTSTATE_EMPTY;
pEvdev->slots[slot].dirty = 0;
valuator_mask_zero(pEvdev->mt_mask);
}
@@ -751,29 +755,28 @@ EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
} else
{
int slot_index = last_mt_vals_slot(pEvdev);
if (slot_index < 0) {
LogMessageVerbSigSafe(X_WARNING, 0,
"%s: Invalid slot index %d, touch events may be incorrect.\n",
pInfo->name,
slot_index);
return;
}
if (pEvdev->slot_state == SLOTSTATE_EMPTY)
pEvdev->slot_state = SLOTSTATE_UPDATE;
pEvdev->slots[slot_index].dirty = 1;
if (ev->code == ABS_MT_TRACKING_ID) {
if (ev->value >= 0) {
pEvdev->slot_state = SLOTSTATE_OPEN;
pEvdev->slots[slot_index].state = SLOTSTATE_OPEN;
if (slot_index >= 0)
valuator_mask_copy(pEvdev->mt_mask,
pEvdev->last_mt_vals[slot_index]);
else
LogMessageVerbSigSafe(X_WARNING, 0,
"%s: Attempted to copy values from out-of-range "
"slot, touch events may be incorrect.\n",
pInfo->name);
} else
pEvdev->slot_state = SLOTSTATE_CLOSE;
valuator_mask_copy(pEvdev->mt_mask,
pEvdev->last_mt_vals[slot_index]);
} else if (pEvdev->slots[slot_index].state != SLOTSTATE_EMPTY)
pEvdev->slots[slot_index].state = SLOTSTATE_CLOSE;
} else {
map = pEvdev->abs_axis_map[ev->code];
valuator_mask_set(pEvdev->mt_mask, map, ev->value);
if (slot_index >= 0)
valuator_mask_set(pEvdev->last_mt_vals[slot_index], map,
ev->value);
valuator_mask_set(pEvdev->last_mt_vals[slot_index], map,
ev->value);
}
}
}
@@ -865,8 +868,7 @@ EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev)
* Post the relative motion events.
*/
void
EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
int v[MAX_VALUATORS])
EvdevPostRelativeMotionEvents(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
@@ -879,8 +881,7 @@ EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
* Post the absolute motion events.
*/
void
EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
int v[MAX_VALUATORS])
EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
@@ -899,8 +900,7 @@ EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
}
static void
EvdevPostProximityEvents(InputInfoPtr pInfo, int which, int num_v, int first_v,
int v[MAX_VALUATORS])
EvdevPostProximityEvents(InputInfoPtr pInfo, int which)
{
int i;
EvdevPtr pEvdev = pInfo->private;
@@ -915,8 +915,7 @@ EvdevPostProximityEvents(InputInfoPtr pInfo, int which, int num_v, int first_v,
break;
case EV_QUEUE_PROXIMITY:
if (pEvdev->queue[i].val == which)
xf86PostProximityEventP(pInfo->dev, which, first_v, num_v,
v + first_v);
xf86PostProximityEvent(pInfo->dev, which, 0, 0);
break;
}
}
@@ -925,8 +924,7 @@ EvdevPostProximityEvents(InputInfoPtr pInfo, int which, int num_v, int first_v,
/**
* Post the queued key/button events.
*/
static void EvdevPostQueuedEvents(InputInfoPtr pInfo, int num_v, int first_v,
int v[MAX_VALUATORS])
static void EvdevPostQueuedEvents(InputInfoPtr pInfo)
{
int i;
EvdevPtr pEvdev = pInfo->private;
@@ -944,9 +942,8 @@ static void EvdevPostQueuedEvents(InputInfoPtr pInfo, int num_v, int first_v,
break;
if (pEvdev->abs_queued && pEvdev->in_proximity) {
xf86PostButtonEventP(pInfo->dev, Absolute, pEvdev->queue[i].detail.key,
pEvdev->queue[i].val, first_v, num_v,
v + first_v);
xf86PostButtonEvent(pInfo->dev, Absolute, pEvdev->queue[i].detail.key,
pEvdev->queue[i].val, 0, 0);
} else
xf86PostButtonEvent(pInfo->dev, Relative, pEvdev->queue[i].detail.key,
@@ -973,8 +970,6 @@ static void
EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
{
int i;
int num_v = 0, first_v = 0;
int v[MAX_VALUATORS] = {};
EvdevPtr pEvdev = pInfo->private;
EvdevProcessProximityState(pInfo);
@@ -982,11 +977,11 @@ EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
EvdevProcessValuators(pInfo);
EvdevProcessTouch(pInfo);
EvdevPostProximityEvents(pInfo, TRUE, num_v, first_v, v);
EvdevPostRelativeMotionEvents(pInfo, num_v, first_v, v);
EvdevPostAbsoluteMotionEvents(pInfo, num_v, first_v, v);
EvdevPostQueuedEvents(pInfo, num_v, first_v, v);
EvdevPostProximityEvents(pInfo, FALSE, num_v, first_v, v);
EvdevPostProximityEvents(pInfo, TRUE);
EvdevPostRelativeMotionEvents(pInfo);
EvdevPostAbsoluteMotionEvents(pInfo);
EvdevPostQueuedEvents(pInfo);
EvdevPostProximityEvents(pInfo, FALSE);
memset(pEvdev->delta, 0, sizeof(pEvdev->delta));
for (i = 0; i < ArrayLength(pEvdev->queue); i++)
@@ -1030,10 +1025,6 @@ EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
}
}
#undef ABS_X_VALUE
#undef ABS_Y_VALUE
#undef ABS_VALUE
static void
EvdevFreeMasks(EvdevPtr pEvdev)
{
@@ -1041,6 +1032,8 @@ EvdevFreeMasks(EvdevPtr pEvdev)
int i;
#endif
free(pEvdev->slots);
pEvdev->slots = NULL;
valuator_mask_free(&pEvdev->vals);
valuator_mask_free(&pEvdev->old_vals);
valuator_mask_free(&pEvdev->prox);
@@ -1214,7 +1207,7 @@ is_blacklisted_axis(int axis)
static int
EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_axes)
{
InputInfoPtr pInfo;
EvdevPtr pEvdev;
@@ -1276,16 +1269,9 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
#endif
#ifdef HAVE_SMOOTH_SCROLLING
if (want_scroll_axes && libevdev_has_event_type(pEvdev->dev, EV_REL))
{
if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
num_axes++;
if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
num_axes++;
if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
num_axes++;
}
num_axes += num_scroll_axes;
#endif
if (num_axes + num_mt_axes > MAX_VALUATORS) {
@@ -1320,6 +1306,17 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
goto out;
}
pEvdev->slots = calloc(nslots, sizeof(*pEvdev->slots));
if (!pEvdev->slots) {
xf86Msg(X_ERROR, "%s: failed to allocate slot state array.\n",
device->name);
goto out;
}
for (i = 0; i < nslots; i++) {
pEvdev->slots[i].state = SLOTSTATE_EMPTY;
pEvdev->slots[i].dirty = 0;
}
pEvdev->last_mt_vals = calloc(nslots, sizeof(ValuatorMask *));
if (!pEvdev->last_mt_vals) {
xf86IDrvMsg(pInfo, X_ERROR,
@@ -1379,7 +1376,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
}
#ifdef HAVE_SMOOTH_SCROLLING
if (want_scroll_axes)
if (num_scroll_axes > 0)
{
mapping++; /* continue from abs axis mapping */
@@ -1489,7 +1486,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
#endif
#ifdef HAVE_SMOOTH_SCROLLING
if (want_scroll_axes)
if (num_scroll_axes)
{
int idx;
if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
@@ -1624,7 +1621,7 @@ EvdevSetScrollValuators(DeviceIntPtr device)
}
static int
EvdevAddRelValuatorClass(DeviceIntPtr device)
EvdevAddRelValuatorClass(DeviceIntPtr device, int num_scroll_axes)
{
InputInfoPtr pInfo;
EvdevPtr pEvdev;
@@ -1637,24 +1634,22 @@ EvdevAddRelValuatorClass(DeviceIntPtr device)
if (!libevdev_has_event_type(pEvdev->dev, EV_REL))
goto out;
for (i = 0; i < REL_MAX; i++)
for (i = 0; i < REL_MAX; i++) {
if (i == REL_WHEEL || i == REL_HWHEEL || i == REL_DIAL)
continue;
if (libevdev_has_event_code(pEvdev->dev, EV_REL, i))
num_axes++;
if (num_axes < 1)
goto out;
}
#ifndef HAVE_SMOOTH_SCROLLING
/* Wheels are special, we post them as button events. So let's ignore them
* in the axes list too */
if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
num_axes--;
if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
num_axes--;
if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
num_axes--;
/* If we have only relative scroll axes, then we punt axis init to
EvdevInitAbsValuators if possible */
if (num_axes < 1 &&
(num_scroll_axes == 0 || pEvdev->flags & EVDEV_ABSOLUTE_EVENTS))
goto out;
if (num_axes <= 0)
goto out;
#ifdef HAVE_SMOOTH_SCROLLING
num_axes += num_scroll_axes;
#endif
if (num_axes > MAX_VALUATORS) {
@@ -1793,20 +1788,36 @@ EvdevInitButtonMapping(InputInfoPtr pInfo)
}
static int
EvdevCountScrollAxes(EvdevPtr pEvdev)
{
int num_scroll_axes = 0;
#ifdef HAVE_SMOOTH_SCROLLING
if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
num_scroll_axes++;
if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
num_scroll_axes++;
if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
num_scroll_axes++;
#endif
return num_scroll_axes;
}
static void
EvdevInitAnyValuators(DeviceIntPtr device, EvdevPtr pEvdev)
{
InputInfoPtr pInfo = device->public.devicePrivate;
int rel_success = FALSE;
int num_scroll_axes = EvdevCountScrollAxes(pEvdev);
if (pEvdev->flags & EVDEV_RELATIVE_EVENTS &&
EvdevAddRelValuatorClass(device) == Success)
{
rel_success = TRUE;
EvdevAddRelValuatorClass(device, num_scroll_axes) == Success)
xf86IDrvMsg(pInfo, X_INFO, "initialized for relative axes.\n");
}
/* FIXME: EvdevAddAbsValuatorClass overwrites the valuators initialized
in EvdevAddRelValuatorClass and leaks the latter's memory */
if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS &&
EvdevAddAbsValuatorClass(device, !rel_success) == Success)
EvdevAddAbsValuatorClass(device, num_scroll_axes) == Success)
xf86IDrvMsg(pInfo, X_INFO, "initialized for absolute axes.\n");
}
@@ -1814,8 +1825,9 @@ static void
EvdevInitAbsValuators(DeviceIntPtr device, EvdevPtr pEvdev)
{
InputInfoPtr pInfo = device->public.devicePrivate;
int num_scroll_axes = EvdevCountScrollAxes(pEvdev);
if (EvdevAddAbsValuatorClass(device, TRUE) == Success) {
if (EvdevAddAbsValuatorClass(device, num_scroll_axes) == Success) {
xf86IDrvMsg(pInfo, X_INFO,"initialized for absolute axes.\n");
} else {
xf86IDrvMsg(pInfo, X_ERROR,"failed to initialize for absolute axes.\n");
@@ -1828,8 +1840,9 @@ EvdevInitRelValuators(DeviceIntPtr device, EvdevPtr pEvdev)
{
InputInfoPtr pInfo = device->public.devicePrivate;
int has_abs_axes = pEvdev->flags & EVDEV_ABSOLUTE_EVENTS;
int num_scroll_axes = EvdevCountScrollAxes(pEvdev);
if (EvdevAddRelValuatorClass(device) == Success) {
if (EvdevAddRelValuatorClass(device, num_scroll_axes) == Success) {
xf86IDrvMsg(pInfo, X_INFO,"initialized for relative axes.\n");
@@ -1890,7 +1903,9 @@ EvdevInit(DeviceIntPtr device)
* used and relative axes are ignored.
*/
if (pEvdev->flags & (EVDEV_UNIGNORE_RELATIVE | EVDEV_UNIGNORE_ABSOLUTE))
if ((pEvdev->flags & (EVDEV_UNIGNORE_RELATIVE|EVDEV_UNIGNORE_ABSOLUTE)) == EVDEV_UNIGNORE_RELATIVE)
EvdevInitRelValuators(device, pEvdev);
else if (pEvdev->flags & EVDEV_UNIGNORE_ABSOLUTE)
EvdevInitAnyValuators(device, pEvdev);
else if (pEvdev->flags & (EVDEV_TOUCHPAD | EVDEV_TOUCHSCREEN | EVDEV_TABLET))
EvdevInitTouchDevice(device, pEvdev);
@@ -2256,9 +2271,6 @@ EvdevProbe(InputInfoPtr pInfo)
#endif
EvdevForceXY(pInfo, Absolute);
}
}
for (i = 0; i < BTN_MISC; i++) {

View File

@@ -167,7 +167,10 @@ typedef struct {
ValuatorMask *mt_mask;
ValuatorMask **last_mt_vals;
int cur_slot;
enum SlotState slot_state;
struct slot {
int dirty;
enum SlotState state;
} *slots;
#ifdef MULTITOUCH
struct mtdev *mtdev;
#endif
@@ -262,10 +265,8 @@ void EvdevQueueTouchEvent(InputInfoPtr pInfo, unsigned int touch,
#endif
void EvdevPostButtonEvent(InputInfoPtr pInfo, int button, enum ButtonAction act);
void EvdevQueueButtonClicks(InputInfoPtr pInfo, int button, int count);
void EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
int v[MAX_VALUATORS]);
void EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
int v[MAX_VALUATORS]);
void EvdevPostRelativeMotionEvents(InputInfoPtr pInfo);
void EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo);
unsigned int EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code);
/* Middle Button emulation */