dwmstatus

A simple dwm status application in C.
git clone git://git.suckless.org/dwmstatus
Log | Files | Refs | 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