shithub: volume

Download patch

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;
+	}
+}