diff -Nur xbattbar-1.4.2/acpi.h xbattbar-1.4.2-acpi/acpi.h
--- xbattbar-1.4.2/acpi.h	1970-01-01 01:00:00.000000000 +0100
+++ xbattbar-1.4.2-acpi/acpi.h	2005-06-15 07:10:57.580549170 +0200
@@ -0,0 +1,69 @@
+/* 
+ * A not-yet-general-purpose ACPI library, by Joey Hess <joey@kitenet.net>
+ */
+
+/* Define ACPI_THERMAL to make the library support finding info about thermal
+ * sources. */
+//#define ACPI_THERMAL 1
+
+/* Define ACPI_APM to get the acpi_read function, which is like apm_read. */
+//#define ACPI_APM 1
+
+/* The lowest version of ACPI proc files supported. */
+#define ACPI_VERSION 20011018
+
+/* The number of acpi items of each class supported. */
+#define ACPI_MAXITEM 8
+
+int acpi_supported (void);
+#ifdef ACPI_APM
+int acpi_read (int battery, apm_info *info);
+#endif
+char *get_acpi_file (const char *file);
+int scan_acpi_num (const char *buf, const char *key);
+char *scan_acpi_value (const char *buf, const char *key);
+char *get_acpi_value (const char *file, const char *key);
+int get_acpi_batt_capacity(int battery);
+
+extern int acpi_batt_count;
+/* Filenames of the battery info files for each system battery. */
+extern char acpi_batt_info[ACPI_MAXITEM][128];
+/* Filenames of the battery status files for each system battery. */
+extern char acpi_batt_status[ACPI_MAXITEM][128];
+/* Stores battery capacity, or 0 if the battery is absent. */
+extern int acpi_batt_capacity[ACPI_MAXITEM];
+
+extern int acpi_ac_count;
+extern char acpi_ac_adapter_info[ACPI_MAXITEM][128];
+extern char acpi_ac_adapter_status[ACPI_MAXITEM][128];
+
+#if ACPI_THERMAL
+extern int acpi_thermal_count;
+extern char acpi_thermal_info[ACPI_MAXITEM][128];
+extern char acpi_thermal_status[ACPI_MAXITEM][128];
+extern char acpi_thermal_temperature[ACPI_MAXITEM][128];
+#endif
+
+/* This enum is used to index into the acpi_labels */
+enum acpi_labels_items {
+	label_info,
+	label_status,
+	label_battery,
+	label_ac_adapter,
+	label_online,
+	label_design_capacity,
+	label_last_full_capacity,
+	label_present,
+	label_remaining_capacity,
+	label_present_rate,
+	label_charging_state,
+#if ACPI_THERMAL
+	label_thermal,
+	label_temperature,
+#endif
+	label_ac_state,
+};
+
+/* This is set to point to a list of strings used for the given acpi
+ *  * version. */
+extern char **acpi_labels;
diff -Nur xbattbar-1.4.2/xbattbar.c xbattbar-1.4.2-acpi/xbattbar.c
--- xbattbar-1.4.2/xbattbar.c	2001-02-02 06:25:29.000000000 +0100
+++ xbattbar-1.4.2-acpi/xbattbar.c	2005-06-21 09:28:27.089146497 +0200
@@ -23,12 +23,13 @@
  * 
  */
 
-static char *ReleaseVersion="1.4.2";
+static char *ReleaseVersion="1.4.2-acpi";
 
 #include <sys/types.h>
 #include <sys/time.h>
 #include <signal.h>
 #include <stdio.h>
+#include <dirent.h>
 #include <unistd.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
@@ -49,6 +50,14 @@
 #define DiagXMergin 20
 #define DiagYMergin 5
 
+/* Uncomment this to support ACPI */
+#define SUPPORT_ACPI
+
+#ifndef SUPPORT_ACPI
+  #define SUPPORT_APM
+#endif
+
+
 /*
  * Global variables
  */
@@ -109,7 +118,8 @@
 {
   fprintf(stderr, 
 	  "This is xbattbar version %s, "
-	  "copyright (c)1998-2001 Suguru Yamaguchi\n",
+	  "copyright (c)1998-2001 Suguru Yamaguchi\n"
+	  "modified to understand ACPI also by Alexander Griesser [xbattbar@tuxx-home.at]\n",
 	  ReleaseVersion);
 }
 
