public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Alessandro Di Marco <dmr@gmx.it>
To: Arjan van de Ven <arjan@infradead.org>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [ANNOUNCE] System Inactivity Monitor v1.0
Date: Fri, 19 Jan 2007 15:49:43 +0100	[thread overview]
Message-ID: <87zm8fkr5k.fsf@gmx.it> (raw)
In-Reply-To: <1169192306.3055.379.camel@laptopd505.fenrus.org> (Arjan van de Ven's message of "Fri\, 19 Jan 2007 08\:38\:26 +0100")

[-- Attachment #1: Type: text/plain, Size: 1009 bytes --]

Arjan van de Ven <arjan@infradead.org> writes:

   On Thu, 2007-01-18 at 20:29 +0100, Alessandro Di Marco wrote:
   > Hi all,
   > 
   > this is a new 2.6.20 module implementing a user inactivity trigger. Basically
   > it acts as an event sniffer, issuing an ACPI event when no user activity is
   > detected for more than a certain amount of time. This event can be successively
   > grabbed and managed by an user-level daemon such as acpid, blanking the screen,
   > dimming the lcd-panel light à la mac, etc...


   Hi,

   why did you chose an ACPI event? I'd expect a uevent (which dbus
   captures etc) to be a more logical choice..

Laziness... :) Just an idea realized in a hurry to dim my laptop panel when it
is in idle (I don't use X11, so no xscreensaver et simila.)  

Anyway I can accommodate it, if someone of you thinks that it is interesting
enough to be carried on the business.

The patch in attachment fixes some silly bugs of the previous version.

Regards,


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: sin-1.2.patch --]
[-- Type: text/x-patch, Size: 10525 bytes --]

diff -uN old/procfs.c new/procfs.c
--- old/procfs.c	2007-01-19 15:24:12.000000000 +0100
+++ new/procfs.c	2007-01-19 15:20:26.000000000 +0100
@@ -89,9 +89,19 @@
 	return err;
 }
 
