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 *); + +#define DEFAULT_WSMOUSE0_DEV "/dev/wsmouse0" +#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"); +} + +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; + } + + 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; + + 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