devdraw, libdraw: handle keyboard runes > U+FFFF

Runes in Plan 9 were limited to the 16-bit BMP when I drew up
the RPC protocol between graphical programs and devdraw
a long time ago. Now that they can be 32-bit, use a 32-bit wire
encoding too. A new message number to avoid problems with
other clients (like 9fans.net/go).

Add keyboard shortcut alt : , for U+1F602, face with tears of joy,
to test that it all works.
This commit is contained in:
Russ Cox 2020-05-18 23:45:03 -04:00
parent b4cc38f943
commit d25d0ca1a3
7 changed files with 34 additions and 8 deletions

View file

@ -22,8 +22,11 @@ tag[1] Rbouncemouse
tag[1] Trdkbd tag[1] Trdkbd
tag[1] Rrdkbd rune[2] tag[1] Rrdkbd rune[2]
tag[1] Trdkbd4
tag[1] Rrdkbd4 rune[4]
tag[1] Tlabel label[s] tag[1] Tlabel label[s]
tag[1] Rlabel tag[1] Rlabel
tag[1] Tctxt wsysid[s] tag[1] Tctxt wsysid[s]
tag[1] Rctxt tag[1] Rctxt
@ -31,7 +34,7 @@ tag[1] Rctxt
tag[1] Tinit winsize[s] label[s] font[s] tag[1] Tinit winsize[s] label[s] font[s]
tag[1] Rinit tag[1] Rinit
tag[1] Trdsnarf tag[1] Trdsnarf
tag[1] Rrdsnarf snarf[s] tag[1] Rrdsnarf snarf[s]
tag[1] Twrsnarf snarf[s] tag[1] Twrsnarf snarf[s]
@ -47,7 +50,7 @@ tag[1] Ttop
tag[1] Rtop tag[1] Rtop
tag[1] Tresize rect[4*4] tag[1] Tresize rect[4*4]
tag[1] Rresize tag[1] Rresize
*/ */
@ -99,6 +102,8 @@ enum {
Rcursor2, Rcursor2,
Tctxt = 30, Tctxt = 30,
Rctxt, Rctxt,
Trdkbd4 = 32,
Rrdkbd4,
Tmax, Tmax,
}; };

View file

@ -584,3 +584,4 @@
F015 ZA  raw alt (plan 9 specific) F015 ZA  raw alt (plan 9 specific)
F016 ZS  raw shift (plan 9 specific) F016 ZS  raw shift (plan 9 specific)
F017 ZC  raw ctl (plan 9 specific) F017 ZC  raw ctl (plan 9 specific)
1F602 :, 😂 face with tears of joy

View file

@ -191,7 +191,7 @@ readfile(char *fname)
r = strtol(line, nil, 16); r = strtol(line, nil, 16);
p = strchr(line, ' '); p = strchr(line, ' ');
if(r == 0 || p != line+4 || p[0] != ' ' || p[1] != ' ') { if(r == 0 || (p != line+4 && p != line+5) || p[0] != ' ' || (p == line+4 && p[1] != ' ')) {
fprint(2, "%s:%d: cannot parse line\n", fname, lineno); fprint(2, "%s:%d: cannot parse line\n", fname, lineno);
continue; continue;
} }

View file

