upgraded to TridiaVNC 1.2.1

pull/1/head
dscho 23 years ago
parent 130ae151d1
commit 05c8f2d484

@ -1,11 +1,13 @@
0.2
cursors are supported
source is now equivalent to TridiaVNC 1.2.1
pthreads now work (use the iterators!)
cursors are supported (rfbSetCursor automatically undraws cursor)
support for 3 bytes/pixel (slow!)
server side colourmap support
fixed rfbCloseClient not to close the connection (pthreads!)
pthreads now work
this is done lazily (and with proper signalling).
cleaned up mac.c (from original OSXvnc); now compiles (untested!)
compiles cleanly on Linux, IRIX, BSD, Apple
compiles cleanly on Linux, IRIX, BSD, Apple (Darwin)
fixed prototypes
0.1
rewrote API to use pseudo-methods instead of required functions.

@ -65,7 +65,7 @@ sratest.o: sraRegion.c
blooptest: blooptest.o libvncserver.a
$(CC) -o blooptest blooptest.o $(LIBS)
blooptest.o: example.c
blooptest.o: example.c rfb.h
$(CC) $(CFLAGS) -DBACKGROUND_LOOP_TEST -c -o blooptest.o example.c
pnmshow24: pnmshow24.o libvncserver.a

14
TODO

@ -2,18 +2,16 @@ immediate:
----------
fix bug in http (java) client with big endian server: byte swapping is broken
update to newest TridiaVNC version.
udp
documentation
perhaps the option (or just hint) not to mark very tiny regions as
modified, because that is inefficient for the encodings.
optionally dont draw rich cursors as xcursors
later:
------
udp
documentation
optionally dont draw rich cursors as xcursors
autoconf? at least Sun Solaris and Windows compilation
perhaps the option (or just hint) not to mark very tiny regions as modified,
because that is inefficient for the encodings.
rfbConnect, ConnectToTcpAddr
CORBA
cursor "smears" sometimes when not using cursor encoding
(seems to be gone now; haven't debugged properly, though)
@ -21,6 +19,8 @@ cursor "smears" sometimes when not using cursor encoding
done:
-----
.rfbConnect, ConnectToTcpAddr
.update to newest TridiaVNC version (1.2.1).
.adapt rdp2vnc (rdesktop)
.pthreads concept: How to iterate over rfbClientPtr's? So that it can be
either called from rfbProcessEvents (which locks the list mutex)

@ -48,7 +48,7 @@ rfbLog(char *format, ...)
char buf[256];
time_t log_clock;
IF_PTHREADS(pthread_mutex_lock(&logMutex));
IF_PTHREADS(LOCK(logMutex));
va_start(args, format);
time(&log_clock);
@ -59,7 +59,7 @@ rfbLog(char *format, ...)
fflush(stderr);
va_end(args);
IF_PTHREADS(pthread_mutex_unlock(&logMutex));
IF_PTHREADS(UNLOCK(logMutex));
}
void rfbLogPerror(char *str)
@ -314,6 +314,7 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv,
if(width&3)
fprintf(stderr,"WARNING: Width (%d) is not a multiple of 4. VncViewer has problems with that.\n",width);
rfbScreen->rfbClientHead=0;
rfbScreen->rfbPort=5900;
rfbScreen->socketInitDone=FALSE;
@ -323,6 +324,7 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv,
rfbScreen->udpSock=-1;
rfbScreen->udpSockConnected=FALSE;
rfbScreen->udpPort=0;
rfbScreen->udpClient=0;
rfbScreen->maxFd=0;
rfbScreen->rfbListenSock=-1;
@ -419,6 +421,7 @@ void rfbInitServer(rfbScreenInfoPtr rfbScreen)
{
rfbInitSockets(rfbScreen);
httpInitSockets(rfbScreen);
INIT_MUTEX(logMutex);
}
void
@ -451,7 +454,6 @@ void rfbRunEventLoop(rfbScreenInfoPtr rfbScreen, long usec, Bool runInBackground
#ifdef HAVE_PTHREADS
pthread_t listener_thread;
pthread_mutex_init(&logMutex, NULL);
pthread_create(&listener_thread, NULL, listenerRun, rfbScreen);
return;
#else

@ -221,6 +221,7 @@ typedef struct
int rfbListenSock;
int udpPort;
int udpSock;
struct rfbClientRec* udpClient;
Bool udpSockConnected;
struct sockaddr_in udpRemoteAddr;
Bool inetdInitDone;
@ -517,6 +518,8 @@ extern void rfbCloseClient(rfbClientPtr cl);
extern int ReadExact(rfbClientPtr cl, char *buf, int len);
extern int WriteExact(rfbClientPtr cl, char *buf, int len);
extern void rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec);
extern int rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port);
extern int ConnectToTcpAddr(char* host, int port);
extern int ListenOnTCPPort(int port);
extern int ListenOnUDPPort(int port);
@ -536,7 +539,7 @@ extern void rfbReleaseClientIterator(rfbClientIteratorPtr iterator);
extern void rfbNewClientConnection(rfbScreenInfoPtr rfbScreen,int sock);
extern rfbClientPtr rfbNewClient(rfbScreenInfoPtr rfbScreen,int sock);
extern rfbClientPtr rfbReverseConnection(char *host, int port);
extern rfbClientPtr rfbReverseConnection(rfbScreenInfoPtr rfbScreen,char *host, int port);
extern void rfbClientConnectionGone(rfbClientPtr cl);
extern void rfbProcessClientMessage(rfbClientPtr cl);
extern void rfbClientConnFailed(rfbClientPtr cl, char *reason);

@ -34,6 +34,10 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef CORBA
#include <vncserverctrl.h>
#endif
rfbClientPtr pointerClient = NULL; /* Mutex for pointer events */
static void rfbProcessClientProtocolVersion(rfbClientPtr cl);
@ -124,6 +128,10 @@ rfbNewClientConnection(rfbScreen,sock)
rfbClientPtr cl;
cl = rfbNewClient(rfbScreen,sock);
#ifdef CORBA
if(cl!=NULL)
newConnection(cl, (KEYBOARD_DEVICE|POINTER_DEVICE),1,1,1);
#endif
}
@ -133,27 +141,24 @@ rfbNewClientConnection(rfbScreen,sock)
*/
rfbClientPtr
rfbReverseConnection(host, port)
rfbReverseConnection(rfbScreen,host, port)
rfbScreenInfoPtr rfbScreen;
char *host;
int port;
{
return NULL;
#ifdef NOT_YET
int sock;
rfbClientPtr cl;
if ((sock = rfbConnect(host, port)) < 0)
if ((sock = rfbConnect(rfbScreen, host, port)) < 0)
return (rfbClientPtr)NULL;
cl = rfbNewClient(sock);
cl = rfbNewClient(rfbScreen, sock);
if (cl) {
cl->reverseConnection = TRUE;
}
return cl;
#endif
}
@ -189,6 +194,8 @@ rfbNewClient(rfbScreen,sock)
cl->host = strdup(inet_ntoa(addr.sin_addr));
INIT_MUTEX(cl->outputMutex);
INIT_MUTEX(cl->refCountMutex);
INIT_COND(cl->deleteCond);
cl->state = RFB_PROTOCOL_VERSION;
@ -323,6 +330,10 @@ rfbClientConnectionGone(cl)
LOCK(cl->outputMutex);
TINI_MUTEX(cl->outputMutex);
#ifdef CORBA
destroyConnection(cl);
#endif
rfbPrintStats(cl);
xfree(cl);
@ -977,9 +988,11 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
if (sendCursorShape) {
cl->cursorWasChanged = FALSE;
if (!rfbSendCursorShape(cl))
if (!rfbSendCursorShape(cl)) {
sraRgnDestroy(updateRegion);
return FALSE;
}
}
if (!sraRgnEmpty(updateCopyRegion)) {
if (!rfbSendCopyRegion(cl,updateCopyRegion,dx,dy)) {
@ -1003,21 +1016,25 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
switch (cl->preferredEncoding) {
case rfbEncodingRaw:
if (!rfbSendRectEncodingRaw(cl, x, y, w, h)) {
sraRgnDestroy(updateRegion);
return FALSE;
}
break;
case rfbEncodingRRE:
if (!rfbSendRectEncodingRRE(cl, x, y, w, h)) {
sraRgnDestroy(updateRegion);
return FALSE;
}
break;
case rfbEncodingCoRRE:
if (!rfbSendRectEncodingCoRRE(cl, x, y, w, h)) {
sraRgnDestroy(updateRegion);
return FALSE;
}
break;
case rfbEncodingHextile:
if (!rfbSendRectEncodingHextile(cl, x, y, w, h)) {
sraRgnDestroy(updateRegion);
return FALSE;
}
break;
@ -1038,11 +1055,14 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
if ( nUpdateRegionRects == 0xFFFF &&
!rfbSendLastRectMarker(cl) ) {
sraRgnDestroy(updateRegion);
return FALSE;
}
if (!rfbSendUpdateBuf(cl))
if (!rfbSendUpdateBuf(cl)) {
sraRgnDestroy(updateRegion);
return FALSE;
}
if(cursorWasDrawn != cl->screen->cursorIsDrawn) {
if(cursorWasDrawn)
@ -1051,6 +1071,7 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
rfbUndrawCursor(cl);
}
sraRgnDestroy(updateRegion);
return TRUE;
}
@ -1315,7 +1336,6 @@ rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len)
rfbServerCutTextMsg sct;
rfbClientIteratorPtr iterator;
/* XXX bad-- writing with client list lock held */
iterator = rfbGetClientIterator(rfbScreen);
while ((cl = rfbClientIteratorNext(iterator)) != NULL) {
sct.type = rfbServerCutText;
@ -1334,8 +1354,6 @@ rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len)
rfbReleaseClientIterator(iterator);
}
unsigned char ptrAcceleration = 50;
/*****************************************************************************
*
* UDP can be used for keyboard and pointer events when the underlying
@ -1344,6 +1362,8 @@ unsigned char ptrAcceleration = 50;
* packets (such as 100s of pen readings per second!).
*/
unsigned char ptrAcceleration = 50;
void
rfbNewUDPConnection(rfbScreen,sock)
rfbScreenInfoPtr rfbScreen;

