vncv: snarfvers race, silly walks, add -l option for clipboard charset

This commit is contained in:
cinap_lenrek 2012-10-09 15:15:57 +02:00
parent 14817c4991
commit 3cc39a0ac7
4 changed files with 98 additions and 44 deletions

View file

@ -51,6 +51,10 @@ vncs, vncv \- remote frame buffer server and viewer for Virtual Network Computin
.I encodings .I encodings
] ]
[ [
.B -l
.I charset
]
[
.B -k .B -k
.I keypattern .I keypattern
] ]
@ -167,6 +171,12 @@ The default (and full) set is
The encodings should be given as a single space-separated argument The encodings should be given as a single space-separated argument
(quoted when using the shell). (quoted when using the shell).
.TP .TP
.B -l \fIcharset
sets the character set (see
.IR tcs (1))
used by the server to encode clipboard text. The default is
.B utf-8.
.TP
.B -k \fIkeypattern .B -k \fIkeypattern
add add
.I keypattern .I keypattern

View file

@ -2,6 +2,7 @@
#include "vncv.h" #include "vncv.h"
#include <libsec.h> #include <libsec.h>
char* charset = "utf-8";
char* encodings = "copyrect hextile corre rre raw mousewarp"; char* encodings = "copyrect hextile corre rre raw mousewarp";
int bpp12; int bpp12;
int shared; int shared;
@ -10,6 +11,7 @@ Vnc* vnc;
int mousefd; int mousefd;
int tls; int tls;
static int vncstart(Vnc*, int); static int vncstart(Vnc*, int);
enum enum
@ -36,7 +38,7 @@ shutdown(void)
pid = getpid(); pid = getpid();
for(i = 0; i < NProcs; i++) for(i = 0; i < NProcs; i++)
if(pids[i] != pid) if(pids[i] != 0 && pids[i] != pid)
postnote(PNPROC, pids[i], killkin); postnote(PNPROC, pids[i], killkin);
} }
@ -72,15 +74,15 @@ vnchungup(Vnc*)
void void
usage(void) usage(void)
{ {
fprint(2, "usage: vncv [-e encodings] [-k keypattern] [-csv] host[:n]\n"); fprint(2, "usage: vncv [-e encodings] [-k keypattern] [-l charset] [-csv] host[:n]\n");
exits("usage"); exits("usage");
} }
void void
main(int argc, char **argv) main(int argc, char **argv)
{ {
int p, fd, dfd, cfd, shared; int p, dfd, cfd, shared;
char *keypattern, *addr; char *keypattern, *addr, *label;
Point d; Point d;
TLSconn conn; TLSconn conn;
@ -105,6 +107,9 @@ main(int argc, char **argv)
case 'k': case 'k':
keypattern = EARGF(usage()); keypattern = EARGF(usage());
break; break;
case 'l':
charset = EARGF(usage());
break;
default: default:
usage(); usage();
}ARGEND; }ARGEND;
@ -132,7 +137,8 @@ main(int argc, char **argv)
if(vncstart(vnc, shared) < 0) if(vncstart(vnc, shared) < 0)
sysfatal("init failure: %r"); sysfatal("init failure: %r");
if(initdraw(0, 0, "vncv") < 0) label = smprint("vnc %s", serveraddr);
if(initdraw(0, 0, label) < 0)
sysfatal("initdraw: %r"); sysfatal("initdraw: %r");
display->locking = 1; display->locking = 1;
unlockdisplay(display); unlockdisplay(display);
@ -173,12 +179,6 @@ main(int argc, char **argv)
} }
pids[2] = p; pids[2] = p;
fd = open("/dev/label", OWRITE);
if(fd >= 0){
fprint(fd, "vnc %s", serveraddr);
close(fd);
}
if(access("/dev/snarf", AEXIST) >= 0){
switch(p = rfork(RFPROC|RFMEM)){ switch(p = rfork(RFPROC|RFMEM)){
case -1: case -1:
sysfatal("rfork: %r"); sysfatal("rfork: %r");
@ -189,7 +189,6 @@ main(int argc, char **argv)
readkbd(vnc); readkbd(vnc);
exits(nil); exits(nil);
} }
}
pids[3] = p; pids[3] = p;
readmouse(vnc); readmouse(vnc);

View file

