summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/eventcomm.c77
-rw-r--r--src/synapticsstr.h1
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
@@ -77,7 +77,9 @@ static Bool
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)];
/* Check for ABS_X, ABS_Y, ABS_PRESSURE and BTN_TOOL_FINGER */
@@ -89,20 +91,24 @@ event_query_is_touchpad(int fd)
!TEST_BIT(EV_KEY, evbits))
return FALSE;
- 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 */
return TRUE;
@@ -114,12 +120,13 @@ event_query_axis_ranges(LocalDevicePtr local)
{
SynapticsPrivate *priv = (SynapticsPrivate *)local->private;
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];
int rc;
SYSCALL(rc = ioctl(local->fd, EVIOCGABS(ABS_X), &abs));
- if (rc == 0)
+ if (rc >= 0)
{
xf86Msg(X_INFO, "%s: x-axis range %d - %d\n", local->name,
abs.minimum, abs.maximum);
@@ -130,7 +137,7 @@ event_query_axis_ranges(LocalDevicePtr local)
strerror(errno));
SYSCALL(rc = ioctl(local->fd, EVIOCGABS(ABS_Y), &abs));
- if (rc == 0)
+ if (rc >= 0)
{
xf86Msg(X_INFO, "%s: y-axis range %d - %d\n", local->name,
abs.minimum, abs.maximum);
@@ -140,17 +147,31 @@ event_query_axis_ranges(LocalDevicePtr local)
xf86Msg(X_ERROR, "%s: failed to query axis range (%s)\n", local->name,
strerror(errno));
- 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)
{
xf86Msg(X_INFO, "%s: finger width range %d - %d\n", local->name,
abs.minimum, abs.maximum);
@@ -158,19 +179,19 @@ event_query_axis_ranges(LocalDevicePtr local)
priv->maxw = abs.maximum;
}
- 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)
{
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");
xf86Msg(X_INFO, "%s: buttons:%s\n", local->name, buf);
}
@@ -229,6 +250,8 @@ EventReadHwState(LocalDevicePtr local, struct SynapticsHwInfo *synhw,
struct input_event ev;
Bool v;
struct SynapticsHwState *hw = &(comm->hwState);
+ SynapticsPrivate *priv = (SynapticsPrivate *)local->private;
+ SynapticsSHM *para = priv->synpara;
while (SynapticsReadEvent(comm, &ev)) {
switch (ev.type) {
@@ -304,6 +327,10 @@ EventReadHwState(LocalDevicePtr local, struct SynapticsHwInfo *synhw,
case BTN_B:
hw->guest_right = v;
break;
+ case BTN_TOUCH:
+ if (!priv->has_pressure)
+ hw->z = v ? para->finger_high + 1 : 0;
+ break;
}
break;
case EV_ABS:
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index cc0a29f..688167c 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -145,6 +145,7 @@ typedef struct _SynapticsPrivateRec
Bool has_middle; /* middle button detected for this device */
Bool has_double; /* double click detected for this device */
Bool has_triple; /* triple click detected for this device */
+ Bool has_pressure; /* device reports pressure */
} SynapticsPrivate;
#endif /* _SYNAPTICSSTR_H_ */