shithub: evdump

Download patch

ref: 92425f089e4966c8ed400041ef3a80098d746956
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Wed Sep 2 09:06:00 EDT 2020

first

--- /dev/null
+++ b/.gitignore
@@ -1,0 +1,2 @@
+[a0125678vqki].out
+*.[o0125678vqki]
--- /dev/null
+++ b/README.md
@@ -1,0 +1,28 @@
+# aux/kbfind
+
+Finds the correct `/dev/kbmap` entry for a non-working key on your
+keyboard, in 9front.
+
+## Process
+
+1) after installing (`mk install`) run `aux/kbfind`.
+2) press the non-working key _once_
+3) press any other _working_ key _once_ (or Delete to exit)
+4) go to step 2
+
+If the key was not mapped before and is producing scancodes,
+eventually the program will print out the needed entry that needs to
+be put into `/dev/kbmap` for the key to work.  Replace the last `0` of
+that entry to whichever Rune you want your key to produce, converted
+to a number, see `/sys/include/keyboard.h` for some of the existing
+"special" keys.
+
+## How does this work
+
+Unmapped entries in `/dev/kbmap` have the Rune (third number) set to
+0.  `aux/kbfind` sets those entries to a custom Rune and awaits for
+key presses to be available on `/dev/kbd`.  If the custom Rune was
+found the entries currently enabled are cut into half to see whether
+the key would still produce the rune.  If not, the other half is
+enabled instead and the process is repeated, cutting the number of
+keys to test in half every time.
--- /dev/null
+++ b/kbfind.c
@@ -1,0 +1,159 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <keyboard.h>
+
+typedef struct {
+	int e;
+	int c;
+	int r;
+}K;
+
+static K k[1280];
+static int nk, kbmap, kbd;
+static int k0, ke;
+static int ak0, ake;
+static int nohits, left;
+
+enum {
+	Kunmapped = 0xf789,
+};
+
+static void
+mapto(Rune r)
+{
+	int i;
+
+	/* disable the range */
+	for(i = k0; i <= ke; i++)
+		fprint(kbmap, "%d\t%d\t%d\n", k[i].e, k[i].c, r);
+}
+
+static void
+revert(void)
+{
+	mapto(0);
+}
+
+static void
+hit(int unmapped)
+{
+	char kbup[32];
+
+	/* disable mapping */
+	mapto(0);
+
+	if(unmapped){
+		nohits = 0;
+		/* got a hit */
+		if(k0 == ke){
+			/* only one left */
+			print("%d\t%d\t0\n", k[k0].e, k[k0].c);
+			/* skip key up so there isn't garbage printed out */
+			read(kbd, kbup, sizeof(kbup));
+			exits(nil);
+		}
+		/* reduce */
+		ake = ke;
+		ke = k0 + (ke-k0)/2;
+		ak0 = ke+1;
+	}else if(++nohits > 1){
+		nohits = 0;
+		if(k0 == ak0 && ke == ake){
+			/* give up */
+			fprint(2, "key doesn't work\n");
+			exits(nil);
+		}
+		/* try a different half */
+		k0 = ak0;
+		ke = ake;
+	}
+	if(left != ke-k0+1){
+		left = ke-k0+1;
+		fprint(2, "%d possible left\n", left);
+	}
+
+	/* enable the new range */
+	mapto(Kunmapped);
+}
+
+void
+main(int argc, char **argv)
+{
+	Biobuf *b;
+	char *s, buf[128], buf2[128];
+	int n;
+	Rune r;
+
+	USED(argc); USED(argv);
+
+	if((b = Bopen("/dev/kbmap", OREAD)) == nil)
+		sysfatal("%r");
+	for(nk = 0; nk < nelem(k);){
+		if((s = Brdline(b, '\n')) == nil)
+			break;
+		k[nk].e = strtol(s, &s, 10);
+		k[nk].c = strtol(s, &s, 10);
+		k[nk].r = strtol(s, &s, 10);
+		if(k[nk].r == 0)
+			nk++;
+	}
+	if(nk < 1)
+		sysfatal("no keys to map");
+	Bterm(b);
+	fprint(2, "there are %d unmapped keys\n", nk);
+	ke = nk-1;
+
+	kbd = -1;
+	if((kbmap = open("/dev/kbmap", OWRITE)) < 0 || (kbd = open("/dev/kbd", OREAD)) < 0)
+		sysfatal("%r");
+	mapto(Kunmapped);
+
+	buf2[0] = 0;
+	buf2[1] = 0;
+	buf[0] = 0;
+	for(;;){
+		if(buf[0] != 0){
+			n = strlen(buf)+1;
+			memmove(buf, buf+n, sizeof(buf)-n);
+		}
+		if(buf[0] == 0){
+			n = read(kbd, buf, sizeof(buf)-1);
+			if(n <= 0)
+				break;
+			buf[n-1] = 0;
+		}
+
+		switch(buf[0]){
+		case 'k':
+			s = buf+1;
+			while(*s){
+				s += chartorune(&r, s);
+				if(utfrune(buf2+1, r) == nil){
+					if(r == Kdel)
+						goto end;
+					if(r == Kshift || r == Kalt || r == Kctl){
+						fprint(2, "please don't press shift/alt/ctl\n");
+						continue;
+					}
+					hit(r == Kunmapped);
+				}
+			}
+			break;
+
+		case 'K':
+			s = buf2+1;
+			while(*s)
+				s += chartorune(&r, s);
+			break;
+
+		default:
+			continue;
+		}
+
+		strcpy(buf2, buf);
+	}
+
+end:
+	exits(nil);
+}
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,6 @@
+</$objtype/mkfile
+BIN=/$objtype/bin/aux
+TARG=kbfind
+OFILES=kbfind.$O
+default:V: all
+</sys/src/cmd/mkone