shithub: riscv

Download patch

ref: 36abc45f2895ebc6b02f746586e814349581579b
parent: da5c0bada7be9dd82ca1f63e621670143597d3bb
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Jul 29 22:21:28 EDT 2018

vncv: implement extended DesktopSize extension, cleanup

--- a/sys/src/cmd/vnc/draw.c
+++ b/sys/src/cmd/vnc/draw.c
@@ -11,6 +11,8 @@
 	"raw",		EncRaw,
 	"rre",		EncRre,
 	"mousewarp",	EncMouseWarp,
+	"desktopsize",	EncDesktopSize,
+	"xdesktopsize",	EncXDesktopSize,
 };
 
 static	uchar	*pixbuf;
@@ -20,6 +22,16 @@
 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 @@
 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 @@
 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 @@
 	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 @@
 
 	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 @@
 		dohextile(v, r, stride);
 		updatescreen(r);
 		break;
-
-	case EncMouseWarp:
-		mousewarp(r.min);
-		break;
 	}
 }
 
@@ -348,10 +387,7 @@
 	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){
--- a/sys/src/cmd/vnc/vnc.h
+++ b/sys/src/cmd/vnc/vnc.h
@@ -31,9 +31,16 @@
 	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 @@
 	MKey,
 	MMouse,
 	MCCut,
+	MSetDesktopSize = 251,
 
 	/* image encoding methods */
 	EncRaw		= 0,
@@ -75,6 +83,9 @@
 	EncZHextile	= 8,
 	EncMouseWarp	= 9,
 
+	EncDesktopSize	= -223,
+	EncXDesktopSize	= -308,
+
 	/* paramaters for hextile encoding */
 	HextileDim	= 16,
 	HextileRaw	= 1,
@@ -131,4 +142,4 @@
 extern	void		vnchungup(Vnc*);
 
 extern	int		verbose;
-extern	char*	serveraddr;
\ No newline at end of file
+extern	char*		serveraddr;
--- a/sys/src/cmd/vnc/vncs.c
+++ b/sys/src/cmd/vnc/vncs.c
@@ -21,29 +21,6 @@
 	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 @@
 	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 @@
 		case EncMouseWarp:
 			v->canwarp = 1;
 			continue;
+		case EncDesktopSize:
+		case EncXDesktopSize:
+			continue;
 		}
 		if(v->countrect != nil)
 			continue;
@@ -1118,7 +1098,7 @@
 		|| (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);
--- 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 @@
 {
 	int p, dfd, cfd, shared;
 	char *keypattern, *label;
-	Point d;
 
 	keypattern = nil;
 	shared = 0;
@@ -140,10 +139,6 @@
 	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 @@
 {
 	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;
--- a/sys/src/cmd/vnc/wsys.c
+++ b/sys/src/cmd/vnc/wsys.c
@@ -16,20 +16,20 @@
 	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 @@
 eresized(void)
 {
 	resize(vnc, 0);
-
 	requestupdate(vnc, 0);
 }
 
@@ -147,7 +146,7 @@
 				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) {