Compare commits

..

9 Commits

Author SHA1 Message Date
Peter Hutterer
f7850a4042 evdev 2.3.2
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2009-12-11 13:42:33 +10:00
Peter Hutterer
bd4102af6e Fix up BTN_TOUCH handling for non-button tablets.
BTN_TOOL_* is treated as tool, just like before. BTN_TOUCH on the other hand
may need to be treated as a button left press. This again requires a button
class.

Tested on an HP Touchsmart and a Wacom tablet.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 1b0df04abe)
2009-12-03 09:27:32 +10:00
Peter Hutterer
22e816eb32 Only init the calibration property for absolute devices.
Relative devices can't be calibrated anyway so why bother.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 2ca24a16f0)
2009-12-03 09:27:31 +10:00
David Woodhouse
b6b377fe9a Report initial calibration parameters.
Where an initial calibration is provided through the Calibration option
to the driver, it wasn't being exposed in the 'Evdev Axis Calibration'
property. Remedy that...

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 7b285a802b)
2009-12-03 09:27:28 +10:00
David Woodhouse
3772676fd6 Swap axes before applying touch screen calibration.
When the SwapAxes option is set, the X and Y axes in calibration should
be labelled as the user perceives them -- not as the kernel sends them.

Currently, we apply the X-axis calibration to the X-axis of the input,
and then do the axis swapping so we've actually applied the X-axis
calibration to what the user sees as the Y-axis.

This patch changes the order of the operations, so that the axes are
swapped before the calibration is applied.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit f187badb71)
2009-12-03 09:27:25 +10:00
Peter Hutterer
4f05afd495 evdev 2.3.1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2009-11-20 11:18:03 +10:00
Bartosz Brachaczek
c6964dd28a Set all valuators for relative motion events (#24737)
We should process all the deltas reported by a relative motion device,
otherwise some devices such as A4Tech X-750F or similar may trigger a
situation when the `v` array contains random values (it isn't
initialized anywhere) and later we process them and in effect the mouse
cursor "jumps" on the screen.
I'm not sure why, but we also must be sure that the `first` and `last`
variables reflect the axis map, otherwise the mouse cursor "jumps" on
the screen when clicking mouse buttons in some rare cases reported by
Bartek Iwaniec on Bugzilla. That's why a simple initialization of the
`v` array with zeros isn't sufficient.

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

Signed-off-by: Bartosz Brachaczek <b.brachaczek@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit c1f16a4f59)
2009-11-20 11:17:44 +10:00
Dmitry Torokhov
175af93bdb Relax checks when reopening devices
When checking whether we are dealing with the same device as before
when we try to reopen it evdev should not require exact match of
entire keymap. Users should be allowed to adjust keymaps to better
match their hardware even after X starts. However we don't expect
changes in [BTN_MISC, KEY_OK) range since these codes are reserved for
mice, joysticks, tablets and so forth, so we will limit the check to
this range.

The same goes for absinfo - limits can change and it should not result
in device being disabled.

Also check the length of the data returned by ioctl and don't try to
compare more than we were given.

[peter: moved the key comparison below the led+abs comparison]

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit a0f7f34dc5)
2009-11-20 11:17:42 +10:00
Peter Hutterer
7c3c7f83d0 Fix drag-lock property handler for multiple draglock buttons.
Parsing of the values was wrong. Given an input of 1 2 3 4, button 1 sets
the lock for button 2 and button 3 sets the lock for button 4.

This also means we need to return BadMatch if the property isn't a multiple
of 2.

Red Hat Bug 524428 <https://bugzilla.redhat.com/show_bug.cgi?id=524428>

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 11669d8279)
2009-11-20 11:17:41 +10:00
12 changed files with 230 additions and 253 deletions

76
.gitignore vendored
View File

