[PATCH 2.6.28] input: activity counters

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch provides the input infrastructure with activity
counters. Their purpose is to ease the development of idle triggers,
such as screen-savers - see the followed-up Perl script as an example
(X11 agnostic).

I had submitted something similar a couple of years ago, by way of a
kernel module named SIN (http://lkml.org/lkml/2007/1/18/138).

Despite SIN has been properly maintained along this period, soon it
revealed some design weaknesses which urged me towards alternative
approaches. IMO the resulting patch fits the target: it is quite
straightforward, yet provides good features such as:

1) userland programs retains the whole control logic

2) userland programs are EVIOCGRAB hassle free

3) userland programs do not get biased towards a specific environment
(e.g. one monitor, one keyboard...)

4) userland programs do not need superuser privileges to do their work

Regards,

Signed-off-by: Alessandro Di Marco <dmr@xxxxxxxxxxx>
---
 drivers/input/input.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/input.h |    3 +++
 2 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/drivers/input/input.c b/drivers/input/input.c
index c13ced3..1758144 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -73,6 +73,11 @@ static void input_pass_event(struct input_dev *dev,
 {
 	struct input_handle *handle;

+	dev->activity = ktime_get();
+
+	if (dev->activity_notifier)
+		sysfs_notify_dirent(dev->activity_notifier);
+
 	rcu_read_lock();

 	handle = rcu_dereference(dev->grab);
@@ -1012,11 +1017,25 @@ static ssize_t input_dev_show_modalias(struct device *dev,
 }
 static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);

+static ssize_t input_dev_show_activity(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	struct input_dev *id = to_input_dev(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "A: %lld\nD: %lld\n",
+			 ktime_to_ns(id->activity),
+			 ktime_to_us(ktime_sub(ktime_get(), id->activity)));
+}
+
+static DEVICE_ATTR(activity, S_IRUGO, input_dev_show_activity, NULL);
+
 static struct attribute *input_dev_attrs[] = {
 	&dev_attr_name.attr,
 	&dev_attr_phys.attr,
 	&dev_attr_uniq.attr,
 	&dev_attr_modalias.attr,
+	&dev_attr_activity.attr,
 	NULL
 };

@@ -1227,10 +1246,33 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
 	return 0;
 }

+static inline int warp_activity(struct device *dev)
+{
+	struct input_dev *id = to_input_dev(dev);
+
+	id->activity = ktime_sub(ktime_get(), id->activity);
+	return 0;
+}
+
+int input_dev_suspend(struct device *dev, pm_message_t state)
+{
+	if (state.event & (PM_EVENT_FREEZE|PM_EVENT_SUSPEND))
+		(void) warp_activity(dev);
+
+	return 0;
+}
+
+int input_dev_resume(struct device *dev)
+{
+	return warp_activity(dev);
+}
+
 static struct device_type input_dev_type = {
 	.groups		= input_dev_attr_groups,
 	.release	= input_dev_release,
 	.uevent		= input_dev_uevent,
+	.suspend	= input_dev_suspend,
+	.resume		= input_dev_resume,
 };

 struct class input_class = {
@@ -1401,6 +1443,8 @@ int input_register_device(struct input_dev *dev)
 		dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
 	kfree(path);

+	dev->activity_notifier = sysfs_get_dirent(dev->dev.kobj.sd, "activity");
+
 	error = mutex_lock_interruptible(&input_mutex);
 	if (error) {
 		device_del(&dev->dev);
@@ -1446,6 +1490,9 @@ void input_unregister_device(struct input_dev *dev)

 	mutex_unlock(&input_mutex);

+	sysfs_put(dev->activity_notifier);
+	dev->activity_notifier = NULL;
+
 	device_unregister(&dev->dev);
 }
 EXPORT_SYMBOL(input_unregister_device);
diff --git a/include/linux/input.h b/include/linux/input.h
index 9a6355f..d372bb9 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1096,6 +1096,9 @@ struct input_dev {

 	struct input_handle *grab;

+	struct sysfs_dirent *activity_notifier;
+	ktime_t activity;
+
 	spinlock_t event_lock;
 	struct mutex mutex;
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux