#define _GNU_SOURCE #include #include #include #include #include #include #include #include int stop = 0; #ifdef BATTERY char *readfile(char *buf, size_t len, const char *fn) { FILE *f; size_t n; f = fopen(fn, "r"); if (!f) { return NULL; } n = fread(buf, 1, len-1, f); if (ferror(f)) { return NULL; } fclose(f); if (n >= len-1 || n < 1) { return NULL; } buf[n] = '\0'; return buf; } int getnum(const char *fn) { char buf[1024]; if (readfile(buf, sizeof(buf), fn)) { return atoi(buf); } return -1; } #ifdef CHARGING int charging(void) { char buf[1024]; if (readfile(buf, sizeof(buf), STATUS)) { return !strcmp(buf, CHARGING); } return 0; } #endif /* CHARGING */ #endif /* BATTERY */ void handler(int sig) { stop = sig; } int main(void) { struct tm *tm; time_t now; #ifdef BATTERY long long curr, max, a=-1, b=-1, i; char name[8 + 9]; /* (p)pp.pp% hh:mm:ss\0 */ char *perc = name; char *clock = name + 8; char sign = '%'; #else char name[9]; /* hh:mm:ss\0 */ char *clock = name; #endif /* BATTERY */ struct sigaction act; Display *disp; int screen; Window root; act.sa_handler = handler; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(SIGHUP, &act, NULL); sigaction(SIGINT, &act, NULL); sigaction(SIGQUIT, &act, NULL); sigaction(SIGTERM, &act, NULL); disp = XOpenDisplay(NULL); #ifdef BATTERY for (i=0; !stop; ++i) { #else while (!stop) { #endif /* BATTERY */ if (!disp) { puts("Cannot open display!"); return 1; } screen = DefaultScreen(disp); root = RootWindow(disp, screen); #ifdef BATTERY if (i % (BAT_REFRESH_SECONDS) == 0) { curr = getnum(ENERGY_NOW) * MUL; max = getnum(ENERGY_FULL); #ifdef CHARGING sign = charging() ? '+' : '%'; #endif /* CHARGING */ if (curr < 0 || max < 1) { a = b = -1; } else { a = curr * 10000 / max; b = a % 100; a /= 100; } } if (a < 0 || b < 0) { snprintf(perc, 8, "NO BAT "); } else if (a < 0 || a > 999999 || b < 0 || b > 99) { snprintf(perc, 8, "INVALID"); } else if (a > 999) { snprintf(perc, 8, "%6lld%c", a, sign); } else { snprintf(perc, 8, "%3lld.%02lld%c", a, b, sign); } perc[7] = ' '; #endif /* BATTERY */ now = time(NULL); tm = localtime(&now); strftime(clock, 9, "%H:%M:%S", tm); XStoreName(disp, root, name); XFlush(disp); sleep(1); } XCloseDisplay(disp); return 0; }