Compare commits

...

22 Commits

Author SHA1 Message Date
Peter Hutterer
f48abf89e4 evdev 2.1.3
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2009-02-17 16:17:30 +10:00
Peter Hutterer
87819fe86b man: Fix two minor typos in man page.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 0de20a8f1b)
2009-02-17 16:11:06 +10:00
Peter Hutterer
ffa1fbc770 Log which EVIOCGABS ioctl failed.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 95099cb036)
2009-02-17 16:08:47 +10:00
Peter Hutterer
40bb3c69ce Remove duplicate MB emu finalization.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 32242871f7)
2009-02-17 16:08:42 +10:00
Bryce Harrington
675218cbf5 Add descriptive messages for device-has-changed errs
As can be seen in e.g. bugs 19819 & 20025, it can be unclear what
exactly caused a given "Device has changed - disabled" error.  This
patch adds some more specific messages to give a better clue on what
exactly was seen to have changed.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 2a6c1d7a60)
2009-02-13 13:19:59 +10:00
Julien Plissonneau Duquene
ad834abd57 EvdevCacheCompare: ignore changes in current device position
Input devices (especially touchscreens) were disabled when switching
virtual console back to X because EvdevCacheCompare() thought the device
was substituted by another while away from X. Actually only the current
position reported by the device changed from what was in the cache. Fixed
by ignoring the current position in the comparison.

Fixes bug #19819.

Signed-off-by: Julien Cristau <jcristau@debian.org>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 0dbb88c52b)
2009-02-13 13:19:50 +10:00
Peter Breitenlohner
3549c3e5f0 fix manpage formatting
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit c928156702)
2009-02-13 13:19:46 +10:00
Peter Hutterer
5def56d2f4 evdev 2.1.2
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2009-02-02 11:13:10 +10:00
Peter Hutterer
b907c23d00 Protect against zero-sized property values. #19882
X.Org Bug 19882 <http://bugs.freedesktop.org/show_bug.cgi?id=19882>

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 07f40a04df)
2009-02-02 11:12:28 +10:00
Alan Coopersmith
6c975917f8 Add README with pointers to mailing list, bugzilla & git repos
(cherry picked from commit e260993b6a)
2009-02-02 11:12:25 +10:00
Peter Hutterer
ac421e536c Reshuffle property initialization.
We don't need axis calibration, etc. on keyboards, so let's do it
conditionally on actually having axes.

Reported by Simon Thum.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 1906e4d5c1)

Conflicts:

	src/evdev.c
2009-01-22 15:20:05 +11:00
Peter Hutterer
bd55c2f021 Don't print xkb options twice to the log file.
xf86SetStrOption already prints with X_CONFIG anyway, no need to do it again.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 263bf04a9d)
2009-01-22 15:18:45 +11:00
Peter Hutterer
11d506dce6 evdev 2.1.1 2009-01-13 11:36:14 +10:00
Michael Chapman
a34a2cd347 Disable middle mouse button emulation when a middle mouse button event is registered
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 0592d97fbb)
2009-01-13 11:36:14 +10:00
Matt Helsley
78c00bd77f Fix FOO_MAX off-by-one
In linux/input.h each section's (e.g. ABS) FOO_MAX is the maximum FOO
value. Recent kernels define FOO_CNT as the maximum number of FOO there
will ever be. Hence using FOO_MAX to size the bit vectors representing
the capabilities of an evdev device is off by one.

Define FOO_CNT values for use with Linux kernels which lack them. Use
FOO_CNT whenever we need to know the number of bits needed -- usually to
calculate the number of longs needed.

When iterating over the values FOO_MAX still seems appropriate however
the loop test should include FOO_MAX rather than skip it.

Signed-off-by: Matt Helsley <matt.helsley@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 4dfd86b220)

Conflicts:

	src/evdev.c
2009-01-13 11:36:13 +10:00
Matt Helsley
760f1c6bb1 rename NBITS to NLONGS to reflect its actual meaning
NBITS really convers the number of bits passed as its argument
into a number of longs. This is somewhat atypical of many
function-like-macro names. Rename it to NLONGS.

Signed-off-by: Matt Helsley <matt.helsley@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

