tlibdraw: connect to devdraw via $wsysid when set - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit dbf57689c45611b8da9e269c24e409ee33a877d5
 (DIR) parent 41547af3f614061dd2c94bb52ae118f146925743
 (HTM) Author: Russ Cox <rsc@swtch.com>
       Date:   Sat, 11 Jan 2020 05:52:59 -0500
       
       libdraw: connect to devdraw via $wsysid when set
       
       Diffstat:
         M include/drawfcall.h                 |       6 ++++++
         M src/libdraw/drawclient.c            |      64 ++++++++++++++++++++++++++++++-
         M src/libdraw/drawfcall.c             |      16 ++++++++++++++++
       
       3 files changed, 85 insertions(+), 1 deletion(-)
       ---
 (DIR) diff --git a/include/drawfcall.h b/include/drawfcall.h
       t@@ -25,6 +25,9 @@ tag[1] Rrdkbd rune[2]
        tag[1] Tlabel label[s]
        tag[1] Rlabel 
        
       +tag[1] Tctxt wsysid[s]
       +tag[1] Rctxt
       +
        tag[1] Tinit winsize[s] label[s] font[s]
        tag[1] Rinit
        
       t@@ -94,6 +97,8 @@ enum {
                Rresize,
                Tcursor2 = 28,
                Rcursor2,
       +        Tctxt = 30,
       +        Rctxt,
                Tmax,
        };
        
       t@@ -116,6 +121,7 @@ struct Wsysmsg
                char *label;
                char *snarf;
                char *error;
       +        char *id;
                uchar *data;
                uint count;
                Rectangle rect;
 (DIR) diff --git a/src/libdraw/drawclient.c b/src/libdraw/drawclient.c
       t@@ -22,11 +22,69 @@ static int canreadfd(int);
        int
        _displayconnect(Display *d)
        {
       -        int pid, p[2];
       +        int pid, p[2], fd, nbuf, n;
       +        char *wsysid, *addr, *id;
       +        uchar *buf;
       +        Wsysmsg w;
        
                fmtinstall('W', drawfcallfmt);
                fmtinstall('H', encodefmt);
        
       +        wsysid = getenv("wsysid");
       +        if(wsysid != nil) {
       +                // Connect to running devdraw service.
       +                // wsysid=devdrawname/id
       +                id = strchr(wsysid, '/');
       +                if(id == nil) {
       +                        werrstr("invalid $wsysid");
       +                        return -1;
       +                }
       +                *id++ = '\0';
       +                addr = smprint("unix!%s/%s", getns(), wsysid);
       +                if(addr == nil)
       +                        return -1;
       +                fd = dial(addr, 0, 0, 0);
       +                free(addr);
       +                if(fd < 0)
       +                        return -1;
       +                nbuf = strlen(id) + 500;
       +                buf = malloc(nbuf);
       +                if(buf == nil) {
       +                        close(fd);
       +                        return -1;
       +                }
       +                memset(&w, 0, sizeof w);
       +                w.type = Tctxt;
       +                w.id = id;
       +                n = convW2M(&w, buf, nbuf);
       +                if(write(fd, buf, n) != n) {
       +                        close(fd);
       +                        werrstr("wsys short write: %r");
       +                        return -1;
       +                }
       +                n = readwsysmsg(fd, buf, nbuf);
       +                if(n < 0) {
       +                        close(fd);
       +                        werrstr("wsys short read: %r");
       +                        return -1;
       +                }
       +                if(convM2W(buf, n, &w) <= 0) {
       +                        close(fd);
       +                        werrstr("wsys decode error");
       +                        return -1;
       +                }
       +                if(w.type != Rctxt) {
       +                        close(fd);
       +                        if(w.type == Rerror)
       +                                werrstr("%s", w.error);
       +                        else
       +                                werrstr("wsys rpc phase error (%d)", w.type);
       +                        return -1;
       +                }
       +                d->srvfd = fd;
       +                return 0;
       +        }
       +
                if(pipe(p) < 0)
                        return -1;
                if((pid=fork()) < 0){
       t@@ -36,6 +94,10 @@ _displayconnect(Display *d)
                }
                if(pid == 0){
                        char *devdraw;
       +
       +                devdraw = getenv("DEVDRAW");
       +                if(devdraw == nil)
       +                        devdraw = "devdraw";
                        close(p[0]);
                        dup(p[1], 0);
                        dup(p[1], 1);
 (DIR) diff --git a/src/libdraw/drawfcall.c b/src/libdraw/drawfcall.c
       t@@ -51,6 +51,7 @@ sizeW2M(Wsysmsg *m)
                case Rcursor2:
                case Trdkbd:
                case Rlabel:
       +        case Rctxt:
                case Rinit:
                case Trdsnarf:
                case Rwrsnarf:
       t@@ -74,6 +75,9 @@ sizeW2M(Wsysmsg *m)
                        return 4+1+1+2;
                case Tlabel:
                        return 4+1+1+_stringsize(m->label);
       +        case Tctxt:
       +                return 4+1+1
       +                        +_stringsize(m->id);
                case Tinit:
                        return 4+1+1
                                +_stringsize(m->winsize)
       t@@ -114,6 +118,7 @@ convW2M(Wsysmsg *m, uchar *p, uint n)
                case Rcursor2:
                case Trdkbd:
                case Rlabel:
       +        case Rctxt:
                case Rinit:
                case Trdsnarf:
                case Rwrsnarf:
       t@@ -164,6 +169,9 @@ convW2M(Wsysmsg *m, uchar *p, uint n)
                case Tlabel:
                        PUTSTRING(p+6, m->label);
                        break;
       +        case Tctxt:
       +                PUTSTRING(p+6, m->id);
       +                break;
                case Tinit:
                        p += 6;
                        p += PUTSTRING(p, m->winsize);
       t@@ -214,6 +222,7 @@ convM2W(uchar *p, uint n, Wsysmsg *m)
                case Rcursor2:
                case Trdkbd:
                case Rlabel:
       +        case Rctxt:
                case Rinit:
                case Trdsnarf:
                case Rwrsnarf:
       t@@ -264,6 +273,9 @@ convM2W(uchar *p, uint n, Wsysmsg *m)
                case Tlabel:
                        GETSTRING(p+6, &m->label);
                        break;
       +        case Tctxt:
       +                GETSTRING(p+6, &m->id);
       +                break;
                case Tinit:
                        p += 6;
                        p += GETSTRING(p, &m->winsize);
       t@@ -352,6 +364,10 @@ drawfcallfmt(Fmt *fmt)
                        return fmtprint(fmt, "Tlabel label='%s'", m->label);
                case Rlabel:
                        return fmtprint(fmt, "Rlabel");
       +        case Tctxt:
       +                return fmtprint(fmt, "Tctxt id='%s'", m->id);
       +        case Rctxt:
       +                return fmtprint(fmt, "Rctxt");
                case Tinit:
                        return fmtprint(fmt, "Tinit label='%s' winsize='%s'", m->label, m->winsize);
                case Rinit: