ref: 09b250f079e38883e8ad5dc47e4aa93258e0c083
parent: e95f557ba57b7102693b169bbe3f93661de8bec7
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Feb 26 21:36:54 EST 2016
kbdfs: read outer /dev/kbd file and use it just like /dev/kbdin this allows running kbdfs under kbdfs :-) going use this in new drawterm. drawterm provides the initial /dev/kbd, but only sends rune up/down messages (keeps it simple). the servers kbdfs reads that and exports itself the full set of files, similar to what we do in vncs. this also provides note processing.
--- a/sys/src/cmd/aux/kbdfs/kbdfs.c
+++ b/sys/src/cmd/aux/kbdfs/kbdfs.c
@@ -89,16 +89,20 @@
char Ephase[] = "the front fell off";
char Eintr[] = "interrupted";
-int scanfd;
-int ledsfd;
-int consfd;
-int mctlfd;
-int msinfd;
-int notefd;
+int kbdifd = -1;
+int scanfd = -1;
+int ledsfd = -1;
+int consfd = -1;
+int mctlfd = -1;
+int msinfd = -1;
+int notefd = -1;
+int killfd = -1;
int kbdopen;
int consctlopen;
int quiet = 0;
+char *sname = nil;
+char *mntpt = "/dev";
int debug;
@@ -260,8 +264,50 @@
[0x78] 0, '', 0, '\b', 0, 0, 0, 0,
};
-void reboot(void);
+char*
+dev(char *file)
+{
+ static char *buf = nil;
+ free(buf);
+ buf = smprint("%s/%s", mntpt, file);
+ return buf;
+}
+int
+eopen(char *name, int mode)
+{
+ int fd;
+
+ fd = open(name, mode);
+ if(fd < 0 && !quiet)
+ fprint(2, "%s: warning: can't open %s: %r\n", argv0, name);
+ return fd;
+}
+
+void
+reboot(void)
+{
+ int fd;
+
+ if(debug)
+ return;
+
+ if((fd = eopen(dev("reboot"), OWRITE)) < 0)
+ return;
+ fprint(fd, "reboot\n");
+ close(fd);
+}
+
+void
+shutdown(void)
+{
+ if(notefd >= 0)
+ write(notefd, "hangup", 6);
+ if(killfd >= 0)
+ write(killfd, "hangup", 6);
+ threadexitsall(nil);
+}
+
/*
* Scan code processing
*/
@@ -347,6 +393,83 @@
scan->esc1 = 0;
}
+static void
+kbdin(Scan *a, char *p, int n)
+{
+ char *s;
+ Key k;
+ int i;
+
+ if(n > 0 && p[n-1] != 0){
+ /*
+ * old format as used by bitsy keyboard:
+ * just a string of characters, no keyup
+ * information.
+ */
+ s = emalloc9p(n+1);
+ memmove(s, p, n);
+ s[n] = 0;
+ p = s;
+ while(*p){
+ p += chartorune(&k.r, p);
+ if(k.r)
+ send(rawchan, &k.r);
+ }
+ free(s);
+ return;
+ } else if(n < 2)
+ return;
+ switch(p[0]){
+ case 'R':
+ case 'r':
+ /* rune up/down */
+ chartorune(&k.r, p+1);
+ if(k.r == 0)
+ break;
+ k.b = k.r;
+ k.down = (p[0] == 'r');
+ /*
+ * handle ^X forms according to keymap and
+ * assign button.
+ */
+ for(i=0; i<Nscan; i++){
+ if((a->shift && kbtabshift[i] == k.r) || (kbtab[i] == k.r)){
+ if(kbtab[i])
+ k.b = kbtab[i];
+ if(a->shift)
+ k.r = kbtabshift[i];
+ else if(a->altgr)
+ k.r = kbtabaltgr[i];
+ else if(a->ctl)
+ k.r = kbtabctl[i];
+ break;
+ }
+ }
+ if(k.b)
+ send(keychan, &k);
+ if(k.r == Kshift)
+ a->shift = k.down;
+ else if(k.r == Kaltgr)
+ a->altgr = k.down;
+ else if(k.r == Kctl)
+ a->ctl = k.down;
+ break;
+
+ case 'c':
+ chartorune(&k.r, p+1);
+ nbsend(runechan, &k.r);
+ break;
+
+ default:
+ if(!kbdopen)
+ break;
+ s = emalloc9p(n);
+ memmove(s, p, n);
+ if(nbsendp(kbdchan, s) <= 0)
+ free(s);
+ }
+}
+
void
setleds(Scan *scan, int leds)
{
@@ -378,8 +501,26 @@
kbdputsc(&scan, buf[i]);
setleds(&scan, (scan.num<<1) | (scan.caps<<2));
}
+
+ shutdown();
}
+void
+kbdiproc(void *)
+{
+ char buf[1024];
+ Scan scan;
+ int n;
+
+ threadsetname("kbdiproc");
+
+ memset(&scan, 0, sizeof scan);
+ while((n = read(kbdifd, buf, sizeof buf)) > 0)
+ kbdin(&scan, buf, n);
+
+ shutdown();
+}
+
char*
utfconv(Rune *r, int n)
{
@@ -492,6 +633,8 @@
memmove(buf, p, n);
p = buf + n;
}
+
+ shutdown();
}
static int
@@ -782,6 +925,8 @@
threadsetname("ctlproc");
+ if(kbdifd >= 0)
+ proccreate(kbdiproc, nil, STACK); /* kbdifd -> kbdin() */
if(scanfd >= 0)
proccreate(scanproc, nil, STACK); /* scanfd -> keychan */
if(consfd >= 0)
@@ -1164,12 +1309,12 @@
fswrite(Req *r)
{
Fid *f;
- Scan *a;
- char *p, *s;
+ char *p;
int n, i;
- Key k;
f = r->fid;
+ p = r->ifcall.data;
+ n = r->ifcall.count;
switch((ulong)f->qid.path){
default:
respond(r, Ephase);
@@ -1176,17 +1321,13 @@
return;
case Qcons:
- n = r->ifcall.count;
- if(write(1, r->ifcall.data, n) != n){
+ if(write(1, p, n) != n){
responderror(r);
return;
}
- r->ofcall.count = n;
break;
case Qconsctl:
- p = r->ifcall.data;
- n = r->ifcall.count;
if(n >= 5 && memcmp(p, "rawon", 5) == 0)
sendul(ctlchan, Rawon);
else if(n >= 6 && memcmp(p, "rawoff", 6) == 0)
@@ -1195,91 +1336,22 @@
respond(r, Ebadarg);
return;
}
- r->ofcall.count = n;
break;
+ case Qkbin:
case Qkbdin:
- p = r->ifcall.data;
- n = r->ifcall.count;
- r->ofcall.count = n;
if(n == 0)
break;
- if(p[n-1] != 0){
- /*
- * old format as used by bitsy keyboard:
- * just a string of characters, no keyup
- * information.
- */
- s = emalloc9p(n+1);
- memmove(s, p, n);
- s[n] = 0;
- p = s;
- while(*p){
- p += chartorune(&k.r, p);
- if(k.r)
- send(rawchan, &k.r);
- }
- free(s);
- break;
- }
- switch(p[0]){
- case 'R':
- case 'r':
- /* rune up/down */
- chartorune(&k.r, p+1);
- if(k.r == 0)
- break;
- k.b = k.r;
- k.down = (p[0] == 'r');
- if(f->aux == nil){
- f->aux = emalloc9p(sizeof(Scan));
- memset(f->aux, 0, sizeof(Scan));
- }
- a = f->aux;
- /*
- * handle ^X forms according to keymap and
- * assign button.
- */
- for(i=0; i<Nscan; i++){
- if((a->shift && kbtabshift[i] == k.r) || (kbtab[i] == k.r)){
- if(kbtab[i])
- k.b = kbtab[i];
- if(a->shift)
- k.r = kbtabshift[i];
- else if(a->altgr)
- k.r = kbtabaltgr[i];
- else if(a->ctl)
- k.r = kbtabctl[i];
- break;
- }
- }
- if(k.b)
- send(keychan, &k);
- if(k.r == Kshift)
- a->shift = k.down;
- else if(k.r == Kaltgr)
- a->altgr = k.down;
- else if(k.r == Kctl)
- a->ctl = k.down;
- break;
- default:
- if(!kbdopen)
- break;
- s = emalloc9p(n);
- memmove(s, p, n);
- if(nbsendp(kbdchan, s) <= 0)
- free(s);
- }
- break;
-
- case Qkbin:
if(f->aux == nil){
f->aux = emalloc9p(sizeof(Scan));
memset(f->aux, 0, sizeof(Scan));
}
- for(i=0; i<r->ifcall.count; i++)
- kbdputsc((Scan*)f->aux, (uchar)r->ifcall.data[i]);
- r->ofcall.count = i;
+ if(f->qid.path == Qkbin){
+ for(i=0; i<n; i++)
+ kbdputsc((Scan*)f->aux, (uchar)p[i]);
+ } else {
+ kbdin((Scan*)f->aux, p, n);
+ }
break;
case Qkbmap:
@@ -1287,6 +1359,7 @@
return;
}
+ r->ofcall.count = n;
respond(r, nil);
}
@@ -1329,50 +1402,7 @@
}
}
-static void
-fsend(Srv*)
-{
- threadexitsall(nil);
-}
-
-Srv fs = {
- .attach= fsattach,
- .walk1= fswalk1,
- .open= fsopen,
- .read= fsread,
- .write= fswrite,
- .stat= fsstat,
- .flush= fsflush,
- .destroyfid= fsdestroyfid,
- .end= fsend,
-};
-
-int
-eopen(char *name, int mode)
-{
- int fd;
-
- fd = open(name, mode);
- if(fd < 0 && !quiet)
- fprint(2, "%s: warning: can't open %s: %r\n", argv0, name);
- return fd;
-}
-
-void
-reboot(void)
-{
- int fd;
-
- if(debug)
- return;
-
- if((fd = eopen("/dev/reboot", OWRITE)) < 0)
- return;
- fprint(fd, "reboot\n");
- close(fd);
-}
-
-int
+static int
procopen(int pid, char *name, int mode)
{
char buf[128];
@@ -1381,7 +1411,7 @@
return eopen(buf, mode);
}
-void
+static void
elevate(void)
{
Dir *d, nd;
@@ -1410,10 +1440,37 @@
close(fd);
}
+static void
+fsstart(Srv*)
+{
+ killfd = procopen(getpid(), "notepg", OWRITE);
+ elevate();
+ proccreate(ctlproc, nil, STACK);
+}
+
+static void
+fsend(Srv*)
+{
+ shutdown();
+}
+
+Srv fs = {
+ .start= fsstart,
+ .attach= fsattach,
+ .walk1= fswalk1,
+ .open= fsopen,
+ .read= fsread,
+ .write= fswrite,
+ .stat= fsstat,
+ .flush= fsflush,
+ .destroyfid= fsdestroyfid,
+ .end= fsend,
+};
+
void
usage(void)
{
- fprint(2, "usage: %s [ -qdD ] [ -s srv ] [ -m mntpnt ] [ file ]\n", argv0);
+ fprint(2, "usage: %s [ -qdD ] [ -s sname ] [ -m mntpnt ] [ file ]\n", argv0);
exits("usage");
}
@@ -1420,11 +1477,6 @@
void
threadmain(int argc, char** argv)
{
- char *mtpt = "/dev";
- char *srv = nil;
-
- consfd = -1;
-
ARGBEGIN{
case 'd':
debug++;
@@ -1433,10 +1485,10 @@
chatty9p++;
break;
case 's':
- srv = EARGF(usage());
+ sname = EARGF(usage());
break;
case 'm':
- mtpt = EARGF(usage());
+ mntpt = EARGF(usage());
break;
case 'q':
quiet++;
@@ -1445,16 +1497,19 @@
usage();
}ARGEND
- notefd = procopen(getpid(), "notepg", OWRITE);
-
- scanfd = eopen("/dev/scancode", OREAD);
- ledsfd = eopen("/dev/leds", OWRITE);
- mctlfd = eopen("/dev/mousectl", OWRITE);
- msinfd = eopen("/dev/mousein", OWRITE);
-
if(*argv)
consfd = eopen(*argv, OREAD);
+ kbdifd = open(dev("kbd"), OREAD);
+ if(kbdifd < 0){
+ scanfd = eopen(dev("scancode"), OREAD);
+ ledsfd = eopen(dev("leds"), OWRITE);
+ mctlfd = eopen(dev("mousectl"), OWRITE);
+ msinfd = eopen(dev("mousein"), OWRITE);
+ }
+
+ notefd = procopen(getpid(), "notepg", OWRITE);
+
consreqchan = chancreate(sizeof(Req*), 0);
kbdreqchan = chancreate(sizeof(Req*), 0);
@@ -1466,8 +1521,6 @@
kbdchan = chancreate(sizeof(char*), 16);
intchan = chancreate(sizeof(int), 0);
- elevate();
- procrfork(ctlproc, nil, STACK, RFNAMEG|RFNOTEG);
- threadpostmountsrv(&fs, srv, mtpt, MBEFORE);
+ threadpostmountsrv(&fs, sname, mntpt, MBEFORE);
threadexits(0);
}