#!/usr/bin/perl ########### # # Daemon to monitor sonypi events and do things, on machines that have # the sony programmable I/O device. Requires the "sonypid" daemon as # input, and the "spicctrl", "aumix", and "sox" programs for output. # # There is a table of actions to take for each sonypi function-key event. # Only a few of the events (notably brightness and loudness) are used. # # There is currently no support for anything other than function-key # events -- but it should be obvious where to add that functionality. # # The external commands may need customization for your system; they work # on my Z1 machine with Red Hat 9 and aumix and spicctrl installed in # /usr/local/bin. # # Best of luck; questions, comments, or revisions may be directed to # "deforest@boulder.swri.edu". # # Copyright Craig DeForest, 2003 # # You may distribute this under the terms of the GPL version 2; the # complete license is available at http://www.gnu.org/licenses/gpl.txt # ########## # Some setup variables collected here for convenience $bright_steps = 10; $spicctrl = '/usr/local/bin/spicctrl'; $aumix = '/usr/local/bin/aumix'; $click = "/usr/bin/sox /usr/share/sounds/KDE_Click.wav -r 48000 -t raw /dev/audio"; ########## # What to do when the brightness key is hit $bs = 256/$bright_steps; $brighter = sub { $B = int( $bs * ( int(`$spicctrl -B` / $bs + 0.5) + 1 )); `$spicctrl -b $B`; }; ########## # Table of function-key actions. List ref containing strings # executes strings as shell commands; code ref gets executed in situ. @fcmds = (undef # 0 , undef # 1 , ["aumix -v-10","$click"] # 2 - reduce volume , ["$aumix -v0"] # 3 - mute , ["$aumix -v+10","$click"] # 4 - increase volume , $brighter # 5 - increase brightness , ["$spicctrl -b 0"] # 6 - minimum brightness , undef # 7 - LCD/VGA - not yet , undef # 8 , undef # 9 , undef # 10 , undef # 11 , undef # 12 ); # # Daemon stuff -- check the lockfile (There Can Only Be One!) and # spawn twice to disassociate from the terminal. # if(open FILE,"); @lines = `ps -e`; @found = grep(/^\s*$otherpid\s/o && /sonypidd/,@lines); if(@found) { print STDERR "Sonypidd is already running (PID $otherpid)\n"; exit(1); } } open FILE,">/tmp/.sonypidd-lock" || die "Couldn't open lock file\n"; exit 0 if(fork); exit 0 if(fork); print FILE $$,"\n"; close FILE; ########## # Open a sonypid process to read the sonypi device pipe READ,WRITE; $pid = fork(); $| = 1; if(!$pid) { close READ; open STDERR,">&WRITE"; open STDOUT,">&WRITE"; exec('/usr/local/bin/sonypid'); die; } close WRITE; ########## # Interrupt handling -- clean up the sonypid before dying... $die = sub{ kill(9,$pid); exit 1; }; $SIG{HUP} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = $die; ########## # Event loop -- grab the function-key events, look 'em up, and do 'em. # Go away as soon as the sonypid dies. while(defined( $_ = )){ s/^Event:\s*//; @words = split(m/\s+/,$_); if($words[0] =~ m/^Fn-F(\d+)$/) { my $f_no = $1; if(defined($fcmds[$f_no])) { if(ref $fcmds[$f_no] eq 'CODE') { &{$fcmds[$f_no]}; } elsif(ref $fcmds[$f_no] eq 'ARRAY') { for(@{$fcmds[$f_no]}) { `$_`; } } } } } exit 0;