Compare commits

...

27 Commits

Author SHA1 Message Date
Peter Hutterer
777cfa148f evdev 2.7.3
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2012-08-13 16:22:00 +10:00
Peter Hutterer
447fd220e0 Fix broken ButtonMapping option (#53168)
Regression introduced in 8af0e6f1eb.
s is now initialized to NULL, so we never entered the loop.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 33e7831b5f)
2012-08-13 16:21:38 +10:00
Peter Hutterer
f2c6da0242 Link against libudev
Fixes /usr/bin/Xorg: symbol lookup error:
/usr/lib64/xorg/modules/input/evdev_drv.so: undefined symbol: udev_new

This doesn't appear in the default configuration as Xorg links against
libudev and the symbol is defined when evdev is loaded. It can be reproduced
with a HAL-enabled server.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
(cherry picked from commit bc8997e812)
2012-08-07 08:17:07 +10:00
Peter Hutterer
9791afc4c1 Don't delete the device on ENODEV
This is signal handler code and we cannot clean up properly while in the
signal handler. So reduce the code to removing the signal handler and let
the device be cleaned up later.

If hotplugging is on, the server will remove it when the config backend says
so and if it is off, the server will remove it on shutdown.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
(cherry picked from commit 1cb8f074df)
2012-08-07 08:17:06 +10:00
Peter Hutterer
f1ee12b9a3 evdev 2.7.2
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2012-08-03 16:00:31 +10:00
Peter Hutterer
74690817fc Don't re-open mtdev after PreInit
==16557== 388,240 (3,520 direct, 384,720 indirect) bytes in 10 blocks are definitely lost in loss record 1,669 of 1,671
==16557==    at 0x4A06F18: calloc (vg_replace_malloc.c:566)
==16557==    by 0xC3EAD4D: mtdev_new (core.c:345)
==16557==    by 0xC3EAE6B: mtdev_new_open (core.c:383)
==16557==    by 0xC1E0452: EvdevOpenDevice (evdev.c:2365)
==16557==    by 0xC1E068C: EvdevPreInit (evdev.c:2431)
==16557==    by 0x4B8304: xf86NewInputDevice (xf86Xinput.c:846)
==16557==    by 0x4B8857: NewInputDeviceRequest (xf86Xinput.c:989)
==16557==    by 0x4CCB4C: device_added (udev.c:211)
==16557==    by 0x4CCFA6: config_udev_init (udev.c:342)
==16557==    by 0x4CBE81: config_init (config.c:48)
==16557==    by 0x4A8A9A: InitInput (xf86Init.c:918)
==16557==    by 0x4921EE: main (main.c:258)

After PreInit, the fd and mtdev pointer are still valid. We check for the
fd, but unconditionally allocated another mtdev struct for each device.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
(cherry picked from commit 98af2003d4)
2012-07-30 15:36:23 +10:00
Peter Hutterer
b2cbbb178e Constify InputDriverRec->default_options
Removes a warning, and with the input ABI 18 this is forced to const in the
server.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
(cherry picked from commit 9624f4e2ba)
2012-07-30 15:36:23 +10:00
Marcin Slusarz
7d91fc7bfc Fix some obvious constness-related compile warnings.
Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 2c8da280b3)
2012-07-30 15:22:06 +10:00
Daniel Stone
09987eab9a Fix compilation warnings for non-multitouch builds
Signed-off-by: Daniel Stone <daniel@fooishbar.org>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit f5ede98085)
2012-07-30 15:17:10 +10:00
Peter Hutterer
8af0e6f1eb strtol doesn't need a empty string, NULL is good enough.
Fixes:
evdev.c: In function 'EvdevInitButtonMapping':
evdev.c:1659:25: warning: initialization discards 'const' qualifier from
pointer target type [enabled by default]

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
(cherry picked from commit 61faf2e6e7)
2012-07-30 15:16:49 +10:00
Peter Hutterer
56e9a7a248 evdev 2.7.1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2012-07-24 14:05:09 +10:00
Peter Hutterer
7df6523774 Close the fd when mtdev open fails
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
(cherry picked from commit 8251d7a8ec)
2012-07-04 08:21:54 +10:00
Peter Hutterer
f4e76a4c53 Release mtdev data whenever we close the fd
Add a new EvdevCloseDevice() function to unify this.
We used to leak data
- PreInit allocates mtdev, but nothing except one error path released it.
- each DEVICE_ON re-allocates mtdev but it is never released

