All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.6.28] input: activity counters (Perl trigger)
@ 2009-02-09  1:29 Alessandro Di Marco
  0 siblings, 0 replies; 2+ messages in thread
From: Alessandro Di Marco @ 2009-02-09  1:29 UTC (permalink / raw)
  To: linux-input; +Cc: Dmitry Torokhov, dtor

#!/usr/bin/perl -w

# Copyright (C) 2009 Alessandro Di Marco <dmr@c0nc3pt.com>

# This file is part of SIN.

# SIN is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.

# SIN is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

# You should have received a copy of the GNU General Public License along with
# SIN.  If not, see <http://www.gnu.org/licenses/>.

use strict;

use IO::File;
use IO::Select;
use Getopt::Long;
use Pod::Usage;

use Storable;

use constant CONFIG => 'SIN.conf';
use constant ENROLL_TIMEOUT => 5;

my @script = ( { timeout => 5, action => 'echo "dim screen"' },
	       { timeout => 10, action => 'echo "blank screen"' },
	       { timeout => 20, action => 'echo "system suspend"' } );

use constant RESUME => 'echo "restore screen"';

sub devices {
    open my $devices, "/proc/bus/input/devices"
	or die "uhm, no input devices?!?";

    my $name;
    my $devs;

    while (<$devices>) {
	$name = $1 if $_ =~ /^N: Name=\"(.*)\"\n$/;
	$devs->{$1} = $name if $_ =~ /S: Sysfs=(.*)\n$/;
    }

    $devs;
}

sub activity {
    my ($enrolled) = @_;

    $enrolled = $_ unless defined $enrolled;

    my $activities;

    foreach (keys %$enrolled) {
	open my $handle, "/sys$_/activity"
	    or die "missing activity on $_; please apply the patch!";

	my @data = <$handle>;

	$data[0] =~ /A: (0|[1-9][0-9]*)\n$/;
	my $last = $1;

	$data[1] =~ /D: (0|[1-9][0-9]*)\n$/;
	my $delta = $1;

	$activities->{$handle} = {
	    'path' => $_,
	    'handle' => $handle,
	    'last' => $last,
	    'delta' => $delta,
	};
    }

    $activities;
}

sub latest {
    my ($activities) = @_;

    $activities = $_ unless defined $activities;

    foreach (values %$activities) {
	my $handle = $_->{'handle'};

	seek $handle, 0, SEEK_SET;

	my @data = <$handle>;

	$data[0] =~ /A: (0|[1-9][0-9]*)\n$/;
	$_->{'last'} = $1;

	$data[1] =~ /D: (0|[1-9][0-9]*)\n$/;
	$_->{'delta'} = $1;
    }

    $activities;
}

sub configure {
    my ($devs) = @_;

    select(undef, undef, undef, 0.1);

    print "Input device enrolling:\n";
    print "  please interact with the desired input devices;\n";
    print "  the process will terminate after " . ENROLL_TIMEOUT
	. " seconds from the last enrollment.\n";

    my $activities = activity($devs);

    my $select = new IO::Select(map { $_->{'handle'} } values %$activities);

    while ($select->handles) {
	last unless my @picked = $select->can_read(ENROLL_TIMEOUT);

    	foreach (@picked) {
    	    print "Enrolled $devs->{$activities->{$_}->{'path'}}\n";
    	}

    	$select->remove(@picked);
    }

    delete $activities->{$_} foreach ($select->handles);

    my $enrolled;

    foreach (map { $_->{'path'} } values %$activities) {
	$enrolled->{$_} = $devs->{$_};
    }

    $enrolled;
}

my %opts = ();

GetOptions('configure' => \$opts{'configure'},
	   'help|?' => \$opts{'help'},
	   'man' => \$opts{'man'})
    or pod2usage(2);

pod2usage(1) if $opts{'help'};
pod2usage('-exitstatus' => 0, '-verbose' => 2) if $opts{'man'};

my $enrolled;

if ($opts{'configure'}) {
    $enrolled = configure devices;
    store $enrolled, CONFIG;
    exit 0;
}

die "No usable configuration found" unless -e CONFIG;