@@ -1,78 +1,28 @@
#
# X.Org module default exclusion patterns
# The next section if for module specific patterns
#
# Do not edit the following section
# GNU Build System (Autotools)
aclocal.m4
autom4te.cache/
autoscan.log
*.patch
ChangeLog
compile
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.guess
config.h
config.h.in
config.log
config-ml.in
config.py
config.status
config.status.lineno
config.sub
configure
configure.scan
depcomp
.deps/
INSTALL
install-sh
.libs/
libtool
libtool.m4
ltmain.sh
lt~obsolete.m4
ltoptions.m4
ltsugar.m4
ltversion.m4
Makefile
Makefile.in
mdate-sh
man/evdev.4
missing
mkinstalldirs
.deps
.libs
*.lo
*.la
stamp-h1
xf86-input-evdev-*.tar.*
*.pc
py-compile
stamp-h?
symlink-tree
texinfo.tex
ylwrap
# Do not edit the following section
# Edit Compile Debug Document Distribute
*~
*.[0-9]
*.[0-9]x
*.bak
*.bin
core
*.dll
*.exe
*-ISO*.bdf
*-JIS*.bdf
*-KOI8*.bdf
*.kld
*.ko
*.ko.cmd
*.lai
*.l[oa]
*.[oa]
*.obj
*.patch
*.so
*.pcf.gz
*.pdb
*.tar.bz2
*.tar.gz
#
# Add & Override patterns for xf86-input-evdev
#
# Edit the following section as needed
# For example, !report.pc overrides *.pc. See 'man gitignore'
#
tags

35
COPYING
View File

@@ -23,24 +23,27 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Copyright 2005 Sun Microsystems, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
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.
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the copyright holders shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from the copyright holders.
Copyright © 2008 University of South Australia
copyrights taken from xf86-input-mouse, partly valid for this driver.

View File

@@ -18,23 +18,23 @@
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
AUTOMAKE_OPTIONS = foreign
# Ensure headers are installed below $(prefix) for distcheck
DISTCHECK_CONFIGURE_FLAGS = --with-sdkdir='$${includedir}/xorg'
SUBDIRS = src man include
MAINTAINERCLEANFILES = ChangeLog INSTALL
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = xorg-evdev.pc
EXTRA_DIST = ChangeLog
.PHONY: ChangeLog INSTALL
MAINTAINERCLEANFILES=ChangeLog
INSTALL:
$(INSTALL_CMD)
.PHONY: ChangeLog
ChangeLog:
$(CHANGELOG_CMD)
dist-hook: ChangeLog INSTALL
dist-hook: ChangeLog

View File

