summaryrefslogtreecommitdiff
path: root/sys/src/cmd/vnc/vncs.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2018-08-20 19:23:42 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2018-08-20 19:23:42 +0200
commitd2089f949edd71626e2391672b723aa2d9fbcb9b (patch)
tree0709ec4e1abfb8805f08ceb24587f6a8e84fddf6 /sys/src/cmd/vnc/vncs.c
parent670137bf0a75813df93d9b727ce70ddb099d11e1 (diff)
vncs: support for desktop resize extension, update devdraw
Diffstat (limited to 'sys/src/cmd/vnc/vncs.c')
-rw-r--r--sys/src/cmd/vnc/vncs.c192
1 files changed, 115 insertions, 77 deletions
diff --git a/sys/src/cmd/vnc/vncs.c b/sys/src/cmd/vnc/vncs.c
index ef6965957..376f93830 100644
--- a/sys/src/cmd/vnc/vncs.c
+++ b/sys/src/cmd/vnc/vncs.c
@@ -571,7 +571,7 @@ vncaccept(Vncs *v)
if(!shared)
killclients(v);
- v->dim = rectsubpt(gscreen->r, gscreen->r.min);
+ v->dim = rectsubpt(gscreen->clipr, gscreen->clipr.min);
vncwrpoint(v, v->dim.max);
if(verbose)
fprint(2, "%V: send screen size %R\n", v, v->dim);
@@ -592,6 +592,8 @@ vncaccept(Vncs *v)
if(verbose)
fprint(2, "%V: handshaking done\n", v);
+ v->updatereq = 0;
+
switch(rfork(RFPROC|RFMEM)){
case -1:
fprint(2, "%V: cannot fork: %r; hanging up\n", v);
@@ -674,7 +676,10 @@ setencoding(Vncs *v)
v->canwarp = 1;
continue;
case EncDesktopSize:
+ v->canresize |= 1;
+ continue;
case EncXDesktopSize:
+ v->canresize |= 2;
continue;
}
if(v->countrect != nil)
@@ -710,9 +715,10 @@ setencoding(Vncs *v)
}
if(verbose)
- fprint(2, "Encoding with %s%s%s\n", v->encname,
+ fprint(2, "Encoding with %s%s%s%s\n", v->encname,
v->copyrect ? ", copyrect" : "",
- v->canwarp ? ", canwarp" : "");
+ v->canwarp ? ", canwarp" : "",
+ v->canresize ? ", resize" : "");
}
/*
@@ -755,18 +761,40 @@ clientreadproc(Vncs *v)
case MFrameReq:
incremental = vncrdchar(v);
r = vncrdrect(v);
- if(incremental){
- vnclock(v);
- v->updaterequest = 1;
- vncunlock(v);
- }else{
- drawlock(); /* protects rlist */
- vnclock(v); /* protects updaterequest */
- v->updaterequest = 1;
+ if(!incremental){
+ qlock(&drawlock); /* protects rlist */
addtorlist(&v->rlist, r);
- vncunlock(v);
- drawunlock();
+ qunlock(&drawlock);
}
+ v->updatereq++;
+ break;
+
+ case MSetDesktopSize:
+ vncrdchar(v);
+ vncrdpoint(v); // desktop size
+ n = vncrdchar(v);
+ vncrdchar(v);
+ if(n == 0)
+ break;
+ vncrdlong(v); // id
+ r = vncrdrect(v);
+ vncrdlong(v); // flags
+ while(--n > 0){
+ vncrdlong(v);
+ vncrdrect(v);
+ vncrdlong(v);
+ }
+ qlock(&drawlock);
+ if(!rectclip(&r, gscreen->r)){
+ qunlock(&drawlock);
+ break;
+ }
+ gscreen->clipr = r;
+ qunlock(&drawlock);
+
+ screenwin();
+ deletescreenimage();
+ resetscreenimage();
break;
/* send keystroke */
@@ -905,7 +933,7 @@ flushmemscreen(Rectangle r)
{
Vncs *v;
- if(!rectclip(&r, gscreen->r))
+ if(!rectclip(&r, gscreen->clipr))
return;
qlock(&clients);
for(v=clients.head; v; v=v->next)
@@ -925,7 +953,7 @@ mousewarpnote(Point p)
for(v=clients.head; v; v=v->next){
if(v->canwarp){
vnclock(v);
- v->needwarp = 1;
+ v->dowarp = 1;
v->warppt = p;
vncunlock(v);
}
@@ -940,7 +968,7 @@ mousewarpnote(Point p)
static int
updateimage(Vncs *v)
{
- int i, ncount, nsend, docursor, needwarp;
+ int i, j, ncount, nsend, docursor, dowarp, doresize;
vlong ooffset;
Point warppt;
Rectangle cr;
@@ -949,20 +977,37 @@ updateimage(Vncs *v)
int (*count)(Vncs*, Rectangle);
int (*send)(Vncs*, Rectangle);
- if(v->image == nil)
- return 0;
-
- /* warping info and unlock v so that updates can proceed */
- needwarp = v->canwarp && v->needwarp;
+ vnclock(v);
+ dowarp = v->canwarp && v->dowarp;
warppt = v->warppt;
- v->needwarp = 0;
+ v->dowarp = 0;
vncunlock(v);
/* copy the screen bits and then unlock the screen so updates can proceed */
- drawlock();
+ qlock(&drawlock);
rlist = v->rlist;
memset(&v->rlist, 0, sizeof v->rlist);
+ if(v->canresize && !eqrect(v->screen[0].rect, gscreen->clipr)){
+ v->screen[0].rect = gscreen->clipr;
+ v->dim = rectsubpt(gscreen->clipr, gscreen->clipr.min);
+ doresize = 1;
+ } else
+ doresize = 0;
+
+ if(doresize
+ || (v->image == nil && v->imagechan != 0)
+ || (v->image != nil && v->image->chan != v->imagechan)){
+ if(v->image)
+ freememimage(v->image);
+ v->image = allocmemimage(v->dim, v->imagechan);
+ if(v->image == nil){
+ fprint(2, "%V: allocmemimage: %r; hanging up\n", v);
+ qlock(&drawlock);
+ vnchungup(v);
+ }
+ }
+
/* if the cursor has moved or changed shape, we need to redraw its square */
lock(&cursor);
if(v->cursorver != cursorver || !eqpt(v->cursorpos, cursorpos)){
@@ -978,7 +1023,7 @@ updateimage(Vncs *v)
if(docursor){
addtorlist(&rlist, v->cursorr);
- if(!rectclip(&cr, gscreen->r))
+ if(!rectclip(&cr, gscreen->clipr))
cr.max = cr.min;
addtorlist(&rlist, cr);
}
@@ -996,15 +1041,7 @@ updateimage(Vncs *v)
v->cursorr = cr;
}
- drawunlock();
-
- ooffset = Boffset(&v->out);
- /* no more locks are held; talk to the client */
-
- if(rlist.nrect == 0 && needwarp == 0){
- vnclock(v);
- return 0;
- }
+ qunlock(&drawlock);
count = v->countrect;
send = v->sendrect;
@@ -1014,16 +1051,45 @@ updateimage(Vncs *v)
}
ncount = 0;
- for(i=0; i<rlist.nrect; i++)
- ncount += (*count)(v, rlist.rect[i]);
+ for(i=j=0; i<rlist.nrect; i++){
+ if(j < i)
+ rlist.rect[j] = rlist.rect[i];
+ if(rectclip(&rlist.rect[j], v->dim))
+ ncount += (*count)(v, rlist.rect[j++]);
+ }
+ rlist.nrect = j;
+
+ if(doresize == 0 && ncount == 0 && dowarp == 0)
+ return 0;
+
+ if(verbose > 1){
+ fprint(2, "sendupdate: rlist.nrect=%d, ncount=%d\n", rlist.nrect, ncount);
+ t1 = nsec();
+ ooffset = Boffset(&v->out);
+ }
+
+ if(doresize && v->canresize == 1){
+ doresize = 0;
- if(verbose > 1)
- fprint(2, "sendupdate: rlist.nrect=%d, ncount=%d", rlist.nrect, ncount);
+ vncwrchar(v, MFrameUpdate);
+ vncwrchar(v, 0);
+ vncwrshort(v, 1);
+ vncwrrect(v, v->dim);
+ vncwrlong(v, EncDesktopSize);
+ }
- t1 = nsec();
vncwrchar(v, MFrameUpdate);
vncwrchar(v, 0);
- vncwrshort(v, ncount+needwarp);
+ vncwrshort(v, doresize+ncount+dowarp);
+
+ if(doresize){
+ vncwrrect(v, gscreen->r);
+ vncwrlong(v, EncXDesktopSize);
+ vncwrlong(v, 1<<24);
+ vncwrlong(v, v->screen[0].id);
+ vncwrrect(v, v->screen[0].rect);
+ vncwrlong(v, v->screen[0].flags);
+ }
nsend = 0;
for(i=0; i<rlist.nrect; i++)
@@ -1034,17 +1100,17 @@ updateimage(Vncs *v)
vnchungup(v);
}
- if(needwarp){
+ if(dowarp){
vncwrrect(v, Rect(warppt.x, warppt.y, warppt.x+1, warppt.y+1));
vncwrlong(v, EncMouseWarp);
}
- t1 = nsec() - t1;
- if(verbose > 1)
+ if(verbose > 1){
+ t1 = nsec() - t1;
fprint(2, " in %lldms, %lld bytes\n", t1/1000000, Boffset(&v->out) - ooffset);
+ }
freerlist(&rlist);
- vnclock(v);
return 1;
}
@@ -1059,13 +1125,11 @@ updatesnarf(Vncs *v)
if(v->snarfvers == snarf.vers)
return;
- vncunlock(v);
qlock(&snarf);
len = snarf.n;
buf = malloc(len);
if(buf == nil){
qunlock(&snarf);
- vnclock(v);
return;
}
memmove(buf, snarf.buf, len);
@@ -1077,7 +1141,6 @@ updatesnarf(Vncs *v)
vncwrlong(v, len);
vncwrbytes(v, buf, len);
free(buf);
- vnclock(v);
}
/*
@@ -1086,41 +1149,16 @@ updatesnarf(Vncs *v)
static void
clientwriteproc(Vncs *v)
{
- char buf[32], buf2[32];
- int sent;
+ ulong last = 0;
vncname("write %V", v);
- for(;;){
- vnclock(v);
- if(v->ndead)
- break;
- if((v->image == nil && v->imagechan!=0)
- || (v->image && v->image->chan != v->imagechan)){
- if(v->image)
- freememimage(v->image);
- v->image = allocmemimage(v->dim, v->imagechan);
- if(v->image == nil){
- fprint(2, "%V: allocmemimage: %r; hanging up\n", v);
- vnchungup(v);
- }
- if(verbose)
- fprint(2, "%V: translating image from chan=%s to chan=%s\n",
- v, chantostr(buf, gscreen->chan), chantostr(buf2, v->imagechan));
- }
- sent = 0;
- if(v->updaterequest){
- v->updaterequest = 0;
- updatesnarf(v);
- sent = updateimage(v);
- if(!sent)
- v->updaterequest = 1;
- }
- vncunlock(v);
+ while(!v->ndead){
+ sleep(sleeptime);
+ updatesnarf(v);
+ if(v->updatereq != last && updateimage(v))
+ last++;
vncflush(v);
- if(!sent)
- sleep(sleeptime);
}
- vncunlock(v);
vnchungup(v);
}