ref: 3b0a35dd198d23c2d83a2426d61c7628ca5b82bf
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;
enum {
Base = 0xf0000,
End = 0xffffd
};
static char *
k2s(Rune r)
{
static char s[4];
switch(r){
case Kack: return "Kack";
case Kalt: return "Kalt";
case Kaltgr: return "Kaltgr";
case Kbreak: return "Kbreak";
case Kbs: return "Kbs";
case Kcaps: return "Kcaps";
case Kctl: return "Kctl";
case Kdel: return "Kdel";
case Kdown: return "Kdown";
case Kend: return "Kend";
case Kenq: return "Kenq";
case Keof: return "Keof";
case Kesc: return "Kesc";
case Ketb: return "Ketb";
case Ketx: return "Ketx";
case Khome: return "Khome";
case Kins: return "Kins";
case Kleft: return "Kleft";
case Kmiddle: return "Kmiddle";
case Kmod4: return "Kmod4";
case Knack: return "Knack";
case Knum: return "Knum";
case Kpgdown: return "Kpgdown";
case Kpgup: return "Kpgup";
case Kprint: return "Kprint";
case Kright: return "Kright";
case Kscroll: return "Kscroll";
case Kscrollonedown: return "Kscrollonedown";
case Kscrolloneup: return "Kscrolloneup";
case Kshift: return "Kshift";
case Ksoh: return "Ksoh";
case Kstx: return "Kstx";
case Kup: return "Kup";
default:
if(r >= (KF|1) && r <= (KF|12)){
sprint(s, "F%d", r-KF);
return s;
}
}
return nil;
}
static void
cleanup(void)
{
int i;
for(i = 0; i <= nk; i++)
fprint(kbmap, "%d\t%d\t%d\n", k[i].e, k[i].c, 0);
}
void
main(int argc, char **argv)
{
char *s, *x, buf[128], buf2[128];
Biobuf *b;
int i, 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);
print("there are %d unmapped keys\n", nk);
kbd = -1;
if((kbmap = open("/dev/kbmap", OWRITE)) < 0 || (kbd = open("/dev/kbd", OREAD)) < 0)
sysfatal("%r");
atexit(cleanup);
for(i = 0; i <= nk; i++)
fprint(kbmap, "%d\t%d\t%d\n", k[i].e, k[i].c, Base+i);
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((x = k2s(r)) != nil)
print("%s\n", x);
else if(r >= Base && r <= End && (i = r-Base) < nk)
print("%d\t%d\t%d\n", k[i].e, k[i].c, r);
else if(r != Runeerror)
print("%C\n", r);
else
print("unknown key: rune 0x%x\n", r);
if(r == Kdel)
goto end;
}
}
break;
case 'K':
s = buf2+1;
while(*s)
s += chartorune(&r, s);
break;
default:
continue;
}
strcpy(buf2, buf);
}
end:
exits(nil);
}