Created
June 6, 2017 16:09
-
-
Save syntactician/a88bf008e9255b8943296094d65568ef to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #define _BSD_SOURCE | |
| #include <unistd.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <stdarg.h> | |
| #include <string.h> | |
| #include <strings.h> | |
| #include <sys/time.h> | |
| #include <time.h> | |
| #include <sys/types.h> | |
| #include <sys/wait.h> | |
| #include <X11/Xlib.h> | |
| #define BASE "/sys/class/power_supply/BAT0" | |
| static Display *dpy; | |
| char * | |
| smprintf(char *fmt, ...) | |
| { | |
| va_list fmtargs; | |
| char *ret; | |
| int len; | |
| va_start(fmtargs, fmt); | |
| len = vsnprintf(NULL, 0, fmt, fmtargs); | |
| va_end(fmtargs); | |
| ret = malloc(++len); | |
| if (ret == NULL) { | |
| perror("malloc"); | |
| exit(1); | |
| } | |
| va_start(fmtargs, fmt); | |
| vsnprintf(ret, len, fmt, fmtargs); | |
| va_end(fmtargs); | |
| return ret; | |
| } | |
| char * | |
| readfile(const char *base, const char *file) | |
| { | |
| char *path, line[513]; | |
| FILE *fd; | |
| memset(line, 0, sizeof(line)); | |
| path = smprintf("%s/%s", base, file); | |
| fd = fopen(path, "r"); | |
| if (fd == NULL) | |
| return NULL; | |
| free(path); | |
| if (fgets(line, sizeof(line)-1, fd) == NULL) | |
| return NULL; | |
| fclose(fd); | |
| return smprintf("%s", line); | |
| } | |
| char | |
| statussymbol(const char *base) | |
| { | |
| char *co; | |
| co = readfile(base, "status"); | |
| if (co == NULL) | |
| return 'f'; | |
| else if (!strncmp(co, "Discharging", 11)) | |
| return '-'; | |
| else if (!strncmp(co, "Charging", 8)) | |
| return '+'; | |
| else if (!strncmp(co, "Full", 4)) | |
| return '='; | |
| else | |
| return '!'; | |
| free(co); | |
| } | |
| /* | |
| * Linux seems to change the filenames after suspend/hibernate | |
| * according to a random scheme. So just check for both possibilities. | |
| */ | |
| char * | |
| getbattery(const char *base) | |
| { | |
| char *co; | |
| int descap, remcap; | |
| descap = -1; | |
| remcap = -1; | |
| co = readfile(base, "present"); | |
| if (co == NULL || co[0] != '1') { | |
| if (co != NULL) free(co); | |
| return smprintf("not present"); | |
| } | |
| free(co); | |
| co = readfile(base, "charge_full"); | |
| if (co == NULL) { | |
| co = readfile(base, "energy_full"); | |
| if (co == NULL) | |
| return smprintf(""); | |
| } | |
| sscanf(co, "%d", &descap); | |
| free(co); | |
| co = readfile(base, "charge_now"); | |
| if (co == NULL) { | |
| co = readfile(base, "energy_now"); | |
| if (co == NULL) | |
| return smprintf(""); | |
| } | |
| sscanf(co, "%d", &remcap); | |
| free(co); | |
| if (remcap < 0 || descap < 0) | |
| return smprintf("invalid"); | |
| return smprintf("%.0f%c", | |
| ((float)remcap / (float)descap) * 100, | |
| statussymbol(base)); | |
| } | |
| char * | |
| mktimes(char *fmt) | |
| { | |
| char buf[129]; | |
| time_t tim; | |
| struct tm *timtm; | |
| memset(buf, 0, sizeof(buf)); | |
| tim = time(NULL); | |
| timtm = localtime(&tim); | |
| if (timtm == NULL) { | |
| perror("localtime"); | |
| exit(1); | |
| } | |
| if (!strftime(buf, sizeof(buf)-1, fmt, timtm)) { | |
| fprintf(stderr, "strftime == 0\n"); | |
| exit(1); | |
| } | |
| return smprintf("%s", buf); | |
| } | |
| void | |
| setstatus(char *str) | |
| { | |
| XStoreName(dpy, DefaultRootWindow(dpy), str); | |
| XSync(dpy, False); | |
| } | |
| int | |
| main(void) | |
| { | |
| char *batt; | |
| char *stat; | |
| char *time; | |
| if (!(dpy = XOpenDisplay(NULL))) { | |
| fprintf(stderr, "dwmstatus: cannot open display.\n"); | |
| return 1; | |
| } | |
| for (;;sleep(90)) { | |
| batt = getbattery(BASE); | |
| time = mktimes("%a %d %b %H:%M"); | |
| stat = smprintf("%s %s", time, batt); | |
| setstatus(stat); | |
| free(batt); | |
| free(stat); | |
| free(time); | |
| } | |
| XCloseDisplay(dpy); | |
| return 0; | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment