#include #include #include #include #include #include #include #include #include #include #define BATTERY "BAT1" #define BATT_INFO_PATH "/proc/acpi/battery/"BATTERY"/info" #define BATT_STATE_PATH "/proc/acpi/battery/"BATTERY"/state" #define BATT_FULL_REGEX "^last full capacity:[ ]+([0-9]*) .*$" #define BATT_CUR_REGEX "^remaining capacity:[ ]+([0-9]*) .*$" #define DATE_FORMAT "%H:%M (%Z) - %a %d.%m.%Y" #define BUFFER_SIZE 4096 #define STATUS_SIZE 256 static char *buf; static regex_t *batt_full_re, *batt_cur_re; static Display *dpy; static Window root; static XTextProperty name; void update_status(char *c) { name.value=(unsigned char*)c; name.nitems=strlen(c); XSetWMName(dpy, root, &name); XSync(dpy, False); } void cleanup(void) { regfree(batt_full_re); regfree(batt_cur_re); free(buf); } void die(int unused) { update_status("dwmrc died!"); exit(EXIT_FAILURE); } int read_batt(const char *batt_path, const regex_t *batt_re) { FILE *f; int batt_total = -1; regmatch_t result_re[2]; f = fopen(batt_path, "r"); fread(buf, 1, BUFFER_SIZE, f); regexec(batt_re, buf, 2, result_re, 0); if(result_re[1].rm_so != -1 && result_re[1].rm_eo != -1) { buf[result_re[1].rm_eo]='\0'; batt_total = atoi(buf+result_re[1].rm_so); } fclose(f); return batt_total; } int main(int argc, char **argv) { time_t cur_t; struct tm *cur_lt; char *status; int batt_full, batt_cur; int n; if( !(dpy = XOpenDisplay(NULL)) || !(buf = calloc(1, sizeof(char)*BUFFER_SIZE)) || !(status = calloc(1, sizeof(char)*STATUS_SIZE)) || !(batt_full_re = calloc(1, sizeof(regex_t))) || !(batt_cur_re = calloc(1, sizeof(regex_t))) ) die(0); regcomp(batt_full_re, BATT_FULL_REGEX, REG_EXTENDED|REG_NEWLINE); regcomp(batt_cur_re, BATT_CUR_REGEX, REG_EXTENDED|REG_NEWLINE); root = RootWindow(dpy, DefaultScreen(dpy)); name.encoding=XA_STRING; name.format=8; signal(SIGINT, die); signal(SIGILL, die); signal(SIGTERM, die); while(1) { batt_full=read_batt(BATT_INFO_PATH, batt_full_re); batt_cur =read_batt(BATT_STATE_PATH, batt_cur_re); if(batt_full > 0 && batt_cur >= 0) n=snprintf(status, STATUS_SIZE, "%3d%% -- ", (100*batt_cur/batt_full)); else n=snprintf(status, STATUS_SIZE, " NAN -- "); cur_t = time(NULL); cur_lt = localtime(&cur_t); strftime(&status[n], STATUS_SIZE-n, DATE_FORMAT, cur_lt); update_status(status); sleep(10); } return EXIT_SUCCESS; }