Blame samples/panasonic/hotkey.pl

Packit a94d48
#!/usr/bin/perl -w
Packit a94d48
# Hotkey handler v1.0
Packit a94d48
# Handles hotkey events for Panasonic notebooks
Packit a94d48
#
Packit a94d48
# Copyright (C) 2004 David Bronaugh
Packit a94d48
#
Packit a94d48
# This program is free software; you can redistribute it and/or modify 
Packit a94d48
# it under the terms of the GNU General Public License version 2 as 
Packit a94d48
# published by the Free Software Foundation
Packit a94d48
#
Packit a94d48
# This program is distributed in the hope that it will be useful,
Packit a94d48
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit a94d48
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit a94d48
# GNU General Public License for more details.
Packit a94d48
#
Packit a94d48
# You should have received a copy of the GNU General Public License
Packit a94d48
# along with this program; if not, write to the Free Software
Packit a94d48
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit a94d48
Packit a94d48
use strict;
Packit a94d48
use POSIX qw(ceil floor);
Packit a94d48
Packit a94d48
our($config);
Packit a94d48
our($power_state);
Packit a94d48
Packit a94d48
sub read_file {
Packit a94d48
  my($file) = @_;
Packit a94d48
  my($fh);
Packit a94d48
  my($contents) = "";
Packit a94d48
  if(open($fh, $file)) {
Packit a94d48
    $/ = undef;
Packit a94d48
    $contents = <$fh>;
Packit a94d48
    close($fh);
Packit a94d48
  } else {
Packit a94d48
    print "Couldn't open file " . $file . "!\n";
Packit a94d48
  }
Packit a94d48
  return $contents;
Packit a94d48
}
Packit a94d48
Packit a94d48
sub write_file {
Packit a94d48
  my($file, $contents) = @_;
Packit a94d48
  my($fh);
Packit a94d48
Packit a94d48
  if(open($fh, ">", $file)) {
Packit a94d48
    print $fh $contents;
Packit a94d48
    close($fh);
Packit a94d48
    return 1;
Packit a94d48
  } else {
Packit a94d48
    print "Couldn't open file " . $file . "!\n";
Packit a94d48
    return 0;
Packit a94d48
  }
Packit a94d48
}
Packit a94d48
Packit a94d48
sub get_amixer_control_info {
Packit a94d48
  my($control) = @_;
Packit a94d48
  my($cmd) = $config->{'mixer_program'} . " cget name='" . $control . "'";
Packit a94d48
  my(%info);
Packit a94d48
  my($fh, $field);
Packit a94d48
  my($contents) = "";
Packit a94d48
  if(open($fh, $cmd . "|")) {
Packit a94d48
    while(<$fh>) {
Packit a94d48
      chomp;
Packit a94d48
      $contents .= $_;
Packit a94d48
    }
Packit a94d48
  } else {
Packit a94d48
    print "Couldn't run command " . $cmd . "!\n";
Packit a94d48
  }
Packit a94d48
Packit a94d48
  $contents =~ m/\; ([^\s]*)/;
Packit a94d48
Packit a94d48
  foreach(split(/,/, $+)) {
Packit a94d48
    my(@foo) = split(/=/, $_);
Packit a94d48
    $info{$foo[0]} = $foo[1];
Packit a94d48
  }
Packit a94d48
Packit a94d48
  $contents =~ m/\: ([^\s]*)/;
Packit a94d48
  my(@foo) = split(/=/, $+);
Packit a94d48
  $info{$foo[0]} = [];
Packit a94d48
  @{$info{$foo[0]}} = split(/,/, $foo[1]);
Packit a94d48
Packit a94d48
  return \%info;
Packit a94d48
}
Packit a94d48
Packit a94d48
sub set_amixer_control_info {
Packit a94d48
  my($control, $values) = @_;
Packit a94d48
  my($cmd) = $config->{'mixer_program'} . " -q cset name='" . $control . "' " . $values;
Packit a94d48
Packit a94d48
  if(system($cmd) == 0) {
Packit a94d48
    return 1;
Packit a94d48
  } else {
Packit a94d48
    return 0;
Packit a94d48
  }
Packit a94d48
}
Packit a94d48
Packit a94d48
sub get_pcc_field {
Packit a94d48
  my($field) = @_;
Packit a94d48
  my($file) = $config->{'pcc_path'} . "/" . $power_state . "_" . $field;
Packit a94d48
Packit a94d48
  return read_file($file);
Packit a94d48
}
Packit a94d48
Packit a94d48
sub set_pcc_field {
Packit a94d48
  my($field, $contents) = @_;
Packit a94d48
  my($file) = $config->{'pcc_path'} . "/" . $power_state . "_" . $field;
Packit a94d48
Packit a94d48
  if(!write_file($file, $contents)) {
Packit a94d48
    print "Couldn't set pcc " . $field . " field (are you root?)\n";
Packit a94d48
    return 0;
Packit a94d48
  }
Packit a94d48
  return 1;
Packit a94d48
}
Packit a94d48
Packit a94d48
sub get_brightness {
Packit a94d48
  return (get_pcc_field("brightness_min"), get_pcc_field("brightness_max"), get_pcc_field("brightness"));
Packit a94d48
}
Packit a94d48
Packit a94d48
sub set_brightness {
Packit a94d48
  my($value) = @_;
Packit a94d48
  return set_pcc_field("brightness", $value);
Packit a94d48
}
Packit a94d48
Packit a94d48
sub get_mute {
Packit a94d48
  my($info) = get_amixer_control_info($config->{'mute_switch'});
Packit a94d48
Packit a94d48
  if($info->{'values'}[0] eq "on") {
Packit a94d48
    return 0;
Packit a94d48
  } elsif($info->{'values'}[0] eq "off") {
Packit a94d48
    return 1;
Packit a94d48
  } else {
Packit a94d48
    print "Error getting mute status!\n";
Packit a94d48
    return -1;
Packit a94d48
  }
Packit a94d48
}
Packit a94d48
Packit a94d48
sub set_mute {
Packit a94d48
  my($value) = @_;
Packit a94d48
  if($value == 0) {
Packit a94d48
    $value = "on";
Packit a94d48
  } elsif($value == 1) {
Packit a94d48
    $value = "off";
Packit a94d48
  }
Packit a94d48
Packit a94d48
  if(set_amixer_control_info($config->{'mute_switch'}, $value)) {
Packit a94d48
    return 1;
Packit a94d48
  } else {
Packit a94d48
    print "Couldn't set mute status!\n";
Packit a94d48
    return 0;
Packit a94d48
  }
Packit a94d48
}
Packit a94d48
Packit a94d48
sub get_volume {
Packit a94d48
  my($config) = @_;
Packit a94d48
  my($info) = get_amixer_control_info($config->{'volume_ctl'});
Packit a94d48
Packit a94d48
  return ($info->{'min'}, $info->{'max'}, $info->{'values'});
Packit a94d48
}
Packit a94d48
Packit a94d48
sub set_volume {
Packit a94d48
  my($values) = @_;
Packit a94d48
Packit a94d48
  return set_amixer_control_info($config->{'volume_ctl'}, join(",", @{$values}));
Packit a94d48
}
Packit a94d48
Packit a94d48
sub get_power_state {
Packit a94d48
  my($data) = read_file($config->{"ac_state"});
Packit a94d48
Packit a94d48
  if($data =~ /on-line/) {
Packit a94d48
    return "ac";
Packit a94d48
  } elsif($data =~ /off-line/) {
Packit a94d48
    return "dc";
Packit a94d48
  } else {
Packit a94d48
    print "Couldn't get power state! (is ACPI enabled?)\n";
Packit a94d48
    exit(1);
Packit a94d48
  }
Packit a94d48
}
Packit a94d48
Packit a94d48
sub adjust_brightness { 
Packit a94d48
  my($adjust) = @_;
Packit a94d48
  my($min, $max, $bright) = get_brightness($config);
Packit a94d48
  my($threshold) = $config->{'max_bright_levels'};
Packit a94d48
  my($divisor) = 1;
Packit a94d48
Packit a94d48
  $bright -= $min;
Packit a94d48
Packit a94d48
  if($max - $min > $threshold) {
Packit a94d48
    $divisor = ($max - $min) / $threshold;
Packit a94d48
  }
Packit a94d48
Packit a94d48
  $bright = ceil($bright / $divisor);
Packit a94d48
  $bright += $adjust;
Packit a94d48
  $bright = floor($bright * $divisor);
Packit a94d48
Packit a94d48
  $bright += $min;
Packit a94d48
Packit a94d48
  if($bright < $min) {
Packit a94d48
    $bright = $min;
Packit a94d48
  }
Packit a94d48
Packit a94d48
  if($bright > $max) {
Packit a94d48
    $bright = $max;
Packit a94d48
  }
Packit a94d48
Packit a94d48
  if(!set_brightness($bright)) {
Packit a94d48
    print "Couldn't adjust brightness!\n";
Packit a94d48
  }
Packit a94d48
Packit a94d48
  return;
Packit a94d48
}
Packit a94d48
Packit a94d48
sub adjust_volume {
Packit a94d48
  my($increment) = @_;
Packit a94d48
  my($min, $max, $volume) = get_volume($config);
Packit a94d48
Packit a94d48
  $volume->[0] += $increment;
Packit a94d48
  $volume->[1] += $increment;
Packit a94d48
Packit a94d48
  $volume->[0] = ($volume->[0] < $min)?$min:$volume->[0];
Packit a94d48
  $volume->[1] = ($volume->[1] < $min)?$min:$volume->[1];
Packit a94d48
  $volume->[0] = ($volume->[0] > $max)?$max:$volume->[0];
Packit a94d48
  $volume->[1] = ($volume->[1] > $max)?$max:$volume->[1];
Packit a94d48
Packit a94d48
  if(!set_volume($volume)) {
Packit a94d48
    print "Couldn't set volume!\n";
Packit a94d48
  }
Packit a94d48
Packit a94d48
  return;
Packit a94d48
}
Packit a94d48
Packit a94d48
# Functions which implement hotkey functions directly
Packit a94d48
sub down_brightness {
Packit a94d48
  adjust_brightness(-1);
Packit a94d48
}
Packit a94d48
Packit a94d48
sub up_brightness {
Packit a94d48
  adjust_brightness(1);
Packit a94d48
}
Packit a94d48
Packit a94d48
sub switch_monitor {
Packit a94d48
  #STUB
Packit a94d48
}
Packit a94d48
Packit a94d48
sub toggle_mute {
Packit a94d48
  my($mute) = get_mute();
Packit a94d48
Packit a94d48
  if($mute >= 0) {
Packit a94d48
    set_mute($mute ^ 1);
Packit a94d48
  }
Packit a94d48
}
Packit a94d48
Packit a94d48
sub volume_up {
Packit a94d48
  adjust_volume($config->{"volume_increment"})
Packit a94d48
}
Packit a94d48
Packit a94d48
sub volume_down {
Packit a94d48
  adjust_volume(-1 * $config->{"volume_increment"})
Packit a94d48
}
Packit a94d48
Packit a94d48
sub suspend_to_ram {
Packit a94d48
  # This space intentionally left blank (because it doesn't work here)
Packit a94d48
}
Packit a94d48
Packit a94d48
sub spin_down_hd {
Packit a94d48
  if(system("hdparm -q -y /dev/hda") != 0) {
Packit a94d48
    print "Error running hdparm -- is it installed?\n";
Packit a94d48
  }
Packit a94d48
}
Packit a94d48
Packit a94d48
sub suspend_to_disk {
Packit a94d48
  system("hwclock --systohc");
Packit a94d48
  write_file($config->{'suspend_control'}, "disk");
Packit a94d48
  system("hwclock --hctosys");
Packit a94d48
}
Packit a94d48
Packit a94d48
my($key) = $ARGV[3];
Packit a94d48
Packit a94d48
my(%dispatch) = (
Packit a94d48
	     "00000081" => \&down_brightness,
Packit a94d48
	     "00000082" => \&up_brightness,
Packit a94d48
	     "00000003" => \&switch_monitor,
Packit a94d48
	     "00000084" => \&toggle_mute,
Packit a94d48
	     "00000085" => \&volume_down,
Packit a94d48
	     "00000086" => \&volume_up,
Packit a94d48
	     "00000007" => \&suspend_to_ram,
Packit a94d48
	     "00000089" => \&spin_down_hd,
Packit a94d48
	     "0000000a" => \&suspend_to_disk
Packit a94d48
	    );
Packit a94d48
Packit a94d48
$config = {
Packit a94d48
	       "pcc_path" => "/proc/acpi/pcc",
Packit a94d48
	       "mixer_program" => "amixer",
Packit a94d48
	       "ac_state" => "/proc/acpi/ac_adapter/AC/state",
Packit a94d48
	       "mute_switch" => "Master Playback Switch",
Packit a94d48
	       "volume_ctl" => "Master Playback Volume",
Packit a94d48
	       "max_bright_levels" => 20,
Packit a94d48
	       "volume_increment" => 2,
Packit a94d48
	       "suspend_control" => "/sys/power/state"
Packit a94d48
	      };
Packit a94d48
Packit a94d48
$power_state = get_power_state();
Packit a94d48
Packit a94d48
$dispatch{$key}();