Reported-by: Zdenek Kabelac <zdenek.kabelac@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
(cherry picked from commit ac5173163d)
2012-07-04 08:21:11 +10:00
Chase Douglas
ac772cde94 Fix buffer overrun when populating axis label property array
The axis label property array currently only has enough elements for the
non-multitouch axes. This change allocates enough space for all axes,
which prevents an array overrun write. This may manifest as stack
corruption on some platforms.

Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 4145fe1c08)
2012-07-04 08:21:03 +10:00
Chase Douglas
7749159241 Report the correct number of touches for MT protocol B devices
Protocol B devices report the number of touches by giving a maximum and
minimum slot value. The current code ignores the minimum value, which is
usually 0, and underreports the number of touches by 1.

Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 9ce068e760)
2012-07-04 08:20:55 +10:00
Peter Hutterer
833fc517d7 Devices configured as mice need REL_X/Y
Some keyboards export scroll axes and any absolute axis possible in 11
dimensions. All these axes are mute, except possibly for the scroll wheels.

So if a device has a scroll axis, and we're configuring it as mouse, force
the x/y axes into existence. This stops the logspam complaining about not
enough axes on pointer movement after a xrandr change.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
(cherry picked from commit f28507e8ce)
2012-07-04 08:20:50 +10:00
Peter Hutterer
4d698d8ece Fix inverted horizontal scroll (#46205)
REL_HWHEEL has a positive increment, not a negative one like REL_WHEEL.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
(cherry picked from commit 99340147b9)
2012-07-04 08:20:43 +10:00
Peter Hutterer
76b1d58a97 evdev 2.7.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2012-03-07 20:39:09 +10:00
Peter Hutterer
224a28de25 Only force REL_X/Y if no ABS_X/Y exists
5c5b2c8db8 added forced x/y axes if a device
has any axes of the same mode. This was too broad a brush, some devices have
a relative wheel but absolute x/y axes and would now get misdetected as
purely relative device.

Only force relative axes if a device no rel x/y _and_ no abs x/y.

Reproducible: virtual machine with QEMU USB Tablet will stop working

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
2012-01-26 16:07:10 +10:00
Chase Douglas
bc2f01ab83 Copy last valuator values into new touch valuator masks
Evdev is a 100% stateful protocol. The following represents three
touches. Two touches begin and end at the same time at (500, 500) and
(1000, 1000). The third touch begins after the first two end, and is at
(500, 500).

ABS_MT_SLOT		0	/* Set touch slot */
ABS_MT_TRACKING_ID	0	/* New touch with ID 0 in slot 0 */
ABS_MT_POSITION_X	500	/* Initial X position */
ABS_MT_POSITION_Y	500	/* Initial Y position */
ABS_MT_SLOT		1	/* Set touch slot */
ABS_MT_TRACKING_ID	1	/* New touch with ID 1 in slot 1 */
ABS_MT_POSITION_X	1000	/* Initial X position */
ABS_MT_POSITION_Y	1000	/* Initial Y position */
SYNC				/* End of frame */
ABS_MT_SLOT		0	/* Go back to slot 0 */
ABS_MT_TRACKING_ID	-1	/* Touch in slot 0 ended */
ABS_MT_SLOT		1	/* Go to slot 1 */
ABS_MT_TRACKING_ID	-1	/* Touch in slot 1 ended */
SYNC				/* End of frame */
ABS_MT_SLOT		0	/* Go back to slot 0 */
ABS_MT_TRACKING_ID	2	/* New touch in slot 0 with ID 2 */
SYNC				/* End of frame */
ABS_MT_TRACKING_ID	-1	/* Touch in last slot (0) ended */
SYNC				/* End of frame */

Note that touch 2 has the same X and Y position as touch 0. This is
implied because no new value was emitted for slot 0. In fact, Linux will
not emit an event in the same slot with the same event type and code
unless the value has changed. Thus, we can only assume that all the MT
valuators have the same values as they were when they were last sent for
the given slot.

This change adds an array of valuator mask to hold all the last valuator
values that came from evdev for each slot. When a new touch begins, all
the last values are copied into it.

This patch assumes initial axis values of 0 in each slot. Linux and
mtdev do not provide a facility to query the current values of axes in
each slot yet. This may cause spurious incorrect touch valuator values
at the beginning of an X session, but there's nothing we can do about it
right now.

Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2012-01-24 12:12:47 +10:00
Peter Hutterer
9d9c9870c8 Prefere relative axis labelling over absolute axis labelling
If a device has both relative and absolute axes, we'd initialise the
relative axes but label them with the absolute labels.

The current code is broken for mixed mode devices. Most of these devices
operate primarily in relative mode, but have some absolute axes available
for secondary functionality. For now, label the relative axes properly. We
can fix the absolute axes later.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
2012-01-18 16:47:16 +10:00
Peter Hutterer
5c5b2c8db8 Force x/y axes to exist on devices with any other axes (#44655)
Too much in the server relies on x/y to exist and to be axes 0 and 1. So if
any relative axes exist, initialize REL_X/Y or ABS_X/Y as well.

For servers up to 1.11: a scrollwheel-only device now has relative axes
where it only had buttons before.

For servers 1.12 or later: the device now has x/y in addition to the scroll
axes.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Daniel Stone <daniel@fooishbar.org>
2012-01-17 14:33:54 +10:00
Pete Beardmore
854df75f49 missing multitouch related define tests
addition of two missing define tests required when no multitouch related
symbols are available in user-space

Fixes X.Org Bug 44578 <https://bugs.freedesktop.org/show_bug.cgi?id=44578>

Signed-off-by: Pete Beardmore <pete.beardmore@msn.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2012-01-10 10:56:45 +10:00
Chase Douglas
8c55e94a6a Set the default resolution to 0
If we don't know the resolution, set it to 0. This is invalid, and tells
the X client that we don't know the resolution, rather than reporting an
incorrect value.

This value was originally from commit
6271494faa, which is the initial commit
from Adam Jackson adding absolute axis support.

Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2012-01-06 12:17:00 +10:00
Peter Hutterer
965338e9d0 Remove unused udev.c
Added in 683a55e504 due to a botched up
rebase -i. The contents of udev.c and EvdevIsVirtual are identical, there is
no need for an extra file for this one function.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2012-01-03 08:44:27 +10:00
Cyril Brulebois
0075da20d6 configure.ac: Fix udev/libudev dependency.
In 683a55e504, a dependency on libudev was
added, but documented in configure.ac as a dependency on udev (which
also happens to ship a pkg-config file).

Signed-off-by: Cyril Brulebois <kibi@debian.org>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2012-01-03 08:40:02 +10:00
Jeremy Huddleston
009ac94a8e Remove redundant redeclaration of Evdev3BEmuPreInit
Found-by: Tinderbox
Signed-off-by: Jeremy Huddleston <jeremyhu@apple.com>
2011-12-31 21:28:53 -05:00
6 changed files with 221 additions and 148 deletions

View File

@@ -23,7 +23,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-input-evdev],
[2.6.99.901],
[2.7.3],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
[xf86-input-evdev])
AC_CONFIG_SRCDIR([Makefile.am])
@@ -46,7 +46,7 @@ XORG_DEFAULT_OPTIONS
# Obtain compiler/linker options from server and required extensions
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.10] xproto inputproto)
PKG_CHECK_MODULES(UDEV, udev)
PKG_CHECK_MODULES(UDEV, libudev)
PKG_CHECK_MODULES(XI22, [inputproto >= 2.1.99.3] [xorg-server >= 1.11.99.901], HAVE_XI22="yes", HAVE_XI22="no")

