vncv: snarfvers race, silly walks, add -l option for clipboard charset
This commit is contained in:
parent
14817c4991
commit
3cc39a0ac7
4 changed files with 98 additions and 44 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue