ref: 92425f089e4966c8ed400041ef3a80098d746956
dir: /kbfind.c/
#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); }