static const char ac_acpi_dir_base[] = "/sys/class/power_supply";
static const char battery_acpi_dir_base[] = "/sys/class/power_supply";
-static void read_ac_status(void)
+static int
+read_int_from_file(const char *path)
{
- FILE *ac_file;
- char ac_file_path[256], ac_file_line[40];
-
- sprintf(ac_file_path, "%s/%s/online", ac_acpi_dir_base,
- ac);
+ FILE *fp;
+ int value;
- ac_file = fopen(ac_file_path, "r");
+ if (access(path, F_OK ) < 0) {
+ /* File not found, abort. */
+ fprintf(stderr, "Missing file.\n");
+ exit(EXIT_FAILURE);
+ }
- if (ac_file == NULL) {
- perror(ac_file_path);
- fprintf(stderr,
- "Unable to find power supply AC online status.\n");
+ fp = fopen(path, "r");
+ if (fp == NULL) {
+ /* File could not be read, abort. */
+ perror(path);
+ fprintf(stderr, "Unable to read file.\n");
exit(EXIT_FAILURE);
} else {
- while (!feof(ac_file)) {
- memset(ac_file_line, 0, 40);
- fgets(ac_file_line, 40, ac_file);
-
- sscanf(ac_file_line, "%d", &ac_online);
+ char buf[40];
- break;
- }
+ memset(buf, 0, sizeof(buf));
+ fgets(buf, sizeof(buf), fp);
+ sscanf(buf, "%d", &value);
#ifdef DEBUG_ACPI
- printf("ac online = %d\n", ac_online);
+ printf("value = %d\n", value);
#endif /* DEBUG_ACPI */
}
- fclose(ac_file);
+ fclose(fp);
+
+ return value;
}
-static void read_battery_status(void)
+static void read_ac_status(void)
{
- FILE *batt_file;
- char batt_file_path[256], batt_file_line[40];
+ char path[256];
- sprintf(batt_file_path, "%s/%s/capacity", battery_acpi_dir_base,
- battery);
+ sprintf(path, "%s/%s/online", ac_acpi_dir_base, ac);
- batt_file = fopen(batt_file_path, "r");
-
- if (batt_file == NULL) {
- perror(batt_file_path);
+ if (access(path, F_OK ) < 0) {
+ perror(path);
fprintf(stderr,
- "Unable to determine battery capacity.\n");
+ "Unable to find power supply AC online status.\n");
exit(EXIT_FAILURE);
- } else {
- while (!feof(batt_file)) {
- memset(batt_file_line, 0, 40);
- fgets(batt_file_line, 40, batt_file);
+ }
- sscanf(batt_file_line, "%d", &capacity);
- break;
- }
+ ac_online = read_int_from_file(path);
#ifdef DEBUG_ACPI
- printf("capacity = %d%%\n", capacity);
+ printf("ac online = %d\n", ac_online);
#endif /* DEBUG_ACPI */
- }
+}
+
+static void
+compute_battery_capacity_from_energy(void)
+{
+ char path[256];
+ int64_t full, now;
- fclose(batt_file);
+ sprintf(path, "%s/%s/energy_full", battery_acpi_dir_base, battery);
+#ifdef DEBUG_ACPI
+ printf("Energy full: ");
+#endif /* DEBUG_ACPI */
+ full = read_int_from_file(path);
+
+ sprintf(path, "%s/%s/energy_now", battery_acpi_dir_base, battery);
+#ifdef DEBUG_ACPI
+ printf("Energy now: ");
+#endif /* DEBUG_ACPI */
+ now = read_int_from_file(path);
+
+ capacity = (now * 100) / full;
+
+#ifdef DEBUG_ACPI
+ printf("capacity = %d%%\n", capacity);
+#endif /* DEBUG_ACPI */
+}
+
+static void read_battery_capacity(void)
+{
+ char path[256];
+
+ sprintf(path, "%s/%s/capacity", battery_acpi_dir_base, battery);
+
+ if (access(path, F_OK ) < 0) {
+ /* Capacity file doesn't exist, try reading energy... */
+ compute_battery_capacity_from_energy();
+ } else {
+ capacity = read_int_from_file(path);
+ }
}
static void
int height;
read_ac_status();
- read_battery_status();
+ read_battery_capacity();
cairo_save(cr);