Introduction
Introduction Statistics Contact Development Disclaimer Help
battery.c - slstatus - status monitor
git clone git://git.suckless.org/slstatus
Log
Files
Refs
README
LICENSE
---
battery.c (5232B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <stdio.h>
3 #include <string.h>
4
5 #include "../slstatus.h"
6 #include "../util.h"
7
8 #if defined(__linux__)
9 /*
10 * https://www.kernel.org/doc/html/latest/power/power_supply_class.html
11 */
12 #include <limits.h>
13 #include <stdint.h>
14 #include <unistd.h>
15
16 #define POWER_SUPPLY_CAPACITY "/sys/class/power_supply/%s/capaci…
17 #define POWER_SUPPLY_STATUS "/sys/class/power_supply/%s/status"
18 #define POWER_SUPPLY_CHARGE "/sys/class/power_supply/%s/charge…
19 #define POWER_SUPPLY_ENERGY "/sys/class/power_supply/%s/energy…
20 #define POWER_SUPPLY_CURRENT "/sys/class/power_supply/%s/curren…
21 #define POWER_SUPPLY_POWER "/sys/class/power_supply/%s/power_…
22
23 static const char *
24 pick(const char *bat, const char *f1, const char *f2, char *path,
25 size_t length)
26 {
27 if (esnprintf(path, length, f1, bat) > 0 &&
28 access(path, R_OK) == 0)
29 return f1;
30
31 if (esnprintf(path, length, f2, bat) > 0 &&
32 access(path, R_OK) == 0)
33 return f2;
34
35 return NULL;
36 }
37
38 const char *
39 battery_perc(const char *bat)
40 {
41 int cap_perc;
42 char path[PATH_MAX];
43
44 if (esnprintf(path, sizeof(path), POWER_SUPPLY_CAPACITY,…
45 return NULL;
46 if (pscanf(path, "%d", &cap_perc) != 1)
47 return NULL;
48
49 return bprintf("%d", cap_perc);
50 }
51
52 const char *
53 battery_state(const char *bat)
54 {
55 static struct {
56 char *state;
57 char *symbol;
58 } map[] = {
59 { "Charging", "+" },
60 { "Discharging", "-" },
61 { "Full", "o" },
62 { "Not charging", "o" },
63 };
64 size_t i;
65 char path[PATH_MAX], state[12];
66
67 if (esnprintf(path, sizeof(path), POWER_SUPPLY_STATUS, b…
68 return NULL;
69 if (pscanf(path, "%12[a-zA-Z ]", state) != 1)
70 return NULL;
71
72 for (i = 0; i < LEN(map); i++)
73 if (!strcmp(map[i].state, state))
74 break;
75
76 return (i == LEN(map)) ? "?" : map[i].symbol;
77 }
78
79 const char *
80 battery_remaining(const char *bat)
81 {
82 uintmax_t charge_now, current_now, m, h;
83 double timeleft;
84 char path[PATH_MAX], state[12];
85
86 if (esnprintf(path, sizeof(path), POWER_SUPPLY_STATUS, b…
87 return NULL;
88 if (pscanf(path, "%12[a-zA-Z ]", state) != 1)
89 return NULL;
90
91 if (!pick(bat, POWER_SUPPLY_CHARGE, POWER_SUPPLY_ENERGY,…
92 sizeof(path)) ||
93 pscanf(path, "%ju", &charge_now) < 0)
94 return NULL;
95
96 if (!strcmp(state, "Discharging")) {
97 if (!pick(bat, POWER_SUPPLY_CURRENT, POWER_SUPPL…
98 sizeof(path)) ||
99 pscanf(path, "%ju", &current_now) < 0)
100 return NULL;
101
102 if (current_now == 0)
103 return NULL;
104
105 timeleft = (double)charge_now / (double)current_…
106 h = timeleft;
107 m = (timeleft - (double)h) * 60;
108
109 return bprintf("%juh %jum", h, m);
110 }
111
112 return "";
113 }
114 #elif defined(__OpenBSD__)
115 #include <fcntl.h>
116 #include <machine/apmvar.h>
117 #include <sys/ioctl.h>
118 #include <unistd.h>
119
120 static int
121 load_apm_power_info(struct apm_power_info *apm_info)
122 {
123 int fd;
124
125 fd = open("/dev/apm", O_RDONLY);
126 if (fd < 0) {
127 warn("open '/dev/apm':");
128 return 0;
129 }
130
131 memset(apm_info, 0, sizeof(struct apm_power_info));
132 if (ioctl(fd, APM_IOC_GETPOWER, apm_info) < 0) {
133 warn("ioctl 'APM_IOC_GETPOWER':");
134 close(fd);
135 return 0;
136 }
137 return close(fd), 1;
138 }
139
140 const char *
141 battery_perc(const char *unused)
142 {
143 struct apm_power_info apm_info;
144
145 if (load_apm_power_info(&apm_info))
146 return bprintf("%d", apm_info.battery_life);
147
148 return NULL;
149 }
150
151 const char *
152 battery_state(const char *unused)
153 {
154 struct {
155 unsigned int state;
156 char *symbol;
157 } map[] = {
158 { APM_AC_ON, "+" },
159 { APM_AC_OFF, "-" },
160 };
161 struct apm_power_info apm_info;
162 size_t i;
163
164 if (load_apm_power_info(&apm_info)) {
165 for (i = 0; i < LEN(map); i++)
166 if (map[i].state == apm_info.ac_state)
167 break;
168
169 return (i == LEN(map)) ? "?" : map[i].symbol;
170 }
171
172 return NULL;
173 }
174
175 const char *
176 battery_remaining(const char *unused)
177 {
178 struct apm_power_info apm_info;
179 unsigned int h, m;
180
181 if (load_apm_power_info(&apm_info)) {
182 if (apm_info.ac_state != APM_AC_ON) {
183 h = apm_info.minutes_left / 60;
184 m = apm_info.minutes_left % 60;
185 return bprintf("%uh %02um", h, m);
186 } else {
187 return "";
188 }
189 }
190
191 return NULL;
192 }
193 #elif defined(__FreeBSD__)
194 #include <sys/sysctl.h>
195
196 #define BATTERY_LIFE "hw.acpi.battery.life"
197 #define BATTERY_STATE "hw.acpi.battery.state"
198 #define BATTERY_TIME "hw.acpi.battery.time"
199
200 const char *
201 battery_perc(const char *unused)
202 {
203 int cap_perc;
204 size_t len;
205
206 len = sizeof(cap_perc);
207 if (sysctlbyname(BATTERY_LIFE, &cap_perc, &len, NULL, 0)…
208 return NULL;
209
210 return bprintf("%d", cap_perc);
211 }
212
213 const char *
214 battery_state(const char *unused)
215 {
216 int state;
217 size_t len;
218
219 len = sizeof(state);
220 if (sysctlbyname(BATTERY_STATE, &state, &len, NULL, 0) <…
221 return NULL;
222
223 switch (state) {
224 case 0: /* FALLTHROUGH */
225 case 2:
226 return "+";
227 case 1:
228 return "-";
229 default:
230 return "?";
231 }
232 }
233
234 const char *
235 battery_remaining(const char *unused)
236 {
237 int rem;
238 size_t len;
239
240 len = sizeof(rem);
241 if (sysctlbyname(BATTERY_TIME, &rem, &len, NULL, 0) < 0 …
242 || rem < 0)
243 return NULL;
244
245 return bprintf("%uh %02um", rem / 60, rem % 60);
246 }
247 #endif
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.