code: plan9front

Download patch

ref: cc861074b49c3c5410f335c7e3668c542c2c46fb
parent: 6ee1e4bd7898b96abb5c655bc9335df96fafa19f
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Aug 24 09:45:51 EDT 2022

reform: add reform/shortcuts

--- a/sys/man/1/reform
+++ b/sys/man/1/reform
@@ -1,7 +1,8 @@
 .TH REFORM 1
 .SH NAME
 audio,
-pm
+pm,
+shortcuts
 - MNT Reform 2 support utilities
 .SH SYNOPSIS
 .B reform/audio
@@ -32,9 +33,20 @@
 .B -s
 .I service
 ]
+.PP
+.B reform/shortcuts
+[
+.B -l
+.I light_step
+]
+[
+.B -v
+.I vol_step
+]
 .SH DESCRIPTION
 These programs provide support for certain functions of MNT Reform 2
-computing device and make controlling file systems available under
+computing device.  Some of them also make controlling file systems
+available under
 .BR /dev .
 .PP
 .SS Audio
@@ -103,6 +115,27 @@
 .TP
 .B cputemp
 Exposes the current temperature reading of the CPU.
+.SS Shortcuts
+.I shortcuts
+enables LCD brightness and audio volume adjustment via keyboard shortcuts.
+.PP
+The program uses Rio's
+.I kbdtap
+to function:
+.IP
+.EX
+reform/shortcuts </dev/kbdtap >/dev/kbdtap
+.EE
+.PP
+.I Super+F1/F2
+decreases/increases LCD brightness,
+.I Super+F3/F4
+decreases/increases "master" volume.
+Optionally, a single step amount can be set with
+.I -l
+for LCD light level (default is 5) and
+.I -v
+for volume (default is 3).
 .SH SOURCE
 .B /sys/src/cmd/reform
 .SH SEE ALSO
--- a/sys/src/cmd/reform/mkfile
+++ b/sys/src/cmd/reform/mkfile
@@ -4,6 +4,7 @@
 TARG=\
 	audio\
 	pm\
+	shortcuts\
 
 </sys/src/cmd/mkmany
 
--- /dev/null
+++ b/sys/src/cmd/reform/shortcuts.c
@@ -1,0 +1,105 @@
+#include <u.h>
+#include <libc.h>
+#include <keyboard.h>
+
+static int lightstep = 5, volstep = 3;
+static int light, vol, mod;
+
+static void
+process(char *s)
+{
+	char b[128], *p;
+	int n, o;
+	Rune r;
+
+	if(*s == 'K' && s[1] == 0)
+		mod = 0;
+
+	o = 0;
+	b[o++] = *s;
+	for(p = s+1; *p != 0; p += n){
+		if((n = chartorune(&r, p)) == 1 && r == Runeerror){
+			/* bail out */
+			n = strlen(p);
+			memmove(b+o, p, n);
+			o += n;
+			p += n;
+			break;
+		}
+
+		if(*s == 'k' && r == Kmod4){
+			mod = 1;
+		}else if(*s == 'K'){
+			if(mod && r >= (KF|1) && r <= (KF|4))
+				continue;
+			if(r == Kmod4)
+				mod = 0;
+		}else if(mod && r >= (KF|1) && r <= (KF|4)){
+			if(*s == 'c'){
+				if(r == (KF|1))
+					fprint(light, "lcd -%d", lightstep);
+				else if(r == (KF|2))
+					fprint(light, "lcd +%d", lightstep);
+				else if(r == (KF|3))
+					fprint(vol, "master -%d", volstep);
+				else if(r == (KF|4))
+					fprint(vol, "master +%d", volstep);
+			}
+			continue;
+			}
+
+		memmove(b+o, p, n);
+		o += n;
+	}
+
+	/* all runes filtered out - ignore completely */
+	if(o == 1 && p-s > 1)
+		return;
+
+	b[o++] = 0;
+	if(write(1, b, o) != o)
+		exits(nil);
+}
+
+static void
+usage(void)
+{
+	fprint(2, "usage: [-l light_step] [-v vol_step] %s\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	char b[128];
+	int i, j, n;
+
+	ARGBEGIN{
+	case 'l':
+		lightstep = atoi(EARGF(usage()));
+		break;
+	case 'v':
+		volstep = atoi(EARGF(usage()));
+		break;
+	default:
+		usage();
+	}ARGEND
+
+	light = open("/dev/light", OWRITE);
+	vol = open("/dev/volume", OWRITE);
+	for(i = 0;;){
+		if((n = read(0, b+i, sizeof(b)-i)) <= 0)
+			break;
+		n += i;
+		for(j = 0; j < n; j++){
+			if(b[j] == 0){
+				process(b+i);
+				i = j+1;
+			}
+		}
+		memmove(b, b+i, j-i);
+		i -= j;
+	}
+
+	exits(nil);
+}