@ -56,7 +56,6 @@ struct timeval
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h>
#include "rfb.h"
@ -182,7 +181,6 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
return;
}
fprintf(stderr,"\n");
rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));
FD_SET(sock, &(rfbScreen->allFds));
@ -224,8 +222,8 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock);
}
//TODO: UDP also needs a client
//rfbProcessUDPInput(rfbScreen,rfbScreen->udpSock);
/* TODO: UDP also needs a client
rfbProcessUDPInput(rfbScreen,rfbScreen->udpSock); */
}
FD_CLR(rfbScreen->udpSock, &fds);
@ -263,6 +261,47 @@ rfbCloseClient(cl)
}
/*
* rfbConnect is called to make a connection out to a given TCP address.
*/
int
rfbConnect(rfbScreen, host, port)
rfbScreenInfoPtr rfbScreen;
char *host;
int port;
{
int sock;
int one = 1;
rfbLog("Making connection to client on host %s port %d\n",
host,port);
if ((sock = ConnectToTcpAddr(host, port)) < 0) {
rfbLogPerror("connection failed");
return -1;
}
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
rfbLogPerror("fcntl failed");
close(sock);
return -1;
}
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof(one)) < 0) {
rfbLogPerror("setsockopt failed");
close(sock);
return -1;
}
/* AddEnabledDevice(sock); */
FD_SET(sock, &rfbScreen->allFds);
rfbScreen->maxFd = max(sock,rfbScreen->maxFd);
return sock;
}
/*
* ReadExact reads an exact number of bytes from a client. Returns 1 if
* those bytes have been read, 0 if the other end has closed, or -1 if an error
@ -385,7 +424,6 @@ WriteExact(cl, buf, len)
return 1;
}
int
ListenOnTCPPort(port)
int port;
@ -396,7 +434,7 @@ ListenOnTCPPort(port)
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
//addr.sin_addr.s_addr = interface.s_addr;
/* addr.sin_addr.s_addr = interface.s_addr; */
addr.sin_addr.s_addr = INADDR_ANY;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
@ -419,6 +457,39 @@ ListenOnTCPPort(port)
return sock;
}
int
ConnectToTcpAddr(host, port)
char *host;
int port;
{
struct hostent *hp;
int sock;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
if ((addr.sin_addr.s_addr = inet_addr(host)) == -1)
{
if (!(hp = gethostbyname(host))) {
errno = EINVAL;
return -1;
}
addr.sin_addr.s_addr = *(unsigned long *)hp->h_addr;
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return -1;
}
if (connect(sock, (struct sockaddr *)&addr, (sizeof(addr))) < 0) {
close(sock);
return -1;
}
return sock;
}
int
ListenOnUDPPort(port)
int port;
@ -429,7 +500,7 @@ ListenOnUDPPort(port)
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
//addr.sin_addr.s_addr = interface.s_addr;
/* addr.sin_addr.s_addr = interface.s_addr; */
addr.sin_addr.s_addr = INADDR_ANY;
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

