-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hello,

On Thu, 10 Feb 2011 00:04:32 +0100
gregor herrmann <[email protected]> wrote:

> The ACPI backend for --battery doesn't work with newer kernels
> (experienced with 2.6.37 from experimental); if I read acpi.c
> correctly, it looks for /proc/acpi/{ac_adapter,battery}, and those
> paths seem to have vanished.

> (The fallback on hal doesn't really help if hal isn't installed but
> it still produces lots of DBUS errors; without failing on startup.)

The attached patch fixes ACPI backend (removing the old procfs method
at the same time).

- -- 
WBR, Andrew
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iQIcBAEBCAAGBQJQtS5IAAoJEG6k0jEaLSaN0AkQAILxIdTfGzSgbdyZ3DrF3SnJ
kuVAXS0qNWQ9jlVGhadoyOEUKPdXDU7gOe+BOzPkoqtG/BpAlG+8vDOoUUPEBNnh
T97g2bvzEHChC6+FXbGgBtx35Ims5f8cJY33K8OXqU9ijyz8uyYho4hNl4wUE1Vr
U78NyK5BwxIi6ugve0yfn+0hqwub0mWerb1VHm063KVnlhmSvi7ucTd+/FP3OUsB
vdaW0xqlOnDXABX86ELhVIHdXFICAuq+2gObmv2oeQ0kSk+95fT2Q1xfYYxW91aD
HR2yGDMT3gEWRvVJo0OGPa0q9orJvejdCrXyb07BwfIqo4tU5d9AZ6UDaGcdI5IJ
BXjXeGcF05901W1sfzdm4k6Dqt2PTXIkYWRaGFO81ygSUX0Foe/DLQMqq3+SQADP
5ljTjeXDEjQ2t7BA1J//5ABuIdu7oPE2duQ0KAFWHLDI+X4m6yZN2UxVZUmbb/ac
vAyh/XUpNYoldlbdzMJLJYGjYtjchGLn9XAuheW7GMc+s0N2hyiP3yLrwLnB/y1c
NKRsQ/QEEtL+ZRr21EYyHiKt+nLOhKwZWKGDyUYojztSDwFPnAZAcrVQhLoyJ5rK
Rnqz6zlZxH9rdMGGNT3oZv1d/fYeXjl3y2DUK+9gKT6aVC3baUhEYuN0e+2gUOh6
ciKOIOERu+4Od4V/9fTI
=C3v6
-----END PGP SIGNATURE-----
From: Andrew Shadura <[email protected]>
Subject: Use sysfs instead of procfs.
Date: Tue, 27 Nov 2012 22:10:12 +0100
Commit-Id: 179:5047487ef89e85d419f1c99d59e22eecad992f81

Use sysfs instead of procfs.

diff --git a/acpi.c b/acpi.c
--- a/acpi.c
+++ b/acpi.c
@@ -17,7 +17,7 @@
 
 #include "acpi.h"
 
-#define PROC_ACPI "/proc/acpi"
+#define SYSFS_PATH "/sys/class/power_supply"
 #define ACPI_MAXITEM 8
 
 int acpi_batt_count = 0;
@@ -32,48 +32,25 @@ 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",
+char *acpi_labels[] = {
+	"uevent",
 	"status",
-	"battery",
-	"ac_adapter",
-	"on-line",
-	"Design Capacity:",
-	"Present:",
-	"Remaining Capacity:",
-	"Present Rate:",
-	"State:",
-#if ACPI_THERMAL
-	"thermal",
-#endif
-	"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:",
-	"present:",
-	"remaining capacity:",
-	"present rate:",
-	"charging state:",
+	"BAT",
+	"AC",
+	"POWER_SUPPLY_CAPACITY=",
+	"POWER_SUPPLY_CHARGE_FULL_DESIGN=",
+	"POWER_SUPPLY_PRESENT=",
+	"POWER_SUPPLY_CHARGE_NOW=",
+	"POWER_SUPPLY_CURRENT_NOW=",
+	"POWER_SUPPLY_STATUS=",
 #if ACPI_THERMAL
 	"thermal_zone",
 #endif
-	"state:",
-	"last full capacity:",
+	"POWER_SUPPLY_ONLINE=",
+	"POWER_SUPPLY_CHARGE_FULL=",
 	NULL
 };
 
-char **acpi_labels = NULL;
-
 #if ACPI_THERMAL
 int acpi_thermal_count = 0;
 char acpi_thermal_info[ACPI_MAXITEM][128];
@@ -129,6 +106,21 @@ char *get_acpi_value (const char *file, 
 	return scan_acpi_value(buf, key);
 }
 
+/* Returns the battery percentage.
+ */
+int get_acpi_batt_percentage(int battery) {
+	int d;
+	char *s;
+
+	s = get_acpi_value(acpi_batt_info[battery], acpi_labels[label_capacity]);
+	if (s == NULL)
+		d = 0; /* battery not present */
+	else
+		d = atoi(s);
+
+	return d;
+}
+
 /* Returns the maximum capacity of a battery.
  *
  * Note that this returns the highest possible capacity for the battery,
@@ -182,7 +174,7 @@ int find_items (char *itemname, char inf
 	
 	char pathname[128];
 
-	sprintf(pathname,PROC_ACPI "/%s",itemname);
+	sprintf(pathname, SYSFS_PATH);
 
 	dir = opendir(pathname);
 	if (dir == NULL)
@@ -192,6 +184,9 @@ int find_items (char *itemname, char inf
 		    !strcmp("..", ent->d_name))
 			continue;
 
+		if (strstr(ent->d_name, itemname) != ent->d_name)
+			continue;
+
 		devices[num_devices]=strdup(ent->d_name);
 		num_devices++;
 		if (num_devices >= ACPI_MAXITEM)
@@ -199,14 +194,14 @@ int find_items (char *itemname, char inf
 	}
 	closedir(dir);
 	
-	/* Sort, since readdir can return in any order. /proc/ does
-	 * sometimes list BATT2 before BATT1. */
+	/* Sort, since readdir can return in any order. /sys/ does
+	 * sometimes list BAT1 before BAT0. */
 	qsort(devices, num_devices, sizeof(char *), _acpi_compare_strings);
 
 	for (i = 0; i < num_devices; i++) {
-		sprintf(infoarray[i], PROC_ACPI "/%s/%s/%s", itemname, devices[i],
+		sprintf(infoarray[i], SYSFS_PATH "/%s/%s", devices[i],
 			acpi_labels[label_info]);
-		sprintf(statusarray[i], PROC_ACPI "/%s/%s/%s", itemname, devices[i],
+		sprintf(statusarray[i], SYSFS_PATH "/%s/%s", devices[i],
 			acpi_labels[label_status]);
 		free(devices[i]);
 	}
@@ -243,8 +238,8 @@ int find_thermal(void) {
 int on_ac_power (void) {
 	int i;
 	for (i = 0; i < acpi_ac_count; i++) {
-                char *online=get_acpi_value(acpi_ac_adapter_status[i], acpi_labels[label_ac_state]);
-		if (online && strcmp(acpi_labels[label_online], online) == 0)
+		char *online=get_acpi_value(acpi_ac_adapter_info[i], acpi_labels[label_ac_state]);
+		if (online && atoi(online))
 			return 1;
 		else
 			return 0;
@@ -259,7 +254,7 @@ int acpi_supported (void) {
 	DIR *dir;
 	int num;
 
-	if (!(dir = opendir(PROC_ACPI))) {
+	if (!(dir = opendir(SYSFS_PATH))) {
 		return 0;
 	}
 	closedir(dir);
@@ -269,13 +264,6 @@ int acpi_supported (void) {
 	
 	version = get_acpi_file("/sys/module/acpi/parameters/acpica_version");
 	if (version == NULL) {
-		version = get_acpi_value(PROC_ACPI "/info", "ACPI-CA Version:");
-		if (version == NULL) {
-			/* 2.5 kernel acpi */
-			version = get_acpi_value(PROC_ACPI "/info", "version:");
-		}
-	}
-	if (version == NULL) {
 		return 0;
 	}
 	num = atoi(version);
@@ -284,12 +272,6 @@ int acpi_supported (void) {
 				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();
@@ -319,9 +301,9 @@ int acpi_read (int battery, apm_info *in
 	/* Internally it's zero indexed. */
 	battery--;
 	
-	buf = get_acpi_file(acpi_batt_status[battery]);
+	buf = get_acpi_file(acpi_batt_info[battery]);
 	if (buf == NULL) {
-		fprintf(stderr, "unable to read %s\n", acpi_batt_status[battery]);
+		fprintf(stderr, "unable to read %s\n", acpi_batt_info[battery]);
 		perror("read");
 		exit(1);
 	}
@@ -332,66 +314,34 @@ int acpi_read (int battery, apm_info *in
 	
 	/* Work out if the battery is present, and what percentage of full
 	 * it is and how much time is left. */
-	if (strcmp(scan_acpi_value(buf, acpi_labels[label_present]), "yes") == 0) {
+	if (strcmp(scan_acpi_value(buf, acpi_labels[label_present]), "1") == 0) {
 		int pcap = scan_acpi_num(buf, acpi_labels[label_remaining_capacity]);
-		int rate = scan_acpi_num(buf, acpi_labels[label_present_rate]);
-
-		if (rate) {
-			/* time remaining = (current_capacity / discharge rate) */
-			info->battery_time = (float) pcap / (float) rate * 60;
-		}
-		else {
-			char *rate_s = scan_acpi_value(buf, acpi_labels[label_present_rate]);
-			if (! rate_s) {
-				/* Time remaining unknown. */
-				info->battery_time = 0;
-			}
-			else {
-				/* a zero or unknown in the file; time 
-				 * unknown so use a negative one to
-				 * indicate this */
-				info->battery_time = -1;
-			}
-		}
-
 		state = scan_acpi_value(buf, acpi_labels[label_charging_state]);
 		if (state) {
-			if (state[0] == 'd') { /* discharging */
+			if (state[0] == 'D') { /* discharging */
 				info->battery_status = BATTERY_STATUS_CHARGING;
 				/* Expensive ac power check used here
 				 * because AC power might be on even if a
 				 * battery is discharging in some cases. */
 				info->ac_line_status = on_ac_power();
 			}
-			else if (state[0] == 'c' && state[1] == 'h') { /* charging */
+			else if (state[0] == 'C' && state[1] == 'h') { /* charging */
 				info->battery_status = BATTERY_STATUS_CHARGING;
 				info->ac_line_status = 1;
 				info->battery_flags = info->battery_flags | BATTERY_FLAGS_CHARGING;
-				if (rate)
-					info->battery_time = -1 * (float) (acpi_batt_capacity[battery] - pcap) / (float) rate * 60;
-				else
-					info->battery_time = 0;
-				if (abs(info->battery_time) < 0.5)
-					info->battery_time = 0;
 			}
-			else if (state[0] == 'o') { /* ok */
+			else if (state[0] == 'F') { /* full */
 				/* charged, on ac power */
 				info->battery_status = BATTERY_STATUS_HIGH;
 				info->ac_line_status = 1;
 			}
-			else if (state[0] == 'c') { /* not charging, so must be critical */
+			else if (state[0] == 'C') { /* not charging, so must be critical */
 				info->battery_status = BATTERY_STATUS_CRITICAL;
 				/* Expensive ac power check used here
 				 * because AC power might be on even if a
 				 * battery is critical in some cases. */
 				info->ac_line_status = on_ac_power();
 			}
-			else if (rate == 0) {
-				/* if rate is null, battery charged, on
-				 * ac power */
-				info->battery_status = BATTERY_STATUS_HIGH;
-				info->ac_line_status = 1;
-			}
 			else {
 				fprintf(stderr, "unknown battery state: %s\n", state);
 			}
@@ -414,10 +364,11 @@ int acpi_read (int battery, apm_info *in
 			 * capacity. Rescan for a new max capacity. */
 			find_batteries();
 		}
 		
 		if (pcap && acpi_batt_capacity[battery]) {
-			/* percentage = (current_capacity / max capacity) * 100 */
-			info->battery_percentage = (float) pcap / (float) acpi_batt_capacity[battery] * 100;
+			info->battery_percentage = get_acpi_batt_percentage(battery);
+			if (info->battery_percentage > 100)
+				info->battery_percentage = 100;
 		}
 		else {
 			info->battery_percentage = -1;
diff --git a/acpi.h b/acpi.h
--- a/acpi.h
+++ b/acpi.h
@@ -49,7 +49,7 @@ enum acpi_labels_items {
 	label_status,
 	label_battery,
 	label_ac_adapter,
-	label_online,
+	label_capacity,
 	label_design_capacity,
 	label_present,
 	label_remaining_capacity,
@@ -64,4 +64,4 @@ enum acpi_labels_items {
 
 /* This is set to point to a list of strings used for the given acpi
  *  * version. */
-extern char **acpi_labels;
+extern char *acpi_labels[];

Reply via email to