@ -11,6 +11,7 @@ extern void readfromserver(Vnc*);
extern uchar zero[]; extern uchar zero[];
/* vncv.c */ /* vncv.c */
extern char *charset;
extern char *encodings; extern char *encodings;
extern int bpp12; extern int bpp12;
extern Vnc* vnc; extern Vnc* vnc;

View file

@ -169,6 +169,42 @@ readmouse(Vnc *v)
} }
} }
static int
tcs(int fd0, int fd1)
{
int pfd[2];
if(strcmp(charset, "utf-8") == 0)
goto Dup;
if(pipe(pfd) < 0)
goto Dup;
switch(rfork(RFPROC|RFFDG|RFMEM)){
case -1:
close(pfd[0]);
close(pfd[1]);
goto Dup;
case 0:
if(fd0 < 0){
dup(pfd[0], 0);
dup(fd1, 1);
close(fd1);
} else {
dup(pfd[0], 1);
dup(fd0, 0);
close(fd0);
}
close(pfd[0]);
close(pfd[1]);
execl("/bin/tcs", "tcs", fd0 < 0 ? "-f" : "-t", charset, 0);
execl("/bin/cat", "cat", 0);
_exits(0);
}
close(pfd[0]);
return pfd[1];
Dup:
return dup(fd0 < 0 ? fd1 : fd0, -1);
}
static int snarffd = -1; static int snarffd = -1;
static ulong snarfvers; static ulong snarfvers;
@ -176,39 +212,47 @@ void
writesnarf(Vnc *v, long n) writesnarf(Vnc *v, long n)
{ {
uchar buf[8192]; uchar buf[8192];
int fd, sfd;
long m; long m;
Biobuf *b;
if((b = Bopen("/dev/snarf", OWRITE)) == nil){ vnclock(v);
if((sfd = create("/dev/snarf", OWRITE, 0666)) < 0)
fd = -1;
else {
fd = tcs(-1, sfd);
close(sfd);
}
if(fd < 0){
vncunlock(v);
vncgobble(v, n); vncgobble(v, n);
return; return;
} }
while(n > 0){ while(n > 0){
m = n; m = n;
if(m > sizeof(buf)) if(m > sizeof(buf))
m = sizeof(buf); m = sizeof(buf);
vncrdbytes(v, buf, m); vncrdbytes(v, buf, m);
n -= m; n -= m;
write(fd, buf, m);
Bwrite(b, buf, m);
} }
Bterm(b); close(fd);
snarfvers++; snarfvers++;
vncunlock(v);
} }
char * char *
getsnarf(int *sz) getsnarf(int *sz)
{ {
char *snarf, *p; char *snarf, *p;
int n, c; int fd, n, c;
*sz =0; *sz =0;
n = 8192; n = 8192;
p = snarf = malloc(n); p = snarf = malloc(n);
seek(snarffd, 0, 0); seek(snarffd, 0, 0);
while ((c = read(snarffd, p, n)) > 0){ if((fd = tcs(snarffd, -1)) >= 0){
while((c = read(fd, p, n)) > 0){
p += c; p += c;
n -= c; n -= c;
*sz += c; *sz += c;
@ -217,6 +261,8 @@ getsnarf(int *sz)
n = 8192; n = 8192;
} }
} }
close(fd);
}
return snarf; return snarf;
} }
@ -236,24 +282,22 @@ checksnarf(Vnc *v)
for(;;){ for(;;){
sleep(1000); sleep(1000);
dir = dirstat("/dev/snarf"); vnclock(v);
if(dir == nil) /* this happens under old drawterm */ dir = dirfstat(snarffd);
continue; if(dir != nil && dir->qid.vers != snarfvers){
if(dir->qid.vers > snarfvers){ snarfvers = dir->qid.vers;
snarf = getsnarf(&len); snarf = getsnarf(&len);
vnclock(v);
vncwrchar(v, MCCut); vncwrchar(v, MCCut);
vncwrbytes(v, "pad", 3); vncwrbytes(v, "pad", 3);
vncwrlong(v, len); vncwrlong(v, len);
vncwrbytes(v, snarf, len); vncwrbytes(v, snarf, len);
vncflush(v); vncflush(v);
vncunlock(v);
free(snarf); free(snarf);
snarfvers = dir->qid.vers;
} }
free(dir); free(dir);
vncunlock(v);
} }
} }