diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/vnc/wsys.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/vnc/wsys.c')
-rwxr-xr-x | sys/src/cmd/vnc/wsys.c | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/sys/src/cmd/vnc/wsys.c b/sys/src/cmd/vnc/wsys.c new file mode 100755 index 000000000..bc088782c --- /dev/null +++ b/sys/src/cmd/vnc/wsys.c @@ -0,0 +1,259 @@ +#include "vnc.h" +#include "vncv.h" +#include <cursor.h> + +typedef struct Cursor Cursor; + +typedef struct Mouse Mouse; +struct Mouse { + int buttons; + Point xy; +}; + +static void +resize(Vnc *v, int first) +{ + int fd; + Point d; + + d = addpt(v->dim, Pt(2*Borderwidth, 2*Borderwidth)); + lockdisplay(display); + + if(getwindow(display, Refnone) < 0) + sysfatal("internal error: can't get the window image"); + + /* + * limit the window to at most the vnc server's size + */ + if(first || d.x < Dx(screen->r) || d.y < Dy(screen->r)){ + fd = open("/dev/wctl", OWRITE); + if(fd >= 0){ + fprint(fd, "resize -dx %d -dy %d", d.x, d.y); + close(fd); + } + } + unlockdisplay(display); +} + +static void +eresized(void) +{ + resize(vnc, 0); + + requestupdate(vnc, 0); +} + +static Cursor dotcursor = { + {-7, -7}, + {0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x03, 0xc0, + 0x07, 0xe0, + 0x0f, 0xf0, + 0x0f, 0xf0, + 0x0f, 0xf0, + 0x07, 0xe0, + 0x03, 0xc0, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, }, + {0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x03, 0xc0, + 0x07, 0xe0, + 0x07, 0xe0, + 0x07, 0xe0, + 0x03, 0xc0, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, } +}; + +static void +mouseevent(Vnc *v, Mouse m) +{ + vnclock(v); + vncwrchar(v, MMouse); + vncwrchar(v, m.buttons); + vncwrpoint(v, m.xy); + vncflush(v); + vncunlock(v); +} + +void +mousewarp(Point pt) +{ + pt = addpt(pt, screen->r.min); + if(fprint(mousefd, "m%d %d", pt.x, pt.y) < 0) + fprint(2, "mousefd write: %r\n"); +} + +void +initmouse(void) +{ + char buf[1024]; + + snprint(buf, sizeof buf, "%s/mouse", display->devdir); + if((mousefd = open(buf, ORDWR)) < 0) + sysfatal("open %s: %r", buf); +} + +enum { + EventSize = 1+4*12 +}; +void +readmouse(Vnc *v) +{ + int cursorfd, len, n; + char buf[10*EventSize], *start, *end; + uchar curs[2*4+2*2*16]; + Cursor *cs; + Mouse m; + + cs = &dotcursor; + + snprint(buf, sizeof buf, "%s/cursor", display->devdir); + if((cursorfd = open(buf, OWRITE)) < 0) + sysfatal("open %s: %r", buf); + + BPLONG(curs+0*4, cs->offset.x); + BPLONG(curs+1*4, cs->offset.y); + memmove(curs+2*4, cs->clr, 2*2*16); + write(cursorfd, curs, sizeof curs); + + resize(v, 1); + requestupdate(vnc, 0); + start = end = buf; + len = 0; + for(;;){ + if((n = read(mousefd, end, sizeof(buf) - (end - buf))) < 0) + sysfatal("read mouse failed"); + + len += n; + end += n; + while(len >= EventSize){ + if(*start == 'm'){ + m.xy.x = atoi(start+1); + m.xy.y = atoi(start+1+12); + m.buttons = atoi(start+1+2*12) & 0x1F; + m.xy = subpt(m.xy, screen->r.min); + if(ptinrect(m.xy, Rpt(ZP, v->dim))){ + mouseevent(v, m); + /* send wheel button *release* */ + if ((m.buttons & 0x7) != m.buttons) { + m.buttons &= 0x7; + mouseevent(v, m); + } + } + } else + eresized(); + + start += EventSize; + len -= EventSize; + } + if(start - buf > sizeof(buf) - EventSize){ + memmove(buf, start, len); + start = buf; + end = start+len; + } + } +} + +static int snarffd = -1; +static ulong snarfvers; + +void +writesnarf(Vnc *v, long n) +{ + uchar buf[8192]; + long m; + Biobuf *b; + + if((b = Bopen("/dev/snarf", OWRITE)) == nil){ + vncgobble(v, n); + return; + } + + while(n > 0){ + m = n; + if(m > sizeof(buf)) + m = sizeof(buf); + vncrdbytes(v, buf, m); + n -= m; + + Bwrite(b, buf, m); + } + Bterm(b); + snarfvers++; +} + +char * +getsnarf(int *sz) +{ + char *snarf, *p; + int n, c; + + *sz =0; + n = 8192; + p = snarf = malloc(n); + + seek(snarffd, 0, 0); + while ((c = read(snarffd, p, n)) > 0){ + p += c; + n -= c; + *sz += c; + if (n == 0){ + snarf = realloc(snarf, *sz + 8192); + n = 8192; + } + } + return snarf; +} + +void +checksnarf(Vnc *v) +{ + Dir *dir; + char *snarf; + int len; + + if(snarffd < 0){ + snarffd = open("/dev/snarf", OREAD); + if(snarffd < 0) + sysfatal("can't open /dev/snarf: %r"); + } + + for(;;){ + sleep(1000); + + dir = dirstat("/dev/snarf"); + if(dir == nil) /* this happens under old drawterm */ + continue; + if(dir->qid.vers > snarfvers){ + snarf = getsnarf(&len); + + vnclock(v); + vncwrchar(v, MCCut); + vncwrbytes(v, "pad", 3); + vncwrlong(v, len); + vncwrbytes(v, snarf, len); + vncflush(v); + vncunlock(v); + + free(snarf); + + snarfvers = dir->qid.vers; + } + free(dir); + } +} |