[PATCH libevdev] tools: print out evdev override udev rule from touchpad edge detector

Peter Hutterer peter.hutterer at who-t.net
Thu Jul 30 17:54:40 PDT 2015


We're starting to collect overrides for custom devices, making this easier for
users and us saves us time. Once we measured everything, print out a
guesstimated udev rule and instructions on how to calculate the resolution.
Extra output now is:

	Touchpad size as listed by the kernel: 132x111mm
	Calculate resolution as:
		x axis: 6076/<width in mm>
		y axis: 5021/<height in mm>

	Suggested udev rule:
	# <Laptop model description goes here>
	evdev:input:b0005v05ACp030E*
	 EVDEV_ABS_01=-2694:2862:<x resolution>
	 EVDEV_ABS_02=-20:121:<y resolution>
	 EVDEV_ABS_35=-2694:2862:<x resolution>
	 EVDEV_ABS_36=-20:121:<y resolution>

The ABS_MT_ axes are only printed if the device have them, if the device isn't
bluetooth/usb we print the dmi modalias instead.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 tools/touchpad-edge-detector.c | 82 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 81 insertions(+), 1 deletion(-)

diff --git a/tools/touchpad-edge-detector.c b/tools/touchpad-edge-detector.c
index fdc496e..4dbae11 100644
--- a/tools/touchpad-edge-detector.c
+++ b/tools/touchpad-edge-detector.c
@@ -136,6 +136,85 @@ mainloop(struct libevdev *dev, struct dimensions *dim) {
 	return 0;
 }
 
+static inline void
+pid_vid_matchstr(struct libevdev *dev, char *match, size_t sz)
+{
+	snprintf(match, sz, "input:b%04Xv%04Xp%04X",
+		libevdev_get_id_bustype(dev),
+		libevdev_get_id_vendor(dev),
+		libevdev_get_id_product(dev));
+}
+
+static inline void
+dmi_matchstr(struct libevdev *dev, char *match, size_t sz)
+{
+	char modalias[PATH_MAX];
+	FILE *fp;
+
+	fp = fopen("/sys/class/dmi/id/modalias", "r");
+	if (!fp || fgets(modalias, sizeof(modalias), fp) == NULL) {
+		sprintf(match, "ERROR READING DMI MODALIAS");
+		if (fp)
+			fclose(fp);
+		return;
+	}
+
+	fclose(fp);
+
+	modalias[strlen(modalias) - 1] = '\0'; /* drop \n */
+	snprintf(match, sz, "name:%s:%s", libevdev_get_name(dev), modalias);
+
+	return;
+}
+
+static void
+print_udev_override_rule(struct libevdev *dev, const struct dimensions *dim) {
+	const struct input_absinfo *x, *y;
+	char match[PATH_MAX];
+	int w, h;
+
+	x = libevdev_get_abs_info(dev, ABS_X);
+	y = libevdev_get_abs_info(dev, ABS_Y);
+	w = x->maximum - x->minimum;
+	h = y->maximum - y->minimum;
+
+	if (x->resolution && y->resolution) {
+		printf("Touchpad size as listed by the kernel: %dx%dmm\n",
+		       w/x->resolution, h/y->resolution);
+	} else {
+		printf("Touchpad has no resolution, size unknown\n");
+	}
+
+	printf("Calculate resolution as:\n");
+	printf("	x axis: %d/<width in mm>\n", w);
+	printf("	y axis: %d/<height in mm>\n", h);
+	printf("\n");
+	printf("Suggested udev rule:\n");
+
+	switch(libevdev_get_id_bustype(dev)) {
+	case BUS_USB:
+	case BUS_BLUETOOTH:
+		pid_vid_matchstr(dev, match, sizeof(match));
+		break;
+	default:
+		dmi_matchstr(dev, match, sizeof(match));
+		break;
+	}
+
+	printf("# <Laptop model description goes here>\n"
+	       "evdev:%s*\n"
+	       " EVDEV_ABS_01=%d:%d:<x resolution>\n"
+	       " EVDEV_ABS_02=%d:%d:<y resolution>\n",
+	       match,
+	       dim->left, dim->right,
+	       dim->top, dim->bottom);
+	if (libevdev_has_event_code(dev, EV_ABS, ABS_MT_POSITION_X))
+		printf(" EVDEV_ABS_35=%d:%d:<x resolution>\n"
+		       " EVDEV_ABS_36=%d:%d:<y resolution>\n",
+		       dim->left, dim->right,
+		       dim->top, dim->bottom);
+}
+
 int main (int argc, char **argv) {
 	int rc;
 	int fd;
@@ -192,8 +271,9 @@ int main (int argc, char **argv) {
 	setbuf(stdout, NULL);
 
 	rc = mainloop(dev, &dim);
+	printf("\n\n");
 
-	printf("\n");
+	print_udev_override_rule(dev, &dim);
 
 out:
 	libevdev_free(dev);
-- 
2.4.3



More information about the Input-tools mailing list