summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordscho <dscho>2001-10-03 02:11:59 +0000
committerdscho <dscho>2001-10-03 02:11:59 +0000
commit05c8f2d4840e8e4d0166b176b8c88bfdfffcce91 (patch)
tree256410bdcf6ad8343f914b146bb67f47ae90d11f
parent130ae151d118378e5765713581283728fdfb3e20 (diff)
downloadlibtdevnc-05c8f2d4840e8e4d0166b176b8c88bfdfffcce91.tar.gz
libtdevnc-05c8f2d4840e8e4d0166b176b8c88bfdfffcce91.zip
upgraded to TridiaVNC 1.2.1
-rw-r--r--CHANGES8
-rw-r--r--Makefile2
-rw-r--r--TODO14
-rw-r--r--main.c8
-rw-r--r--rfb.h5
-rw-r--r--rfbserver.c44
-rw-r--r--sockets.c85
-rw-r--r--stats.c4
-rw-r--r--tight.c77
9 files changed, 190 insertions, 57 deletions
diff --git a/CHANGES b/CHANGES
index d9ed9c8..ccf5ee5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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.
diff --git a/Makefile b/Makefile
index 5c92c7a..c456673 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/TODO b/TODO
index 904a5fe..17ffe48 100644
--- a/TODO
+++ b/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)
diff --git a/main.c b/main.c
index 7412b30..7362e4d 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/rfb.h b/rfb.h
index efb69d2..e67e683 100644
--- a/rfb.h
+++ b/rfb.h
@@ -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);
diff --git a/rfbserver.c b/rfbserver.c
index 930a9ed..f43ceac 100644
--- a/rfbserver.c
+++ b/rfbserver.c
@@ -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,8 +988,10 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
if (sendCursorShape) {
cl->cursorWasChanged = FALSE;
- if (!rfbSendCursorShape(cl))
+ if (!rfbSendCursorShape(cl)) {
+ sraRgnDestroy(updateRegion);
return FALSE;
+ }
}
if (!sraRgnEmpty(updateCopyRegion)) {
@@ -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;
diff --git a/sockets.c b/sockets.c
index ef83269..3882147 100644
--- a/sockets.c
+++ b/sockets.c
@@ -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);
@@ -264,6 +262,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
* occurred (errno is set to ETIMEDOUT if it timed out).
@@ -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) {
@@ -420,6 +458,39 @@ ListenOnTCPPort(port)
}
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) {
diff --git a/stats.c b/stats.c
index f712021..b6fcf62 100644
--- a/stats.c
+++ b/stats.c
@@ -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);
diff --git a/tight.c b/tight.c
index 509a6d8..db0d382 100644
--- a/tight.c
+++ b/tight.c
@@ -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 = compressedLen - i;
- if (portionLen > UPDATE_BUF_SIZE - cl->ublen)
- portionLen = UPDATE_BUF_SIZE - cl->ublen;
-
+ portionLen = UPDATE_BUF_SIZE;
+ for (i = 0; i < compressedLen; i += portionLen) {
+ if (i + portionLen > compressedLen) {
+ portionLen = compressedLen - i;
+ }
+ if (cl->ublen + portionLen > UPDATE_BUF_SIZE) {
+ if (!rfbSendUpdateBuf(cl))
+ return FALSE;
+ }
memcpy(&cl->updateBuf[cl->ublen], &tightAfterBuf[i], portionLen);
-
cl->ublen += portionLen;
- i += portionLen;
-
- if (!rfbSendUpdateBuf(cl))
- return FALSE;
}
+ 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; \