(cherry-picked from commit d3fd42d864)
Not really required, but it makes cherry-picking
4dfd86b220 easier.
2009-01-13 11:36:13 +10:00
Alan Coopersmith
2db04ba3c3 Remove xorgconfig & xorgcfg from See Also list in man page
(cherry picked from commit 0f0a149067)
2009-01-13 11:36:13 +10:00
Yan Li
363d0bdb9f Fix XkbModel parsing error
Signed-off-by: Yan Li <yan.i.li@intel.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit d170cba0cd)
2009-01-13 11:36:13 +10:00
Peter Hutterer
16a26a1eca Finalize MB emu (and wakeup handlers) before closing the fd.
Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
(cherry picked from commit 2bf6e29b40)
2009-01-13 11:36:13 +10:00
Peter Hutterer
b879ae7351 evdev 2.1 2008-11-18 15:21:01 +10:00
Peter Hutterer
53566b7d4d Store device file's minor/major to avoid duplicate devices.
Devices added that use the same min/maj as an already added device are ignored
by the driver. This way users can have an xorg.conf entry on
/dev/input/by-id/blahblah and not get the same device added by HAL.

Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
(cherry picked from commit 63af314368)
2008-11-18 15:13:34 +10:00
Fernando Carrijo
29c2765fc3 Fix error message
(cherry picked from commit 4c5c9c111d)
2008-11-11 14:37:45 +10:00
8 changed files with 264 additions and 82 deletions

20
README Normal file
View File

@@ -0,0 +1,20 @@
xf86-input-evdev - Generic Linux input driver for the Xorg X server
Please submit bugs & patches to the Xorg bugzilla:
https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
All questions regarding this software should be directed at the
Xorg mailing list:
http://lists.freedesktop.org/mailman/listinfo/xorg
The master development code repository can be found at:
git://anongit.freedesktop.org/git/xorg/driver/xf86-input-evdev
http://cgit.freedesktop.org/xorg/driver/xf86-input-evdev
For more information on the git code manager, see:
http://wiki.x.org/wiki/GitPage

View File

@@ -22,7 +22,7 @@
AC_PREREQ(2.57)
AC_INIT([xf86-input-evdev],
2.0.99.3,
2.1.3,
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
xf86-input-evdev)

View File

@@ -155,7 +155,7 @@ Force a grab on the event device. Doing so will ensure that no other driver
can initialise the same device and it will also stop the device from sending
events to /dev/kbd or /dev/input/mice. Events from this device will not be
sent to virtual devices (e.g. rfkill or the Macintosh mouse button emulation).
Default disabled.
Default: disabled.
.SH SUPPORTED PROPERTIES
The following properties are provided by the
@@ -189,6 +189,7 @@ value.
.TP 7
.BI "Evdev Axis Inversion"
2 boolean values (8 bit, 0 or 1), order X, Y. 1 inverts the axis.
.TP 7
.BI "Evdev Axis Calibration"
4 32-bit values, order min-x, max-x, min-y, max-y or 0 values to disable
run-time axis calibration. This feature is required for devices that need to
@@ -196,10 +197,10 @@ scale to a different coordinate system than originally reported to the X
server, such as touchscreens that require run-time calibration.
.TP 7
.BI "Evdev Axis Swap"
1 boolean values (8 bit, 0 or 1). 1 swaps x/y axes.
1 boolean value (8 bit, 0 or 1). 1 swaps x/y axes.
.SH AUTHORS
Kristian Høgsberg.
.SH "SEE ALSO"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__),
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__),
README.mouse.

View File

