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