ref: ccc10edd72c940d731563964683df392fd742bd7
author: Igor Böhm <igor@9lab.org>
date: Sun Oct 10 16:35:39 EDT 2021
Initial import.
--- /dev/null
+++ b/README.md
@@ -1,0 +1,1 @@
+different rio volume controls.
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,7 @@
+</$objtype/mkfile
+
+BIN=$home/bin/$objtype
+TARG=vol
+OFILES=vol.$O
+
+</sys/src/cmd/mkone
--- /dev/null
+++ b/vol.c
@@ -1,0 +1,131 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+
+int vol, muted, headphones;
+Image *bg, *mlevel, *level;
+Rectangle slider;
+
+struct{
+ char *sys;
+ int phones;
+ int speakers;
+} pins[] = {
+ "asquith", 27, 21,
+ "x201", 25, 31,
+ "r400", 22, 26,
+};
+
+char*
+b2menugen(int n)
+{
+ if(n == 0)
+ return muted ? "unmute" : "mute";
+ return nil;
+}
+
+char*
+b3menugen(int n)
+{
+ if(n == 0)
+ return headphones ? "speakers" : "headphones";
+ return nil;
+}
+
+void
+redraw(void)
+{
+ slider.min = screen->r.min;
+ slider.max = screen->r.max;
+ slider.min.y += (100 - vol) * Dy(screen->r) / 100;
+
+ draw(screen, screen->r, bg, nil, ZP);
+ draw(screen, slider, muted ? mlevel : level, nil, ZP);
+ flushimage(display, 1);
+}
+
+void
+eresized(int new)
+{
+ if(new && getwindow(display, Refnone) < 0)
+ fprint(2,"can't reattach to window");
+
+ redraw();
+}
+
+void
+main()
+{
+ char *system;
+ int i, hpin, spin, volfd, pinfd;
+ Mouse m;
+ Event e;
+ Menu b2menu = {nil, b2menugen, 0};
+ Menu b3menu = {nil, b3menugen, 0};
+
+ volfd = open("/dev/volume", OWRITE);
+ if (volfd < 0)
+ sysfatal("open /dev/volume: %r");
+ pinfd = open("/dev/audioctl", OWRITE);
+ if (pinfd < 0)
+ sysfatal("open /dev/audioctl: %r");
+
+ hpin = spin = 0;
+ system = getenv("sysname");
+ for(i = 0; i < (sizeof(pins) / sizeof(pins[0])); i++){
+ if(strcmp(pins[i].sys, system) == 0){
+ hpin = pins[i].phones;
+ spin = pins[i].speakers;
+ break;
+ }
+ }
+
+ if(initdraw(nil, nil, "vol") < 0)
+ sysfatal("initdraw: %r");
+ einit(Emouse);
+
+ bg = allocimagemix(display, DPalebluegreen, DWhite);
+ level = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalegreygreen);
+ mlevel = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xCCCCCCFF);
+ if(bg == nil || level == nil || mlevel == nil)
+ sysfatal ("allocimage");
+
+ vol = 75;
+ muted = headphones = 0;
+ if(hpin && spin)
+ fprint (pinfd, "pin %d\n", spin);
+ fprint (volfd, "%d\n", vol);
+ redraw();
+
+ for(;;){
+ if(event(&e) == Emouse){
+ m = e.mouse;
+ if(m.buttons & 1){
+ vol = (slider.max.y - m.xy.y) * 100 / Dy(screen->r);
+ redraw();
+ if(!muted)
+ fprint (volfd, "%d\n", vol);
+ sleep(50);
+ }
+ if(m.buttons & 2)
+ if(emenuhit(2, &m, &b2menu) == 0){
+ if(muted)
+ fprint (volfd, "%d\n", vol);
+ else
+ fprint (volfd, "0\n");
+ muted ^= 1;
+ redraw();
+ }
+ if(m.buttons & 4)
+ if(emenuhit(3, &m, &b3menu) == 0){
+ headphones ^= 1;
+ if(hpin && spin){
+ muted = 0;
+ fprint (pinfd, "pin %d\n", headphones ? hpin : spin);
+ fprint (volfd, "%d\n", vol);
+ }
+ }
+ }
+ }
+}
--- /dev/null
+++ b/vol.knob.c
@@ -1,0 +1,109 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+
+int volume;
+Image *knob;
+Image *back;
+Image *rim;
+
+Point
+volumept(Point c, int volume, int r) {
+ double rad = (double) (volume*3.0+30) * PI/180.0;
+
+ c.x -= sin(rad) * r;
+ c.y += cos(rad) * r;
+
+ return c;
+}
+
+void
+redraw(Image *screen)
+{
+ Point c = divpt(addpt(screen->r.min, screen->r.max), 2);
+
+ draw(screen, screen->r, back, nil, ZP);
+
+ line(screen, volumept(c, 0, 45), volumept(c, 0, 40), 0, 0, 1, display->black, ZP);
+ line(screen, volumept(c, 100, 45), volumept(c, 100, 40), 0, 0, 1, display->black, ZP);
+ ellipse(screen, c, 40, 40, 1, rim, ZP);
+ fillellipse(screen, volumept(c, volume, 30), 3, 3, knob, ZP);
+
+ flushimage(display, 1);
+}
+
+void
+eresized(int new)
+{
+ if(new && getwindow(display, Refnone) < 0)
+ fprint(2,"can't reattach to window");
+
+ redraw(screen);
+}
+
+void
+main()
+{
+ int key;
+ Mouse m;
+ Event e;
+ int f;
+ char buf[256];
+ char *ptr;
+ Point p;
+ double rad;
+ int d;
+
+ f = open("/dev/volume", ORDWR);
+ if (f < 0)
+ sysfatal ("open volume failed");
+
+ read (f, buf, sizeof(buf));
+ strtok(buf, " ");
+ ptr = strtok(nil, " ");
+ volume = atoi(ptr);
+
+ if (initdraw(0, 0, "volume") < 0)
+ sysfatal ("initdraw failed");
+
+ einit (Emouse);
+
+ 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);
+
+ redraw(screen);
+
+ for (;;) {
+ key = event(&e);
+
+ if(key == Emouse) {
+ m = e.mouse;
+ 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;
+
+ volume = d;
+
+ fprint (f, "%d\n", volume);
+
+ redraw(screen);
+
+ sleep(50);
+ }
+ }
+ }
+}
--- /dev/null
+++ b/vol.simple.c
@@ -1,0 +1,101 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+#include <keyboard.h>
+
+char volstr[] = "volume";
+char mutestr[] = "muted";
+int volume, muted;
+Image *back;
+
+void
+eresized(int new)
+{
+ Rectangle r1, r2;
+
+ if(new && getwindow(display, Refnone) < 0)
+ sysfatal("Cannot get window: %r");
+ r1 = screen->r;
+ r2 = r1;
+ r1.min.y = r1.max.y - ((vlong)Dy(r2) * volume) / 100;
+ r2.max.y = r1.min.y;
+ draw(screen, r1, back, nil, ZP);
+ draw(screen, r2, display->white, nil, ZP);
+ r2.min = ZP;
+ r2.max = stringsize(display->defaultfont, muted ? mutestr : volstr);
+ r1 = rectsubpt(screen->r, screen->r.min);
+ r2 = rectaddpt(r2, subpt(divpt(r1.max, 2), divpt(r2.max, 2)));
+ r2 = rectaddpt(r2, screen->r.min);
+ r1 = insetrect(r2, -4);
+ draw(screen, r1, display->white, nil, ZP);
+ border(screen, insetrect(r1, 1), 2, display->black, ZP);
+ string(screen, r2.min, display->black, ZP, display->defaultfont, muted ? mutestr : volstr);
+ flushimage(display, 1);
+}
+
+void
+mute(int fd)
+{
+ static int oldvol, t;
+
+ fprint(fd, "%d\n", oldvol);
+ t = oldvol;
+ oldvol = volume;
+ volume = t;
+ muted ^= 1;
+}
+
+void
+main()
+{
+ int f;
+ Mouse m;
+ Event e;
+ char buf[256], *toks[2];
+ vlong o;
+
+ f = open("/dev/volume", ORDWR);
+ if(f < 0)
+ sysfatal ("open volume failed");
+ read(f, buf, sizeof(buf));
+ gettokens(buf, toks, 2, " ");
+ volume = atoi(toks[1]);
+ if(initdraw(0, 0, "volume") < 0)
+ sysfatal("initdraw failed: %r");
+ einit(Emouse|Ekeyboard);
+ back = allocimagemix(display, DPalebluegreen, DWhite);
+ eresized(0);
+ for(;;) switch(event(&e)){
+ default:
+ break;
+ case Emouse:
+ if(muted)
+ break;
+ m = e.mouse;
+ if(m.buttons & 1) {
+ o = screen->r.max.y - m.xy.y;
+ if(o < 0) o = 0LL;
+ o *= 100;
+ o /= Dy(screen->r);
+ volume = o;
+ eresized(0);
+ fprint(f, "%d\n", volume);
+ }
+ break;
+ case Ekeyboard:
+ switch(e.kbdc){
+ default:
+ break;
+ case 'm':
+ mute(f);
+ eresized(0);
+ break;
+ case 'q':
+ case Kdel:
+ exits(0);
+ break;
+ }
+ break;
+ }
+}