#!/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, the sony_acpi driver, "aumix" and "play" programs for output, # and "hibernate" for suspending the laptop. # # 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. # # Best of luck; questions, comments, or revisions may be directed to # "deforest@boulder.swri.edu". # # Copyright Craig DeForest, 2003 # Modified by Jan Merka (jm@highsphere,net), 2005, for use with the # sony_acpi driver. # # 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; $aumix = '/usr/bin/aumix'; $click = "/usr/bin/play /usr/share/sounds/KDE_Click.wav"; $brt = '/proc/acpi/sony/brt'; $maxbrt = 8; $minbrt = 1; ########## # What to do when the brightness key is hit $brighter = sub { `$click`; $cb = `cat $brt`; $B = $cb + 1; if($B <= $maxbrt){ `echo "$B" > $brt`; } }; $darker = sub { `$click`; $cb = `cat $brt`; $B = $cb - 1; if($B >= $minbrt){ `echo "$B" > $brt`; } }; ########## # 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 -v0"] # 2 - mute , ["aumix -v-10","$click"] # 3 - reduce volume , ["$aumix -v+10","$click"] # 4 - increase volume , $darker # 5 - decrease brightness , $brighter # 6 - increase brightness , undef # 7 - LCD/VGA - not yet , undef # 8 , undef # 9 , undef # 10 , undef # 11 , ["$click","hibernate"] # 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/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;