X-Git-Url: https://git.xinqibao.xyz/slstatus.git/blobdiff_plain/ec5c35ec9f23254f09e734d0c1880559774dfa52..a1ac203d16c379d7fc05765545af2977a7a3584d:/components/battery.c

diff --git a/components/battery.c b/components/battery.c
index ff06f40..07b6ac1 100644
--- a/components/battery.c
+++ b/components/battery.c
@@ -1,5 +1,4 @@
 /* See LICENSE file for copyright and license details. */
-#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -7,21 +6,20 @@
 
 #if defined(__linux__)
 	#include <limits.h>
+	#include <stdint.h>
 	#include <unistd.h>
 
-	#define CHARGE_NOW    "/sys/class/power_supply/%s/charge_now"
-	#define ENERGY_NOW    "/sys/class/power_supply/%s/energy_now"
-	#define CURRENT_NOW   "/sys/class/power_supply/%s/current_now"
-	#define POWER_NOW     "/sys/class/power_supply/%s/power_now"
-
 	static const char *
-	pick(const char *bat, const char *f1, const char *f2, char *path, size_t length)
+	pick(const char *bat, const char *f1, const char *f2, char *path,
+	     size_t length)
 	{
-		if (esnprintf(path, length, f1, bat) > 0 && access(path, R_OK) == 0) {
+		if (esnprintf(path, length, f1, bat) > 0 &&
+		    access(path, R_OK) == 0) {
 			return f1;
 		}
 
-		if (esnprintf(path, length, f2, bat) > 0 && access(path, R_OK) == 0) {
+		if (esnprintf(path, length, f2, bat) > 0 &&
+		    access(path, R_OK) == 0) {
 			return f2;
 		}
 
@@ -35,8 +33,7 @@
 		char path[PATH_MAX];
 
 		if (esnprintf(path, sizeof(path),
-		              "/sys/class/power_supply/%s/capacity",
-		              bat) < 0) {
+		              "/sys/class/power_supply/%s/capacity", bat) < 0) {
 			return NULL;
 		}
 		if (pscanf(path, "%d", &perc) != 1) {
@@ -60,8 +57,7 @@
 		char path[PATH_MAX], state[12];
 
 		if (esnprintf(path, sizeof(path),
-		              "/sys/class/power_supply/%s/status",
-		              bat) < 0) {
+		              "/sys/class/power_supply/%s/status", bat) < 0) {
 			return NULL;
 		}
 		if (pscanf(path, "%12s", state) != 1) {
@@ -79,35 +75,42 @@
 	const char *
 	battery_remaining(const char *bat)
 	{
-		int charge_now, current_now, m, h;
-		float timeleft;
+		uintmax_t charge_now, current_now, m, h;
+		double timeleft;
 		char path[PATH_MAX], state[12];
 
 		if (esnprintf(path, sizeof(path),
-		              "/sys/class/power_supply/%s/status",
-		              bat) < 0) {
+		              "/sys/class/power_supply/%s/status", bat) < 0) {
 			return NULL;
 		}
 		if (pscanf(path, "%12s", state) != 1) {
 			return NULL;
 		}
 
-		if (pick(bat, CHARGE_NOW, ENERGY_NOW, path, sizeof (path)) == NULL ||
-		    pscanf(path, "%d", &charge_now) < 0) {
+		if (!pick(bat, "/sys/class/power_supply/%s/charge_now",
+		          "/sys/class/power_supply/%s/energy_now", path,
+		          sizeof(path)) ||
+		    pscanf(path, "%ju", &charge_now) < 0) {
 			return NULL;
 		}
 
 		if (!strcmp(state, "Discharging")) {
-			if (pick(bat, CURRENT_NOW, POWER_NOW, path, sizeof (path)) == NULL ||
-			    pscanf(path, "%d", &current_now) < 0) {
+			if (!pick(bat, "/sys/class/power_supply/%s/current_now",
+			          "/sys/class/power_supply/%s/power_now", path,
+			          sizeof(path)) ||
+			    pscanf(path, "%ju", &current_now) < 0) {
+				return NULL;
+			}
+
+			if (current_now == 0) {
 				return NULL;
 			}
 
-			timeleft = (float)charge_now / (float)current_now;
+			timeleft = (double)charge_now / (double)current_now;
 			h = timeleft;
-			m = (timeleft - (float)h) * 60;
+			m = (timeleft - (double)h) * 60;
 
-			return bprintf("%dh %dm", h, m);
+			return bprintf("%juh %jum", h, m);
 		}
 
 		return "";
@@ -182,7 +185,8 @@
 
 		if (load_apm_power_info(&apm_info)) {
 			if (apm_info.ac_state != APM_AC_ON) {
-				return bprintf("%uh %02um", apm_info.minutes_left / 60,
+				return bprintf("%uh %02um",
+			                       apm_info.minutes_left / 60,
 				               apm_info.minutes_left % 60);
 			} else {
 				return "";
@@ -191,4 +195,57 @@
 
 		return NULL;
 	}
+#elif defined(__FreeBSD__)
+	#include <sys/sysctl.h>
+
+	const char *
+	battery_perc(const char *unused)
+	{
+		int cap;
+		size_t len;
+
+		len = sizeof(cap);
+		if (sysctlbyname("hw.acpi.battery.life", &cap, &len, NULL, 0) == -1
+				|| !len)
+			return NULL;
+
+		return bprintf("%d", cap);
+	}
+
+	const char *
+	battery_state(const char *unused)
+	{
+		int state;
+		size_t len;
+
+		len = sizeof(state);
+		if (sysctlbyname("hw.acpi.battery.state", &state, &len, NULL, 0) == -1
+				|| !len)
+			return NULL;
+
+		switch(state) {
+			case 0:
+			case 2:
+				return "+";
+			case 1:
+				return "-";
+			default:
+				return "?";
+		}
+	}
+
+	const char *
+	battery_remaining(const char *unused)
+	{
+		int rem;
+		size_t len;
+
+		len = sizeof(rem);
+		if (sysctlbyname("hw.acpi.battery.time", &rem, &len, NULL, 0) == -1
+				|| !len
+				|| rem == -1)
+			return NULL;
+
+		return bprintf("%uh %02um", rem / 60, rem % 60);
+	}
 #endif