[PATCH synaptics] Adding support for OpenBSD

Alexandr Shadchin alexandr.shadchin at gmail.com
Fri Aug 19 08:13:33 PDT 2011


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 *);
+
+#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



More information about the xorg-devel mailing list