diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-07-30 02:21:28 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-07-30 02:21:28 +0200 |
commit | 36abc45f2895ebc6b02f746586e814349581579b (patch) | |
tree | 38b8630235d82554a35a068abf06b769b3e5e11a /sys/src/cmd/vnc | |
parent | da5c0bada7be9dd82ca1f63e621670143597d3bb (diff) |
vncv: implement extended DesktopSize extension, cleanup
Diffstat (limited to 'sys/src/cmd/vnc')
-rw-r--r-- | sys/src/cmd/vnc/draw.c | 82 | ||||
-rw-r--r-- | sys/src/cmd/vnc/vnc.h | 15 | ||||
-rw-r--r-- | sys/src/cmd/vnc/vncs.c | 34 | ||||
-rw-r--r-- | sys/src/cmd/vnc/vncv.c | 9 | ||||
-rw-r--r-- | sys/src/cmd/vnc/wsys.c | 25 |
5 files changed, 93 insertions, 72 deletions
diff --git a/sys/src/cmd/vnc/draw.c b/sys/src/cmd/vnc/draw.c index 9941b81f0..d55719cfd 100644 --- a/sys/src/cmd/vnc/draw.c +++ b/sys/src/cmd/vnc/draw.c @@ -11,6 +11,8 @@ static struct { "raw", EncRaw, "rre", EncRre, "mousewarp", EncMouseWarp, + "desktopsize", EncDesktopSize, + "xdesktopsize", EncXDesktopSize, }; static uchar *pixbuf; @@ -20,6 +22,16 @@ static int pixb; static void (*pixcp)(uchar*, uchar*); static void +vncsetdim(Vnc *v, Rectangle dim) +{ + v->dim = rectsubpt(dim, dim.min); + linebuf = realloc(linebuf, v->dim.max.x * vpixb); + pixbuf = realloc(pixbuf, v->dim.max.x * pixb * v->dim.max.y); + if(linebuf == nil || pixbuf == nil) + sysfatal("can't allocate pix decompression storage"); +} + +static void vncrdcolor(Vnc *v, uchar *color) { vncrdbytes(v, color, vpixb); @@ -31,8 +43,8 @@ vncrdcolor(Vnc *v, uchar *color) void sendencodings(Vnc *v) { - char *f[10]; - int enc[10], nenc, i, j, nf; + char *f[16]; + int enc[16], nenc, i, j, nf; nf = tokenize(encodings, f, nelem(f)); nenc = 0; @@ -60,21 +72,27 @@ sendencodings(Vnc *v) void requestupdate(Vnc *v, int incremental) { - int x, y; + Rectangle r; lockdisplay(display); flushimage(display, 1); - x = Dx(screen->r); - y = Dy(screen->r); + r = rectsubpt(screen->r, screen->r.min); unlockdisplay(display); - if(x > v->dim.x) - x = v->dim.x; - if(y > v->dim.y) - y = v->dim.y; vnclock(v); + if(incremental == 0 && v->canresize && !eqrect(r, v->dim)){ + vncwrchar(v, MSetDesktopSize); + vncwrchar(v, 0); + vncwrpoint(v, r.max); + vncwrchar(v, 1); + vncwrchar(v, 0); + vncwrlong(v, v->screen[0].id); + vncwrrect(v, r); + vncwrlong(v, v->screen[0].flags); + } else + rectclip(&r, v->dim); vncwrchar(v, MFrameReq); vncwrchar(v, incremental); - vncwrrect(v, Rpt(ZP, Pt(x, y))); + vncwrrect(v, r); vncflush(v); vncunlock(v); } @@ -237,16 +255,42 @@ dorectangle(Vnc *v) Rectangle r, subr, maxr; r = vncrdrect(v); - if(!rectinrect(r, Rpt(ZP, v->dim))) - sysfatal("bad rectangle from server: %R not in %R", r, Rpt(ZP, v->dim)); - stride = Dx(r) * pixb; type = vncrdlong(v); switch(type){ + case EncMouseWarp: + mousewarp(r.min); + return; + + case EncXDesktopSize: + v->canresize = 1; + n = vncrdlong(v)>>24; + if(n <= 0) + break; + v->screen[0].id = vncrdlong(v); + v->screen[0].rect = vncrdrect(v); + v->screen[0].flags = vncrdlong(v); + while(--n > 0){ + vncrdlong(v); + vncrdrect(v); + vncrdlong(v); + } + /* wet floor */ + case EncDesktopSize: + vncsetdim(v, r); + return; + } + + if(!rectinrect(r, v->dim)) + sysfatal("bad rectangle from server: %R not in %R", r, v->dim); + maxr = rectsubpt(r, r.min); + stride = maxr.max.x * pixb; + + switch(type){ default: sysfatal("bad rectangle encoding from server"); break; case EncRaw: - loadbuf(v, Rpt(ZP, Pt(Dx(r), Dy(r))), stride); + loadbuf(v, maxr, stride); updatescreen(r); break; @@ -261,7 +305,6 @@ dorectangle(Vnc *v) case EncRre: case EncCorre: - maxr = Rpt(ZP, Pt(Dx(r), Dy(r))); n = vncrdlong(v); vncrdcolor(v, (uchar*)&color); fillrect(maxr, stride, (uchar*)&color); @@ -282,10 +325,6 @@ dorectangle(Vnc *v) dohextile(v, r, stride); updatescreen(r); break; - - case EncMouseWarp: - mousewarp(r.min); - break; } } @@ -348,10 +387,7 @@ readfromserver(Vnc *v) default: sysfatal("can't handle your screen: bad depth %d", pixb); } - linebuf = malloc(v->dim.x * vpixb); - pixbuf = malloc(v->dim.x * pixb * v->dim.y); - if(linebuf == nil || pixbuf == nil) - sysfatal("can't allocate pix decompression storage"); + vncsetdim(v, v->dim); for(;;){ type = vncrdchar(v); switch(type){ diff --git a/sys/src/cmd/vnc/vnc.h b/sys/src/cmd/vnc/vnc.h index afa020624..b0eed373b 100644 --- a/sys/src/cmd/vnc/vnc.h +++ b/sys/src/cmd/vnc/vnc.h @@ -31,9 +31,16 @@ struct Vnc { Biobuf in; Biobuf out; - Point dim; + Rectangle dim; Pixfmt; char *name; /* client only */ + + int canresize; + struct { + ulong id; + Rectangle rect; + ulong flags; + } screen[1]; }; enum { @@ -63,6 +70,7 @@ enum { MKey, MMouse, MCCut, + MSetDesktopSize = 251, /* image encoding methods */ EncRaw = 0, @@ -75,6 +83,9 @@ enum { EncZHextile = 8, EncMouseWarp = 9, + EncDesktopSize = -223, + EncXDesktopSize = -308, + /* paramaters for hextile encoding */ HextileDim = 16, HextileRaw = 1, @@ -131,4 +142,4 @@ extern void hexdump(void*, int); extern void vnchungup(Vnc*); extern int verbose; -extern char* serveraddr;
\ No newline at end of file +extern char* serveraddr; diff --git a/sys/src/cmd/vnc/vncs.c b/sys/src/cmd/vnc/vncs.c index f613ec864..efa1b996d 100644 --- a/sys/src/cmd/vnc/vncs.c +++ b/sys/src/cmd/vnc/vncs.c @@ -21,29 +21,6 @@ Dev *devtab[] = nil }; -static char *msgname[] = { - [MPixFmt] = "MPixFmt", - [MFixCmap] = "MFixCmap", - [MSetEnc] = "MSetEnc", - [MFrameReq] = "MFrameReq", - [MKey] = "MKey", - [MMouse] = "MMouse", - [MCCut] = "MCCut", -}; - -static char *encname[] = { - [EncRaw] = "raw", - [EncCopyRect] = "copy rect", - [EncRre] = "rre", - [EncCorre] = "corre", - [EncHextile] = "hextile", - [EncZlib] = "zlib", - [EncTight] = "zlibtight", - [EncZHextile] = "zhextile", - [EncMouseWarp] = "mousewarp", - -}; - /* * list head. used to hold the list, the lock, dim, and pixelfmt */ @@ -594,10 +571,10 @@ vncaccept(Vncs *v) if(!shared) killclients(v); - v->dim = (Point){Dx(gscreen->r), Dy(gscreen->r)}; - vncwrpoint(v, v->dim); + v->dim = rectsubpt(screen->r, screen->r.min); + vncwrpoint(v, v->dim.max); if(verbose) - fprint(2, "%V: send screen size %P (rect %R)\n", v, v->dim, gscreen->r); + fprint(2, "%V: send screen size %R\n", v, v->dim); v->bpp = gscreen->depth; v->depth = gscreen->depth; @@ -696,6 +673,9 @@ setencoding(Vncs *v) case EncMouseWarp: v->canwarp = 1; continue; + case EncDesktopSize: + case EncXDesktopSize: + continue; } if(v->countrect != nil) continue; @@ -1118,7 +1098,7 @@ clientwriteproc(Vncs *v) || (v->image && v->image->chan != v->imagechan)){ if(v->image) freememimage(v->image); - v->image = allocmemimage(Rpt(ZP, v->dim), v->imagechan); + v->image = allocmemimage(v->dim, v->imagechan); if(v->image == nil){ fprint(2, "%V: allocmemimage: %r; hanging up\n", v); vnchungup(v); diff --git a/sys/src/cmd/vnc/vncv.c b/sys/src/cmd/vnc/vncv.c index fcd262836..95f7b6a25 100644 --- a/sys/src/cmd/vnc/vncv.c +++ b/sys/src/cmd/vnc/vncv.c @@ -3,7 +3,7 @@ #include <libsec.h> char* charset = "utf-8"; -char* encodings = "copyrect hextile corre rre raw mousewarp"; +char* encodings = "copyrect hextile corre rre raw mousewarp desktopsize xdesktopsize"; int bpp12; int shared; int verbose; @@ -77,7 +77,6 @@ main(int argc, char **argv) { int p, dfd, cfd, shared; char *keypattern, *label; - Point d; keypattern = nil; shared = 0; @@ -140,10 +139,6 @@ main(int argc, char **argv) display->locking = 1; unlockdisplay(display); - d = addpt(vnc->dim, Pt(2*Borderwidth, 2*Borderwidth)); - if(verbose) - fprint(2, "screen size %P, desktop size %P\n", display->image->r.max, d); - choosecolor(vnc); sendencodings(vnc); initmouse(); @@ -197,7 +192,7 @@ vncstart(Vnc *v, int shared) { vncwrchar(v, shared); vncflush(v); - v->dim = vncrdpoint(v); + v->dim = Rpt(ZP, vncrdpoint(v)); v->Pixfmt = vncrdpixfmt(v); v->name = vncrdstring(v); return 0; diff --git a/sys/src/cmd/vnc/wsys.c b/sys/src/cmd/vnc/wsys.c index 9e5c1cd0a..21c8ce424 100644 --- a/sys/src/cmd/vnc/wsys.c +++ b/sys/src/cmd/vnc/wsys.c @@ -16,20 +16,20 @@ 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); + if(!v->canresize){ + /* + * limit the window to at most the vnc server's size + */ + d = addpt(v->dim.max, Pt(2*Borderwidth, 2*Borderwidth)); + 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); @@ -39,7 +39,6 @@ static void eresized(void) { resize(vnc, 0); - requestupdate(vnc, 0); } @@ -147,7 +146,7 @@ readmouse(Vnc *v) 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))){ + if(ptinrect(m.xy, v->dim)){ mouseevent(v, m); /* send wheel button *release* */ if ((m.buttons & 0x7) != m.buttons) { |