$enrolled = retrieve(CONFIG)
    or die "uhm, invalid configuration?!?\n";

my $devs = devices;

foreach (keys %$enrolled) {
    die "uhm, stored configuration doesn't match?!?\n"
	unless defined $devs->{$_};
}

sub latter_of {
    my ($activities) = @_;

    $activities = $_ unless defined $activities;

    my $last = 0;
    my $me;

    foreach (values %$activities) {
	if ($_->{'last'} > $last) {
	    $last = $_->{'last'};
	    $me = $_;
	}
    }

    $me;
}

sub warp {
    (($_[0]->{'timeout'} * 1000000) - $_[1]->{'delta'}) / 1000000;
}

my $activities = activity $enrolled;
my $select = new IO::Select(map { $_->{'handle'} } values %$activities);

start:
    while (1) {
	my $last = latter_of latest $activities;
	my $trig = 0;

	for (my $i = 0; $i < @script; $i++) {
	    if ($trig) {
		if ($select->can_read(warp($script[$i], $last))) {
		    system RESUME;
		    next start;
		}

		$last = latter_of latest $activities;
	    } else {
		while ((my $timeout = warp($script[$i], $last)) > 0) {
		    select(undef, undef, undef, $timeout);
		    $last = latter_of latest $activities;
		}

		$trig = 1;
	    }

	    system $script[$i]->{'action'};
	}

	$select->can_read;

	system RESUME;
}

__END__

=pod

=head1 NAME

SIN - System Inactivity Notifier

=head1 SYNOPSIS

B<SIN> [B<--configure>] [B<--help>] [B<--man>]

=head1 OPTIONS

=over 8

=item B<--configure>

Let the user configure SIN.

=item B<--help>

Print a brief help message and exits.

=item B<--man>

Prints the manual page and exits.

=back

=head1 DESCRIPTION

B<SIN> is an inactivity notifier. This means that you can instruct SIN to
perform different actions depending on the user's activity degree.

=cut

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH 2.6.28] input: activity counters (Perl trigger)
@ 2009-05-11  9:27 Alessandro Di Marco
  0 siblings, 0 replies; 2+ messages in thread
From: Alessandro Di Marco @ 2009-05-11  9:27 UTC (permalink / raw)
  To: linux-input; +Cc: Dmitry Torokhov, dtor

#!/usr/bin/perl -w

# Copyright (C) 2009 Alessandro Di Marco <dmr@c0nc3pt.com>

# This file is part of SIN.

# SIN is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.

# SIN is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

# You should have received a copy of the GNU General Public License along with
# SIN.  If not, see <http://www.gnu.org/licenses/>.

use strict;

use IO::File;
use IO::Select;
use Getopt::Long;
use Pod::Usage;

use Storable;

use constant CONFIG => 'SIN.conf';
use constant ENROLL_TIMEOUT => 5;

my @script = ( { timeout => 5, action => 'echo "dim screen"' },
	       { timeout => 10, action => 'echo "blank screen"' },
	       { timeout => 20, action => 'echo "system suspend"' } );

use constant RESUME => 'echo "restore screen"';

sub devices {
    open my $devices, "/proc/bus/input/devices"
	or die "uhm, no input devices?!?";

    my $name;
    my $devs;

    while (<$devices>) {
	$name = $1 if $_ =~ /^N: Name=\"(.*)\"\n$/;
	$devs->{$1} = $name if $_ =~ /S: Sysfs=(.*)\n$/;
    }

    $devs;
}

sub activity {
    my ($enrolled) = @_;

    $enrolled = $_ unless defined $enrolled;

    my $activities;

    foreach (keys %$enrolled) {
	open my $handle, "/sys$_/activity"
	    or die "missing activity on $_; please apply the patch!";

	my @data = <$handle>;

	$data[0] =~ /A: (0|[1-9][0-9]*)\n$/;
	my $last = $1;

	$data[1] =~ /D: (0|[1-9][0-9]*)\n$/;
	my $delta = $1;

	$activities->{$handle} = {
	    'path' => $_,
	    'handle' => $handle,
	    'last' => $last,
	    'delta' => $delta,
	};
    }

    $activities;
}

