Compare commits

..

32 Commits

Author SHA1 Message Date
Peter Hutterer
891bfc56be evdev 2.0.8
Expect this to be the last 2.0.x release.
2008-11-18 17:16:33 +10:00
Julien Cristau
6626ad5cb9 Fix TestBit() on 64bit
Reported by Albert Damen <albrt@gmx.net>
X.Org Bug#18150 <http://bugs.freedesktop.org/show_bug.cgi?id=18150>
(cherry picked from commit f57e8face9)
2008-10-22 08:49:27 +10:30
Peter Hutterer
ae247ff09c evdev 2.0.7 2008-10-17 11:42:21 +10:30
Peter Hutterer
46f2b83e01 Don't post keycodes > 255.
If we only have keys > 255 we don't set up a key class rec, so don't post
them. It makes the server unhappy.

Signed-off-by: Julien Cristau <jcristau@debian.org>
(cherry picked from commit 7243116f55)
2008-10-17 11:19:06 +10:30
Peter Hutterer
d73a1732c6 Fix "Device reopened after N attempts" message.
(cherry picked from commit 0089d931ac)
2008-10-17 11:18:22 +10:30
Julien Cristau
8c332a8367 Set pInfo->fd to -1 on DEVICE_CLOSE
This allows the reopen logic to kick in later.
DEVICE_CLOSE gets called on regen, so without this we'd keep a stale
file descriptor in pInfo->fd in subsequent sessions.

Debian bug#496101 (http://bugs.debian.org/496101)
(cherry picked from commit b0b6399023bcdbb3337027f85c8da42d8b18c983)
2008-10-13 11:01:29 +10:30
Peter Hutterer
91e30bb07c evdev 2.0.6 2008-10-02 12:05:14 +09:30
Peter Hutterer
36d9b9f166 Close fd on DEVICE_OFF. (LP #276887)
Leaving the fd open means we still get keyboard events after VT switching
away. Coming back, some of these events are replayed on the application that
has the current focus.

Reproduceable:
1. open terminal, focus.
2. VT switch away
3. type something, preferably a password
4. VT switch back, trigger a mouse event
5. Observe the X server guessing your password.

Closing the fd on DEVICE_OFF fixes this. Reopen is handled by the reopen
code introduced with

    commit 9930477cbe
    Author: Peter Hutterer <peter.hutterer@redhat.com>
    Date:   Tue Aug 26 14:33:40 2008 +0930

        Attempt to re-open devices on read errors.

Launchpad Bug 276887
<https://bugs.edge.launchpad.net/ubuntu/+source/xorg-server/+bug/276887>
(cherry picked from commit ccd48d2f50231e2837e0984833641ac79f327ba4)
2008-10-02 11:19:40 +09:30
Peter Hutterer
69f01976f1 evdev 2.0.5 2008-09-19 09:32:08 +09:30
Peter Hutterer
32768f8acd Attempt to re-open devices on read errors.
Coming back from resume may leave us with a file descriptor that can be opened
but fails on the first read (ENODEV).
In this case, try to open the device until it becomes available or until the
predefined count expires. To be safe, we cache the information from the device
and compare against it when we re-open. This way we ensure that if the
topology changes under us, we don't open a completely different device. If a
device has changed, we disable it.

Adds option "ReopenAttempts" <int>

Conflicts:

	man/evdev.man
	src/evdev.c
	src/evdev.h
2008-09-04 20:17:29 +09:30
Peter Hutterer
ed1382866c evdev 2.0.4 2008-08-14 23:17:16 +09:30
Adam Jackson
8fe38b2287 Print a warning if a keycode exceeds the range accepted by the server.
Keycodes over 255 are silently ignored in the server. The least we can do is
put a warning in the logs.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit c1f7f8c3d2)
2008-08-07 10:40:14 +09:30
Julien Cristau
ef607b6cce Actually close the fd on DEVICE_CLOSE (bug#16948)
Fixes file descriptor leak.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit d9097df01b)
2008-08-04 09:25:27 +09:30
Julien Cristau
906a5d6add Print the device name when we get a read error
(cherry picked from commit 5c074af5a9)
2008-08-04 09:25:14 +09:30
Peter Hutterer
5152d616ca evdev 2.0.3 2008-08-01 17:29:24 +09:30
Michel Dänzer
2e9a71df5f xf86-input-evdev: Fix EVIOCGBIT ioctl usage on big endian platforms.
With this fix, on my PowerBook HAL hotplugging correctly detects my USB mouse,
and no longer thinks keyboards have random numbers of mouse buttons. :)

The LONG_BITS and NBITS macro definitions are stolen from xf86-input-synaptics.

Signed-off-by: Michel Dänzer <michel@tungstengraphics.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
[cherry-picked from master and fixed the trivial conflict -- jcristau]
2008-07-30 10:45:31 +02:00
Julien Cristau
49de32e70f Fill up the version info
Report correct versions instead of
"compiled for 0.0.0, module version = 1.0.0"
(cherry picked from commit 2b7edaa4ab)
2008-07-20 11:45:30 +02:00
Peter Hutterer
f135e07462 evdev 2.0.2 2008-07-14 13:34:36 +09:30
Peter Hutterer
e926356eb0 Don't enable the device if the grab failed with ENODEV.
After suspend/resume, sometimes the device doesn't come back up on the same
node. Since we do not call PreInit for the device (which would detect this
situation), we continue to try to read a nonexisting file, spamming the log
file with "Read Error".
(cherry picked from commit bf0d81011e)
2008-07-14 13:17:39 +09:30
Peter Hutterer
bd56ab3d72 Add .gitignore file.
(cherry picked from commit ef4bb69c1a)
2008-07-10 19:34:05 +09:30
Peter Hutterer
2b30413598 Remove static ChangeLog, autogenerate as part of make dist.
Hook taken from xserver's Makefile.am
(cherry picked from commit ec23c6b2f5)
2008-07-10 19:29:57 +09:30
Ander Conselvan de Oliveira
52fc8ee846 Mice with a lot of buttons (e.g. Logitech MX1000) generate button events greater than BTN_TASK.
Signed-off-by: Peter Hutterer <peter@cs.unisa.edu.au>
(cherry picked from commit 0830676a0c)
2008-07-10 19:29:45 +09:30
Peter Hutterer
b125b834f4 evdev 2.0.1 2008-06-22 17:52:58 +09:30
Peter Hutterer
05b20db8db No need to finalize MB emulation after EvdevProbe anymore.
Follow-up to 76800bfa75.
(cherry picked from commit 5a0ea39b79)
2008-06-22 16:26:10 +09:30
Simon Munton
43768d59da Close file descriptor if EvdevProbe fails.
Signed-off-by: Peter Hutterer <peter@cs.unisa.edu.au>
(cherry picked from commit 373e13ae35)
2008-06-22 16:25:48 +09:30
Keith Packard
9c524f6963 Enable middle button emulation at DEVICE_ON instead of DEVICE_INIT.
This ensures that the middle button emulation is re-enabled after VT switch,
otherwise the block handler that deals with the timeouts would not get
re-registered.

Signed-off-by: Keith Packard <keithp@keithp.com>
(cherry picked from commit 76800bfa75)
2008-06-22 16:24:57 +09:30
Peter Hutterer
04003a98a9 evdev 2.0.0 2008-06-17 14:01:49 +09:30
Peter Hutterer
0443fb430f Shut up compiler warning "implicit declaration of function 'xf86Msg'" 2008-06-17 13:59:15 +09:30
Peter Hutterer
998f52010f Finalize MB emulation if EvdevProbe fails.
This avoids segfaults when HAL is restarted behind our backs. Also, only init
MB emulation when the device actually has a button.
2008-06-12 11:24:04 +09:30
Peter Hutterer
de07c04f5c evdev 1.99.4
1.99.3 had a nasty bug, so here's a quick update.
2008-06-11 11:55:12 +09:30
Peter Hutterer
01355b9d4b If Emulate3Buttons is specified in the config, don't auto-deactivate it.
Default setting is still "on" until middle button is pressed.  If the options
is however explicitly stated in the config file, it takes the value from the
config file, no matter if a middle button is present.
2008-06-11 11:23:53 +09:30
Peter Hutterer
9591dc1f6c Remove wakeup handlers when device is closed.
Less SIGABRTs are less exciting, but sometimes boredom is what we want.
2008-06-11 11:23:38 +09:30
8 changed files with 373 additions and 75 deletions

26
.gitignore vendored Normal file
View File

@@ -0,0 +1,26 @@
*.patch
ChangeLog
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.guess
config.h
config.h.in
config.log
config.status
config.sub
configure
depcomp
install-sh
libtool
ltmain.sh
man/evdev.4
missing
.deps
.libs
*.lo
*.la
stamp-h1
*.bz2
*.gz

View File

@@ -1,47 +0,0 @@
2006-01-09 David Nusinow,,, <set EMAIL_ADDRESS environment variable>
* man/Makefile.am:
* man/evdev.man:
Bugzilla #968 <https://bugs.freedesktop.org/show_bug.cgi?id=968>
Patch #4301 <https://bugs.freedesktop.org/attachment.cgi?id=4301>
Add evdev manpage
2005-12-20 Kevin E. Martin <kem-at-freedesktop-dot-org>
* configure.ac:
Update package version for X11R7 release.
2005-12-14 Kevin E. Martin <kem-at-freedesktop-dot-org>
* configure.ac:
Update package version number for final X11R7 release candidate.
2005-12-06 Kevin E. Martin <kem-at-freedesktop-dot-org>
* man/Makefile.am:
Change *man_SOURCES ==> *man_PRE to fix autotools warnings.
2005-12-03 Kevin E. Martin <kem-at-freedesktop-dot-org>
* configure.ac:
Update package version number for X11R7 RC3 release.
2005-12-01 Kevin E. Martin <kem-at-freedesktop-dot-org>
* configure.ac:
Remove extraneous AC_MSG_RESULT.
2005-11-29 Adam Jackson <ajax@freedesktop.org>
* configure.ac:
Only build dlloader modules by default.
2005-11-09 Kevin E. Martin <kem-at-freedesktop-dot-org>
* configure.ac:
Update package version number for X11R7 RC2 release.
2005-11-01 Kevin E. Martin <kem-at-freedesktop-dot-org>
* configure.ac:
Update pkgcheck dependencies to work with separate build roots.

View File

@@ -20,3 +20,15 @@
AUTOMAKE_OPTIONS = foreign
SUBDIRS = src man
EXTRA_DIST = ChangeLog autogen.sh
MAINTAINERCLEANFILES=ChangeLog
.PHONY: ChangeLog
ChangeLog:
(GIT_DIR=$(top_srcdir)/.git git-log > .changelog.tmp && mv .changelog.tmp ChangeLog; rm -f .changelog.tmp) || \
(touch ChangeLog; echo 'git directory not found: installing possibly empty changelog.' >&2)
dist-hook: ChangeLog

View File

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

View File

@@ -67,6 +67,11 @@ button event is registered.
Sets the timeout (in milliseconds) that the driver waits before deciding
if two buttons where pressed "simultaneously" when 3 button emulation is
enabled. Default: 50.
.TP 7
.BI "Option \*qReopenAttempts\*q \*q" integer \*q
Number of reopen attempts after a read error occurs on the device (e.g. after
waking up from suspend). In between each attempt is a 100ms wait. Default: 10.
.SH AUTHORS
Kristian Høgsberg.
.SH "SEE ALSO"

View File

@@ -34,8 +34,16 @@
#include "config.h"
#endif
#include <xf86.h>
#include "evdev.h"
enum {
MBEMU_DISABLED = 0,
MBEMU_ENABLED,
MBEMU_AUTO
};
/*
* Lets create a simple finite-state machine for 3 button emulation:
*
@@ -288,9 +296,17 @@ void
EvdevMBEmuPreInit(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
pEvdev->emulateMB.enabled = MBEMU_AUTO;
if (xf86FindOption(pInfo->options, "Emulate3Buttons"))
{
pEvdev->emulateMB.enabled = xf86SetBoolOption(pInfo->options,
"Emulate3Buttons",
MBEMU_ENABLED);
xf86Msg(X_INFO, "%s: Forcing middle mouse button emulation.\n",
pInfo->name);
}
pEvdev->emulateMB.enabled = xf86SetBoolOption(pInfo->options,
"Emulate3Buttons", TRUE);
pEvdev->emulateMB.timeout = xf86SetIntOption(pInfo->options,
"Emulate3Timeout", 50);
RegisterBlockAndWakeupHandlers (EvdevMBEmuBlockHandler,
@@ -299,10 +315,20 @@ EvdevMBEmuPreInit(InputInfoPtr pInfo)
}
void
EvdevMBEmuFinalize(InputInfoPtr pInfo)
{
RemoveBlockAndWakeupHandlers (EvdevMBEmuBlockHandler,
EvdevMBEmuWakeupHandler,
(pointer)pInfo);
}
/* Enable/disable middle mouse button emulation. */
void
EvdevMBEmuEnable(InputInfoPtr pInfo, BOOL enable)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
pEvdev->emulateMB.enabled = enable;
if (pEvdev->emulateMB.enabled == MBEMU_AUTO)
pEvdev->emulateMB.enabled = enable;
}

View File

@@ -42,6 +42,7 @@
#include <xf86Xinput.h>
#include <exevents.h>
#include <mipointer.h>
#include <xorgVersion.h>
#include "evdev.h"
@@ -72,6 +73,7 @@
#define EVDEV_RELATIVE_EVENTS (1 << 2)
#define EVDEV_ABSOLUTE_EVENTS (1 << 3)
#define EVDEV_TOUCHPAD (1 << 4)
#define EVDEV_INITIALIZED (1 << 5) /* WheelInit etc. called already? */
#define MIN_KEYCODE 8
#define GLYPHS_PER_KEY 2
@@ -95,6 +97,9 @@ static const char *evdevDefaults[] = {
NULL
};
static int EvdevOn(DeviceIntPtr);
static int EvdevCacheCompare(InputInfoPtr pInfo, Bool compare);
static void
SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
{
@@ -130,6 +135,9 @@ PostButtonClicks(InputInfoPtr pInfo, int button, int count)
static void
PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
{
int code = ev->code + MIN_KEYCODE;
static char warned[KEY_MAX];
/* filter repeat events for chording keys */
if (value == 2 &&
(ev->code == KEY_LEFTCTRL || ev->code == KEY_RIGHTCTRL ||
@@ -140,7 +148,66 @@ PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
ev->code == KEY_SCROLLLOCK)) /* XXX windows keys? */
return;
xf86PostKeyboardEvent(pInfo->dev, ev->code + MIN_KEYCODE, value);
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);
warned[ev->code] = 1;
}
/* The X server can't handle keycodes > 255 anyway, just drop them. */
if (code > 255)
return;
xf86PostKeyboardEvent(pInfo->dev, code, value);
}
/**
* Coming back from resume may leave us with a file descriptor that can be
* opened but fails on the first read (ENODEV).
* In this case, try to open the device until it becomes available or until
* the predefined count expires.
*/
static CARD32
EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
{
InputInfoPtr pInfo = (InputInfoPtr)arg;
EvdevPtr pEvdev = pInfo->private;
do {
pInfo->fd = open(pEvdev->device, O_RDWR, 0);
} while (pInfo->fd < 0 && errno == EINTR);
if (pInfo->fd != -1)
{
if (EvdevCacheCompare(pInfo, TRUE) == Success)
{
xf86Msg(X_INFO, "%s: Device reopened after %d attempts.\n", pInfo->name,
pEvdev->reopen_attempts - pEvdev->reopen_left + 1);
EvdevOn(pInfo->dev);
} else
{
xf86Msg(X_ERROR, "%s: Device has changed - disabling.\n",
pInfo->name);
DisableDevice(pInfo->dev);
close(pInfo->fd);
pInfo->fd = -1;
}
pEvdev->reopen_left = 0;
return 0;
}
pEvdev->reopen_left--;
if (!pEvdev->reopen_left)
{
xf86Msg(X_ERROR, "%s: Failed to reopen device after %d attempts.\n",
pInfo->name, pEvdev->reopen_attempts);
DisableDevice(pInfo->dev);
return 0;
}
return 100; /* come back in 100 ms */
}
static void
@@ -161,7 +228,16 @@ EvdevReadInput(InputInfoPtr pInfo)
if (len != sizeof ev) {
/* The kernel promises that we always only read a complete
* event, so len != sizeof ev is an error. */
xf86Msg(X_ERROR, "Read error: %s\n", strerror(errno));
xf86Msg(X_ERROR, "%s: Read error: %s\n", pInfo->name, strerror(errno));
if (errno == ENODEV) /* May happen after resume */
{
xf86RemoveEnabledDevice(pInfo);
close(pInfo->fd);
pInfo->fd = -1;
pEvdev->reopen_left = pEvdev->reopen_attempts;
pEvdev->reopen_timer = TimerSet(NULL, 0, 100, EvdevReopenTimer, pInfo);
}
break;
}
@@ -252,8 +328,15 @@ EvdevReadInput(InputInfoPtr pInfo)
break;
default:
if (ev.code > BTN_TASK && ev.code < KEY_OK)
if (ev.code > BTN_TASK && ev.code < KEY_OK) {
/* Some fancy mice with a lot of buttons generate
* button events between BTN_TASK and BTN_JOYSTICK */
if (ev.code < BTN_JOYSTICK)
xf86PostButtonEvent(pInfo->dev, 0,
ev.code - BTN_LEFT + 5,
value, 0, 0);
break;
}
PostKbdEvent(pInfo, &ev, value);
break;
@@ -298,7 +381,7 @@ EvdevReadInput(InputInfoPtr pInfo)
}
}
#define TestBit(bit, array) (array[(bit) / 8] & (1 << ((bit) % 8)))
#define TestBit(bit, array) (array[(bit) / LONG_BITS]) & (1L << ((bit) % LONG_BITS))
static void
EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
@@ -816,6 +899,56 @@ EvdevInit(DeviceIntPtr device)
return Success;
}
/**
* Init all extras (wheel emulation, etc.) and grab the device.
*
* Coming from a resume, the grab may fail with ENODEV. In this case, we set a
* timer to wake up and try to reopen the device later.
*/
static int
EvdevOn(DeviceIntPtr device)
{
InputInfoPtr pInfo;
EvdevPtr pEvdev;
int rc = 0;
pInfo = device->public.devicePrivate;
pEvdev = pInfo->private;
if (pInfo->fd != -1 && !pEvdev->kernel24 &&
(rc = ioctl(pInfo->fd, EVIOCGRAB, (void *)1)))
{
xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name,
strerror(errno));
/* ENODEV - device has disappeared after resume */
if (rc && errno == ENODEV)
{
close(pInfo->fd);
pInfo->fd = -1;
}
}
if (pInfo->fd == -1)
{
pEvdev->reopen_left = pEvdev->reopen_attempts;
pEvdev->reopen_timer = TimerSet(NULL, 0, 100, EvdevReopenTimer, pInfo);
} else
{
xf86AddEnabledDevice(pInfo);
if ((pEvdev->flags & EVDEV_BUTTON_EVENTS) &&
!(pEvdev->flags & EVDEV_INITIALIZED))
{
EvdevMBEmuPreInit(pInfo);
}
pEvdev->flags |= EVDEV_INITIALIZED;
device->public.on = TRUE;
}
return Success;
}
static int
EvdevProc(DeviceIntPtr device, int what)
{
@@ -831,23 +964,35 @@ EvdevProc(DeviceIntPtr device, int what)
return EvdevInit(device);
case DEVICE_ON:
if (!pEvdev->kernel24 && ioctl(pInfo->fd, EVIOCGRAB, (void *)1))
xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name,
strerror(errno));
xf86AddEnabledDevice(pInfo);
device->public.on = TRUE;
break;
return EvdevOn(device);
case DEVICE_OFF:
if (!pEvdev->kernel24 && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
xf86Msg(X_WARNING, "%s: Release failed (%s)\n", pInfo->name,
strerror(errno));
xf86RemoveEnabledDevice(pInfo);
if (pInfo->fd != -1)
{
if (!pEvdev->kernel24 && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
xf86Msg(X_WARNING, "%s: Release failed (%s)\n", pInfo->name,
strerror(errno));
xf86RemoveEnabledDevice(pInfo);
close(pInfo->fd);
pInfo->fd = -1;
}
if (pEvdev->flags & EVDEV_INITIALIZED)
EvdevMBEmuFinalize(pInfo);
pEvdev->flags &= ~EVDEV_INITIALIZED;
device->public.on = FALSE;
if (pEvdev->reopen_timer)
{
TimerFree(pEvdev->reopen_timer);
pEvdev->reopen_timer = NULL;
}
break;
case DEVICE_CLOSE:
xf86Msg(X_INFO, "%s: Close\n", pInfo->name);
if (pInfo->fd != -1) {
close(pInfo->fd);
pInfo->fd = -1;
}
break;
}
@@ -877,13 +1022,123 @@ EvdevConvert(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
return TRUE;
}
/**
* Get as much information as we can from the fd and cache it.
* If compare is True, then the information retrieved will be compared to the
* one already cached. If the information does not match, then this function
* returns an error.
*
* @return Success if the information was cached, or !Success otherwise.
*/
static int
EvdevCacheCompare(InputInfoPtr pInfo, Bool compare)
{
EvdevPtr pEvdev = pInfo->private;
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];
if (ioctl(pInfo->fd,
EVIOCGNAME(sizeof(name) - 1), name) < 0) {
xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
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));
goto error;
}
if (compare && memcmp(pEvdev->bitmask, bitmask, sizeof(bitmask)))
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));
goto error;
}
if (compare && memcmp(pEvdev->rel_bitmask, rel_bitmask, sizeof(rel_bitmask)))
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));
goto error;
}
if (compare && memcmp(pEvdev->abs_bitmask, abs_bitmask, sizeof(abs_bitmask)))
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));
goto error;
}
if (compare && memcmp(pEvdev->key_bitmask, key_bitmask, sizeof(key_bitmask)))
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));
goto error;
}
if (compare && memcmp(pEvdev->led_bitmask, led_bitmask, sizeof(led_bitmask)))
goto error;
memset(absinfo, 0, sizeof(absinfo));
for (i = 0; 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));
goto error;
}
}
}
if (compare && memcmp(pEvdev->absinfo, absinfo, sizeof(absinfo)))
goto error;
/* cache info */
if (!compare)
{
strcpy(pEvdev->name, name);
memcpy(pEvdev->bitmask, bitmask, sizeof(bitmask));
memcpy(pEvdev->key_bitmask, key_bitmask, sizeof(key_bitmask));
memcpy(pEvdev->rel_bitmask, rel_bitmask, sizeof(rel_bitmask));
memcpy(pEvdev->abs_bitmask, abs_bitmask, sizeof(abs_bitmask));
memcpy(pEvdev->led_bitmask, led_bitmask, sizeof(led_bitmask));
memcpy(pEvdev->absinfo, absinfo, sizeof(absinfo));
}
return Success;
error:
return !Success;
}
static int
EvdevProbe(InputInfoPtr pInfo)
{
char key_bitmask[(KEY_MAX + 7) / 8];
char rel_bitmask[(REL_MAX + 7) / 8];
char abs_bitmask[(ABS_MAX + 7) / 8];
long key_bitmask[NBITS(KEY_MAX)];
long rel_bitmask[NBITS(REL_MAX)];
long abs_bitmask[NBITS(ABS_MAX)];
int i, has_axes, has_buttons, has_keys;
EvdevPtr pEvdev = pInfo->private;
@@ -1024,8 +1279,6 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
*/
pEvdev->tool = 1;
EvdevMBEmuPreInit(pInfo);
device = xf86CheckStrOption(dev->commonOptions, "Path", NULL);
if (!device)
device = xf86CheckStrOption(dev->commonOptions, "Device", NULL);
@@ -1035,11 +1288,12 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
return NULL;
}
pEvdev->device = device;
xf86Msg(deviceFrom, "%s: Device: \"%s\"\n", pInfo->name, device);
do {
pInfo->fd = open(device, O_RDWR, 0);
}
while (pInfo->fd < 0 && errno == EINTR);
} while (pInfo->fd < 0 && errno == EINTR);
if (pInfo->fd < 0) {
xf86Msg(X_ERROR, "Unable to open evdev device \"%s\".\n", device);
@@ -1047,14 +1301,19 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
return NULL;
}
pEvdev->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10);
pEvdev->noXkb = noXkbExtension;
/* parse the XKB options during kbd setup */
if (EvdevProbe(pInfo)) {
close(pInfo->fd);
xf86DeleteInput(pInfo, 0);
return NULL;
}
EvdevCacheCompare(pInfo, FALSE); /* cache device data */
return pInfo;
}
@@ -1089,8 +1348,8 @@ static XF86ModuleVersionInfo EvdevVersionRec =
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
0, /* Missing from SDK: XORG_VERSION_CURRENT, */
1, 0, 0,
XORG_VERSION_CURRENT,
PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
ABI_CLASS_XINPUT,
ABI_XINPUT_VERSION,
MOD_CLASS_XINPUT,

View File

@@ -40,7 +40,11 @@
#include <X11/extensions/XKBstr.h>
#endif
#define LONG_BITS (sizeof(long) * 8)
#define NBITS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
typedef struct {
const char *device;
int kernel24;
int screen;
int min_x, min_y, max_x, max_y;
@@ -67,6 +71,18 @@ typedef struct {
Time expires; /* time of expiry */
Time timeout;
} emulateMB;
int reopen_attempts; /* max attempts to re-open after read failure */
int reopen_left; /* number of attempts left to re-open the device */
OsTimerPtr reopen_timer;
/* 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];
} EvdevRec, *EvdevPtr;
/* Middle Button emulation */
@@ -75,6 +91,7 @@ BOOL EvdevMBEmuFilterEvent(InputInfoPtr, int, BOOL);
void EvdevMBEmuWakeupHandler(pointer, int, pointer);
void EvdevMBEmuBlockHandler(pointer, struct timeval**, pointer);
void EvdevMBEmuPreInit(InputInfoPtr);
void EvdevMBEmuFinalize(InputInfoPtr);
void EvdevMBEmuEnable(InputInfoPtr, BOOL);
#endif