@ -69,6 +69,10 @@ rfbPrintStats(rfbClientPtr cl)
totalBytesSent += cl->rfbBytesSent[i];
}
totalRectanglesSent += (cl->rfbCursorUpdatesSent +
cl->rfbLastRectMarkersSent);
totalBytesSent += (cl->rfbCursorBytesSent + cl->rfbLastRectBytesSent);
rfbLog(" framebuffer updates %d, rectangles %d, bytes %d\n",
cl->rfbFramebufferUpdateMessagesSent, totalRectanglesSent,
totalBytesSent);

@ -32,6 +32,11 @@
/* Note: The following constant should not be changed. */
#define TIGHT_MIN_TO_COMPRESS 12
/* The parameters below may be adjusted. */
#define MIN_SPLIT_RECT_SIZE 4096
#define MIN_SOLID_SUBRECT_SIZE 2048
#define MAX_SPLIT_TILE_SIZE 16
/* May be set to TRUE with "-lazytight" Xvnc option. */
Bool rfbTightDisableGradient = FALSE;
@ -53,7 +58,7 @@ typedef struct TIGHT_CONF_s {
} TIGHT_CONF;
static TIGHT_CONF tightConf[10] = {
{ 512, 32, 6, 65536, 0, 0, 0, 0, 0, 0, 4, 20, 10000, 25000 },
{ 512, 32, 6, 65536, 0, 0, 0, 0, 0, 0, 4, 20, 10000, 23000 },
{ 2048, 128, 6, 65536, 1, 1, 1, 0, 0, 0, 8, 30, 8000, 18000 },
{ 6144, 256, 8, 65536, 3, 3, 2, 0, 0, 0, 24, 40, 6500, 15000 },
{ 10240, 1024, 12, 65536, 5, 5, 3, 0, 0, 0, 32, 50, 5000, 12000 },
@ -174,10 +179,6 @@ static void JpegSetDstManager(j_compress_ptr cinfo);
* Tight encoding implementation.
*/
#define MIN_SPLIT_RECT_SIZE 4096
#define MIN_SOLID_SUBRECT_SIZE 2048
#define MAX_SPLIT_TILE_SIZE 16
int
rfbNumCodedRectsTight(cl, x, y, w, h)
rfbClientPtr cl;
@ -209,11 +210,15 @@ rfbSendRectEncodingTight(cl, x, y, w, h)
rfbClientPtr cl;
int x, y, w, h;
{
int nMaxRows;
CARD32 colorValue;
int dx, dy, dw, dh;
int x_best, y_best, w_best, h_best;
char *fbptr;
compressLevel = cl->tightCompressLevel;
qualityLevel = cl->tightQualityLevel;
if ( cl->format.depth == 24 && cl->format.redMax == 0xFF &&
cl->format.greenMax == 0xFF && cl->format.blueMax == 0xFF ) {
usePixelFormat24 = TRUE;
@ -224,7 +229,7 @@ rfbSendRectEncodingTight(cl, x, y, w, h)
if (!cl->enableLastRectEncoding || w * h < MIN_SPLIT_RECT_SIZE)
return SendRectSimple(cl, x, y, w, h);
/* Make sure we can write one pixel into tightBeforeBuf. */
/* Make sure we can write at least one pixel into tightBeforeBuf. */
if (tightBeforeBufSize < 4) {
tightBeforeBufSize = 4;
@ -235,10 +240,30 @@ rfbSendRectEncodingTight(cl, x, y, w, h)
tightBeforeBufSize);
}
/* Calculate maximum number of rows in one non-solid rectangle. */
{
int maxRectSize, maxRectWidth, nMaxWidth;
maxRectSize = tightConf[compressLevel].maxRectSize;
maxRectWidth = tightConf[compressLevel].maxRectWidth;
nMaxWidth = (w > maxRectWidth) ? maxRectWidth : w;
nMaxRows = maxRectSize / nMaxWidth;
}
/* Try to find large solid-color areas and send them separately. */
for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) {
/* If a rectangle becomes too large, send its upper part now. */
if (dy - y >= nMaxRows) {
if (!SendRectSimple(cl, x, y, w, nMaxRows))
return 0;
y += nMaxRows;
h -= nMaxRows;
}
dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ?
MAX_SPLIT_TILE_SIZE : (y + h - dy);
@ -462,8 +487,6 @@ SendRectSimple(cl, x, y, w, h)
int dx, dy;
int rw, rh;
compressLevel = cl->tightCompressLevel;
qualityLevel = cl->tightQualityLevel;
maxRectSize = tightConf[compressLevel].maxRectSize;
maxRectWidth = tightConf[compressLevel].maxRectWidth;
@ -516,6 +539,12 @@ SendSubrect(cl, x, y, w, h)
char *fbptr;
Bool success = FALSE;
/* Send pending data if there is more than 128 bytes. */
if (cl->ublen > 128) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
if (!SendTightHeader(cl, x, y, w, h))
return FALSE;
@ -566,7 +595,7 @@ SendSubrect(cl, x, y, w, h)
break;
default:
/* Up to 256 different colors */
if ( paletteNumColors > 64 &&
if ( paletteNumColors > 96 &&
qualityLevel != -1 && qualityLevel <= 3 &&
DetectSmoothImage(cl, &cl->format, w, h) ) {
success = SendJpegRect(cl, x, y, w, h,
@ -644,7 +673,8 @@ SendMonoRect(cl, w, h)
int streamId = 1;
int paletteLen, dataLen;
if ( cl->ublen + 6 + 2 * cl->format.bitsPerPixel / 8 > UPDATE_BUF_SIZE ) {
if ( cl->ublen + TIGHT_MIN_TO_COMPRESS + 6 +
2 * cl->format.bitsPerPixel / 8 > UPDATE_BUF_SIZE ) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
@ -708,7 +738,8 @@ SendIndexedRect(cl, w, h)
int streamId = 2;
int i, entryLen;
if ( cl->ublen + 6 + paletteNumColors * cl->format.bitsPerPixel / 8 >
if ( cl->ublen + TIGHT_MIN_TO_COMPRESS + 6 +
paletteNumColors * cl->format.bitsPerPixel / 8 >
UPDATE_BUF_SIZE ) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
@ -902,19 +933,19 @@ static Bool SendCompressedData(cl, compressedLen)
}
}
for (i = 0; i < compressedLen; ) {
portionLen = UPDATE_BUF_SIZE;
for (i = 0; i < compressedLen; i += portionLen) {
if (i + portionLen > compressedLen) {
portionLen = compressedLen - i;
if (portionLen > UPDATE_BUF_SIZE - cl->ublen)
portionLen = UPDATE_BUF_SIZE - cl->ublen;
memcpy(&cl->updateBuf[cl->ublen], &tightAfterBuf[i], portionLen);
cl->ublen += portionLen;
i += portionLen;
}
if (cl->ublen + portionLen > UPDATE_BUF_SIZE) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
memcpy(&cl->updateBuf[cl->ublen], &tightAfterBuf[i], portionLen);
cl->ublen += portionLen;
}
portionLen = UPDATE_BUF_SIZE;
cl->rfbBytesSent[rfbEncodingTight] += compressedLen;
return TRUE;
}
@ -978,7 +1009,7 @@ FillPalette##bpp(count) \
\
c0 = data[0]; \
for (i = 1; i < count && data[i] == c0; i++); \
if (i == count) { \
if (i >= count) { \
paletteNumColors = 1; /* Solid rectangle */ \
return; \
} \
@ -1000,7 +1031,7 @@ FillPalette##bpp(count) \
} else \
break; \
} \
if (i == count) { \
if (i >= count) { \
if (n0 > n1) { \
monoBackground = (CARD32)c0; \
monoForeground = (CARD32)c1; \

Loading…
Cancel
Save