#!/usr/bin/perl -w
use strict;

use Time::HiRes qw( usleep );

my $interval = 50000;

my $config = "/etc/button_exec.conf";
my $daemon = 1;
my $dev = "/dev/ppb";

my $arg;
while (defined($arg = shift @ARGV)) {
	if ($arg eq '-f') {
		$daemon = 0;
	} elsif ($arg eq '-d') {
		$dev = shift @ARGV;
		if (!defined $dev) { usage(); }
	} else {
		$config = $arg;
	}
}

if (!defined $config) { usage(); }

my %action;

open CONFIG, $config or dienice("Could not open $config");
while (<CONFIG>) {
	if (/^\s*(\d+-\w+):/) {
		(my $event = $_) =~ s/^\s*(\d+-\w+):.*/$1/;
		$_ =~ s/^\s*(\d+-\w+):\s*//;
		$action{$event} = $_;
		print "$event: $_\n";
	} else {
		dienice("Error on line $. in $config");
	}
}
close CONFIG;

if ($daemon) {
	my $child = fork();
	if ($child != 0) { exit 0; } # exit parent
}

open PPB, $dev or dienice("Could not open $dev");
while (1) {
	my ($read, $old_data, $new_data);

	sysread PPB, $read, 1;
	$old_data = ord $read;

	do {
		sysread PPB, $read, 1;
		$new_data = ord $read;
		usleep($interval);
	} while ($new_data == $old_data);

	my $changed = $old_data ^ $new_data;
	for (my $i = 0; $i < 4; $i++) {
		my $button = 1 << $i;
		if ($changed & $button) {
			if ($new_data & $button) {
				action("$i-pressed");
			} else {
				action("$i-released");
			}
		}
	}
}
close PPB;

sub action {
	if (defined $action{$_[0]}) {
		system($action{$_[0]});
	}
}

sub usage {
	dienice("Usage: $0 [-f] [-d <dev>] <config file>");
}

sub dienice {
	print "$_[0]\n";
	exit(1);
}

