Package: urfkill
Version: 0.3.0-1
Severity: normal
Tags: upstream patch

Dear Maintainer,

urfkill opens the accelerometer device on my laptop and waits for data
from it in an attempt to find any EV_KEY events which might be relevant.

The accelerometer generates continous data, so having the input device
open means that a kernel thread polls about 20 times / second and that
urfkilld wakes up with the same frequency (thanks powertop).

There is some code in src/urf-input.c which excludes e.g. PC speakers
from consideration, but the "blacklist" approach seems likely to fail in
the future if and when other platform devices are added.

I've attached a patch which checks if an input device has the EV_KEY
capabilities before using it (which excludes both the PC speaker and the
accelerometer).

Please consider applying (and upstreaming).

-- 
David Härdeman
--- a/src/urf-input.c
+++ b/src/urf-input.c
@@ -65,11 +65,14 @@
 	struct udev_device *platform_dev;
 	const char *platform_driver;
 	const char *dev_name;
+	const char *ev_caps_str;
+	unsigned long ev_caps;
 
 	/* The laptop platform drivers issue hotkey events through its own input
-	 * device or the i8042 keyboard device. Now we filter out the PC Speaker
-	 * and the i8042 devices other than keyboard and assume the rest is the
-	 * input device generated by the laptop platform driver.
+	 * device or the i8042 keyboard device. Now we filter out devices
+	 * without the EV_KEY capability and the i8042 devices other than
+	 * keyboard and assume the rest is the input device generated by the
+	 * laptop platform driver.
 	 */
 	platform_dev = udev_device_get_parent_with_subsystem_devtype(dev, "platform", 0);
 	if (!platform_dev)
@@ -80,12 +83,15 @@
 
 	platform_driver = udev_device_get_driver (platform_dev);
 	dev_name = udev_device_get_sysattr_value (input_dev, "name");
+	ev_caps_str = udev_device_get_sysattr_value (input_dev, "capabilities/ev");
+	ev_caps = strtoul(ev_caps_str ? ev_caps_str : "", NULL, 16);
 
-	/* PC Speaker */
-	if (g_strcmp0 (platform_driver, "pcspkr") == 0) {
+	/* Check if the EV_KEY capability is set */
+	if (!(ev_caps & (1 << EV_KEY)))
 		return NULL;
+
 	/* i8042 devices */
-	} else if (g_strcmp0 (platform_driver, "i8042") == 0) {
+	if (g_strcmp0 (platform_driver, "i8042") == 0) {
 		if (g_strcmp0 (dev_name, "AT Translated Set 2 keyboard") != 0)
 			return NULL;
 	}

Reply via email to