[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

ACPI patch for the Gnome2 battery applet



Hi

I've been following your discussion about the gnome-applets2 battery
monitor and the fact that it has hardcoded the ACPI info directories. I
didn't like that soulution and have come up with this patch.

Give it a try. It scans /proc/acpi/battery and ac_adapter looking for a
subdir with the state and info files, and uses the first subdir it
founds with those files. The scan is done only once, and
ac_adapter/state is also read only once.

It WorksForMe(tm), but I think it should work in any other system.

If enough people test it and find it works in their system, I'll submit
the patch to the applet author.

Regards.

PS: I'll upload shortly a binary .deb package in case anyone
can't/doesn't_want_to compile this. It will be available at:
http://www.bisente.com/programas/parches/gnome-applets2-battery-acpi/.

-- 
 Vicente Aguilar <bisente@bisente.com> | http://www.bisente.com
diff -urN gnome-applets2-2.0.3.orig/battstat/acpi-linux.c gnome-applets2-2.0.3/battstat/acpi-linux.c
--- gnome-applets2-2.0.3.orig/battstat/acpi-linux.c	2002-09-13 21:58:51.000000000 +0200
+++ gnome-applets2-2.0.3/battstat/acpi-linux.c	2002-09-25 13:05:13.000000000 +0200
@@ -39,6 +39,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <unistd.h>
+#include <dirent.h>
 #include "acpi-linux.h"
 
 static GHashTable *
@@ -141,12 +142,15 @@
  */
 gboolean acpi_linux_read(struct apm_info *apminfo)
 {
-  guint32 max_capacity, low_capacity, critical_capacity, remain;
+  static guint8 acpi_data_initialized=0;
+  static guint32 max_capacity=0, low_capacity=0, critical_capacity=0;
+  guint32 remain;
   gboolean charging, ac_online;
   gulong acpi_ver;
   char buf[BUFSIZ];
   GHashTable *hash;
-  const char *batt_info, *batt_state, *ac_state, *ac_state_state, *charging_state;
+  static const char batt_info[50], batt_state[50], ac_state[50], *ac_state_state, *charging_state;
+  /* 50 bytes should be enough for everybod... errr... those strings. */
 
   /*
    * apminfo.ac_line_status must be one when on ac power
@@ -157,10 +161,6 @@
   
   g_assert(apminfo);
 
-  max_capacity = 0;
-  low_capacity = 0;
-  critical_capacity = 0;
-
   hash = read_file ("/proc/acpi/info", buf, sizeof (buf));
   if (!hash)
     return FALSE;
@@ -168,28 +168,84 @@
   acpi_ver = read_ulong (hash, "version");
   g_hash_table_destroy (hash);
 
-  if (acpi_ver < (gulong)20020208) {
-    batt_info  = "/proc/acpi/battery/1/info";
-    batt_state = "/proc/acpi/battery/1/status";
-    ac_state   = "/proc/acpi/ac_adapter/0/status";
-    ac_state_state = "status";
-    charging_state = "state";
-  } else {
-    batt_info  = "/proc/acpi/battery/BAT1/info";
-    batt_state = "/proc/acpi/battery/BAT1/state";
-    ac_state   = "/proc/acpi/ac_adapter/ACAD/state";
-    ac_state_state = "state";
-    charging_state = "charging state";
-  }
+  if(!acpi_data_initialized) {
+    DIR *dir_fd;
+    struct dirent *dir_data;
+    char *battery_base_dir="/proc/acpi/battery";
+    char *ac_base_dir="/proc/acpi/ac_adapter";
+
+    if (acpi_ver < (gulong)20020208) {
+      ac_state_state = "status";
+      charging_state = "state";
+    } else {
+      ac_state_state = "state";
+      charging_state = "charging state";
+    }
+    
+    /* Look for the battery dir */
+    dir_fd=opendir(battery_base_dir);
+    if(dir_fd!=NULL) {
+      int dir_found=0;
+      struct stat tmp_stat;
+
+      /* Skip . and .. */
+      readdir(dir_fd);
+      readdir(dir_fd);
+
+      /* Start looking for a subdir with an "info" file ... */
+      while( !dir_found && (dir_data=readdir(dir_fd))!=NULL ) {
+        snprintf(batt_info, 49, "%s/%s/info", battery_base_dir, 
+                 dir_data->d_name);
+
+        if( !stat(batt_info, &tmp_stat) ) { /* We've found it!! */
+          /* We assume that, if info exists, state should also exist */ 
+          /* Is this a safe guess?                                   */
+          snprintf(batt_state, 49, "%s/%s/%s", battery_base_dir, 
+                  dir_data->d_name, ac_state_state);
+          dir_found=1;
+        }
+      }
+
+      closedir(dir_fd);
+      if(!dir_found) {
+        return FALSE;
+      }
+
+      dir_fd=opendir(ac_base_dir);
+      if(dir_fd!=NULL) {
+        dir_found=0;
+
+        /* Skip . and .. */
+        readdir(dir_fd);
+        readdir(dir_fd);
+
+        /* Start looking for a subdir with a "status" file ... */
+        while( !dir_found && (dir_data=readdir(dir_fd))!=NULL ) {
+          snprintf(ac_state, 49, "%s/%s/%s", ac_base_dir, 
+                  dir_data->d_name, ac_state_state);
+
+          if( !stat(ac_state, &tmp_stat) ) { /* We've found it!! */
+            dir_found=1;
+          }
+        }
+
+        closedir(dir_fd);
+        if(!dir_found) {
+          return FALSE;
+        }
+      }
+    }
 
-  hash = read_file (batt_info, buf, sizeof (buf));
-  if (hash)
-    {
+    hash = read_file (batt_info, buf, sizeof (buf));
+    if (hash) {
       max_capacity = read_long (hash, "design capacity");
       low_capacity = read_long (hash, "design capacity warning");
       critical_capacity = read_long (hash, "design capacity low");
       g_hash_table_destroy (hash);
     }
+
+    acpi_data_initialized=1;
+  }
   
   if (!max_capacity)
     return FALSE;

Reply to: