History

first

Sigrid Haflínudóttir committed 6 years ago

Commit 92425f0No parent (first commit)4 files · +195 −0Browse files

Unified · Split

4 files
  1. .gitignore +2 −0
  2. README.md +28 −0
  3. kbfind.c +159 −0
  4. mkfile +6 −0
.gitignore+2−0
@@ -0,0 +1,2 @@
1+[a0125678vqki].out
2+*.[o0125678vqki]
README.md+28−0
@@ -0,0 +1,28 @@
1+# aux/kbfind
2+
3+Finds the correct `/dev/kbmap` entry for a non-working key on your
4+keyboard, in 9front.
5+
6+## Process
7+
8+1) after installing (`mk install`) run `aux/kbfind`.
9+2) press the non-working key _once_
10+3) press any other _working_ key _once_ (or Delete to exit)
11+4) go to step 2
12+
13+If the key was not mapped before and is producing scancodes,
14+eventually the program will print out the needed entry that needs to
15+be put into `/dev/kbmap` for the key to work. Replace the last `0` of
16+that entry to whichever Rune you want your key to produce, converted
17+to a number, see `/sys/include/keyboard.h` for some of the existing
18+"special" keys.
19+
20+## How does this work
21+
22+Unmapped entries in `/dev/kbmap` have the Rune (third number) set to
23+0. `aux/kbfind` sets those entries to a custom Rune and awaits for
24+key presses to be available on `/dev/kbd`. If the custom Rune was
25+found the entries currently enabled are cut into half to see whether
26+the key would still produce the rune. If not, the other half is
27+enabled instead and the process is repeated, cutting the number of
28+keys to test in half every time.
kbfind.c+159−0
@@ -0,0 +1,159 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <bio.h>
4+#include <keyboard.h>
5+
6+typedef struct {
7+ int e;
8+ int c;
9+ int r;
10+}K;
11+
12+static K k[1280];
13+static int nk, kbmap, kbd;
14+static int k0, ke;
15+static int ak0, ake;
16+static int nohits, left;
17+
18+enum {
19+ Kunmapped = 0xf789,
20+};
21+
22+static void
23+mapto(Rune r)
24+{
25+ int i;
26+
27+ /* disable the range */
28+ for(i = k0; i <= ke; i++)
29+ fprint(kbmap, "%d\t%d\t%d\n", k[i].e, k[i].c, r);
30+}
31+
32+static void
33+revert(void)
34+{
35+ mapto(0);
36+}
37+
38+static void
39+hit(int unmapped)
40+{
41+ char kbup[32];
42+
43+ /* disable mapping */
44+ mapto(0);
45+
46+ if(unmapped){
47+ nohits = 0;
48+ /* got a hit */
49+ if(k0 == ke){
50+ /* only one left */
51+ print("%d\t%d\t0\n", k[k0].e, k[k0].c);
52+ /* skip key up so there isn't garbage printed out */
53+ read(kbd, kbup, sizeof(kbup));
54+ exits(nil);
55+ }
56+ /* reduce */
57+ ake = ke;
58+ ke = k0 + (ke-k0)/2;
59+ ak0 = ke+1;
60+ }else if(++nohits > 1){
61+ nohits = 0;
62+ if(k0 == ak0 && ke == ake){
63+ /* give up */
64+ fprint(2, "key doesn't work\n");
65+ exits(nil);
66+ }
67+ /* try a different half */
68+ k0 = ak0;
69+ ke = ake;
70+ }
71+ if(left != ke-k0+1){
72+ left = ke-k0+1;
73+ fprint(2, "%d possible left\n", left);
74+ }
75+
76+ /* enable the new range */
77+ mapto(Kunmapped);
78+}
79+
80+void
81+main(int argc, char **argv)
82+{
83+ Biobuf *b;
84+ char *s, buf[128], buf2[128];
85+ int n;
86+ Rune r;
87+
88+ USED(argc); USED(argv);
89+
90+ if((b = Bopen("/dev/kbmap", OREAD)) == nil)
91+ sysfatal("%r");
92+ for(nk = 0; nk < nelem(k);){
93+ if((s = Brdline(b, '\n')) == nil)
94+ break;
95+ k[nk].e = strtol(s, &s, 10);
96+ k[nk].c = strtol(s, &s, 10);
97+ k[nk].r = strtol(s, &s, 10);
98+ if(k[nk].r == 0)
99+ nk++;
100+ }
101+ if(nk < 1)
102+ sysfatal("no keys to map");
103+ Bterm(b);
104+ fprint(2, "there are %d unmapped keys\n", nk);
105+ ke = nk-1;
106+
107+ kbd = -1;
108+ if((kbmap = open("/dev/kbmap", OWRITE)) < 0 || (kbd = open("/dev/kbd", OREAD)) < 0)
109+ sysfatal("%r");
110+ mapto(Kunmapped);
111+
112+ buf2[0] = 0;
113+ buf2[1] = 0;
114+ buf[0] = 0;
115+ for(;;){
116+ if(buf[0] != 0){
117+ n = strlen(buf)+1;
118+ memmove(buf, buf+n, sizeof(buf)-n);
119+ }
120+ if(buf[0] == 0){
121+ n = read(kbd, buf, sizeof(buf)-1);
122+ if(n <= 0)
123+ break;
124+ buf[n-1] = 0;
125+ }
126+
127+ switch(buf[0]){
128+ case 'k':
129+ s = buf+1;
130+ while(*s){
131+ s += chartorune(&r, s);
132+ if(utfrune(buf2+1, r) == nil){
133+ if(r == Kdel)
134+ goto end;
135+ if(r == Kshift || r == Kalt || r == Kctl){
136+ fprint(2, "please don't press shift/alt/ctl\n");
137+ continue;
138+ }
139+ hit(r == Kunmapped);
140+ }
141+ }
142+ break;
143+
144+ case 'K':
145+ s = buf2+1;
146+ while(*s)
147+ s += chartorune(&r, s);
148+ break;
149+
150+ default:
151+ continue;
152+ }
153+
154+ strcpy(buf2, buf);
155+ }
156+
157+end:
158+ exits(nil);
159+}
mkfile+6−0
@@ -0,0 +1,6 @@
1+</$objtype/mkfile
2+BIN=/$objtype/bin/aux
3+TARG=kbfind
4+OFILES=kbfind.$O
5+default:V: all
6+</sys/src/cmd/mkone

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t