Compare commits

...

12 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
Peter Hutterer
5d239ceb26 evdev 2.9.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-05-20 15:41:08 +10:00
Peter Hutterer
13dea90bc8 Use the server's device list for duplicate detection (#78309)
EvdevAddDevice/EvdevRemoveDevice keep a reference to the device to detect
duplicate devices based on the dev_t.

EvdevAddDevices was called during PreInit, EvdevRemoveDevice was called during
DEVICE_CLOSE. That makes it imbalanced if the device succeeds PreInit but the
server skips everything else because MAX_DEVICES is exceeded. So for all
devices after MAX_DEVICES, we'd add a reference but never remove it,
eventually reading/writing past evdev_devices.

The server keeps the list of devices for us anyway, so remove the copy of all
the pointers and instead run through the device list the server gives us.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-05-07 07:27:29 +10:00
3 changed files with 165 additions and 166 deletions

View File

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

View File

@@ -68,20 +68,9 @@
/* removed from server, purge when dropping support for server 1.10 */
#define XI86_SEND_DRAG_EVENTS 0x08
#ifndef MAXDEVICES
#include <inputstr.h> /* for MAX_DEVICES */
#define MAXDEVICES MAX_DEVICES
#endif
#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
@@ -146,11 +135,6 @@ static Atom prop_device;
static Atom prop_virtual;
static Atom prop_scroll_dist;
/* All devices the evdev driver has allocated and knows about.
* MAXDEVICES is safe as null-terminated array, as two devices (VCP and VCK)
* cannot be used by evdev, leaving us with a space of 2 at the end. */
static EvdevPtr evdev_devices[MAXDEVICES] = {NULL};
static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode)
{
InputInfoPtr pInfo;
@@ -216,60 +200,25 @@ static BOOL
EvdevIsDuplicate(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
EvdevPtr* dev = evdev_devices;
InputInfoPtr d;
if (pEvdev->min_maj)
nt_list_for_each_entry(d, xf86FirstLocalDevice(), next)
{
while(*dev)
{
if ((*dev) != pEvdev &&
(*dev)->min_maj &&
(*dev)->min_maj == pEvdev->min_maj)
return TRUE;
dev++;
}
EvdevPtr e;
if (strcmp(d->drv->driverName, "evdev") != 0)
continue;
e = (EvdevPtr)d->private;
if (e != pEvdev &&
e->min_maj &&
e->min_maj == pEvdev->min_maj)
return TRUE;
}
return FALSE;
}
/**
* Add to internal device list.
*/
static void
EvdevAddDevice(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
EvdevPtr* dev = evdev_devices;
while(*dev)
dev++;
*dev = pEvdev;
}
/**
* Remove from internal device list.
*/
static void
EvdevRemoveDevice(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
EvdevPtr *dev = evdev_devices;
int count = 0;
while(*dev)
{
count++;
if (*dev == pEvdev)
{
memmove(dev, dev + 1,
sizeof(evdev_devices) - (count * sizeof(EvdevPtr)));
break;
}
dev++;
}
}
static BOOL
EvdevDeviceIsVirtual(const char* devicenode)
{
@@ -732,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);
}
@@ -792,33 +751,40 @@ EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
if (ev->code == ABS_MT_SLOT) {
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;
} 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);
}
}
}
@@ -910,8 +876,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;
@@ -924,8 +889,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;
@@ -944,8 +908,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;
@@ -960,8 +923,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;
}
}
@@ -970,8 +932,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;
@@ -989,9 +950,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,
@@ -1018,8 +978,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);
@@ -1027,11 +985,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++)
@@ -1075,10 +1033,6 @@ EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
}
}
#undef ABS_X_VALUE
#undef ABS_Y_VALUE
#undef ABS_VALUE
static void
EvdevFreeMasks(EvdevPtr pEvdev)
{
@@ -1086,6 +1040,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);
@@ -1259,11 +1215,12 @@ 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;
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 */
num_mt_axes_total = 0; /* total number of MT axes, including
double-counted ones, excluding blacklisted */
@@ -1276,6 +1233,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
if (!libevdev_has_event_type(pEvdev->dev, EV_ABS))
goto out;
/* Find number of absolute axis, including MT ones, will decrease later. */
for (i = 0; i < ABS_MAX; i++)
if (libevdev_has_event_code(pEvdev->dev, EV_ABS, i))
num_axes++;
@@ -1284,6 +1242,30 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
goto out;
#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++)
{
if (libevdev_has_event_code(pEvdev->dev, EV_ABS, axis))
@@ -1291,6 +1273,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
int j;
Bool skip = FALSE;
/* Setup mapping if axis is in MT->legacy axis table. */
for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
{
if (mt_axis_mappings[j].mt_code == axis &&
@@ -1311,8 +1294,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
}
}
/* device only has mt-axes. the kernel should give us ABS_X etc for
backwards compat but some devices don't have it. */
/* Panic if, after faking ABS_X etc, we still only have mt-axes. */
if (num_axes == 0 && num_mt_axes > 0) {
xf86IDrvMsg(pInfo, X_ERROR,
"found only multitouch-axes. That shouldn't happen.\n");
@@ -1321,16 +1303,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) {
@@ -1365,6 +1340,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,
@@ -1424,7 +1410,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 */
@@ -1534,7 +1520,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))
@@ -1669,7 +1655,7 @@ EvdevSetScrollValuators(DeviceIntPtr device)
}
static int
EvdevAddRelValuatorClass(DeviceIntPtr device)
EvdevAddRelValuatorClass(DeviceIntPtr device, int num_scroll_axes)
{
InputInfoPtr pInfo;
EvdevPtr pEvdev;
@@ -1682,24 +1668,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) {
@@ -1838,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
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");
}
@@ -1859,8 +1859,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");
@@ -1873,8 +1874,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");
@@ -1935,7 +1937,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);
@@ -2026,7 +2030,6 @@ EvdevProc(DeviceIntPtr device, int what)
xf86IDrvMsg(pInfo, X_INFO, "Close\n");
EvdevCloseDevice(pInfo);
EvdevFreeMasks(pEvdev);
EvdevRemoveDevice(pInfo);
pEvdev->min_maj = 0;
break;
@@ -2302,9 +2305,6 @@ EvdevProbe(InputInfoPtr pInfo)
#endif
EvdevForceXY(pInfo, Absolute);
}
}
for (i = 0; i < BTN_MISC; i++) {
@@ -2659,8 +2659,6 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
pInfo->type_name);
pInfo->type_name = pEvdev->type_name;
EvdevAddDevice(pInfo);
if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
{
EvdevMBEmuPreInit(pInfo);

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 */