sub latest {
    my ($activities) = @_;

    $activities = $_ unless defined $activities;

    foreach (values %$activities) {
	my $handle = $_->{'handle'};

	seek $handle, 0, SEEK_SET;

	my @data = <$handle>;

	$data[0] =~ /A: (0|[1-9][0-9]*)\n$/;
	$_->{'last'} = $1;

	$data[1] =~ /D: (0|[1-9][0-9]*)\n$/;
	$_->{'delta'} = $1;
    }

    $activities;
}

sub configure {
    my ($devs) = @_;

    select(undef, undef, undef, 0.1);

    print "Input device enrolling:\n";
    print "  please interact with the desired input devices;\n";
    print "  the process will terminate after " . ENROLL_TIMEOUT
	. " seconds from the last enrollment.\n";

    my $activities = activity($devs);

    my $select = new IO::Select(map { $_->{'handle'} } values %$activities);

    while ($select->handles) {
	last unless my @picked = $select->can_read(ENROLL_TIMEOUT);

    	foreach (@picked) {
    	    print "Enrolled $devs->{$activities->{$_}->{'path'}}\n";
    	}

    	$select->remove(@picked);
    }

    delete $activities->{$_} foreach ($select->handles);

    my $enrolled;

    foreach (map { $_->{'path'} } values %$activities) {
	$enrolled->{$_} = $devs->{$_};
    }

    $enrolled;
}

my %opts = ();

GetOptions('configure' => \$opts{'configure'},
	   'help|?' => \$opts{'help'},
	   'man' => \$opts{'man'})
    or pod2usage(2);

pod2usage(1) if $opts{'help'};
pod2usage('-exitstatus' => 0, '-verbose' => 2) if $opts{'man'};

my $enrolled;

if ($opts{'configure'}) {
    $enrolled = configure devices;
    store $enrolled, CONFIG;
    exit 0;
}

die "No usable configuration found" unless -e CONFIG;

$enrolled = retrieve(CONFIG)
    or die "uhm, invalid configuration?!?\n";

my $devs = devices;

foreach (keys %$enrolled) {
    die "uhm, stored configuration doesn't match?!?\n"
	unless defined $devs->{$_};
}

sub latter_of {
    my ($activities) = @_;

    $activities = $_ unless defined $activities;

    my $last = 0;
    my $me;

    foreach (values %$activities) {
	if ($_->{'last'} > $last) {
	    $last = $_->{'last'};
	    $me = $_;
	}
    }

    $me;
}

sub warp {
    (($_[0]->{'timeout'} * 1000000) - $_[1]->{'delta'}) / 1000000;
}

my $activities = activity $enrolled;
my $select = new IO::Select(map { $_->{'handle'} } values %$activities);

start:
    while (1) {
	my $last = latter_of latest $activities;
	my $trig = 0;

	for (my $i = 0; $i < @script; $i++) {
	    if ($trig) {
		if ($select->can_read(warp($script[$i], $last))) {
		    system RESUME;
		    next start;
		}

		$last = latter_of latest $activities;
	    } else {
		while ((my $timeout = warp($script[$i], $last)) > 0) {
		    select(undef, undef, undef, $timeout);
		    $last = latter_of latest $activities;
		}

		$trig = 1;
	    }

	    system $script[$i]->{'action'};
	}

	$select->can_read;

	system RESUME;
}

__END__

=pod

=head1 NAME

SIN - System Inactivity Notifier

=head1 SYNOPSIS

B<SIN> [B<--configure>] [B<--help>] [B<--man>]

=head1 OPTIONS

=over 8

=item B<--configure>

Let the user configure SIN.

=item B<--help>

Print a brief help message and exits.

=item B<--man>

Prints the manual page and exits.

=back

=head1 DESCRIPTION

B<SIN> is an inactivity notifier. This means that you can instruct SIN to
perform different actions depending on the user's activity degree.

=cut


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-05-11  9:48 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-11  9:27 [PATCH 2.6.28] input: activity counters (Perl trigger) Alessandro Di Marco
  -- strict thread matches above, loose matches on Subject: below --
2009-02-09  1:29 Alessandro Di Marco

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.