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,