Compare commits

...

10 Commits

Author SHA1 Message Date
Peter Hutterer
24368d8379 evdev 2.9.2
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-03-27 11:37:03 +10:00
Tobias Himmer
4996694cc9 Check for incoming MT slot indices exceeding the allocated number of slots.
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=88715

Signed-off-by: Tobias Himmer <provisorisch@online.de>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit abc4a8b603)
2015-03-24 14:59:43 +10:00
Colin B. Macdonald
05f7057ad5 Workaround lack of ABS_X on MT devices (#80470)
Often on Android, we have ABS_MT_POSITION_X without ABS_X (which is contrary
to spec). We add fake ABS_X axis in that case.

X.Org Bug 80470 <http://bugs.freedesktop.org/show_bug.cgi?id=80470>

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit b370ccdff8)
2015-03-24 14:59:39 +10:00
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 152 additions and 105 deletions

View File

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

View File

@@ -71,12 +71,6 @@
#define ArrayLength(a) (sizeof(a) / (sizeof((a)[0]))) #define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
#define MIN_KEYCODE 8 #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 CAPSFLAG 1
#define NUMFLAG 2 #define NUMFLAG 2
@@ -687,28 +681,38 @@ EvdevProcessTouch(InputInfoPtr pInfo)
{ {
EvdevPtr pEvdev = pInfo->private; EvdevPtr pEvdev = pInfo->private;
int type; int type;
int slot = pEvdev->cur_slot;
if (pEvdev->cur_slot < 0 || !pEvdev->mt_mask) if (slot < 0 || !pEvdev->mt_mask)
return; return;
/* If the ABS_MT_SLOT is the first event we get after EV_SYN, skip this */ if (!pEvdev->slots[slot].dirty)
if (pEvdev->slot_state == SLOTSTATE_EMPTY)
return; return;
if (pEvdev->slot_state == SLOTSTATE_CLOSE) switch(pEvdev->slots[slot].state)
type = XI_TouchEnd; {
else if (pEvdev->slot_state == SLOTSTATE_OPEN) case SLOTSTATE_EMPTY:
type = XI_TouchBegin; return;
else case SLOTSTATE_CLOSE:
type = XI_TouchUpdate; 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); EvdevSwapAbsValuators(pEvdev, pEvdev->mt_mask);
EvdevApplyCalibration(pEvdev, pEvdev->mt_mask); EvdevApplyCalibration(pEvdev, pEvdev->mt_mask);
EvdevQueueTouchEvent(pInfo, pEvdev->cur_slot, pEvdev->mt_mask, type); 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); valuator_mask_zero(pEvdev->mt_mask);
} }
@@ -747,33 +751,40 @@ EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
if (ev->code == ABS_MT_SLOT) { if (ev->code == ABS_MT_SLOT) {
EvdevProcessTouch(pInfo); EvdevProcessTouch(pInfo);
if (ev->value >= num_slots(pEvdev) ) {
LogMessageVerbSigSafe(X_WARNING, 0,
"%s: Slot index %d out of bounds (max %d), touch events may be incorrect.\n",
pInfo->name,
ev->value,
num_slots(pEvdev) - 1);
return;
}
pEvdev->cur_slot = ev->value; pEvdev->cur_slot = ev->value;
} else } else
{ {
int slot_index = last_mt_vals_slot(pEvdev); 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->slots[slot_index].dirty = 1;
pEvdev->slot_state = SLOTSTATE_UPDATE;
if (ev->code == ABS_MT_TRACKING_ID) { if (ev->code == ABS_MT_TRACKING_ID) {
if (ev->value >= 0) { 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,
valuator_mask_copy(pEvdev->mt_mask, pEvdev->last_mt_vals[slot_index]);
pEvdev->last_mt_vals[slot_index]); } else if (pEvdev->slots[slot_index].state != SLOTSTATE_EMPTY)
else pEvdev->slots[slot_index].state = SLOTSTATE_CLOSE;
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;
} else { } else {
map = pEvdev->abs_axis_map[ev->code]; map = pEvdev->abs_axis_map[ev->code];
valuator_mask_set(pEvdev->mt_mask, map, ev->value); valuator_mask_set(pEvdev->mt_mask, map, ev->value);
if (slot_index >= 0) valuator_mask_set(pEvdev->last_mt_vals[slot_index], map,
valuator_mask_set(pEvdev->last_mt_vals[slot_index], map, ev->value);
ev->value);
} }
} }
} }
@@ -865,8 +876,7 @@ EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev)
* Post the relative motion events. * Post the relative motion events.
*/ */
void void
EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int num_v, int first_v, EvdevPostRelativeMotionEvents(InputInfoPtr pInfo)
int v[MAX_VALUATORS])
{ {
EvdevPtr pEvdev = pInfo->private; EvdevPtr pEvdev = pInfo->private;
@@ -879,8 +889,7 @@ EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
* Post the absolute motion events. * Post the absolute motion events.
*/ */
void void
EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int num_v, int first_v, EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo)
int v[MAX_VALUATORS])
{ {
EvdevPtr pEvdev = pInfo->private; EvdevPtr pEvdev = pInfo->private;
@@ -899,8 +908,7 @@ EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
} }
static void static void
EvdevPostProximityEvents(InputInfoPtr pInfo, int which, int num_v, int first_v, EvdevPostProximityEvents(InputInfoPtr pInfo, int which)
int v[MAX_VALUATORS])
{ {
int i; int i;
EvdevPtr pEvdev = pInfo->private; EvdevPtr pEvdev = pInfo->private;
@@ -915,8 +923,7 @@ EvdevPostProximityEvents(InputInfoPtr pInfo, int which, int num_v, int first_v,
break; break;
case EV_QUEUE_PROXIMITY: case EV_QUEUE_PROXIMITY:
if (pEvdev->queue[i].val == which) if (pEvdev->queue[i].val == which)
xf86PostProximityEventP(pInfo->dev, which, first_v, num_v, xf86PostProximityEvent(pInfo->dev, which, 0, 0);
v + first_v);
break; break;
} }
} }
@@ -925,8 +932,7 @@ EvdevPostProximityEvents(InputInfoPtr pInfo, int which, int num_v, int first_v,
/** /**
* Post the queued key/button events. * Post the queued key/button events.
*/ */
static void EvdevPostQueuedEvents(InputInfoPtr pInfo, int num_v, int first_v, static void EvdevPostQueuedEvents(InputInfoPtr pInfo)
int v[MAX_VALUATORS])
{ {
int i; int i;
EvdevPtr pEvdev = pInfo->private; EvdevPtr pEvdev = pInfo->private;
@@ -944,9 +950,8 @@ static void EvdevPostQueuedEvents(InputInfoPtr pInfo, int num_v, int first_v,
break; break;
if (pEvdev->abs_queued && pEvdev->in_proximity) { if (pEvdev->abs_queued && pEvdev->in_proximity) {
xf86PostButtonEventP(pInfo->dev, Absolute, pEvdev->queue[i].detail.key, xf86PostButtonEvent(pInfo->dev, Absolute, pEvdev->queue[i].detail.key,
pEvdev->queue[i].val, first_v, num_v, pEvdev->queue[i].val, 0, 0);
v + first_v);
} else } else
xf86PostButtonEvent(pInfo->dev, Relative, pEvdev->queue[i].detail.key, xf86PostButtonEvent(pInfo->dev, Relative, pEvdev->queue[i].detail.key,
@@ -973,8 +978,6 @@ static void
EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev) EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
{ {
int i; int i;
int num_v = 0, first_v = 0;
int v[MAX_VALUATORS] = {};
EvdevPtr pEvdev = pInfo->private; EvdevPtr pEvdev = pInfo->private;
EvdevProcessProximityState(pInfo); EvdevProcessProximityState(pInfo);
@@ -982,11 +985,11 @@ EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
EvdevProcessValuators(pInfo); EvdevProcessValuators(pInfo);
EvdevProcessTouch(pInfo); EvdevProcessTouch(pInfo);
EvdevPostProximityEvents(pInfo, TRUE, num_v, first_v, v); EvdevPostProximityEvents(pInfo, TRUE);
EvdevPostRelativeMotionEvents(pInfo, num_v, first_v, v); EvdevPostRelativeMotionEvents(pInfo);
EvdevPostAbsoluteMotionEvents(pInfo, num_v, first_v, v); EvdevPostAbsoluteMotionEvents(pInfo);
EvdevPostQueuedEvents(pInfo, num_v, first_v, v); EvdevPostQueuedEvents(pInfo);
EvdevPostProximityEvents(pInfo, FALSE, num_v, first_v, v); EvdevPostProximityEvents(pInfo, FALSE);
memset(pEvdev->delta, 0, sizeof(pEvdev->delta)); memset(pEvdev->delta, 0, sizeof(pEvdev->delta));
for (i = 0; i < ArrayLength(pEvdev->queue); i++) for (i = 0; i < ArrayLength(pEvdev->queue); i++)
@@ -1030,10 +1033,6 @@ EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
} }
} }
#undef ABS_X_VALUE
#undef ABS_Y_VALUE
#undef ABS_VALUE
static void static void
EvdevFreeMasks(EvdevPtr pEvdev) EvdevFreeMasks(EvdevPtr pEvdev)
{ {
@@ -1041,6 +1040,8 @@ EvdevFreeMasks(EvdevPtr pEvdev)
int i; int i;
#endif #endif
free(pEvdev->slots);
pEvdev->slots = NULL;
valuator_mask_free(&pEvdev->vals); valuator_mask_free(&pEvdev->vals);
valuator_mask_free(&pEvdev->old_vals); valuator_mask_free(&pEvdev->old_vals);
valuator_mask_free(&pEvdev->prox); valuator_mask_free(&pEvdev->prox);
@@ -1214,11 +1215,12 @@ is_blacklisted_axis(int axis)
static int static int
EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes) EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_axes)
{ {
InputInfoPtr pInfo; InputInfoPtr pInfo;
EvdevPtr pEvdev; EvdevPtr pEvdev;
int num_axes = 0, axis, i = 0; int axis, i = 0;
int num_axes = 0; /* number of non-MT axes */
int num_mt_axes = 0, /* number of MT-only axes */ int num_mt_axes = 0, /* number of MT-only axes */
num_mt_axes_total = 0; /* total number of MT axes, including num_mt_axes_total = 0; /* total number of MT axes, including
double-counted ones, excluding blacklisted */ double-counted ones, excluding blacklisted */
@@ -1231,6 +1233,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
if (!libevdev_has_event_type(pEvdev->dev, EV_ABS)) if (!libevdev_has_event_type(pEvdev->dev, EV_ABS))
goto out; goto out;
/* Find number of absolute axis, including MT ones, will decrease later. */
for (i = 0; i < ABS_MAX; i++) for (i = 0; i < ABS_MAX; i++)
if (libevdev_has_event_code(pEvdev->dev, EV_ABS, i)) if (libevdev_has_event_code(pEvdev->dev, EV_ABS, i))
num_axes++; num_axes++;
@@ -1239,6 +1242,30 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
goto out; goto out;
#ifdef MULTITOUCH #ifdef MULTITOUCH
/* Android drivers often have ABS_MT_POSITION_X but not ABS_X.
Loop over the MT->legacy axis table and add fake axes. */
for (i = 0; i < ArrayLength(mt_axis_mappings); i++)
{
int mt_code = mt_axis_mappings[i].mt_code;
int code = mt_axis_mappings[i].code;
if (libevdev_has_event_code(pEvdev->dev, EV_ABS, mt_code) &&
!libevdev_has_event_code(pEvdev->dev, EV_ABS, code))
{
const struct input_absinfo* abs;
abs = libevdev_get_abs_info(pEvdev->dev, mt_code);
if (libevdev_enable_event_code(pEvdev->dev, EV_ABS, code, abs))
{
xf86IDrvMsg(pInfo, X_ERROR, "Failed to fake axis %s.\n",
libevdev_event_code_get_name(EV_ABS, code));
goto out;
}
xf86IDrvMsg(pInfo, X_INFO, "Faking axis %s.\n",
libevdev_event_code_get_name(EV_ABS, code));
num_axes++;
}
}
/* Absolute multitouch axes: adjust mapping and axes counts. */
for (axis = ABS_MT_SLOT; axis < ABS_MAX; axis++) for (axis = ABS_MT_SLOT; axis < ABS_MAX; axis++)
{ {
if (libevdev_has_event_code(pEvdev->dev, EV_ABS, axis)) if (libevdev_has_event_code(pEvdev->dev, EV_ABS, axis))
@@ -1246,6 +1273,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
int j; int j;
Bool skip = FALSE; Bool skip = FALSE;
/* Setup mapping if axis is in MT->legacy axis table. */
for (j = 0; j < ArrayLength(mt_axis_mappings); j++) for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
{ {
if (mt_axis_mappings[j].mt_code == axis && if (mt_axis_mappings[j].mt_code == axis &&
@@ -1266,8 +1294,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
} }
} }
/* device only has mt-axes. the kernel should give us ABS_X etc for /* Panic if, after faking ABS_X etc, we still only have mt-axes. */
backwards compat but some devices don't have it. */
if (num_axes == 0 && num_mt_axes > 0) { if (num_axes == 0 && num_mt_axes > 0) {
xf86IDrvMsg(pInfo, X_ERROR, xf86IDrvMsg(pInfo, X_ERROR,
"found only multitouch-axes. That shouldn't happen.\n"); "found only multitouch-axes. That shouldn't happen.\n");
@@ -1276,16 +1303,9 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
#endif #endif
#ifdef HAVE_SMOOTH_SCROLLING #ifdef HAVE_SMOOTH_SCROLLING
if (want_scroll_axes && libevdev_has_event_type(pEvdev->dev, EV_REL)) num_axes += num_scroll_axes;
{
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++;
}
#endif #endif
if (num_axes + num_mt_axes > MAX_VALUATORS) { if (num_axes + num_mt_axes > MAX_VALUATORS) {
@@ -1320,6 +1340,17 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
goto out; 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 *)); pEvdev->last_mt_vals = calloc(nslots, sizeof(ValuatorMask *));
if (!pEvdev->last_mt_vals) { if (!pEvdev->last_mt_vals) {
xf86IDrvMsg(pInfo, X_ERROR, xf86IDrvMsg(pInfo, X_ERROR,
@@ -1379,7 +1410,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
} }
#ifdef HAVE_SMOOTH_SCROLLING #ifdef HAVE_SMOOTH_SCROLLING
if (want_scroll_axes) if (num_scroll_axes > 0)
{ {
mapping++; /* continue from abs axis mapping */ mapping++; /* continue from abs axis mapping */
@@ -1489,7 +1520,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
#endif #endif
#ifdef HAVE_SMOOTH_SCROLLING #ifdef HAVE_SMOOTH_SCROLLING
if (want_scroll_axes) if (num_scroll_axes)
{ {
int idx; int idx;
if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL)) if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
@@ -1624,7 +1655,7 @@ EvdevSetScrollValuators(DeviceIntPtr device)
} }
static int static int
EvdevAddRelValuatorClass(DeviceIntPtr device) EvdevAddRelValuatorClass(DeviceIntPtr device, int num_scroll_axes)
{ {
InputInfoPtr pInfo; InputInfoPtr pInfo;
EvdevPtr pEvdev; EvdevPtr pEvdev;
@@ -1637,24 +1668,22 @@ EvdevAddRelValuatorClass(DeviceIntPtr device)
if (!libevdev_has_event_type(pEvdev->dev, EV_REL)) if (!libevdev_has_event_type(pEvdev->dev, EV_REL))
goto out; 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)) if (libevdev_has_event_code(pEvdev->dev, EV_REL, i))
num_axes++; num_axes++;
if (num_axes < 1) }
goto out;
#ifndef HAVE_SMOOTH_SCROLLING /* If we have only relative scroll axes, then we punt axis init to
/* Wheels are special, we post them as button events. So let's ignore them EvdevInitAbsValuators if possible */
* in the axes list too */ if (num_axes < 1 &&
if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL)) (num_scroll_axes == 0 || pEvdev->flags & EVDEV_ABSOLUTE_EVENTS))
num_axes--; goto out;
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 (num_axes <= 0) #ifdef HAVE_SMOOTH_SCROLLING
goto out; num_axes += num_scroll_axes;
#endif #endif
if (num_axes > MAX_VALUATORS) { if (num_axes > MAX_VALUATORS) {
@@ -1793,20 +1822,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 static void
EvdevInitAnyValuators(DeviceIntPtr device, EvdevPtr pEvdev) EvdevInitAnyValuators(DeviceIntPtr device, EvdevPtr pEvdev)
{ {
InputInfoPtr pInfo = device->public.devicePrivate; InputInfoPtr pInfo = device->public.devicePrivate;
int rel_success = FALSE; int num_scroll_axes = EvdevCountScrollAxes(pEvdev);
if (pEvdev->flags & EVDEV_RELATIVE_EVENTS && if (pEvdev->flags & EVDEV_RELATIVE_EVENTS &&
EvdevAddRelValuatorClass(device) == Success) EvdevAddRelValuatorClass(device, num_scroll_axes) == Success)
{
rel_success = TRUE;
xf86IDrvMsg(pInfo, X_INFO, "initialized for relative axes.\n"); 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 && 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"); xf86IDrvMsg(pInfo, X_INFO, "initialized for absolute axes.\n");
} }
@@ -1814,8 +1859,9 @@ static void
EvdevInitAbsValuators(DeviceIntPtr device, EvdevPtr pEvdev) EvdevInitAbsValuators(DeviceIntPtr device, EvdevPtr pEvdev)
{ {
InputInfoPtr pInfo = device->public.devicePrivate; 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"); xf86IDrvMsg(pInfo, X_INFO,"initialized for absolute axes.\n");
} else { } else {
xf86IDrvMsg(pInfo, X_ERROR,"failed to initialize for absolute axes.\n"); xf86IDrvMsg(pInfo, X_ERROR,"failed to initialize for absolute axes.\n");
@@ -1828,8 +1874,9 @@ EvdevInitRelValuators(DeviceIntPtr device, EvdevPtr pEvdev)
{ {
InputInfoPtr pInfo = device->public.devicePrivate; InputInfoPtr pInfo = device->public.devicePrivate;
int has_abs_axes = pEvdev->flags & EVDEV_ABSOLUTE_EVENTS; 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"); xf86IDrvMsg(pInfo, X_INFO,"initialized for relative axes.\n");
@@ -1890,7 +1937,9 @@ EvdevInit(DeviceIntPtr device)
* used and relative axes are ignored. * 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); EvdevInitAnyValuators(device, pEvdev);
else if (pEvdev->flags & (EVDEV_TOUCHPAD | EVDEV_TOUCHSCREEN | EVDEV_TABLET)) else if (pEvdev->flags & (EVDEV_TOUCHPAD | EVDEV_TOUCHSCREEN | EVDEV_TABLET))
EvdevInitTouchDevice(device, pEvdev); EvdevInitTouchDevice(device, pEvdev);
@@ -2256,9 +2305,6 @@ EvdevProbe(InputInfoPtr pInfo)
#endif #endif
EvdevForceXY(pInfo, Absolute); EvdevForceXY(pInfo, Absolute);
} }
} }
for (i = 0; i < BTN_MISC; i++) { for (i = 0; i < BTN_MISC; i++) {

View File

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