@@ -243,7 +243,9 @@ EvdevDragLockSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
return BadValue;
}
if (val->size == 1)
if (val->size == 0)
return BadMatch;
else if (val->size == 1)
{
int meta = *((CARD8*)val->data);
if (meta > EVDEV_MAXBUTTONS)

View File

@@ -231,6 +231,11 @@ EvdevMBEmuFilterEvent(InputInfoPtr pInfo, int button, BOOL press)
if (!pEvdev->emulateMB.enabled)
return ret;
if (button == 2) {
EvdevMBEmuEnable(pInfo, FALSE);
return ret;
}
/* don't care about other buttons */
if (button != 1 && button != 3)
return ret;

View File

@@ -350,11 +350,13 @@ EvdevWheelEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
}
else if (atom == prop_wheel_button)
{
int bt = *((CARD8*)val->data);
int bt;
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
bt = *((CARD8*)val->data);
if (bt < 0 || bt >= EVDEV_MAXBUTTONS)
return BadValue;
@@ -374,11 +376,13 @@ EvdevWheelEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
}
} else if (atom == prop_wheel_inertia)
{
int inertia = *((CARD16*)val->data);
int inertia;
if (val->format != 16 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
inertia = *((CARD16*)val->data);
if (inertia < 0)
return BadValue;
@@ -386,11 +390,13 @@ EvdevWheelEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
pEvdev->emulateWheel.inertia = inertia;
} else if (atom == prop_wheel_timeout)
{
int timeout = *((CARD16*)val->data);
int timeout;
if (val->format != 16 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
timeout = *((CARD16*)val->data);
if (timeout < 0)
return BadValue;

View File

@@ -32,6 +32,7 @@
#include <X11/keysym.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
@@ -51,6 +52,10 @@
#include <evdev-properties.h>
#endif
#ifndef MAXDEVICES
#include <inputstr.h> /* for MAX_DEVICES */
#define MAXDEVICES MAX_DEVICES
#endif
/* 2.4 compatibility */
#ifndef EVIOCGRAB
@@ -112,6 +117,88 @@ static Atom prop_calibration = 0;
static Atom prop_swap = 0;
#endif
/* 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] = {0};
static int
EvdevGetMajorMinor(InputInfoPtr pInfo)
{
struct stat st;
if (fstat(pInfo->fd, &st) == -1)
{
xf86Msg(X_ERROR, "%s: stat failed (%s). cannot check for duplicates.\n",
pInfo->name, strerror(errno));
return 0;
}
return st.st_rdev;
}
/**
* Return TRUE if one of the devices we know about has the same min/maj
* number.
*/
static BOOL
EvdevIsDuplicate(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
EvdevPtr* dev = evdev_devices;
if (pEvdev->min_maj)
{
while(*dev)
{
if ((*dev) != pEvdev &&
(*dev)->min_maj &&
(*dev)->min_maj == pEvdev->min_maj)
return TRUE;
dev++;
}
}
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 void
SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
@@ -124,7 +211,6 @@ SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
*option = NULL;
} else {
*option = s;
xf86Msg(X_CONFIG, "%s: %s: \"%s\"\n", pInfo->name, name, s);
}
}
}
@@ -149,7 +235,7 @@ static void
PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
{
int code = ev->code + MIN_KEYCODE;
static char warned[KEY_MAX];
static char warned[KEY_CNT];
/* filter repeat events for chording keys */
if (value == 2 &&
@@ -161,7 +247,7 @@ PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
ev->code == KEY_SCROLLLOCK)) /* XXX windows keys? */
return;
if (code > 255 && ev->code < KEY_MAX) {
if (code > 255 && ev->code <= KEY_MAX) {
if (!warned[ev->code])
xf86Msg(X_WARNING, "%s: unable to handle keycode %d\n",
pInfo->name, ev->code);
@@ -205,6 +291,7 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
DisableDevice(pInfo->dev);
close(pInfo->fd);
pInfo->fd = -1;
pEvdev->min_maj = 0; /* don't hog the device */
}
pEvdev->reopen_left = 0;
return 0;
@@ -217,6 +304,7 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
xf86Msg(X_ERROR, "%s: Failed to reopen device after %d attempts.\n",
pInfo->name, pEvdev->reopen_attempts);
DisableDevice(pInfo->dev);
pEvdev->min_maj = 0; /* don't hog the device */
return 0;
}
@@ -765,7 +853,7 @@ EvdevAddKeyClass(DeviceIntPtr device)
SetXkbOption(pInfo, "xkb_rules", &pEvdev->xkb_rules);
SetXkbOption(pInfo, "xkb_model", &pEvdev->xkb_model);
if (!pEvdev->xkb_model)
SetXkbOption(pInfo, "XkbModel", &pEvdev->xkb_rules);
SetXkbOption(pInfo, "XkbModel", &pEvdev->xkb_model);
SetXkbOption(pInfo, "xkb_layout", &pEvdev->xkb_layout);
if (!pEvdev->xkb_layout)
SetXkbOption(pInfo, "XkbLayout", &pEvdev->xkb_layout);
@@ -803,13 +891,13 @@ EvdevAddAbsClass(DeviceIntPtr device)
if (ioctl(pInfo->fd,
EVIOCGABS(ABS_X), &absinfo_x) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGABS failed: %s\n", strerror(errno));
xf86Msg(X_ERROR, "ioctl EVIOCGABS ABS_X failed: %s\n", strerror(errno));
return !Success;
}
if (ioctl(pInfo->fd,
EVIOCGABS(ABS_Y), &absinfo_y) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGABS failed: %s\n", strerror(errno));
xf86Msg(X_ERROR, "ioctl EVIOCGABS ABS_Y failed: %s\n", strerror(errno));
return !Success;
}
@@ -1024,6 +1112,14 @@ EvdevOn(DeviceIntPtr device)
pEvdev->reopen_timer = TimerSet(NULL, 0, 100, EvdevReopenTimer, pInfo);
} else
{
pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
if (EvdevIsDuplicate(pInfo))
{
xf86Msg(X_WARNING, "%s: Refusing to enable duplicate device.\n",
pInfo->name);
return !Success;
}
xf86FlushInput(pInfo->fd);
xf86AddEnabledDevice(pInfo);
EvdevMBEmuOn(pInfo);
@@ -1053,6 +1149,8 @@ EvdevProc(DeviceIntPtr device, int what)
return EvdevOn(device);
case DEVICE_OFF:
if (pEvdev->flags & EVDEV_INITIALIZED)
EvdevMBEmuFinalize(pInfo);
if (pInfo->fd != -1)
{
if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
@@ -1062,8 +1160,7 @@ EvdevProc(DeviceIntPtr device, int what)
close(pInfo->fd);
pInfo->fd = -1;
}
if (pEvdev->flags & EVDEV_INITIALIZED)
EvdevMBEmuFinalize(pInfo);
pEvdev->min_maj = 0;
pEvdev->flags &= ~EVDEV_INITIALIZED;
device->public.on = FALSE;
if (pEvdev->reopen_timer)
@@ -1079,6 +1176,8 @@ EvdevProc(DeviceIntPtr device, int what)
close(pInfo->fd);
pInfo->fd = -1;
}
EvdevRemoveDevice(pInfo);
pEvdev->min_maj = 0;
break;
}
@@ -1100,12 +1199,12 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
int i;
char name[1024] = {0};
long bitmask[NBITS(EV_MAX)] = {0};
long key_bitmask[NBITS(KEY_MAX)] = {0};
long rel_bitmask[NBITS(REL_MAX)] = {0};
long abs_bitmask[NBITS(ABS_MAX)] = {0};
long led_bitmask[NBITS(LED_MAX)] = {0};
struct input_absinfo absinfo[ABS_MAX];
long bitmask[NLONGS(EV_CNT)] = {0};
long key_bitmask[NLONGS(KEY_CNT)] = {0};
long rel_bitmask[NLONGS(REL_CNT)] = {0};
long abs_bitmask[NLONGS(ABS_CNT)] = {0};
long led_bitmask[NLONGS(LED_CNT)] = {0};
struct input_absinfo absinfo[ABS_CNT];
if (ioctl(pInfo->fd,
EVIOCGNAME(sizeof(name) - 1), name) < 0) {
@@ -1113,70 +1212,86 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
goto error;
}
if (compare && strcmp(pEvdev->name, name))
goto error;
if (ioctl(pInfo->fd,
EVIOCGBIT(0, sizeof(bitmask)), bitmask) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
if (compare && strcmp(pEvdev->name, name)) {
xf86Msg(X_ERROR, "%s: device name changed: %s != %s\n", pInfo->name, pEvdev->name, name);
goto error;
}
if (compare && memcmp(pEvdev->bitmask, bitmask, sizeof(bitmask)))
if (ioctl(pInfo->fd,
EVIOCGBIT(0, sizeof(bitmask)), bitmask) < 0) {
xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno));
goto error;
}
if (compare && memcmp(pEvdev->bitmask, bitmask, sizeof(bitmask))) {
xf86Msg(X_ERROR, "%s: device bitmask has changed\n", pInfo->name);
goto error;
}
if (ioctl(pInfo->fd,
EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno));
goto error;
}
if (compare && memcmp(pEvdev->rel_bitmask, rel_bitmask, sizeof(rel_bitmask)))
if (compare && memcmp(pEvdev->rel_bitmask, rel_bitmask, sizeof(rel_bitmask))) {
xf86Msg(X_ERROR, "%s: device rel_bitmask has changed\n", pInfo->name);
goto error;
}
if (ioctl(pInfo->fd,
EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno));
goto error;
}
if (compare && memcmp(pEvdev->abs_bitmask, abs_bitmask, sizeof(abs_bitmask)))
if (compare && memcmp(pEvdev->abs_bitmask, abs_bitmask, sizeof(abs_bitmask))) {
xf86Msg(X_ERROR, "%s: device abs_bitmask has changed\n", pInfo->name);
goto error;
}
if (ioctl(pInfo->fd,
EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno));
goto error;
}
if (compare && memcmp(pEvdev->key_bitmask, key_bitmask, sizeof(key_bitmask)))
if (compare && memcmp(pEvdev->key_bitmask, key_bitmask, sizeof(key_bitmask))) {
xf86Msg(X_ERROR, "%s: device key_bitmask has changed\n", pInfo->name);
goto error;
}
if (ioctl(pInfo->fd,
EVIOCGBIT(EV_LED, sizeof(led_bitmask)), led_bitmask) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
xf86Msg(X_ERROR, "%s: ioctl EVIOCGBIT failed: %s\n", pInfo->name, strerror(errno));
goto error;
}
if (compare && memcmp(pEvdev->led_bitmask, led_bitmask, sizeof(led_bitmask)))
if (compare && memcmp(pEvdev->led_bitmask, led_bitmask, sizeof(led_bitmask))) {
xf86Msg(X_ERROR, "%s: device led_bitmask has changed\n", pInfo->name);
goto error;
}
memset(absinfo, 0, sizeof(absinfo));
for (i = 0; i < ABS_MAX; i++)
for (i = ABS_X; i <= ABS_MAX; i++)
{
if (TestBit(i, abs_bitmask))
{
if (ioctl(pInfo->fd, EVIOCGABS(i), &absinfo[i]) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGABS failed: %s\n", strerror(errno));
xf86Msg(X_ERROR, "%s: ioctl EVIOCGABS failed: %s\n", pInfo->name, strerror(errno));
goto error;
}
/* ignore current position (value) in comparison (bug #19819) */
absinfo[i].value = pEvdev->absinfo[i].value;
}
}
if (compare && memcmp(pEvdev->absinfo, absinfo, sizeof(absinfo)))
goto error;
if (compare && memcmp(pEvdev->absinfo, absinfo, sizeof(absinfo))) {
xf86Msg(X_ERROR, "%s: device absinfo has changed\n", pInfo->name);
goto error;
}
/* cache info */
if (!compare)
@@ -1200,9 +1315,9 @@ error:
static int
EvdevProbe(InputInfoPtr pInfo)
{
long key_bitmask[NBITS(KEY_MAX)] = {0};
long rel_bitmask[NBITS(REL_MAX)] = {0};
long abs_bitmask[NBITS(ABS_MAX)] = {0};
long key_bitmask[NLONGS(KEY_CNT)] = {0};
long rel_bitmask[NLONGS(REL_CNT)] = {0};
long abs_bitmask[NLONGS(ABS_CNT)] = {0};
int i, has_axes, has_keys, num_buttons;
int kernel24 = 0;
EvdevPtr pEvdev = pInfo->private;
@@ -1386,6 +1501,17 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
return NULL;
}
/* Check major/minor of device node to avoid adding duplicate devices. */
pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
if (EvdevIsDuplicate(pInfo))
{
xf86Msg(X_WARNING, "%s: device file already in use. Ignoring.\n",
pInfo->name);
close(pInfo->fd);
xf86DeleteInput(pInfo, 0);
return NULL;
}
pEvdev->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10);
pEvdev->invert_x = xf86SetBoolOption(pInfo->options, "InvertX", FALSE);
pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
@@ -1407,6 +1533,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
}
EvdevCacheCompare(pInfo, FALSE); /* cache device data */
EvdevAddDevice(pInfo);
if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
{
@@ -1536,6 +1663,16 @@ EvdevInitProperty(DeviceIntPtr dev)
BOOL invert[2];
char reopen;
prop_reopen = MakeAtom(EVDEV_PROP_REOPEN, strlen(EVDEV_PROP_REOPEN),
TRUE);
reopen = pEvdev->reopen_attempts;
rc = XIChangeDeviceProperty(dev, prop_reopen, XA_INTEGER, 8,
PropModeReplace, 1, &reopen, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_reopen, FALSE);
if (pEvdev->flags & (EVDEV_RELATIVE_EVENTS | EVDEV_ABSOLUTE_EVENTS))
{
@@ -1551,38 +1688,27 @@ EvdevInitProperty(DeviceIntPtr dev)
return;
XISetDevicePropertyDeletable(dev, prop_invert, FALSE);
prop_calibration = MakeAtom(EVDEV_PROP_CALIBRATION,
strlen(EVDEV_PROP_CALIBRATION), TRUE);
rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER, 32,
PropModeReplace, 0, NULL, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
prop_swap = MakeAtom(EVDEV_PROP_SWAP_AXES,
strlen(EVDEV_PROP_SWAP_AXES), TRUE);
rc = XIChangeDeviceProperty(dev, prop_swap, XA_INTEGER, 8,
PropModeReplace, 1, &pEvdev->swap_axes, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_swap, FALSE);
}
prop_reopen = MakeAtom(EVDEV_PROP_REOPEN, strlen(EVDEV_PROP_REOPEN),
TRUE);
reopen = pEvdev->reopen_attempts;
rc = XIChangeDeviceProperty(dev, prop_reopen, XA_INTEGER, 8,
PropModeReplace, 1, &reopen, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_reopen, FALSE);
prop_calibration = MakeAtom(EVDEV_PROP_CALIBRATION,
strlen(EVDEV_PROP_CALIBRATION), TRUE);
rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER, 32,
PropModeReplace, 0, NULL, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
prop_swap = MakeAtom(EVDEV_PROP_SWAP_AXES,
strlen(EVDEV_PROP_SWAP_AXES), TRUE);
rc = XIChangeDeviceProperty(dev, prop_swap, XA_INTEGER, 8,
PropModeReplace, 1, &pEvdev->swap_axes, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_swap, FALSE);
}
static int

