ref: 6ee890563245c79719349fb164f04d5aeb4d2052
dir: /volume.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <event.h> enum { SEC = 1000 }; typedef struct Volume Volume; struct Volume { char dev[32]; int fd; int lvl[2]; int ismixfs; }; Volume vol; Image *knob; Image *back; Image *rim; Point volumept(Point c, int volume, int r) { double rad; rad = (double)(volume*3.0 + 30) * PI/180.0; c.x -= sin(rad) * r; c.y += cos(rad) * r; return c; } void redraw(void) { Point c; char v[5]; /* nnn% */ c = divpt(addpt(screen->r.min, screen->r.max), 2); snprint(v, sizeof(v), "%d%%", vol.lvl[0]); draw(screen, screen->r, back, nil, ZP); string(screen, addpt(c, Pt(0-stringwidth(font, v)/2, -32-font->height)), display->black, ZP, font, v); /* knob stops */ line(screen, volumept(c, 0, 35), volumept(c, 0, 30), 0, 0, 1, display->black, ZP); line(screen, volumept(c, 100, 35), volumept(c, 100, 30), 0, 0, 1, display->black, ZP); /* knob */ ellipse(screen, c, 30, 30, 1, rim, ZP); fillellipse(screen, volumept(c, vol.lvl[0], 20), 3, 3, knob, ZP); /* dev name */ string(screen, addpt(c, Pt(0-stringwidth(font, vol.dev)/2, 32)), display->black, ZP, font, vol.dev); } void update(void) { char buf[256], *s, *e, *f[4]; int n, nf; if((n = pread(vol.fd, buf, sizeof(buf)-1, 0)) <= 0) sysfatal("pread: %r"); buf[n] = 0; s = buf; while((e = strchr(s, '\n')) != nil){ *e++ = 0; nf = tokenize(s, f, nelem(f)); if(nf < 2) break; if(strcmp(f[0], "dev") == 0){ snprint(vol.dev, sizeof(vol.dev), "%s", f[1]); vol.ismixfs = 1; }else if(strcmp(f[0], "mix") == 0 || strcmp(f[0], "master") == 0){ vol.lvl[0] = strtol(f[1], nil, 0); vol.lvl[1] = strtol(f[2], nil, 0); } s = e; } } void eresized(int new) { if(new && getwindow(display, Refnone) < 0) fprint(2, "can't reattach to window"); redraw(); } void usage(void) { fprint(2, "usage: %s\n", argv0); exits("usage"); } void main(int argc, char *argv[]) { Mouse m; Event e; Point p; double rad; int Etimer, ev, d; ARGBEGIN{ default: usage(); }ARGEND; if(argc != 0) usage(); vol.fd = open("/dev/volume", ORDWR); if(vol.fd < 0) sysfatal("open: %r"); update(); if(initdraw(0, 0, "volume") < 0) sysfatal("initdraw: %r"); back = allocimagemix(display, 0x88FF88FF, DWhite); knob = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x008800FF); rim = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x004400FF); einit(Emouse); Etimer = etimer(0, 2*SEC); redraw(); for(;;){ ev = event(&e); if(ev == Emouse){ m = e.mouse; if(!(m.buttons & (1|8|16))) continue; if(m.buttons & 1){ p = subpt(m.xy, divpt(addpt(screen->r.min, screen->r.max), 2)); rad = atan2(-p.x, p.y); d = rad * 180.0/PI; if(d < 0) d += 360; d *= 160.0/360.0; if(d < 30) d = 0; else if(d > 130) d = 100; else d -= 30; vol.lvl[0] = d; } if(m.buttons & 8 && vol.lvl[0] < 100) vol.lvl[0]++; if(m.buttons & 16 && vol.lvl[0] > 0) vol.lvl[0]--; fprint(vol.fd, "%s%d", vol.ismixfs? "mix " : "", vol.lvl[0]); redraw(); }else if(ev == Etimer){ update(); redraw(); } } }