battstat support for acpi 20020208
- From: jacob berkman <jacob ximian com>
- To: desktop-devel-list <desktop-devel-list gnome org>
- Subject: battstat support for acpi 20020208
- Date: 18 Feb 2002 01:29:37 -0500
this patch makes the acpi support in battstat work with the 20020208
release of acpi.
i just used the acpi file reading from the applet i wrote; i think it's
simpler and less prone to kernel changes (ie, if the order of fields
changes in the kernel the old applet would break).
also it removes C++ comments from acpi-linux.c
it should work with older (> 2.4.12) acpi also, but i haven't yet tested
this yet. someone else running one of these please let me know if it
works or doesn't work before i commit this.
jacob
--
Index: acpi-linux.c
===================================================================
RCS file: /cvs/gnome/gnome-applets/battstat/acpi-linux.c,v
retrieving revision 1.3
diff -u -r1.3 acpi-linux.c
--- acpi-linux.c 2001/11/04 23:41:22 1.3
+++ acpi-linux.c 2002/02/18 06:26:06
@@ -18,8 +18,10 @@
$Id: acpi-linux.c,v 1.3 2001/11/04 23:41:22 jdthood Exp $
*/
-// ACPI battery read-out functions for Linux >= 2.4.12
-// October 2001 by Lennart Poettering <lennart poettering de>
+/*
+ * ACPI battery read-out functions for Linux >= 2.4.12
+ * October 2001 by Lennart Poettering <lennart poettering de>
+ */
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -32,87 +34,161 @@
#include <glib.h>
#include <string.h>
#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
#include "acpi-linux.h"
-// Returns the first line of file f which starts with "field: " in
-// tmp. Return value is a pointer to the end of the string
-static gchar *al_get_field(FILE *f, const gchar *field, gchar *tmp, int s)
+static GHashTable *
+read_file (const char *file, char *buf, size_t bufsize)
{
- g_assert(f && field && tmp && s);
+ GHashTable *hash = NULL;
- while (!feof(f))
- {
- gchar *c, *e;
-
- if (!fgets(tmp, s, f)) break;
-
- if ((c = strchr(tmp, ':'))) // Is a colon separated line
- {
- *c = 0;
- if (strcmp(tmp, field) == 0) // It is the right line
- {
- c++; // Find the beginning of the data
- if (*c)
- c ++;
- c = c + strspn(c, " \t");
-
- if ((e = strchr(c, 0)) > tmp) // Remove NL from end
- {
- e--;
- if (*e == '\n')
- *e = 0;
- }
-
- return c;
- }
-
- }
+ int fd, len, i;
+ char *key, *value;
+ gboolean reading_key;
+
+ fd = open (file, O_RDONLY);
+
+ if (fd == -1) {
+ g_message ("Couldn't open %s: %s", file, g_strerror (errno));
+ return hash;
+ }
+
+ len = read (fd, buf, bufsize);
+
+ close (fd);
+
+ if (len < 0) {
+ g_message ("Error reading %s: %s", file, g_strerror (errno));
+ return hash;
+ }
+
+ hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ for (i = 0, value = key = buf, reading_key = TRUE; i < len; i++) {
+ if (buf[i] == ':' && reading_key) {
+ reading_key = FALSE;
+ buf[i] = '\0';
+ value = buf + i + 1;
+ } else if (buf[i] == '\n') {
+ reading_key = TRUE;
+ buf[i] = '\0';
+ /* g_message ("Read: %s => %s\n", key, value); */
+ g_hash_table_insert (hash, key, g_strstrip (value));
+ key = buf + i + 1;
+ } else if (reading_key) {
+ /* in acpi 20020214 it switched to lower-case proc
+ * entries. fixing this up here simplifies the
+ * code.
+ */
+ buf[i] = g_ascii_tolower (buf[i]);
}
-
- return NULL;
+ }
+
+ return hash;
}
-// Returns the same as the function above, but converted into an integer
-static int al_get_field_int(FILE *f, const gchar *field)
+#if 0
+static gboolean
+read_bool (GHashTable *hash, const char *key)
{
- gchar tmp[256];
- gchar *p;
-
- g_assert(f && field);
-
- p = al_get_field(f, field, tmp, sizeof(tmp));
- if (p)
- return atoi(p);
- else
- return 0;
+ char *s;
+
+ g_return_val_if_fail (hash, FALSE);
+ g_return_val_if_fail (key, FALSE);
+
+ s = g_hash_table_lookup (hash, key);
+ return s && (*s == 'y');
+}
+#endif
+
+static long
+read_long (GHashTable *hash, const char *key)
+{
+ char *s;
+
+ g_return_val_if_fail (hash, 0);
+ g_return_val_if_fail (key, 0);
+
+ s = g_hash_table_lookup (hash, key);
+ return s ? strtol (s, NULL, 10) : 0;
}
-// Fills out a classic apm_info structure with the data gathered from
-// the ACPI kernel interface in /proc
+static gulong
+read_ulong (GHashTable *hash, const char *key)
+{
+ char *s;
+
+ g_return_val_if_fail (hash, 0);
+ g_return_val_if_fail (key, 0);
+
+ s = g_hash_table_lookup (hash, key);
+ return s ? strtoul (s, NULL, 10) : 0;
+}
+
+static const char *
+read_string (GHashTable *hash, const char *key)
+{
+ return g_hash_table_lookup (hash, key);
+}
+
+/*
+ * Fills out a classic apm_info structure with the data gathered from
+ * the ACPI kernel interface in /proc
+ */
gboolean acpi_linux_read(struct apm_info *apminfo)
{
guint32 max_capacity, low_capacity, critical_capacity, remain;
gboolean charging, ac_online;
- FILE *f;
-
- // apminfo.ac_line_status must be one when on ac power
- // apminfo.battery_status must be 0 for high, 1 for low, 2 for critical, 3 for charging
- // apminfo.battery_percentage must contain batter charge percentage
- // apminfo.battery_flags & 0x8 must be nonzero when charging
+ gulong acpi_ver;
+ char buf[BUFSIZ];
+ GHashTable *hash;
+ const char *batt_info, *batt_state, *ac_state, *ac_state_state, *charging_state;
+
+ /*
+ * apminfo.ac_line_status must be one when on ac power
+ * apminfo.battery_status must be 0 for high, 1 for low, 2 for critical, 3 for charging
+ * apminfo.battery_percentage must contain batter charge percentage
+ * apminfo.battery_flags & 0x8 must be nonzero when charging
+ */
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;
+
+ acpi_ver = read_ulong (hash, "version");
+ g_hash_table_destroy (hash);
- if ((f = fopen("/proc/acpi/battery/1/info", "r")))
+ 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";
+ }
+
+ hash = read_file (batt_info, buf, sizeof (buf));
+ if (hash)
{
- max_capacity = al_get_field_int(f, "Design Capacity");
- low_capacity = al_get_field_int(f, "Design Capacity Warning");
- critical_capacity = al_get_field_int(f, "Design Capacity Low");
-
- fclose(f);
+ 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);
}
if (!max_capacity)
@@ -121,30 +197,25 @@
charging = FALSE;
remain = 0;
- if ((f = fopen("/proc/acpi/battery/1/status", "r")))
+ hash = read_file (batt_state, buf, sizeof (buf));
+ if (hash)
{
- gchar *s;
- gchar tmp[256];
-
- if ((s = al_get_field(f, "State", tmp, sizeof(tmp))))
- charging = strcmp(s, "charging") == 0;
-
- remain = al_get_field_int(f, "Remaining Capacity");
-
- fclose(f);
+ const char *s;
+ s = read_string (hash, charging_state);
+ charging = s ? (strcmp (s, "charging") == 0) : 0;
+ remain = read_long (hash, "remaining capacity");
+ g_hash_table_destroy (hash);
}
-
+
ac_online = FALSE;
- if ((f = fopen("/proc/acpi/ac_adapter/0/status", "r")))
+ hash = read_file (ac_state, buf, sizeof (buf));
+ if (hash)
{
- gchar *s;
- gchar tmp[256];
-
- if ((s = al_get_field(f, "Status", tmp, sizeof(tmp))))
- ac_online = strcmp(s, "on-line") == 0;
-
- fclose(f);
+ const char *s;
+ s = read_string (hash, ac_state_state);
+ ac_online = s ? (strcmp (s, "on-line") == 0) : 0;
+ g_hash_table_destroy (hash);
}
apminfo->ac_line_status = ac_online ? 1 : 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]