summaryrefslogtreecommitdiff
blob: 6ed8e68f8999ae6b74049360dc967a6c08f0abb7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
diff -urN synaptics-0.14.6_p20070706.orig/eventcomm.c synaptics-0.14.6_p20070706/eventcomm.c
--- synaptics-0.14.6_p20070706.orig/eventcomm.c	2008-08-29 09:34:11.000000000 +0200
+++ synaptics-0.14.6_p20070706/eventcomm.c	2008-08-29 10:23:04.000000000 +0200
@@ -41,17 +41,25 @@
  *	Function Definitions
  ****************************************************************************/
 
-static void
+static Bool
+grab_event_device(int fd)
+{
+    int ret;
+    SYSCALL(ret = ioctl(fd, EVIOCGRAB, (pointer)1));
+    return !(ret < 0);
+}
+
+static Bool
 EventDeviceOnHook(LocalDevicePtr local, SynapticsSHM *para)
 {
     if (para->grab_event_device) {
 	/* Try to grab the event device so that data don't leak to /dev/input/mice */
-	int ret;
-	SYSCALL(ret = ioctl(local->fd, EVIOCGRAB, (pointer)1));
-	if (ret < 0) {
+	if(!grab_event_device(local->fd)) {
 	    xf86Msg(X_WARNING, "%s can't grab event device, errno=%d\n",
 		    local->name, errno);
+	return FALSE;
 	}
+    return TRUE;
     }
 }
 
@@ -273,6 +281,7 @@
 	char fname[64];
 	int fd = -1;
 	Bool is_touchpad;
+	Bool is_grabbable;
 
 	sprintf(fname, "%s/%s%d", DEV_INPUT_EVENT, EVENT_DEV_NAME, i);
 	SYSCALL(fd = open(fname, O_RDONLY));
@@ -289,7 +298,14 @@
 	noent_cnt = 0;
 	have_evdev = TRUE;
 	is_touchpad = event_query_is_touchpad(fd);
-	if (is_touchpad) {
+	/** 
+	* Check whether device can be grabbed. This means there is a race 
+	* condition with EventDeviceOnHook, which can't be solved cleanly
+	* the way things are done with the current design. One possible 
+	* solution would be to keep the file descriptor open.
+	*/
+	is_grabbable = grab_event_device(fd);
+	if (is_touchpad && is_grabbable) {
 	    xf86Msg(X_PROBED, "%s auto-dev sets device to %s\n",
 		    local->name, fname);
 	    xf86ReplaceStrOption(local->options, "Device", fname);
diff -urN synaptics-0.14.6_p20070706.orig/synaptics.c synaptics-0.14.6_p20070706/synaptics.c
--- synaptics-0.14.6_p20070706.orig/synaptics.c	2008-08-29 09:34:11.000000000 +0200
+++ synaptics-0.14.6_p20070706/synaptics.c	2008-08-29 10:26:01.000000000 +0200
@@ -595,7 +595,8 @@
 	return !Success;
     }
 
-    priv->proto_ops->DeviceOnHook(local, priv->synpara);
+    if(!priv->proto_ops->DeviceOnHook(local, priv->synpara))
+	return !Success;
 
     priv->comm.buffer = XisbNew(local->fd, 64);
     if (!priv->comm.buffer) {
diff -urN synaptics-0.14.6_p20070706.orig/synproto.h synaptics-0.14.6_p20070706/synproto.h
--- synaptics-0.14.6_p20070706.orig/synproto.h	2008-08-29 09:34:11.000000000 +0200
+++ synaptics-0.14.6_p20070706/synproto.h	2008-08-29 10:28:34.000000000 +0200
@@ -77,7 +77,7 @@
 struct CommData;
 
 struct SynapticsProtocolOperations {
-    void (*DeviceOnHook)(LocalDevicePtr local, struct _SynapticsSHM *para);
+    Bool (*DeviceOnHook)(LocalDevicePtr local, struct _SynapticsSHM *para);
     void (*DeviceOffHook)(LocalDevicePtr local);
     Bool (*QueryHardware)(LocalDevicePtr local, struct SynapticsHwInfo *synhw);
     Bool (*ReadHwState)(LocalDevicePtr local, struct SynapticsHwInfo *synhw,