Bug#818471: xserver-xorg-input-synaptics: syndaemon not disabling touch pad
Package: xserver-xorg-input-synaptics
Version: 1.9.1-1
Followup-For: Bug #818471
Dear Maintainer,
I am experiencing similar problem. The core of the issue is that some laptops have separated touchpad-like driver for the touchpad itself and for the buttons. As a result, two touchpad devices can be found in xinput -list. In my case these are:
SYNA3071:00 06CB:82F1 Touchpad
SynPS/2 Synaptics TouchPad
The synclient and syndaemon programs are taking blindly the first touchpad-like device they find, which is unfortunatelly the generic SynPS/2 one. A possible dirty workaround is to disable 'psmouse' module, which makes that SynPS/2 touchpad to disappear, but at the same time the buttons next to the touchpad stop (partly) working.
Attached is a patch to the synclient and syndaemon code, which makes sure the SynPS/2 device is used only when there is no other touchpad-like device found. At the same time a new option "-n device" is added so that user can select (by name) which device is to be used by the synclient and syndaemon programs.
Feel free to alter the patch as/if needed.
Best regards,
Pavel
--- old/tools/synclient.c
+++ new/tools/synclient.c
@@ -30,6 +30,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/time.h>
@@ -74,6 +75,8 @@
int prop_offset; /* Offset inside property */
};
+static const char *dev_substring;
+
static struct Parameter params[] = {
{"LeftEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_EDGES, 32, 0},
{"RightEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_EDGES, 32, 1},
@@ -245,12 +248,27 @@
return dpy;
}
+static void
+dp_get_device_unwind(Atom ** properties, XDevice ** dev, int error, Display * dpy, XDeviceInfo * info)
+{
+ if ( *properties ) {
+ XFree(*properties);
+ *properties = NULL;
+ }
+ if ( info ) XFreeDeviceList(info);
+ if ( error && (*dev) ) {
+ XCloseDevice(dpy, *dev);
+ *dev = NULL;
+ }
+}
+
static XDevice *
dp_get_device(Display * dpy)
{
XDevice *dev = NULL;
XDeviceInfo *info = NULL;
int ndevices = 0;
+ int generic_device = -1;
Atom touchpad_type = 0;
Atom synaptics_property = 0;
Atom *properties = NULL;
@@ -267,16 +285,16 @@
if (!dev) {
fprintf(stderr, "Failed to open device '%s'.\n",
info[ndevices].name);
- error = 1;
- goto unwind;
+ dp_get_device_unwind(&properties, &dev, error = 1, dpy, NULL);
+ continue;
}
properties = XListDeviceProperties(dpy, dev, &nprops);
if (!properties || !nprops) {
fprintf(stderr, "No properties on device '%s'.\n",
info[ndevices].name);
- error = 1;
- goto unwind;
+ dp_get_device_unwind(&properties, &dev, error = 1, dpy, NULL);
+ continue;
}
while (nprops--) {
@@ -286,23 +304,41 @@
if (!nprops) {
fprintf(stderr, "No synaptics properties on device '%s'.\n",
info[ndevices].name);
- error = 1;
- goto unwind;
+ dp_get_device_unwind(&properties, &dev, error = 1, dpy, NULL);
+ continue;
}
- break; /* Yay, device is suitable */
+ fprintf(stderr, "Found device '%s'.\n", info[ndevices].name);
+
+ if ( dev_substring != NULL && strlen(dev_substring) > 0 && !strstr(info[ndevices].name, dev_substring) ) {
+ fprintf(stderr, " - device '%s' not matching requested name '%s'.\n",
+ info[ndevices].name, dev_substring);
+ dp_get_device_unwind(&properties, &dev, error = 1, dpy, NULL);
+ continue;
+ }
+
+ if ( !strcmp(info[ndevices].name, "SynPS/2 Synaptics TouchPad") ) {
+ fprintf(stderr, " - device '%s' is generic one, searching for another candidate.\n",
+ info[ndevices].name);
+ generic_device = ndevices;
+ dp_get_device_unwind(&properties, &dev, error = 1, dpy, NULL);
+ continue;
+ }
+
+ fprintf(stderr, "Taking device '%s'.\n", info[ndevices].name);
+ error = 0;
+ break; /* Yay, device is suitable */
}
}
- unwind:
- XFree(properties);
- XFreeDeviceList(info);
- if (!dev)
- fprintf(stderr, "Unable to find a synaptics device.\n");
- else if (error && dev) {
- XCloseDevice(dpy, dev);
- dev = NULL;
+ if ( generic_device != -1 && error && !dev ) {
+ fprintf(stderr, "Reverting back to generic device '%s'.\n",
+ info[generic_device].name);
+ dev = XOpenDevice(dpy, info[generic_device].id);
+ error = 0;
}
+ dp_get_device_unwind(&properties, &dev, error, dpy, info);
+
return dev;
}
@@ -470,6 +506,7 @@
{
fprintf(stderr, "Usage: synclient [-h] [-l] [-V] [-?] [var1=value1 [var2=value2] ...]\n");
fprintf(stderr, " -l List current user settings\n");
+ fprintf(stderr, " -n Name (substring) of the touchpad device (xinput -list).\n");
fprintf(stderr, " -V Print synclient version string and exit\n");
fprintf(stderr, " -? Show this help message\n");
fprintf(stderr, " var=value Set user parameter 'var' to 'value'.\n");
@@ -490,11 +527,14 @@
dump_settings = 1;
/* Parse command line parameters */
- while ((c = getopt(argc, argv, "lV?")) != -1) {
+ while ((c = getopt(argc, argv, "ln:V?")) != -1) {
switch (c) {
case 'l':
dump_settings = 1;
break;
+ case 'n':
+ dev_substring = optarg;
+ break;
case 'V':
printf("%s\n", VERSION);
exit(0);
--- old/tools/syndaemon.c
+++ new/tools/syndaemon.c
@@ -65,6 +65,7 @@
static int ignore_modifier_keys;
static int background;
static const char *pid_file;
+static const char *dev_substring;
static Display *display;
static XDevice *dev;
static Atom touchpad_off_prop;
@@ -79,7 +80,7 @@
usage(void)
{
fprintf(stderr,
- "Usage: syndaemon [-i idle-time] [-m poll-delay] [-d] [-t] [-k]\n");
+ "Usage: syndaemon (reznicek) [-i idle-time] [-m poll-delay] [-d] [-t] [-k]\n");
fprintf(stderr,
" -i How many seconds to wait after the last key press before\n");
fprintf(stderr, " enabling the touchpad. (default is 2.0s)\n");
@@ -87,6 +88,7 @@
fprintf(stderr, " (default is 200ms)\n");
fprintf(stderr, " -d Start as a daemon, i.e. in the background.\n");
fprintf(stderr, " -p Create a pid file with the specified name.\n");
+ fprintf(stderr, " -n Name (substring) of the touchpad device (xinput -list).\n");
fprintf(stderr,
" -t Only disable tapping and scrolling, not mouse movements.\n");
fprintf(stderr,
@@ -502,12 +504,26 @@
}
#endif /* HAVE_X11_EXTENSIONS_RECORD_H */
+dp_get_device_unwind(Atom ** properties, XDevice ** dev, int error, Display * dpy, XDeviceInfo * info)
+{
+ if ( *properties ) {
+ XFree(*properties);
+ *properties = NULL;
+ }
+ if ( info ) XFreeDeviceList(info);
+ if ( error && (*dev) ) {
+ XCloseDevice(dpy, *dev);
+ *dev = NULL;
+ }
+}
+
static XDevice *
dp_get_device(Display * dpy)
{
XDevice *dev = NULL;
XDeviceInfo *info = NULL;
int ndevices = 0;
+ int generic_device = -1;
Atom touchpad_type = 0;
Atom *properties = NULL;
int nprops = 0;
@@ -523,16 +539,16 @@
if (!dev) {
fprintf(stderr, "Failed to open device '%s'.\n",
info[ndevices].name);
- error = 1;
- goto unwind;
+ dp_get_device_unwind(&properties, &dev, error = 1, dpy, NULL);
+ continue;
}
properties = XListDeviceProperties(dpy, dev, &nprops);
if (!properties || !nprops) {
fprintf(stderr, "No properties on device '%s'.\n",
info[ndevices].name);
- error = 1;
- goto unwind;
+ dp_get_device_unwind(&properties, &dev, error = 1, dpy, NULL);
+ continue;
}
while (nprops--) {
@@ -542,23 +558,41 @@
if (nprops < 0) {
fprintf(stderr, "No synaptics properties on device '%s'.\n",
info[ndevices].name);
- error = 1;
- goto unwind;
+ dp_get_device_unwind(&properties, &dev, error = 1, dpy, NULL);
+ continue;
+ }
+
+ fprintf(stderr, "Found device '%s'.\n", info[ndevices].name);
+
+ if ( dev_substring != NULL && strlen(dev_substring) > 0 && !strstr(info[ndevices].name, dev_substring) ) {
+ fprintf(stderr, " - device '%s' not matching requested name '%s'.\n",
+ info[ndevices].name, dev_substring);
+ dp_get_device_unwind(&properties, &dev, error = 1, dpy, NULL);
+ continue;
+ }
+
+ if ( !strcmp(info[ndevices].name, "SynPS/2 Synaptics TouchPad") ) {
+ fprintf(stderr, " - device '%s' is generic one, searching for another candidate.\n",
+ info[ndevices].name);
+ generic_device = ndevices;
+ dp_get_device_unwind(&properties, &dev, error = 1, dpy, NULL);
+ continue;
}
- break; /* Yay, device is suitable */
+ fprintf(stderr, "Taking device '%s'.\n", info[ndevices].name);
+ error = 0;
+ break; /* Yay, device is suitable */
}
}
- unwind:
- XFree(properties);
- XFreeDeviceList(info);
- if (!dev)
- fprintf(stderr, "Unable to find a synaptics device.\n");
- else if (error && dev) {
- XCloseDevice(dpy, dev);
- dev = NULL;
+ if ( generic_device != -1 && error && !dev ) {
+ fprintf(stderr, "Reverting back to generic device '%s'.\n",
+ info[generic_device].name);
+ dev = XOpenDevice(dpy, info[generic_device].id);
+ error = 0;
}
+ dp_get_device_unwind(&properties, &dev, error, dpy, info);
+
return dev;
}
@@ -571,7 +605,7 @@
int use_xrecord = 0;
/* Parse command line parameters */
- while ((c = getopt(argc, argv, "i:m:dtp:kKR?v")) != EOF) {
+ while ((c = getopt(argc, argv, "i:m:dtp:n:kKR?v")) != EOF) {
switch (c) {
case 'i':
idle_time = atof(optarg);
@@ -588,6 +622,9 @@
case 'p':
pid_file = optarg;
break;
+ case 'n':
+ dev_substring = optarg;
+ break;
case 'k':
ignore_modifier_keys = 1;
break;
Reply to: