[PATCH 10/18] Add multi-touch support
Peter Hutterer
peter.hutterer at who-t.net
Wed Oct 13 21:54:47 PDT 2010
On Wed, Oct 13, 2010 at 08:12:12AM +0200, Takashi Iwai wrote:
> At Wed, 13 Oct 2010 14:25:16 +1000,
> Peter Hutterer wrote:
> >
> > On Fri, Oct 08, 2010 at 07:22:34PM +0200, Takashi Iwai wrote:
> > > Signed-off-by: Takashi Iwai <tiwai at suse.de>
> > > ---
> > > src/eventcomm.c | 56 +++++++++++++++++++--
> > > src/synaptics.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++----
> > > src/synapticsstr.h | 12 +++++
> > > src/synproto.h | 6 ++
> > > 4 files changed, 196 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/src/eventcomm.c b/src/eventcomm.c
> > > index 76ff69d..5969448 100644
> > > --- a/src/eventcomm.c
> > > +++ b/src/eventcomm.c
> > > @@ -53,6 +53,17 @@
> > >
> > > #define SYNAPTICS_LED_SYS_FILE "/sys/class/leds/psmouse::synaptics/brightness"
> > >
> > > +#ifndef SYN_MT_REPORT
> > > +#define SYN_MT_REPORT 2
> > > +#endif
> > > +#ifndef ABS_MT_POSITION_X
> > > +#define ABS_MT_POSITION_X 0x35
> > > +#define ABS_MT_POSITION_Y 0x36
> > > +#endif
> > > +#ifndef ABS_MT_PRESSURE
> > > +#define ABS_MT_PRESSURE 0x3a
> > > +#endif
> > > +
> > > /*****************************************************************************
> > > * Function Definitions
> > > ****************************************************************************/
> > > @@ -168,6 +179,22 @@ event_query_info(InputInfoPtr pInfo)
> > > }
> > > }
> > >
> > > +static void event_query_multi_touch(LocalDevicePtr local)
> > > +{
> > > + SynapticsPrivate *priv = (SynapticsPrivate *)local->private;
> > > + unsigned long absbits[NBITS(ABS_MAX)] = {0};
> > > + int rc;
> > > +
> > > + priv->can_multi_touch = FALSE;
> >
> > has_multitouch would be more in line with the has_left, has_right, etc.
> >
> > > + if (priv->model != MODEL_SYNAPTICS)
> > > + return;
> > > + SYSCALL(rc = ioctl(local->fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits));
> > > + if (rc >= 0 && TEST_BIT(ABS_MT_POSITION_X, absbits)) {
> > > + priv->can_multi_touch = TRUE;
> > > + xf86Msg(X_INFO, "%s: supports multi-touch finger detection\n", local->name);
> > > + }
> > > +}
> > > +
> >
> > I think we should just rely on MT_SLOTS here and wrap devices that don't do
> > it with mtdev. It'll likely make the code simpler (especially in regards to
> > tracking the primary) and I can blame Henrik if the tracking doesn't work ;)
>
> Hm, synaptics devices don't track individual points (MT type A), thus
> MT_SLOTS can't be used.
hence the suggestion to wrap through mtdev, which does the tracking for us.
> > > static void
> > > event_query_clickpad(LocalDevicePtr local)
> > > {
> > > @@ -175,7 +202,7 @@ event_query_clickpad(LocalDevicePtr local)
> > >
> > > /* clickpad device reports only the single left button mask */
> > > if (priv->has_left && !priv->has_right && !priv->has_middle &&
> > > - !priv->has_double &&
> > > + (!priv->has_double || priv->can_multi_touch) &&
> > > priv->model == MODEL_SYNAPTICS) {
> > > priv->is_clickpad = TRUE;
> > > /* enable right/middle button caps; otherwise gnome-settings-daemon
> > > @@ -383,21 +410,27 @@ EventReadHwState(InputInfoPtr pInfo,
> > > switch (ev.type) {
> > > case EV_SYN:
> > > switch (ev.code) {
> > > + case SYN_MT_REPORT:
> > > + hw->multi_touch_count++;
> > > + break;
> > > case SYN_REPORT:
> > > if (comm->oneFinger)
> > > - hw->numFingers = 1;
> > > + hw->numFingers = hw->multi_touch_count ? hw->multi_touch_count : 1;
> > > else if (comm->twoFingers)
> > > hw->numFingers = 2;
> > > else if (comm->threeFingers)
> > > hw->numFingers = 3;
> > > else
> > > hw->numFingers = 0;
> > > + hw->multi_touch = hw->multi_touch_count;
> > > + hw->multi_touch_count = 0;
> > > /* if the coord is out of range, we filter it out */
> > > if (priv->is_clickpad && hw->z > 0 && (hw->x < minx || hw->x > maxx || hw->y < miny || hw->y > maxy))
> > > return FALSE;
> > > *hwRet = *hw;
> > > return TRUE;
> > > }
> > > + break;
> > > case EV_KEY:
> > > v = (ev.value ? TRUE : FALSE);
> > > switch (ev.code) {
> > > @@ -458,13 +491,25 @@ EventReadHwState(InputInfoPtr pInfo,
> > > case EV_ABS:
> > > switch (ev.code) {
> > > case ABS_X:
> > > - hw->x = ev.value;
> > > + case ABS_MT_POSITION_X:
> > > + if (hw->multi_touch_count)
> > > + hw->multi_touch_x = ev.value;
> > > + else
> > > + hw->x = ev.value;
> >
> > if I read this correctly this patch doesn't add multi-touch support but only
> > two-finger support, otherwise you'd be overwriting the value after the
> > second finger.
>
> The odd thing is that there is no third finger tracking. Synaptics devices
> track up to two finger points although it can detect number of fingers up to
> three.
oh, I didn't know this. that should go into a comment and the commit message
then. Though a few touchpads support up to 4 fingers, isn't it (Henrik,
what about the apple touchpads?)
and either way, keeping it generic from the start saves us some unexpected
pain later.
Cheers,
Peter
More information about the xorg-devel
mailing list