| #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"); |
| } |
| } |