summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--freebsd_mouse.h59
-rw-r--r--ps2comm.c2
-rw-r--r--psmcomm.c169
-rw-r--r--psmcomm.h7
-rw-r--r--synaptics.c11
-rw-r--r--synproto.h4
7 files changed, 250 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index eddff13..7e5cafc 100644
--- a/Makefile
+++ b/Makefile
@@ -52,8 +52,8 @@ CC = gcc
LDCOMBINEFLAGS = -r
-SRCS = synaptics.c ps2comm.c eventcomm.c
-OBJS = synaptics.o ps2comm.o eventcomm.o
+SRCS = synaptics.c ps2comm.c eventcomm.c psmcomm.c
+OBJS = synaptics.o ps2comm.o eventcomm.o psmcomm.o
.c.o:
$(RM) $@
@@ -99,6 +99,7 @@ syndaemon : syndaemon.o
synaptics.o : synaptics.h synproto.h Makefile
ps2comm.o : ps2comm.h synproto.h synaptics.h
eventcomm.o : eventcomm.h linux_input.h synproto.h synaptics.h
+psmcomm.o : freebsd_mouse.h psmcomm.h synproto.h synaptics.h
synclient.o : synaptics.h
syndaemon.o : synaptics.h
@@ -117,6 +118,7 @@ ALLFILES = COMPATIBILITY FILES INSTALL INSTALL.DE INSTALL.FR LICENSE Makefile \
NEWS README README.alps TODO Xincludes/ alps.patch linux_input.h \
pc_keyb.c.diff.2.4.3 \
synproto.h ps2comm.c ps2comm.h eventcomm.c eventcomm.h \
+ psmcomm.c psmcomm.h freebsd_mouse.h \
synaptics.c synaptics.h synaptics.spec \
synclient.c syndaemon.c
diff --git a/freebsd_mouse.h b/freebsd_mouse.h
new file mode 100644
index 0000000..7af95b8
--- /dev/null
+++ b/freebsd_mouse.h
@@ -0,0 +1,59 @@
+#ifndef _FREEBSD_MOUSE_H_
+#define _FREEBSD_MOUSE_H_
+
+
+typedef struct mousehw {
+ int buttons; /* -1 if unknown */
+ int iftype; /* MOUSE_IF_XXX */
+ int type; /* mouse/track ball/pad... */
+ int model; /* I/F dependent model ID: MOUSE_MODEL_XXX */
+ int hwid; /* I/F dependent hardware ID
+ * for the PS/2 mouse, it will be PSM_XXX_ID
+ */
+} mousehw_t;
+
+/* ioctls */
+#define MOUSE_GETSTATUS _IOR('M', 0, mousestatus_t)
+#define MOUSE_GETHWINFO _IOR('M', 1, mousehw_t)
+#define MOUSE_GETMODE _IOR('M', 2, mousemode_t)
+#define MOUSE_SETMODE _IOW('M', 3, mousemode_t)
+#define MOUSE_GETLEVEL _IOR('M', 4, int)
+#define MOUSE_SETLEVEL _IOW('M', 5, int)
+#define MOUSE_GETVARS _IOR('M', 6, mousevar_t)
+#define MOUSE_SETVARS _IOW('M', 7, mousevar_t)
+#define MOUSE_READSTATE _IOWR('M', 8, mousedata_t)
+#define MOUSE_READDATA _IOWR('M', 9, mousedata_t)
+#define MOUSE_SYNGETHWINFO _IOR('M', 10, synapticshw_t)
+
+#define MOUSE_SYNAPTICS_CMD _IOW('M', 10, char)
+#define MOUSE_SYNAPTICS_INFO _IOW('M', 11, char)
+#define MOUSE_SYNAPTICS_ENABLE_PASSTHROUGH _IOW('M', 12, char)
+
+
+typedef struct synapticshw {
+ int infoMajor;
+ int infoMinor;
+ int infoRot180;
+ int infoPortrait;
+ int infoSensor;
+ int infoHardware;
+ int infoNewAbs;
+ int capPen;
+ int infoSimplC;
+ int infoGeometry;
+ int capExtended;
+ int capSleep;
+ int capFourButtons;
+ int capMultiFinger;
+ int capPalmDetect;
+ int capPassthrough;
+} synapticshw_t;
+
+
+#define MOUSE_MODEL_SYNAPTICS 13
+
+/* Synaptics Touchpad */
+#define MOUSE_SYNAPTICS_PACKETSIZE 6
+
+
+#endif /* _FREEBSD_MOUSE_H_ */
diff --git a/ps2comm.c b/ps2comm.c
index 3a1550d..c9084b4 100644
--- a/ps2comm.c
+++ b/ps2comm.c
@@ -414,7 +414,7 @@ ps2_query_is_synaptics(int fd)
}
}
-static void
+void
ps2_print_ident(const struct SynapticsHwInfo *synhw)
{
xf86Msg(X_PROBED, " Synaptics Touchpad, model: %d\n", SYN_ID_MODEL(*synhw));
diff --git a/psmcomm.c b/psmcomm.c
new file mode 100644
index 0000000..ef80137
--- /dev/null
+++ b/psmcomm.c
@@ -0,0 +1,169 @@
+/* Copyright (C) 2001 Stefan Gmeiner <riddlebox@freesurf.ch>
+ *
+ * Copyright (c) 1997 C. Scott Ananian <cananian@alumni.priceton.edu>
+ * Copyright (c) 1998-2000 Bruce Kalk <kall@compass.com>
+ * code für the special synaptics commands (from the tpconfig-source)
+ *
+ * Synaptics Passthrough Support
+ * Copyright (c) 2002 Linuxcare Inc. David Kennedy <dkennedy@linuxcare.com>
+ * adapted to version 0.12.1
+ * Copyright (c) 2003 Fred Hucht <fred@thp.Uni-Duisburg.de>
+ *
+ * Copyright (c) 2004 Arne Schwabe <schwabe@uni-paderborn.de>
+ * FreeBSD Support
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "psmcomm.h"
+#include "synproto.h"
+#include "synaptics.h"
+#include <xf86.h>
+
+#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
+
+void ps2_print_ident(const struct SynapticsHwInfo *synhw);
+
+/*
+ * Identify Touchpad
+ * See also the SYN_ID_* macros
+ */
+static Bool
+psm_synaptics_identify(int fd, synapticshw_t *ident)
+{
+ int ret;
+
+ SYSCALL(ret = ioctl(fd, MOUSE_SYNGETHWINFO, ident));
+ if (ret == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/* This define is used in a ioctl but not in mouse.h :/ */
+#define PSM_LEVEL_NATIVE 2
+
+static Bool
+PSMQueryIsSynaptics(LocalDevicePtr local)
+{
+ int ret;
+ int level = PSM_LEVEL_NATIVE;
+ mousehw_t mhw;
+
+ /* Put the device in native protocol mode to be sure
+ * Otherwise HWINFO will not return the right id
+ * And we will need native mode anyway ...
+ */
+ SYSCALL(ret = ioctl(local->fd, MOUSE_SETLEVEL, &level));
+ if (ret != 0) {
+ xf86Msg(X_ERROR, "%s Can't set native mode\n", local->name);
+ return FALSE;
+ }
+ SYSCALL(ret = ioctl(local->fd, MOUSE_GETHWINFO, &mhw));
+ if (ret != 0) {
+ xf86Msg(X_ERROR, "%s Can't get hardware info\n", local->name);
+ return FALSE;
+ }
+
+ if (mhw.model == MOUSE_MODEL_SYNAPTICS) {
+ return TRUE;
+ } else {
+ xf86Msg(X_ERROR, "%s Found no Synaptics, found Mouse model %d instead\n",
+ local->name, mhw.model);
+ return FALSE;
+ }
+}
+
+static void
+PSMDeviceOnHook(LocalDevicePtr local)
+{
+}
+
+static void
+PSMDeviceOffHook(LocalDevicePtr local)
+{
+}
+
+static void
+convert_hw_info(const synapticshw_t *psm_ident, struct SynapticsHwInfo *synhw)
+{
+ memset(synhw, 0, sizeof(*synhw));
+ synhw->model_id = ((psm_ident->infoRot180 << 23) |
+ (psm_ident->infoPortrait << 22) |
+ (psm_ident->infoSensor << 16) |
+ (psm_ident->infoHardware << 9) |
+ (psm_ident->infoNewAbs << 7) |
+ (psm_ident->capPen << 6) |
+ (psm_ident->infoSimplC << 5) |
+ (psm_ident->infoGeometry));
+ synhw->capabilities = ((psm_ident->capExtended << 23) |
+ (psm_ident->capPassthrough << 7) |
+ (psm_ident->capSleep << 4) |
+ (psm_ident->capFourButtons << 3) |
+ (psm_ident->capMultiFinger << 1) |
+ (psm_ident->capPalmDetect));
+ synhw->ext_cap = 0;
+ synhw->identity = ((psm_ident->infoMajor) |
+ (0x47 << 8) |
+ (psm_ident->infoMinor << 16));
+}
+
+static Bool
+PSMQueryHardware(LocalDevicePtr local, struct SynapticsHwInfo *synhw)
+{
+ synapticshw_t psm_ident;
+
+ /* is the synaptics touchpad active? */
+ if (!PSMQueryIsSynaptics(local))
+ return FALSE;
+
+ xf86Msg(X_PROBED, "%s synaptics touchpad found\n", local->name);
+
+ if (!psm_synaptics_identify(local->fd, &psm_ident))
+ return FALSE;
+
+ convert_hw_info(&psm_ident, synhw);
+
+ /* Check to see if the host mouse supports a guest */
+ synhw->hasGuest = FALSE;
+ if (psm_ident.capPassthrough) {
+ synhw->hasGuest = TRUE;
+ }
+
+ ps2_print_ident(synhw);
+
+ return TRUE;
+}
+
+static Bool
+PSMReadHwState(LocalDevicePtr local, struct SynapticsHwInfo *synhw,
+ struct CommData *comm, struct SynapticsHwState *hwRet)
+{
+ return psaux_proto_operations.ReadHwState(local, synhw, comm, hwRet);
+}
+
+static Bool PSMAutoDevProbe(LocalDevicePtr local)
+{
+ return FALSE;
+}
+
+struct SynapticsProtocolOperations psm_proto_operations = {
+ PSMDeviceOnHook,
+ PSMDeviceOffHook,
+ PSMQueryHardware,
+ PSMReadHwState,
+ PSMAutoDevProbe
+};
diff --git a/psmcomm.h b/psmcomm.h
new file mode 100644
index 0000000..6d64df6
--- /dev/null
+++ b/psmcomm.h
@@ -0,0 +1,7 @@
+#ifndef _PSMCOMM_H_
+#define _PSMCOMM_H_
+
+#include <sys/ioctl.h>
+#include "freebsd_mouse.h"
+
+#endif /* _PSMCOMM_H_ */
diff --git a/synaptics.c b/synaptics.c
index a532e4b..348181c 100644
--- a/synaptics.c
+++ b/synaptics.c
@@ -171,10 +171,12 @@ SetDeviceAndProtocol(LocalDevicePtr local)
enum SynapticsProtocol proto = SYN_PROTO_PSAUX;
str_par = xf86FindOptionValue(local->options, "Protocol");
- if (str_par && !strcmp(str_par, "event")) {
- proto = SYN_PROTO_EVENT;
- } else if (str_par && !strcmp(str_par, "psaux")) {
+ if (str_par && !strcmp(str_par, "psaux")) {
/* Already set up */
+ } else if (str_par && !strcmp(str_par, "event")) {
+ proto = SYN_PROTO_EVENT;
+ } else if (str_par && !strcmp(str_par, "psm")) {
+ proto = SYN_PROTO_PSM;
} else { /* default to auto-dev */
if (event_proto_operations.autoDevProbe(local))
proto = SYN_PROTO_EVENT;
@@ -186,7 +188,8 @@ SetDeviceAndProtocol(LocalDevicePtr local)
case SYN_PROTO_EVENT:
priv->proto_ops = &event_proto_operations;
break;
- default:
+ case SYN_PROTO_PSM:
+ priv->proto_ops = &psm_proto_operations;
break;
}
}
diff --git a/synproto.h b/synproto.h
index 1b1d042..d73c1e8 100644
--- a/synproto.h
+++ b/synproto.h
@@ -66,7 +66,8 @@ struct CommData {
enum SynapticsProtocol {
SYN_PROTO_PSAUX, /* Raw psaux device */
- SYN_PROTO_EVENT /* Linux kernel event interface */
+ SYN_PROTO_EVENT, /* Linux kernel event interface */
+ SYN_PROTO_PSM /* FreeBSD psm driver */
};
struct SynapticsHwInfo;
@@ -83,6 +84,7 @@ struct SynapticsProtocolOperations {
extern struct SynapticsProtocolOperations psaux_proto_operations;
extern struct SynapticsProtocolOperations event_proto_operations;
+extern struct SynapticsProtocolOperations psm_proto_operations;
#endif /* _SYNPROTO_H_ */