@@ -22,28 +22,26 @@
AC_PREREQ(2.57)
AC_INIT([xf86-input-evdev],
2.4.0,
2.3.2,
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
xf86-input-evdev)
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_AUX_DIR(.)
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_INIT_AUTOMAKE([dist-bzip2])
AM_MAINTAINER_MODE
# Require xorg-macros: XORG_DEFAULT_OPTIONS
m4_ifndef([XORG_MACROS_VERSION],
[m4_fatal([must install xorg-macros 1.3 or later before running autoconf/autogen])])
m4_ifndef([XORG_MACROS_VERSION], [AC_FATAL([must install xorg-macros 1.3 or later before running autoconf/autogen])])
XORG_MACROS_VERSION(1.3)
XORG_DEFAULT_OPTIONS
AM_CONFIG_HEADER([config.h])
# Checks for programs.
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
AC_PROG_CC
XORG_DEFAULT_OPTIONS
AH_TOP([#include "xorg-server.h"])
@@ -55,13 +53,10 @@ AC_ARG_WITH(xorg-module-dir,
inputdir=${moduledir}/input
AC_SUBST(inputdir)
# Checks for extensions
XORG_DRIVER_CHECK_EXT(XINPUT, inputproto)
# Checks for pkg-config packages. We need to be able to override sdkdir
# to satisfy silly distcheck requirements.
PKG_CHECK_MODULES(XORG, xorg-server xproto $REQUIRED_MODULES)
XORG_CFLAGS="$CWARNFLAGS $XORG_CFLAGS"
AC_ARG_WITH([sdkdir], [],
[sdkdir="$withval"],
[sdkdir=`$PKG_CONFIG --variable=sdkdir xorg-server`])

View File

@@ -56,7 +56,7 @@
/* Reopen attempts. */
/* CARD8 */
#define EVDEV_PROP_REOPEN "Evdev Reopen Attempts" /* OBSOLETE */
#define EVDEV_PROP_REOPEN "Evdev Reopen Attempts"
/* Run-time calibration */
/* CARD32, 4 values [minx, maxx, miny, maxy], or no values for unset */

View File

@@ -1,23 +1,26 @@
# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# 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.
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the copyright holders shall
# not be used in advertising or otherwise to promote the sale, use or
# other dealings in this Software without prior written authorization
# from the copyright holders.
#
drivermandir = $(DRIVER_MAN_DIR)

View File

@@ -76,15 +76,13 @@ indicating that the next button pressed is to be
.BI "Option \*qEmulate3Buttons\*q \*q" boolean \*q
Enable/disable the emulation of the third (middle) mouse button for mice
which only have two physical buttons. The third button is emulated by
pressing both buttons simultaneously. Default: off for touchscreens, otherwise
on until a middle mouse button event is registered. Property: "Evdev Middle
Button Emulation".
pressing both buttons simultaneously. Default: on, until a middle mouse
button event is registered. Property: "Evdev Middle Button Emulation".
.TP 7
.BI "Option \*qEmulate3Timeout\*q \*q" integer \*q
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. Property: "Evdev Middle Button Timeout".
.TP 7
.BI "Option \*qEmulateWheel\*q \*q" boolean \*q
Enable/disable "wheel" emulation. Wheel emulation means emulating button
press/release events when the mouse is moved while a specific real button
@@ -153,6 +151,10 @@ axes regardless of the presence of other axes. This may trigger buggy
behavior and events from this axis are always forwarded. Users are
discouraged from setting this option.
.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.
.TP 7
.BI "Option \*qCalibration\*q \*q" "min-x max-x min-y max-y" \*q
Calibrates the X and Y axes for devices that need to scale to a different
coordinate system than reported to the X server. This feature is required
@@ -161,11 +163,6 @@ originally reported by the kernel (e.g. touchscreens). The scaling to the
custom coordinate system is done in-driver and the X server is unaware of
the transformation. Property: "Evdev Axis Calibration".
.TP 7
.B Option \*qMode\*q \*qRelative\*q\fP|\fP\*qAbsolute\*q
Sets the mode of the device if device has absolute axes.
The default value for touchpads is relative, for other absolute.
This option has no effect on devices without absolute axes.
.TP 7
.BI "Option \*qSwapAxes\*q \*q" Bool \*q
Swap x/y axes. Default: off. Property: "Evdev Axes Swap".
.TP 7

View File

@@ -24,8 +24,7 @@
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
AM_CFLAGS = $(XORG_CFLAGS) $(CWARNFLAGS)
AM_CFLAGS = $(XORG_CFLAGS)
@DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version

View File

@@ -309,11 +309,7 @@ void
EvdevMBEmuPreInit(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
if (pEvdev->flags & EVDEV_TOUCHSCREEN)
pEvdev->emulateMB.enabled = MBEMU_DISABLED;
else
pEvdev->emulateMB.enabled = MBEMU_AUTO;
pEvdev->emulateMB.enabled = MBEMU_AUTO;
if (xf86FindOption(pInfo->options, "Emulate3Buttons"))
{

View File

@@ -100,7 +100,6 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
WheelAxisPtr pAxis = NULL, pOtherAxis = NULL;
int value = pEv->value;
int oldValue;
/* Has wheel emulation been configured to be enabled? */
if (!pEvdev->emulateWheel.enabled)
@@ -119,21 +118,12 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
}
/* We don't want to intercept real mouse wheel events */
if(pEv->type == EV_ABS) {
oldValue = pEvdev->vals[pEvdev->axis_map[pEv->code]];
pEvdev->vals[pEvdev->axis_map[pEv->code]] = value;
value -= oldValue; /* make value into a differential measurement */
}
switch(pEv->code) {
/* ABS_X has the same value as REL_X, so this case catches both */
case REL_X:
pAxis = &(pEvdev->emulateWheel.X);
pOtherAxis = &(pEvdev->emulateWheel.Y);
break;
/* ABS_Y has the same value as REL_Y, so this case catches both */
case REL_Y:
pAxis = &(pEvdev->emulateWheel.Y);
pOtherAxis = &(pEvdev->emulateWheel.X);
@@ -143,11 +133,11 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
break;
}
/* If we found REL_X, REL_Y, ABS_X or ABS_Y then emulate a mouse
wheel. Reset the inertia of the other axis when a scroll event
was sent to avoid the buildup of erroneous scroll events if the
user doesn't move in a perfectly straight line.
*/
/* If we found REL_X or REL_Y, emulate a mouse wheel.
Reset the inertia of the other axis when a scroll event was sent
to avoid the buildup of erroneous scroll events if the user
doesn't move in a perfectly straight line.
*/
if (pAxis)
{
if (EvdevWheelEmuInertia(pInfo, pAxis, value))

View File

@@ -32,7 +32,6 @@
#endif
#include <X11/keysym.h>
#include <X11/extensions/XI.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -81,6 +80,19 @@
#define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
/* evdev flags */
#define EVDEV_KEYBOARD_EVENTS (1 << 0)
#define EVDEV_BUTTON_EVENTS (1 << 1)
#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 EVDEV_TOUCHSCREEN (1 << 6)
#define EVDEV_CALIBRATED (1 << 7) /* run-time calibrated? */
#define EVDEV_TABLET (1 << 8) /* device looks like a tablet? */
#define EVDEV_UNIGNORE_ABSOLUTE (1 << 9) /* explicitly unignore abs axes */
#define EVDEV_UNIGNORE_RELATIVE (1 << 10) /* explicitly unignore rel axes */
#define MIN_KEYCODE 8
#define GLYPHS_PER_KEY 2
#define AltMask Mod1Mask
@@ -105,7 +117,6 @@ static const char *evdevDefaults[] = {
static int EvdevOn(DeviceIntPtr);
static int EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare);
static void EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl);
static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode);
#ifdef HAVE_PROPERTIES
static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
@@ -114,6 +125,7 @@ static void EvdevInitProperty(DeviceIntPtr dev);
static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
XIPropertyValuePtr val, BOOL checkonly);
static Atom prop_invert = 0;
static Atom prop_reopen = 0;
static Atom prop_calibration = 0;
static Atom prop_swap = 0;
static Atom prop_axis_label = 0;
@@ -125,38 +137,6 @@ static Atom prop_btn_label = 0;
* 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;
EvdevPtr pEvdev;
pInfo = device->public.devicePrivate;
pEvdev = pInfo->private;
if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
{
if (mode == Relative)
return Success;
else
return XI_BadMode;
}
switch (mode) {
case Absolute:
pEvdev->flags &= ~EVDEV_RELATIVE_MODE;
break;
case Relative:
pEvdev->flags |= EVDEV_RELATIVE_MODE;
break;
default:
return XI_BadMode;
}
return Success;
}
static size_t CountBits(unsigned long *array, size_t nlongs)
{
unsigned int i;
@@ -276,6 +256,7 @@ void
EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
{
int code = ev->code + MIN_KEYCODE;
static char warned[KEY_CNT];
EventQueuePtr pQueue;
EvdevPtr pEvdev = pInfo->private;
@@ -293,6 +274,19 @@ EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
)
return;
if (code > 255)
{
if (ev->code <= KEY_MAX && !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. */
return;
}
if (pEvdev->num_queue >= EVDEV_MAXQUEUE)
{
xf86Msg(X_NONE, "%s: dropping event due to full queue!\n", pInfo->name);
@@ -346,6 +340,56 @@ EvdevQueueButtonClicks(InputInfoPtr pInfo, int button, int count)
}
}
/**
* 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 | O_NONBLOCK, 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);
xf86DisableDevice(pInfo->dev, FALSE);
close(pInfo->fd);
pInfo->fd = -1;
pEvdev->min_maj = 0; /* don't hog the device */
}
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);
xf86DisableDevice(pInfo->dev, FALSE);
pEvdev->min_maj = 0; /* don't hog the device */
return 0;
}
return 100; /* come back in 100 ms */
}
#define ABS_X_VALUE 0x1
#define ABS_Y_VALUE 0x2
#define ABS_VALUE 0x4
@@ -362,7 +406,7 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
*num_v = *first_v = 0;
/* convert to relative motion for touchpads */
if (pEvdev->abs && (pEvdev->flags & EVDEV_RELATIVE_MODE)) {
if (pEvdev->abs && (pEvdev->flags & EVDEV_TOUCHPAD)) {
if (pEvdev->tool) { /* meaning, touch is active */
if (pEvdev->old_vals[0] != -1)
pEvdev->delta[REL_X] = pEvdev->vals[0] - pEvdev->old_vals[0];
@@ -488,7 +532,7 @@ EvdevProcessButtonEvent(InputInfoPtr pInfo, struct input_event *ev)
static void
EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
{
int value;
static int value;
EvdevPtr pEvdev = pInfo->private;
/* Get the signed value, earlier kernels had this as unsigned */
@@ -533,7 +577,7 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
static void
EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
{
int value;
static int value;
EvdevPtr pEvdev = pInfo->private;
/* Get the signed value, earlier kernels had this as unsigned */
@@ -546,9 +590,6 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
if (ev->code > ABS_MAX)
return;
if (EvdevWheelEmuFilterMotion(pInfo, ev))
return;
pEvdev->vals[pEvdev->axis_map[ev->code]] = value;
if (ev->code == ABS_X)
pEvdev->abs |= ABS_X_VALUE;
@@ -564,7 +605,7 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
static void
EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev)
{
int value;
static int value;
EvdevPtr pEvdev = pInfo->private;
/* Get the signed value, earlier kernels had this as unsigned */
@@ -724,6 +765,7 @@ EvdevReadInput(InputInfoPtr pInfo)
{
struct input_event ev[NUM_EVENTS];
int i, len = sizeof(ev);
EvdevPtr pEvdev = pInfo->private;
while (len == sizeof(ev))
{
@@ -736,6 +778,11 @@ EvdevReadInput(InputInfoPtr pInfo)
xf86RemoveEnabledDevice(pInfo);
close(pInfo->fd);
pInfo->fd = -1;
if (pEvdev->reopen_timer)
{
pEvdev->reopen_left = pEvdev->reopen_attempts;
pEvdev->reopen_timer = TimerSet(pEvdev->reopen_timer, 0, 100, EvdevReopenTimer, pInfo);
}
} else if (errno != EAGAIN)
{
/* We use X_NONE here because it doesn't alloc */
@@ -1150,7 +1197,6 @@ EvdevAddAbsClass(DeviceIntPtr device)
EvdevPtr pEvdev;
int num_axes, axis, i = 0;
Atom *atoms;
const char *mode;
pInfo = device->public.devicePrivate;
pEvdev = pInfo->private;
@@ -1222,22 +1268,6 @@ EvdevAddAbsClass(DeviceIntPtr device)
TestBit(ABS_TILT_Y, pEvdev->abs_bitmask)))
pInfo->flags |= XI86_POINTER_CAPABLE;
if (pEvdev->flags & EVDEV_TOUCHPAD)
pEvdev->flags |= EVDEV_RELATIVE_MODE;
else
pEvdev->flags &= ~EVDEV_RELATIVE_MODE;
if (xf86FindOption(pInfo->options, "Mode"))
{
mode = xf86SetStrOption(pInfo->options, "Mode", NULL);
if (!strcasecmp("absolute", mode))
pEvdev->flags &= ~EVDEV_RELATIVE_MODE;
else if (!strcasecmp("relative", mode))
pEvdev->flags |= EVDEV_RELATIVE_MODE;
else
xf86Msg(X_INFO, "%s: unknown mode, use default\n", pInfo->name);
}
return Success;
}
@@ -1299,9 +1329,6 @@ EvdevAddRelClass(DeviceIntPtr device)
GetMotionHistorySize(), Relative))
return !Success;
if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
return !Success;
for (axis = REL_X; axis <= REL_MAX; axis++)
{
int axnum = pEvdev->axis_map[axis];
@@ -1318,6 +1345,9 @@ EvdevAddRelClass(DeviceIntPtr device)
xfree(atoms);
if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
return !Success;
pInfo->flags |= XI86_POINTER_CAPABLE;
return Success;
@@ -1525,6 +1555,9 @@ EvdevInit(DeviceIntPtr device)
/**
* 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)
@@ -1536,36 +1569,42 @@ EvdevOn(DeviceIntPtr device)
pInfo = device->public.devicePrivate;
pEvdev = pInfo->private;
if (pInfo->fd == -1) /* after PreInit fd is still open */
if (pInfo->fd != -1 && pEvdev->grabDevice &&
(rc = ioctl(pInfo->fd, EVIOCGRAB, (void *)1)))
{
do {
pInfo->fd = open(pEvdev->device, O_RDWR | O_NONBLOCK, 0);
} while (pInfo->fd < 0 && errno == EINTR);
if (pInfo->fd < 0) {
xf86Msg(X_ERROR, "Unable to open evdev device \"%s\".\n",
pEvdev->device);
return !Success;
}
}
if (pEvdev->grabDevice && (rc = ioctl(pInfo->fd, EVIOCGRAB, (void *)1)))
xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name,
strerror(errno));
pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
if (EvdevIsDuplicate(pInfo))
{
xf86Msg(X_WARNING, "%s: Refusing to enable duplicate device.\n",
pInfo->name);
return !Success;
/* ENODEV - device has disappeared after resume */
if (rc && errno == ENODEV)
{
close(pInfo->fd);
pInfo->fd = -1;
}
}
xf86FlushInput(pInfo->fd);
xf86AddEnabledDevice(pInfo);
EvdevMBEmuOn(pInfo);
pEvdev->flags |= EVDEV_INITIALIZED;
device->public.on = TRUE;
if (pInfo->fd == -1)
{
pEvdev->reopen_left = pEvdev->reopen_attempts;
pEvdev->reopen_timer = TimerSet(pEvdev->reopen_timer, 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;
}
pEvdev->reopen_timer = TimerSet(pEvdev->reopen_timer, 0, 0, NULL, NULL);
xf86FlushInput(pInfo->fd);
xf86AddEnabledDevice(pInfo);
EvdevMBEmuOn(pInfo);
pEvdev->flags |= EVDEV_INITIALIZED;
device->public.on = TRUE;
}
return Success;
}
@@ -1603,6 +1642,11 @@ EvdevProc(DeviceIntPtr device, int what)
pEvdev->min_maj = 0;
pEvdev->flags &= ~EVDEV_INITIALIZED;
device->public.on = FALSE;
if (pEvdev->reopen_timer)
{
TimerFree(pEvdev->reopen_timer);
pEvdev->reopen_timer = NULL;
}
break;
case DEVICE_CLOSE:
@@ -1767,7 +1811,6 @@ static int
EvdevProbe(InputInfoPtr pInfo)
{
int i, has_rel_axes, has_abs_axes, has_keys, num_buttons, has_scroll;
int has_lmr; /* left middle right */
int kernel24 = 0;
int ignore_abs = 0, ignore_rel = 0;
EvdevPtr pEvdev = pInfo->private;
@@ -1810,7 +1853,6 @@ EvdevProbe(InputInfoPtr pInfo)
has_abs_axes = FALSE;
has_keys = FALSE;
has_scroll = FALSE;
has_lmr = FALSE;
num_buttons = 0;
/* count all buttons */
@@ -1825,10 +1867,6 @@ EvdevProbe(InputInfoPtr pInfo)
}
}
has_lmr = TestBit(BTN_LEFT, pEvdev->key_bitmask) ||
TestBit(BTN_MIDDLE, pEvdev->key_bitmask) ||
TestBit(BTN_RIGHT, pEvdev->key_bitmask);
if (num_buttons)
{
pEvdev->flags |= EVDEV_BUTTON_EVENTS;
@@ -1901,7 +1939,7 @@ EvdevProbe(InputInfoPtr pInfo)
}
} else if (TestBit(ABS_PRESSURE, pEvdev->abs_bitmask) ||
TestBit(BTN_TOUCH, pEvdev->key_bitmask)) {
if (has_lmr || TestBit(BTN_TOOL_FINGER, pEvdev->key_bitmask)) {
if (num_buttons || TestBit(BTN_TOOL_FINGER, pEvdev->key_bitmask)) {
xf86Msg(X_INFO, "%s: Found absolute touchpad.\n", pInfo->name);
pEvdev->flags |= EVDEV_TOUCHPAD;
memset(pEvdev->old_vals, -1, sizeof(int) * pEvdev->num_vals);
@@ -2010,7 +2048,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
pInfo->history_size = 0;
pInfo->control_proc = NULL;
pInfo->close_proc = NULL;
pInfo->switch_mode = EvdevSwitchMode;
pInfo->switch_mode = NULL;
pInfo->conversion_proc = NULL;
pInfo->reverse_conversion_proc = NULL;
pInfo->dev = NULL;
@@ -2063,6 +2101,7 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
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);
pEvdev->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE);
@@ -2450,6 +2489,18 @@ EvdevInitProperty(DeviceIntPtr dev)
EvdevPtr pEvdev = pInfo->private;
int rc;
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))
{
@@ -2542,6 +2593,13 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
pEvdev->invert_x = data[0];
pEvdev->invert_y = data[1];
}
} else if (atom == prop_reopen)
{
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
if (!checkonly)
pEvdev->reopen_attempts = *((CARD8*)val->data);
} else if (atom == prop_calibration)
{
if (val->format != 32 || val->type != XA_INTEGER)

View File

@@ -38,7 +38,7 @@
#include <xf86_OSproc.h>
#include <xkbstr.h>
#ifndef EV_CNT /* linux 2.6.23 kernels and earlier lack _CNT defines */
#ifndef EV_CNT /* linux 2.4 kernels and earlier lack _CNT defines */
#define EV_CNT (EV_MAX+1)
#endif
#ifndef KEY_CNT
@@ -57,20 +57,6 @@
#define EVDEV_MAXBUTTONS 32
#define EVDEV_MAXQUEUE 32
/* evdev flags */
#define EVDEV_KEYBOARD_EVENTS (1 << 0)
#define EVDEV_BUTTON_EVENTS (1 << 1)
#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 EVDEV_TOUCHSCREEN (1 << 6)
#define EVDEV_CALIBRATED (1 << 7) /* run-time calibrated? */
#define EVDEV_TABLET (1 << 8) /* device looks like a tablet? */
#define EVDEV_UNIGNORE_ABSOLUTE (1 << 9) /* explicitly unignore abs axes */
#define EVDEV_UNIGNORE_RELATIVE (1 << 10) /* explicitly unignore rel axes */
#define EVDEV_RELATIVE_MODE (1 << 11) /* Force relative events for devices with absolute axes */
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
#define HAVE_PROPERTIES 1
#endif