ref: f34cd2fe2f884b250bf0c4396cfe4186b34b2bf9
dir: /bar.c/
#include "theme.c"
#include "nanosec.c"
#include <keyboard.h>
#include <mouse.h>
#define MAX(a,b) ((a)>=(b)?(a):(b))
#define MIN(a,b) ((a)<=(b)?(a):(b))
#define CLAMP(x,min,max) MAX(min, MIN(max, x))
enum {
Off = 4,
};
static Font *f;
static struct {
int w, h;
}scr;
static char *wday[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
static char *pos = "rb";
static int wctl, width, bottom, bat;
static void
place(void)
{
static int ow, oh;
char t[61], *a[5];
int f, n, w, h, minx, miny, maxx, maxy;
if((f = open("/dev/screen", OREAD)) < 0)
return;
n = read(f, t, sizeof(t)-1);
close(f);
t[sizeof(t)-1] = 0;
if(n != sizeof(t)-1 || tokenize(t, a, 5) != 5)
return;
w = atoi(a[3]);
h = atoi(a[4]);
if(ow != w || oh != h){
if(pos[0] == 't' || pos[1] == 't'){
miny = 0;
maxy = 48;
}else{
miny = h-48;
maxy = h;
}
if(pos[0] == 'l' || pos[1] == 'l'){
minx = 0;
maxx = Borderwidth+width+Borderwidth;
}else{
minx = w-Borderwidth-width-Borderwidth;
maxx = w;
}
fprint(wctl, "resize -r %d %d %d %d", minx, miny, maxx, maxy);
ow = w;
oh = h;
}
}
static void
redraw(void)
{
Tm *tm;
char bats[16], s[128], *t;
Point p;
Rectangle r;
lockdisplay(display);
r = screen->r;
draw(screen, r, colors[Dback].im, nil, ZP);
if(bat < 0 || pread(bat, bats, 4, 0) < 4)
bats[0] = 0;
else{
t = strchr(bats, ' ');
strcpy(t, "% | ");
}
tm = localtime(time(nil));
snprint(
s, sizeof(s),
"%s%04d/%02d/%02d %s %02d:%02d:%02d",
bats,
tm->year+1900, tm->mon+1, tm->mday,
wday[tm->wday],
tm->hour, tm->min, tm->sec
);
width = Off + stringwidth(f, s) + Off;
p.x = r.max.x - width + Off;
p.y = (pos[0] == 't' || pos[1] == 't') ? r.max.y - (f->height + Off) : r.min.y + Off;
string(screen, p, colors[Dfhigh].im, ZP, f, s);
flushimage(display, 1);
unlockdisplay(display);
place();
}
static void
updateproc(void *)
{
uvlong t, n;
t = nanosec();
for(;;){
sleep(250);
if(wctl < 0)
break;
fprint(wctl, bottom ? "bottom" : "top");
if((n = nanosec()) - t >= 1000000000ULL){
redraw();
t = n;
}
}
threadexits(nil);
}
void
themechanged(void)
{
redraw();
}
static void
usage(void)
{
fprint(2, "usage: %s [-b] [-p lt|rt|lb|rb]\n", argv0);
threadexitsall("usage");
}
void
threadmain(int argc, char **argv)
{
Keyboardctl *kctl;
Mousectl *mctl;
Rune key;
Mouse m;
Alt a[] =
{
{ nil, &m, CHANRCV },
{ nil, nil, CHANRCV },
{ nil, &key, CHANRCV },
{ nil, nil, CHANEND },
};
ARGBEGIN{
case 'p':
pos = EARGF(usage());
break;
case 'b':
bottom = 1;
break;
default:
usage();
}ARGEND
if((wctl = open("/dev/wctl", ORDWR)) < 0)
sysfatal("%r");
bat = open("/mnt/acpi/battery", OREAD);
if(initdraw(nil, nil, "bar") < 0)
sysfatal("initdraw: %r");
f = display->defaultfont;
unlockdisplay(display);
if((mctl = initmouse(nil, screen)) == nil)
sysfatal("initmouse: %r");
if((kctl = initkeyboard(nil)) == nil)
sysfatal("initkeyboard: %r");
a[0].c = mctl->c;
a[1].c = mctl->resizec;
a[2].c = kctl->c;
nanosec();
themeinit();
redraw();
proccreate(updateproc, nil, 4096);
for(;;){
redraw();
switch(alt(a)){
case 0:
break;
case 1:
if(getwindow(display, Refnone) < 0)
sysfatal("getwindow: %r");
break;
case 2:
if(key == Kdel){
close(wctl);
wctl = -1;
threadexitsall(nil);
}
break;
}
}
}