diff options
author | rsc <devnull@localhost> | 2006-06-25 19:00:14 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2006-06-25 19:00:14 +0000 |
commit | 257fb6261eba6026e127e1a42e06b8b2d9c3b722 (patch) | |
tree | d68dbebd7d6460e6bbcc022f2e01d172c8a7174a /src/libdraw | |
parent | 74dc60da74c62e07f0d63179da9724d705794a6d (diff) | |
download | plan9port-257fb6261eba6026e127e1a42e06b8b2d9c3b722.tar.gz plan9port-257fb6261eba6026e127e1a42e06b8b2d9c3b722.tar.bz2 plan9port-257fb6261eba6026e127e1a42e06b8b2d9c3b722.zip |
new
Diffstat (limited to 'src/libdraw')
-rw-r--r-- | src/libdraw/drawclient.c | 336 | ||||
-rw-r--r-- | src/libdraw/drawfcall.c | 367 | ||||
-rw-r--r-- | src/libdraw/snarf.c | 15 | ||||
-rw-r--r-- | src/libdraw/wsys.c | 24 |
4 files changed, 742 insertions, 0 deletions
diff --git a/src/libdraw/drawclient.c b/src/libdraw/drawclient.c new file mode 100644 index 00000000..ae8719a9 --- /dev/null +++ b/src/libdraw/drawclient.c @@ -0,0 +1,336 @@ +/* Copyright (c) 2006 Russ Cox */ + +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <mouse.h> +#include <cursor.h> +#include <drawfcall.h> +#include <mux.h> + +int chattydrawclient; + +static int drawgettag(Mux *mux, void *vmsg); +static void* drawrecv(Mux *mux); +static int drawsend(Mux *mux, void *vmsg); +static int drawsettag(Mux *mux, void *vmsg, uint tag); + +int +_displayconnect(Display *d) +{ + int pid, p[2]; + + fmtinstall('W', drawfcallfmt); + fmtinstall('H', encodefmt); + + if(pipe(p) < 0) + return -1; + if((pid=fork()) < 0){ + close(p[0]); + close(p[1]); + return -1; + } + if(pid == 0){ + close(p[0]); + dup(p[1], 0); + dup(p[1], 1); + /* execl("strace", "strace", "-o", "drawsrv.out", "drawsrv", nil); */ + execl("drawsrv", "drawsrv", nil); + sysfatal("exec drawsrv: %r"); + } + close(p[1]); + d->srvfd = p[0]; + return 0; +} + +int +_displaymux(Display *d) +{ + if((d->mux = mallocz(sizeof(*d->mux), 1)) == nil) + return -1; + + d->mux->mintag = 1; + d->mux->maxtag = 255; + d->mux->send = drawsend; + d->mux->recv = drawrecv; + d->mux->gettag = drawgettag; + d->mux->settag = drawsettag; + d->mux->aux = d; + muxinit(d->mux); + + return 0; +} + +#define GET(p, x) \ + ((x) = (((p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | ((p)[3]))) + +static int +drawsend(Mux *mux, void *vmsg) +{ + int n; + uchar *msg; + Display *d; + + msg = vmsg; + GET(msg, n); + d = mux->aux; + return write(d->srvfd, msg, n); +} + +static void* +drawrecv(Mux *mux) +{ + int n; + uchar buf[4], *p; + Display *d; + + d = mux->aux; + if((n=readn(d->srvfd, buf, 4)) != 4){ +fprint(2, "readn 4 got %d: %r\n", n); + return nil; + } + GET(buf, n); + p = malloc(n); + if(p == nil){ + fprint(2, "out of memory allocating %d in drawrecv\n", n); + return nil; + } + memmove(p, buf, 4); + if(readn(d->srvfd, p+4, n-4) != n-4){ +fprint(2, "short readn\n"); + return nil; + } + return p; +} + +static int +drawgettag(Mux *mux, void *vmsg) +{ + USED(mux); + uchar *msg; + + msg = vmsg; + return msg[4]; +} + +static int +drawsettag(Mux *mux, void *vmsg, uint tag) +{ + USED(mux); + uchar *msg; + + msg = vmsg; + msg[4] = tag; + return 0; +} + +static int +displayrpc(Display *d, Wsysmsg *tx, Wsysmsg *rx, void **freep) +{ + int n, nn; + void *tpkt, *rpkt; + + n = sizeW2M(tx); + tpkt = malloc(n); + if(freep) + *freep = nil; + if(tpkt == nil) + return -1; + tx->tag = 0; + if(chattydrawclient) + fprint(2, "<- %W\n", tx); + nn = convW2M(tx, tpkt, n); + if(nn != n){ + free(tpkt); + werrstr("drawclient: sizeW2M convW2M mismatch"); + fprint(2, "%r\n"); + return -1; + } + rpkt = muxrpc(d->mux, tpkt); + free(tpkt); + if(rpkt == nil){ + werrstr("muxrpc: %r"); + return -1; + } + GET((uchar*)rpkt, n); + nn = convM2W(rpkt, n, rx); + if(nn != n){ + free(rpkt); + werrstr("drawclient: convM2W packet size mismatch %d %d %.*H", n, nn, n, rpkt); + fprint(2, "%r\n"); + return -1; + } + if(chattydrawclient) + fprint(2, "-> %W\n", rx); + if(rx->type == Rerror){ + werrstr("%s", rx->error); + free(rpkt); + return -1; + } + if(rx->type != tx->type+1){ + werrstr("packet type mismatch -- tx %d rx %d", + tx->type, rx->type); + free(rpkt); + return -1; + } + if(freep) + *freep = rpkt; + else + free(rpkt); + return 0; +} + +int +_displayinit(Display *d, char *label, char *winsize) +{ + Wsysmsg tx, rx; + + tx.type = Tinit; + tx.label = ""; + tx.winsize = ""; + return displayrpc(d, &tx, &rx, nil); +} + +int +_displayrdmouse(Display *d, Mouse *m, int *resized) +{ + Wsysmsg tx, rx; + + tx.type = Trdmouse; + if(displayrpc(d, &tx, &rx, nil) < 0) + return -1; + *m = rx.mouse; + *resized = rx.resized; + return 0; +} + +int +_displayrdkbd(Display *d, Rune *r) +{ + Wsysmsg tx, rx; + + tx.type = Trdkbd; + if(displayrpc(d, &tx, &rx, nil) < 0) + return -1; + *r = rx.rune; + return 0; +} + +int +_displaymoveto(Display *d, Point p) +{ + Wsysmsg tx, rx; + + tx.type = Tmoveto; + tx.mouse.xy = p; + return displayrpc(d, &tx, &rx, nil); +} + +int +_displaycursor(Display *d, Cursor *c) +{ + Wsysmsg tx, rx; + + tx.type = Tcursor; + if(c == nil){ + memset(&tx.cursor, 0, sizeof tx.cursor); + tx.arrowcursor = 1; + }else{ + tx.arrowcursor = 0; + tx.cursor = *c; + } + return displayrpc(d, &tx, &rx, nil); +} + +int +_displaybouncemouse(Display *d, Mouse *m) +{ + Wsysmsg tx, rx; + + tx.type = Tbouncemouse; + tx.mouse = *m; + return displayrpc(d, &tx, &rx, nil); +} + +int +_displaylabel(Display *d, char *label) +{ + Wsysmsg tx, rx; + + tx.type = Tlabel; + tx.label = label; + return displayrpc(d, &tx, &rx, nil); +} + +char* +_displayrdsnarf(Display *d) +{ + void *p; + char *s; + Wsysmsg tx, rx; + + tx.type = Trdsnarf; + if(displayrpc(d, &tx, &rx, &p) < 0) + return nil; + s = strdup(rx.snarf); + free(p); + return s; +} + +int +_displaywrsnarf(Display *d, char *snarf) +{ + Wsysmsg tx, rx; + + tx.type = Twrsnarf; + tx.snarf = snarf; + return displayrpc(d, &tx, &rx, nil); +} + +int +_displayrddraw(Display *d, void *v, int n) +{ + void *p; + Wsysmsg tx, rx; + + tx.type = Trddraw; + tx.count = n; + if(displayrpc(d, &tx, &rx, &p) < 0) + return -1; + memmove(v, rx.data, rx.count); + free(p); + return rx.count; +} + +int +_displaywrdraw(Display *d, void *v, int n) +{ + Wsysmsg tx, rx; + + tx.type = Twrdraw; + tx.count = n; + tx.data = v; + if(displayrpc(d, &tx, &rx, nil) < 0) + return -1; + return rx.count; +} + +int +_displaytop(Display *d) +{ + Wsysmsg tx, rx; + + tx.type = Ttop; + return displayrpc(d, &tx, &rx, nil); +} + +int +_displayresize(Display *d, Rectangle r) +{ + Wsysmsg tx, rx; + + tx.type = Tresize; + tx.rect = r; + return displayrpc(d, &tx, &rx, nil); +} + diff --git a/src/libdraw/drawfcall.c b/src/libdraw/drawfcall.c new file mode 100644 index 00000000..09a54f91 --- /dev/null +++ b/src/libdraw/drawfcall.c @@ -0,0 +1,367 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <mouse.h> +#include <cursor.h> +#include <drawfcall.h> + +#define PUT(p, x) \ + (p)[0] = ((x) >> 24)&0xFF, \ + (p)[1] = ((x) >> 16)&0xFF, \ + (p)[2] = ((x) >> 8)&0xFF, \ + (p)[3] = (x)&0xFF + +#define GET(p, x) \ + ((x) = (((p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | ((p)[3]))) + +#define PUT2(p, x) \ + (p)[0] = ((x) >> 8)&0xFF, \ + (p)[1] = (x)&0xFF + +#define GET2(p, x) \ + ((x) = (((p)[0] << 8) | ((p)[1]))) + +static int +_stringsize(char *s) +{ + return 4+strlen(s); +} + +static int +PUTSTRING(uchar *p, char *s) +{ + int n; + + if(s == nil) + s = ""; + n = strlen(s); + PUT(p, n); + memmove(p+4, s, n); + return n+4; +} + +static int +GETSTRING(uchar *p, char **s) +{ + int n; + + GET(p, n); + memmove(p, p+4, n); + *s = (char*)p; + p[n] = 0; + return n+4; +} + +uint +sizeW2M(Wsysmsg *m) +{ + switch(m->type){ + default: + return 0; + case Trdmouse: + case Rbouncemouse: + case Rmoveto: + case Rcursor: + case Trdkbd: + case Rlabel: + case Rinit: + case Trdsnarf: + case Rwrsnarf: + case Ttop: + case Rtop: + case Rresize: + return 4+1+1; + case Rrdmouse: + return 4+1+1+4+4+4+4+1; + case Tbouncemouse: + return 4+1+1+4+4+4; + case Tmoveto: + return 4+1+1+4+4; + case Tcursor: + return 4+1+1+4+4+2*16+2*16+1; + case Rerror: + return 4+1+1+_stringsize(m->error); + case Rrdkbd: + return 4+1+1+2; + case Tlabel: + return 4+1+1+_stringsize(m->label); + case Tinit: + return 4+1+1 + +_stringsize(m->winsize) + +_stringsize(m->label); + case Rrdsnarf: + case Twrsnarf: + return 4+1+1+_stringsize(m->snarf); + case Rrddraw: + case Twrdraw: + return 4+1+1+4+m->count; + case Trddraw: + case Rwrdraw: + return 4+1+1+4; + case Tresize: + return 4+1+1+4*4; + } +} + +uint +convW2M(Wsysmsg *m, uchar *p, uint n) +{ + int nn; + + nn = sizeW2M(m); + if(n < nn || nn == 0 || n < 6) + return 0; + PUT(p, nn); + p[4] = m->tag; + p[5] = m->type; + + switch(m->type){ + default: + return 0; + case Trdmouse: + case Rbouncemouse: + case Rmoveto: + case Rcursor: + case Trdkbd: + case Rlabel: + case Rinit: + case Trdsnarf: + case Rwrsnarf: + case Ttop: + case Rtop: + case Rresize: + break; + case Rerror: + PUTSTRING(p+6, m->error); + break; + case Rrdmouse: + PUT(p+6, m->mouse.xy.x); + PUT(p+10, m->mouse.xy.y); + PUT(p+14, m->mouse.buttons); + PUT(p+18, m->mouse.msec); + p[19] = m->resized; + break; + case Tbouncemouse: + PUT(p+6, m->mouse.xy.x); + PUT(p+10, m->mouse.xy.y); + PUT(p+14, m->mouse.buttons); + break; + case Tmoveto: + PUT(p+6, m->mouse.xy.x); + PUT(p+10, m->mouse.xy.y); + break; + case Tcursor: + PUT(p+6, m->cursor.offset.x); + PUT(p+10, m->cursor.offset.y); + memmove(p+14, m->cursor.clr, sizeof m->cursor.clr); + memmove(p+46, m->cursor.set, sizeof m->cursor.set); + p[78] = m->arrowcursor; + break; + case Rrdkbd: + PUT2(p+6, m->rune); + break; + case Tlabel: + PUTSTRING(p+6, m->label); + break; + case Tinit: + p += 6; + p += PUTSTRING(p, m->winsize); + p += PUTSTRING(p, m->label); + break; + case Rrdsnarf: + case Twrsnarf: + PUTSTRING(p+6, m->snarf); + break; + case Rrddraw: + case Twrdraw: + PUT(p+6, m->count); + memmove(p+10, m->data, m->count); + break; + case Trddraw: + case Rwrdraw: + PUT(p+6, m->count); + break; + case Tresize: + PUT(p+6, m->rect.min.x); + PUT(p+10, m->rect.min.y); + PUT(p+14, m->rect.max.x); + PUT(p+18, m->rect.max.y); + break; + } + return nn; +} + +uint +convM2W(uchar *p, uint n, Wsysmsg *m) +{ + int nn; + + if(n < 6) + return 0; + GET(p, nn); + if(nn > n) + return 0; + m->tag = p[4]; + m->type = p[5]; + switch(m->type){ + default: + return 0; + case Trdmouse: + case Rbouncemouse: + case Rmoveto: + case Rcursor: + case Trdkbd: + case Rlabel: + case Rinit: + case Trdsnarf: + case Rwrsnarf: + case Ttop: + case Rtop: + case Rresize: + break; + case Rerror: + GETSTRING(p+6, &m->error); + break; + case Rrdmouse: + GET(p+6, m->mouse.xy.x); + GET(p+10, m->mouse.xy.y); + GET(p+14, m->mouse.buttons); + GET(p+18, m->mouse.msec); + m->resized = p[19]; + break; + case Tbouncemouse: + GET(p+6, m->mouse.xy.x); + GET(p+10, m->mouse.xy.y); + GET(p+14, m->mouse.buttons); + break; + case Tmoveto: + GET(p+6, m->mouse.xy.x); + GET(p+10, m->mouse.xy.y); + break; + case Tcursor: + GET(p+6, m->cursor.offset.x); + GET(p+10, m->cursor.offset.y); + memmove(m->cursor.clr, p+14, sizeof m->cursor.clr); + memmove(m->cursor.set, p+46, sizeof m->cursor.set); + m->arrowcursor = p[78]; + break; + case Rrdkbd: + GET2(p+6, m->rune); + break; + case Tlabel: + GETSTRING(p+6, &m->label); + break; + case Tinit: + p += 6; + p += GETSTRING(p, &m->winsize); + p += GETSTRING(p, &m->label); + break; + case Rrdsnarf: + case Twrsnarf: + GETSTRING(p+6, &m->snarf); + break; + case Rrddraw: + case Twrdraw: + GET(p+6, m->count); + m->data = p+10; + break; + case Trddraw: + case Rwrdraw: + GET(p+6, m->count); + break; + case Tresize: + GET(p+6, m->rect.min.x); + GET(p+10, m->rect.min.y); + GET(p+14, m->rect.max.x); + GET(p+18, m->rect.max.y); + break; + } + return nn; +} + +int +readwsysmsg(int fd, uchar *buf, uint nbuf) +{ + int n; + + if(nbuf < 6) + return -1; + if(readn(fd, buf, 4) != 4) + return -1; + GET(buf, n); + if(n > nbuf) + return -1; + if(readn(fd, buf+4, n-4) != n-4) + return -1; + return n; +} + +int +drawfcallfmt(Fmt *fmt) +{ + Wsysmsg *m; + + m = va_arg(fmt->args, Wsysmsg*); + fmtprint(fmt, "tag=%d ", m->tag); + switch(m->type){ + default: + return fmtprint(fmt, "unknown msg %d", m->type); + case Rerror: + return fmtprint(fmt, "Rerror error='%s'", m->error); + case Trdmouse: + return fmtprint(fmt, "Trdmouse"); + case Rrdmouse: + return fmtprint(fmt, "Rrdmouse x=%d y=%d buttons=%d msec=%d resized=%d", + m->mouse.xy.x, m->mouse.xy.y, + m->mouse.buttons, m->mouse.msec, m->resized); + case Tbouncemouse: + return fmtprint(fmt, "Tbouncemouse x=%d y=%d buttons=%d", + m->mouse.xy.x, m->mouse.xy.y, m->mouse.buttons); + case Rbouncemouse: + return fmtprint(fmt, "Rbouncemouse"); + case Tmoveto: + return fmtprint(fmt, "Tmoveto x=%d y=%d", m->mouse.xy.x, m->mouse.xy.y); + case Rmoveto: + return fmtprint(fmt, "Rmoveto"); + case Tcursor: + return fmtprint(fmt, "Tcursor arrow=%d", m->arrowcursor); + case Rcursor: + return fmtprint(fmt, "Rcursor"); + case Trdkbd: + return fmtprint(fmt, "Trdkbd"); + case Rrdkbd: + return fmtprint(fmt, "Rrdkbd rune=%C", m->rune); + case Tlabel: + return fmtprint(fmt, "Tlabel label='%s'", m->label); + case Rlabel: + return fmtprint(fmt, "Rlabel"); + case Tinit: + return fmtprint(fmt, "Tinit label='%s' winsize='%s'", m->label, m->winsize); + case Rinit: + return fmtprint(fmt, "Rinit"); + case Trdsnarf: + return fmtprint(fmt, "Trdsnarf"); + case Rrdsnarf: + return fmtprint(fmt, "Rrdsnarf snarf='%s'", m->snarf); + case Twrsnarf: + return fmtprint(fmt, "Twrsnarf snarf='%s'", m->snarf); + case Rwrsnarf: + return fmtprint(fmt, "Rwrsnarf"); + case Trddraw: + return fmtprint(fmt, "Trddraw %d", m->count); + case Rrddraw: + return fmtprint(fmt, "Rrddraw %d %.*H", m->count, m->count, m->data); + case Twrdraw: + return fmtprint(fmt, "Twrdraw %d %.*H", m->count, m->count, m->data); + case Rwrdraw: + return fmtprint(fmt, "Rwrdraw %d", m->count); + case Ttop: + return fmtprint(fmt, "Ttop"); + case Rtop: + return fmtprint(fmt, "Rtop"); + case Tresize: + return fmtprint(fmt, "Tresize %R", m->rect); + case Rresize: + return fmtprint(fmt, "Rresize"); + } +} diff --git a/src/libdraw/snarf.c b/src/libdraw/snarf.c new file mode 100644 index 00000000..d5ad4827 --- /dev/null +++ b/src/libdraw/snarf.c @@ -0,0 +1,15 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> + +void +putsnarf(char *snarf) +{ + _displaywrsnarf(display, snarf); +} + +char* +getsnarf(void) +{ + return _displayrdsnarf(display); +} diff --git a/src/libdraw/wsys.c b/src/libdraw/wsys.c new file mode 100644 index 00000000..e8136177 --- /dev/null +++ b/src/libdraw/wsys.c @@ -0,0 +1,24 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> + +int _wantfocuschanges; + +void +drawtopwindow(void) +{ + _displaytop(display); +} + +int +drawsetlabel(char *label) +{ + return _displaylabel(display, label); +} + +void +bouncemouse(Mouse *m) +{ + _displaybouncemouse(display, m); +} + |