summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Osterlund <petero2@telia.com>2003-09-24 23:03:43 +0200
committerPeter Osterlund <petero2@telia.com>2006-04-09 04:01:12 +0200
commitfe3d1e6d2bae13264eb85d2466d1e8c78686d993 (patch)
treeb75f696f20f2fd7756b830bed53da81979a558ba
parent95256de7cafa261258f02152a89e6f272c0e498c (diff)
Use the EVIOCGID ioctl for synaptics event device auto
detection. This is much simpler than parsing /proc/bus/input/devices and more robust too.
-rw-r--r--linux_input.h18
-rw-r--r--synaptics.c128
2 files changed, 41 insertions, 105 deletions
diff --git a/linux_input.h b/linux_input.h
index 1442dfd..39762d5 100644
--- a/linux_input.h
+++ b/linux_input.h
@@ -14,9 +14,19 @@ struct input_event {
unsigned long tv_usec;
unsigned short type;
unsigned short code;
- unsigned int value;
+ int value;
};
+struct input_id {
+ unsigned short bustype;
+ unsigned short vendor;
+ unsigned short product;
+ unsigned short version;
+};
+
+#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
+
+
#define EV_SYN 0x00
#define EV_KEY 0x01
#define EV_REL 0x02
@@ -44,4 +54,10 @@ struct input_event {
#define MSC_GESTURE 0x02
+
+#define BUS_I8042 0x11
+
+#define PSMOUSE_SYNAPTICS 7
+
+
#endif /* _LINUX_INPUT_H_ */
diff --git a/synaptics.c b/synaptics.c
index 1767b45..feaf2d4 100644
--- a/synaptics.c
+++ b/synaptics.c
@@ -45,6 +45,7 @@
* Standard Headers
****************************************************************************/
+#include <sys/ioctl.h>
#include <misc.h>
#include <xf86.h>
#define NEED_XF86_TYPES
@@ -93,10 +94,8 @@ typedef enum {
#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
/* for auto-dev: */
-#define INP_DEV_N "N: Name=\"SynPS/2 "
-#define INP_DEV_H "H: Handlers="
-#define DEV_INPUT_EVENT "/dev/input/"
-#define PROC_BUS_INPUT_DEV "/proc/bus/input/devices"
+#define DEV_INPUT_EVENT "/dev/input"
+#define EVENT_DEV_NAME "event"
#define VERSION "0.11.4"
@@ -150,55 +149,6 @@ XF86ModuleData synapticsModuleData = {&VersionRec, &SetupProc, NULL };
* Function Definitions
****************************************************************************/
-/*
- * This is used to read /proc/bus/input/devices line by line...
- * Input: fd: a filehandle, opened for reading.
- * Output: line, len: Pointing to a string.
- * ExitCode: 0 success, -1 EOF then line+len are not to use
- */
-static int
-GetlineBuffSys(char **line, size_t *len,int fd)
-{
-#define BLEN 100 /* must hold the whole line, to get a match */
- static char buffer[BLEN + 1]; /* buffer to hold the rest from last call */
- static int brest = 0, old_i = 0; /* rest and its start in buffer[] */
- static char first_char = 0; /* As it made place for the term.-'\0'... */
- int read_len, i;
-
- /* In the buffer[] are still brest characters, starting at old_i.*/
- if (old_i)
- memmove(buffer, buffer + old_i, brest);
- buffer[0] = first_char; /* 1. char was stored separately, to make place for
- the terminating '\0' */
- /* We fill up the buffer to its limit, each time */
- SYSCALL(read_len = read(fd, buffer + brest, BLEN - brest));
- if (read_len < 0) {
- ErrorF("auto-dev: Read error on " PROC_BUS_INPUT_DEV ".\n");
- return -1; /* report EOF on behalf... */
- }
- read_len += brest;
- /* from now read_len is the count of valid characters in the buffer[] */
- if (read_len == 0)
- return -1; /* EOF */
- /* find EOL */
- for (i = 0; i < read_len && buffer[i] != '\n'; ++i)
- ;
- /* If not EO-buffer, we include terminating '\n' */
- if (i < read_len)
- ++i;
- *line = buffer;
- *len = i;
-
- /* store the first char, of the next line, to make place for
- the termination '\0' */
- first_char = buffer[i];
- buffer[i] = 0;
-
- brest = read_len-i;
- old_i = i;
- return 0;
-}
-
static void
SetDeviceAndProtocol(LocalDevicePtr local)
{
@@ -215,63 +165,33 @@ SetDeviceAndProtocol(LocalDevicePtr local)
/* We are trying to find the right eventX Device, or fall back to
the psaux Protocol and the given Device from XF86Config */
int fd = -1;
- int status = 0; /* 0, start, 1=found "Synaptics", 2=found device */
- SYSCALL(fd = open(PROC_BUS_INPUT_DEV, O_RDONLY));
- if (fd < 0) {/* no luck, so fall back to "psaux" */
- /* hopefully we have a valid device from XF86Config...*/
- xf86Msg(X_PROBED, "%s Could not open " PROC_BUS_INPUT_DEV
- " to auto-determine the synaptics touchpad device, "
- "falling back to psaux protocol and the Device Option.\n",
- local->name);
- } else {
- char *line = NULL;
- size_t len = 0;
- while (GetlineBuffSys(&line, &len, fd) != -1) {
- if (strncmp(line, INP_DEV_N, sizeof(INP_DEV_N) - 1) == 0) {
- DBG(7, ErrorF("auto-dev: Found Synaptics in " PROC_BUS_INPUT_DEV "\n"));
- status = 1;
- }
- else if (strncmp(line, INP_DEV_H, sizeof(INP_DEV_H) - 1) == 0 && status == 1) {
- status = 2;
- DBG(7, ErrorF("auto-dev: Found its handler entry\n"));
+ int i;
+ for (i = 0; ; i++) {
+ char fname[64];
+ struct input_id id;
+ int ret;
+
+ sprintf(fname, "%s/%s%d", DEV_INPUT_EVENT, EVENT_DEV_NAME, i);
+ SYSCALL(fd = open(fname, O_RDONLY));
+ if (fd < 0) {
+ if (errno == ENOENT) {
+ ErrorF("%s no synaptics event device found\n", local->name);
break;
+ } else {
+ continue;
}
}
+ SYSCALL(ret = ioctl(fd, EVIOCGID, &id));
SYSCALL(close(fd));
- if (status != 2) { /* fall back... */
- ErrorF("auto-dev: Could not find " INP_DEV_N " and its handler entry "
- INP_DEV_H " in " PROC_BUS_INPUT_DEV ". So we are unable to auto-determine "
- "the synaptics touchpad device, falling back to psaux protocol and "
- "the Device Option.\n");
- } else { /* Now update Device Option to found eventX */
- static char *event_device;
- char *s;
-
- event_device=NULL;
- s=strstr(line+sizeof(INP_DEV_H)-1, "event"); /* there might also be some other devices f.e. js0... */
- if (s != NULL) {
- char *p = s + sizeof("event");
- while (*p && (*p >= '0') && (*p <= '9'))
- p++;
- *p = 0; /* terminate the string after event2 */
- event_device = malloc(strlen(s) + sizeof(DEV_INPUT_EVENT) + 1);
- }
- if (s == NULL || event_device == NULL) {
- if (s == NULL)
- ErrorF("auto-dev: cannot find the event-device in the handlers-entry for the "
- "Synaptics touchpad hardware. Falling back to psaux protocol and the "
- "Device Option from XF86Config.\n");
- else
- ErrorF("auto-dev: cannot get memory for telling the right device name. "
- "Falling back to psaux protocol and the Device Option from XF86Config.\n");
- } else {
+ if (ret >= 0) {
+ if ((id.bustype == BUS_I8042) &&
+ (id.vendor == 0x0002) &&
+ (id.product == PSMOUSE_SYNAPTICS)) {
priv->proto = SYN_PROTO_EVENT;
- strcpy(event_device, DEV_INPUT_EVENT);
- strcat(event_device, s);
xf86Msg(X_PROBED, "%s auto-dev sets Synaptics Device to %s\n",
- local->name, event_device);
- xf86ReplaceStrOption(local->options, "Device", event_device);
- free(event_device);
+ local->name, fname);
+ xf86ReplaceStrOption(local->options, "Device", fname);
+ break;
}
}
}