dwmstatus.c - dwmstatus - A simple dwm status application in C.
HTML git clone git://git.suckless.org/dwmstatus
DIR Log
DIR Files
DIR Refs
DIR LICENSE
---
dwmstatus.c (4380B)
---
1 /*
2 * Copy me if you can.
3 * by 20h
4 */
5
6 #define _BSD_SOURCE
7 #include <unistd.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <stdarg.h>
11 #include <string.h>
12 #include <strings.h>
13 #include <sys/time.h>
14 #include <time.h>
15 #include <sys/types.h>
16 #include <sys/wait.h>
17
18 #include <X11/Xlib.h>
19
20 char *tzargentina = "America/Buenos_Aires";
21 char *tzutc = "UTC";
22 char *tzberlin = "Europe/Berlin";
23
24 static Display *dpy;
25
26 char *
27 smprintf(char *fmt, ...)
28 {
29 va_list fmtargs;
30 char *ret;
31 int len;
32
33 va_start(fmtargs, fmt);
34 len = vsnprintf(NULL, 0, fmt, fmtargs);
35 va_end(fmtargs);
36
37 ret = malloc(++len);
38 if (ret == NULL) {
39 perror("malloc");
40 exit(1);
41 }
42
43 va_start(fmtargs, fmt);
44 vsnprintf(ret, len, fmt, fmtargs);
45 va_end(fmtargs);
46
47 return ret;
48 }
49
50 void
51 settz(char *tzname)
52 {
53 setenv("TZ", tzname, 1);
54 }
55
56 char *
57 mktimes(char *fmt, char *tzname)
58 {
59 char buf[129];
60 time_t tim;
61 struct tm *timtm;
62
63 settz(tzname);
64 tim = time(NULL);
65 timtm = localtime(&tim);
66 if (timtm == NULL)
67 return smprintf("");
68
69 if (!strftime(buf, sizeof(buf)-1, fmt, timtm)) {
70 fprintf(stderr, "strftime == 0\n");
71 return smprintf("");
72 }
73
74 return smprintf("%s", buf);
75 }
76
77 void
78 setstatus(char *str)
79 {
80 XStoreName(dpy, DefaultRootWindow(dpy), str);
81 XSync(dpy, False);
82 }
83
84 char *
85 loadavg(void)
86 {
87 double avgs[3];
88
89 if (getloadavg(avgs, 3) < 0)
90 return smprintf("");
91
92 return smprintf("%.2f %.2f %.2f", avgs[0], avgs[1], avgs[2]);
93 }
94
95 char *
96 readfile(char *base, char *file)
97 {
98 char *path, line[513];
99 FILE *fd;
100
101 memset(line, 0, sizeof(line));
102
103 path = smprintf("%s/%s", base, file);
104 fd = fopen(path, "r");
105 free(path);
106 if (fd == NULL)
107 return NULL;
108
109 if (fgets(line, sizeof(line)-1, fd) == NULL) {
110 fclose(fd);
111 return NULL;
112 }
113 fclose(fd);
114
115 return smprintf("%s", line);
116 }
117
118 char *
119 getbattery(char *base)
120 {
121 char *co, status;
122 int descap, remcap;
123
124 descap = -1;
125 remcap = -1;
126
127 co = readfile(base, "present");
128 if (co == NULL)
129 return smprintf("");
130 if (co[0] != '1') {
131 free(co);
132 return smprintf("not present");
133 }
134 free(co);
135
136 co = readfile(base, "charge_full_design");
137 if (co == NULL) {
138 co = readfile(base, "energy_full_design");
139 if (co == NULL)
140 return smprintf("");
141 }
142 sscanf(co, "%d", &descap);
143 free(co);
144
145 co = readfile(base, "charge_now");
146 if (co == NULL) {
147 co = readfile(base, "energy_now");
148 if (co == NULL)
149 return smprintf("");
150 }
151 sscanf(co, "%d", &remcap);
152 free(co);
153
154 co = readfile(base, "status");
155 if (!strncmp(co, "Discharging", 11)) {
156 status = '-';
157 } else if(!strncmp(co, "Charging", 8)) {
158 status = '+';
159 } else {
160 status = '?';
161 }
162
163 if (remcap < 0 || descap < 0)
164 return smprintf("invalid");
165
166 return smprintf("%.0f%%%c", ((float)remcap / (float)descap) * 100, status);
167 }
168
169 char *
170 gettemperature(char *base, char *sensor)
171 {
172 char *co;
173
174 co = readfile(base, sensor);
175 if (co == NULL)
176 return smprintf("");
177 return smprintf("%02.0f°C", atof(co) / 1000);
178 }
179
180 char *
181 execscript(char *cmd)
182 {
183 FILE *fp;
184 char retval[1025], *rv;
185
186 memset(retval, 0, sizeof(retval));
187
188 fp = popen(cmd, "r");
189 if (fp == NULL)
190 return smprintf("");
191
192 rv = fgets(retval, sizeof(retval), fp);
193 pclose(fp);
194 if (rv == NULL)
195 return smprintf("");
196 retval[strlen(retval)-1] = '\0';
197
198 return smprintf("%s", retval);
199 }
200
201 int
202 main(void)
203 {
204 char *status;
205 char *avgs;
206 char *bat;
207 char *tmar;
208 char *tmutc;
209 char *tmbln;
210 char *t0;
211 char *t1;
212 char *kbmap;
213 char *surfs;
214 char *memes;
215
216 if (!(dpy = XOpenDisplay(NULL))) {
217 fprintf(stderr, "dwmstatus: cannot open display.\n");
218 return 1;
219 }
220
221 for (;;sleep(30)) {
222 avgs = loadavg();
223 bat = getbattery("/sys/class/power_supply/BAT0");
224 tmar = mktimes("%H:%M", tzargentina);
225 tmutc = mktimes("%H:%M", tzutc);
226 tmbln = mktimes("KW %W %a %d %b %H:%M %Z %Y", tzberlin);
227 kbmap = execscript("setxkbmap -query | grep layout | cut -d':' -f 2- | tr -d ' '");
228 surfs = execscript("surf-status");
229 memes = execscript("meme-status");
230 t0 = gettemperature("/sys/devices/virtual/thermal/thermal_zone0", "temp");
231 t1 = gettemperature("/sys/devices/virtual/thermal/thermal_zone1", "temp");
232
233 status = smprintf("S:%s M:%s K:%s T:%s|%s L:%s B:%s A:%s U:%s %s",
234 surfs, memes, kbmap, t0, t1, avgs, bat, tmar, tmutc,
235 tmbln);
236 setstatus(status);
237
238 free(surfs);
239 free(memes);
240 free(kbmap);
241 free(t0);
242 free(t1);
243 free(avgs);
244 free(bat);
245 free(tmar);
246 free(tmutc);
247 free(tmbln);
248 free(status);
249 }
250
251 XCloseDisplay(dpy);
252
253 return 0;
254 }
255