+static int fake_write_proc(struct file *file, const __user char *ubuf,
+			   unsigned long count, void *data)
+{
+	void (*func)(void) = data;
+
+	func();
+	return count;
+}
+
 int start_procfs(void)
 {
-	struct proc_dir_entry *inputd, *acpid, *table, *ilink, *alink;
+	struct proc_dir_entry *inputd, *acpid,
+		*table, *interact, *ilink, *alink;
 
 	int err = -ENOMEM;
 
@@ -159,24 +169,35 @@
 	table->write_proc = write_proc;
 	table->owner = THIS_MODULE;
 
+	interact = create_proc_entry("interact", 0200, rootdir);
+	if (!interact) {
+		goto cleanout9;
+	}
+
+	interact->data = (void *) simulate_interaction;
+	interact->write_proc = fake_write_proc;
+	interact->owner = THIS_MODULE;
+
 	ilink = proc_symlink("sources", rootdir, "input");
 	if (!ilink) {
-		goto cleanout9;
+		goto cleanout10;
 	}
 
 	ilink->owner = THIS_MODULE;
 
 	alink = proc_symlink("destinations", rootdir, "acpi");
 	if (!alink) {
-		goto cleanout10;
+		goto cleanout11;
 	}
 
 	alink->owner = THIS_MODULE;
 
 	return 0;
 
-cleanout10:
+cleanout11:
 	remove_proc_entry("sources", rootdir);
+cleanout10:
+	remove_proc_entry("interact", rootdir);
 cleanout9:
 	remove_proc_entry("table", rootdir);
 cleanout8:
@@ -203,6 +224,7 @@
 {
 	remove_proc_entry("destinations", rootdir);
 	remove_proc_entry("sources", rootdir);
+	remove_proc_entry("interact", rootdir);
 	remove_proc_entry("table", rootdir);
 	remove_proc_entry("acpi", rootdir);
 	remove_proc_entry("input", rootdir);
diff -uN old/sin.c new/sin.c
--- old/sin.c	2007-01-19 15:24:12.000000000 +0100
+++ new/sin.c	2007-01-19 15:20:26.000000000 +0100
@@ -34,7 +34,7 @@
 
 MODULE_ALIAS("blanker");
 
-MODULE_VERSION("1.0");
+MODULE_VERSION("1.2");
 
 static struct acpi_device *acpi_device;
 
@@ -49,13 +49,18 @@
 static DEFINE_MUTEX(runlock);
 static int running;
 
-static void event(struct input_handle *handle,
-		  unsigned int type, unsigned int code, int value)
+inline void signal_interaction(void)
 {
 	if (unlikely(test_and_clear_bit(0, &notify))) {
 		clear_bit(1, &notify);
 		occasionally_generate_event(acpi_device);
 	}
+}
+
+static void event(struct input_handle *handle,
+		  unsigned int type, unsigned int code, int value)
+{
+	signal_interaction();
 
 	atomic_inc(&interactions);
 }
@@ -166,8 +171,13 @@
 	if (running) {
 		shutdown = 1;
 		del_timer_sync(&timer);
+
 		input_unregister_handler(&ih);
 		kfree(ih.id_table);
+
+		signal_interaction();
+		cleanup_table();
+
 		running = 0;
 	}
 
@@ -176,14 +186,14 @@
 
 static int __init sih_init(void)
 {
-	printk("System Inactivity Notifier 1.0 - (c) Alessandro Di Marco <dmr@c0nc3pt.com>\n");
+	printk("System Inactivity Notifier 1.2 - (c) Alessandro Di Marco <dmr@c0nc3pt.com>\n");
 	return start_procfs();
 }
 
 static void __exit sih_exit(void)
 {
 	stop_procfs();
-	stop_monitor();
+	(void) stop_monitor();
 }
 
 module_init(sih_init);
diff -uN old/sin.h new/sin.h
--- old/sin.h	2007-01-19 15:24:12.000000000 +0100
+++ new/sin.h	2007-01-19 15:20:26.000000000 +0100
@@ -26,6 +26,8 @@
 
 #define MODULE_NAME "sin"
 
+extern void signal_interaction(void);
+
 extern int start_monitor(char *ids, struct input_device_id *idi, unsigned long pace);
 extern void stop_monitor(void);
 
diff -uN old/table.c new/table.c
--- old/table.c	2007-01-19 15:24:12.000000000 +0100
+++ new/table.c	2007-01-19 15:20:26.000000000 +0100
@@ -32,7 +32,7 @@
 #include "acpi_enumerator.h"
 
 static struct table rt;
-static int debug;
+static int counter, action;
 
 /*
  * WARNING: sonypi, buttons and others issue a spurious event when removed from
@@ -42,7 +42,7 @@
 
 void occasionally_generate_event(struct acpi_device *acpi_device)
 {
-	if (unlikely(debug)) {
+	if (unlikely(rt.debug)) {
 		printk("generating special event [%d, %d]\n",
 		       rt.rules[rt.rnum].type, rt.rules[rt.rnum].data);
 	}
@@ -54,17 +54,15 @@
 void timely_generate_event(struct acpi_device *acpi_device,
 			   int interactions, unsigned long *notify)
 {
-	static int counter, action;
-
 	if (interactions && counter) {
-		if (unlikely(debug)) {
+		if (unlikely(rt.debug)) {
 			printk("user activity detected, counter reset!\n");
 		}
 
 		counter = action = 0;
 	}
 
-	if (unlikely(debug)) {
+	if (unlikely(rt.debug)) {
 		printk("global counter %d, next rule is [%d %d %d]\n",
 		       counter,
 		       rt.rules[action].counter,
@@ -73,7 +71,7 @@
 	}
 
 	while (action < rt.rnum && rt.rules[action].counter == counter) {
-		if (unlikely(debug)) {
+		if (unlikely(rt.debug)) {
 			printk("generating event [%d, %d]\n",
 			       rt.rules[action].type,
 			       rt.rules[action].data);
@@ -87,7 +85,7 @@
 	}
 
 	if (rt.raction >= 0 && action == rt.rnum) {
-		if (unlikely(debug)) {
+		if (unlikely(rt.debug)) {
 			printk("last rule reached, restarting from %d\n",
 			       rt.rcounter);
 		}
@@ -101,6 +99,12 @@
 	}
 }
 
+void simulate_interaction(void)
+{
+	signal_interaction();
+	counter = action = 0;
+}
+
 #define parse_num(endp) ({				\
 			char *cp = endp;		\
 							\
@@ -129,6 +133,7 @@
 
 int push_table(char *buf, unsigned long count)
 {
+	struct table nrt;
 	struct input_device_id *idi;
 	struct uniq uniq;
 	int devices;
@@ -137,25 +142,25 @@
 
 	devices = get_devices();
 
-	debug = parse_num(buf);
+	nrt.debug = parse_num(buf);
 
-	rt.pace = (parse_num(buf) * HZ) / 10;
-	rt.dnum = parse_num(buf);
-	rt.rnum = parse_num(buf);
+	nrt.pace = (parse_num(buf) * HZ) / 10;
+	nrt.dnum = parse_num(buf);
+	nrt.rnum = parse_num(buf);
 
-	if (out_of_range(1, rt.pace, 1000000) ||
-	    out_of_range(0, rt.dnum, devices)) {
+	if (out_of_range(1, nrt.pace, 1000000) ||
+	    out_of_range(0, nrt.dnum, devices)) {
 		err = -EINVAL;
 		goto out;
 	}
 
-	rt.devices = kmalloc(rt.dnum * sizeof (int), GFP_KERNEL);
-	if (!rt.devices) {
+	nrt.devices = kmalloc(nrt.dnum * sizeof (int), GFP_KERNEL);
+	if (!nrt.devices) {
 		goto out;
 	}
 
-	rt.rules = kmalloc((rt.rnum + 1) * sizeof (struct rule), GFP_KERNEL);
-	if (!rt.rules) {
+	nrt.rules = kmalloc((nrt.rnum + 1) * sizeof (struct rule), GFP_KERNEL);
+	if (!nrt.rules) {
 		goto cleanout1;
 	}
 
@@ -163,69 +168,76 @@
 		goto cleanout2;
 	}
 
-	for (i = 0; i < rt.dnum; i++) {
-		rt.devices[i] = parse_num(buf);
-		if (uniq_check(&uniq, rt.devices[i])) {
+	for (i = 0; i < nrt.dnum; i++) {
+		nrt.devices[i] = parse_num(buf);
+		if (uniq_check(&uniq, nrt.devices[i])) {
 			break;
 		}
 	}
 
 	uniq_free(&uniq);
 
-	if (i < rt.dnum) {
+	if (i < nrt.dnum) {
 		err = -EINVAL;
 		goto cleanout2;
 	}
 
-	rt.handle = parse_num(buf);
-	if (out_of_range(0, rt.handle, get_handlers())) {
+	nrt.handle = parse_num(buf);
+	if (out_of_range(0, nrt.handle, get_handlers())) {
 		err = -EINVAL;
 		goto cleanout2;
 	}
 
-	rt.rcounter = parse_num(buf);
+	nrt.rcounter = parse_num(buf);
 
-	rt.rules[rt.rnum].counter = -1;
-	rt.rules[rt.rnum].type = parse_num(buf);
-	rt.rules[rt.rnum].data = parse_num(buf);
-
-	for (i = 0; i < rt.rnum; i++) {
-		rt.rules[i].counter = parse_num(buf);
-		if (rt.rules[i].counter < 0) {
+	nrt.rules[nrt.rnum].counter = -1;
+	nrt.rules[nrt.rnum].type = parse_num(buf);
+	nrt.rules[nrt.rnum].data = parse_num(buf);
+
+	for (i = 0; i < nrt.rnum; i++) {
+		nrt.rules[i].counter = parse_num(buf);
+		if (nrt.rules[i].counter < 0) {
 			err = -EINVAL;
 			goto cleanout2;
 		}
 
-		rt.rules[i].type = parse_num(buf);
-		rt.rules[i].data = parse_num(buf);
+		nrt.rules[i].type = parse_num(buf);
+		nrt.rules[i].data = parse_num(buf);
 	}
 
-	sort(rt.rules, rt.rnum, sizeof (struct rule), cmp, swap);
+	sort(nrt.rules, nrt.rnum, sizeof (struct rule), cmp, swap);
 
-	rt.raction = -1;
+	nrt.raction = -1;
 
-	if (rt.rcounter >= 0) {
-		for (i = 0; i < rt.rnum; i++) {
-			if (rt.rules[i].counter >= rt.rcounter) {
-				rt.raction = i;
+	if (nrt.rcounter >= 0) {
+		for (i = 0; i < nrt.rnum; i++) {
+			if (nrt.rules[i].counter >= nrt.rcounter) {
+				nrt.raction = i;
 				break;
 			}
 		}
 	}
 
+	if (!tablecmp(&rt, &nrt)) {
+		err = count;
+		goto cleanout2;
+	}
+
 	stop_monitor();
 
-	idi = kzalloc((rt.dnum + 1) *
+	idi = kzalloc((nrt.dnum + 1) *
 		      sizeof (struct input_device_id), GFP_KERNEL);
 	if (!idi) {
 		goto cleanout2;
 	}
 
-	for (i = 0; i < rt.dnum; i++) {
-		fill_input_device(&idi[i], rt.devices[i]);
+	for (i = 0; i < nrt.dnum; i++) {
+		fill_input_device(&idi[i], nrt.devices[i]);
 	}
 
-	err = start_monitor(get_hardware_id(rt.handle), idi, rt.pace);
+	memcpy(&rt, &nrt, sizeof (struct table));
+
+	err = start_monitor(get_hardware_id(rt.handle), idi, nrt.pace);
 	if (err < 0) {
 		goto cleanout3;
 	}
@@ -235,9 +247,9 @@
 cleanout3:
 	kfree(idi);
 cleanout2:
-	kfree(rt.rules);
+	kfree(nrt.rules);
 cleanout1:
-	kfree(rt.devices);
+	kfree(nrt.devices);
 out:
 	return err;
 }
@@ -252,7 +264,7 @@
 		return -EFAULT;
 	}
 
-	b += sprintf(b, "%d\n%lu\n%d %d\n", debug,
+	b += sprintf(b, "%d\n%lu\n%d %d\n", rt.debug,
 		     (rt.pace * 10) / HZ, rt.dnum, rt.rnum);
 
 	for (i = 0; i < rt.dnum; i++) {
@@ -272,3 +284,12 @@
 
 	return b - *buf;
 }
+
+void cleanup_table(void)
+{
+	kfree(rt.devices);
+	kfree(rt.rules);
+	memset(&rt, 0, sizeof (struct table));
+
+	counter = action = 0;
+}
diff -uN old/table.h new/table.h
--- old/table.h	2007-01-19 15:24:12.000000000 +0100
+++ new/table.h	2007-01-19 15:20:26.000000000 +0100
@@ -31,6 +31,7 @@
 };
 
 struct table {
+	int debug;
 	unsigned long pace;
 	int dnum, rnum;
 	int *devices;
@@ -39,6 +40,28 @@
 	struct rule *rules;
 };
 
+static inline int tablecmp(struct table *l, struct table *r)
+{
+	if (l->debug != r->debug ||
+	    l->pace != r->pace ||
+	    l->dnum != r->dnum ||
+	    l->handle != r->handle ||
+	    l->rcounter != r->rcounter ||
+	    l->raction != r->raction) {
+		return 1;
+	}
+
+	if (memcmp(l->devices, r->devices, l->dnum * sizeof (int))) {
+		return 1;
+	}
+
+	if (memcmp(l->rules, r->rules, l->rnum * sizeof (struct rule))) {
+		return 1;
+	}
+
+	return 0;
+}
+
 #define TABLE_SIZE (sizeof (struct table) - 2 * sizeof (void *)	  \
 		    + rt.dnum * sizeof (int)			  \
 		    + rt.rnum * sizeof (struct rule))
@@ -48,7 +71,10 @@
 extern void occasionally_generate_event(struct acpi_device *acpi_device);
 extern void timely_generate_event(struct acpi_device *acpi_device, int interactions, unsigned long *notify);
 
+void simulate_interaction(void);
+
 extern int push_table(char *buf, unsigned long count);
 extern int pull_table(char **buf);
+extern void cleanup_table(void);
 
 #endif /* TABLE_H */

[-- Attachment #3: Type: text/plain, Size: 159 bytes --]


-- 
Ethics is not definable, is not implementable, because it is not conscious; it
involves not only our thinking, but also our feeling. - Valdemar W. Setzer

  reply	other threads:[~2007-01-19 14:49 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-18 19:29 [ANNOUNCE] System Inactivity Monitor v1.0 Alessandro Di Marco
2007-01-19  7:38 ` Arjan van de Ven
2007-01-19 14:49   ` Alessandro Di Marco [this message]
2007-01-19 17:45     ` Scott Preece
2007-01-19 22:21       ` Jan Engelhardt
2007-01-19 22:30         ` Scott Preece
2007-01-19 10:11 ` Pavel Machek
2007-01-21 21:04   ` Jan Engelhardt
2007-01-23  9:38     ` Pavel Machek
2007-01-22 12:46   ` Alessandro Di Marco
2007-01-23  9:41     ` Pavel Machek
2007-01-23 14:14       ` Alessandro Di Marco
2007-01-23 16:34         ` Pavel Machek
2007-01-23 17:11           ` Alessandro Di Marco
2007-01-23 18:44             ` Pavel Machek
2007-01-24  2:51               ` Alessandro Di Marco
2007-01-26 17:15                 ` Pavel Machek
2007-01-26 17:55                   ` Alessandro Di Marco
2007-01-27 17:45                     ` Pavel Machek
2007-01-27 19:20                       ` Vojtech Pavlik
2007-01-29 13:58                         ` Alessandro Di Marco
2007-01-29 22:28                           ` Pavel Machek
2007-01-29 22:42                             ` Alessandro Di Marco
2007-01-30  0:03                               ` Pavel Machek
2007-01-30  9:42                               ` Vojtech Pavlik
2007-01-30 12:33                                 ` Alessandro Di Marco
2007-01-30 13:09                                   ` Vojtech Pavlik
2007-01-30 15:22                                     ` Alessandro Di Marco
2009-01-27  0:52                                 ` [PATCH] input: Activity counters Alessandro Di Marco
2009-01-27  0:54                                 ` Alessandro Di Marco
2009-01-27  0:54                                 ` Alessandro Di Marco
2009-01-27  0:54                                 ` Alessandro Di Marco
2007-01-29  8:24                       ` [ANNOUNCE] System Inactivity Monitor v1.0 Stefan Seyfried
2007-01-24 18:08               ` Alessandro Di Marco
2007-01-23 19:01           ` Mattia Dongili
2007-01-23 19:02             ` Pavel Machek
2007-01-23 20:07               ` Mattia Dongili
2007-01-23 19:34           ` Scott Preece
2007-01-24  2:02             ` Alessandro Di Marco
2007-01-24 14:01             ` Pavel Machek
2007-01-19 21:18 ` Bill Davidsen
2007-01-20 15:37   ` Alessandro Di Marco
     [not found] <7ELhf-4rC-9@gated-at.bofh.it>
     [not found] ` <7FKM6-7Gy-1@gated-at.bofh.it>
     [not found]   ` <7G6ME-1g2-11@gated-at.bofh.it>
     [not found]     ` <7GqrZ-6YY-1@gated-at.bofh.it>
     [not found]       ` <7GuFj-5pj-5@gated-at.bofh.it>
     [not found]         ` <7GwQL-h3-7@gated-at.bofh.it>
     [not found]           ` <7GzF3-4L6-47@gated-at.bofh.it>
2007-01-25 12:28             ` Bodo Eggert
2007-01-25 15:18               ` Scott Preece
2007-01-25 15:43                 ` Alessandro Di Marco
2007-01-25 16:03                   ` Scott Preece

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87zm8fkr5k.fsf@gmx.it \
    --to=dmr@gmx.it \
    --cc=arjan@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox