|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <draw.h> | 
|  | #include <mouse.h> | 
|  | #include <cursor.h> | 
|  | #include <drawfcall.h> | 
|  |  | 
|  | static int | 
|  | _stringsize(char *s) | 
|  | { | 
|  | if(s == nil) | 
|  | 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"); | 
|  | } | 
|  | } |