summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@centraldogma>2011-05-28 08:16:01 +0000
committercinap_lenrek <cinap_lenrek@centraldogma>2011-05-28 08:16:01 +0000
commitfbbb449cc0bd35ebb89b87d5b46ed2874246876e (patch)
tree73dc04ae8e0dd22becec50be198b25a300c67f77 /sys
parent98f4157b5a2f9bce37939e2ea807b631943d969c (diff)
big /dev/kbd change, new format, support Alt+Stuff (key composing)
Diffstat (limited to 'sys')
-rw-r--r--sys/man/8/kbdfs53
-rw-r--r--sys/src/cmd/aux/kbdfs/kbdfs.c (renamed from sys/src/cmd/aux/kbdfs.c)184
-rw-r--r--sys/src/cmd/aux/kbdfs/mkfile16
-rw-r--r--sys/src/cmd/aux/kbdfs/mkfile.mklatin7
-rw-r--r--sys/src/cmd/aux/kbdfs/mklatin.c (renamed from sys/src/cmd/aux/mklatinkbd.c)0
-rw-r--r--sys/src/cmd/aux/mkfile3
-rw-r--r--sys/src/cmd/rio/rio.c6
-rw-r--r--sys/src/cmd/rio/wind.c18
-rw-r--r--sys/src/games/doom/i_video.c46
9 files changed, 236 insertions, 97 deletions
diff --git a/sys/man/8/kbdfs b/sys/man/8/kbdfs
index 7149cbd62..733953bdf 100644
--- a/sys/man/8/kbdfs
+++ b/sys/man/8/kbdfs
@@ -152,26 +152,41 @@ This is used on serial consoles.
.SS Keyboard
A read on the
.BR kbd
-file returns a null terminated, variable-length,
+file returns the character
+.B k,
+.B K
+or
+.B c
+followed by a null terminated, variable-length,
.SM UTF
-encoded string of all the keys that are currently pressed (key is
-down) on the keyboard. This includes all keys that have a keyboard
-mapping and modifier keys. No key is treated specially. A new event
-is generated on each state change or at keyboard repeat rate and put
-in a buffer. Each
-.IR read (2)
-will return a single event or block until there are new events
-available. The read data is always terminated with a null-byte,
-so when all keys are released (all keys are up), a single
-null-byte will be returned. Newly pressed keys are appended to the
-string before the null-byte. Key releases remove the
-character from the string. Change on a modifier key like
+encoded string. The
+.B k
+message is send when a key is pressed down
+and
+.B K
+when a key is released. The following string contains all the keycodes
+of the keys that are currently pressed down in decomposed form.
+This includes all keys that have a keyboard mapping and modifier keys.
+Some keys may produce multiple characters like
.B Shift
-or
-.B Num
-will not change
-the characters already present in the string, but will
-take effect on newly pressed keys. Opening the
+and
+.B a
+will produce
+.B Shift,
+.B a,
+.B A
+in the string. The string following the
+.B c
+message contains the single character that would have been appeared
+on the
+.BR cons
+file instead. The
+.B c
+message will be resent at the keyboard repeat rate.
+Each
+.IR read (2)
+will return a single message or block until there are new messages
+available. Opening the
.BR kbd
file disables input processing on the
.BR cons
@@ -222,4 +237,4 @@ to represent a control character.
.SH FILES
.B /dev/lib/kbmap/*
.SH SOURCE
-.B /sys/src/cmd/aux/kbdfs.c
+.B /sys/src/cmd/aux/kbdfs
diff --git a/sys/src/cmd/aux/kbdfs.c b/sys/src/cmd/aux/kbdfs/kbdfs.c
index 1a0a0fa3d..2da4f958f 100644
--- a/sys/src/cmd/aux/kbdfs.c
+++ b/sys/src/cmd/aux/kbdfs/kbdfs.c
@@ -101,6 +101,7 @@ Channel *reqchan; /* Req* */
Channel *ctlchan; /* int */
Channel *rawchan; /* Rune */
+Channel *runechan; /* Rune */
Channel *linechan; /* char * */
Channel *kbdchan; /* char* */
@@ -354,7 +355,7 @@ utfconv(Rune *r, int n)
void
keyproc(void *)
{
- Rune rb[Nscan*2];
+ Rune rb[Nscan*2+1];
int cb[Nscan];
Key key;
int i, nb;
@@ -364,42 +365,35 @@ keyproc(void *)
nb = 0;
while(recv(keychan, &key) > 0){
- if(key.down){
- switch(key.r){
- case 0:
- case Kcaps:
- case Knum:
- case Kshift:
- case Kalt:
- case Kctl:
- case Kaltgr:
- break;
- default:
- nbsend(rawchan, &key.r);
- }
- }
+ if(key.down && key.r)
+ nbsend(rawchan, &key.r);
+ rb[0] = 0;
for(i=0; i<nb && cb[i] != key.c; i++)
;
if(!key.down){
while(i < nb && cb[i] == key.c){
memmove(cb+i, cb+i+1, (nb-i+1) * sizeof(cb[0]));
- memmove(rb+i, rb+i+1, (nb-i+1) * sizeof(rb[0]));
+ memmove(rb+i+1, rb+i+2, (nb-i+1) * sizeof(rb[0]));
nb--;
+ rb[0] = 'K';
}
} else if(i == nb && nb < nelem(cb) && key.b){
cb[nb] = key.c;
- rb[nb] = key.b;
+ rb[nb+1] = key.b;
nb++;
if(nb < nelem(cb) && key.r && key.b != key.r){
cb[nb] = key.c;
- rb[nb] = key.r;
+ rb[nb+1] = key.r;
nb++;
}
+ rb[0] = 'k';
+ }
+ if(rb[0]){
+ s = utfconv(rb, nb+1);
+ if(nbsendp(kbdchan, s) <= 0)
+ free(s);
}
- s = utfconv(rb, nb);
- if(nbsendp(kbdchan, s) <= 0)
- free(s);
}
}
@@ -429,7 +423,7 @@ consproc(void *)
}
if(cr = (r == '\r'))
r = '\n';
- send(rawchan, &r);
+ send(runechan, &r);
}
}
n = x - p;
@@ -438,6 +432,101 @@ consproc(void *)
}
}
+static int
+nextrune(Channel *ch, Rune *r)
+{
+ while(recv(ch, r) > 0){
+ switch(*r){
+ case 0:
+ case Kcaps:
+ case Knum:
+ case Kshift:
+ case Kctl:
+ case Kaltgr:
+ /* ignore these special keys */
+ continue;
+
+ case Kalt:
+ /* latin escape! */
+ return 1;
+ }
+ return 0;
+ }
+ return -1;
+}
+
+/*
+ * Read runes from rawchan, possibly compose special characters
+ * and output the new runes to runechan
+ */
+void
+runeproc(void *)
+{
+ static struct {
+ 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 */
+ } tab[] = {
+#include "latin1.h"
+ };
+ Rune r, rr;
+ int i, j;
+
+ threadsetname("runeproc");
+
+ while((i = nextrune(rawchan, &r)) >= 0){
+ if(i == 0){
+Forward:
+ send(runechan, &r);
+ continue;
+ }
+
+ /* latin sequence */
+ if(nextrune(rawchan, &r))
+ continue;
+
+ if(r == 'X'){
+ r = 0;
+ for(i = 0; i<4; i++){
+ if(nextrune(rawchan, &rr))
+ break;
+ r <<= 4;
+ if(rr >= '0' && rr <= '9')
+ r |= (rr - '0');
+ else if(rr >= 'a' && rr <= 'f')
+ r |= 10 + (rr - 'a');
+ else if(rr >= 'A' && rr <= 'F')
+ r |= 10 + (rr - 'A');
+ else
+ break;
+ }
+ if(i == 4 && r > 0)
+ goto Forward;
+ } else {
+ if(nextrune(rawchan, &rr))
+ continue;
+ for(i = 0; i<nelem(tab); i++){
+ if(tab[i].ld[0] != r)
+ continue;
+ if(tab[i].ld[1] == 0)
+ break;
+ if(tab[i].ld[1] == rr){
+ nextrune(rawchan, &rr);
+ break;
+ }
+ }
+ if(i == nelem(tab) || rr == 0)
+ continue;
+ for(j = 0; tab[i].si[j]; j++){
+ if(tab[i].si[j] != rr)
+ continue;
+ r = tab[i].so[j];
+ goto Forward;
+ }
+ }
+ }
+}
+
/*
* Cook lines for cons
*/
@@ -496,7 +585,7 @@ ctlproc(void *)
Req *h;
Req **t;
} qcons, qkbd, *q;
- enum { Areq, Actl, Araw, Aline, Akbd, Aend };
+ enum { Areq, Actl, Arune, Aline, Akbd, Aend };
Alt a[Aend+1];
Req *req;
Fid *fid;
@@ -510,12 +599,13 @@ ctlproc(void *)
cook = chancreate(sizeof(Rune), 0);
if(scanfd >= 0)
- proccreate(scanproc, nil, STACK);
+ proccreate(scanproc, nil, STACK); /* scanfd -> keychan */
if(consfd >= 0)
- proccreate(consproc, nil, STACK);
+ proccreate(consproc, nil, STACK); /* consfd -> runechan */
- threadcreate(keyproc, nil, STACK);
- threadcreate(lineproc, cook, STACK);
+ threadcreate(keyproc, nil, STACK); /* keychan -> rawchan, kbdchan */
+ threadcreate(runeproc, nil, STACK); /* rawchan -> runechan */
+ threadcreate(lineproc, cook, STACK); /* cook -> linechan */
raw = 0;
@@ -536,9 +626,9 @@ ctlproc(void *)
a[Actl].v = &c;
a[Actl].op = CHANRCV;
- a[Araw].c = rawchan;
- a[Araw].v = &r;
- a[Araw].op = CHANRCV;
+ a[Arune].c = runechan;
+ a[Arune].v = &r;
+ a[Arune].op = CHANRCV;
a[Aline].c = linechan;
a[Aline].v = &s;
@@ -553,9 +643,15 @@ ctlproc(void *)
for(;;){
s = nil;
- a[Araw].op = (b == nil) ? CHANRCV : CHANNOP;
- a[Aline].op = (b == nil) ? CHANRCV : CHANNOP;
- a[Akbd].op = qkbd.h || !kbdopen ? CHANRCV : CHANNOP;
+ if(kbdopen){
+ a[Arune].op = qkbd.h ? CHANRCV : CHANNOP;
+ a[Akbd].op = qkbd.h ? CHANRCV : CHANNOP;
+ a[Aline].op = CHANNOP;
+ }else{
+ a[Arune].op = (b == nil) ? CHANRCV : CHANNOP;
+ a[Akbd].op = CHANRCV;
+ a[Aline].op = (b == nil) ? CHANRCV : CHANNOP;
+ }
switch(alt(a)){
case Areq:
@@ -604,8 +700,15 @@ ctlproc(void *)
}
break;
- case Araw:
- if(raw || kbdopen){
+ case Arune:
+ if(kbdopen){
+ s = emalloc9p(UTFmax+2);
+ s[0] = 'c';
+ s[1+runetochar(s+1, &r)] = 0;
+ goto Havekbd;
+ }
+
+ if(raw){
s = emalloc9p(UTFmax+1);
s[runetochar(s, &r)] = 0;
} else {
@@ -620,11 +723,6 @@ ctlproc(void *)
e = s + strlen(s);
Havereq:
- if(kbdopen){
- free(b);
- b = nil;
- break;
- }
while(b && (req = qcons.h)){
if((qcons.h = req->aux) == nil)
qcons.t = &qcons.h;
@@ -643,6 +741,7 @@ ctlproc(void *)
break;
case Akbd:
+ Havekbd:
if(req = qkbd.h){
if((qkbd.h = req->aux) == nil)
qkbd.t = &qkbd.h;
@@ -1166,11 +1265,12 @@ threadmain(int argc, char** argv)
keychan = chancreate(sizeof(Key), 8);
reqchan = chancreate(sizeof(Req*), 0);
ctlchan = chancreate(sizeof(int), 0);
- rawchan = chancreate(sizeof(Rune), 32);
+ rawchan = chancreate(sizeof(Rune), 16);
+ runechan = chancreate(sizeof(Rune), 32);
linechan = chancreate(sizeof(char*), 16);
kbdchan = chancreate(sizeof(char*), 16);
- if(!(keychan && reqchan && ctlchan && rawchan && linechan && kbdchan))
+ if(!(keychan && reqchan && ctlchan && rawchan && runechan && linechan && kbdchan))
sysfatal("allocating chans");
elevate();
diff --git a/sys/src/cmd/aux/kbdfs/mkfile b/sys/src/cmd/aux/kbdfs/mkfile
new file mode 100644
index 000000000..dea627845
--- /dev/null
+++ b/sys/src/cmd/aux/kbdfs/mkfile
@@ -0,0 +1,16 @@
+</$objtype/mkfile
+
+BIN=/$objtype/bin/aux
+
+TARG=kbdfs
+OFILES=kbdfs.$O
+HFILES=latin1.h
+CLEANFILES=latin1.h mklatin.$cputype
+
+</sys/src/cmd/mkone
+
+mklatin.$cputype: mkfile.mklatin
+ @{objtype=$cputype mk -f $prereq $target}
+
+latin1.h: mklatin.$cputype /lib/keyboard
+ $prereq >$target
diff --git a/sys/src/cmd/aux/kbdfs/mkfile.mklatin b/sys/src/cmd/aux/kbdfs/mkfile.mklatin
new file mode 100644
index 000000000..ba34ac12c
--- /dev/null
+++ b/sys/src/cmd/aux/kbdfs/mkfile.mklatin
@@ -0,0 +1,7 @@
+</$objtype/mkfile
+
+mklatin.$cputype: mklatin.$O
+ $LD $LDFLAGS -o $target $prereq
+
+</sys/src/cmd/mkone
+
diff --git a/sys/src/cmd/aux/mklatinkbd.c b/sys/src/cmd/aux/kbdfs/mklatin.c
index 64787f00f..64787f00f 100644
--- a/sys/src/cmd/aux/mklatinkbd.c
+++ b/sys/src/cmd/aux/kbdfs/mklatin.c
diff --git a/sys/src/cmd/aux/mkfile b/sys/src/cmd/aux/mkfile
index d46602c63..943ae06f2 100644
--- a/sys/src/cmd/aux/mkfile
+++ b/sys/src/cmd/aux/mkfile
@@ -17,11 +17,9 @@ TARG=\
disksim\
getflags\
icanhasmsi\
- kbdfs\
lines\
listen\
listen1\
- mklatinkbd\
ms2\
msexceltables\
mswordstrings\
@@ -57,6 +55,7 @@ UPDATE=\
DIRS=mnihongo\
flashfs\
gps\
+ kbdfs\
na\
vga\
realemu
diff --git a/sys/src/cmd/rio/rio.c b/sys/src/cmd/rio/rio.c
index 1550213ef..a101ee256 100644
--- a/sys/src/cmd/rio/rio.c
+++ b/sys/src/cmd/rio/rio.c
@@ -1234,10 +1234,8 @@ kbdproc(void *arg)
e = p + n;
while(p < e && fullrune(p, e - p)){
p += chartorune(&r, p);
- if(r){
- chanprint(c, "%C", r);
- chanprint(c, "");
- }
+ if(r)
+ chanprint(c, "c%C", r);
}
n = e - p;
memmove(buf, p, n);
diff --git a/sys/src/cmd/rio/wind.c b/sys/src/cmd/rio/wind.c
index 104c19e93..92b63c177 100644
--- a/sys/src/cmd/rio/wind.c
+++ b/sys/src/cmd/rio/wind.c
@@ -292,20 +292,16 @@ winctl(void *arg)
}
switch(alt(alts)){
case WKbd:
- if(utflen(kbds) >= utflen(kbdq[kbdqw] ? kbdq[kbdqw] : "")){
- Rune r;
-
- i = 0;
- r = 0;
- while(kbds[i])
- i += chartorune(&r, kbds+i);
- if(!w->kbdopen)
- wkeyctl(w, r);
- }
if(w->kbdopen){
i = (kbdqw+1) % nelem(kbdq);
if(i != kbdqr)
kbdqw = i;
+ } else if(*kbds == 'c'){
+ Rune r;
+
+ chartorune(&r, kbds+1);
+ if(r)
+ wkeyctl(w, r);
}
free(kbdq[kbdqw]);
kbdq[kbdqw] = kbds;
@@ -319,7 +315,7 @@ winctl(void *arg)
sendp(krm.ck, kbdq[i]);
kbdq[i] = nil;
}else
- sendp(krm.ck, strdup(""));
+ sendp(krm.ck, strdup("K"));
continue;
case WMouse:
diff --git a/sys/src/games/doom/i_video.c b/sys/src/games/doom/i_video.c
index dcf31a993..34543bc96 100644
--- a/sys/src/games/doom/i_video.c
+++ b/sys/src/games/doom/i_video.c
@@ -217,32 +217,40 @@ kbdproc(void *)
sysfatal("can't open kbd: %r");
buf2[0] = 0;
+ buf2[1] = 0;
while((n = read(kfd, buf, sizeof(buf))) > 0){
buf[n-1] = 0;
- s = buf;
- while(*s){
- s += chartorune(&r, s);
- if(utfrune(buf2, r) == nil){
- e.type = ev_keydown;
- if(e.data1 = runetokey(r)){
- e.data2 = *s == 0 ? e.data1 : -1;
- e.data3 = *s ? e.data1 : -1;
- D_PostEvent(&e);
+ switch(buf[0]){
+ case 'k':
+ s = buf+1;
+ while(*s){
+ s += chartorune(&r, s);
+ if(utfrune(buf2+1, r) == nil){
+ if(e.data1 = runetokey(r)){
+ e.data2 = *s == 0 ? e.data1 : -1;
+ e.data3 = -1;
+ e.type = ev_keydown;
+ D_PostEvent(&e);
+ }
}
}
- }
- s = buf2;
- while(*s){
- s += chartorune(&r, s);
- if(utfrune(buf, r) == nil){
- e.type = ev_keyup;
- if(e.data1 = runetokey(r)){
- e.data2 = -1;
- e.data3 = -1;
- D_PostEvent(&e);
+ break;
+ case 'K':
+ s = buf2+1;
+ while(*s){
+ s += chartorune(&r, s);
+ if(utfrune(buf+1, r) == nil){
+ if(e.data1 = runetokey(r)){
+ e.data2 = e.data3 = -1;
+ e.type = ev_keyup;
+ D_PostEvent(&e);
+ }
}
}
+ break;
+ default:
+ continue;
}
strcpy(buf2, buf);
}