shithub: evdump

ref: 3b0a35dd198d23c2d83a2426d61c7628ca5b82bf
dir: /kbfind.c/

View raw version
#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);
}