@ -229,6 +229,7 @@ runmsg(Client *c, Wsysmsg *m)
break; break;
case Trdkbd: case Trdkbd:
case Trdkbd4:
qlock(&c->eventlk); qlock(&c->eventlk);
if((c->kbdtags.wi+1)%nelem(c->kbdtags.t) == c->kbdtags.ri) { if((c->kbdtags.wi+1)%nelem(c->kbdtags.t) == c->kbdtags.ri) {
qunlock(&c->eventlk); qunlock(&c->eventlk);
@ -236,7 +237,7 @@ runmsg(Client *c, Wsysmsg *m)
replyerror(c, m); replyerror(c, m);
break; break;
} }
c->kbdtags.t[c->kbdtags.wi++] = m->tag; c->kbdtags.t[c->kbdtags.wi++] = (m->tag<<1) | (m->type==Trdkbd4);
if(c->kbdtags.wi == nelem(c->kbdtags.t)) if(c->kbdtags.wi == nelem(c->kbdtags.t))
c->kbdtags.wi = 0; c->kbdtags.wi = 0;
c->kbd.stall = 0; c->kbd.stall = 0;
@ -357,13 +358,17 @@ replymsg(Client *c, Wsysmsg *m)
static void static void
matchkbd(Client *c) matchkbd(Client *c)
{ {
int tag;
Wsysmsg m; Wsysmsg m;
if(c->kbd.stall) if(c->kbd.stall)
return; return;
while(c->kbd.ri != c->kbd.wi && c->kbdtags.ri != c->kbdtags.wi){ while(c->kbd.ri != c->kbd.wi && c->kbdtags.ri != c->kbdtags.wi){
tag = c->kbdtags.t[c->kbdtags.ri++];
m.type = Rrdkbd; m.type = Rrdkbd;
m.tag = c->kbdtags.t[c->kbdtags.ri++]; if(tag&1)
m.type = Rrdkbd4;
m.tag = tag>>1;
if(c->kbdtags.ri == nelem(c->kbdtags.t)) if(c->kbdtags.ri == nelem(c->kbdtags.t))
c->kbdtags.ri = 0; c->kbdtags.ri = 0;
m.rune = c->kbd.r[c->kbd.ri++]; m.rune = c->kbd.r[c->kbd.ri++];

View file

@ -333,7 +333,7 @@ _displayrdkbd(Display *d, Rune *r)
{ {
Wsysmsg tx, rx; Wsysmsg tx, rx;
tx.type = Trdkbd; tx.type = Trdkbd4;
if(displayrpc(d, &tx, &rx, nil) < 0) if(displayrpc(d, &tx, &rx, nil) < 0)
return -1; return -1;
*r = rx.rune; *r = rx.rune;

View file

@ -50,6 +50,7 @@ sizeW2M(Wsysmsg *m)
case Rcursor: case Rcursor:
case Rcursor2: case Rcursor2:
case Trdkbd: case Trdkbd:
case Trdkbd4:
case Rlabel: case Rlabel:
case Rctxt: case Rctxt:
case Rinit: case Rinit:
@ -73,6 +74,8 @@ sizeW2M(Wsysmsg *m)
return 4+1+1+_stringsize(m->error); return 4+1+1+_stringsize(m->error);
case Rrdkbd: case Rrdkbd:
return 4+1+1+2; return 4+1+1+2;
case Rrdkbd4:
return 4+1+1+4;
case Tlabel: case Tlabel:
return 4+1+1+_stringsize(m->label); return 4+1+1+_stringsize(m->label);
case Tctxt: case Tctxt:
@ -117,6 +120,7 @@ convW2M(Wsysmsg *m, uchar *p, uint n)
case Rcursor: case Rcursor:
case Rcursor2: case Rcursor2:
case Trdkbd: case Trdkbd:
case Trdkbd4:
case Rlabel: case Rlabel:
case Rctxt: case Rctxt:
case Rinit: case Rinit:
@ -166,6 +170,9 @@ convW2M(Wsysmsg *m, uchar *p, uint n)
case Rrdkbd: case Rrdkbd:
PUT2(p+6, m->rune); PUT2(p+6, m->rune);
break; break;
case Rrdkbd4:
PUT(p+6, m->rune);
break;
case Tlabel: case Tlabel:
PUTSTRING(p+6, m->label); PUTSTRING(p+6, m->label);
break; break;
@ -221,6 +228,7 @@ convM2W(uchar *p, uint n, Wsysmsg *m)
case Rcursor: case Rcursor:
case Rcursor2: case Rcursor2:
case Trdkbd: case Trdkbd:
case Trdkbd4:
case Rlabel: case Rlabel:
case Rctxt: case Rctxt:
case Rinit: case Rinit:
@ -270,6 +278,9 @@ convM2W(uchar *p, uint n, Wsysmsg *m)
case Rrdkbd: case Rrdkbd:
GET2(p+6, m->rune); GET2(p+6, m->rune);
break; break;
case Rrdkbd4:
GET(p+6, m->rune);
break;
case Tlabel: case Tlabel:
GETSTRING(p+6, &m->label); GETSTRING(p+6, &m->label);
break; break;
@ -360,6 +371,10 @@ drawfcallfmt(Fmt *fmt)
return fmtprint(fmt, "Trdkbd"); return fmtprint(fmt, "Trdkbd");
case Rrdkbd: case Rrdkbd:
return fmtprint(fmt, "Rrdkbd rune=%C", m->rune); return fmtprint(fmt, "Rrdkbd rune=%C", m->rune);
case Trdkbd4:
return fmtprint(fmt, "Trdkbd4");
case Rrdkbd4:
return fmtprint(fmt, "Rrdkbd4 rune=%C", m->rune);
case Tlabel: case Tlabel:
return fmtprint(fmt, "Tlabel label='%s'", m->label); return fmtprint(fmt, "Tlabel label='%s'", m->label);
case Rlabel: case Rlabel:

View file

@ -284,7 +284,7 @@ extract(int canblock)
} }
}else if(i == Skeyboard){ }else if(i == Skeyboard){
if(eslave[i].rpc == nil) if(eslave[i].rpc == nil)
eslave[i].rpc = startrpc(Trdkbd); eslave[i].rpc = startrpc(Trdkbd4);
if(eslave[i].rpc){ if(eslave[i].rpc){
/* if ready, don't block in select */ /* if ready, don't block in select */
if(eslave[i].rpc->p) if(eslave[i].rpc->p)