Monday, February 28, 2011

Using Perl to read Linux events

For a simple demo that played a movie on a BeagleBoard, I wanted to add a simple mechanism to start the movie over again if the USER button was pressed.

To read a Linux input event, it is as simple as just performing a read. The only trick to this for me, however, is that I wanted the read to timeout. This was resolved by using the Perl alarm() function can catching the signal within an eval().

I've uploaded a gist of my example play_movie.pl script:

#!/usr/bin/perl
$ENV{'DISPLAY'} = ":0.0";
system("xhost +");
#system("totem --quit");
#system("nice -n -5 totem --fullscreen /home/root/playlist.xml &");
$cmdline_start = "nice -n -5 mplayer /home/root/*.mov &";
system($cmdline_start);
open(FILE, "/dev/input/event0");
binmode(FILE);
while(1)
{
eval
{
local $SIG{ALRM} = sub { die("Alarm!\n") };
alarm(60*28); # 28 minutes
read(FILE, $buf, 16);
alarm(0);
};
if($@)
{
printf("Restarting due to timeout\n");
#system("totem --next");
system("killall -15 mplayer");
sleep(1);
system("killall -9 mplayer");
sleep(1);
system($cmdline_start);
}
else
{
($time1, $time2, $type, $code, $value) = unpack("iissi", $buf);
printf("%f %05d %05d 0x%08x\n", $time1+$time2/1000000, $type, $code, $value);
if($code == 276 && $value == 1) # USER button pressed
{
printf("Restarting due to USER button press\n");
#system("totem --next");
system("killall -15 mplayer");
sleep(1);
system("killall -9 mplayer");
sleep(1);
system($cmdline_start);
}
}
}
view raw play_movie.pl hosted with ❤ by GitHub