dwmstatus

A simple dwm status application in C.
git clone git://git.suckless.org/dwmstatus
Log | Files | Refs | LICENSE

dwmstatus.c (3923B)


      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 		return NULL;
    111 	fclose(fd);
    112 
    113 	return smprintf("%s", line);
    114 }
    115 
    116 char *
    117 getbattery(char *base)
    118 {
    119 	char *co, status;
    120 	int descap, remcap;
    121 
    122 	descap = -1;
    123 	remcap = -1;
    124 
    125 	co = readfile(base, "present");
    126 	if (co == NULL)
    127 		return smprintf("");
    128 	if (co[0] != '1') {
    129 		free(co);
    130 		return smprintf("not present");
    131 	}
    132 	free(co);
    133 
    134 	co = readfile(base, "charge_full_design");
    135 	if (co == NULL) {
    136 		co = readfile(base, "energy_full_design");
    137 		if (co == NULL)
    138 			return smprintf("");
    139 	}
    140 	sscanf(co, "%d", &descap);
    141 	free(co);
    142 
    143 	co = readfile(base, "charge_now");
    144 	if (co == NULL) {
    145 		co = readfile(base, "energy_now");
    146 		if (co == NULL)
    147 			return smprintf("");
    148 	}
    149 	sscanf(co, "%d", &remcap);
    150 	free(co);
    151 
    152 	co = readfile(base, "status");
    153 	if (!strncmp(co, "Discharging", 11)) {
    154 		status = '-';
    155 	} else if(!strncmp(co, "Charging", 8)) {
    156 		status = '+';
    157 	} else {
    158 		status = '?';
    159 	}
    160 
    161 	if (remcap < 0 || descap < 0)
    162 		return smprintf("invalid");
    163 
    164 	return smprintf("%.0f%%%c", ((float)remcap / (float)descap) * 100, status);
    165 }
    166 
    167 char *
    168 gettemperature(char *base, char *sensor)
    169 {
    170 	char *co;
    171 
    172 	co = readfile(base, sensor);
    173 	if (co == NULL)
    174 		return smprintf("");
    175 	return smprintf("%02.0f°C", atof(co) / 1000);
    176 }
    177 
    178 int
    179 main(void)
    180 {
    181 	char *status;
    182 	char *avgs;
    183 	char *bat;
    184 	char *bat1;
    185 	char *tmar;
    186 	char *tmutc;
    187 	char *tmbln;
    188 	char *t0, *t1, *t2;
    189 
    190 	if (!(dpy = XOpenDisplay(NULL))) {
    191 		fprintf(stderr, "dwmstatus: cannot open display.\n");
    192 		return 1;
    193 	}
    194 
    195 	for (;;sleep(60)) {
    196 		avgs = loadavg();
    197 		bat = getbattery("/sys/class/power_supply/BAT0");
    198 		bat1 = getbattery("/sys/class/power_supply/BAT1");
    199 		tmar = mktimes("%H:%M", tzargentina);
    200 		tmutc = mktimes("%H:%M", tzutc);
    201 		tmbln = mktimes("KW %W %a %d %b %H:%M %Z %Y", tzberlin);
    202 		t0 = gettemperature("/sys/devices/virtual/hwmon/hwmon0", "temp1_input");
    203 		t1 = gettemperature("/sys/devices/virtual/hwmon/hwmon2", "temp1_input");
    204 		t2 = gettemperature("/sys/devices/virtual/hwmon/hwmon4", "temp1_input");
    205 
    206 		status = smprintf("T:%s|%s|%s L:%s B:%s|%s A:%s U:%s %s",
    207 				t0, t1, t2, avgs, bat, bat1, tmar, tmutc,
    208 				tmbln);
    209 		setstatus(status);
    210 
    211 		free(t0);
    212 		free(t1);
    213 		free(t2);
    214 		free(avgs);
    215 		free(bat);
    216 		free(bat1);
    217 		free(tmar);
    218 		free(tmutc);
    219 		free(tmbln);
    220 		free(status);
    221 	}
    222 
    223 	XCloseDisplay(dpy);
    224 
    225 	return 0;
    226 }
    227