[PATCH synaptics] Adding support for OpenBSD

Alexandr Shadchin alexandr.shadchin at gmail.com
Tue Aug 23 08:34:58 PDT 2011


On Tue, Aug 23, 2011 at 01:20:10PM +1000, Peter Hutterer wrote:
> On Fri, Aug 19, 2011 at 09:13:33PM +0600, Alexandr Shadchin wrote:
> > Signed-off-by: Alexandr Shadchin <Alexandr.Shadchin at gmail.com>
> > ---
> >  configure.ac     |    8 ++
> >  src/Makefile.am  |    5 +
> >  src/synaptics.c  |    3 +
> >  src/synproto.h   |    3 +
> >  src/wsconscomm.c |  278 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  5 files changed, 297 insertions(+), 0 deletions(-)
> >  create mode 100644 src/wsconscomm.c
> > 
> > diff --git a/configure.ac b/configure.ac
> > index 09306ec..c3807e8 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -110,6 +110,10 @@ case "${host}" in
> >  	BUILD_PS2COMM="yes"
> >  	BUILD_PSMCOMM="yes"
> >  	;;
> > +*openbsd*)
> > +	AC_MSG_RESULT([wsconscomm])
> > +	BUILD_WSCONSCOMM="yes"
> > +	;;
> >  *)
> >  	AC_MSG_RESULT([none])
> >  	;;
> > @@ -123,9 +127,13 @@ fi
> >  if test "x$BUILD_PS2COMM" = xyes; then
> >      AC_DEFINE(BUILD_PS2COMM, 1, [Optional backend ps2comm and alpscomm enabled])
> >  fi
> > +if test "x$BUILD_WSCONSCOMM" = xyes; then
> > +    AC_DEFINE(BUILD_WSCONSCOMM, 1, [Optional backend wsconscomm enabled])
> > +fi
> >  AM_CONDITIONAL([BUILD_EVENTCOMM], [test "x${BUILD_EVENTCOMM}" = "xyes"])
> >  AM_CONDITIONAL([BUILD_PSMCOMM], [test "x${BUILD_PSMCOMM}" = "xyes"])
> >  AM_CONDITIONAL([BUILD_PS2COMM], [test "x${BUILD_PS2COMM}" = "xyes"])
> > +AM_CONDITIONAL([BUILD_WSCONSCOMM], [test "x${BUILD_WSCONSCOMM}" = "xyes"])
> >  
> >  # -----------------------------------------------------------------------------
> >  #			Dependencies for synclient and syndaemon
> > diff --git a/src/Makefile.am b/src/Makefile.am
> > index 5e04670..ef297c8 100644
> > --- a/src/Makefile.am
> > +++ b/src/Makefile.am
> > @@ -50,3 +50,8 @@ if BUILD_PSMCOMM
> >  @DRIVER_NAME at _drv_la_SOURCES += \
> >  	psmcomm.c
> >  endif
> > +
> > +if BUILD_WSCONSCOMM
> > + at DRIVER_NAME@_drv_la_SOURCES += \
> > +	wsconscomm.c
> > +endif
> > diff --git a/src/synaptics.c b/src/synaptics.c
> > index cf91b9f..dd0142c 100644
> > --- a/src/synaptics.c
> > +++ b/src/synaptics.c
> > @@ -150,6 +150,9 @@ const static struct {
> >      {"psaux", &psaux_proto_operations},
> >      {"alps", &alps_proto_operations},
> >  #endif
> > +#ifdef BUILD_WSCONSCOMM
> > +    {"wscons", &wscons_proto_operations},
> > +#endif
> >      {NULL, NULL}
> >  };
> >  
> > diff --git a/src/synproto.h b/src/synproto.h
> > index 75f90e4..260c248 100644
> > --- a/src/synproto.h
> > +++ b/src/synproto.h
> > @@ -89,5 +89,8 @@ extern struct SynapticsProtocolOperations event_proto_operations;
> >  #ifdef BUILD_PSMCOMM
> >  extern struct SynapticsProtocolOperations psm_proto_operations;
> >  #endif /* BUILD_PSMCOMM */
> > +#ifdef BUILD_WSCONSCOMM
> > +extern struct SynapticsProtocolOperations wscons_proto_operations;
> > +#endif /* BUILD_WSCONSCOMM */
> >  
> >  #endif /* _SYNPROTO_H_ */
> > diff --git a/src/wsconscomm.c b/src/wsconscomm.c
> > new file mode 100644
> > index 0000000..2b5b2d8
> > --- /dev/null
> > +++ b/src/wsconscomm.c
> > @@ -0,0 +1,278 @@
> > +/*
> > + * Copyright ? 2011 Alexandr Shadchin <shadchin at openbsd.org>
> > + *
> > + * Permission to use, copy, modify, and distribute this software for any
> > + * purpose with or without fee is hereby granted, provided that the above
> > + * copyright notice and this permission notice appear in all copies.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> > + */
> > +
> > +#ifdef HAVE_CONFIG_H
> > +#include "config.h"
> > +#endif
> > +
> > +#include <xorg-server.h>
> > +#include <unistd.h>
> > +#include <sys/ioctl.h>
> > +#include <errno.h>
> > +#include <string.h>
> > +#include "synproto.h"
> > +#include "synaptics.h"
> > +#include "synapticsstr.h"
> > +#include <xf86.h>
> > +
> > +#include <dev/wscons/wsconsio.h>
> > +
> > +extern int priv_open_device(const char *);
> 
> is this a BSD-specific function? can't seem to find the definition for it
> anywhere
> 

Err, this is a OpenBSD-specific function. I'll replace it for a standard open()
in next patch.

> > +
> > +#define DEFAULT_WSMOUSE0_DEV		"/dev/wsmouse0"
> 
> DEFAULT_WSMOUSE_DEV, if it's default, the 0 in the define is unnecessary.
> 

I agree.

> > +#define NEVENTS				64
> > +
> > +static const char *synaptics_devs[] = {
> > +    DEFAULT_WSMOUSE0_DEV,
> > +    NULL
> > +};
> > +
> > +static Bool
> > +WSConsIsSynaptics(InputInfoPtr pInfo, const char *device)
> > +{
> > +    int wsmouse_type, fd = -1;
> > +    Bool res = FALSE;
> > +
> > +    fd = priv_open_device(device);
> > +
> > +    if (fd < 0)
> > +        return FALSE;
> > +
> > +    if (ioctl(fd, WSMOUSEIO_GTYPE, &wsmouse_type) == -1) {
> > +        xf86IDrvMsg(pInfo, X_ERROR, "cannot get mouse type\n");
> > +        goto out;
> > +    }
> > +
> > +    if (wsmouse_type == WSMOUSE_TYPE_SYNAPTICS)
> > +        res = TRUE;
> > +
> > +out:
> > +    close(fd);
> > +    return res;
> > +}
> > +
> > +static void
> > +WSConsDeviceOnHook(InputInfoPtr pInfo, SynapticsParameters *para)
> > +{
> > +    int wsmouse_mode = WSMOUSE_NATIVE;
> > +
> > +    if (ioctl(pInfo->fd, WSMOUSEIO_SETMODE, &wsmouse_mode) == -1)
> > +        xf86IDrvMsg(pInfo, X_ERROR, "cannot set native mode\n");
> > +}
> > +
> > +static void
> > +WSConsDeviceOffHook(InputInfoPtr pInfo)
> > +{
> > +    int wsmouse_mode = WSMOUSE_COMPAT;
> > +
> > +    if (ioctl(pInfo->fd, WSMOUSEIO_SETMODE, &wsmouse_mode) == -1)
> > +        xf86IDrvMsg(pInfo, X_ERROR, "cannot set compat mode\n");
> > +}
> 
> if these two are an error, we should change the On/Off hooks to return
> boolean so we can bail out of the caller. that'd be a separate patch, at
> least eventcomm.c needs it too.
> 

Hmm, in http://cgit.freedesktop.org/xorg/driver/xf86-input-synaptics/
On/Off hooks is 'static void'. Maybe it's in your local repository?
Could not you show this patch?

> > +
> > +static Bool
> > +WSConsQueryHardware(InputInfoPtr pInfo)
> > +{
> > +    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
> > +    struct CommData *comm = &priv->comm;
> > +    int wsmouse_type;
> > +
> > +    if (ioctl(pInfo->fd, WSMOUSEIO_GTYPE, &wsmouse_type) == -1) {
> > +        xf86IDrvMsg(pInfo, X_ERROR, "cannot get mouse type\n");
> > +        return FALSE;
> > +    }
> > +
> > +    if (wsmouse_type != WSMOUSE_TYPE_SYNAPTICS)
> > +        return FALSE;
> > +
> > +    if (comm->buffer)
> > +        XisbFree(comm->buffer);
> > +    comm->buffer = XisbNew(pInfo->fd, sizeof(struct wscons_event) * NEVENTS);
> > +    if (comm->buffer == NULL)
> > +        return FALSE;
> > +
> > +    return TRUE;
> > +}
> > +
> > +static Bool
> > +WSConsReadHwState(InputInfoPtr pInfo,
> > +    struct CommData *comm, struct SynapticsHwState *hwRet)
> > +{
> > +    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
> > +    struct SynapticsHwState *hw = &(comm->hwState);
> > +    struct wscons_event event;
> > +    unsigned char *pBuf = (unsigned char *)&event;
> > +    int c, n = 0;
> > +    Bool v;
> > +
> > +    XisbBlockDuration(comm->buffer, -1);
> > +    while (n < sizeof(struct wscons_event) && (c = XisbRead(comm->buffer)) >= 0)
> > +        pBuf[n++] = (unsigned char)c;
> > +
> > +    if (n != sizeof(struct wscons_event))
> > +        return FALSE;
> > +
> > +    switch (event.type) {
> > +    case WSCONS_EVENT_MOUSE_UP:
> > +    case WSCONS_EVENT_MOUSE_DOWN:
> > +        v = (event.type == WSCONS_EVENT_MOUSE_DOWN) ? TRUE : FALSE;
> > +        switch (event.value) {
> > +        case 0:
> > +            hw->left = v;
> > +            break;
> > +        case 1:
> > +            hw->middle = v;
> > +            break;
> > +        case 2:
> > +            hw->right = v;
> > +            break;
> > +        case 3:
> > +            hw->up = v;
> > +            break;
> > +        case 4:
> > +            hw->down = v;
> > +            break;
> > +        case 5:
> > +            hw->multi[0] = v;
> > +            break;
> > +        case 6:
> > +            hw->multi[1] = v;
> > +            break;
> > +        case 7:
> > +            hw->multi[2] = v;
> > +            break;
> > +        case 8:
> > +            hw->multi[3] = v;
> > +            break;
> > +        case 9:
> > +            hw->multi[4] = v;
> > +            break;
> > +        case 10:
> > +            hw->multi[5] = v;
> > +            break;
> > +        case 11:
> > +            hw->multi[6] = v;
> > +            break;
> > +        case 12:
> > +            hw->multi[7] = v;
> > +            break;
> > +        }
> > +        break;
> > +    case WSCONS_EVENT_MOUSE_ABSOLUTE_X:
> > +        if (event.value <= 1)
> > +            return FALSE;
> > +        hw->x = event.value;
> > +        break;
> > +    case WSCONS_EVENT_MOUSE_ABSOLUTE_Y:
> > +        if (event.value <= 1)
> > +            return FALSE;
> > +        hw->y = priv->maxy - event.value + priv->miny;
> > +        break;
> > +    case WSCONS_EVENT_MOUSE_ABSOLUTE_Z:
> > +        hw->z = event.value;
> > +        break;
> > +    case WSCONS_EVENT_MOUSE_ABSOLUTE_W:
> > +        switch (event.value) {
> > +        case 0:
> > +            hw->fingerWidth = 5;
> > +            hw->numFingers = 2;
> > +            break;
> > +        case 1:
> > +            hw->fingerWidth = 5;
> > +            hw->numFingers = 3;
> > +            break;
> > +        case 4 ... 5:
> > +            hw->fingerWidth = event.value;
> > +            hw->numFingers = 1;
> > +            break;
> > +        }
> > +        break;
> > +    default:
> > +        return FALSE;
> > +    }
> > +
> > +    *hwRet = *hw;
> > +    return TRUE;
> > +}
> > +
> > +static Bool
> > +WSConsAutoDevProbe(InputInfoPtr pInfo, const char *device)
> > +{
> > +    int i;
> > +
> > +    if (device && WSConsIsSynaptics(pInfo, device))
> > +        return TRUE;
> > +
> > +    for (i = 0; synaptics_devs[i]; i++)
> > +        if (WSConsIsSynaptics(pInfo, synaptics_devs[i])) {
> > +            xf86IDrvMsg(pInfo, X_PROBED, "auto-dev sets device to %s\n",
> > +                synaptics_devs[i]);
> > +            xf86ReplaceStrOption(pInfo->options, "Device", synaptics_devs[i]);
> > +            return TRUE;
> > +        }
> 
> if you're only testing one device, this seems a bit overengineered? is there
> a case where the touchpad isn't on wsmouse0?
> 

I agree, overdone it :-) I will correct it.

