diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2008-10-28 17:10:45 +1030 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@redhat.com> | 2008-10-28 17:26:20 +1030 |
commit | 2acbd6e67c859290a37cf3134b120c5ca7577268 (patch) | |
tree | 2a112e91e867bebd74776f1bfa20930826f2344f | |
parent | 934bc0012f948c52aadc8eda912f7728fb7394a2 (diff) |
Add support for touchpads (such as Elantech) that do not report pressure
Change the driver to react to BTN_TOUCH if device does not report
ABS_PRESSURE since there are touchpads (such as Elantech) that do not
support pressure reading but otherwise are perfectly useable in absolute
mode.
Also fix error checking of ioctl calls (positive return value is not an
error, only negative is).
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
-rw-r--r-- | src/eventcomm.c | 77 | ||||
-rw-r--r-- | src/synapticsstr.h | 1 |
2 files changed, 53 insertions, 25 deletions
diff --git a/src/eventcomm.c b/src/eventcomm.c index b2d0891..620f2f3 100644 --- a/src/eventcomm.c +++ b/src/eventcomm.c @@ -79,3 +79,5 @@ event_query_is_touchpad(int fd) int ret; - unsigned long evbits[NBITS(KEY_MAX)]; + unsigned long evbits[NBITS(EV_MAX)]; + unsigned long absbits[NBITS(ABS_MAX)]; + unsigned long keybits[NBITS(KEY_MAX)]; @@ -91,16 +93,20 @@ event_query_is_touchpad(int fd) - SYSCALL(ret = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(evbits)), evbits)); + SYSCALL(ret = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits)); if (ret < 0) return FALSE; - if (!TEST_BIT(ABS_X, evbits) || - !TEST_BIT(ABS_Y, evbits) || - !TEST_BIT(ABS_PRESSURE, evbits)) + if (!TEST_BIT(ABS_X, absbits) || + !TEST_BIT(ABS_Y, absbits)) return FALSE; - SYSCALL(ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(evbits)), evbits)); + SYSCALL(ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits)); if (ret < 0) return FALSE; - if (!TEST_BIT(BTN_TOOL_FINGER, evbits)) + + /* we expect touchpad either report raw pressure or touches */ + if (!TEST_BIT(ABS_PRESSURE, absbits) && !TEST_BIT(BTN_TOUCH, keybits)) + return FALSE; + /* all Synaptics-like touchpad report BTN_TOOL_FINGER */ + if (!TEST_BIT(BTN_TOOL_FINGER, keybits)) return FALSE; - if (TEST_BIT(BTN_TOOL_PEN, evbits)) + if (TEST_BIT(BTN_TOOL_PEN, keybits)) return FALSE; /* Don't match wacom tablets */ @@ -116,3 +122,4 @@ event_query_axis_ranges(LocalDevicePtr local) struct input_absinfo abs; - unsigned long evbits[NBITS(KEY_MAX)]; + unsigned long absbits[NBITS(ABS_MAX)]; + unsigned long keybits[NBITS(KEY_MAX)]; char buf[256]; @@ -121,3 +128,3 @@ event_query_axis_ranges(LocalDevicePtr local) SYSCALL(rc = ioctl(local->fd, EVIOCGABS(ABS_X), &abs)); - if (rc == 0) + if (rc >= 0) { @@ -132,3 +139,3 @@ event_query_axis_ranges(LocalDevicePtr local) SYSCALL(rc = ioctl(local->fd, EVIOCGABS(ABS_Y), &abs)); - if (rc == 0) + if (rc >= 0) { @@ -142,13 +149,27 @@ event_query_axis_ranges(LocalDevicePtr local) - SYSCALL(rc = ioctl(local->fd, EVIOCGABS(ABS_PRESSURE), &abs)); - if (rc == 0) + priv->has_pressure = FALSE; + SYSCALL(rc = ioctl(local->fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits)); + if (rc >= 0) + priv->has_pressure = TEST_BIT(ABS_PRESSURE, absbits); + else + xf86Msg(X_ERROR, "%s: failed to query ABS bits (%s)\n", local->name, + strerror(errno)); + + if (priv->has_pressure) { - xf86Msg(X_INFO, "%s: pressure range %d - %d\n", local->name, - abs.minimum, abs.maximum); - priv->minp = abs.minimum; - priv->maxp = abs.maximum; - } + SYSCALL(rc = ioctl(local->fd, EVIOCGABS(ABS_PRESSURE), &abs)); + if (rc >= 0) + { + xf86Msg(X_INFO, "%s: pressure range %d - %d\n", local->name, + abs.minimum, abs.maximum); + priv->minp = abs.minimum; + priv->maxp = abs.maximum; + } + } else + xf86Msg(X_INFO, + "%s: device does not report pressure, will use touch data.\n", + local->name); SYSCALL(rc = ioctl(local->fd, EVIOCGABS(ABS_TOOL_WIDTH), &abs)); - if (rc == 0) + if (rc >= 0) { @@ -160,3 +181,3 @@ event_query_axis_ranges(LocalDevicePtr local) - SYSCALL(rc = ioctl(local->fd, EVIOCGBIT(EV_KEY, sizeof(evbits)), evbits)); + SYSCALL(rc = ioctl(local->fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits)); if (rc >= 0) @@ -164,11 +185,11 @@ event_query_axis_ranges(LocalDevicePtr local) buf[0] = 0; - if ((priv->has_left = TEST_BIT(BTN_LEFT, evbits))) + if ((priv->has_left = TEST_BIT(BTN_LEFT, keybits))) strcat(buf, " left"); - if ((priv->has_right = TEST_BIT(BTN_RIGHT, evbits))) + if ((priv->has_right = TEST_BIT(BTN_RIGHT, keybits))) strcat(buf, " right"); - if ((priv->has_middle = TEST_BIT(BTN_MIDDLE, evbits))) + if ((priv->has_middle = TEST_BIT(BTN_MIDDLE, keybits))) strcat(buf, " middle"); - if ((priv->has_double = TEST_BIT(BTN_TOOL_DOUBLETAP, evbits))) + if ((priv->has_double = TEST_BIT(BTN_TOOL_DOUBLETAP, keybits))) strcat(buf, " double"); - if ((priv->has_triple = TEST_BIT(BTN_TOOL_TRIPLETAP, evbits))) + if ((priv->has_triple = TEST_BIT(BTN_TOOL_TRIPLETAP, keybits))) strcat(buf, " triple"); @@ -231,2 +252,4 @@ EventReadHwState(LocalDevicePtr local, struct SynapticsHwInfo *synhw, struct SynapticsHwState *hw = &(comm->hwState); + SynapticsPrivate *priv = (SynapticsPrivate *)local->private; + SynapticsSHM *para = priv->synpara; @@ -306,2 +329,6 @@ EventReadHwState(LocalDevicePtr local, struct SynapticsHwInfo *synhw, break; + case BTN_TOUCH: + if (!priv->has_pressure) + hw->z = v ? para->finger_high + 1 : 0; + break; } diff --git a/src/synapticsstr.h b/src/synapticsstr.h index cc0a29f..688167c 100644 --- a/src/synapticsstr.h +++ b/src/synapticsstr.h @@ -147,2 +147,3 @@ typedef struct _SynapticsPrivateRec Bool has_triple; /* triple click detected for this device */ + Bool has_pressure; /* device reports pressure */ } SynapticsPrivate; |