@@ -632,8 +642,11 @@
 #ifdef linux
 
 #include <errno.h>
-#include <linux/apm_bios.h>
 
+/* APM Support */
+#ifdef SUPPORT_APM
+
+#include <linux/apm_bios.h>
 #define APM_PROC	"/proc/apm"
 
 #define        APM_STAT_LINE_OFF       0
@@ -708,5 +721,333 @@
   signal(SIGALRM, (void *)(battery_check));
 }
 
+#endif /* APM Support */
+
+/* ACPI Support */
+#ifdef SUPPORT_ACPI
+#include "acpi.h"
+#define PROC_ACPI "/proc/acpi"
+#define ACPI_MAXITEM 8
+#define ACPI_STAT_LINE_ON 1
+#define ACPI_STAT_LINE_OFF 0
+
+int acpi_batt_count = 0;
+/* Filenames of the battery info files for each system battery. */
+char acpi_batt_info[ACPI_MAXITEM][128];
+/* Filenames of the battery status files for each system battery. */
+char acpi_batt_status[ACPI_MAXITEM][128];
+/* Stores battery capacity, or 0 if the battery is absent. */
+int acpi_batt_capacity[ACPI_MAXITEM];
+
+int acpi_ac_count = 0;
+char acpi_ac_adapter_info[ACPI_MAXITEM][128];
+char acpi_ac_adapter_status[ACPI_MAXITEM][128];
+
+/* These are the strings used in the ACPI shipped with the 2.4 kernels */
+char *acpi_labels_old[] = {
+        "info",
+        "status",
+        "battery",
+        "ac_adapter",
+        "on-line",
+        "Design Capacity:",
+        "Present:",
+        "Remaining Capacity:",
+        "Present Rate:",
+        "State:",
+        "Status:",
+        NULL
+};
+
+/* These are the strings used in ACPI in the 2.5 kernels, circa version
+ * 20020214 */
+char *acpi_labels_20020214[] = {
+        "info",
+        "state",
+        "battery",
+        "ac_adapter",
+        "on-line",
+        "design capacity:",
+        "last full capacity:",
+        "present:",
+        "remaining capacity:",
+        "present rate:",
+        "charging state:",
+        "state:",
+        NULL
+};
+
+char **acpi_labels = NULL;
+
+/* Read in an entire ACPI proc file (well, the first 1024 bytes anyway), and
+ * return a statically allocated array containing it. */
+inline char *get_acpi_file (const char *file) {
+        int fd;
+        int end;
+        static char buf[1024];
+        fd = open(file, O_RDONLY);
+        if (fd == -1) return NULL;
+        end = read(fd, buf, sizeof(buf));
+        buf[end] = '\0';
+        close(fd);
+        return buf;
+}
+
+/* Given a buffer holding an acpi file, searches for the given key in it,
+ * and returns the numeric value. 0 is returned on failure. */
+inline int scan_acpi_num (const char *buf, const char *key) {
+        char *ptr;
+        int ret;
+        if ((ptr = strstr(buf, key))) {
+                if (sscanf(ptr + strlen(key), "%d", &ret) == 1)
+                        return ret;
+        }
+        return 0;
+}
+
+/* Given a buffer holding an acpi file, searches for the given key in it,
+ * and returns its value in a statically allocated string. */
+inline char *scan_acpi_value (const char *buf, const char *key) {
+        char *ptr;
+        static char ret[256];
+
+        if ((ptr = strstr(buf, key))) {
+                if (sscanf(ptr + strlen(key), "%s", ret) == 1)
+                        return ret;
+        }
+        return NULL;
+}
+
+/* Read an ACPI proc file, pull out the requested piece of information, and
+ * return it (statically allocated string). Returns NULL on error, This is
+ * the slow, dumb way, fine for initialization or if only one value is needed
+ * from a file, slow if called many times. */
+char *get_acpi_value (const char *file, const char *key) {
+        char *buf = get_acpi_file(file);
+        if (! buf) return NULL;
+        return scan_acpi_value(buf, key);
+}
+
+/* Returns the last-full capacity of a battery. */
+int get_acpi_batt_capacity(int battery) {
+        int cap;
+        char *caps=get_acpi_value(acpi_batt_info[battery], acpi_labels[label_last_full_capacity]);
+        if (caps == NULL)
+                cap=0; /* battery not present */
+        else
+                cap=atoi(caps);
+        /* This is ACPI's broken way of saying that there is no battery. */
+        if (cap == 655350)
+                return 0;
+        return cap;
+}
+
+/* Comparison function for qsort. */
+int _acpi_compare_strings (const void *a, const void *b) {
+        const char **pa = (const char **)a;
+        const char **pb = (const char **)b;
+        return strcasecmp((const char *)*pa, (const char *)*pb);
+}
+
+/* Find something (batteries, ac adpaters, etc), and set up a string array
+ * to hold the paths to info and status files of the things found. Must be
+ * in /proc/acpi to call this. Returns the number of items found. */
+int find_items (char *itemname, char infoarray[ACPI_MAXITEM][128],
+                                char statusarray[ACPI_MAXITEM][128]) {
+        DIR *dir;
+        struct dirent *ent;
+        int num_devices=0;
+        int i;
+        char **devices = malloc(ACPI_MAXITEM * sizeof(char *));
+
+        dir = opendir(itemname);
+        if (dir == NULL)
+                return 0;
+        while ((ent = readdir(dir))) {
+                if (!strncmp(".", ent->d_name, 1) ||
+                    !strncmp("..", ent->d_name, 2))
+                        continue;
+
+                devices[num_devices]=strdup(ent->d_name);
+                num_devices++;
+                if (num_devices >= ACPI_MAXITEM)
+                        break;
+        }
+        closedir(dir);
+
+        /* Sort, since readdir can return in any order. /proc/does
+         * sometimes list BATT2 before BATT1. */
+        qsort(devices, num_devices, sizeof(char *), _acpi_compare_strings);
+
+        for (i = 0; i < num_devices; i++) {
+                sprintf(infoarray[i], "%s/%s/%s", itemname, devices[i],
+                        acpi_labels[label_info]);
+                sprintf(statusarray[i], "%s/%s/%s", itemname, devices[i],
+                        acpi_labels[label_status]);
+                free(devices[i]);
+        }
+
+        return num_devices;
+}
+
+/* Find batteries, return the number, and set acpi_batt_count to it as well. */
+int find_batteries(void) {
+        int i;
+        acpi_batt_count = find_items(acpi_labels[label_battery], acpi_batt_info, acpi_batt_status);
+        /* Read in the last charged capacity of the batteries. */
+        for (i = 0; i < acpi_batt_count; i++)
+                acpi_batt_capacity[i] = get_acpi_batt_capacity(i);
+        return acpi_batt_count;
+}
+
+/* Find AC power adapters, return the number found, and set acpi_ac_count to it
+ * as well. */
+int find_ac_adapters(void) {
+        acpi_ac_count = find_items(acpi_labels[label_ac_adapter], acpi_ac_adapter_info, acpi_ac_adapter_status);
+        return acpi_ac_count;
+}
+
+
+/* Returns true if the system is on ac power. Call find_ac_adapters first. */
+int on_ac_power (void) {
+        int i;
+        for (i = 0; i < acpi_ac_count; i++) {
+                if (strcmp(acpi_labels[label_online], get_acpi_value(acpi_ac_adapter_status[i], acpi_labels[label_ac_state])) == 0)
+                        return 1;
+                else
+                        return 0;
+        }
+        return 0;
+}
+
+/* See if we have ACPI support and check version. Also find batteries and
+ * ac power adapters. */
+int acpi_supported (void) {
+        char *version;
+        int num;
+
+        if (chdir(PROC_ACPI) == -1) {
+                return 0;
+        }
+
+        version = get_acpi_value("info", "ACPI-CA Version:");
+        if (version == NULL) {
+                /* 2.5 kernel acpi */
+                version = get_acpi_value("info", "version:");
+        }
+        if (version == NULL) {
+                return 0;
+        }
+        num = atoi(version);
+        if (num < ACPI_VERSION) {
+                fprintf(stderr, "ACPI subsystem %s too is old, consider upgrading to %i.\n",
+                                version, ACPI_VERSION);
+                return 0;
+        }
+        else if (num >= 20020214) {
+                acpi_labels = acpi_labels_20020214;
+        }
+        else {
+                acpi_labels = acpi_labels_old;
+        }
+
+        find_batteries();
+        find_ac_adapters();
+
+        return 1;
+}
+
+void battery_check(void)
+{
+  int i, j;
+  char *buf;
+  if (! acpi_supported())
+  {
+    fprintf(stderr, "xbattbar: ACPI is not supported by your running kernel!");
+    signal(SIGALRM, (void *)(battery_check));
+    exit(1);
+  }
+
+  ++elapsed_time;
+
+  int index=0;
+
+  float percent = 0, timeleft = 0, timefull = 0;
+  int rate = 0, pcap = 0;
+  char *status;
+
+  buf = get_acpi_file(acpi_batt_status[index]);
+  if (! buf) return;
+
+  if (strcmp(scan_acpi_value(buf, acpi_labels[label_present]), "yes") == 0)
+  {
+    pcap = scan_acpi_num(buf, acpi_labels[label_remaining_capacity]);
+    rate = scan_acpi_num(buf, acpi_labels[label_present_rate]);
+
+    if (rate)
+    {
+      /* time remaining till empty = current_capacity / discharge rate) */
+      timeleft = (float) pcap / (float) rate * 60;
+    }
+    else
+    {
+      char *rate_s = scan_acpi_value(buf, acpi_labels[label_present_rate]);
+      /* If the battery is not present, ACPI may
+       * still say it is but sets rate to unknown
+       * (on my picturebook, anyway). I don't
+       * know if this is the correct way to do
+       * it. */
+      if (rate_s && strcmp(rate_s, "unknown") == 0)
+      {
+        fprintf(stderr, "xbattbar: unknown rate!"); 
+      }
+    }
+
+    /* time remaining till full */
+    timefull = (float)(acpi_batt_capacity[index] - pcap) / (float) rate * 60;
+
+    /* Status. */
+    if (on_ac_power())
+    {
+      /* System is on ac power */
+      ac_line = ACPI_STAT_LINE_ON;
+    }
+    else
+    {
+      /* System runs on batteries */
+      ac_line = ACPI_STAT_LINE_OFF;
+    }
+
+    if (acpi_batt_capacity[index] == 0)
+    {
+      /* The battery was absent, and now is
+       * present. Well, it might be a different
+       * battery. So re-probe the battery. */
+      /* NOTE that this invalidates buf. */
+      acpi_batt_capacity[index] = get_acpi_batt_capacity(index);
+    }
+
+    if (pcap)
+    {
+      /* percentage = (current_capacity / last_full_capacity) * 100 */
+      percent = (float) pcap / (float) acpi_batt_capacity[index] * 100;
+    }
+    else
+    {
+      percent = 0;
+    }
+  }
+
+  /* Percent charged. */
+  battery_level = percent;
+
+  redraw();
+  signal(SIGALRM, (void *)(battery_check));
+}
+
+
+#endif /* ACPI Support */
+
+
 #endif /* linux */
 
diff -Nur xbattbar-1.4.2/xbattbar.man xbattbar-1.4.2-acpi/xbattbar.man
--- xbattbar-1.4.2/xbattbar.man	2001-02-02 06:25:29.000000000 +0100
+++ xbattbar-1.4.2-acpi/xbattbar.man	2005-06-21 09:18:19.866296771 +0200
@@ -36,8 +36,8 @@
 .Sh DESCRIPTION
 .Nm xbattbar
 shows the current (laptop) battery status in the X window environment.
-Battery status is obtained through the APM kernel module.
-The APM kernel module depends on your UNIX platform,
+Battery status is obtained through the APM or ACPI kernel module.
+The APM/ACPI kernel module depends on your UNIX platform,
 therefore, consult your documentation for its detail.
 .Pp
 .Nm xbattbar
@@ -81,7 +81,7 @@
 .Pp
 .Nm xbattbar
 trys to know its battery status in every 10 seconds in default.
-This is achived by APM polling.
+This is achived by APM/ACPI polling.
 .Nm -p
 option sets the polling interval in second.
 .Pp

