#!/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" and "readeontool" programs for output. # # There is a table of actions to take for each sonypi function-key event. # Only a few of the events (notably eject, brightness, video out, and # suspend to disk) are used. # # The path may need customization for your system; it works on my VGN-A197 # machine with Debian sarge and radeontool and sonypid installed in # /usr/local/bin. # # Best of luck; questions, comments, or revisions may be directed to # "deforest@boulder.swri.edu". # # Copyright Craig DeForest, 2003 # # Minor adjustments to fit into Debian's framework and support # Sony's VAIO A-Series by Denny Priebe, 2004 # # 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 # $ENV{PATH} = '/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin'; $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; delete @ENV{qw(IFS CDPATH ENV BASH_ENV LD_LIBRARY_PATH)}; ########## # Some setup variables collected here for convenience $bright_steps = 10; $spicctrl = 'spicctrl'; # /dev/cdrom is usally a good idea. Change this if needed. $cdrom = "/dev/cdrom"; # Change this to the command that usually suspends your machine. # It differs between the existing implementations (pmdisk, swsusp, swsusp2) $suspend_command = "true"; ########## # Some brightness settings $minbs = 0; $maxbs = 255; $bs = ($maxbs-$minbs+1)/$bright_steps; ########## # What to do when the raise brightness key is hit $brighter = sub { $B = int(`$spicctrl -B`) + int($bs); if ($B <= $maxbs) { `$spicctrl -b $B`; } }; ########## # What to do when the lower brightness key is hit $darker = sub { $B = int(`$spicctrl -B`) - int($bs); if ($B >= $minbs) { `$spicctrl -b $B`; } }; ########## # What to do when the toggle video out key is hit $toggle_vo = sub { $rv = `radeontool dac`; @words = split(m/\s+/,$rv); $status = $words[$#words]; $ns = "off" if $status eq "on"; $ns = "on" if $status eq "off"; `radeontool dac $ns && logger -t sonypidd "Video out is $ns"`; }; ########## # What to do when the suspend key is hit $suspend = sub { `logger -t sonypidd "Suspending"`; `$suspend_command`; }; ########## # Table of function-key actions. List ref containing strings # executes strings as shell commands; code ref gets executed in situ. %cmds = ( "F5" => $darker, # Fn-F5 - decrease brightness "F6" => $brighter, # Fn-F6 - increase brightness "F7" => $toggle_vo, # Fn-F7 - toggle video out "F12" => $suspend, # Fn-F12 - suspend to disk "E" => ["eject $cdrom"], # Eject button aka Fn-E ); # # 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,">/var/run/sonypidd.pid" || 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('sonypid'); die; } close WRITE; ########## # Interrupt handling -- clean up the sonypid before dying... $die = sub{ kill(9,$pid); unlink("/var/run/sonypidd.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-([0-9A-Za-z]+)$/) { my $f_no = $1; if(defined($cmds{$f_no})) { if(ref $cmds{$f_no} eq 'CODE') { &{$cmds{$f_no}}; } elsif(ref $cmds{$f_no} eq 'ARRAY') { for(@{$cmds{$f_no}}) { `$_`; } } } } } exit 0;