Xinqi Bao's Git
1 /* See LICENSE file for copyright and license details. */
12 #define CHARGE_NOW "/sys/class/power_supply/%s/charge_now"
13 #define ENERGY_NOW "/sys/class/power_supply/%s/energy_now"
14 #define CURRENT_NOW "/sys/class/power_supply/%s/current_now"
15 #define POWER_NOW "/sys/class/power_supply/%s/power_now"
18 pick(const char *bat
, const char *f1
, const char *f2
, char *path
, size_t length
)
20 if (esnprintf(path
, length
, f1
, bat
) > 0 && access(path
, R_OK
) == 0) {
24 if (esnprintf(path
, length
, f2
, bat
) > 0 && access(path
, R_OK
) == 0) {
32 battery_perc(const char *bat
)
37 if (esnprintf(path
, sizeof(path
),
38 "/sys/class/power_supply/%s/capacity",
42 if (pscanf(path
, "%d", &perc
) != 1) {
46 return bprintf("%d%%", perc
);
50 battery_state(const char *bat
)
57 { "Discharging", "-" },
60 char path
[PATH_MAX
], state
[12];
62 if (esnprintf(path
, sizeof(path
),
63 "/sys/class/power_supply/%s/status",
67 if (pscanf(path
, "%12s", state
) != 1) {
71 for (i
= 0; i
< LEN(map
); i
++) {
72 if (!strcmp(map
[i
].state
, state
)) {
76 return (i
== LEN(map
)) ? "?" : map
[i
].symbol
;
80 battery_remaining(const char *bat
)
82 int charge_now
, current_now
, m
, h
;
84 char path
[PATH_MAX
], state
[12];
86 if (esnprintf(path
, sizeof(path
),
87 "/sys/class/power_supply/%s/status",
91 if (pscanf(path
, "%12s", state
) != 1) {
95 if (pick(bat
, CHARGE_NOW
, ENERGY_NOW
, path
, sizeof (path
)) == NULL
||
96 pscanf(path
, "%d", &charge_now
) < 0) {
100 if (!strcmp(state
, "Discharging")) {
101 if (pick(bat
, CURRENT_NOW
, POWER_NOW
, path
, sizeof (path
)) == NULL
||
102 pscanf(path
, "%d", ¤t_now
) < 0) {
106 timeleft
= (float)charge_now
/ (float)current_now
;
108 m
= (timeleft
- (float)h
) * 60;
110 return bprintf("%dh %dm", h
, m
);
115 #elif defined(__OpenBSD__)
117 #include <machine/apmvar.h>
118 #include <sys/ioctl.h>
122 load_apm_power_info(struct apm_power_info
*apm_info
)
126 fd
= open("/dev/apm", O_RDONLY
);
128 warn("open '/dev/apm':");
132 memset(apm_info
, 0, sizeof(struct apm_power_info
));
133 if (ioctl(fd
, APM_IOC_GETPOWER
, apm_info
) < 0) {
134 warn("ioctl 'APM_IOC_GETPOWER':");
142 battery_perc(const char *unused
)
144 struct apm_power_info apm_info
;
146 if (load_apm_power_info(&apm_info
)) {
147 return bprintf("%d%%", apm_info
.battery_life
);
154 battery_state(const char *unused
)
163 struct apm_power_info apm_info
;
166 if (load_apm_power_info(&apm_info
)) {
167 for (i
= 0; i
< LEN(map
); i
++) {
168 if (map
[i
].state
== apm_info
.ac_state
) {
172 return (i
== LEN(map
)) ? "?" : map
[i
].symbol
;
179 battery_remaining(const char *unused
)
181 struct apm_power_info apm_info
;
183 if (load_apm_power_info(&apm_info
)) {
184 if (apm_info
.ac_state
!= APM_AC_ON
) {
185 return bprintf("%uh %02um", apm_info
.minutes_left
/ 60,
186 apm_info
.minutes_left
% 60);