Compare commits

...

9 Commits

Author SHA1 Message Date
Peter Hutterer
540a4cce90 evdev 2.5.99.903
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2011-01-05 09:04:56 +10:00
Peter Hutterer
bed25600f6 Don't update first_val and num_val if we don't have data (#32480)
For touchpads, rel_queued may be on (due to abs to rel conversion) but the
delta for x/y is 0/0 on the first touch. Hence, we don't have any valuators
to post. The current results in a num_vals of -15 and a subsequent segfault
when the data is posted to the server.

Start with a last valuator of -1, so that we know if we have at least one to
post.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
2011-01-04 08:12:21 +10:00
Peter Hutterer
9aea1c5fa0 Add use_proximity bit for BTN_TOOL handling.
Touchpads send garbage data between BTN_TOOL_FINGER and BTN_TOUCH. This
leads to cursor movement towards invalid positions (bottom left corner,
usually).

Add a new flag "use_proximity" as a delimiter for BTN_TOUCH handling. If
unset, the actual proximity bits are ignored, no proximity events are sent
and BTN_TOUCH is used for the tool handling.

Example event stream for synaptics:

Event: time 1292893041.002731, -------------- Report Sync ------------
Event: time 1292893041.015807, type 1 (Key), code 330 (Touch), value 0
Event: time 1292893041.015812, type 3 (Absolute), code 0 (X), value 4283
Event: time 1292893041.015813, type 3 (Absolute), code 1 (Y), value 4860
Event: time 1292893041.015815, type 3 (Absolute), code 24 (Pressure), value 23
Event: time 1292893041.015817, type 3 (Absolute), code 28 (Tool Width), value 5
Event: time 1292893041.027537, -------------- Report Sync ------------
Event: time 1292893041.038854, type 3 (Absolute), code 0 (X), value 1
Event: time 1292893041.038857, type 3 (Absolute), code 1 (Y), value 5855
Event: time 1292893041.038859, type 3 (Absolute), code 24 (Pressure), value 1
Event: time 1292893041.038861, type 3 (Absolute), code 28 (Tool Width), value 5
Event: time 1292893041.038864, -------------- Report Sync ------------
Event: time 1292893041.062432, type 3 (Absolute), code 24 (Pressure), value 0
Event: time 1292893041.062435, type 3 (Absolute), code 28 (Tool Width), value 0
Event: time 1292893041.062437, type 1 (Key), code 325 (ToolFinger), value 0
Event: time 1292893041.062438, -------------- Report Sync ------------

Reported-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chris Bagwell <chris@cnpbagwell.com>
2010-12-22 09:18:52 +10:00
Peter Hutterer
0c987a929d Revert "Don't count BTN_TOUCH as tool. (#29428)"
Synaptics devices send garbage between BTN_TOUCH and BTN_TOOL_FINGER. By
switching to use this as proximity data now, the pointer is reset to the
garbage data position (usually around 1/5855).

This reverts commit 899218e181.

Reported-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chris Bagwell <chris@cnpbagwell.com>
2010-12-22 09:18:52 +10:00
Peter Hutterer
242a01eb0f Rename proximity to in_proximity.
No functional change, just making it a bit more obvious to read.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Dan Nicholson <dbn.lists@gmail.com>
Reviewed-by: Chris Bagwell <chris@cnpbagwell.com>
2010-12-22 09:07:28 +10:00
Peter Hutterer
7415953b9a Fix grammar typo in comment.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2010-12-21 11:13:15 +10:00
Peter Korsgaard
1ced7ec7e2 evdev: rename EvdevCacheCompare() to EvdevCache()
Since 59056e656c (Remove the reopen timer logic) from last year,
EvdevCacheCompare() is only used for caching ioctl values and not for
comparing, so remove the unused compare logic and rename the function
to EvdevCache().

Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2010-12-13 10:46:43 +10:00
Peter Hutterer
1c5ad6f8a0 evdev 2.5.99.902
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2010-12-08 12:40:49 +10:00
Peter Hutterer
6fd1d0860e Return error codes from EvdevOpenDevice()
The server's behaviour is to stop adding new devices when a BadAlloc occurs
on any device (on the assumption that new devices won't magically have more
memory). Change EvdevOpenDevice() to return an error code of BadValue when
it fails (and thus to the server) to prevent other devices being ignored
because of one misconfigured one.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Daniel Stone <daniel@fooishbar.org>
2010-12-07 08:05:42 +10:00
3 changed files with 56 additions and 88 deletions

View File

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

View File

@@ -107,12 +107,12 @@ static int proximity_bits[] = {
};
static int EvdevOn(DeviceIntPtr);
static int EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare);
static int EvdevCache(InputInfoPtr pInfo);
static void EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl);
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 BOOL EvdevOpenDevice(InputInfoPtr pInfo);
static int EvdevOpenDevice(InputInfoPtr pInfo);
#ifdef HAVE_PROPERTIES
static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
@@ -385,7 +385,7 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
/* convert to relative motion for touchpads */
if (pEvdev->abs_queued && (pEvdev->flags & EVDEV_RELATIVE_MODE)) {
if (pEvdev->proximity) {
if (pEvdev->in_proximity) {
if (pEvdev->old_vals[0] != -1)
pEvdev->delta[REL_X] = pEvdev->vals[0] - pEvdev->old_vals[0];
if (pEvdev->old_vals[1] != -1)
@@ -402,7 +402,7 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
}
if (pEvdev->rel_queued) {
int first = REL_CNT, last = 0;
int first = REL_CNT, last = -1;
int i;
if (pEvdev->swap_axes) {
@@ -428,19 +428,22 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
}
}
*num_v = (last - first + 1);
*first_v = first;
if (last >= 0)
{
*num_v = (last - first + 1);
*first_v = first;
}
}
/*
* Some devices only generate valid abs coords when BTN_TOOL_PEN is
* pressed. On wacom tablets, this means that the pen is in
* proximity of the tablet. After the pen is removed, BTN_TOOL_PEN is
* released, and a (0, 0) absolute event is generated. Checking
* pEvdev->proximity here lets us ignore that event. pEvdev is
* initialized to 1 so devices that doesn't use this scheme still
* pEvdev->in_proximity here lets us ignore that event. pEvdev is
* initialized to 1 so devices that don't use this scheme still
* just works.
*/
else if (pEvdev->abs_queued && pEvdev->proximity) {
else if (pEvdev->abs_queued && pEvdev->in_proximity) {
memcpy(v, pEvdev->vals, sizeof(int) * pEvdev->num_vals);
if (pEvdev->swap_axes) {
@@ -486,6 +489,9 @@ EvdevProcessProximityEvent(InputInfoPtr pInfo, struct input_event *ev)
{
EvdevPtr pEvdev = pInfo->private;
if (!pEvdev->use_proximity)
return;
pEvdev->prox_queued = 1;
EvdevQueueProximityEvent(pInfo, ev->value);
@@ -515,7 +521,7 @@ EvdevProcessProximityState(InputInfoPtr pInfo)
/* no proximity change in the queue */
if (!pEvdev->prox_queued)
{
if (pEvdev->abs_queued && !pEvdev->proximity)
if (pEvdev->abs_queued && !pEvdev->in_proximity)
pEvdev->abs_prox = pEvdev->abs_queued;
return 0;
}
@@ -529,8 +535,8 @@ EvdevProcessProximityState(InputInfoPtr pInfo)
}
}
if ((prox_state && !pEvdev->proximity) ||
(!prox_state && pEvdev->proximity))
if ((prox_state && !pEvdev->in_proximity) ||
(!prox_state && pEvdev->in_proximity))
{
/* We're about to go into/out of proximity but have no abs events
* within the EV_SYN. Use the last coordinates we have. */
@@ -541,7 +547,7 @@ EvdevProcessProximityState(InputInfoPtr pInfo)
}
}
pEvdev->proximity = prox_state;
pEvdev->in_proximity = prox_state;
return 1;
}
@@ -679,6 +685,10 @@ EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev)
switch (ev->code) {
case BTN_TOUCH:
/* For devices that have but don't use proximity, use
* BTN_TOUCH as the proximity notifier */
if (!pEvdev->use_proximity)
pEvdev->in_proximity = value ? ev->code : 0;
if (!(pEvdev->flags & (EVDEV_TOUCHSCREEN | EVDEV_TABLET)))
break;
/* Treat BTN_TOUCH from devices that only have BTN_TOUCH as
@@ -720,11 +730,11 @@ EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
* pressed. On wacom tablets, this means that the pen is in
* proximity of the tablet. After the pen is removed, BTN_TOOL_PEN is
* released, and a (0, 0) absolute event is generated. Checking
* pEvdev->proximity here lets us ignore that event. pEvdev->proximity is
* initialized to 1 so devices that don't use this scheme still
* just work.
* pEvdev->in_proximity here lets us ignore that event.
* pEvdev->in_proximity is initialized to 1 so devices that don't use
* this scheme still just work.
*/
if (pEvdev->abs_queued && pEvdev->proximity) {
if (pEvdev->abs_queued && pEvdev->in_proximity) {
xf86PostMotionEventP(pInfo->dev, TRUE, first_v, num_v, v + first_v);
}
}
@@ -767,7 +777,7 @@ static void EvdevPostQueuedEvents(InputInfoPtr pInfo, int num_v, int first_v,
break;
case EV_QUEUE_BTN:
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 11
if (pEvdev->abs_queued && pEvdev->proximity) {
if (pEvdev->abs_queued && pEvdev->in_proximity) {
xf86PostButtonEventP(pInfo->dev, 1, pEvdev->queue[i].key,
pEvdev->queue[i].val, first_v, num_v,
v + first_v);
@@ -1345,6 +1355,9 @@ EvdevAddAbsClass(DeviceIntPtr device)
for (i = 0; i < ArrayLength(proximity_bits); i++)
{
if (!pEvdev->use_proximity)
break;
if (TestBit(proximity_bits[i], pEvdev->key_bitmask))
{
InitProximityClassDeviceStruct(device);
@@ -1675,12 +1688,14 @@ EvdevOn(DeviceIntPtr device)
{
InputInfoPtr pInfo;
EvdevPtr pEvdev;
int rc = Success;
pInfo = device->public.devicePrivate;
pEvdev = pInfo->private;
/* after PreInit fd is still open */
if (!EvdevOpenDevice(pInfo))
return !Success;
rc = EvdevOpenDevice(pInfo);
if (rc != Success)
return rc;
EvdevGrabDevice(pInfo, 1, 0);
@@ -1742,14 +1757,11 @@ EvdevProc(DeviceIntPtr device, int what)
/**
* 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)
EvdevCache(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
int i, len;
@@ -1766,13 +1778,7 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
goto error;
}
if (!compare) {
strcpy(pEvdev->name, name);
} else if (strcmp(pEvdev->name, name)) {
xf86Msg(X_ERROR, "%s: device name changed: %s != %s\n",
pInfo->name, pEvdev->name, name);
goto error;
}
strcpy(pEvdev->name, name);
len = ioctl(pInfo->fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask);
if (len < 0) {
@@ -1781,12 +1787,7 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
goto error;
}
if (!compare) {
memcpy(pEvdev->bitmask, bitmask, len);
} else if (memcmp(pEvdev->bitmask, bitmask, len)) {
xf86Msg(X_ERROR, "%s: device bitmask has changed\n", pInfo->name);
goto error;
}
memcpy(pEvdev->bitmask, bitmask, len);
len = ioctl(pInfo->fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask);
if (len < 0) {
@@ -1795,12 +1796,7 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
goto error;
}
if (!compare) {
memcpy(pEvdev->rel_bitmask, rel_bitmask, len);
} else if (memcmp(pEvdev->rel_bitmask, rel_bitmask, len)) {
xf86Msg(X_ERROR, "%s: device rel_bitmask has changed\n", pInfo->name);
goto error;
}
memcpy(pEvdev->rel_bitmask, rel_bitmask, len);
len = ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
if (len < 0) {
@@ -1809,12 +1805,7 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
goto error;
}
if (!compare) {
memcpy(pEvdev->abs_bitmask, abs_bitmask, len);
} else if (memcmp(pEvdev->abs_bitmask, abs_bitmask, len)) {
xf86Msg(X_ERROR, "%s: device abs_bitmask has changed\n", pInfo->name);
goto error;
}
memcpy(pEvdev->abs_bitmask, abs_bitmask, len);
len = ioctl(pInfo->fd, EVIOCGBIT(EV_LED, sizeof(led_bitmask)), led_bitmask);
if (len < 0) {
@@ -1823,12 +1814,7 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
goto error;
}
if (!compare) {
memcpy(pEvdev->led_bitmask, led_bitmask, len);
} else if (memcmp(pEvdev->led_bitmask, led_bitmask, len)) {
xf86Msg(X_ERROR, "%s: device led_bitmask has changed\n", pInfo->name);
goto error;
}
memcpy(pEvdev->led_bitmask, led_bitmask, len);
/*
* Do not try to validate absinfo data since it is not expected
@@ -1852,27 +1838,6 @@ EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare)
goto error;
}
if (compare) {
/*
* Keys are special as user can adjust keymap at any time (on
* devices that support EVIOCSKEYCODE. However we do not expect
* buttons reserved for mice/tablets/digitizers and so on to
* appear/disappear so we will check only those in
* [BTN_MISC, KEY_OK) range.
*/
size_t start_word = BTN_MISC / LONG_BITS;
size_t start_byte = start_word * sizeof(unsigned long);
size_t end_word = KEY_OK / LONG_BITS;
size_t end_byte = end_word * sizeof(unsigned long);
if (len >= start_byte &&
memcmp(&pEvdev->key_bitmask[start_word], &key_bitmask[start_word],
min(len, end_byte) - start_byte + 1)) {
xf86Msg(X_ERROR, "%s: device key_bitmask has changed\n", pInfo->name);
goto error;
}
}
/* Copy the data so we have reasonably up-to-date info */
memcpy(pEvdev->key_bitmask, key_bitmask, len);
@@ -2086,6 +2051,7 @@ EvdevProbe(InputInfoPtr pInfo)
if (pEvdev->flags & EVDEV_TOUCHPAD) {
xf86Msg(X_INFO, "%s: Configuring as touchpad\n", pInfo->name);
pInfo->type_name = XI_TOUCHPAD;
pEvdev->use_proximity = 0;
} else if (pEvdev->flags & EVDEV_TABLET) {
xf86Msg(X_INFO, "%s: Configuring as tablet\n", pInfo->name);
pInfo->type_name = XI_TABLET;
@@ -2141,7 +2107,7 @@ EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4])
}
}
static BOOL
static int
EvdevOpenDevice(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
@@ -2152,7 +2118,7 @@ EvdevOpenDevice(InputInfoPtr pInfo)
device = xf86CheckStrOption(pInfo->options, "Device", NULL);
if (!device) {
xf86Msg(X_ERROR, "%s: No device specified.\n", pInfo->name);
return FALSE;
return BadValue;
}
pEvdev->device = device;
@@ -2167,7 +2133,7 @@ EvdevOpenDevice(InputInfoPtr pInfo)
if (pInfo->fd < 0) {
xf86Msg(X_ERROR, "Unable to open evdev device \"%s\".\n", device);
return FALSE;
return BadValue;
}
}
@@ -2178,10 +2144,10 @@ EvdevOpenDevice(InputInfoPtr pInfo)
xf86Msg(X_WARNING, "%s: device file is duplicate. Ignoring.\n",
pInfo->name);
close(pInfo->fd);
return FALSE;
return BadMatch;
}
return TRUE;
return Success;
}
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
@@ -2243,14 +2209,16 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
pInfo->read_input = EvdevReadInput;
pInfo->switch_mode = EvdevSwitchMode;
if (!EvdevOpenDevice(pInfo))
rc = EvdevOpenDevice(pInfo);
if (rc != Success)
goto error;
/*
* We initialize pEvdev->proximity to 1 so that device that doesn't use
* We initialize pEvdev->in_proximity to 1 so that device that doesn't use
* proximity will still report events.
*/
pEvdev->proximity = 1;
pEvdev->in_proximity = 1;
pEvdev->use_proximity = 1;
/* Grabbing the event device stops in-kernel event forwarding. In other
words, it disables rfkill and the "Macintosh mouse button emulation".
@@ -2270,8 +2238,7 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
EvdevInitButtonMapping(pInfo);
if (EvdevCacheCompare(pInfo, FALSE) ||
EvdevProbe(pInfo)) {
if (EvdevCache(pInfo) || EvdevProbe(pInfo)) {
rc = BadMatch;
goto error;
}

View File

@@ -125,7 +125,8 @@ typedef struct {
int old_vals[MAX_VALUATORS]; /* Translate absolute inputs to relative */
int flags;
int proximity;
int in_proximity; /* device in proximity */
int use_proximity; /* using the proximity bit? */
int num_buttons; /* number of buttons */
BOOL swap_axes;
BOOL invert_x;