#include #include #include #include #if defined(__FreeBSD__) #include #endif // maximum number of batteries supported #define MAXBAT 2 const char *icon[] = { "󰂎", /* 0% */ "󰁺", "󰁻", "󰁼", "󰁽", "󰁾", /* 50% */ "󰁿", "󰂀", "󰂁", "󰂂", "󰁹", /* 100% */ }; const char charging[] = "󰂄"; const char disconnected[] = "󰂃"; const char unknown[] = "󰂑"; typedef enum { CHARGED = 0, DISCHARGING = 1, CHARGING = 2, DISCONNECTED = 7, UNKNOWN = -1 } State; const char separator[] = " "; // space between battery indicators void battery_state(int *nbats, int bat[], State state[]) { #if defined(__linux__) FILE *fd; int i; for (i = 0; i < MAXBAT; i++) { char filename[50], status[50]; // get current capacity sprintf(filename, "/sys/class/power_supply/BAT%d/capacity", i); fd = fopen(filename, "rb"); if (fd == NULL) break; fscanf(fd, "%d", &bat[i]); fclose(fd); // battery status (charging...) sprintf(filename, "/sys/class/power_supply/BAT%d/status", i); fd = fopen(filename, "rb"); fgets(status, 50, fd); // puts(status); fclose(fd); if (!strcmp(status, "Not charging\n")) state[i] = CHARGED; else if (!strcmp(status, "Discharging\n")) state[i] = DISCHARGING; else if (!strcmp(status, "Charging\n")) state[i] = CHARGING; else state[i] = UNKNOWN; } *nbats = i; #elif defined(__FreeBSD__) size_t len = sizeof(int); int status, life = 0; *nbats = 1; // FIXME: deal with multiple batteries if (sysctlbyname("hw.acpi.battery.state", &status, &len, NULL, 0) || sysctlbyname("hw.acpi.battery.life", &life, &len, NULL, 0)) { state[0] = UNKNOWN; bat[0] = 0; } else { bat[0] = life; state[0] = status; } #else #error "Unsupported" #endif } int main() { char *color; int life[2], nbats; State state[2]; battery_state(&nbats, life, state); for (int i = 0; i < nbats; i++) { if (i > 0) printf("%s", separator); switch (state[i]) { case CHARGED: /* fully charged */ printf("%s %d%%", icon[life[i] / 10], life[i]); break; case DISCHARGING: /* discharging */ if (life[i] >= 50) color = "colour028"; /* green */ else if (life[i] >= 25) color = "colour172"; /* yellow */ else color = "colour196"; /* red */ printf("#[fg=%s]%s#[fg=default] %d%%", color, icon[life[i] / 10], life[i]); break; case CHARGING: /* charging */ printf("#[fg=yellow]%s#[fg=default] %d%%", charging, life[i]); break; case DISCONNECTED: /* disconnected */ printf("%s", disconnected); break; default: /* unknown code */ printf("%s", unknown); } } return EXIT_SUCCESS; }