View File

@@ -30,7 +30,7 @@ AM_CPPFLAGS =-I$(top_srcdir)/include
@DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
@DRIVER_NAME@_drv_la_LIBADD = $(MTDEV_LIBS)
@DRIVER_NAME@_drv_la_LIBADD = $(MTDEV_LIBS) $(UDEV_LIBS)
@DRIVER_NAME@_drv_ladir = @inputdir@
@DRIVER_NAME@_drv_la_SOURCES = @DRIVER_NAME@.c \

View File

@@ -51,7 +51,6 @@ static Atom prop_wheel_timeout = 0;
static Atom prop_wheel_button = 0;
/* Local Funciton Prototypes */
static BOOL EvdevWheelEmuHandleButtonMap(InputInfoPtr pInfo, WheelAxisPtr pAxis, char *axis_name);
static int EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value);
/* Filter mouse button events */
@@ -197,7 +196,8 @@ EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value)
/* Handle button mapping here to avoid code duplication,
returns true if a button mapping was found. */
static BOOL
EvdevWheelEmuHandleButtonMap(InputInfoPtr pInfo, WheelAxisPtr pAxis, char* axis_name)
EvdevWheelEmuHandleButtonMap(InputInfoPtr pInfo, WheelAxisPtr pAxis,
const char *axis_name)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
char *option_string;

View File

@@ -93,7 +93,7 @@
#define ABS_MT_TRACKING_ID 0x39
#endif
static char *evdevDefaults[] = {
static const char *evdevDefaults[] = {
"XkbRules", "evdev",
"XkbModel", "evdev",
"XkbLayout", "us",
@@ -119,8 +119,9 @@ static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode);
static BOOL EvdevGrabDevice(InputInfoPtr pInfo, int grab, int ungrab);
static void EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4]);
static int EvdevOpenDevice(InputInfoPtr pInfo);
static void EvdevCloseDevice(InputInfoPtr pInfo);
static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
static void EvdevInitAxesLabels(EvdevPtr pEvdev, int mode, int natoms, Atom *atoms);
static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
static void EvdevInitProperty(DeviceIntPtr dev);
static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
@@ -277,7 +278,7 @@ EvdevRemoveDevice(InputInfoPtr pInfo)
static void
SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
SetXkbOption(InputInfoPtr pInfo, const char *name, char **option)
{
char *s;
@@ -746,6 +747,24 @@ EvdevProcessTouch(InputInfoPtr pInfo)
valuator_mask_zero(pEvdev->mt_mask);
}
static int
num_slots(EvdevPtr pEvdev)
{
int value = pEvdev->absinfo[ABS_MT_SLOT].maximum -
pEvdev->absinfo[ABS_MT_SLOT].minimum + 1;
/* If we don't know how many slots there are, assume at least 10 */
return value > 1 ? value : 10;
}
static int
last_mt_vals_slot(EvdevPtr pEvdev)
{
int value = pEvdev->cur_slot - pEvdev->absinfo[ABS_MT_SLOT].minimum;
return value < num_slots(pEvdev) ? value : -1;
}
static void
EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
{
@@ -757,16 +776,29 @@ EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
pEvdev->cur_slot = ev->value;
} else
{
int slot_index = last_mt_vals_slot(pEvdev);
if (pEvdev->slot_state == SLOTSTATE_EMPTY)
pEvdev->slot_state = SLOTSTATE_UPDATE;
if (ev->code == ABS_MT_TRACKING_ID) {
if (ev->value >= 0)
pEvdev->slot_state = SLOTSTATE_OPEN;
else
pEvdev->slot_state = SLOTSTATE_CLOSE;
if (ev->value >= 0) {
pEvdev->slot_state = SLOTSTATE_OPEN;
if (slot_index >= 0)
valuator_mask_copy(pEvdev->mt_mask,
pEvdev->last_mt_vals[slot_index]);
else
xf86IDrvMsg(pInfo, X_WARNING,
"Attempted to copy values from out-of-range "
"slot, touch events may be incorrect.\n");
} else
pEvdev->slot_state = SLOTSTATE_CLOSE;
} else {
map = pEvdev->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);
}
}
}
@@ -1027,6 +1059,30 @@ EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
#undef ABS_Y_VALUE
#undef ABS_VALUE
static void
EvdevFreeMasks(EvdevPtr pEvdev)
{
#ifdef MULTITOUCH
int i;
#endif
valuator_mask_free(&pEvdev->vals);
valuator_mask_free(&pEvdev->old_vals);
valuator_mask_free(&pEvdev->prox);
#ifdef MULTITOUCH
valuator_mask_free(&pEvdev->mt_mask);
if (pEvdev->last_mt_vals)
{
for (i = 0; i < num_slots(pEvdev); i++)
valuator_mask_free(&pEvdev->last_mt_vals[i]);
free(pEvdev->last_mt_vals);
pEvdev->last_mt_vals = NULL;
}
for (i = 0; i < EVDEV_MAXQUEUE; i++)
valuator_mask_free(&pEvdev->queue[i].touchMask);
#endif
}
/* just a magic number to reduce the number of reads */
#define NUM_EVENTS 16
@@ -1051,13 +1107,8 @@ EvdevReadInput(InputInfoPtr pInfo)
if (len <= 0)
{
if (errno == ENODEV) /* May happen after resume */
{
EvdevMBEmuFinalize(pInfo);
Evdev3BEmuFinalize(pInfo);
xf86RemoveEnabledDevice(pInfo);
close(pInfo->fd);
pInfo->fd = -1;
} else if (errno != EAGAIN)
else if (errno != EAGAIN)
{
/* We use X_NONE here because it doesn't alloc */
xf86MsgVerb(X_NONE, 0, "%s: Read error: %s\n", pInfo->name,
@@ -1143,6 +1194,7 @@ EvdevAddKeyClass(DeviceIntPtr device)
return Success;
}
#ifdef MULTITOUCH
/* MT axes are counted twice - once as ABS_X (which the kernel keeps for
* backwards compatibility), once as ABS_MT_POSITION_X. So we need to keep a
* mapping of those axes to make sure we only count them once
@@ -1160,6 +1212,7 @@ static struct mt_axis_mappings mt_axis_mappings[] = {
{ABS_MT_PRESSURE, ABS_PRESSURE},
{ABS_MT_DISTANCE, ABS_DISTANCE},
};
#endif
/**
* return TRUE if the axis is not one we should count as true axis
@@ -1249,6 +1302,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
}
#ifdef MULTITOUCH
if (num_mt_axes_total > 0) {
pEvdev->num_mt_vals = num_mt_axes_total;
pEvdev->mt_mask = valuator_mask_new(num_mt_axes_total);
if (!pEvdev->mt_mask) {
xf86Msg(X_ERROR, "%s: failed to allocate MT valuator mask.\n",
@@ -1256,6 +1310,24 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
goto out;
}
pEvdev->last_mt_vals = calloc(num_slots(pEvdev), sizeof(ValuatorMask *));
if (!pEvdev->last_mt_vals) {
xf86IDrvMsg(pInfo, X_ERROR,
"%s: failed to allocate MT last values mask array.\n",
device->name);
goto out;
}
for (i = 0; i < num_slots(pEvdev); i++) {
pEvdev->last_mt_vals[i] = valuator_mask_new(num_mt_axes_total);
if (!pEvdev->last_mt_vals[i]) {
xf86IDrvMsg(pInfo, X_ERROR,
"%s: failed to allocate MT last values mask.\n",
device->name);
goto out;
}
}
for (i = 0; i < EVDEV_MAXQUEUE; i++) {
pEvdev->queue[i].touchMask =
valuator_mask_new(num_mt_axes_total);
@@ -1271,7 +1343,9 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
i = 0;
for (axis = ABS_X; i < MAX_VALUATORS && axis <= ABS_MAX; axis++) {
#ifdef MULTITOUCH
int j;
#endif
int mapping;
pEvdev->axis_map[axis] = -1;
if (!EvdevBitIsSet(pEvdev->abs_bitmask, axis) ||
@@ -1280,6 +1354,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
mapping = i;
#ifdef MULTITOUCH
for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
{
if (mt_axis_mappings[j].code == axis)
@@ -1288,13 +1363,13 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
mt_axis_mappings[j].needs_mapping)
mapping = mt_axis_mappings[j].mapping;
}
#endif
pEvdev->axis_map[axis] = mapping;
if (mapping == i)
i++;
}
EvdevInitAxesLabels(pEvdev, pEvdev->num_vals + num_mt_axes, atoms);
EvdevInitAxesLabels(pEvdev, Absolute, pEvdev->num_vals + num_mt_axes, atoms);
if (!InitValuatorClassDeviceStruct(device, num_axes + num_mt_axes, atoms,
GetMotionHistorySize(), Absolute)) {
@@ -1310,7 +1385,8 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
XIDependentTouch : XIDirectTouch;
if (pEvdev->mtdev->caps.slot.maximum > 0)
num_touches = pEvdev->mtdev->caps.slot.maximum;
num_touches = pEvdev->mtdev->caps.slot.maximum -
pEvdev->mtdev->caps.slot.minimum + 1;
if (!InitTouchClassDeviceStruct(device, num_touches, mode,
num_mt_axes_total)) {
@@ -1318,12 +1394,23 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
device->name);
goto out;
}
for (i = 0; i < num_slots(pEvdev); i++) {
for (axis = ABS_MT_TOUCH_MAJOR; axis < ABS_MAX; axis++) {
if (pEvdev->axis_map[axis] >= 0) {
/* XXX: read initial values from mtdev when it adds support
* for doing so. */
valuator_mask_set(pEvdev->last_mt_vals[i],
pEvdev->axis_map[axis], 0);
}
}
}
}
#endif
for (axis = ABS_X; axis < ABS_MT_SLOT; axis++) {
int axnum = pEvdev->axis_map[axis];
int resolution = 10000;
int resolution = 0;
if (axnum == -1)
continue;
@@ -1345,7 +1432,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
#ifdef MULTITOUCH
for (axis = ABS_MT_TOUCH_MAJOR; axis <= ABS_MAX; axis++) {
int axnum = pEvdev->axis_map[axis];
int resolution = 10000;
int resolution = 0;
int j;
BOOL skip = FALSE;
@@ -1423,14 +1510,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
return Success;
out:
valuator_mask_free(&pEvdev->vals);
valuator_mask_free(&pEvdev->old_vals);
valuator_mask_free(&pEvdev->prox);
#ifdef MULTITOUCH
valuator_mask_free(&pEvdev->mt_mask);
for (i = 0; i < EVDEV_MAXQUEUE; i++)
valuator_mask_free(&pEvdev->queue[i].touchMask);
#endif
EvdevFreeMasks(pEvdev);
return !Success;
}
@@ -1493,7 +1573,7 @@ EvdevAddRelValuatorClass(DeviceIntPtr device)
i++;
}
EvdevInitAxesLabels(pEvdev, pEvdev->num_vals, atoms);
EvdevInitAxesLabels(pEvdev, Relative, pEvdev->num_vals, atoms);
if (!InitValuatorClassDeviceStruct(device, num_axes, atoms,
GetMotionHistorySize(), Relative)) {
@@ -1522,7 +1602,7 @@ EvdevAddRelValuatorClass(DeviceIntPtr device)
else if (axis == REL_DIAL)
SetScrollValuator(device, axnum, SCROLL_TYPE_VERTICAL, -1.0, SCROLL_FLAG_NONE);
else if (axis == REL_HWHEEL)
SetScrollValuator(device, axnum, SCROLL_TYPE_HORIZONTAL, -1.0, SCROLL_FLAG_NONE);
SetScrollValuator(device, axnum, SCROLL_TYPE_HORIZONTAL, 1.0, SCROLL_FLAG_NONE);
#endif
}
@@ -1580,12 +1660,12 @@ EvdevInitButtonMapping(InputInfoPtr pInfo)
/* Check for user-defined button mapping */
if ((mapping = xf86CheckStrOption(pInfo->options, "ButtonMapping", NULL)))
{
char *map, *s = " ";
char *map, *s = NULL;
int btn = 0;
xf86IDrvMsg(pInfo, X_CONFIG, "ButtonMapping '%s'\n", mapping);
map = mapping;
while (s && *s != '\0' && nbuttons < EVDEV_MAXBUTTONS)
do
{
btn = strtol(map, &s, 10);
@@ -1599,7 +1679,7 @@ EvdevInitButtonMapping(InputInfoPtr pInfo)
pEvdev->btnmap[nbuttons++] = btn;
map = s;
}
} while (s && *s != '\0' && nbuttons < EVDEV_MAXBUTTONS);
free(mapping);
}
@@ -1764,9 +1844,6 @@ EvdevProc(DeviceIntPtr device, int what)
{
InputInfoPtr pInfo;
EvdevPtr pEvdev;
#ifdef MULTITOUCH
int i;
#endif
pInfo = device->public.devicePrivate;
pEvdev = pInfo->private;
@@ -1789,8 +1866,7 @@ EvdevProc(DeviceIntPtr device, int what)
{
EvdevGrabDevice(pInfo, 0, 1);
xf86RemoveEnabledDevice(pInfo);
close(pInfo->fd);
pInfo->fd = -1;
EvdevCloseDevice(pInfo);
}
pEvdev->min_maj = 0;
pEvdev->flags &= ~EVDEV_INITIALIZED;
@@ -1799,20 +1875,8 @@ EvdevProc(DeviceIntPtr device, int what)
case DEVICE_CLOSE:
xf86IDrvMsg(pInfo, X_INFO, "Close\n");
if (pInfo->fd != -1) {
close(pInfo->fd);
pInfo->fd = -1;
}
valuator_mask_free(&pEvdev->vals);
valuator_mask_free(&pEvdev->old_vals);
valuator_mask_free(&pEvdev->prox);
#ifdef MULTITOUCH
valuator_mask_free(&pEvdev->mt_mask);
for (i = 0; i < EVDEV_MAXQUEUE; i++)
valuator_mask_free(&pEvdev->queue[i].touchMask);
if (pEvdev->mtdev)
mtdev_close(pEvdev->mtdev);
#endif
EvdevCloseDevice(pInfo);
EvdevFreeMasks(pEvdev);
EvdevRemoveDevice(pInfo);
pEvdev->min_maj = 0;
break;
@@ -1955,6 +2019,38 @@ EvdevGrabDevice(InputInfoPtr pInfo, int grab, int ungrab)
return TRUE;
}
/**
* Some devices only have other axes (e.g. wheels), but we
* still need x/y for these. The server relies on devices having
* x/y as axes 0/1 and core/XI 1.x clients expect it too (#44655)
*/
static void
EvdevForceXY(InputInfoPtr pInfo, int mode)
{
EvdevPtr pEvdev = pInfo->private;
xf86IDrvMsg(pInfo, X_INFO, "Forcing %s x/y axes to exist.\n",
(mode == Relative) ? "relative" : "absolute");
if (mode == Relative)
{
EvdevSetBit(pEvdev->rel_bitmask, REL_X);
EvdevSetBit(pEvdev->rel_bitmask, REL_Y);
} else if (mode == Absolute)
{
EvdevSetBit(pEvdev->abs_bitmask, ABS_X);
EvdevSetBit(pEvdev->abs_bitmask, ABS_Y);
pEvdev->absinfo[ABS_X].minimum = 0;
pEvdev->absinfo[ABS_X].maximum = 1000;
pEvdev->absinfo[ABS_X].value = 0;
pEvdev->absinfo[ABS_X].resolution = 0;
pEvdev->absinfo[ABS_Y].minimum = 0;
pEvdev->absinfo[ABS_Y].maximum = 1000;
pEvdev->absinfo[ABS_Y].value = 0;
pEvdev->absinfo[ABS_Y].resolution = 0;
}
}
static int
EvdevProbe(InputInfoPtr pInfo)
{
@@ -2048,7 +2144,9 @@ EvdevProbe(InputInfoPtr pInfo)
if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_X) &&
EvdevBitIsSet(pEvdev->rel_bitmask, REL_Y)) {
xf86IDrvMsg(pInfo, X_PROBED, "Found x and y relative axes\n");
}
} else if (!EvdevBitIsSet(pEvdev->abs_bitmask, ABS_X) ||
!EvdevBitIsSet(pEvdev->abs_bitmask, ABS_Y))
EvdevForceXY(pInfo, Relative);
} else {
xf86IDrvMsg(pInfo, X_INFO, "Relative axes present but ignored.\n");
has_rel_axes = FALSE;
@@ -2113,7 +2211,16 @@ EvdevProbe(InputInfoPtr pInfo)
pEvdev->flags |= EVDEV_TOUCHSCREEN;
pEvdev->flags |= EVDEV_BUTTON_EVENTS;
}
} else {
#ifdef MULTITOUCH
if (!EvdevBitIsSet(pEvdev->abs_bitmask, ABS_MT_POSITION_X) ||
!EvdevBitIsSet(pEvdev->abs_bitmask, ABS_MT_POSITION_Y))
#endif
EvdevForceXY(pInfo, Absolute);
}
}
for (i = 0; i < BTN_MISC; i++) {
@@ -2162,6 +2269,9 @@ EvdevProbe(InputInfoPtr pInfo)
xf86IDrvMsg(pInfo, X_INFO, "Configuring as touchscreen\n");
pInfo->type_name = XI_TOUCHSCREEN;
} else {
if (!EvdevBitIsSet(pEvdev->rel_bitmask, REL_X) ||
!EvdevBitIsSet(pEvdev->rel_bitmask, REL_Y))
EvdevForceXY(pInfo, Relative);
xf86IDrvMsg(pInfo, X_INFO, "Configuring as mouse\n");
pInfo->type_name = XI_MOUSE;
}
@@ -2240,13 +2350,16 @@ EvdevOpenDevice(InputInfoPtr pInfo)
}
#ifdef MULTITOUCH
pEvdev->mtdev = mtdev_new_open(pInfo->fd);
if (!pEvdev->mtdev) { /* after PreInit mtdev is still valid */
pEvdev->mtdev = mtdev_new_open(pInfo->fd);
if (!pEvdev->mtdev) {
xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
EvdevCloseDevice(pInfo);
return FALSE;
}
}
if (pEvdev->mtdev)
pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
else {
xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
return FALSE;
}
#endif
/* Check major/minor of device node to avoid adding duplicate devices. */
@@ -2254,17 +2367,34 @@ EvdevOpenDevice(InputInfoPtr pInfo)
if (EvdevIsDuplicate(pInfo))
{
xf86IDrvMsg(pInfo, X_WARNING, "device file is duplicate. Ignoring.\n");
close(pInfo->fd);
#ifdef MULTITOUCH
mtdev_close_delete(pEvdev->mtdev);
pEvdev->mtdev = NULL;
#endif
EvdevCloseDevice(pInfo);
return BadMatch;
}
return Success;
}
static void
EvdevCloseDevice(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
if (pInfo->fd >= 0)
{
close(pInfo->fd);
pInfo->fd = -1;
}
#ifdef MULTITOUCH
if (pEvdev->mtdev)
{
mtdev_close_delete(pEvdev->mtdev);
pEvdev->mtdev = NULL;
}
#endif
}
static void
EvdevUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
{
@@ -2345,8 +2475,7 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
return Success;
error:
if (pInfo->fd >= 0)
close(pInfo->fd);
EvdevCloseDevice(pInfo);
return rc;
}
@@ -2435,7 +2564,7 @@ EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code)
/* Aligned with linux/input.h.
Note that there are holes in the ABS_ range, these are simply replaced with
MISC here */
static char* abs_labels[] = {
static const char *abs_labels[] = {
AXIS_LABEL_PROP_ABS_X, /* 0x00 */
AXIS_LABEL_PROP_ABS_Y, /* 0x01 */
AXIS_LABEL_PROP_ABS_Z, /* 0x02 */
@@ -2498,7 +2627,7 @@ static char* abs_labels[] = {
AXIS_LABEL_PROP_ABS_MT_PRESSURE, /* 0x3a */
};
static char* rel_labels[] = {
static const char *rel_labels[] = {
AXIS_LABEL_PROP_REL_X,
AXIS_LABEL_PROP_REL_Y,
AXIS_LABEL_PROP_REL_Z,
@@ -2511,7 +2640,7 @@ static char* rel_labels[] = {
AXIS_LABEL_PROP_REL_MISC
};
static char* btn_labels[][16] = {
static const char *btn_labels[][16] = {
{ /* BTN_MISC group offset 0x100*/
BTN_LABEL_PROP_BTN_0, /* 0x00 */
BTN_LABEL_PROP_BTN_1, /* 0x01 */
@@ -2592,18 +2721,18 @@ static char* btn_labels[][16] = {
}
};
static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms)
static void EvdevInitAxesLabels(EvdevPtr pEvdev, int mode, int natoms, Atom *atoms)
{
Atom atom;
int axis;
char **labels;
const char **labels;
int labels_len = 0;
if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
if (mode == Absolute)
{
labels = abs_labels;
labels_len = ArrayLength(abs_labels);
} else if ((pEvdev->flags & EVDEV_RELATIVE_EVENTS))
} else if (mode == Relative)
{
labels = rel_labels;
labels_len = ArrayLength(rel_labels);
@@ -2765,10 +2894,22 @@ EvdevInitProperty(DeviceIntPtr dev)
/* Axis labelling */
if ((pEvdev->num_vals > 0) && (prop_axis_label = XIGetKnownProperty(AXIS_LABEL_PROP)))
{
Atom atoms[pEvdev->num_vals];
EvdevInitAxesLabels(pEvdev, pEvdev->num_vals, atoms);
int mode;
int num_axes = pEvdev->num_vals + pEvdev->num_mt_vals;
Atom atoms[num_axes];
if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
mode = Absolute;
else if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
mode = Relative;
else {
xf86IDrvMsg(pInfo, X_ERROR, "BUG: mode is neither absolute nor relative\n");
mode = Absolute;
}
EvdevInitAxesLabels(pEvdev, mode, num_axes, atoms);
XIChangeDeviceProperty(dev, prop_axis_label, XA_ATOM, 32,
PropModeReplace, pEvdev->num_vals, atoms, FALSE);
PropModeReplace, num_axes, atoms, FALSE);
XISetDevicePropertyDeletable(dev, prop_axis_label, FALSE);
}
/* Button labelling */

View File

@@ -153,11 +153,13 @@ typedef struct {
int grabDevice; /* grab the event device? */
int num_vals; /* number of valuators */
int num_mt_vals; /* number of multitouch valuators */
int axis_map[max(ABS_CNT, REL_CNT)]; /* Map evdev <axis> to index */
ValuatorMask *vals; /* new values coming in */
ValuatorMask *old_vals; /* old values for calculating relative motion */
ValuatorMask *prox; /* last values set while not in proximity */
ValuatorMask *mt_mask;
ValuatorMask **last_mt_vals;
int cur_slot;
enum SlotState slot_state;
#ifdef MULTITOUCH
@@ -278,7 +280,6 @@ void EvdevMBEmuFinalize(InputInfoPtr);
CARD32 Evdev3BEmuTimer(OsTimerPtr timer, CARD32 time, pointer arg);
BOOL Evdev3BEmuFilterEvent(InputInfoPtr, int, BOOL);
void Evdev3BEmuPreInit(InputInfoPtr pInfo);
void Evdev3BEmuPreInit(InputInfoPtr);
void Evdev3BEmuOn(InputInfoPtr);
void Evdev3BEmuFinalize(InputInfoPtr);
void Evdev3BEmuProcessRelMotion(InputInfoPtr pInfo, int dx, int dy);

View File

@@ -1,69 +0,0 @@
/*
* Copyright © 2011 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of Red Hat
* not be used in advertising or publicity pertaining to distribution
* of the software without specific, written prior permission. Red
* Hat makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied
* warranty.
*
* THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Authors:
* Peter Hutterer (peter.hutterer@redhat.com)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "evdev.h"
#include <libudev.h>
#include <sys/types.h>
#include <sys/stat.h>
Bool
udev_device_is_virtual(const char* devicenode)
{
struct udev *udev = NULL;
struct udev_device *device = NULL;
struct stat st;
int rc = FALSE;
const char *devpath;
udev = udev_new();
if (!udev)
goto out;
stat(devicenode, &st);
device = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
if (!device)
goto out;
devpath = udev_device_get_devpath(device);
if (!devpath)
goto out;
if (strstr(devpath, "LNXSYSTM"))
rc = TRUE;
out:
udev_device_unref(device);
udev_unref(udev);
return rc;
}