vncs: /dev/kbd support by running kbdfs and forwarding keycodes thru kbdin
This commit is contained in:
parent
f2b6ec3140
commit
ce6b942ff1
10 changed files with 190 additions and 603 deletions
|
@ -20,6 +20,7 @@ kbdfs \- keyboard and console filesystem
|
||||||
.B /dev/cons
|
.B /dev/cons
|
||||||
.B /dev/consctl
|
.B /dev/consctl
|
||||||
.B /dev/kbd
|
.B /dev/kbd
|
||||||
|
.B /dev/kbdin
|
||||||
.B /dev/kbin
|
.B /dev/kbin
|
||||||
.B /dev/kbmap
|
.B /dev/kbmap
|
||||||
.fi
|
.fi
|
||||||
|
@ -34,6 +35,8 @@ translates raw keyboard scancodes from
|
||||||
.IR kbd (3))
|
.IR kbd (3))
|
||||||
and its
|
and its
|
||||||
.BR kbin
|
.BR kbin
|
||||||
|
and
|
||||||
|
.BR kbdin
|
||||||
file and optionaly reads console input from
|
file and optionaly reads console input from
|
||||||
.I consfile
|
.I consfile
|
||||||
to provide initial keyboard and console input.
|
to provide initial keyboard and console input.
|
||||||
|
@ -42,6 +45,7 @@ It serves a one-level directory containing the files
|
||||||
.BR cons,
|
.BR cons,
|
||||||
.BR consctl,
|
.BR consctl,
|
||||||
.BR kbd,
|
.BR kbd,
|
||||||
|
.BR kbdin,
|
||||||
.BR kbin
|
.BR kbin
|
||||||
and
|
and
|
||||||
.BR kbmap.
|
.BR kbmap.
|
||||||
|
@ -171,17 +175,9 @@ message is send when a key is pressed down
|
||||||
and
|
and
|
||||||
.B K
|
.B K
|
||||||
when a key is released. The following string contains all the keycodes
|
when a key is released. The following string contains all the keycodes
|
||||||
of the keys that are currently pressed down in decomposed form.
|
of the keys that are currently pressed down in unshifted form.
|
||||||
This includes all keys that have a keyboard mapping and modifier keys.
|
This includes all keys that have a keyboard mapping and modifier keys.
|
||||||
Some keys may produce multiple characters like
|
The string following the
|
||||||
.B Shift
|
|
||||||
and
|
|
||||||
.B a
|
|
||||||
will produce
|
|
||||||
.B Shift,
|
|
||||||
.B a,
|
|
||||||
.B A
|
|
||||||
in the string. The string following the
|
|
||||||
.B c
|
.B c
|
||||||
message contains the single character that would have been returned
|
message contains the single character that would have been returned
|
||||||
on the
|
on the
|
||||||
|
@ -198,6 +194,25 @@ file disables input processing on the
|
||||||
.BR cons
|
.BR cons
|
||||||
file until it is closed again.
|
file until it is closed again.
|
||||||
.PP
|
.PP
|
||||||
|
.B K,
|
||||||
|
.B k
|
||||||
|
and
|
||||||
|
.B c
|
||||||
|
messages can be written to
|
||||||
|
.BR kbdin
|
||||||
|
and will forwarded to the reader of
|
||||||
|
.BR cons
|
||||||
|
or
|
||||||
|
.BR kbd.
|
||||||
|
Writing a
|
||||||
|
.B r
|
||||||
|
or
|
||||||
|
.B R
|
||||||
|
message followed by a
|
||||||
|
.SM UTF
|
||||||
|
encoded rune will simulate the press or
|
||||||
|
release of that particular rune.
|
||||||
|
.PP
|
||||||
Raw scancodes can be written to the
|
Raw scancodes can be written to the
|
||||||
.BR kbin
|
.BR kbin
|
||||||
file for external keyboard input (used for USB keyboards).
|
file for external keyboard input (used for USB keyboards).
|
||||||
|
@ -241,6 +256,6 @@ to represent a control character.
|
||||||
.IR utf (6),
|
.IR utf (6),
|
||||||
.IR kbd (3)
|
.IR kbd (3)
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.B /dev/lib/kbmap/*
|
.B /sys/lib/kbmap/*
|
||||||
.SH SOURCE
|
.SH SOURCE
|
||||||
.B /sys/src/cmd/aux/kbdfs
|
.B /sys/src/cmd/aux/kbdfs
|
||||||
|
|
|
@ -11,6 +11,7 @@ enum {
|
||||||
|
|
||||||
Qroot= 0,
|
Qroot= 0,
|
||||||
Qkbd,
|
Qkbd,
|
||||||
|
Qkbdin,
|
||||||
Qkbin,
|
Qkbin,
|
||||||
Qkbmap,
|
Qkbmap,
|
||||||
Qcons,
|
Qcons,
|
||||||
|
@ -58,6 +59,10 @@ struct Qtab {
|
||||||
0600,
|
0600,
|
||||||
0,
|
0,
|
||||||
|
|
||||||
|
"kbdin",
|
||||||
|
0200,
|
||||||
|
0,
|
||||||
|
|
||||||
"kbin",
|
"kbin",
|
||||||
0200,
|
0200,
|
||||||
0,
|
0,
|
||||||
|
@ -353,8 +358,7 @@ utfconv(Rune *r, int n)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read key events from keychan and produce characters to
|
* Read key events from keychan and produce characters to
|
||||||
* rawchan and keystate in kbdchan. this way here is only
|
* rawchan and keystate in kbdchan.
|
||||||
* one global keystate even if multiple keyboards are used.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
keyproc(void *)
|
keyproc(void *)
|
||||||
|
@ -369,9 +373,6 @@ keyproc(void *)
|
||||||
|
|
||||||
nb = 0;
|
nb = 0;
|
||||||
while(recv(keychan, &key) > 0){
|
while(recv(keychan, &key) > 0){
|
||||||
if(key.down && key.r)
|
|
||||||
send(rawchan, &key.r);
|
|
||||||
|
|
||||||
rb[0] = 0;
|
rb[0] = 0;
|
||||||
for(i=0; i<nb && cb[i] != key.c; i++)
|
for(i=0; i<nb && cb[i] != key.c; i++)
|
||||||
;
|
;
|
||||||
|
@ -386,14 +387,14 @@ keyproc(void *)
|
||||||
cb[nb] = key.c;
|
cb[nb] = key.c;
|
||||||
rb[nb+1] = key.b;
|
rb[nb+1] = key.b;
|
||||||
nb++;
|
nb++;
|
||||||
if(nb < nelem(cb) && key.r && key.b != key.r){
|
|
||||||
cb[nb] = key.c;
|
|
||||||
rb[nb+1] = key.r;
|
|
||||||
nb++;
|
|
||||||
}
|
|
||||||
rb[0] = 'k';
|
rb[0] = 'k';
|
||||||
}
|
}
|
||||||
if(rb[0]){
|
if(rb[0]){
|
||||||
|
if(kbdopen){
|
||||||
|
s = utfconv(rb, nb+1);
|
||||||
|
if(nbsendp(kbdchan, s) <= 0)
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
if(mctlfd >= 0){
|
if(mctlfd >= 0){
|
||||||
if(key.r == Kshift){
|
if(key.r == Kshift){
|
||||||
if(key.down){
|
if(key.down){
|
||||||
|
@ -405,12 +406,9 @@ keyproc(void *)
|
||||||
}
|
}
|
||||||
fprint(mctlfd, "twitch");
|
fprint(mctlfd, "twitch");
|
||||||
}
|
}
|
||||||
if(kbdopen){
|
|
||||||
s = utfconv(rb, nb+1);
|
|
||||||
if(nbsendp(kbdchan, s) <= 0)
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if(key.down && key.r)
|
||||||
|
send(rawchan, &key.r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1084,8 +1082,10 @@ static void
|
||||||
fswrite(Req *r)
|
fswrite(Req *r)
|
||||||
{
|
{
|
||||||
Fid *f;
|
Fid *f;
|
||||||
char *p;
|
Scan *a;
|
||||||
|
char *p, *s;
|
||||||
int n, i;
|
int n, i;
|
||||||
|
Key k;
|
||||||
|
|
||||||
f = r->fid;
|
f = r->fid;
|
||||||
switch((ulong)f->qid.path){
|
switch((ulong)f->qid.path){
|
||||||
|
@ -1116,6 +1116,80 @@ fswrite(Req *r)
|
||||||
r->ofcall.count = n;
|
r->ofcall.count = n;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Qkbdin:
|
||||||
|
p = r->ifcall.data;
|
||||||
|
n = r->ifcall.count;
|
||||||
|
if(n <= 0)
|
||||||
|
n = 0;
|
||||||
|
r->ofcall.count = n;
|
||||||
|
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.c = 0x100 + k.r; /* fake */
|
||||||
|
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,
|
||||||
|
* assign base and scancode if any
|
||||||
|
*/
|
||||||
|
for(i=0; i<Nscan; i++){
|
||||||
|
if((a->shift && kbtabshift[i] == k.r) || (kbtab[i] == k.r)){
|
||||||
|
k.c = 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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:
|
case Qkbin:
|
||||||
if(f->aux == nil){
|
if(f->aux == nil){
|
||||||
f->aux = emalloc9p(sizeof(Scan));
|
f->aux = emalloc9p(sizeof(Scan));
|
||||||
|
@ -1155,6 +1229,7 @@ fsdestroyfid(Fid *f)
|
||||||
|
|
||||||
if(f->omode != -1)
|
if(f->omode != -1)
|
||||||
switch((ulong)f->qid.path){
|
switch((ulong)f->qid.path){
|
||||||
|
case Qkbdin:
|
||||||
case Qkbin:
|
case Qkbin:
|
||||||
case Qkbmap:
|
case Qkbmap:
|
||||||
if(p = f->aux){
|
if(p = f->aux){
|
||||||
|
|
|
@ -4,180 +4,10 @@
|
||||||
#include "kbd.h"
|
#include "kbd.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|
||||||
typedef struct Queue Queue;
|
|
||||||
struct Queue
|
|
||||||
{
|
|
||||||
QLock qwait;
|
|
||||||
Rendez rwait;
|
|
||||||
|
|
||||||
Lock lock;
|
|
||||||
int notempty;
|
|
||||||
char buf[1024];
|
|
||||||
char *w;
|
|
||||||
char *r;
|
|
||||||
char *e;
|
|
||||||
};
|
|
||||||
|
|
||||||
Queue* kbdq; /* unprocessed console input */
|
|
||||||
Queue* lineq; /* processed console input */
|
|
||||||
Snarf snarf = {
|
Snarf snarf = {
|
||||||
.vers = 1
|
.vers = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct
|
|
||||||
{
|
|
||||||
QLock;
|
|
||||||
int raw; /* true if we shouldn't process input */
|
|
||||||
int ctl; /* number of opens to the control file */
|
|
||||||
int x; /* index into line */
|
|
||||||
char line[1024]; /* current input line */
|
|
||||||
} kbd;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cheapo fixed-length queues
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
qwrite(Queue *q, void *v, int n)
|
|
||||||
{
|
|
||||||
char *buf, *next;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
buf = v;
|
|
||||||
lock(&q->lock);
|
|
||||||
for(i = 0; i < n; i++){
|
|
||||||
next = q->w+1;
|
|
||||||
if(next >= q->e)
|
|
||||||
next = q->buf;
|
|
||||||
if(next == q->r)
|
|
||||||
break;
|
|
||||||
*q->w = buf[i];
|
|
||||||
q->w = next;
|
|
||||||
}
|
|
||||||
q->notempty = 1;
|
|
||||||
unlock(&q->lock);
|
|
||||||
rendwakeup(&q->rwait);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
qcanread(void *vq)
|
|
||||||
{
|
|
||||||
Queue *q;
|
|
||||||
int ne;
|
|
||||||
|
|
||||||
q = vq;
|
|
||||||
lock(&q->lock);
|
|
||||||
ne = q->notempty;
|
|
||||||
unlock(&q->lock);
|
|
||||||
return ne;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
qread(Queue *q, void *v, int n)
|
|
||||||
{
|
|
||||||
char *a;
|
|
||||||
int nn, notempty;
|
|
||||||
|
|
||||||
if(n == 0)
|
|
||||||
return 0;
|
|
||||||
a = v;
|
|
||||||
nn = 0;
|
|
||||||
for(;;){
|
|
||||||
lock(&q->lock);
|
|
||||||
|
|
||||||
while(nn < n && q->r != q->w){
|
|
||||||
a[nn++] = *q->r++;
|
|
||||||
if(q->r >= q->e)
|
|
||||||
q->r = q->buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
notempty = q->notempty;
|
|
||||||
q->notempty = q->r != q->w;
|
|
||||||
unlock(&q->lock);
|
|
||||||
if(notempty)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* wait for something to show up in the kbd buffer.
|
|
||||||
*/
|
|
||||||
qlock(&q->qwait);
|
|
||||||
if(waserror()){
|
|
||||||
qunlock(&q->qwait);
|
|
||||||
nexterror();
|
|
||||||
}
|
|
||||||
rendsleep(&q->rwait, qcanread, q);
|
|
||||||
qunlock(&q->qwait);
|
|
||||||
poperror();
|
|
||||||
}
|
|
||||||
return nn;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Queue *
|
|
||||||
mkqueue(void)
|
|
||||||
{
|
|
||||||
Queue *q;
|
|
||||||
|
|
||||||
q = smalloc(sizeof(Queue));
|
|
||||||
q->r = q->buf;
|
|
||||||
q->w = q->r;
|
|
||||||
q->e = &q->buf[sizeof q->buf];
|
|
||||||
q->notempty = 0;
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
echoscreen(char *buf, int n)
|
|
||||||
{
|
|
||||||
char *e, *p;
|
|
||||||
char ebuf[128];
|
|
||||||
int x;
|
|
||||||
|
|
||||||
p = ebuf;
|
|
||||||
e = ebuf + sizeof(ebuf) - 4;
|
|
||||||
while(n-- > 0){
|
|
||||||
if(p >= e){
|
|
||||||
screenputs(ebuf, p - ebuf);
|
|
||||||
p = ebuf;
|
|
||||||
}
|
|
||||||
x = *buf++;
|
|
||||||
if(x == 0x15){
|
|
||||||
*p++ = '^';
|
|
||||||
*p++ = 'U';
|
|
||||||
*p++ = '\n';
|
|
||||||
} else
|
|
||||||
*p++ = x;
|
|
||||||
}
|
|
||||||
if(p != ebuf)
|
|
||||||
screenputs(ebuf, p - ebuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Put character, possibly a rune, into read queue at interrupt time.
|
|
||||||
* Called at interrupt time to process a character.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
kbdputc(int ch)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
char buf[3];
|
|
||||||
Rune r;
|
|
||||||
|
|
||||||
r = ch;
|
|
||||||
n = runetochar(buf, &r);
|
|
||||||
qwrite(kbdq, buf, n);
|
|
||||||
if(!kbd.raw)
|
|
||||||
echoscreen(buf, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
kbdputcinit(void)
|
|
||||||
{
|
|
||||||
kbdq = mkqueue();
|
|
||||||
lineq = mkqueue();
|
|
||||||
kbd.raw = 0;
|
|
||||||
kbd.ctl = 0;
|
|
||||||
kbd.x = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum{
|
enum{
|
||||||
Qdir,
|
Qdir,
|
||||||
Qcons,
|
Qcons,
|
||||||
|
@ -194,12 +24,6 @@ static Dirtab consdir[]={
|
||||||
"winname", {Qwinname}, 0, 0000,
|
"winname", {Qwinname}, 0, 0000,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
|
||||||
consinit(void)
|
|
||||||
{
|
|
||||||
kbdputcinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
static Chan*
|
static Chan*
|
||||||
consattach(char *spec)
|
consattach(char *spec)
|
||||||
{
|
{
|
||||||
|
@ -225,9 +49,6 @@ consopen(Chan *c, int omode)
|
||||||
c = devopen(c, omode, consdir, nelem(consdir), devgen);
|
c = devopen(c, omode, consdir, nelem(consdir), devgen);
|
||||||
switch((ulong)c->qid.path){
|
switch((ulong)c->qid.path){
|
||||||
case Qconsctl:
|
case Qconsctl:
|
||||||
qlock(&kbd);
|
|
||||||
kbd.ctl++;
|
|
||||||
qunlock(&kbd);
|
|
||||||
break;
|
break;
|
||||||
case Qsnarf:
|
case Qsnarf:
|
||||||
if((c->mode&3) == OWRITE || (c->mode&3) == ORDWR)
|
if((c->mode&3) == OWRITE || (c->mode&3) == ORDWR)
|
||||||
|
@ -266,12 +87,6 @@ consclose(Chan *c)
|
||||||
switch((ulong)c->qid.path){
|
switch((ulong)c->qid.path){
|
||||||
/* last close of control file turns off raw */
|
/* last close of control file turns off raw */
|
||||||
case Qconsctl:
|
case Qconsctl:
|
||||||
if(c->flag&COPEN){
|
|
||||||
qlock(&kbd);
|
|
||||||
if(--kbd.ctl == 0)
|
|
||||||
kbd.raw = 0;
|
|
||||||
qunlock(&kbd);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
/* odd behavior but really ok: replace snarf buffer when /dev/snarf is closed */
|
/* odd behavior but really ok: replace snarf buffer when /dev/snarf is closed */
|
||||||
case Qsnarf:
|
case Qsnarf:
|
||||||
|
@ -289,9 +104,6 @@ consclose(Chan *c)
|
||||||
static long
|
static long
|
||||||
consread(Chan *c, void *buf, long n, vlong off)
|
consread(Chan *c, void *buf, long n, vlong off)
|
||||||
{
|
{
|
||||||
char ch;
|
|
||||||
int send;
|
|
||||||
|
|
||||||
if(n <= 0)
|
if(n <= 0)
|
||||||
return n;
|
return n;
|
||||||
switch((ulong)c->qid.path){
|
switch((ulong)c->qid.path){
|
||||||
|
@ -310,48 +122,8 @@ consread(Chan *c, void *buf, long n, vlong off)
|
||||||
return devdirread(c, buf, n, consdir, nelem(consdir), devgen);
|
return devdirread(c, buf, n, consdir, nelem(consdir), devgen);
|
||||||
|
|
||||||
case Qcons:
|
case Qcons:
|
||||||
qlock(&kbd);
|
error(Egreg);
|
||||||
if(waserror()){
|
return -1;
|
||||||
qunlock(&kbd);
|
|
||||||
nexterror();
|
|
||||||
}
|
|
||||||
while(!qcanread(lineq)){
|
|
||||||
qread(kbdq, &ch, 1);
|
|
||||||
send = 0;
|
|
||||||
if(ch == 0){
|
|
||||||
/* flush output on rawoff -> rawon */
|
|
||||||
if(kbd.x > 0)
|
|
||||||
send = !qcanread(kbdq);
|
|
||||||
}else if(kbd.raw){
|
|
||||||
kbd.line[kbd.x++] = ch;
|
|
||||||
send = !qcanread(kbdq);
|
|
||||||
}else{
|
|
||||||
switch(ch){
|
|
||||||
case '\b':
|
|
||||||
if(kbd.x > 0)
|
|
||||||
kbd.x--;
|
|
||||||
break;
|
|
||||||
case 0x15: /* ^U */
|
|
||||||
kbd.x = 0;
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
case 0x04: /* ^D */
|
|
||||||
send = 1;
|
|
||||||
default:
|
|
||||||
if(ch != 0x04)
|
|
||||||
kbd.line[kbd.x++] = ch;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(send || kbd.x == sizeof kbd.line){
|
|
||||||
qwrite(lineq, kbd.line, kbd.x);
|
|
||||||
kbd.x = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n = qread(lineq, buf, n);
|
|
||||||
qunlock(&kbd);
|
|
||||||
poperror();
|
|
||||||
return n;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
print("consread 0x%llux\n", c->qid.path);
|
print("consread 0x%llux\n", c->qid.path);
|
||||||
|
@ -364,8 +136,7 @@ static long
|
||||||
conswrite(Chan *c, void *va, long n, vlong)
|
conswrite(Chan *c, void *va, long n, vlong)
|
||||||
{
|
{
|
||||||
Snarf *t;
|
Snarf *t;
|
||||||
char buf[256], *a;
|
char *a;
|
||||||
char ch;
|
|
||||||
|
|
||||||
switch((ulong)c->qid.path){
|
switch((ulong)c->qid.path){
|
||||||
case Qcons:
|
case Qcons:
|
||||||
|
@ -373,22 +144,7 @@ conswrite(Chan *c, void *va, long n, vlong)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qconsctl:
|
case Qconsctl:
|
||||||
if(n >= sizeof(buf))
|
error(Egreg);
|
||||||
n = sizeof(buf)-1;
|
|
||||||
strncpy(buf, va, n);
|
|
||||||
buf[n] = 0;
|
|
||||||
for(a = buf; a;){
|
|
||||||
if(strncmp(a, "rawon", 5) == 0){
|
|
||||||
kbd.raw = 1;
|
|
||||||
/* clumsy hack - wake up reader */
|
|
||||||
ch = 0;
|
|
||||||
qwrite(kbdq, &ch, 1);
|
|
||||||
} else if(strncmp(a, "rawoff", 6) == 0){
|
|
||||||
kbd.raw = 0;
|
|
||||||
}
|
|
||||||
if(a = strchr(a, ' '))
|
|
||||||
a++;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qsnarf:
|
case Qsnarf:
|
||||||
|
@ -416,7 +172,7 @@ Dev consdevtab = {
|
||||||
"cons",
|
"cons",
|
||||||
|
|
||||||
devreset,
|
devreset,
|
||||||
consinit,
|
devinit,
|
||||||
consattach,
|
consattach,
|
||||||
conswalk,
|
conswalk,
|
||||||
consstat,
|
consstat,
|
||||||
|
|
|
@ -14,9 +14,8 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Snarf snarf;
|
extern Snarf snarf;
|
||||||
|
extern int kbdin;
|
||||||
|
|
||||||
long latin1(Rune *k, int n);
|
|
||||||
void kbdputc(int c);
|
|
||||||
void screenputs(char*, int);
|
void screenputs(char*, int);
|
||||||
void vncputc(int, int);
|
void vncputc(int, int);
|
||||||
void setsnarf(char *buf, int n, int *vers);
|
void setsnarf(char *buf, int n, int *vers);
|
||||||
|
|
|
@ -1,81 +1,48 @@
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
|
#include <keyboard.h>
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "kbd.h"
|
#include "kbd.h"
|
||||||
#include "ksym2utf.h"
|
#include "ksym2utf.h"
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
VKSpecial = 0xff00,
|
VKSpecial = 0xff00,
|
||||||
|
|
||||||
/*
|
|
||||||
* plan 9 key mappings
|
|
||||||
*/
|
|
||||||
Spec= 0xF800,
|
|
||||||
|
|
||||||
PF= Spec|0x20, /* num pad function key */
|
|
||||||
View= Spec|0x00, /* view (shift window up) */
|
|
||||||
KF= 0xF000, /* function key (begin Unicode private space) */
|
|
||||||
Shift= Spec|0x60,
|
|
||||||
Break= Spec|0x61,
|
|
||||||
Ctrl= Spec|0x62,
|
|
||||||
Latin= Spec|0x63,
|
|
||||||
Caps= Spec|0x64,
|
|
||||||
Num= Spec|0x65,
|
|
||||||
Middle= Spec|0x66,
|
|
||||||
No= 0x00, /* peter */
|
|
||||||
|
|
||||||
Home= KF|13,
|
|
||||||
Up= KF|14,
|
|
||||||
Pgup= KF|15,
|
|
||||||
Print= KF|16,
|
|
||||||
Left= KF|17,
|
|
||||||
Right= KF|18,
|
|
||||||
End= '\r',
|
|
||||||
Down= View,
|
|
||||||
Pgdown= KF|19,
|
|
||||||
Ins= KF|20,
|
|
||||||
Del= 0x7F,
|
|
||||||
Scroll= KF|21,
|
|
||||||
|
|
||||||
Esc = 0x1b,
|
|
||||||
Delete = 0x7f,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static Rune vnckeys[] =
|
static Rune vnckeys[] =
|
||||||
{
|
{
|
||||||
[0x00] No, No, No, No, No, No, No, No,
|
[0x00] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0x08] '\b', '\t', '\r', No, No, '\n', No, No,
|
[0x08] '\b', '\t', '\r', 0, 0, '\n', 0, 0,
|
||||||
[0x10] No, No, No, No, Scroll, No, No, No,
|
[0x10] 0, 0, 0, 0, Kscroll,0, 0, 0,
|
||||||
[0x18] No, No, No, Esc, No, No, No, No,
|
[0x18] 0, 0, 0, Kesc, 0, 0, 0, 0,
|
||||||
[0x20] No, No, No, No, No, No, No, No,
|
[0x20] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0x28] No, No, No, No, No, No, No, No,
|
[0x28] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0x30] No, No, No, No, No, No, No, No,
|
[0x30] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0x38] No, No, No, No, No, No, No, No,
|
[0x38] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0x40] No, No, No, No, No, No, No, No,
|
[0x40] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0x48] No, No, No, No, No, No, No, No,
|
[0x48] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0x50] Home, Left, Up, Right, Down, Pgup, Pgdown, No,
|
[0x50] Khome, Kleft, Kup, Kright, Kdown, Kpgup, Kpgdown,0,
|
||||||
[0x58] No, No, No, No, No, No, No, No,
|
[0x58] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0x60] No, Print, No, Ins, No, No, No, No,
|
[0x60] 0, Kprint, 0, Kins, 0, 0, 0, 0,
|
||||||
[0x68] No, No, No, Break, No, No, No, No,
|
[0x68] 0, 0, 0, Kbreak, 0, 0, 0, 0,
|
||||||
[0x70] No, No, No, No, No, No, No, No,
|
[0x70] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0x78] No, No, No, No, No, No, No, Num,
|
[0x78] 0, 0, 0, 0, 0, 0, 0, Knum,
|
||||||
[0x80] No, No, No, No, No, No, No, No,
|
[0x80] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0x88] No, No, No, No, No, No, No, No,
|
[0x88] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0x90] No, No, No, No, No, No, No, No,
|
[0x90] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0x98] No, No, No, No, No, No, No, No,
|
[0x98] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0xa0] No, No, No, No, No, No, No, No,
|
[0xa0] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0xa8] No, No, '*', '+', No, '-', '.', '/',
|
[0xa8] 0, 0, '*', '+', 0, '-', '.', '/',
|
||||||
[0xb0] '0', '1', '2', '3', '4', '5', '6', '7',
|
[0xb0] '0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
[0xb8] '8', '9', No, No, No, '=', No, No,
|
[0xb8] '8', '9', 0, 0, 0, '=', 0, 0,
|
||||||
[0xc0] No, No, No, No, No, No, No, No,
|
[0xc0] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0xc8] No, No, No, No, No, No, No, No,
|
[0xc8] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0xd0] No, No, No, No, No, No, No, No,
|
[0xd0] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0xd8] No, No, No, No, No, No, No, No,
|
[0xd8] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0xe0] No, Shift, Shift, Ctrl, Ctrl, Caps, Caps, No,
|
[0xe0] 0, Kshift, Kshift, Kctl, Kctl, Kcaps, Kcaps, 0,
|
||||||
[0xe8] No, Latin, Latin, No, No, No, No, No,
|
[0xe8] 0, Kalt, Kalt, 0, 0, 0, 0, 0,
|
||||||
[0xf0] No, No, No, No, No, No, No, No,
|
[0xf0] 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
[0xf8] No, No, No, No, No, No, No, Delete,
|
[0xf8] 0, 0, 0, 0, 0, 0, 0, Kdel,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -84,21 +51,14 @@ static Rune vnckeys[] =
|
||||||
void
|
void
|
||||||
vncputc(int keyup, int c)
|
vncputc(int keyup, int c)
|
||||||
{
|
{
|
||||||
int i;
|
char buf[16];
|
||||||
static int esc1, esc2;
|
|
||||||
static int alt, caps, ctl, num, shift;
|
|
||||||
static int collecting, nk;
|
|
||||||
static Rune kc[5];
|
|
||||||
|
|
||||||
if(caps && c<='z' && c>='a')
|
|
||||||
c += 'A' - 'a';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* character mapping
|
* character mapping
|
||||||
*/
|
*/
|
||||||
if((c & VKSpecial) == VKSpecial){
|
if((c & VKSpecial) == VKSpecial){
|
||||||
c = vnckeys[c & 0xff];
|
c = vnckeys[c & 0xff];
|
||||||
if(c == No)
|
if(c == 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -106,68 +66,9 @@ vncputc(int keyup, int c)
|
||||||
*/
|
*/
|
||||||
if((c & 0xff00) && c < nelem(ksym2utf) && ksym2utf[c] != 0)
|
if((c & 0xff00) && c < nelem(ksym2utf) && ksym2utf[c] != 0)
|
||||||
c = ksym2utf[c];
|
c = ksym2utf[c];
|
||||||
|
snprint(buf, sizeof(buf), "r%C", c);
|
||||||
/*
|
if(keyup)
|
||||||
* keyup only important for shifts
|
buf[0] = 'R';
|
||||||
*/
|
if(kbdin >= 0)
|
||||||
if(keyup){
|
write(kbdin, buf, strlen(buf)+1);
|
||||||
switch(c){
|
|
||||||
case Latin:
|
|
||||||
alt = 0;
|
|
||||||
break;
|
|
||||||
case Shift:
|
|
||||||
shift = 0;
|
|
||||||
break;
|
|
||||||
case Ctrl:
|
|
||||||
ctl = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* normal character
|
|
||||||
*/
|
|
||||||
if(!(c & (Spec|KF))){
|
|
||||||
if(ctl){
|
|
||||||
c &= 0x1f;
|
|
||||||
}
|
|
||||||
if(!collecting){
|
|
||||||
kbdputc(c);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
kc[nk++] = c;
|
|
||||||
c = latin1(kc, nk);
|
|
||||||
if(c < -1) /* need more keystrokes */
|
|
||||||
return;
|
|
||||||
if(c != -1) /* valid sequence */
|
|
||||||
kbdputc(c);
|
|
||||||
else /* dump characters */
|
|
||||||
for(i=0; i<nk; i++)
|
|
||||||
kbdputc(kc[i]);
|
|
||||||
nk = 0;
|
|
||||||
collecting = 0;
|
|
||||||
return;
|
|
||||||
}else{
|
|
||||||
switch(c){
|
|
||||||
case Caps:
|
|
||||||
caps ^= 1;
|
|
||||||
return;
|
|
||||||
case Num:
|
|
||||||
num ^= 1;
|
|
||||||
return;
|
|
||||||
case Shift:
|
|
||||||
shift = 1;
|
|
||||||
return;
|
|
||||||
case Latin:
|
|
||||||
alt = 1;
|
|
||||||
collecting = 1;
|
|
||||||
nk = 0;
|
|
||||||
return;
|
|
||||||
case Ctrl:
|
|
||||||
ctl = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
kbdputc(c);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,11 +229,12 @@ readkbd(Vnc *v)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
chartorune(&r, buf+1);
|
|
||||||
if(utfrune(buf2+1, Kctl) || utfrune(buf2+1, Kalt) || utfrune(buf2+1, Kaltgr))
|
if(utfrune(buf2+1, Kctl) || utfrune(buf2+1, Kalt) || utfrune(buf2+1, Kaltgr))
|
||||||
continue;
|
continue;
|
||||||
if(utfrune(buf2+1, r))
|
chartorune(&r, buf+1);
|
||||||
keyevent(v, runetovnc(r), 1);
|
keyevent(v, runetovnc(r), 1);
|
||||||
|
if(utfrune(buf2+1, r) == nil)
|
||||||
|
keyevent(v, runetovnc(r), 0);
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
#include <u.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code makes two assumptions: strlen(ld) is 1 or 2; latintab[i].ld can be a
|
|
||||||
* prefix of latintab[j].ld only when j<i.
|
|
||||||
*/
|
|
||||||
struct cvlist
|
|
||||||
{
|
|
||||||
char *ld; /* must be seen before using this conversion */
|
|
||||||
char *si; /* options for last input characters */
|
|
||||||
Rune *so; /* the corresponding Rune for each si entry */
|
|
||||||
} latintab[] = {
|
|
||||||
#include "latin1.h"
|
|
||||||
0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given 5 characters k[0]..k[4], find the rune or return -1 for failure.
|
|
||||||
*/
|
|
||||||
long
|
|
||||||
unicode(Rune *k)
|
|
||||||
{
|
|
||||||
long i, c;
|
|
||||||
|
|
||||||
k++; /* skip 'X' */
|
|
||||||
c = 0;
|
|
||||||
for(i=0; i<4; i++,k++){
|
|
||||||
c <<= 4;
|
|
||||||
if('0'<=*k && *k<='9')
|
|
||||||
c += *k-'0';
|
|
||||||
else if('a'<=*k && *k<='f')
|
|
||||||
c += 10 + *k-'a';
|
|
||||||
else if('A'<=*k && *k<='F')
|
|
||||||
c += 10 + *k-'A';
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given n characters k[0]..k[n-1], find the corresponding rune or return -1 for
|
|
||||||
* failure, or something < -1 if n is too small. In the latter case, the result
|
|
||||||
* is minus the required n.
|
|
||||||
*/
|
|
||||||
long
|
|
||||||
latin1(Rune *k, int n)
|
|
||||||
{
|
|
||||||
struct cvlist *l;
|
|
||||||
int c;
|
|
||||||
char* p;
|
|
||||||
|
|
||||||
if(k[0] == 'X')
|
|
||||||
if(n>=5)
|
|
||||||
return unicode(k);
|
|
||||||
else
|
|
||||||
return -5;
|
|
||||||
for(l=latintab; l->ld!=0; l++)
|
|
||||||
if(k[0] == l->ld[0]){
|
|
||||||
if(n == 1)
|
|
||||||
return -2;
|
|
||||||
if(l->ld[1] == 0)
|
|
||||||
c = k[1];
|
|
||||||
else if(l->ld[1] != k[1])
|
|
||||||
continue;
|
|
||||||
else if(n == 2)
|
|
||||||
return -3;
|
|
||||||
else
|
|
||||||
c = k[2];
|
|
||||||
for(p=l->si; *p!=0; p++)
|
|
||||||
if(*p == c)
|
|
||||||
return l->so[p - l->si];
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
" ", " i", L"␣ı",
|
|
||||||
"!~", "-=~", L"≄≇≉",
|
|
||||||
"!", "!<=>?bmp", L"¡≮≠≯‽⊄∉⊅",
|
|
||||||
"\"*", "IUiu", L"ΪΫϊϋ",
|
|
||||||
"\"", "\"AEIOUYaeiouy", L"¨ÄËÏÖÜŸäëïöüÿ",
|
|
||||||
"$*", "fhk", L"ϕϑϰ",
|
|
||||||
"$", "BEFHILMRVaefglopv", L"ℬℰℱℋℐℒℳℛƲɑℯƒℊℓℴ℘ʋ",
|
|
||||||
"\'\"", "Uu", L"Ǘǘ",
|
|
||||||
"\'", "\'ACEILNORSUYZacegilnorsuyz", L"´ÁĆÉÍĹŃÓŔŚÚÝŹáćéģíĺńóŕśúýź",
|
|
||||||
"*", "*ABCDEFGHIKLMNOPQRSTUWXYZabcdefghiklmnopqrstuwxyz", L"∗ΑΒΞΔΕΦΓΘΙΚΛΜΝΟΠΨΡΣΤΥΩΧΗΖαβξδεφγθικλμνοπψρστυωχηζ",
|
|
||||||
"+", "-O", L"±⊕",
|
|
||||||
",", ",ACEGIKLNORSTUacegiklnorstu", L"¸ĄÇĘĢĮĶĻŅǪŖŞŢŲąçęģįķļņǫŗşţų",
|
|
||||||
"-*", "l", L"ƛ",
|
|
||||||
"-", "+-2:>DGHILOTZbdghiltuz~", L"∓ƻ÷→ÐǤĦƗŁ⊖ŦƵƀðǥℏɨłŧʉƶ≂",
|
|
||||||
".", ".CEGILOZceglz", L"·ĊĖĠİĿ⊙Żċėġŀż",
|
|
||||||
"/", "Oo", L"Øø",
|
|
||||||
"1", ".234568", L"․½⅓¼⅕⅙⅛",
|
|
||||||
"2", "-.35", L"ƻ‥⅔⅖",
|
|
||||||
"3", ".458", L"…¾⅗⅜",
|
|
||||||
"4", "5", L"⅘",
|
|
||||||
"5", "68", L"⅚⅝",
|
|
||||||
"7", "8", L"⅞",
|
|
||||||
":", "()-=", L"☹☺÷≔",
|
|
||||||
"<!", "=~", L"≨⋦",
|
|
||||||
"<", "-<=>~", L"←«≤≶≲",
|
|
||||||
"=", ":<=>OV", L"≕⋜≡⋝⊜⇒",
|
|
||||||
">!", "=~", L"≩⋧",
|
|
||||||
">", "<=>~", L"≷≥»≳",
|
|
||||||
"?", "!?", L"‽¿",
|
|
||||||
"@\'", "\'", L"ъ",
|
|
||||||
"@@", "\'EKSTYZekstyz", L"ьЕКСТЫЗекстыз",
|
|
||||||
"@C", "Hh", L"ЧЧ",
|
|
||||||
"@E", "Hh", L"ЭЭ",
|
|
||||||
"@K", "Hh", L"ХХ",
|
|
||||||
"@S", "CHch", L"ЩШЩШ",
|
|
||||||
"@T", "Ss", L"ЦЦ",
|
|
||||||
"@Y", "AEOUaeou", L"ЯЕЁЮЯЕЁЮ",
|
|
||||||
"@Z", "Hh", L"ЖЖ",
|
|
||||||
"@c", "h", L"ч",
|
|
||||||
"@e", "h", L"э",
|
|
||||||
"@k", "h", L"х",
|
|
||||||
"@s", "ch", L"щш",
|
|
||||||
"@t", "s", L"ц",
|
|
||||||
"@y", "aeou", L"яеёю",
|
|
||||||
"@z", "h", L"ж",
|
|
||||||
"@", "ABDFGIJLMNOPRUVXabdfgijlmnopruvx", L"АБДФГИЙЛМНОПРУВХабдфгийлмнопрувх",
|
|
||||||
"A", "E", L"Æ",
|
|
||||||
"C", "ACU", L"⋂ℂ⋃",
|
|
||||||
"Dv", "Zz", L"DŽDž",
|
|
||||||
"D", "-e", L"Ð∆",
|
|
||||||
"G", "-", L"Ǥ",
|
|
||||||
"H", "-H", L"Ħℍ",
|
|
||||||
"I", "-J", L"ƗIJ",
|
|
||||||
"L", "&-Jj|", L"⋀ŁLJLj⋁",
|
|
||||||
"M", "#48bs", L"♮♩♪♭♯",
|
|
||||||
"N", "JNj", L"NJℕNj",
|
|
||||||
"O", "*+-./=EIcoprx", L"⊛⊕⊖⊙⊘⊜ŒƢ©⊚℗®⊗",
|
|
||||||
"P", "P", L"ℙ",
|
|
||||||
"Q", "Q", L"ℚ",
|
|
||||||
"R", "R", L"ℝ",
|
|
||||||
"S", "S", L"§",
|
|
||||||
"T", "-u", L"Ŧ⊨",
|
|
||||||
"V", "=", L"⇐",
|
|
||||||
"Y", "R", L"Ʀ",
|
|
||||||
"Z", "-ACSZ", L"Ƶℤ",
|
|
||||||
"^", "ACEGHIJOSUWYaceghijosuwy", L"ÂĈÊĜĤÎĴÔŜÛŴŶâĉêĝĥîĵôŝûŵŷ",
|
|
||||||
"_\"", "AUau", L"ǞǕǟǖ",
|
|
||||||
"_,", "Oo", L"Ǭǭ",
|
|
||||||
"_.", "Aa", L"Ǡǡ",
|
|
||||||
"_", "AEIOU_aeiou", L"ĀĒĪŌŪ¯āēīōū",
|
|
||||||
"`\"", "Uu", L"Ǜǜ",
|
|
||||||
"`", "AEIOUaeiou", L"ÀÈÌÒÙàèìòù",
|
|
||||||
"a", "ben", L"↔æ∠",
|
|
||||||
"b", "()+-0123456789=bknpqru", L"₍₎₊₋₀₁₂₃₄₅₆₇₈₉₌♝♚♞♟♛♜•",
|
|
||||||
"c", "$Oagu", L"¢©∩≅∪",
|
|
||||||
"dv", "z", L"dž",
|
|
||||||
"d", "-adegz", L"ð↓‡°†ʣ",
|
|
||||||
"e", "$lmns", L"€⋯—–∅",
|
|
||||||
"f", "a", L"∀",
|
|
||||||
"g", "$-r", L"¤ǥ∇",
|
|
||||||
"h", "-v", L"ℏƕ",
|
|
||||||
"i", "-bfjps", L"ɨ⊆∞ij⊇∫",
|
|
||||||
"l", "\"$&\'-jz|", L"“£∧‘łlj⋄∨",
|
|
||||||
"m", "iou", L"µ∈×",
|
|
||||||
"n", "jo", L"nj¬",
|
|
||||||
"o", "AOUaeiu", L"Å⊚Ůåœƣů",
|
|
||||||
"p", "Odgrt", L"℗∂¶∏∝",
|
|
||||||
"r", "\"\'O", L"”’®",
|
|
||||||
"s", "()+-0123456789=abnoprstu", L"⁽⁾⁺⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁼ª⊂ⁿº⊃√ß∍∑",
|
|
||||||
"t", "-efmsu", L"ŧ∃∴™ς⊢",
|
|
||||||
"u", "-AEGIOUaegiou", L"ʉĂĔĞĬŎŬ↑ĕğĭŏŭ",
|
|
||||||
"v\"", "Uu", L"Ǚǚ",
|
|
||||||
"v", "ACDEGIKLNORSTUZacdegijklnorstuz", L"ǍČĎĚǦǏǨĽŇǑŘŠŤǓŽǎčďěǧǐǰǩľňǒřšťǔž",
|
|
||||||
"w", "bknpqr", L"♗♔♘♙♕♖",
|
|
||||||
"x", "O", L"⊗",
|
|
||||||
"y", "$", L"¥",
|
|
||||||
"z", "-", L"ƶ",
|
|
||||||
"|", "Pp|", L"Þþ¦",
|
|
||||||
"~!", "=", L"≆",
|
|
||||||
"~", "-=AINOUainou~", L"≃≅ÃĨÑÕŨãĩñõũ≈",
|
|
|
@ -18,7 +18,6 @@ SOFILES=\
|
||||||
compat.$O\
|
compat.$O\
|
||||||
exportfs.$O\
|
exportfs.$O\
|
||||||
kbds.$O\
|
kbds.$O\
|
||||||
latin1.$O\
|
|
||||||
rre.$O\
|
rre.$O\
|
||||||
rlist.$O\
|
rlist.$O\
|
||||||
|
|
||||||
|
@ -34,7 +33,6 @@ HFILES=\
|
||||||
compat.h\
|
compat.h\
|
||||||
errstr.h\
|
errstr.h\
|
||||||
kbd.h\
|
kbd.h\
|
||||||
latin1.h\
|
|
||||||
vncv.h\
|
vncv.h\
|
||||||
vncs.h\
|
vncs.h\
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,8 @@ struct {
|
||||||
int shared;
|
int shared;
|
||||||
int sleeptime = 5;
|
int sleeptime = 5;
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
int kbdin = -1;
|
||||||
|
|
||||||
char *cert;
|
char *cert;
|
||||||
char *pixchan = "r5g6b5";
|
char *pixchan = "r5g6b5";
|
||||||
static int cmdpid;
|
static int cmdpid;
|
||||||
|
@ -88,6 +90,7 @@ main(int argc, char **argv)
|
||||||
int altnet, baseport, cfd, display, exnum, fd, h, killing, w;
|
int altnet, baseport, cfd, display, exnum, fd, h, killing, w;
|
||||||
char adir[NETPATHLEN], ldir[NETPATHLEN];
|
char adir[NETPATHLEN], ldir[NETPATHLEN];
|
||||||
char net[NETPATHLEN], *p;
|
char net[NETPATHLEN], *p;
|
||||||
|
char *kbdfs[] = { "/bin/aux/kbdfs", "-dq", nil };
|
||||||
char *rc[] = { "/bin/rc", "-i", nil };
|
char *rc[] = { "/bin/rc", "-i", nil };
|
||||||
Vncs *v;
|
Vncs *v;
|
||||||
|
|
||||||
|
@ -190,7 +193,7 @@ main(int argc, char **argv)
|
||||||
bind("#c", "/dev", MREPL);
|
bind("#c", "/dev", MREPL);
|
||||||
|
|
||||||
/* run the command */
|
/* run the command */
|
||||||
switch(cmdpid = rfork(RFPROC|RFFDG|RFNOTEG|RFNAMEG|RFREND)){
|
switch(cmdpid = rfork(RFPROC|RFFDG|RFNOTEG)){
|
||||||
case -1:
|
case -1:
|
||||||
sysfatal("rfork: %r");
|
sysfatal("rfork: %r");
|
||||||
break;
|
break;
|
||||||
|
@ -198,12 +201,20 @@ main(int argc, char **argv)
|
||||||
if(mounter("/dev", MBEFORE, fd, exnum) < 0)
|
if(mounter("/dev", MBEFORE, fd, exnum) < 0)
|
||||||
sysfatal("mounter: %r");
|
sysfatal("mounter: %r");
|
||||||
close(exportfd);
|
close(exportfd);
|
||||||
close(0);
|
|
||||||
close(1);
|
close(1);
|
||||||
close(2);
|
close(2);
|
||||||
|
open("/dev/cons", OWRITE);
|
||||||
|
open("/dev/cons", OWRITE);
|
||||||
|
if(rfork(RFPROC|RFMEM|RFFDG) == 0){
|
||||||
|
exec(kbdfs[0], kbdfs);
|
||||||
|
_exits("kbdfs");
|
||||||
|
}
|
||||||
|
waitpid();
|
||||||
|
rfork(RFNAMEG);
|
||||||
|
rendezvous(&cmdpid, 0);
|
||||||
|
rfork(RFREND);
|
||||||
|
close(0);
|
||||||
open("/dev/cons", OREAD);
|
open("/dev/cons", OREAD);
|
||||||
open("/dev/cons", OWRITE);
|
|
||||||
open("/dev/cons", OWRITE);
|
|
||||||
exec(argv[0], argv);
|
exec(argv[0], argv);
|
||||||
fprint(2, "exec %s: %r\n", argv[0]);
|
fprint(2, "exec %s: %r\n", argv[0]);
|
||||||
_exits(nil);
|
_exits(nil);
|
||||||
|
@ -212,6 +223,11 @@ main(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rendezvous(&cmdpid, 0);
|
||||||
|
kbdin = open("/dev/kbdin", OWRITE);
|
||||||
|
unmount(nil, "/dev");
|
||||||
|
bind("#c", "/dev", MREPL);
|
||||||
|
|
||||||
/* run the service */
|
/* run the service */
|
||||||
srvfd = vncannounce(net, display, adir, baseport);
|
srvfd = vncannounce(net, display, adir, baseport);
|
||||||
if(srvfd < 0)
|
if(srvfd < 0)
|
||||||
|
@ -385,6 +401,8 @@ killall(void)
|
||||||
srvfd = -1;
|
srvfd = -1;
|
||||||
close(exportfd);
|
close(exportfd);
|
||||||
exportfd = -1;
|
exportfd = -1;
|
||||||
|
close(kbdin);
|
||||||
|
kbdin = -1;
|
||||||
postnote(PNGROUP, getpid(), killkin);
|
postnote(PNGROUP, getpid(), killkin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue