Sigrid Solveig Haflínudóttirevdump: fix the fixc9bca613 years agoHistory
337 lines · 6.3 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <ctype.h>#include <bio.h>#include <draw.h>#include <keyboard.h>#include <mouse.h>#include <thread.h> typedef struct {	u8int e;	u8int c;	Rune r;}K; enum {	Kmbase = 0xf0000,}; static K k[10*128];static int nk;static int kbd;static Biobuf *kbmap, *wctl;static char *layertab[] = {	"none", "shift", "esc", "altgr",	"ctl", "ctlesc", "shiftesc", "shiftaltgr",	"mod4", "altgrmod4",}; static char *k2s(Rune r){	switch(r){	case Ksbwd: return "Ksbwd";	case Ksfwd: return "Ksfwd";	case Kpause: return "Kpause";	case Kvoldn: return "Kvoldn";	case Kvolup: return "Kvolup";	case Kmute: return "Kmute";	case Kbrtdn: return "Kbrtdn";	case Kbrtup: return "Kbrtup";	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";	case KF|1: return "F1";	case KF|2: return "F2";	case KF|3: return "F3";	case KF|4: return "F4";	case KF|5: return "F5";	case KF|6: return "F6";	case KF|7: return "F7";	case KF|8: return "F8";	case KF|9: return "F9";	case KF|10: return "F10";	case KF|11: return "F11";	case KF|12: return "F12";	case Kmouse|1: return "Kmouse1";	case Kmouse|2: return "Kmouse2";	case Kmouse|3: return "Kmouse3";	case Kmouse|4: return "Kmouse4";	case Kmouse|5: return "Kmouse5";	case '\n': return "\\n";	} 	return nil;} static intkmreset(void *, char *){	int i; 	for(i = 0; i < nk; i++)		Bprint(kbmap, "%d\t%d\t%d\n", k[i].e, k[i].c, k[i].r);	Bflush(kbmap); 	return 0;} static voidkmset(void){	int i; 	for(i = 0; i < nk; i++)		Bprint(kbmap, "%d\t%d\t%d\n", k[i].e, k[i].c, Kmbase+i);	Bflush(kbmap);} static voidkey(Rune r, char *type){	char *s, t[32];	Rune c;	K q; 	if(r < Kmbase || r >= Kmbase+nk){		if((s = k2s(r)) != nil)			snprint(t, sizeof(t), "%s", s);		else if((r < 0x80 && isprint(r)) || r >= 0x20)			snprint(t, sizeof(t), "%C (0x%x)", r, r);		else			snprint(t, sizeof(t), "0x%x", r);		return;	}	q = k[r-Kmbase];	c = q.r;	if((s = k2s(c)) != nil)		snprint(t, sizeof(t), "%s", s);	else if((c < 0x80 && isprint(c)) || c >= 0x20)		snprint(t, sizeof(t), "%C (0x%x)", c, c);	else		snprint(t, sizeof(t), "0x%x", c); 	print("key %s %s: %d %d 0x%ux\n", type, t, q.e, q.c, q.r);} static voidwctlproc(void *){	char s[256], *t[8];	int wctl, n; 	if((wctl = open("/dev/wctl", OREAD)) < 0)		sysfatal("%r");	for(;;){		if((n = read(wctl, s, sizeof(s)-1)) <= 0)			break;		s[n] = 0;		if(tokenize(s, t, nelem(t)) < 6)			continue; 		if(strcmp(t[4], "current") == 0)			kmset();		else if(strcmp(t[4], "notcurrent") == 0)			kmreset(nil, nil); 		print("wctl %s %s\n", t[4], t[5]);	}	close(wctl); 	threadexits(nil);} static voidkbproc(void *){	char *s, buf[128], buf2[128];	int kbd, n;	Rune r; 	threadsetname("kbproc");	if((kbd = open("/dev/kbd", OREAD)) < 0)		sysfatal("/dev/kbd: %r"); 	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;			buf[n] = 0;		} 		switch(buf[0]){		case 'k':			for(s = buf+1; *s;){				s += chartorune(&r, s);				if(utfrune(buf2+1, r) == nil)					key(r, "down");			}			break;		case 'K':			for(s = buf2+1; *s;){				s += chartorune(&r, s);				if(utfrune(buf+1, r) == nil)					key(r, "up");			}			break;		case 'c':			if(chartorune(&r, buf+1) > 0 && r != Runeerror)				key(r, "repeat");		default:			continue;		} 		strcpy(buf2, buf);	} 	close(kbd); 	threadexits(nil);} static voidusage(void){	fprint(2, "usage: %s\n", argv0);	threadexitsall("usage");} voidthreadmain(int argc, char **argv){	Mousectl *mctl;	char tmp[32], *f[4], *s;	int nf, e;	Mouse m;	enum { Cmouse, Cresize, Numchan };	Alt a[Numchan+1] = {		[Cmouse] = { nil, &m, CHANRCV },		[Cresize] = { nil, nil, CHANRCV },		{ nil, nil, CHANEND },	}; 	ARGBEGIN{	default:		usage();	}ARGEND 	if(argc != 0)		usage(); 	if((kbmap = Bopen("/dev/kbmap", OREAD)) == nil)		sysfatal("%r"); 	nk = 0;	for(;;){		if((s = Brdline(kbmap, '\n')) == nil)			break;		s[Blinelen(kbmap)-1] = '\0';		nf = getfields(s, f, nelem(f), 1, " \t");		if(nf < 3)			continue;		for(e = 0; e < nelem(layertab); e++)			if(strcmp(f[0], layertab[e]) == 0)				break;		if(e >= nelem(layertab)){			e = strtoul(f[0], &s, 0);			if(*s != '\0')				continue;		}		k[nk].e = e;		k[nk].c = strtoul(f[1], &s, 0);		if(*s != '\0')			continue;		k[nk].r = strtoul(f[2], &s, 0);		if(*s != '\0')			continue;		if(++nk >= nelem(k))			break;	}	Bterm(kbmap); 	if((kbmap = Bopen("/dev/kbmap", OWRITE)) == nil)		sysfatal("%r");	threadnotify(kmreset, 1); 	snprint(tmp, sizeof(tmp), "-pid %d -dx %d -dy %d", getpid(), 256, 256);	newwindow(tmp); 	if(initdraw(nil, nil, "evdump") < 0)		sysfatal("initdraw: %r");	if((mctl = initmouse(nil, screen)) == nil)		sysfatal("initmouse: %r");	a[Cmouse].c = mctl->c;	a[Cresize].c = mctl->resizec; 	proccreate(kbproc, nil, mainstacksize);	proccreate(wctlproc, nil, mainstacksize); 	for(;;){		draw(screen, screen->r, display->black, nil, ZP); 		switch(alt(a)){		case -1:			goto end; 		case Cmouse:			print(				"mouse buttons 0x%x x %d y %d\n",				m.buttons,				m.xy.x, m.xy.y			);			break; 		case Cresize:			getwindow(display, Refnone);			print(				"resize min %d %d max %d %d\n",				screen->r.min.x, screen->r.min.y,				screen->r.max.x, screen->r.max.y			);			break;		}	} end:	threadexitsall(nil);}