upgraded to TridiaVNC 1.2.1

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

@ -1,11 +1,13 @@
0.2 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!) support for 3 bytes/pixel (slow!)
server side colourmap support server side colourmap support
fixed rfbCloseClient not to close the connection (pthreads!) 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!) 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 fixed prototypes
0.1 0.1
rewrote API to use pseudo-methods instead of required functions. rewrote API to use pseudo-methods instead of required functions.

@ -65,7 +65,7 @@ sratest.o: sraRegion.c
blooptest: blooptest.o libvncserver.a blooptest: blooptest.o libvncserver.a
$(CC) -o blooptest blooptest.o $(LIBS) $(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 $(CC) $(CFLAGS) -DBACKGROUND_LOOP_TEST -c -o blooptest.o example.c
pnmshow24: pnmshow24.o libvncserver.a 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 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: later:
------ ------
udp
documentation
optionally dont draw rich cursors as xcursors
autoconf? at least Sun Solaris and Windows compilation 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 CORBA
cursor "smears" sometimes when not using cursor encoding cursor "smears" sometimes when not using cursor encoding
(seems to be gone now; haven't debugged properly, though) (seems to be gone now; haven't debugged properly, though)
@ -21,6 +19,8 @@ cursor "smears" sometimes when not using cursor encoding
done: done:
----- -----
.rfbConnect, ConnectToTcpAddr
.update to newest TridiaVNC version (1.2.1).
.adapt rdp2vnc (rdesktop) .adapt rdp2vnc (rdesktop)
.pthreads concept: How to iterate over rfbClientPtr's? So that it can be .pthreads concept: How to iterate over rfbClientPtr's? So that it can be
either called from rfbProcessEvents (which locks the list mutex) either called from rfbProcessEvents (which locks the list mutex)

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

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

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

@ -56,7 +56,6 @@ struct timeval
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "rfb.h" #include "rfb.h"
@ -182,7 +181,6 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
return; return;
} }
fprintf(stderr,"\n");
rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr)); rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));
FD_SET(sock, &(rfbScreen->allFds)); FD_SET(sock, &(rfbScreen->allFds));
@ -224,8 +222,8 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock); rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock);
} }
//TODO: UDP also needs a client /* TODO: UDP also needs a client
//rfbProcessUDPInput(rfbScreen,rfbScreen->udpSock); rfbProcessUDPInput(rfbScreen,rfbScreen->udpSock); */
} }
FD_CLR(rfbScreen->udpSock, &fds); 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 * 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 * 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; return 1;
} }
int int
ListenOnTCPPort(port) ListenOnTCPPort(port)
int port; int port;
@ -396,7 +434,7 @@ ListenOnTCPPort(port)
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
addr.sin_port = htons(port); 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; addr.sin_addr.s_addr = INADDR_ANY;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
@ -419,6 +457,39 @@ ListenOnTCPPort(port)
return sock; 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 int
ListenOnUDPPort(port) ListenOnUDPPort(port)
int port; int port;
@ -429,7 +500,7 @@ ListenOnUDPPort(port)
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
addr.sin_port = htons(port); 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; addr.sin_addr.s_addr = INADDR_ANY;
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

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

@ -32,6 +32,11 @@
/* Note: The following constant should not be changed. */ /* Note: The following constant should not be changed. */
#define TIGHT_MIN_TO_COMPRESS 12 #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. */ /* May be set to TRUE with "-lazytight" Xvnc option. */
Bool rfbTightDisableGradient = FALSE; Bool rfbTightDisableGradient = FALSE;
@ -53,7 +58,7 @@ typedef struct TIGHT_CONF_s {
} TIGHT_CONF; } TIGHT_CONF;
static TIGHT_CONF tightConf[10] = { 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 }, { 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 }, { 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 }, { 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. * Tight encoding implementation.
*/ */
#define MIN_SPLIT_RECT_SIZE 4096
#define MIN_SOLID_SUBRECT_SIZE 2048
#define MAX_SPLIT_TILE_SIZE 16
int int
rfbNumCodedRectsTight(cl, x, y, w, h) rfbNumCodedRectsTight(cl, x, y, w, h)
rfbClientPtr cl; rfbClientPtr cl;
@ -209,11 +210,15 @@ rfbSendRectEncodingTight(cl, x, y, w, h)
rfbClientPtr cl; rfbClientPtr cl;
int x, y, w, h; int x, y, w, h;
{ {
int nMaxRows;
CARD32 colorValue; CARD32 colorValue;
int dx, dy, dw, dh; int dx, dy, dw, dh;
int x_best, y_best, w_best, h_best; int x_best, y_best, w_best, h_best;
char *fbptr; char *fbptr;
compressLevel = cl->tightCompressLevel;
qualityLevel = cl->tightQualityLevel;
if ( cl->format.depth == 24 && cl->format.redMax == 0xFF && if ( cl->format.depth == 24 && cl->format.redMax == 0xFF &&
cl->format.greenMax == 0xFF && cl->format.blueMax == 0xFF ) { cl->format.greenMax == 0xFF && cl->format.blueMax == 0xFF ) {
usePixelFormat24 = TRUE; usePixelFormat24 = TRUE;
@ -224,7 +229,7 @@ rfbSendRectEncodingTight(cl, x, y, w, h)
if (!cl->enableLastRectEncoding || w * h < MIN_SPLIT_RECT_SIZE) if (!cl->enableLastRectEncoding || w * h < MIN_SPLIT_RECT_SIZE)
return SendRectSimple(cl, x, y, w, h); 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) { if (tightBeforeBufSize < 4) {
tightBeforeBufSize = 4; tightBeforeBufSize = 4;
@ -235,10 +240,30 @@ rfbSendRectEncodingTight(cl, x, y, w, h)
tightBeforeBufSize); 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. */ /* Try to find large solid-color areas and send them separately. */
for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) { 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) ? dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ?
MAX_SPLIT_TILE_SIZE : (y + h - dy); MAX_SPLIT_TILE_SIZE : (y + h - dy);
@ -462,8 +487,6 @@ SendRectSimple(cl, x, y, w, h)
int dx, dy; int dx, dy;
int rw, rh; int rw, rh;
compressLevel = cl->tightCompressLevel;
qualityLevel = cl->tightQualityLevel;
maxRectSize = tightConf[compressLevel].maxRectSize; maxRectSize = tightConf[compressLevel].maxRectSize;
maxRectWidth = tightConf[compressLevel].maxRectWidth; maxRectWidth = tightConf[compressLevel].maxRectWidth;
@ -516,6 +539,12 @@ SendSubrect(cl, x, y, w, h)
char *fbptr; char *fbptr;
Bool success = FALSE; 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)) if (!SendTightHeader(cl, x, y, w, h))
return FALSE; return FALSE;
@ -566,7 +595,7 @@ SendSubrect(cl, x, y, w, h)
break; break;
default: default:
/* Up to 256 different colors */ /* Up to 256 different colors */
if ( paletteNumColors > 64 && if ( paletteNumColors > 96 &&
qualityLevel != -1 && qualityLevel <= 3 && qualityLevel != -1 && qualityLevel <= 3 &&
DetectSmoothImage(cl, &cl->format, w, h) ) { DetectSmoothImage(cl, &cl->format, w, h) ) {
success = SendJpegRect(cl, x, y, w, h, success = SendJpegRect(cl, x, y, w, h,
@ -644,7 +673,8 @@ SendMonoRect(cl, w, h)
int streamId = 1; int streamId = 1;
int paletteLen, dataLen; 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)) if (!rfbSendUpdateBuf(cl))
return FALSE; return FALSE;
} }
@ -708,7 +738,8 @@ SendIndexedRect(cl, w, h)
int streamId = 2; int streamId = 2;
int i, entryLen; 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 ) { UPDATE_BUF_SIZE ) {
if (!rfbSendUpdateBuf(cl)) if (!rfbSendUpdateBuf(cl))
return FALSE; return FALSE;
@ -902,19 +933,19 @@ static Bool SendCompressedData(cl, compressedLen)
} }
} }
for (i = 0; i < compressedLen; ) { portionLen = UPDATE_BUF_SIZE;
portionLen = compressedLen - i; for (i = 0; i < compressedLen; i += portionLen) {
if (portionLen > UPDATE_BUF_SIZE - cl->ublen) if (i + portionLen > compressedLen) {
portionLen = UPDATE_BUF_SIZE - cl->ublen; portionLen = compressedLen - i;
}
if (cl->ublen + portionLen > UPDATE_BUF_SIZE) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
memcpy(&cl->updateBuf[cl->ublen], &tightAfterBuf[i], portionLen); memcpy(&cl->updateBuf[cl->ublen], &tightAfterBuf[i], portionLen);
cl->ublen += portionLen; cl->ublen += portionLen;
i += portionLen;
if (!rfbSendUpdateBuf(cl))
return FALSE;
} }
portionLen = UPDATE_BUF_SIZE;
cl->rfbBytesSent[rfbEncodingTight] += compressedLen; cl->rfbBytesSent[rfbEncodingTight] += compressedLen;
return TRUE; return TRUE;
} }
@ -978,7 +1009,7 @@ FillPalette##bpp(count) \
\ \
c0 = data[0]; \ c0 = data[0]; \
for (i = 1; i < count && data[i] == c0; i++); \ for (i = 1; i < count && data[i] == c0; i++); \
if (i == count) { \ if (i >= count) { \
paletteNumColors = 1; /* Solid rectangle */ \ paletteNumColors = 1; /* Solid rectangle */ \
return; \ return; \
} \ } \
@ -1000,7 +1031,7 @@ FillPalette##bpp(count) \
} else \ } else \
break; \ break; \
} \ } \
if (i == count) { \ if (i >= count) { \
if (n0 > n1) { \ if (n0 > n1) { \
monoBackground = (CARD32)c0; \ monoBackground = (CARD32)c0; \
monoForeground = (CARD32)c1; \ monoForeground = (CARD32)c1; \

Loading…
Cancel
Save