diff options
-rw-r--r-- | battery.c | 166 | ||||
-rw-r--r-- | mkfile | 8 | ||||
-rw-r--r-- | testfile | 2 |
3 files changed, 176 insertions, 0 deletions
diff --git a/battery.c b/battery.c new file mode 100644 index 0000000..f19d1e8 --- /dev/null +++ b/battery.c @@ -0,0 +1,166 @@ +#include <u.h> +#include <libc.h> +#include <ctype.h> +#include <draw.h> +#include <event.h> + +enum +{ + SEC = 1000, /* ms */ + + /* battery discharge levels and charging state */ + JLOW = 0, + JMED, + JHIG, + JCHR, + NBATTLVL, + + /* percentage text colors */ + PDIS = 0, + PCHR, + NPERC, + + /* color palette */ + CBG = 0, + CFG, + CJUICE, + NCOLOR, + + Labspace = 2 /* room around the label */ +}; + +Image *juicecolors[NBATTLVL], *textcolors[NPERC], *palette[NCOLOR]; +int bfd, nbatt, lvl, ischarging; +char lvlstr[5]; + +char battfile[] = "/mnt/acpi/battery"; + +void +juicereflow(double ratio) +{ + Point sp; + + sp = Pt(screen->r.min.x, screen->r.max.y - Dy(screen->r)*ratio); + draw(screen, Rpt(sp, screen->r.max), palette[CJUICE], nil, ZP); +} + +void +label(Point p, char *text) +{ + string(screen, p, palette[CFG], ZP, font, text); +} + +Image * +rgba(ulong c) +{ + Image *i; + + i = allocimage(display, Rect(0,0,1,1), screen->chan, 1, c); + if(i == nil) + sysfatal("allocimage: %r"); + return i; +} + +void +redraw(void) +{ + Point p = Pt(((screen->r.min.x+screen->r.max.x)/2)-((font->width*strlen(lvlstr))/2), + screen->r.max.y-(font->height+Labspace)); + + draw(screen, screen->r, palette[CBG], nil, ZP); + juicereflow(lvl/100.0); + label(p, lvlstr); +} + +void +update(void) +{ + char buf[256], idbuf[16], *s, *p; + int n; + + if((n = pread(bfd, buf, sizeof(buf)-1, 0)) <= 0) + sysfatal("pread: %r"); + buf[n] = 0; + s = buf; + nbatt = 0; + lvl = strtol(s, &s, 0); + do{ + if(isalpha(*s)){ + p = idbuf; + while(isalpha(*s) && p < idbuf + sizeof idbuf - 1) + *p++ = *s++; + *p = 0; + if(strcmp(idbuf, "charging") == 0) + ischarging = 1; + else if(strcmp(idbuf, "discharging") == 0) + ischarging = 0; + } + if(*s == '\n'){ + nbatt++; + if(isdigit(*++s)) + lvl += strtol(s, &s, 0); + } + }while(*s++); + lvl /= nbatt; + if(ischarging){ + palette[CFG] = textcolors[PCHR]; + palette[CJUICE] = juicecolors[JCHR]; + }else{ + palette[CFG] = textcolors[PDIS]; + palette[CJUICE] = lvl < 20 ? juicecolors[JLOW]: + lvl < 60 ? juicecolors[JMED]: + juicecolors[JHIG]; + } + snprint(lvlstr, sizeof lvlstr, "%d%%", lvl); +} + +void +eresized(int new) +{ + if(new && getwindow(display, Refnone) < 0) + fprint(2, "can't reattach to window\n"); + redraw(); +} + +void +usage(void) +{ + fprint(2, "usage: %s\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + Event e; + int Etimer, key; + + ARGBEGIN{ + default: usage(); + }ARGEND; + if(argc != 0) + usage(); + bfd = open(battfile, OREAD); + if(bfd < 0) + sysfatal("open: %r"); + if(initdraw(0, 0, "battery") < 0) + sysfatal("initdraw: %r"); + juicecolors[JLOW] = rgba(DRed); + juicecolors[JMED] = rgba(DDarkyellow); + juicecolors[JHIG] = rgba(DMedgreen); + juicecolors[JCHR] = rgba(0x0088CCFF); + textcolors[PDIS] = display->black; + textcolors[PCHR] = rgba(DYellow); + palette[CBG] = allocimagemix(display, 0x88FF88FF, DWhite); + palette[CFG] = textcolors[PDIS]; + einit(Emouse); + Etimer = etimer(0, 120*SEC); + update(); + redraw(); + for(;;){ + key = event(&e); + if(key == Etimer) + update(); + redraw(); + } +} @@ -0,0 +1,8 @@ +</$objtype/mkfile + +BIN=/$objtype/bin +TARG=battery +OFILES=\ + battery.$O\ + +</sys/src/cmd/mkone diff --git a/testfile b/testfile new file mode 100644 index 0000000..92dafe0 --- /dev/null +++ b/testfile @@ -0,0 +1,2 @@ +5 mW 1090 21550 23200 1077 200 mV 10782 11100 00:00:00 unknown +91 mW 19820 21690 23480 1084 200 mV 12144 11400 02:39:14 discharging |