[PATCH] xf86-input-acecad: automatic device detection (v2)
Giuseppe Bilotta
giuseppe.bilotta at gmail.com
Wed Apr 25 16:56:06 PDT 2007
When the "Device" option is missing or set to "auto-dev" the acecad module will
attempt autodetection of the correct device.
Currently, it will probe all /dev/input/eventX nodes until one is found that
reports a device name that begins with "ACECAD".
Changes from v1:
* corrections as per Daniel Stone
* report that auto-detection is not implemented when LINUX_INPUT is not defined
---
src/acecad.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 84 insertions(+), 0 deletions(-)
diff --git a/src/acecad.c b/src/acecad.c
index c10aaf4..a640f55 100644
--- a/src/acecad.c
+++ b/src/acecad.c
@@ -65,6 +65,7 @@
#ifdef LINUX_INPUT
#include <errno.h>
+#include <fcntl.h>
#endif
/*****************************************************************************
@@ -181,6 +182,75 @@ IsUSBLine(int fd)
return 0;
}
}
+
+/* Heavyly inspired by synpatics/eventcomm.c */
+#define DEV_INPUT_EVENT "/dev/input"
+#define EVENT_DEV_NAME "event"
+#define EV_DEV_NAME_MAXLEN 64
+
+static Bool
+fd_query_acecad(int fd) {
+ char name[256] = "Unknown";
+ char ace_name[7] = "acecad";
+ ioctl(fd, EVIOCGNAME(sizeof(name)), name);
+ name[6] = '\0';
+ if (xf86NameCmp(name, ace_name) == 0)
+ return TRUE;
+ return FALSE;
+}
+
+static Bool
+AceCadAutoDevProbe(LocalDevicePtr local)
+{
+ /* We are trying to find the right eventX device */
+ int i;
+ Bool have_evdev = FALSE;
+ int noent_cnt = 0;
+ const int max_skip = 10;
+
+ xf86Msg(X_INFO, "%s: probing event devices for Acecad tablets\n", local->name);
+ for (i = 0; ; i++) {
+ char fname[64];
+ int fd = -1;
+ Bool is_acecad;
+
+ int np = snprintf(fname, EV_DEV_NAME_MAXLEN, "%s/%s%d", DEV_INPUT_EVENT, EVENT_DEV_NAME, i);
+ if (np < 0 || np >= EV_DEV_NAME_MAXLEN) {
+ xf86Msg(X_WARNING, "too many devices, giving up");
+ break;
+ }
+ SYSCALL(fd = open(fname, O_RDONLY));
+ if (fd < 0) {
+ if (errno == ENOENT) {
+ if (++noent_cnt >= max_skip)
+ break;
+ else
+ continue;
+ } else {
+ continue;
+ }
+ }
+ noent_cnt = 0;
+ have_evdev = TRUE;
+ is_acecad = fd_query_acecad(fd);
+ SYSCALL(close(fd));
+ if (is_acecad) {
+ xf86Msg(X_PROBED, "%s auto-dev sets device to %s\n",
+ local->name, fname);
+ xf86ReplaceStrOption(local->options, "Device", fname);
+ return TRUE;
+ }
+ }
+ xf86Msg(X_ERROR, "%s: no Acecad event device found (checked %d nodes)\n",
+ local->name, i + 1);
+ if (i <= max_skip)
+ xf86Msg(X_ERROR, "%s: The /dev/input/event* device nodes seem to be missing\n",
+ local->name);
+ if (i > max_skip && !have_evdev)
+ xf86Msg(X_ERROR, "%s: The evdev kernel module seems to be missing\n", local->name);
+ return FALSE;
+}
+
#endif
static InputInfoPtr
@@ -219,6 +289,20 @@ AceCadPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
priv->acecadInc = xf86SetIntOption(local->options, "Increment", 0 );
+ s = xf86FindOptionValue(local->options, "Device");
+ if (!s || (s && (xf86NameCmp(s, "auto-dev") == 0))) {
+#ifdef LINUX_INPUT
+ if (!AceCadAutoDevProbe(local))
+ {
+ xf86Msg(X_ERROR, "%s: unable to find device\n", local->name);
+ goto SetupProc_fail;
+ }
+#else
+ xf86Msg(X_NOT_IMPLEMENTED, "%s: device autodetection not implemented, sorry\n", local->name);
+ goto SetupProc_fail;
+#endif
+ }
+
local->fd = xf86OpenSerial (local->options);
if (local->fd == -1)
{
--
1.5.1.2
More information about the xorg
mailing list