[xiph-commits] r9069 - trunk/mgm/modules/linux

xiphmont at motherfish-iii.xiph.org xiphmont at motherfish-iii.xiph.org
Sat Mar 12 20:51:43 PST 2005


Author: xiphmont
Date: 2005-03-12 20:51:43 -0800 (Sat, 12 Mar 2005)
New Revision: 9069

Modified:
   trunk/mgm/modules/linux/battery
Log:
Update Linux battery module to properly parse ACPI support in the 2.6
kernel.

Note that a common kernel config option could cause trouble; if
'CONFIG_ACPI_DEBUG' is set, any call to the acpi battery status
interface will be VERY expensive, potentially as bad as freezing the
machine for 5-10 *seconds* at a time.  On my thinkpad T42p (about as
fast as they come here in early 2005), it was causing 200ms freezes.



Modified: trunk/mgm/modules/linux/battery
===================================================================
--- trunk/mgm/modules/linux/battery	2005-03-13 04:48:27 UTC (rev 9068)
+++ trunk/mgm/modules/linux/battery	2005-03-13 04:51:43 UTC (rev 9069)
@@ -11,7 +11,8 @@
 use IO::Seekable;
 use Socket;
 use vars qw(@percent @battstatus @gstate $ac $lstate $graph $widget 
-	    $xpath $openp $openf $opena $batteries $ac $active $lastbat);
+	    $xpath $openp $openf $openapm $openacpi $batteries $ac $active $lastbat
+	    @acpi_battery_dirs $acpi_adapter_dir);
 
 sub module_init{
     my$this=shift;
@@ -21,7 +22,9 @@
     $active=0;
     $openp=0;
     $openf=0;
-    $opena=0;
+    $openapm=0;
+    $openacpi=0;
+
     $this->read_proc;
     if($active==0){
 	$toplevel->optionAdd("$xclass.active",        'false',21);      
@@ -112,9 +115,12 @@
     my$test;
     my$this=shift;
 
-    if($opena){return $this->read_proc_apm;}
+    if($openacpi){return $this->read_proc_acpi;}
+    if($openapm){return $this->read_proc_apm;}
     if($openp || $openf){return $this->read_proc_mac;}
 
+    $test=$this->read_proc_acpi;
+    if(defined($test)){return $test;}
     $test=$this->read_proc_apm;
     if(defined($test)){return $test;}
     $this->read_proc_mac;
@@ -248,8 +254,7 @@
     }
 }
 
-# PC style power management.  Of course they're not the same
-# interface.  This is linux.
+# PC APM style power management.
 # /proc/apm only reports one line for all batteries
 sub read_proc_apm{
     my$this=shift;
@@ -295,7 +300,7 @@
     $batteries=0;
     if(open(PROC,"/proc/apm")){
 	$active=1;
-	$opena=1;
+	$openapm=1;
 	sysread PROC,$_,1024;
 	if(m/^\S+\s+\S+\s+\S+\s+(\S+)\s+(\S+)\s+\S+\s+([^ \%]+)\%/){
 	    if($1 eq '0xff'){
@@ -315,6 +320,91 @@
     $percent;
 }
 
+sub list_subdirs{
+    my at dirs;
+    my$path=shift;
+    if(opendir(DIR,$path)){
+	@dirs = map ("$path/$_", grep { /^[^\.]/ && -d "$path/$_" } readdir(DIR));
+	close DIR;
+	return @dirs;
+    }
+    return;
+}
+
+# PC ACPI style power management.
+sub read_proc_acpi{
+    my$this=shift;
+    my$percent;
+
+    $batteries=0;
+
+    if($openacpi==0){
+	# initialize
+	@acpi_battery_dirs=(list_subdirs("/proc/acpi/battery"));
+	my @adapdir=(list_subdirs("/proc/acpi/ac_adapter"));
+	$acpi_adapter_dir=$adapdir[0];
+
+    }
+	    
+    foreach my$dir (@acpi_battery_dirs) {
+
+	if(open(PROC,"$dir/info")){
+	    if(open(PROC2,"$dir/state")){
+		
+		$active=1;
+		$openacpi=1;
+		my$total=0;
+		
+		$battstatus[$batteries]=-1;
+		$percent[$batteries]=0;
+		while(<PROC>){
+		    if(m/^last full capacity:\s+(\d)/){
+			$total=$1;
+		    }
+		    if(m/^present:\s+yes/){
+			$battstatus[$batteries] = 0 if($battstatus[$batteries]==-1);
+		    }
+		}
+		
+		while(<PROC2>){
+		    if(m/^remaining capacity:\s+(\d)/){
+			$percent[$batteries]=$1*100/$total;
+		    }
+		    if(m/^charging state:\s+charging/){
+			$battstatus[$batteries]=1;
+		    }
+		    if(m/^charging state:\s+discharging/){
+			$battstatus[$batteries]=0;
+		    }
+		    if(m/^present:\s+yes/){
+			$battstatus[$batteries] = 0 if($battstatus[$batteries]==-1);
+		    }
+		}
+		close PROC2;
+	    }
+	    close PROC;
+	    
+	    
+	    $batteries++;
+	}
+	
+    }
+    
+    if($batteries && defined($acpi_adapter_dir)){
+	$ac=0;
+	if(open(PROC,"$acpi_adapter_dir/state")){
+	    while(<PROC>){
+		if(m/^state:\s+on-line/){
+		    $ac=1;
+		}
+	    }
+	    close PROC;
+	}
+    }
+
+    $batteries;
+}
+
 sub module_update{ 
     my$this=shift;
     my$toplevel=$this->{"toplevel"};



More information about the commits mailing list