On Fri, Aug 19, 2011 at 09:13:33PM +0600, Alexandr Shadchin wrote: > Signed-off-by: Alexandr Shadchin <alexandr.shadc...@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@_drv_la_SOURCES += \ > psmcomm.c > endif > + > +if BUILD_WSCONSCOMM > +@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 <shadc...@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 > + > +#define DEFAULT_WSMOUSE0_DEV "/dev/wsmouse0" DEFAULT_WSMOUSE_DEV, if it's default, the 0 in the define is unnecessary. > +#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. > + > +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? > + > + 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? 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. Cheers, Peter > + > + priv->model = MODEL_SYNAPTICS; > +} > + > +struct SynapticsProtocolOperations wscons_proto_operations = { > + WSConsDeviceOnHook, > + WSConsDeviceOffHook, > + WSConsQueryHardware, > + WSConsReadHwState, > + WSConsAutoDevProbe, > + WSConsReadDevDimensions > +}; > -- > 1.7.6 > _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel