summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2022-10-08 10:38:14 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2022-10-08 10:38:14 +0000
commit166e8b3cf8d2e087258eb47fdba7e890d6a8432a (patch)
treeda16c7d2198956abacd36cb99a6137136503a11e /sys/src
parent2a29b497f215f91d05b6718a0e852e8a9b6ce6da (diff)
parentc6ae349e9d67ef24ce429f699c5232a9acdcb1ea (diff)
merge
Diffstat (limited to 'sys/src')
-rw-r--r--sys/src/cmd/aux/kbdfs/kbdfs.c22
-rw-r--r--sys/src/cmd/bar.c2
-rw-r--r--sys/src/cmd/cc/pickle.c8
-rw-r--r--sys/src/cmd/git/compat5
-rwxr-xr-xsys/src/cmd/git/hist4
-rw-r--r--[-rwxr-xr-x]sys/src/cmd/git/import4
-rw-r--r--sys/src/cmd/ip/acmed.c905
-rw-r--r--sys/src/cmd/ktrans/main.c133
-rw-r--r--sys/src/cmd/nusb/disk/disk.c4
-rw-r--r--sys/src/cmd/nusb/kb/hid.h1
-rw-r--r--sys/src/cmd/nusb/kb/kb.c211
-rw-r--r--sys/src/cmd/patch.c56
-rw-r--r--sys/src/cmd/reform/pm.c211
-rw-r--r--sys/src/cmd/reform/shortcuts.c66
-rw-r--r--sys/src/cmd/rio/rio.c36
-rw-r--r--sys/src/cmd/riow.c205
-rw-r--r--sys/src/cmd/vt/main.c1
17 files changed, 659 insertions, 1215 deletions
diff --git a/sys/src/cmd/aux/kbdfs/kbdfs.c b/sys/src/cmd/aux/kbdfs/kbdfs.c
index c0b87b2bf..cc2d3c389 100644
--- a/sys/src/cmd/aux/kbdfs/kbdfs.c
+++ b/sys/src/cmd/aux/kbdfs/kbdfs.c
@@ -124,12 +124,16 @@ Channel *kbdchan; /* chan(char*) */
Channel *intchan; /* chan(int) */
/*
- * The codes at 0x79 and 0x7b are produced by the PFU Happy Hacking keyboard.
- * A 'standard' keyboard doesn't produce anything above 0x58.
+ * The codes at 0x79 and 0x7b are for the (無)変換 "(Mu)henkan" keys
+ * used by OADG 109(A) keyboards. The PFU Happy Hacking keyboard
+ * has only one layout and will produce these for otherwise unmarked
+ * keys. The default mappings for the HHKB on other systems map
+ * these to Kdown and Kup. The jp kbmap will instead map these
+ * (along with 0x70) to control characters that ktrans understands.
*/
Rune kbtab[Nscan] =
{
-[0x00] 0, 0x1b, '1', '2', '3', '4', '5', '6',
+[0x00] 0, Kesc, '1', '2', '3', '4', '5', '6',
[0x08] '7', '8', '9', '0', '-', '=', '\b', '\t',
[0x10] 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
[0x18] 'o', 'p', '[', ']', '\n', Kctl, 'a', 's',
@@ -149,7 +153,7 @@ Rune kbtab[Nscan] =
Rune kbtabshift[Nscan] =
{
-[0x00] 0, 0x1b, '!', '@', '#', '$', '%', '^',
+[0x00] 0, Kesc, '!', '@', '#', '$', '%', '^',
[0x08] '&', '*', '(', ')', '_', '+', '\b', '\t',
[0x10] 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
[0x18] 'O', 'P', '{', '}', '\n', Kctl, 'A', 'S',
@@ -171,11 +175,11 @@ Rune kbtabesc1[Nscan] =
{
[0x00] 0, 0, 0, 0, 0, 0, 0, 0,
[0x08] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x10] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x18] 0, 0, 0, 0, '\n', Kctl, 0, 0,
-[0x20] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x28] 0, 0, 0, 0, 0, 0, 0, 0,
-[0x30] 0, 0, 0, 0, 0, '/', 0, Kprint,
+[0x10] Ksbwd, Kbrtdn, 0, 0, 0, 0, 0, 0,
+[0x18] 0, Ksfwd, Kbrtup, 0, '\n', Kctl, 0, 0,
+[0x20] Kmute, 0, Kpause, 0, 0, 0, 0, 0,
+[0x28] 0, 0, 0, 0, 0, 0, Kvoldn, 0,
+[0x30] Kvolup, 0, 0, 0, 0, '/', 0, Kprint,
[0x38] Kaltgr, 0, 0, 0, 0, 0, 0, 0,
[0x40] 0, 0, 0, 0, 0, 0, Kbreak, Khome,
[0x48] Kup, Kpgup, 0, Kleft, 0, Kright, 0, Kend,
diff --git a/sys/src/cmd/bar.c b/sys/src/cmd/bar.c
index 2db493319..1157ad245 100644
--- a/sys/src/cmd/bar.c
+++ b/sys/src/cmd/bar.c
@@ -200,9 +200,9 @@ auxproc(void *c)
Binit(&b, 0, OREAD);
for(;;){
s = Brdstr(&b, '\n', 1);
- sendp(c, s ? s : strdup(""));
if(s == nil)
break;
+ sendp(c, s);
}
Bterm(&b);
diff --git a/sys/src/cmd/cc/pickle.c b/sys/src/cmd/cc/pickle.c
index 1946b4e6c..7cac68421 100644
--- a/sys/src/cmd/cc/pickle.c
+++ b/sys/src/cmd/cc/pickle.c
@@ -172,9 +172,9 @@ pickletype(Type *t)
int n;
char *an;
- if(!debug['P'])
+ if(!debug['Z'])
return;
- if(debug['P'] > 1) {
+ if(debug['Z'] > 1) {
n = 0;
for(i=iostack; i; i=i->link)
n++;
@@ -221,9 +221,9 @@ picklevar(Sym *s)
Type *t;
Sym *s1, *s2;
- if(!debug['P'] || debug['s'])
+ if(!debug['Z'] || debug['s'])
return;
- if(debug['P'] > 1) {
+ if(debug['Z'] > 1) {
n = 0;
for(i=iostack; i; i=i->link)
n++;
diff --git a/sys/src/cmd/git/compat b/sys/src/cmd/git/compat
index f61ff71e9..5058b407c 100644
--- a/sys/src/cmd/git/compat
+++ b/sys/src/cmd/git/compat
@@ -6,10 +6,8 @@ opts=()
args=()
fn cmd_init{
- while(~ $#* 0){
+ while(! ~ $#* 0){
switch($1){
- case --bare
- opts=(-b)
case --
# go likes to use these
case -*
@@ -19,7 +17,6 @@ fn cmd_init{
}
shift
}
- ls >[1=2]
git/init $opts $args
}
diff --git a/sys/src/cmd/git/hist b/sys/src/cmd/git/hist
index 7602d30f1..38ae279c4 100755
--- a/sys/src/cmd/git/hist
+++ b/sys/src/cmd/git/hist
@@ -7,8 +7,8 @@ gitup
fn dodiff {
while(t=`{read}){
h=$t(1)
- o=$gitroot^.git/fs/object/`{git/query $h~}
- c=$gitroot^.git/fs/object/$h
+ o=$gitfs/object/`{git/query $h~}
+ c=$gitfs/object/$h
echo 'Hash:' $h
echo -n 'Date: '; date `{walk -em $c/msg}
echo -n 'Author: '; cat $c/author
diff --git a/sys/src/cmd/git/import b/sys/src/cmd/git/import
index 643e6865c..ebb5dbcb6 100755..100644
--- a/sys/src/cmd/git/import
+++ b/sys/src/cmd/git/import
@@ -96,8 +96,10 @@ fn apply @{
}
git/walk -fRMA $files
if(~ $#nocommit 0){
- if(hash=`{git/save -n $aname -e $amail -N $name -E $email -m $msg -d $date $parents $files})
+ if(hash=`{git/save -n $aname -e $amail -N $name -E $email -m $msg -d $date $parents $files}){
echo $hash > $refpath
+ rm -f .git/index9/removed/$files
+ }
}
status=''''
'
diff --git a/sys/src/cmd/ip/acmed.c b/sys/src/cmd/ip/acmed.c
deleted file mode 100644
index c97429b3a..000000000
--- a/sys/src/cmd/ip/acmed.c
+++ /dev/null
@@ -1,905 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <json.h>
-#include <mp.h>
-#include <libsec.h>
-#include <auth.h>
-#include <authsrv.h>
-
-typedef struct Hdr Hdr;
-
-#pragma varargck type "E" char*
-
-struct Hdr {
- char *name;
- char *val;
- int nval;
-};
-
-#define Keyspec "proto=rsa service=acme role=sign hash=sha256 acct=%s"
-#define Useragent "useragent aclient-plan9"
-#define Contenttype "contenttype application/jose+json"
-#define between(x,min,max) (((min-1-x) & (x-max-1))>>8)
-int debug;
-int (*challengefn)(char*, char*, char*, int*);
-char *keyspec;
-char *provider = "https://acme-v02.api.letsencrypt.org/directory"; /* default endpoint */
-char *challengecmd;
-char *challengeout;
-char *keyid;
-char *epnewnonce;
-char *epnewacct;
-char *epneworder;
-char *eprevokecert;
-char *epkeychange;
-char *jwsthumb;
-JSON *jwskey;
-
-#define dprint(...) if(debug)fprint(2, __VA_ARGS__);
-
-char*
-evsmprint(char *fmt, va_list ap)
-{
- char *r;
-
- if((r = vsmprint(fmt, ap)) == nil)
- abort();
- return r;
-}
-
-char*
-esmprint(char *fmt, ...)
-{
- va_list ap;
- char *r;
-
- va_start(ap, fmt);
- r = evsmprint(fmt, ap);
- va_end(ap);
- return r;
-}
-
-int
-encurl64chr(int o)
-{
- int c;
-
- c = between(o, 0, 25) & ('A'+o);
- c |= between(o, 26, 51) & ('a'+(o-26));
- c |= between(o, 52, 61) & ('0'+(o-52));
- c |= between(o, 62, 62) & ('-');
- c |= between(o, 63, 63) & ('_');
- return c;
-}
-char*
-encurl64(void *in, int n)
-{
- int lim;
- char *out, *p;
-
- lim = 4*n/3 + 5;
- if((out = malloc(lim)) == nil)
- abort();
- enc64x(out, lim, in, n, encurl64chr);
- if((p = strchr(out, '=')) != nil)
- *p = 0;
- return out;
-}
-
-char*
-signRS256(char *hdr, char *prot)
-{
- uchar hash[SHA2_256dlen];
- DigestState *s;
- AuthRpc *rpc;
- int afd;
- char *r;
-
- if((afd = open("/mnt/factotum/rpc", ORDWR|OCEXEC)) < 0)
- return nil;
- if((rpc = auth_allocrpc(afd)) == nil){
- close(afd);
- return nil;
- }
- if(auth_rpc(rpc, "start", keyspec, strlen(keyspec)) != ARok){
- auth_freerpc(rpc);
- close(afd);
- return nil;
- }
-
- s = sha2_256((uchar*)hdr, strlen(hdr), nil, nil);
- s = sha2_256((uchar*)".", strlen("."), nil, s);
- sha2_256((uchar*)prot, strlen(prot), hash, s);
-
- if(auth_rpc(rpc, "write", hash, sizeof(hash)) != ARok)
- sysfatal("sign: write hash: %r");
- if(auth_rpc(rpc, "read", nil, 0) != ARok)
- sysfatal("sign: read sig: %r");
- r = encurl64(rpc->arg, rpc->narg);
- auth_freerpc(rpc);
- close(afd);
- return r;
-}
-
-/*
- * Reads all available data from an fd.
- * guarantees returned value is terminated.
- */
-static void*
-slurp(int fd, int *n)
-{
- char *b;
- int r, sz;
-
- *n = 0;
- sz = 32;
- if((b = malloc(sz)) == nil)
- abort();
- while(1){
- if(*n + 1 == sz){
- sz *= 2;
- if((b = realloc(b, sz)) == nil)
- abort();
- }
- r = read(fd, b + *n, sz - *n - 1);
- if(r == 0)
- break;
- if(r == -1){
- free(b);
- return nil;
- }
- *n += r;
- }
- b[*n] = 0;
- return b;
-}
-
-static int
-webopen(char *url, char *dir, int ndir)
-{
- char buf[16];
- int n, cfd, conn;
-
- if((cfd = open("/mnt/web/clone", ORDWR|OCEXEC)) == -1)
- return -1;
- if((n = read(cfd, buf, sizeof(buf)-1)) == -1)
- goto Error;
- buf[n] = 0;
- conn = atoi(buf);
-
- if(fprint(cfd, "url %s", url) == -1)
- goto Error;
- snprint(dir, ndir, "/mnt/web/%d", conn);
- return cfd;
-Error:
- close(cfd);
- return -1;
-}
-
-static char*
-get(char *url, int *n)
-{
- char *r, dir[64], path[80];
- int cfd, dfd;
-
- r = nil;
- dfd = -1;
- if((cfd = webopen(url, dir, sizeof(dir))) == -1)
- goto Error;
- snprint(path, sizeof(path), "%s/%s", dir, "body");
- if((dfd = open(path, OREAD|OCEXEC)) == -1)
- goto Error;
- r = slurp(dfd, n);
-Error:
- if(dfd != -1) close(dfd);
- if(cfd != -1) close(cfd);
- return r;
-}
-
-static char*
-post(char *url, char *buf, int nbuf, int *nret, Hdr *h)
-{
- char *r, dir[64], path[80];
- int cfd, dfd, hfd, ok;
-
- r = nil;
- ok = 0;
- dfd = -1;
- hfd = -1;
- if((cfd = webopen(url, dir, sizeof(dir))) == -1)
- goto Error;
- if(write(cfd, Contenttype, strlen(Contenttype)) == -1)
- goto Error;
- snprint(path, sizeof(path), "%s/%s", dir, "postbody");
- if((dfd = open(path, OWRITE|OCEXEC)) == -1)
- goto Error;
- if(write(dfd, buf, nbuf) != nbuf)
- goto Error;
- close(dfd);
- snprint(path, sizeof(path), "%s/%s", dir, "body");
- if((dfd = open(path, OREAD|OCEXEC)) == -1)
- goto Error;
- if(h != nil){
- snprint(path, sizeof(path), "%s/%s", dir, h->name);
- if((hfd = open(path, OREAD|OCEXEC)) == -1)
- goto Error;
- if((h->val = slurp(hfd, &h->nval)) == nil)
- goto Error;
- }
- if((r = slurp(dfd, nret)) == nil)
- goto Error;
- ok = 1;
-Error:
- if(hfd != -1) close(hfd);
- if(dfd != -1) close(dfd);
- if(cfd != -1) close(cfd);
- if(!ok && h != nil){
- free(h->val);
- h->val = nil;
- h->nval = 0;
- }
- return r;
-}
-
-static int
-endpoints(void)
-{
- JSON *j;
- JSONEl *e;
- char *s;
- int n;
-
- if((s = get(provider, &n)) == nil)
- sysfatal("get %s: %r", provider);
- if((j = jsonparse(s)) == nil)
- sysfatal("parse endpoints: %r");
- if(j->t != JSONObject)
- sysfatal("expected object");
- for(e = j->first; e != nil; e = e->next){
- if(e->val->t != JSONString)
- continue;
- if(strcmp(e->name, "keyChange") == 0)
- epkeychange = strdup(e->val->s);
- else if(strcmp(e->name, "newAccount") == 0)
- epnewacct = strdup(e->val->s);
- else if(strcmp(e->name, "newNonce") == 0)
- epnewnonce = strdup(e->val->s);
- else if(strcmp(e->name, "newOrder") == 0)
- epneworder = strdup(e->val->s);
- else if(strcmp(e->name, "revokeCert") == 0)
- eprevokecert = strdup(e->val->s);
- }
- jsonfree(j);
- free(s);
- if(epnewnonce==nil|| epnewacct==nil || epneworder==nil
- || eprevokecert==nil || epkeychange==nil){
- sysfatal("missing directory entries");
- return -1;
- }
- return 0;
-}
-
-static char*
-getnonce(void)
-{
- char *r, dir[64], path[80];
- int n, cfd, dfd, hfd;
-
- r = nil;
- dfd = -1;
- hfd = -1;
- if((cfd = webopen(epnewnonce, dir, sizeof(dir))) == -1)
- goto Error;
- fprint(cfd, "request HEAD");
-
- snprint(path, sizeof(path), "%s/%s", dir, "body");
- if((dfd = open(path, OREAD|OCEXEC)) == -1)
- goto Error;
- snprint(path, sizeof(path), "%s/%s", dir, "replaynonce");
- if((hfd = open(path, OREAD|OCEXEC)) == -1)
- goto Error;
- r = slurp(hfd, &n);
-Error:
- if(hfd != -1)
- close(hfd);
- if(dfd != -1)
- close(dfd);
- close(cfd);
- return r;
-}
-
-char*
-jwsenc(char *hdr, char *msg, int *nbuf)
-{
- char *h, *m, *s, *r;
-
- h = encurl64(hdr, strlen(hdr));
- m = encurl64(msg, strlen(msg));
- s = signRS256(h, m);
- if(s == nil)
- return nil;
-
- r = esmprint(
- "{\n"
- "\"protected\": \"%s\",\n"
- "\"payload\": \"%s\",\n"
- "\"signature\": \"%s\"\n"
- "}\n",
- h, m, s);
- *nbuf = strlen(r);
- free(h);
- free(m);
- free(s);
-
- return r;
-}
-
-char*
-jwsheader(char *url)
-{
- char *nonce;
-
- if((nonce = getnonce()) == nil)
- sysfatal("get nonce: %r");
- return esmprint(
- "{"
- "\"alg\": \"RS256\","
- "\"nonce\": \"%E\","
- "\"kid\": \"%E\","
- "\"url\": \"%E\""
- "}",
- nonce, keyid, url);
-}
-
-char*
-jwsrequest(char *url, int *nresp, Hdr *h, char *fmt, ...)
-{
- char *hdr, *msg, *req, *resp;
- int nreq;
- va_list ap;
-
- va_start(ap, fmt);
- hdr = jwsheader(url);
- msg = evsmprint(fmt, ap);
- req = jwsenc(hdr, msg, &nreq);
- dprint("req=\"%s\"\n", req);
- resp = post(url, req, nreq, nresp, h);
- free(hdr);
- free(req);
- free(msg);
- va_end(ap);
- dprint("resp=%s\n", resp);
- return resp;
-}
-
-static void
-mkaccount(char *addr)
-{
- char *nonce, *hdr, *msg, *req, *resp;
- int nreq, nresp;
- Hdr loc = { "location" };
-
- if((nonce = getnonce()) == nil)
- sysfatal("get nonce: %r");
- hdr = esmprint(
- "{"
- "\"alg\": \"RS256\","
- "\"jwk\": %J,"
- "\"nonce\": \"%E\","
- "\"url\": \"%E\""
- "}",
- jwskey, nonce, epnewacct);
- msg = esmprint(
- "{"
- "\"termsOfServiceAgreed\": true,"
- "\"contact\": [\"mailto:%E\"]"
- "}",
- addr);
- free(nonce);
- if((req = jwsenc(hdr, msg, &nreq)) == nil)
- sysfatal("failed to sign: %r");
- dprint("req=\"%s\"\n", req);
-
- if((resp = post(epnewacct, req, nreq, &nresp, &loc)) == nil)
- sysfatal("failed req: %r");
- dprint("resp=%s, loc=%s\n", resp, loc.val);
- keyid = loc.val;
-}
-
-static JSON*
-submitorder(char **dom, int ndom, Hdr *hdr)
-{
- char *req, *resp, *sep, rbuf[8192];
- int nresp, i;
- JSON *r;
-
- sep = "";
- req = seprint(rbuf, rbuf+sizeof(rbuf),
- "{"
- " \"identifiers\": [");
- for(i = 0; i < ndom; i++){
- req = seprint(req, rbuf+sizeof(rbuf),
- "%s{"
- " \"type\": \"dns\","
- " \"value\": \"%E\""
- "}",
- sep, dom[i]);
- sep = ",";
- }
- req = seprint(req, rbuf+sizeof(rbuf),
- " ],"
- " \"wildcard\": false"
- "}");
- if(req - rbuf < 2)
- sysfatal("truncated order");
- resp = jwsrequest(epneworder, &nresp, hdr, "%s", rbuf);
- if(resp == nil)
- sysfatal("submit order: %r");
- if((r = jsonparse(resp)) == nil)
- sysfatal("parse order: %r");
- free(resp);
- return r;
-}
-
-static void
-hashauthbuf(char *buf, int nbuf)
-{
- uchar hash[SHA2_256dlen];
- char *enc;
-
- sha2_256((uchar*)buf, strlen(buf), hash, nil);
- if((enc = encurl64(hash, sizeof(hash))) == nil)
- sysfatal("hashbuf: %r");
- if(snprint(buf, nbuf, "%s", enc) != strlen(enc))
- sysfatal("hashbuf: buffer too small, truncated");
- free(enc);
-}
-
-static int
-runchallenge(char *ty, char *dom, char *tok, int *matched)
-{
- char auth[1024];
- Waitmsg *w;
- int pid;
-
- snprint(auth, sizeof(auth), "%s.%s", tok, jwsthumb);
- if(strcmp(ty, "dns-01") == 0)
- hashauthbuf(auth, sizeof(auth));
-
- pid = fork();
- switch(pid){
- case -1:
- return -1;
- case 0:
- dup(1, 2);
- execl(challengecmd, challengecmd, ty, dom, tok, auth, nil);
- sysfatal("%s: %r", challengecmd);
- }
-
- while((w = wait()) != nil){
- if(w->pid != pid){
- free(w);
- continue;
- }
- if(w->msg[0] == '\0'){
- free(w);
- *matched = 1;
- return 0;
- }
- werrstr("%s", w->msg);
- free(w);
- return -1;
- }
- return -1;
-}
-
-static int
-httpchallenge(char *ty, char *, char *tok, int *matched)
-{
- char path[1024];
- int fd, r;
-
- if(strcmp(ty, "http-01") != 0)
- return -1;
- *matched = 1;
-
- snprint(path, sizeof(path), "%s/%s", challengeout, tok);
- if((fd = create(path, OWRITE|OCEXEC, 0666)) == -1)
- return -1;
- r = fprint(fd, "%s.%s\n", tok, jwsthumb);
- close(fd);
- return r;
-}
-
-static int
-dnschallenge(char *ty, char *dom, char *tok, int *matched)
-{
- char auth[1024];
- int fd;
-
- if(strcmp(ty, "dns-01") != 0)
- return -1;
- *matched = 1;
-
- snprint(auth, sizeof(auth), "%s.%s", tok, jwsthumb);
- hashauthbuf(auth, sizeof(auth));
-
- if((fd = create(challengeout, OWRITE|OCEXEC, 0666)) == -1){
- werrstr("could not create challenge: %r");
- return -1;
- }
- if(fprint(fd,"dom=_acme-challenge.%s soa=\n\ttxt=\"%s\"\n", dom, auth) == -1){
- werrstr("could not write challenge: %r");
- close(fd);
- return -1;
- }
- close(fd);
-
- if((fd = open("/net/dns", OWRITE|OCEXEC)) == -1){
- werrstr("could not open dns ctl: %r");
- return -1;
- }
- if(fprint(fd, "refresh") == -1){
- werrstr("could not write dns refresh: %r");
- close(fd);
- return -1;
- }
- close(fd);
-
- return 0;
-}
-
-static int
-challenge(JSON *j, char *authurl, JSON *id, char *dom[], int ndom, int *matched)
-{
- JSON *dn, *ty, *url, *tok, *poll, *state;
- char *resp;
- int i, nresp;
-
- if((dn = jsonbyname(id, "value")) == nil)
- return -1;
- if(dn->t != JSONString)
- return -1;
-
- /* make sure the identifier matches the csr */
- for(i = 0; i < ndom; i++){
- if(cistrcmp(dom[i], dn->s) == 0)
- break;
- }
- if(i >= ndom){
- werrstr("unknown challenge identifier '%s'", dn->s);
- return -1;
- }
-
- if((ty = jsonbyname(j, "type")) == nil)
- return -1;
- if((url = jsonbyname(j, "url")) == nil)
- return -1;
- if((tok = jsonbyname(j, "token")) == nil)
- return -1;
-
- if(ty->t != JSONString || url->t != JSONString || tok->t != JSONString)
- return -1;
-
- dprint("trying challenge %s\n", ty->s);
- if(challengefn(ty->s, dn->s, tok->s, matched) == -1){
- dprint("challengefn failed: %r\n");
- return -1;
- }
-
- if((resp = jwsrequest(url->s, &nresp, nil, "{}")) == nil)
- sysfatal("challenge: post %s: %r", url->s);
- free(resp);
-
- for(i = 0; i < 60; i++){
- sleep(1000);
- if((resp = jwsrequest(authurl, &nresp, nil, "")) == nil)
- sysfatal("challenge: post %s: %r", url->s);
- if((poll = jsonparse(resp)) == nil){
- free(resp);
- return -1;
- }
- if((state = jsonbyname(poll, "status")) != nil && state->t == JSONString){
- if(strcmp(state->s, "valid") == 0){
- jsonfree(poll);
- return 0;
- }
- else if(strcmp(state->s, "pending") != 0){
- fprint(2, "error: %J", poll);
- werrstr("status '%s'", state->s);
- jsonfree(poll);
- return -1;
- }
- }
- jsonfree(poll);
- }
- werrstr("timeout");
- return -1;
-}
-
-static int
-dochallenges(char *dom[], int ndom, JSON *order)
-{
- JSON *chals, *j, *cl, *id;
- JSONEl *ae, *ce;
- int nresp, matched;
- char *resp;
-
- if((j = jsonbyname(order, "authorizations")) == nil){
- werrstr("parse response: missing authorizations");
- return -1;
- }
- if(j->t != JSONArray){
- werrstr("parse response: authorizations must be array");
- return -1;
- }
- for(ae = j->first; ae != nil; ae = ae->next){
- if(ae->val->t != JSONString){
- werrstr("challenge: auth must be url");
- return -1;
- }
- if((resp = jwsrequest(ae->val->s, &nresp, nil, "")) == nil){
- werrstr("challenge: request %s: %r", ae->val->s);
- return -1;
- }
- if((chals = jsonparse(resp)) == nil){
- werrstr("invalid challenge: %r");
- return -1;
- }
- if((id = jsonbyname(chals, "identifier")) == nil){
- werrstr("missing identifier");
- jsonfree(chals);
- return -1;
- }
- if((cl = jsonbyname(chals, "challenges")) == nil){
- werrstr("missing challenge");
- jsonfree(chals);
- return -1;
- }
- matched = 0;
- for(ce = cl->first; ce != nil; ce = ce->next){
- if(challenge(ce->val, ae->val->s, id, dom, ndom, &matched) == 0)
- break;
- if(matched)
- werrstr("could not complete challenge: %r");
- }
- if(!matched)
- sysfatal("no matching auth type");
- jsonfree(chals);
- free(resp);
- }
- return 0;
-}
-
-static int
-submitcsr(JSON *order, char *b64csr)
-{
- char *resp;
- int nresp;
- JSON *j;
-
- if((j = jsonbyname(order, "finalize")) == nil)
- sysfatal("parse response: missing authorizations");
- if(j->t != JSONString)
- werrstr("parse response: finalizer must be string");
- if((resp = jwsrequest(j->s, &nresp, nil, "{\"csr\":\"%E\"}", b64csr)) == nil)
- sysfatal("submit csr: %r");
- free(resp);
- return 0;
-}
-
-static int
-fetchcert(char *url)
-{
- JSON *cert, *poll, *state;
- int i, r, nresp;
- char *resp;
-
- poll = nil;
- for(i = 0; i < 60; i++){
- sleep(1000);
- if((resp = jwsrequest(url, &nresp, nil, "")) == nil)
- return -1;
- if((poll = jsonparse(resp)) == nil){
- free(resp);
- return -1;
- }
- free(resp);
- if((state = jsonbyname(poll, "status")) != nil && state->t == JSONString){
- if(strcmp(state->s, "valid") == 0)
- break;
- else if(strcmp(state->s, "pending") != 0 && strcmp(state->s, "processing") != 0){
- fprint(2, "error: %J", poll);
- werrstr("invalid request: %s", state->s);
- jsonfree(poll);
- return -1;
-
- }
- }
- jsonfree(poll);
- }
- if(poll == nil){
- werrstr("timed out");
- return -1;
- }
- if((cert = jsonbyname(poll, "certificate")) == nil || cert->t != JSONString){
- werrstr("missing cert url in response");
- jsonfree(poll);
- return -1;
- }
- if((resp = jwsrequest(cert->s, &nresp, nil, "")) == nil){
- jsonfree(poll);
- return -1;
- }
- jsonfree(poll);
- r = write(1, resp, nresp);
- free(resp);
- if(r != nresp)
- return -1;
- return 0;
-}
-
-static void
-getcert(char *csrpath)
-{
- char *csr, *dom[64], name[2048];
- uchar *der;
- int nder, ndom, fd;
- RSApub *rsa;
- Hdr loc = { "location" };
- JSON *o;
-
- if((fd = open(csrpath, OREAD|OCEXEC)) == -1)
- sysfatal("open %s: %r", csrpath);
- if((der = slurp(fd, &nder)) == nil)
- sysfatal("read %s: %r", csrpath);
- if((rsa = X509reqtoRSApub(der, nder, name, sizeof(name))) == nil)
- sysfatal("decode csr: %r");
- if((csr = encurl64(der, nder)) == nil)
- sysfatal("encode %s: %r", csrpath);
- if((ndom = getfields(name, dom, nelem(dom), 1, ", ")) == nelem(dom))
- sysfatal("too man domains");
- rsapubfree(rsa);
- close(fd);
- free(der);
-
- if((o = submitorder(dom, ndom, &loc)) == nil)
- sysfatal("order: %r");
- if(dochallenges(dom, ndom, o) == -1)
- sysfatal("challenge: %r");
- if(submitcsr(o, csr) == -1)
- sysfatal("signing cert: %r");
- if(fetchcert(loc.val) == -1)
- sysfatal("saving cert: %r");
- free(csr);
-}
-
-static int
-Econv(Fmt *f)
-{
- char *s;
- Rune r;
- int w;
-
- w = 0;
- s = va_arg(f->args, char*);
- while(*s){
- s += chartorune(&r, s);
- if(r == '\\' || r == '\"')
- w += fmtrune(f, '\\');
- w += fmtrune(f, r);
- }
- return w;
-}
-
-static int
-loadkey(char *path)
-{
- uchar h[SHA2_256dlen];
- char key[8192];
- JSON *j, *e, *kty, *n;
- DigestState *ds;
- int fd, nr;
-
- if((fd = open(path, OREAD|OCEXEC)) == -1)
- return -1;
- nr = readn(fd, key, sizeof(key));
- close(fd);
- if(nr == -1)
- return -1;
- key[nr] = 0;
-
- if((j = jsonparse(key)) == nil)
- return -1;
- if((e = jsonbyname(j, "e")) == nil || e->t != JSONString)
- return -1;
- if((kty = jsonbyname(j, "kty")) == nil || kty->t != JSONString)
- return -1;
- if((n = jsonbyname(j, "n")) == nil || n->t != JSONString)
- return -1;
-
- ds = sha2_256((uchar*)"{\"e\":\"", 6, nil, nil);
- ds = sha2_256((uchar*)e->s, strlen(e->s), nil, ds);
- ds = sha2_256((uchar*)"\",\"kty\":\"", 9, nil, ds);
- ds = sha2_256((uchar*)kty->s, strlen(kty->s), nil, ds);
- ds = sha2_256((uchar*)"\",\"n\":\"", 7, nil, ds);
- ds = sha2_256((uchar*)n->s, strlen(n->s), nil, ds);
- sha2_256((uchar*)"\"}", 2, h, ds);
- jwskey = j;
- jwsthumb = encurl64(h, sizeof(h));
- return 0;
-}
-
-static void
-usage(void)
-{
- fprint(2, "usage: %s [-a acctkey] [-e cmd | -o chalout -t type] [-p provider] acct csr\n", argv0);
- exits("usage");
-}
-
-void
-main(int argc, char **argv)
-{
- char *acctkey, *ct, *co;
-
- JSONfmtinstall();
- fmtinstall('E', Econv);
-
- ct = nil;
- co = nil;
- acctkey = nil;
- ARGBEGIN{
- case 'd':
- debug++;
- break;
- case 'a':
- acctkey = EARGF(usage());
- break;
- case 'e':
- challengecmd = EARGF(usage());
- break;
- case 'o':
- co = EARGF(usage());
- break;
- case 't':
- ct = EARGF(usage());
- break;
- case 'p':
- provider = EARGF(usage());
- break;
- default:
- usage();
- break;
- }ARGEND;
-
- if(challengecmd != nil){
- if(ct != nil || co != nil)
- usage();
- challengeout = "/dev/null";
- challengefn = runchallenge;
- }else if(ct == nil || strcmp(ct, "http") == 0){
- challengeout = (co != nil) ? co : "/usr/web/.well-known/acme-challenge";
- challengefn = httpchallenge;
- }else if(strcmp(ct, "dns") == 0){
- challengeout = (co != nil) ? co : "/lib/ndb/dnschallenge";
- challengefn = dnschallenge;
- }else {
- sysfatal("unknown challenge type '%s'", ct);
- }
-
- if(argc != 2)
- usage();
-
- if(acctkey == nil)
- acctkey = esmprint("/sys/lib/tls/acmed/%s.pub", argv[0]);
- if((keyspec = smprint(Keyspec, argv[0])) == nil)
- sysfatal("smprint: %r");
- if(loadkey(acctkey) == -1)
- sysfatal("load key: %r");
-
- if(endpoints() == -1)
- sysfatal("endpoints: %r");
- mkaccount(argv[0]);
- getcert(argv[1]);
- exits(nil);
-}
diff --git a/sys/src/cmd/ktrans/main.c b/sys/src/cmd/ktrans/main.c
index 6c702c1e6..dbcd6dd17 100644
--- a/sys/src/cmd/ktrans/main.c
+++ b/sys/src/cmd/ktrans/main.c
@@ -2,6 +2,7 @@
#include <libc.h>
#include <ctype.h>
#include <bio.h>
+#include <plumb.h>
#include <thread.h>
#include "hash.h"
@@ -275,32 +276,28 @@ maplkup(int lang, char *s, Map *m)
return hmapget(*h, s, m);
}
-typedef struct Msg Msg;
-struct Msg {
- char code;
- char buf[64];
-};
-static Channel *dictch;
-static Channel *output;
-static Channel *input;
-static char backspace[64];
+enum { Msgsize = 64 };
+static Channel *dictch;
+static Channel *output;
+static Channel *input;
+static char backspace[Msgsize];
static int
emitutf(Channel *out, char *u, int nrune)
{
- Msg m;
+ char b[Msgsize];
char *e;
- m.code = 'c';
- e = pushutf(m.buf, m.buf + sizeof m.buf, u, nrune);
- send(out, &m);
- return e - m.buf;
+ b[0] = 'c';
+ e = pushutf(b+1, b + Msgsize - 1, u, nrune);
+ send(out, b);
+ return e - b;
}
static void
dictthread(void*)
{
- Msg m;
+ char m[Msgsize];
Rune r;
int n;
char *p;
@@ -325,8 +322,8 @@ dictthread(void*)
resetstr(&last, &line, &okuri, nil);
threadsetname("dict");
- while(recv(dictch, &m) != -1){
- for(p = m.buf; *p; p += n){
+ while(recv(dictch, m) != -1){
+ for(p = m+1; *p; p += n){
n = chartorune(&r, p);
if(r != ''){
if(selected >= 0){
@@ -441,7 +438,7 @@ dictthread(void*)
}
}
-int
+static int
telexlkup(Str *line, Str *out)
{
Map lkup;
@@ -454,7 +451,6 @@ telexlkup(Str *line, Str *out)
if(hmapget(telex, buf, &lkup) < 0)
return -1;
- assert(lkup.leadstomore == 1);
if(utflen(line->b) < 2)
return 2;
@@ -480,34 +476,32 @@ static void
keythread(void*)
{
int lang;
- Msg m;
+ char m[Msgsize];
Map lkup;
char *p;
int n, ln, rn;
Rune r;
char peek[UTFmax+1];
Str line, tbuf;
- int mode;
- mode = 0;
peek[0] = lang = deflang;
resetstr(&line, nil);
if(lang == LangJP || lang == LangZH)
emitutf(dictch, peek, 1);
threadsetname("keytrans");
- while(recv(input, &m) != -1){
- if(m.code == 'z'){
+ while(recv(input, m) != -1){
+ if(m[0] == 'z'){
emitutf(dictch, " ", 1);
resetstr(&line, nil);
continue;
}
- if(m.code != 'c'){
- send(output, &m);
+ if(m[0] != 'c'){
+ send(output, m);
continue;
}
- for(p = m.buf; *p; p += n){
+ for(p = m+1; *p; p += n){
n = chartorune(&r, p);
if(checklang(&lang, r)){
emitutf(dictch, " ", 1);
@@ -527,12 +521,8 @@ keythread(void*)
resetstr(&line, nil);
continue;
}
- if(lang == LangJP && isupper(*p)){
+ if(lang == LangJP && isupper(*p))
*p = tolower(*p);
- mode++;
- } else {
- mode = 0;
- }
}
emitutf(output, p, 1);
@@ -590,62 +580,95 @@ keythread(void*)
static int kbdin;
static int kbdout;
-void
+static void
kbdtap(void*)
{
- Msg msg;
+ char m[Msgsize];
char buf[128];
char *p, *e;
int n;
threadsetname("kbdtap");
for(;;){
-Drop:
+ Drop:
n = read(kbdin, buf, sizeof buf);
if(n < 0)
break;
for(p = buf; p < buf+n;){
- msg.code = p[0];
- p++;
- switch(msg.code){
+ switch(*p){
case 'c': case 'k': case 'K':
case 'z':
break;
default:
goto Drop;
}
- e = utfecpy(msg.buf, msg.buf + sizeof msg.buf, p);
- p += e - msg.buf;
+ *m = *p++;
+ e = utfecpy(m+1, m + Msgsize - 1, p);
+ p += e - m;
p++;
- if(send(input, &msg) == -1)
+ if(send(input, m) == -1)
return;
}
}
}
-void
+static void
kbdsink(void*)
{
- Msg m;
+ char in[Msgsize];
+ char out[Msgsize];
char *p;
+ int n;
Rune rn;
+ out[0] = 'c';
threadsetname("kbdsink");
- while(recv(output, &m) != -1){
- if(m.code != 'c'){
- fprint(kbdout, "%c%s", m.code, m.buf);
+ while(recv(output, in) != -1){
+ if(in[0] != 'c'){
+ if(write(kbdout, in, strlen(in)+1) < 0)
+ break;
continue;
}
- p = m.buf;
- for(;;){
- p += chartorune(&rn, p);
+
+ for(p = in+1; *p; p += n){
+ n = chartorune(&rn, p);
if(rn == Runeerror || rn == '\0')
break;
- fprint(kbdout, "c%C", rn);
+ memmove(out+1, p, n);
+ out[1+n] = '\0';
+ if(write(kbdout, out, 1+n+1) < 0)
+ break;
}
}
}
+static int plumbfd;
+
+static void
+plumbproc(void*)
+{
+ char m[Msgsize];
+ Plumbmsg *p;
+
+ threadsetname("plumbproc");
+ for(; p = plumbrecv(plumbfd); plumbfree(p)){
+ if(p->ndata > sizeof m - 1)
+ continue;
+ memmove(m, p->data, p->ndata);
+ m[p->ndata] = '\0';
+
+ m[1] = parselang(m);
+ if(m[1] == -1)
+ continue;
+ m[0] = 'c';
+ m[2] = '\0';
+
+ if(send(input, m) == -1)
+ break;
+ }
+ plumbfree(p);
+}
+
void
usage(void)
{
@@ -704,9 +727,13 @@ threadmain(int argc, char *argv[])
hangul = openmap("/lib/ktrans/hangul.map");
telex = openmap("/lib/ktrans/telex.map");
- dictch = chancreate(sizeof(Msg), 0);
- input = chancreate(sizeof(Msg), 0);
- output = chancreate(sizeof(Msg), 0);
+ dictch = chancreate(Msgsize, 0);
+ input = chancreate(Msgsize, 0);
+ output = chancreate(Msgsize, 0);
+
+ plumbfd = plumbopen("lang", OREAD);
+ if(plumbfd >= 0)
+ proccreate(plumbproc, nil, mainstacksize);
proccreate(kbdtap, nil, mainstacksize);
proccreate(kbdsink, nil, mainstacksize);
diff --git a/sys/src/cmd/nusb/disk/disk.c b/sys/src/cmd/nusb/disk/disk.c
index 196894cfe..2fb8fc324 100644
--- a/sys/src/cmd/nusb/disk/disk.c
+++ b/sys/src/cmd/nusb/disk/disk.c
@@ -155,10 +155,10 @@ ctlstring(Umsc *lun)
part = &lun->part[0];
fmtstrinit(&fmt);
- fmtprint(&fmt, "dev %s\n", dev->dir);
- fmtprint(&fmt, "lun %zd\n", lun - &ums->lun[0]);
if(lun->flags & Finqok)
fmtprint(&fmt, "inquiry %s\n", lun->inq);
+ fmtprint(&fmt, "dev %s\n", dev->dir);
+ fmtprint(&fmt, "lun %zd\n", lun - &ums->lun[0]);
if(lun->blocks > 0)
fmtprint(&fmt, "geometry %llud %ld\n", lun->blocks, lun->lbsize);
for (p = &part[Qdata+1]; p < &part[Qmax]; p++)
diff --git a/sys/src/cmd/nusb/kb/hid.h b/sys/src/cmd/nusb/kb/hid.h
index 10e614f4b..5c51250aa 100644
--- a/sys/src/cmd/nusb/kb/hid.h
+++ b/sys/src/cmd/nusb/kb/hid.h
@@ -4,6 +4,7 @@
enum {
Stack = 32 * 1024,
+ Nkey = 64,
/* HID class subclass protocol ids */
PtrCSP = 0x020103, /* mouse.boot.hid */
diff --git a/sys/src/cmd/nusb/kb/kb.c b/sys/src/cmd/nusb/kb/kb.c
index e748c9268..5a7b8ee5e 100644
--- a/sys/src/cmd/nusb/kb/kb.c
+++ b/sys/src/cmd/nusb/kb/kb.c
@@ -13,21 +13,21 @@
#include <u.h>
#include <libc.h>
+#include <ctype.h>
+#include <fcall.h>
#include <thread.h>
+#include <9p.h>
#include "usb.h"
#include "hid.h"
enum
{
- Awakemsg=0xdeaddead,
+ Awakemsg = 0xdeaddead,
Diemsg = 0xbeefbeef,
+ Rawon = 0x0defaced,
};
-enum
-{
- Kbdelay = 500,
- Kbrepeat = 100,
-};
+char user[] = "kb";
typedef struct Hiddev Hiddev;
struct Hiddev
@@ -78,7 +78,7 @@ struct Hidreport
Hidslot s[16];
int nk;
- uchar k[64];
+ ushort k[Nkey];
int o;
uchar *e;
@@ -92,6 +92,7 @@ enum {
/* Scan codes (see kbd.c) */
SCesc1 = 0xe0, /* first of a 2-character sequence */
SCesc2 = 0xe1,
+ Consumer = 0x100, /* the key is on consumer page */
Keyup = 0x80, /* flag bit */
Keymask = 0x7f, /* regular scan code bits */
};
@@ -101,12 +102,12 @@ enum {
*/
#define isext(sc) ((sc) >= 0x80)
+static char sctab[2*256] =
+{
/*
* key code to scan code; for the page table used by
* the logitech bluetooth keyboard.
*/
-static char sctab[256] =
-{
[0x00] 0x0, 0x0, 0x0, 0x0, 0x1e, 0x30, 0x2e, 0x20,
[0x08] 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26,
[0x10] 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14,
@@ -124,7 +125,7 @@ static char sctab[256] =
[0x70] 0xf8, 0xf9, 0xfa, 0xfb, 0x0, 0x0, 0x0, 0x0,
[0x78] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf1,
[0x80] 0xf3, 0xf2, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x0,
-[0x88] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x88] 0x70, 0x0, 0x79, 0x7b, 0x0, 0x0, 0x0, 0x0,
[0x90] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
[0x98] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
[0xa0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
@@ -135,10 +136,43 @@ static char sctab[256] =
[0xc8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
[0xd0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
[0xd8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-[0xe0] 0x1d, 0x2a, 0x38, 0xdb, 0xe1, 0x36, 0xb8, 0xfe,
+[0xe0] 0x1d, 0x2a, 0x38, 0xdb, 0x9d, 0x36, 0xb8, 0xfe,
[0xe8] 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, 0xf2, 0xf1,
[0xf0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
[0xf8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+/* consumer page to scan code */
+[0x100] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x108] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x110] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x118] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x120] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x128] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x130] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x138] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x140] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x148] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x150] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x158] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x160] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x168] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9a,
+[0x170] 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x178] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x180] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x188] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x190] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x198] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x1a0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x1a8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x1b0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x99, 0x90, 0x0,
+[0x1b8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x1c0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x1c8] 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0,
+[0x1d0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x1d8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x1e0] 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x1e8] 0x0, 0xb0, 0xae, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x1f0] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+[0x1f8] 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
};
static uchar kbdbootrep[] = {
@@ -165,6 +199,9 @@ static uchar ptrbootrep[] = {
};
static int debug = 0;
+static int kbdelay = 500;
+static int kbrepeat = 100;
+static int havekbd;
static int
signext(int v, int bits)
@@ -377,12 +414,6 @@ setproto(Hiddev *f, Iface *iface)
return usbcmd(f->dev, Rh2d|Rclass|Riface, Setproto, proto, iface->id, nil, 0);
}
-static int
-setleds(Hiddev* f, int, uchar leds)
-{
- return usbcmd(f->dev, Rh2d|Rclass|Riface, Setreport, Reportout, 0, &leds, 1);
-}
-
static void
hdfree(Hiddev *f)
{
@@ -498,9 +529,9 @@ repeatproc(void* arg)
continue;
}
sc = l & 0xff;
- t = Kbdelay;
+ t = kbdelay;
if(alt(a) == 1){
- t = Kbrepeat;
+ t = kbrepeat;
while(alt(a) == 1)
putscan(f, sc, 0);
}
@@ -528,7 +559,7 @@ hidparse(int t, int f, int g[], int l[], int, void *a)
{
Hidreport *p = a;
Hidslot *s = &p->s[p->ns];
- int v, m;
+ int v, m, cp;
switch(t){
case Input:
@@ -571,11 +602,11 @@ hidparse(int t, int f, int g[], int l[], int, void *a)
if(debug > 1)
fprint(2, "hidparse: t=%x f=%x usage=%x v=%x\n", t, f, l[Usage], v);
- if((l[Usage]>>16) == 0x07){ /* keycode */
+ if((cp = ((l[Usage]>>16) == 0x0c)) || (l[Usage]>>16) == 0x07){ /* consumer/keycode */
if((f & (Fvar|Farray)) == Fvar)
if(v != 0) v = l[Usage] & 0xFF;
if(p->nk < nelem(p->k) && v != 0)
- p->k[p->nk++] = v;
+ p->k[p->nk++] = v | cp*Consumer;
return;
}
@@ -677,12 +708,23 @@ sethipri(void)
close(fd);
}
+static ushort *
+keykey(ushort *a, ushort k, int n)
+{
+ while(n > 0){
+ if(*a++ == k)
+ return a-1;
+ n--;
+ }
+ return nil;
+}
+
static void
readerproc(void* a)
{
char err[ERRMAX], mbuf[80];
- uchar lastk[64], uk, dk;
- int i, c, nerrs, bpress, lastb, nlastk;
+ ushort lastk[Nkey], uks[Nkey], dks[Nkey], nuks, ndks;
+ int i, c, nerrs, bpress, lastb, nlastk, stopped;
int abs, x, y, z, b;
Hidreport p;
Hidslot lasts[nelem(p.s)], *s, *l;
@@ -730,7 +772,7 @@ readerproc(void* a)
if(debug){
fprint(2, "kbd: ");
for(i = 0; i < p.nk; i++)
- fprint(2, "%#2.2ux ", p.k[i]);
+ fprint(2, "%#4.4ux ", p.k[i]);
fprint(2, "\n");
}
@@ -745,25 +787,36 @@ readerproc(void* a)
proccreate(repeatproc, f, Stack);
}
- dk = uk = 0;
- for(i=0; i<nlastk; i++){
- if(memchr(p.k, lastk[i], p.nk) == nil){
- uk = sctab[lastk[i]];
- putscan(f, uk, Keyup);
- }
+ /* collect key presses/releases */
+ for(i=nuks=0; i<nlastk; i++){
+ if(keykey(p.k, lastk[i], p.nk) == nil)
+ uks[nuks++] = sctab[lastk[i]];
}
- for(i=0; i<p.nk; i++){
- if(memchr(lastk, p.k[i], nlastk) == nil){
- dk = sctab[p.k[i]];
- putscan(f, dk, 0);
+ for(i=ndks=0; i<p.nk; i++){
+ if(keykey(lastk, p.k[i], nlastk) == nil)
+ dks[ndks++] = sctab[p.k[i]];
+ }
+
+ /*
+ * stop the repeats first to avoid race condition when
+ * the key is released but the repeat happens right after
+ */
+ for(stopped = i = 0; i < nuks; i++){
+ if(ndks == 0 || keykey(dks, uks[i], ndks) != nil){
+ stoprepeat(f);
+ stopped = 1;
+ break;
}
}
- if(uk != 0 && (dk == 0 || dk == uk))
- stoprepeat(f);
- else if(dk != 0)
- startrepeat(f, dk);
+ for(i = 0; i < nuks; i++)
+ putscan(f, uks[i], Keyup);
+ for(i = 0; i < ndks; i++)
+ putscan(f, dks[i], 0);
+
+ if(stopped == 0 && ndks > 0)
+ startrepeat(f, dks[ndks-1]);
- memmove(lastk, p.k, nlastk = p.nk);
+ memmove(lastk, p.k, (nlastk = p.nk)*sizeof(lastk[0]));
p.nk = 0;
}
@@ -871,7 +924,7 @@ quirks(Hiddev *f)
}
}
-static void
+static int
hdsetup(Dev *d, Ep *ep)
{
Hiddev *f;
@@ -896,12 +949,71 @@ hdsetup(Dev *d, Ep *ep)
}
quirks(f);
procrfork(readerproc, f, Stack, RFNOTEG);
- return;
+ return 0;
Err:
hdfree(f);
+ return -1;
+}
+
+static void
+fsread(Req *r)
+{
+ char msg[48], *s, *e;
+
+ s = msg;
+ e = msg+sizeof(msg);
+ *s = 0;
+ if(havekbd)
+ e = seprint(s, e, "repeat %d\ndelay %d\n", kbrepeat, kbdelay);
+ USED(e);
+ readstr(r, msg);
+ respond(r, nil);
}
static void
+fswrite(Req *r)
+{
+ char msg[256], *f[4];
+ void *data;
+ int nf, sz;
+ Dev *dev;
+
+ dev = r->fid->file->aux;
+ data = r->ifcall.data;
+ sz = r->ifcall.count;
+ if(r->fid->aux == (void*)Rawon){
+ if(sz == 6 && memcmp(data, "rawoff", 6) == 0)
+ r->fid->aux = nil;
+ else if(usbcmd(dev, Rh2d|Rclass|Riface, Setreport, Reportout, 0, data, sz) < 0){
+ responderror(r);
+ return;
+ }
+ }else{
+ snprint(msg, sizeof(msg), "%.*s", utfnlen(data, sz), data);
+ nf = tokenize(msg, f, nelem(f));
+ if(nf == 1 && strcmp(f[0], "rawon") == 0)
+ r->fid->aux = (void*)Rawon;
+ else if(nf == 2 && strcmp(f[0], "repeat") == 0)
+ kbrepeat = atoi(f[1]);
+ else if(nf == 2 && strcmp(f[0], "delay") == 0)
+ kbdelay = atoi(f[1]);
+ else if(nf == 2 && strcmp(f[0], "debug") == 0)
+ debug = atoi(f[1]);
+ else{
+ respond(r, "invalid ctl message");
+ return;
+ }
+ }
+ r->ofcall.count = sz;
+ respond(r, nil);
+}
+
+static Srv fs = {
+ .read = fsread,
+ .write = fswrite,
+};
+
+static void
usage(void)
{
fprint(2, "usage: %s [-d] devid\n", argv0);
@@ -911,10 +1023,11 @@ usage(void)
void
threadmain(int argc, char* argv[])
{
- int i;
+ int i, n;
Dev *d;
Ep *ep;
Usbdev *ud;
+ char buf[32];
ARGBEGIN{
case 'd':
@@ -929,20 +1042,28 @@ threadmain(int argc, char* argv[])
if(d == nil)
sysfatal("getdev: %r");
ud = d->usb;
- for(i = 0; i < nelem(ud->ep); i++){
+ for(i = n = 0; i < nelem(ud->ep); i++){
if((ep = ud->ep[i]) == nil)
continue;
if(ep->type != Eintr || ep->dir != Ein)
continue;
switch(ep->iface->csp){
case KbdCSP:
+ havekbd = 1;
case PtrCSP:
case PtrNonBootCSP:
case HidCSP:
- hdsetup(d, ep);
+ n += hdsetup(d, ep) == 0;
break;
}
}
closedev(d);
+ if(n > 0){
+ fs.tree = alloctree(user, "usb", DMDIR|0555, nil);
+ snprint(buf, sizeof buf, "hidU%sctl", d->hname);
+ createfile(fs.tree->root, buf, user, 0666, d);
+ snprint(buf, sizeof buf, "%s.hid", d->hname);
+ threadpostsharesrv(&fs, nil, "usb", buf);
+ }
threadexits(nil);
}
diff --git a/sys/src/cmd/patch.c b/sys/src/cmd/patch.c
index 8e402bba8..5d882150b 100644
--- a/sys/src/cmd/patch.c
+++ b/sys/src/cmd/patch.c
@@ -393,12 +393,11 @@ blat(char *old, char *new, char *o, usize len)
char *tmp;
int fd;
- if(strcmp(new, "/dev/null") == 0 && len != 0){
- sysfatal("diff modifies removed file");
- return;
- }
tmp = nil;
- if(!dryrun){
+ if(strcmp(new, "/dev/null") == 0){
+ if(len != 0)
+ sysfatal("diff modifies removed file");
+ }else if(!dryrun){
if(mkpath(new) == -1)
sysfatal("mkpath %s: %r", new);
if((tmp = smprint("%s.tmp%d", new, getpid())) == nil)
@@ -428,7 +427,7 @@ finish(int ok)
for(i = 0; i < nchanged; i++){
c = &changed[i];
if(!ok){
- if(remove(c->tmp) == -1)
+ if(c->tmp != nil && remove(c->tmp) == -1)
fprint(2, "remove %s: %r\n", c->tmp);
goto Free;
}
@@ -460,7 +459,7 @@ Free:
free(changed);
}
-int
+void
slurp(Fbuf *f, char *path)
{
int n, i, fd, sz, len, nlines, linesz;
@@ -503,7 +502,6 @@ slurp(Fbuf *f, char *path)
f->lines = lines;
f->nlines = nlines;
f->lastln = -1;
- return 0;
}
char*
@@ -517,7 +515,7 @@ search(Fbuf *f, Hunk *h, char *fname)
for(fuzz = 0; scanning && fuzz <= nfuzz; fuzz++){
scanning = 0;
ln = h->oldln - fuzz;
- if(ln > f->lastln){
+ if(ln > f->lastln && ln < f->nlines){
off = f->lines[ln];
if(off + len > f->len)
continue;
@@ -527,8 +525,8 @@ search(Fbuf *f, Hunk *h, char *fname)
return f->buf + off;
}
}
- ln = h->oldln + fuzz - 1;
- if(ln <= f->nlines){
+ ln = h->oldln + fuzz + 1;
+ if(ln > f->lastln && ln < f->nlines){
off = f->lines[ln];
if(off + len >= f->len)
continue;
@@ -558,22 +556,35 @@ append(char *o, int *sz, char *s, char *e)
int
apply(Patch *p, char *fname)
{
- char *o, *s, *e, *curfile;
+ char *o, *s, *e, *curfile, *nextfile;
int i, osz;
- Hunk *h;
+ Hunk *h, *prevh;
Fbuf f;
e = nil;
o = nil;
osz = 0;
curfile = nil;
+ h = nil;
+ prevh = nil;
for(i = 0; i < p->nhunk; i++){
h = &p->hunk[i];
- if(curfile == nil || strcmp(curfile, h->newpath) != 0){
- if(!dryrun && slurp(&f, h->oldpath) == -1)
- sysfatal("slurp %s: %r", h->oldpath);
- curfile = h->newpath;
- e = f.buf;
+ if(strcmp(h->newpath, "/dev/null") == 0)
+ nextfile = h->oldpath;
+ else
+ nextfile = h->newpath;
+ if(curfile == nil || strcmp(curfile, nextfile) != 0){
+ if(curfile != nil){
+ if(!dryrun)
+ o = append(o, &osz, e, f.buf + f.len);
+ blat(prevh->oldpath, prevh->newpath, o, osz);
+ osz = 0;
+ }
+ if(!dryrun){
+ slurp(&f, h->oldpath);
+ e = f.buf;
+ }
+ curfile = nextfile;
}
if(!dryrun){
s = e;
@@ -582,11 +593,12 @@ apply(Patch *p, char *fname)
o = append(o, &osz, h->new, h->new + h->newlen);
e += h->oldlen;
}
- if(i+1 == p->nhunk || strcmp(curfile, p->hunk[i+1].newpath) != 0){
+ prevh = h;
+ }
+ if(curfile != nil){
+ if(!dryrun)
o = append(o, &osz, e, f.buf + f.len);
- blat(h->oldpath, h->newpath, o, osz);
- osz = 0;
- }
+ blat(h->oldpath, h->newpath, o, osz);
}
free(o);
return 0;
diff --git a/sys/src/cmd/reform/pm.c b/sys/src/cmd/reform/pm.c
index 27de4ac83..c6f609430 100644
--- a/sys/src/cmd/reform/pm.c
+++ b/sys/src/cmd/reform/pm.c
@@ -3,11 +3,14 @@
#include <fcall.h>
#include <thread.h>
#include <9p.h>
+#include <draw.h>
+#include <memdraw.h>
enum
{
Mhz = 1000*1000,
Pwmsrcclk = 25*Mhz,
+ Kbdlightmax = 8,
Scharge = 0,
Sovervolted,
@@ -22,8 +25,15 @@ enum
Light = 1,
Temp,
Battery,
+ Kbdoled,
Pmctl,
+ KbdoledW = 126,
+ KbdoledH = 32,
+
+ Lcd = 0,
+ Kbd,
+
PWMSAR = 0x0c/4,
PWMPR = 0x10/4,
@@ -68,9 +78,13 @@ enum
STAT_RR = 1<<3,
};
+static char *uid = "pm";
static Reqqueue *lpcreq;
static u32int *pwm2, *tmu, *spi2;
-static char *uid = "pm";
+static int kbdlight = 0;
+static int kbdhidfd = -1;
+static Memimage *kbdoled;
+static u8int kbdoledraw[4+KbdoledW*KbdoledH/8] = {'W', 'B', 'I', 'T', 0};
static void
wr(u32int *base, int reg, u32int v)
@@ -86,8 +100,96 @@ rd(u32int *base, int reg)
return base != nil ? base[reg] : -1;
}
-static void
-setlight(int p)
+static char *
+readall(int f)
+{
+ int bufsz, sz, n;
+ char *s;
+
+ bufsz = 2047;
+ s = nil;
+ for(sz = 0;; sz += n){
+ if(bufsz-sz < 2048){
+ bufsz *= 2;
+ s = realloc(s, bufsz);
+ }
+ if((n = readn(f, s+sz, bufsz-sz-1)) < 1)
+ break;
+ }
+ if(n < 0 || sz < 1){
+ if(n == 0)
+ werrstr("empty");
+ free(s);
+ return nil;
+ }
+ s[sz] = 0;
+
+ return s;
+}
+
+static int
+openkbdhid(void)
+{
+ char path[32], *s, *k, *e;
+ int f;
+
+ if(kbdhidfd < 0 && (f = open("/dev/usb/ctl", OREAD)) >= 0){
+ if((s = readall(f)) != nil &&
+ (k = strstr(s, "MNT 'Reform Keyboard'")) != nil &&
+ (e = strchr(k+22, ' ')) != nil){
+ *e = 0;
+ snprint(path, sizeof(path), "/dev/hidU%sctl", k+22);
+ if((kbdhidfd = open(path, OWRITE)) >= 0 && write(kbdhidfd, "rawon", 5) != 5){
+ close(kbdhidfd);
+ kbdhidfd = -1;
+ }
+ }
+ free(s);
+ close(f);
+ }
+
+ return kbdhidfd < 0;
+}
+
+static int
+loadkbdoled(void *data, int size)
+{
+ int x, y, i, k, v, bpl;
+ u8int *p, q;
+
+ if(openkbdhid() != 0)
+ return -1;
+ if(size == 0)
+ return write(kbdhidfd, "WCLR", 4);
+
+ bpl = bytesperline(kbdoled->r, kbdoled->depth);
+ if(size == 60+bpl*KbdoledH){
+ data = (u8int*)data + 60;
+ size -= 60;
+ }else if(size != bpl*KbdoledH){
+ werrstr("invalid image: expected %dx%d GREY1 (%d bytes)", KbdoledW, KbdoledH, bpl*KbdoledH);
+ return -1;
+ }
+
+ k = loadmemimage(kbdoled, kbdoled->r, data, size);
+ if(k < 0 || openkbdhid() != 0)
+ return -1;
+ for(y = 0, i = 4; y < KbdoledH; y += 8){
+ for(x = v = 0; x < KbdoledW; x++, v = (v+1)&7){
+ SET(p);
+ if(v == 0)
+ p = byteaddr(kbdoled, Pt(x,y));
+ for(k = q = 0; k < 8; k++)
+ q |= ((p[bpl*k] >> (7-v)) & 1) << k;
+ kbdoledraw[i++] = q;
+ }
+ }
+
+ return write(kbdhidfd, kbdoledraw, sizeof(kbdoledraw));
+}
+
+static int
+setlight(int k, int p)
{
u32int v;
@@ -96,17 +198,37 @@ setlight(int p)
if(p > 100)
p = 100;
- v = Pwmsrcclk / rd(pwm2, PWMSAR);
- wr(pwm2, PWMPR, (Pwmsrcclk/(v*p/100))-2);
+ if(k == Lcd){
+ v = Pwmsrcclk / rd(pwm2, PWMSAR);
+ wr(pwm2, PWMPR, (Pwmsrcclk/(v*p/100))-2);
+ return 0;
+ }else if(k == Kbd && openkbdhid() == 0){
+ v = Kbdlightmax*p/100;
+ if(fprint(kbdhidfd, "LITE%c", '0'+v) > 0){
+ kbdlight = v;
+ return 0;
+ }
+ close(kbdhidfd);
+ kbdhidfd = -1;
+ kbdlight = 0;
+ }
+
+ return -1;
}
static int
-getlight(void)
+getlight(int k)
{
u32int m, v;
- m = Pwmsrcclk / rd(pwm2, PWMSAR);
- v = Pwmsrcclk / (rd(pwm2, PWMPR)+2);
+ SET(m, v);
+ if(k == Lcd){
+ m = Pwmsrcclk / rd(pwm2, PWMSAR);
+ v = Pwmsrcclk / (rd(pwm2, PWMPR)+2);
+ }else if(k == Kbd){
+ m = Kbdlightmax;
+ v = kbdlight;
+ }
return v*100/m;
}
@@ -194,16 +316,16 @@ lpccall(char cmd, u8int arg, void *ret)
wr(spi2, SPIx_TXDATA, cmd);
wr(spi2, SPIx_TXDATA, arg);
wr(spi2, SPIx_CONREG, con | CON_XCH);
- sleep(60);
-
- /* LPC buffers 3 bytes without responding, ignore (including garbage) */
- while(rd(spi2, SPIx_STATREG) & STAT_RR)
- rd(spi2, SPIx_RXDATA);
/*
- * at this point LPC hopefully is blocked waiting for
- * chip select to go active
+ * LPC buffers 3 bytes without responding, but spends some time
+ * to prepare the response. 50ms should be safe, add a bit more
+ * to be sure LPC is blocked waiting for the chip select to go
+ * active again.
*/
+ sleep(60);
+ while(rd(spi2, SPIx_STATREG) & STAT_RR)
+ rd(spi2, SPIx_RXDATA);
/* expecting 8 bytes, start the exchange */
for(i = 0; i < 8; i++)
@@ -315,7 +437,7 @@ fsread(Req *r)
if(r->ifcall.offset == 0){
aux = r->fid->file->aux;
if(aux == (void*)Light){
- snprint(msg, sizeof(msg), "lcd %d\n", getlight());
+ snprint(msg, sizeof(msg), "lcd %d\nkbd %d\n", getlight(Lcd), getlight(Kbd));
}else if(aux == (void*)Temp){
if((c = getcputemp()) < 0){
responderror(r);
@@ -339,29 +461,55 @@ static void
fswrite(Req *r)
{
char msg[256], *f[4];
- int nf, v, p;
+ int nf, v, p, k;
void *aux;
- snprint(msg, sizeof(msg), "%.*s",
- utfnlen((char*)r->ifcall.data, r->ifcall.count), (char*)r->ifcall.data);
- nf = tokenize(msg, f, nelem(f));
aux = r->fid->file->aux;
+
+ if(aux == (void*)Kbdoled){
+ if(loadkbdoled(r->ifcall.data, r->ifcall.count) < 0){
+Err:
+ responderror(r);
+ return;
+ }
+ r->ofcall.count = r->ifcall.count;
+ respond(r, nil);
+ return;
+ }
+
+ snprint(msg, sizeof(msg), "%.*s", utfnlen(r->ifcall.data, r->ifcall.count), r->ifcall.data);
+ nf = tokenize(msg, f, nelem(f));
if(aux == (void*)Light){
if(nf < 2){
Bad:
respond(r, "invalid ctl message");
return;
}
- if(strcmp(f[0], "lcd") == 0){
- v = atoi(f[1]);
- if(*f[1] == '+' || *f[1] == '-')
- v += getlight();
- setlight(v);
- }
+ if(strcmp(f[0], "lcd") == 0)
+ k = Lcd;
+ else if(strcmp(f[0], "kbd") == 0)
+ k = Kbd;
+ else
+ goto Bad;
+ v = atoi(f[1]);
+ if(*f[1] == '+' || *f[1] == '-')
+ v += getlight(k);
+ if(setlight(k, v) != 0)
+ goto Err;
}else if(aux == (void*)Pmctl){
p = -1;
- if(nf == 2 && strcmp(f[0], "power") == 0 && strcmp(f[1], "off") == 0)
- p = Psomoff;
+ if(nf >= 2 && strcmp(f[0], "power") == 0){
+ if(nf == 2 && strcmp(f[1], "off") == 0){
+ /*
+ * LPC firmware might not be up to date so try
+ * shutting down through the keyboard first
+ */
+ if(openkbdhid() == 0){
+ write(kbdhidfd, "PWR0", 4);
+ sleep(2000); /* give it a chance */
+ }
+ }
+ }
if(p < 0)
goto Bad;
lpccall('p', p, msg);
@@ -425,11 +573,16 @@ threadmain(int argc, char **argv)
if((spi2 = segattach(0, "ecspi2", 0, 0x20)) == (void*)-1)
sysfatal("no spi2");
tmuinit();
+ if(memimageinit() != 0)
+ sysfatal("%r");
+ if((kbdoled = allocmemimage(Rect(0, 0, KbdoledW, KbdoledH), GREY1)) == nil)
+ sysfatal("%r");
lpcreq = reqqueuecreate();
fs.tree = alloctree(uid, uid, DMDIR|0555, nil);
- createfile(fs.tree->root, "battery", uid, 0444,(void*)Battery);
+ createfile(fs.tree->root, "battery", uid, 0444, (void*)Battery);
createfile(fs.tree->root, "cputemp", uid, 0444, (void*)Temp);
createfile(fs.tree->root, "light", uid, 0666, (void*)Light);
+ createfile(fs.tree->root, "kbdoled", uid, 0222, (void*)Kbdoled);
createfile(fs.tree->root, "pmctl", uid, 0666, (void*)Pmctl);
threadpostmountsrv(&fs, srv, mtpt, MAFTER);
diff --git a/sys/src/cmd/reform/shortcuts.c b/sys/src/cmd/reform/shortcuts.c
index dc3fdc85f..ce8cbdc43 100644
--- a/sys/src/cmd/reform/shortcuts.c
+++ b/sys/src/cmd/reform/shortcuts.c
@@ -1,22 +1,32 @@
#include <u.h>
#include <libc.h>
#include <keyboard.h>
+#include <plumb.h>
static int lightstep = 5, volstep = 3;
-static int light, vol, actl, mod;
+static int light, vol, actl;
+
+static void
+aplumb(char *s)
+{
+ int f;
+
+ if((f = plumbopen("send", OWRITE)) >= 0){
+ plumbsendtext(f, "shortcuts", "audio", "/", s);
+ close(f);
+ }
+}
static void
process(char *s)
{
char b[128], *p;
- int n, o;
+ int n, o, skip;
Rune r;
- if(*s == 'K' && s[1] == 0)
- mod = 0;
-
o = 0;
b[o++] = *s;
+
for(p = s+1; *p != 0; p += n){
if((n = chartorune(&r, p)) == 1 && r == Runeerror){
/* bail out */
@@ -27,31 +37,31 @@ process(char *s)
break;
}
- if(*s == 'k' && r == Kmod4){
- mod = 1;
- }else if(*s == 'K'){
- if(mod && r >= (KF|1) && r <= (KF|4))
- continue;
- if(r == Kmod4)
- mod = 0;
- }else if(mod && ((r >= (KF|1) && r <= (KF|4) || r == Kesc))){
- if(*s == 'c'){
- if(r == (KF|1))
- fprint(light, "lcd %+d", -lightstep);
- else if(r == (KF|2))
- fprint(light, "lcd %+d", lightstep);
- else if(r == (KF|3))
- fprint(vol, "master %+d", -volstep);
- else if(r == (KF|4))
- fprint(vol, "master %+d", volstep);
- else if(r == Kesc)
- fprint(actl, "master toggle");
- }
- continue;
+ if(skip = (*s == 'c')){
+ if(r == Kbrtdn)
+ fprint(light, "lcd %+d", -lightstep);
+ else if(r == Kbrtup)
+ fprint(light, "lcd %+d", lightstep);
+ else if(r == Kvoldn)
+ fprint(vol, "master %+d", -volstep);
+ else if(r == Kvolup)
+ fprint(vol, "master %+d", volstep);
+ else if(r == Kmute)
+ fprint(actl, "master toggle");
+ else if(r == Ksbwd)
+ aplumb("key <");
+ else if(r == Ksfwd)
+ aplumb("key >");
+ else if(r == Kpause)
+ aplumb("key p");
+ else
+ skip = 0;
}
- memmove(b+o, p, n);
- o += n;
+ if(!skip){
+ memmove(b+o, p, n);
+ o += n;
+ }
}
/* all runes filtered out - ignore completely */
diff --git a/sys/src/cmd/rio/rio.c b/sys/src/cmd/rio/rio.c
index daefffe93..2e59a636d 100644
--- a/sys/src/cmd/rio/rio.c
+++ b/sys/src/cmd/rio/rio.c
@@ -393,32 +393,16 @@ keyboardtap(void*)
threadsetname("keyboardtap");
enum { Awin, Actl, Afrom, Adev, Ato, Ainp, Awatch, NALT };
- static Alt alts[NALT+1];
- /* ctl */
- alts[Awin].c = wintap;
- alts[Awin].v = &w;
- alts[Awin].op = CHANRCV;
- alts[Actl].c = ctltap;
- alts[Actl].v = &ctl;
- alts[Actl].op = CHANRCV;
- /* kbd input */
- alts[Afrom].c = fromtap;
- alts[Afrom].v = &s;
- alts[Afrom].op = CHANRCV;
- alts[Adev].c = kbdchan;
- alts[Adev].v = &s;
- alts[Adev].op = CHANRCV;
- /* kbd output */
- alts[Ato].c = totap;
- alts[Ato].v = &s;
- alts[Ato].op = CHANNOP;
- alts[Ainp].c = nil;
- alts[Ainp].v = &s;
- alts[Ainp].op = CHANNOP;
- alts[Awatch].c = totap;
- alts[Awatch].v = &watched;
- alts[Awatch].op = CHANNOP;
- alts[NALT].op = CHANEND;
+ Alt alts[NALT+1] = {
+ [Awin] {.c = wintap, .v = &w, .op = CHANRCV},
+ [Actl] {.c = ctltap, .v = &ctl, .op = CHANRCV},
+ [Afrom] {.c = fromtap, .v = &s, .op = CHANRCV},
+ [Adev] {.c = kbdchan, .v = &s, .op = CHANRCV},
+ [Ato] {.c = totap, .v = &s, .op = CHANNOP},
+ [Ainp] {.c = nil, .v = &s, .op = CHANNOP},
+ [Awatch]{.c = totap, .v = &watched, .op = CHANNOP},
+ [NALT] {.op = CHANEND},
+ };
cur = nil;
watched = nil;
diff --git a/sys/src/cmd/riow.c b/sys/src/cmd/riow.c
index 787a87ad6..434b0d14d 100644
--- a/sys/src/cmd/riow.c
+++ b/sys/src/cmd/riow.c
@@ -2,6 +2,7 @@
#include <libc.h>
#include <draw.h>
#include <keyboard.h>
+#include <ctype.h>
typedef struct W W;
@@ -24,6 +25,7 @@ struct W {
Rectangle r;
int vd;
int flags;
+ int stickyforced;
};
static int vd = 1; /* current virtual desktop */
@@ -86,12 +88,14 @@ wsupdate(void)
w->r.max.y = atoi(t[3]);
w->vd = -1;
w->flags = 0;
+ w->stickyforced = 0;
/* move over the current state of the window */
for(k = 0, seen = 0; k < wsn; k++){
if(ws[k].id == w->id){
w->vd = ws[k].vd;
w->flags = ws[k].flags & ~(Fvisible|Fcurrent);
+ w->stickyforced = ws[k].stickyforced;
if(w->flags & Ffullscreen)
w->r = ws[k].r;
seen = 1;
@@ -117,17 +121,21 @@ wsupdate(void)
}
/* because a different program can run in any window we have to re-read */
- snprint(s, sizeof(s), "/dev/wsys/%d/label", w->id);
w->flags &= ~Fsticky;
- if((f = open(s, OREAD)) >= 0){
- n = read(f, s, sizeof(s)-1);
- close(f);
- if(n > 0){
- s[n] = 0;
- for(k = 0; k < nelem(sticky) && sticky[k] != nil; k++){
- if(strcmp(sticky[k], s) == 0){
- w->flags |= Fsticky;
- break;
+ if(w->stickyforced){
+ w->flags |= Fsticky;
+ }else{
+ snprint(s, sizeof(s), "/dev/wsys/%d/label", w->id);
+ if((f = open(s, OREAD)) >= 0){
+ n = read(f, s, sizeof(s)-1);
+ close(f);
+ if(n > 0){
+ s[n] = 0;
+ for(k = 0; k < nelem(sticky) && sticky[k] != nil; k++){
+ if(strcmp(sticky[k], s) == 0){
+ w->flags |= Fsticky;
+ break;
+ }
}
}
}
@@ -153,6 +161,7 @@ togglefullscreen(void)
{
int f;
+ wsupdate();
if(wcur == nil || (f = wwctl(wcur->id, OWRITE)) < 0)
return;
wcur->flags ^= Ffullscreen;
@@ -166,8 +175,9 @@ togglefullscreen(void)
static void
togglesticky(void)
{
+ wsupdate();
if(wcur != nil)
- wcur->flags ^= Fsticky;
+ wcur->stickyforced ^= 1;
}
static void
@@ -176,14 +186,15 @@ vdaction(int nvd)
int f, wcurf;
W *w;
+ if(vd == nvd)
+ return;
+
+ wsupdate();
if(mod == Mmod4){
wcur = nil;
wcurf = -1;
vd2wcur[vd] = -1;
for(w = ws; w < ws+wsn; w++){
- if((f = wwctl(w->id, OWRITE)) < 0)
- continue;
-
if(w->flags & Fvisible)
w->vd = vd;
else if(w->vd == vd)
@@ -192,24 +203,33 @@ vdaction(int nvd)
if(w->flags & Fcurrent)
vd2wcur[vd] = w->id;
- if(w->vd != nvd && (w->flags & Fsticky) == 0){
- fprint(f, "hide");
- }else{
- fprint(f, "unhide");
- if(vd2wcur[nvd] == w->id && wcurf < 0){
- wcur = w;
- wcurf = f;
- f = -1;
+ if(w->vd == nvd && (w->flags & Fsticky) == 0){
+ if((f = wwctl(w->id, OWRITE)) >= 0){
+ fprint(f, "unhide");
+ if(vd2wcur[nvd] == w->id && wcurf < 0){
+ wcur = w;
+ wcurf = f;
+ }else
+ close(f);
}
}
- if(f >= 0)
- close(f);
}
+
if(wcur != nil){
fprint(wcurf, "top");
fprint(wcurf, "current");
close(wcurf);
}
+
+ for(w = ws; w < ws+wsn; w++){
+ if(w->vd != nvd && (w->flags & (Fsticky|Fvisible)) == Fvisible){
+ if((f = wwctl(w->id, OWRITE)) >= 0){
+ fprint(f, "hide");
+ close(f);
+ }
+ }
+ }
+
vd = nvd;
fprint(3, "%d\n", vd);
}else if(mod == (Mmod4 | Mshift) && wcur != nil && wcur->vd != nvd){
@@ -228,6 +248,7 @@ arrowaction(int x, int y)
{
int f;
+ wsupdate();
if(wcur == nil || (f = wwctl(wcur->id, OWRITE)) < 0)
return;
@@ -258,6 +279,7 @@ cycleaction(int x, int y)
int wcurid, i, f;
W *w, *w₀;
+ wsupdate();
wcurid = wcur == nil ? -1 : wcur->id;
cyclectx.x = x;
cyclectx.y = y;
@@ -286,49 +308,90 @@ cycleaction(int x, int y)
wcur = w;
}
-static void
-keyevent(Rune r)
+static int
+keyevent(char c, Rune r)
{
- wsupdate();
-
- if(r == '\n')
- spawn("window");
- else if(r == 'f')
- togglefullscreen();
- else if(r == 's')
- togglesticky();
- else if(r >= '0' && r <= '9')
+ if(c == 'c'){
+ if(r == '\n' && mod == Mmod4){
+ spawn("window");
+ return 0;
+ }
+ if(r == 'f' && mod == Mmod4){
+ togglefullscreen();
+ return 0;
+ }
+ if(r == 's' && mod == Mmod4){
+ togglesticky();
+ return 0;
+ }
+ if(r == Kup){
+ arrowaction(0, -1);
+ return 0;
+ }
+ if(r == Kdown){
+ arrowaction(0, 1);
+ return 0;
+ }
+ if(r == Kleft){
+ arrowaction(-1, 0);
+ return 0;
+ }
+ if(r == Kright){
+ arrowaction(1, 0);
+ return 0;
+ }
+ if(r == 'h' && mod == Mmod4){
+ cycleaction(-1, 0);
+ return 0;
+ }
+ if(r == 'l' && mod == Mmod4){
+ cycleaction(1, 0);
+ return 0;
+ }
+ if(r == 'j' && mod == Mmod4){
+ cycleaction(0, 1);
+ return 0;
+ }
+ if(r == 'k' && mod == Mmod4){
+ cycleaction(0, -1);
+ return 0;
+ }
+ if(r >= '0' && r <= '9' && (mod & Mctl) == 0){
+ vdaction(r - '0');
+ return 0;
+ }
+ }
+ /* mod4 + shift + 1…0 yields a shifted value on 'c': workaround */
+ if(c == 'k' && mod == (Mmod4|Mshift) && r >= '0' && r <= '9'){
vdaction(r - '0');
- else if(r == Kup)
- arrowaction(0, -1);
- else if(r == Kdown)
- arrowaction(0, 1);
- else if(r == Kleft)
- arrowaction(-1, 0);
- else if(r == Kright)
- arrowaction(1, 0);
- else if(r == 'h')
- cycleaction(-1, 0);
- else if(r == 'l')
- cycleaction(1, 0);
- else if(r == 'j')
- cycleaction(0, 1);
- else if(r == 'k')
- cycleaction(0, -1);
+ return 0;
+ }
+ /* don't bother to properly deal with handling shifted digit keys */
+ if((mod & Mshift) != 0 && (c == 'c' || c == 'k' || c == 'K'))
+ return ispunct(r) ? 0 : -1;
+
+ return -1;
}
static void
process(char *s)
{
- int n, o, oldmod;
char b[128], *p;
+ int n, o;
Rune r;
- if(*s == 'K' && s[1] == 0)
- mod = 0;
-
o = 0;
b[o++] = *s;
+ if(*s == 'k' || *s == 'K'){
+ mod = 0;
+ if(utfrune(s+1, Kmod4) != nil)
+ mod |= Mmod4;
+ if(utfrune(s+1, Kctl) != nil)
+ mod |= Mctl;
+ if(utfrune(s+1, Kshift) != nil)
+ mod |= Mshift;
+ }
+
for(p = s+1; *p != 0; p += n){
if((n = chartorune(&r, p)) == 1 && r == Runeerror){
/* bail out */
@@ -339,36 +402,10 @@ process(char *s)
break;
}
- oldmod = mod;
-
- if(*s == 'c' && (mod & Mmod4) != 0){
- keyevent(r);
- continue;
- }
-
- if(*s == 'k'){
- if(r == Kmod4)
- mod |= Mmod4;
- else if(r == Kctl)
- mod |= Mctl;
- else if(r == Kshift)
- mod |= Mshift;
- else if(r >= '0' && r <= '9' && (mod & (Mshift|Mmod4)) == (Mshift|Mmod4))
- keyevent(r);
- }else if(*s == 'K'){
- if(r == Kmod4)
- mod &= ~Mmod4;
- else if(r == Kctl)
- mod &= ~Mctl;
- else if(r == Kshift)
- mod &= ~Mshift;
+ if((mod & Mmod4) == 0 || keyevent(*s, r) != 0){
+ memmove(b+o, p, n);
+ o += n;
}
-
- if((oldmod | mod) & Mmod4)
- continue;
-
- memmove(b+o, p, n);
- o += n;
}
/* all runes filtered out - ignore completely */
diff --git a/sys/src/cmd/vt/main.c b/sys/src/cmd/vt/main.c
index c6ec70976..32743c792 100644
--- a/sys/src/cmd/vt/main.c
+++ b/sys/src/cmd/vt/main.c
@@ -299,6 +299,7 @@ threadmain(int argc, char **argv)
if(rfork(RFENVG) < 0)
sysfatal("rfork: %r");
+ doquote = needsrcquote;
quotefmtinstall();
notify(catch);
atexit(shutdown);