> > +
> > +    return FALSE;
> > +}
> > +
> > +static void
> > +WSConsReadDevDimensions(InputInfoPtr pInfo)
> > +{
> > +    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
> > +    struct wsmouse_calibcoords wsmc;
> > +
> > +    if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS, &wsmc) != 0) {
> > +        xf86IDrvMsg(pInfo, X_ERROR, "failed to query axis range (%s)\n",
> > +            strerror(errno));
> > +        return;
> > +    }
> > +
> > +    priv->minx = wsmc.minx;
> > +    priv->maxx = wsmc.maxx;
> > +    priv->resx = wsmc.resx;
> > +    xf86IDrvMsg(pInfo, X_PROBED, "x-axis range %d - %d resolution %d\n",
> > +        priv->minx, priv->maxx, priv->resx);
> > +
> > +    priv->miny = wsmc.miny;
> > +    priv->maxy = wsmc.maxy;
> > +    priv->resy = wsmc.resy;
> > +    xf86IDrvMsg(pInfo, X_PROBED, "y-axis range %d - %d resolution %d\n",
> > +        priv->miny, priv->maxy, priv->resy);
> > +
> > +    priv->minp = 0;
> > +    priv->maxp = 256;
> > +
> > +    priv->minw = 0;
> > +    priv->maxw = 16;
> > +
> > +    priv->has_pressure = TRUE;
> > +    priv->has_width = TRUE;
> > +    priv->has_left = TRUE;
> > +    priv->has_right = TRUE;
> > +    priv->has_middle = TRUE;
> > +    priv->has_double = TRUE;
> > +    priv->has_triple = TRUE;
> > +    priv->has_scrollbuttons = TRUE;
> 
> urgh. you can't query these values?

yes, no standard methods

> user-space tools and even the driver adjusts itself depending what features
> are available, simply claiming all are there will lead to some confusion.
> 
> i recommend at least disabling has_scrollbuttons, because I don't think
> there's many laptops out there that still have those.
> 

make sense, I will correct it.

> Cheers,
>   Peter
> 
> > +
> > +    priv->model = MODEL_SYNAPTICS;
> > +}
> > +
> > +struct SynapticsProtocolOperations wscons_proto_operations = {
> > +    WSConsDeviceOnHook,
> > +    WSConsDeviceOffHook,
> > +    WSConsQueryHardware,
> > +    WSConsReadHwState,
> > +    WSConsAutoDevProbe,
> > +    WSConsReadDevDimensions
> > +};
> > -- 
> > 1.7.6
> > 

-- 
Alexandr Shadchin



More information about the xorg-devel mailing list