From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: ** X-Spam-Status: No, score=2.3 required=5.0 tests=DATE_IN_PAST_96_XX, DKIM_INVALID,DKIM_SIGNED,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.4 Received: (qmail 8928 invoked from network); 21 Dec 2023 05:49:25 -0000 Received: from 9front.inri.net (168.235.81.73) by inbox.vuxu.org with ESMTPUTF8; 21 Dec 2023 05:49:25 -0000 Received: from pb-smtp20.pobox.com ([173.228.157.52]) by 9front; Thu Dec 21 00:47:45 -0500 2023 Received: from pb-smtp20.pobox.com (unknown [127.0.0.1]) by pb-smtp20.pobox.com (Postfix) with ESMTP id 29B0632DCA for <9front@9front.org>; Thu, 21 Dec 2023 00:47:39 -0500 (EST) (envelope-from unobe@cpan.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=pobox.com; h=message-id :to:from:date:subject:mime-version:content-type :content-transfer-encoding; s=sasl; bh=P9MNL/cqFktxJRCI0+o8mPnzF lfzwJcekvpabo3+wy0=; b=LtJNhCT1RV02paU6tiWJD3NG6dL5Ef77XCRQy1EzS YN1SQ8A5H+BTSdr+NIjzAFGFoREt2y60SAdDkuAvw8KZSMexL6mUC++5cMVaSEH5 aKq33TQNwRQbd+66PVpK3/zOnZeiLg5rrD4tOSz7Q7wFjFB9K2wbmhQMVRHYWQJN IY= Received: from pb-smtp20.sea.icgroup.com (unknown [127.0.0.1]) by pb-smtp20.pobox.com (Postfix) with ESMTP id 216B232DC9 for <9front@9front.org>; Thu, 21 Dec 2023 00:47:39 -0500 (EST) (envelope-from unobe@cpan.org) Received: from strider.localdomain (unknown [24.205.13.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pb-smtp20.pobox.com (Postfix) with ESMTPSA id 8BD5E32DC8 for <9front@9front.org>; Thu, 21 Dec 2023 00:47:35 -0500 (EST) (envelope-from unobe@cpan.org) Message-ID: <6A702D8C3A558319FD44AF77F32C8A6D@smtp.pobox.com> To: 9front@9front.org From: Romano Date: Sat, 30 Sep 2023 01:29:29 +0000 MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Pobox-Relay-ID: 712E3F2C-9FC4-11EE-A69C-F515D2CDFF5E-09620299!pb-smtp20.pobox.com List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: method ACPI over SSL component wrapper grid Subject: [9front] [PATCH] vncv: implement autoscaling with -a flag Reply-To: 9front@9front.org Precedence: bulk for large remote framebuffers, only the upper left-hand corner of the screen is ever visible. Autoscaling, while slow, at least makes all the screen visible. There is a noticeable lag while the scaling occurs, but vncv as-is isn't a paragon of speed. While in the code, update documentation for this feature. --- diff a125c800817a8356de8580da78b7d9bd0ef95090 db2177614df64fa9ccf3dae30cdf24df1ce0a0be --- a/sys/man/1/vnc +++ b/sys/man/1/vnc @@ -44,7 +44,7 @@ .PP .B vncv [ -.B -cstv +.B -acstv ] [ .B -e @@ -146,10 +146,14 @@ provides access to remote display .IB host : n \fR. It resizes its window to be the smaller of the -remote frame buffer size and the local screen. +remote frame buffer size and the local screen +when not using the autoscaling option. .PP The options are: .TP +.B -a +autoscale the remote framebuffer to the size of the +local screen window. .B -c when connecting to 8-bit displays, request .B r4g4b4 @@ -166,7 +170,10 @@ .B corre .B hextile .B rre -.BR raw . +.B raw +.B mousewarp +.B desktopsize +.BR xdesktopsize . The encodings should be given as a single space-separated argument (quoted when using the shell). .TP @@ -198,7 +205,7 @@ .SH "SEE ALSO .B http://www.uk.research.att.com/vnc .SH BUGS -If the remote frame buffer is larger than the local screen, +Autoscaling is only implemented for raw encoding. When not in use, if the remote frame buffer is larger than the local screen then only the upper left corner can be accessed. .PP .I Vncs --- a/sys/src/cmd/vnc/draw.c +++ b/sys/src/cmd/vnc/draw.c @@ -20,8 +20,18 @@ static int vpixb; static int pixb; static void (*pixcp)(uchar*, uchar*); +static double scalex; +static double scaley; static void +vncsetscale(Vnc *v) +{ + scalex = (v->dim.max.x - v->dim.min.x) / (double)(screen->r.max.x - screen->r.min.x); + scaley = (v->dim.max.y - v->dim.min.y) / (double)(screen->r.max.y - screen->r.min.y); + if(verbose > 1) fprint(2, "scaling %fx%f\n", scalex, scaley); +} + +static void vncsetdim(Vnc *v, Rectangle dim) { v->dim = rectsubpt(dim, dim.min); @@ -79,7 +89,7 @@ lockdisplay(display); flushimage(display, 1); - r = rectsubpt(screen->r, screen->r.min); + r = autoscale ? v->dim : rectsubpt(screen->r, screen->r.min); unlockdisplay(display); vnclock(v); if(incremental == 0 && (v->canresize&2)!=0 && !eqrect(r, v->dim)){ @@ -94,7 +104,7 @@ } else rectclip(&r, v->dim); vncwrchar(v, MFrameReq); - vncwrchar(v, incremental); + vncwrchar(v, autoscale ? 0 : incremental); vncwrrect(v, r); vncflush(v); vncunlock(v); @@ -167,7 +177,8 @@ static void loadbuf(Vnc *v, Rectangle r, int stride) { - int off, y; + int off; + double x, y, endy; if(cvtpixels){ y = r.min.y; @@ -185,6 +196,12 @@ off += stride; } } + if(autoscale){ + endy = off/(double)stride; + for(y = 0; y < endy; y += scaley) + for(x = 0; x < stride; x+=scalex) + memmove(&pixbuf[(int)(y/scaley)*stride+(int)(x/scalex)/pixb*pixb], &pixbuf[(int)(y)*stride+(int)(x/pixb)*pixb], pixb); + } } static Rectangle @@ -286,12 +303,15 @@ if(!rectinrect(r, v->dim)) sysfatal("bad rectangle from server: %R not in %R", r, v->dim); - maxr = rectsubpt(r, r.min); + maxr = autoscale ? rectsubpt(v->dim, v->dim.min) : rectsubpt( r, r.min ); + maxr.max.x = Dx(maxr); maxr.min.x = 0; + maxr.max.y = Dy(maxr); maxr.min.y = 0; stride = maxr.max.x * pixb; + if(verbose > 2) fprint(2, "maxr.max.x %d; maxr.max.y %d; maxr.min.x %d; maxr.min.y %d, pixb: %d, stride: %ld, type: %lx\n", maxr.max.x, maxr.max.y, maxr.min.x, maxr.min.y, pixb, stride, type); switch(type){ default: - sysfatal("bad rectangle encoding from server"); + sysfatal("bad rectangle encoding from server: %lx", type); break; case EncRaw: loadbuf(v, maxr, stride); @@ -399,6 +419,8 @@ sysfatal("bad message from server: %x", type); break; case MFrameUpdate: + if(autoscale) + vncsetscale(v); vncrdchar(v); n = vncrdshort(v); while(n-- > 0) --- a/sys/src/cmd/vnc/vncv.c +++ b/sys/src/cmd/vnc/vncv.c @@ -4,6 +4,7 @@ char* charset = "utf-8"; char* encodings = "copyrect hextile corre rre raw mousewarp desktopsize xdesktopsize"; +int autoscale; int bpp12; int shared; int verbose; @@ -74,7 +75,7 @@ void usage(void) { - fprint(2, "usage: vncv [-e encodings] [-k keypattern] [-l charset] [-csv] host[:n]\n"); + fprint(2, "usage: vncv [-acstv] [-e encodings] [-l charset] [-k keypattern] host[:n]\n"); exits("usage"); } @@ -87,6 +88,9 @@ keypattern = nil; shared = 0; ARGBEGIN{ + case 'a': + autoscale = 1; + break; case 'c': bpp12 = 1; break; --- a/sys/src/cmd/vnc/vncv.h +++ b/sys/src/cmd/vnc/vncv.h @@ -13,6 +13,7 @@ /* vncv.c */ extern char *charset; extern char *encodings; +extern int autoscale; extern int bpp12; extern Vnc* vnc; extern int mousefd; --- a/sys/src/cmd/vnc/wsys.c +++ b/sys/src/cmd/vnc/wsys.c @@ -48,7 +48,7 @@ if(getwindow(display, Refnone) < 0) sysfatal("internal error: can't get the window image"); if((vnc->canresize&2) == 0) - adjustwin(vnc, first); + adjustwin(vnc, !autoscale && first); unlockdisplay(display); requestupdate(vnc, 0); } @@ -154,8 +154,12 @@ 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(autoscale){ + m.xy.x *= (v->dim.max.x - v->dim.min.x) / (double)(screen->r.max.x - screen->r.min.x); + m.xy.y *= (v->dim.max.y - v->dim.min.y) / (double)(screen->r.max.y - screen->r.min.y); + } + m.buttons = atoi(start+1+2*12) & 0x1F; if(ptinrect(m.xy, v->dim)){ mouseevent(v, m); /* send wheel button *release* */