View File

@@ -31,6 +31,7 @@
#define EVDEV_H
#include <linux/input.h>
#include <linux/types.h>
#include <xf86Xinput.h>
#include <xf86_OSproc.h>
@@ -39,6 +40,22 @@
#include <xkbstr.h>
#endif
#ifndef EV_CNT /* linux 2.4 kernels and earlier lack _CNT defines */
#define EV_CNT (EV_MAX+1)
#endif
#ifndef KEY_CNT
#define KEY_CNT (KEY_MAX+1)
#endif
#ifndef REL_CNT
#define REL_CNT (REL_MAX+1)
#endif
#ifndef ABS_CNT
#define ABS_CNT (ABS_MAX+1)
#endif
#ifndef LED_CNT
#define LED_CNT (LED_MAX+1)
#endif
#define EVDEV_MAXBUTTONS 32
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
@@ -46,7 +63,9 @@
#endif
#define LONG_BITS (sizeof(long) * 8)
#define NBITS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
/* Number of longs needed to hold the given number of bits */
#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
/* axis specific data for wheel emulation */
typedef struct {
@@ -119,12 +138,15 @@ typedef struct {
/* Cached info from device. */
char name[1024];
long bitmask[NBITS(EV_MAX)];
long key_bitmask[NBITS(KEY_MAX)];
long rel_bitmask[NBITS(REL_MAX)];
long abs_bitmask[NBITS(ABS_MAX)];
long led_bitmask[NBITS(LED_MAX)];
struct input_absinfo absinfo[ABS_MAX];
long bitmask[NLONGS(EV_CNT)];
long key_bitmask[NLONGS(KEY_CNT)];
long rel_bitmask[NLONGS(REL_CNT)];
long abs_bitmask[NLONGS(ABS_CNT)];
long led_bitmask[NLONGS(LED_CNT)];
struct input_absinfo absinfo[ABS_CNT];
/* minor/major number */
dev_t min_maj;
} EvdevRec, *EvdevPtr;
unsigned int EvdevUtilButtonEventToButtonNumber(EvdevPtr pEvdev, int code);