Commit ccdbe8f3 authored by steven_carr's avatar steven_carr

The great UltraVNC Compatibility Commit

parent 347c4a98
2006-05-15 Steven Carr <scarr@jsa-usa.com>
* The great UltraVNC Compatibility Commit!
libvncserver now supports the following messages:
SetSingleWindow - Select a single window to be the source of the
framebuffer.
ServerInput - Disable and blank the servers display
TextChat - TextChat between the remote/local user
(Bandwidth friendly VS the Notepad approach)
FileTransfer - Emulates a Windows Filesystem to the viewer
(Currently does not support Delta Transfers)
(Currently does not support Sending Directories)
UltraZip - Improved UltraZip support
* Improved Statistics SubSystem, now supports all encodings
* RFB 3.8 support! Error Messages are a 'Good Thing' (tm)
* Default to identify as RFB 3.6 to emulate UltraVNC server
(Server now has the ability to set the RFB version reported)
(permits the viewer to identify the server has FileTransfer ability)
* Client Encoding AutoSelection Supported (UltraViewer is speed aware)
* libvncclient has improved server detection/capabilities logic!
2006-05-13 Karl Runge <runge@karlrunge.com>
* minilzo.c,minilzo.h,lzoconf.h: switch to non-CRLF versions.
* libvncclient/Makefile.am: add minilzo.c, minilzo.h, lzoconf.h
......
......@@ -150,6 +150,26 @@ static void kbd_leds(rfbClient* cl, int value, int pad) {
fflush(stderr);
}
/* trivial support for textchat */
static void text_chat(rfbClient* cl, int value, char *text) {
switch(value) {
case rfbTextChatOpen:
fprintf(stderr,"TextChat: We should open a textchat window!\n");
TextChatOpen(cl);
break;
case rfbTextChatClose:
fprintf(stderr,"TextChat: We should close our window!\n");
break;
case rfbTextChatFinished:
fprintf(stderr,"TextChat: We should close our window!\n");
break;
default:
fprintf(stderr,"TextChat: Received \"%s\"\n", text);
break;
}
fflush(stderr);
}
#ifdef __MINGW32__
#define LOG_TO_FILE
#endif
......@@ -212,7 +232,7 @@ int main(int argc,char** argv) {
cl->canHandleNewFBSize = TRUE;
cl->GotFrameBufferUpdate=update;
cl->HandleKeyboardLedState=kbd_leds;
cl->HandleTextChat=text_chat;
if(!rfbInitClient(cl,&argc,argv))
return 1;
......
This diff is collapsed.
......@@ -18,8 +18,6 @@
* USA.
*/
#ifdef LIBVNCSERVER_HAVE_LIBZ
/*
* ultrazip.c - handle ultrazip encoding.
*
......@@ -210,5 +208,3 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh)
}
#undef CARDBPP
#endif
......@@ -377,7 +377,7 @@ static int HandleZRLETile(rfbClient* client,
#undef HandleZRLETile
#undef UncompressCPixel
#undef REALBPP
#undef UNCOMP
#endif
#undef UNCOMP
......@@ -317,7 +317,12 @@ rfbAuthProcessClientMessage(rfbClientPtr cl)
if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) {
rfbLogPerror("rfbAuthProcessClientMessage: write");
}
rfbCloseClient(cl);
/* support RFB 3.8 clients, they expect a reason *why* it was disconnected */
if (cl->protocolMinorVersion > 7) {
rfbClientConnFailed(cl, "password check failed!");
}
else
rfbCloseClient(cl);
return;
}
......
......@@ -41,7 +41,7 @@ static char *rreBeforeBuf = NULL;
static int rreAfterBufSize = 0;
static char *rreAfterBuf = NULL;
static int rreAfterBufLen;
static int rreAfterBufLen = 0;
static int subrectEncode8(uint8_t *data, int w, int h);
static int subrectEncode16(uint16_t *data, int w, int h);
......@@ -145,9 +145,9 @@ rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl,
return rfbSendRectEncodingRaw(cl, x, y, w, h);
}
cl->rectanglesSent[rfbEncodingCoRRE]++;
cl->bytesSent[rfbEncodingCoRRE] += (sz_rfbFramebufferUpdateRectHeader
+ sz_rfbRREHeader + rreAfterBufLen);
rfbStatRecordEncodingSent(cl,rfbEncodingCoRRE,
sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + rreAfterBufLen,
sz_rfbFramebufferUpdateRectHeader + w * h * (cl->format.bitsPerPixel / 8));
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader
> UPDATE_BUF_SIZE)
......
......@@ -78,9 +78,6 @@ rfbSendCursorShape(rfbClientPtr cl)
sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
cl->cursorShapeBytesSent += sz_rfbFramebufferUpdateRectHeader;
cl->cursorShapeUpdatesSent++;
if (!rfbSendUpdateBuf(cl))
return FALSE;
......@@ -167,9 +164,8 @@ rfbSendCursorShape(rfbClientPtr cl)
}
/* Send everything we have prepared in the cl->updateBuf[]. */
cl->cursorShapeBytesSent += (cl->ublen - saved_ublen);
cl->cursorShapeUpdatesSent++;
rfbStatRecordMessageSent(cl, (cl->useRichCursorEncoding ? rfbEncodingRichCursor : rfbEncodingXCursor),
sz_rfbFramebufferUpdateRectHeader + (cl->ublen - saved_ublen), sz_rfbFramebufferUpdateRectHeader + (cl->ublen - saved_ublen));
if (!rfbSendUpdateBuf(cl))
return FALSE;
......@@ -201,8 +197,7 @@ rfbSendCursorPos(rfbClientPtr cl)
sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
cl->cursorPosBytesSent += sz_rfbFramebufferUpdateRectHeader;
cl->cursorPosUpdatesSent++;
rfbStatRecordMessageSent(cl, rfbEncodingPointerPos, sz_rfbFramebufferUpdateRectHeader, sz_rfbFramebufferUpdateRectHeader);
if (!rfbSendUpdateBuf(cl))
return FALSE;
......
......@@ -44,7 +44,7 @@ rfbSendRectEncodingHextile(rfbClientPtr cl,
int h)
{
rfbFramebufferUpdateRectHeader rect;
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
......@@ -60,8 +60,9 @@ rfbSendRectEncodingHextile(rfbClientPtr cl,
sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
cl->rectanglesSent[rfbEncodingHextile]++;
cl->bytesSent[rfbEncodingHextile] += sz_rfbFramebufferUpdateRectHeader;
rfbStatRecordEncodingSent(cl, rfbEncodingHextile,
sz_rfbFramebufferUpdateRectHeader,
sz_rfbFramebufferUpdateRectHeader + w * (cl->format.bitsPerPixel / 8) * h);
switch (cl->format.bitsPerPixel) {
case 8:
......@@ -136,6 +137,7 @@ sendHextiles##bpp(rfbClientPtr cl, int rx, int ry, int rw, int rh) {
startUblen = cl->ublen; \
cl->updateBuf[startUblen] = 0; \
cl->ublen++; \
rfbStatRecordEncodingSentAdd(cl, rfbEncodingHextile, 1); \
\
testColours##bpp(clientPixelData, w * h, \
&mono, &solid, &newBg, &newFg); \
......@@ -148,7 +150,6 @@ sendHextiles##bpp(rfbClientPtr cl, int rx, int ry, int rw, int rh) {
} \
\
if (solid) { \
cl->bytesSent[rfbEncodingHextile] += cl->ublen - startUblen; \
continue; \
} \
\
......@@ -175,15 +176,15 @@ sendHextiles##bpp(rfbClientPtr cl, int rx, int ry, int rw, int rh) {
(*cl->translateFn)(cl->translateLookupTable, \
&(cl->screen->serverFormat), &cl->format, fbptr, \
(char *)clientPixelData, \
cl->scaledScreen->paddedWidthInBytes, w, h); \
cl->scaledScreen->paddedWidthInBytes, w, h); \
\
memcpy(&cl->updateBuf[cl->ublen], (char *)clientPixelData, \
w * h * (bpp/8)); \
\
cl->ublen += w * h * (bpp/8); \
rfbStatRecordEncodingSentAdd(cl, rfbEncodingHextile, \
w * h * (bpp/8)); \
} \
\
cl->bytesSent[rfbEncodingHextile] += cl->ublen - startUblen; \
} \
} \
\
......@@ -210,6 +211,7 @@ subrectEncode##bpp(rfbClientPtr cl, uint##bpp##_t *data, int w, int h,
\
nSubrectsUblen = cl->ublen; \
cl->ublen++; \
rfbStatRecordEncodingSentAdd(cl, rfbEncodingHextile, 1); \
\
for (y=0; y<h; y++) { \
line = data+(y*w); \
......@@ -268,6 +270,7 @@ subrectEncode##bpp(rfbClientPtr cl, uint##bpp##_t *data, int w, int h,
\
cl->updateBuf[cl->ublen++] = rfbHextilePackXY(thex,they); \
cl->updateBuf[cl->ublen++] = rfbHextilePackWH(thew,theh); \
rfbStatRecordEncodingSentAdd(cl, rfbEncodingHextile, 1); \
\
/* \
* Now mark the subrect as done. \
......
......@@ -495,22 +495,40 @@ clientInput(void *data)
pthread_create(&output_thread, NULL, clientOutput, (void *)cl);
while (1) {
fd_set fds;
fd_set rfds, wfds, efds;
struct timeval tv;
int n;
FD_ZERO(&fds);
FD_SET(cl->sock, &fds);
FD_ZERO(&rfds);
FD_SET(cl->sock, &rfds);
FD_ZERO(&efds);
FD_SET(cl->sock, &efds);
/* Are we transferring a file in the background? */
FD_ZERO(&wfds);
if ((cl->fileTransfer.fd!=-1) && (cl->fileTransfer.sending==1))
FD_SET(cl->sock, &wfds);
tv.tv_sec = 60; /* 1 minute */
tv.tv_usec = 0;
n = select(cl->sock + 1, &fds, NULL, &fds, &tv);
n = select(cl->sock + 1, &rfds, &wfds, &efds, &tv);
if (n < 0) {
rfbLogPerror("ReadExact: select");
break;
}
if (n == 0) /* timeout */
{
rfbSendFileTransferChunk(cl);
continue;
rfbProcessClientMessage(cl);
}
/* We have some space on the transmit queue, send some data */
if (FD_ISSET(cl->sock, &wfds))
rfbSendFileTransferChunk(cl);
if (FD_ISSET(cl->sock, &rfds) || FD_ISSET(cl->sock, &efds))
rfbProcessClientMessage(cl);
if (cl->sock == -1) {
/* Client has disconnected. */
break;
......@@ -818,6 +836,10 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
screen->handleEventsEagerly = FALSE;
/* Emulate UltraVNC Server by default */
screen->protocolMajorVersion = 3;
screen->protocolMinorVersion = 6;
if(!rfbProcessArguments(screen,argc,argv)) {
free(screen);
return NULL;
......
This diff is collapsed.
......@@ -40,7 +40,7 @@ static char *rreBeforeBuf = NULL;
static int rreAfterBufSize = 0;
static char *rreAfterBuf = NULL;
static int rreAfterBufLen;
static int rreAfterBufLen=0;
static int subrectEncode8(uint8_t *data, int w, int h);
static int subrectEncode16(uint16_t *data, int w, int h);
......@@ -112,9 +112,9 @@ rfbSendRectEncodingRRE(rfbClientPtr cl,
return rfbSendRectEncodingRaw(cl, x, y, w, h);
}
cl->rectanglesSent[rfbEncodingRRE]++;
cl->bytesSent[rfbEncodingRRE] += (sz_rfbFramebufferUpdateRectHeader
+ sz_rfbRREHeader + rreAfterBufLen);
rfbStatRecordEncodingSent(cl, rfbEncodingRRE,
sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + rreAfterBufLen,
sz_rfbFramebufferUpdateRectHeader + w * h * (cl->format.bitsPerPixel / 8));
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader
> UPDATE_BUF_SIZE)
......
......@@ -128,8 +128,8 @@ void rfbScaledCorrection(rfbScreenInfoPtr from, rfbScreenInfoPtr to, int *x, int
*h = (int)h2;
/* Small changes for a thumbnail may be scaled to zero */
if (*w==0) *w++;
if (*h==0) *h++;
if (*w==0) (*w)++;
if (*h==0) (*h)++;
/* scaling from small to big may overstep the size a bit */
if (*x+*w > to->width) *w=to->width - *x;
if (*y+*h > to->height) *h=to->height - *y;
......@@ -212,7 +212,9 @@ void rfbScaledScreenUpdateRect(rfbScreenInfoPtr screen, rfbScreenInfoPtr ptr, in
pixel_value += (srcptr2[z] << (8 * z));
break;
}
//srcptr2 += bytesPerPixel;
/*
srcptr2 += bytesPerPixel;
*/
red += ((pixel_value >> redShift) & redMax);
green += ((pixel_value >> greenShift) & greenMax);
......
......@@ -239,8 +239,18 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
tv.tv_usec = usec;
nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv);
if (nfds == 0) {
/* timed out, check for async events */
i = rfbGetClientIterator(rfbScreen);
while((cl = rfbClientIteratorNext(i))) {
if (cl->onHold)
continue;
if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
rfbSendFileTransferChunk(cl);
}
rfbReleaseClientIterator(i);
return result;
}
if (nfds < 0) {
#ifdef WIN32
errno = WSAGetLastError();
......@@ -332,11 +342,17 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
i = rfbGetClientIterator(rfbScreen);
while((cl = rfbClientIteratorNext(i))) {
if (cl->onHold)
continue;
if (FD_ISSET(cl->sock, &fds) &&
FD_ISSET(cl->sock, &(rfbScreen->allFds)))
rfbProcessClientMessage(cl);
if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
{
if (FD_ISSET(cl->sock, &fds))
rfbProcessClientMessage(cl);
else
rfbSendFileTransferChunk(cl);
}
}
rfbReleaseClientIterator(i);
} while(rfbScreen->handleEventsEagerly);
......
This diff is collapsed.
......@@ -663,8 +663,8 @@ SendTightHeader(rfbClientPtr cl,
sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
cl->rectanglesSent[rfbEncodingTight]++;
cl->bytesSent[rfbEncodingTight] += sz_rfbFramebufferUpdateRectHeader;
rfbStatRecordEncodingSent(cl, rfbEncodingTight, sz_rfbFramebufferUpdateRectHeader,
sz_rfbFramebufferUpdateRectHeader + w * (cl->format.bitsPerPixel / 8) * h);
return TRUE;
}
......@@ -693,7 +693,7 @@ SendSolidRect(rfbClientPtr cl)
memcpy (&cl->updateBuf[cl->ublen], tightBeforeBuf, len);
cl->ublen += len;
cl->bytesSent[rfbEncodingTight] += len + 1;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, len+1);
return TRUE;
}
......@@ -736,7 +736,7 @@ SendMonoRect(rfbClientPtr cl,
memcpy(&cl->updateBuf[cl->ublen], tightAfterBuf, paletteLen);
cl->ublen += paletteLen;
cl->bytesSent[rfbEncodingTight] += 3 + paletteLen;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, 3 + paletteLen);
break;
case 16:
......@@ -747,7 +747,7 @@ SendMonoRect(rfbClientPtr cl,
memcpy(&cl->updateBuf[cl->ublen], tightAfterBuf, 4);
cl->ublen += 4;
cl->bytesSent[rfbEncodingTight] += 7;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, 7);
break;
default:
......@@ -755,7 +755,7 @@ SendMonoRect(rfbClientPtr cl,
cl->updateBuf[cl->ublen++] = (char)monoBackground;
cl->updateBuf[cl->ublen++] = (char)monoForeground;
cl->bytesSent[rfbEncodingTight] += 5;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, 5);
}
return CompressData(cl, streamId, dataLen,
......@@ -801,7 +801,7 @@ SendIndexedRect(rfbClientPtr cl,
memcpy(&cl->updateBuf[cl->ublen], tightAfterBuf, paletteNumColors * entryLen);
cl->ublen += paletteNumColors * entryLen;
cl->bytesSent[rfbEncodingTight] += 3 + paletteNumColors * entryLen;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, 3 + paletteNumColors * entryLen);
break;
case 16:
......@@ -814,7 +814,7 @@ SendIndexedRect(rfbClientPtr cl,
memcpy(&cl->updateBuf[cl->ublen], tightAfterBuf, paletteNumColors * 2);
cl->ublen += paletteNumColors * 2;
cl->bytesSent[rfbEncodingTight] += 3 + paletteNumColors * 2;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, 3 + paletteNumColors * 2);
break;
default:
......@@ -840,7 +840,7 @@ SendFullColorRect(rfbClientPtr cl,
}
cl->updateBuf[cl->ublen++] = 0x00; /* stream id = 0, no flushing, no filter */
cl->bytesSent[rfbEncodingTight]++;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, 1);
if (usePixelFormat24) {
Pack24(cl, tightBeforeBuf, &cl->format, w * h);
......@@ -874,7 +874,7 @@ SendGradientRect(rfbClientPtr cl,
cl->updateBuf[cl->ublen++] = (streamId | rfbTightExplicitFilter) << 4;
cl->updateBuf[cl->ublen++] = rfbTightFilterGradient;
cl->bytesSent[rfbEncodingTight] += 2;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, 2);
if (usePixelFormat24) {
FilterGradient24(cl, tightBeforeBuf, &cl->format, w, h);
......@@ -905,7 +905,7 @@ CompressData(rfbClientPtr cl,
if (dataLen < TIGHT_MIN_TO_COMPRESS) {
memcpy(&cl->updateBuf[cl->ublen], tightBeforeBuf, dataLen);
cl->ublen += dataLen;
cl->bytesSent[rfbEncodingTight] += dataLen;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, dataLen);
return TRUE;
}
......@@ -955,15 +955,15 @@ static rfbBool SendCompressedData(rfbClientPtr cl,
int i, portionLen;
cl->updateBuf[cl->ublen++] = compressedLen & 0x7F;
cl->bytesSent[rfbEncodingTight]++;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, 1);
if (compressedLen > 0x7F) {
cl->updateBuf[cl->ublen-1] |= 0x80;
cl->updateBuf[cl->ublen++] = compressedLen >> 7 & 0x7F;
cl->bytesSent[rfbEncodingTight]++;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, 1);
if (compressedLen > 0x3FFF) {
cl->updateBuf[cl->ublen-1] |= 0x80;
cl->updateBuf[cl->ublen++] = compressedLen >> 14 & 0xFF;
cl->bytesSent[rfbEncodingTight]++;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, 1);
}
}
......@@ -979,7 +979,7 @@ static rfbBool SendCompressedData(rfbClientPtr cl,
memcpy(&cl->updateBuf[cl->ublen], &tightAfterBuf[i], portionLen);
cl->ublen += portionLen;
}
cl->bytesSent[rfbEncodingTight] += compressedLen;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, compressedLen);
return TRUE;
}
......@@ -1686,7 +1686,7 @@ SendJpegRect(rfbClientPtr cl, int x, int y, int w, int h, int quality)
}
cl->updateBuf[cl->ublen++] = (char)(rfbTightJpeg << 4);
cl->bytesSent[rfbEncodingTight]++;
rfbStatRecordEncodingSentAdd(cl, rfbEncodingTight, 1);
return SendCompressedData(cl, jpegDstDataLen);
}
......
......@@ -28,6 +28,12 @@
#include <rfb/rfb.h>
#include <limits.h>
/* PATH_MAX is not defined in limits.h on some platforms */
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#define rfbSecTypeTight 16
void rfbTightUsage(void);
......
......@@ -101,9 +101,7 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl,
}
/* Update statics */
cl->rectanglesSent[rfbEncodingUltra]++;
cl->bytesSent[rfbEncodingUltra] += (sz_rfbFramebufferUpdateRectHeader
+ sz_rfbZlibHeader + lzoAfterBufLen);
rfbStatRecordEncodingSent(cl, rfbEncodingUltra, sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader + lzoAfterBufLen, maxRawSize);
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader
> UPDATE_BUF_SIZE)
......
......@@ -121,6 +121,7 @@ rfbSendOneRectEncodingZlib(rfbClientPtr cl,
zlibAfterBuf = (char *)realloc(zlibAfterBuf, zlibAfterBufSize);
}
/*
* Convert pixel data to client format.
*/
......@@ -176,9 +177,8 @@ rfbSendOneRectEncodingZlib(rfbClientPtr cl,
*/
/* Update statics */
cl->rectanglesSent[rfbEncodingZlib]++;
cl->bytesSent[rfbEncodingZlib] += (sz_rfbFramebufferUpdateRectHeader
+ sz_rfbZlibHeader + zlibAfterBufLen);
rfbStatRecordEncodingSent(cl, rfbEncodingZlib, sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader + zlibAfterBufLen,
+ w * (cl->format.bitsPerPixel / 8) * h);
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader
> UPDATE_BUF_SIZE)
......
......@@ -124,9 +124,8 @@ rfbBool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w, int h)
break;
}
cl->rectanglesSent[rfbEncodingZRLE]++;
cl->bytesSent[rfbEncodingZRLE] += (sz_rfbFramebufferUpdateRectHeader
+ sz_rfbZRLEHeader + ZRLE_BUFFER_LENGTH(&zos->out));
rfbStatRecordEncodingSent(cl, rfbEncodingZRLE, sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader + ZRLE_BUFFER_LENGTH(&zos->out),
+ w * (cl->format.bitsPerPixel / 8) * h);
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZRLEHeader
> UPDATE_BUF_SIZE)
......
......@@ -136,8 +136,22 @@ typedef rfbBool (*rfbPasswordCheckProcPtr)(struct _rfbClientRec* cl,const char*
typedef enum rfbNewClientAction (*rfbNewClientHookPtr)(struct _rfbClientRec* cl);
typedef void (*rfbDisplayHookPtr)(struct _rfbClientRec* cl);
/* support the capability to view the caps/num/scroll states of the X server */
typedef int (*rfbGetKeyboardLedStateHookPtr)(struct _rfbScreenInfo* screen);
typedef int (*rfbGetKeyboardLedStateHookPtr)(struct _rfbScreenInfo* screen);
/* If x==1 and y==1 then set the whole display
* else find the window underneath x and y and set the framebuffer to the dimensions
* of that window
*/
typedef void (*rfbSetSingleWindowProcPtr) (struct _rfbClientRec* cl, int x, int y);
/* Status determines if the X11 server permits input from the local user
* status==0 or 1
*/
typedef void (*rfbSetServerInputProcPtr) (struct _rfbClientRec* cl, int status);
/* Permit the server to allow or deny filetransfers. This is defaulted to deny
* It is called when a client initiates a connection to determine if it is permitted.
*/
typedef int (*rfbFileTransferPermitted) (struct _rfbClientRec* cl);
/* Handle the textchat messages */
typedef void (*rfbSetTextChat) (struct _rfbClientRec* cl, int length, char *string);
typedef struct {
uint32_t count;
......@@ -296,7 +310,11 @@ typedef struct _rfbScreenInfo
rfbSetXCutTextProcPtr setXCutText;
rfbGetCursorProcPtr getCursorPtr;
rfbSetTranslateFunctionProcPtr setTranslateFunction;
rfbSetSingleWindowProcPtr setSingleWindow;
rfbSetServerInputProcPtr setServerInput;
rfbFileTransferPermitted getFileTransferPermission;
rfbSetTextChat setTextChat;
/* newClientHook is called just after a new client is created */
rfbNewClientHookPtr newClientHook;
/* displayHook is called just before a frame buffer update */
......@@ -326,6 +344,10 @@ typedef struct _rfbScreenInfo
/* rfbEncodingServerIdentity */
char *versionString;
/* What does the server tell the new clients which version it supports */
int protocolMajorVersion;
int protocolMinorVersion;
} rfbScreenInfo, *rfbScreenInfoPtr;
......@@ -351,6 +373,27 @@ typedef struct sraRegion* sraRegionPtr;
typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl);
typedef struct _rfbFileTransferData {
int fd;
int compressionEnabled;
int fileSize;
int numPackets;
int receiving;
int sending;
} rfbFileTransferData;
typedef struct _rfbStatList {
uint32_t type;
uint32_t sentCount;
uint32_t bytesSent;
uint32_t bytesSentIfRaw;
uint32_t rcvdCount;
uint32_t bytesRcvd;
uint32_t bytesRcvdIfRaw;
struct _rfbStatList *Next;
} rfbStatList;
typedef struct _rfbClientRec {
/* back pointer to the screen */
......@@ -467,20 +510,11 @@ typedef struct _rfbClientRec {
int ublen;
/* statistics */
int bytesSent[MAX_ENCODINGS];
int rectanglesSent[MAX_ENCODINGS];
int lastRectMarkersSent;
int lastRectBytesSent;
int cursorShapeBytesSent;
int cursorShapeUpdatesSent;
int cursorPosBytesSent;
int cursorPosUpdatesSent;
int framebufferUpdateMessagesSent;
struct _rfbStatList *statEncList;
struct _rfbStatList *statMsgList;
int rawBytesEquivalent;
int keyEventsRcvd;
int pointerEventsRcvd;
int bytesSent;
#ifdef LIBVNCSERVER_HAVE_LIBZ
/* zlib encoding -- necessary compression state info per client */
......@@ -502,6 +536,7 @@ typedef struct _rfbClientRec {
rfbBool compStreamInitedLZO;
char *lzoWrkMem;
rfbFileTransferData fileTransfer;
int lastKeyboardLedState; /* keep track of last value so we can send *change* events */
rfbBool enableSupportedMessages; /* client supports SupportedMessages encoding */
......@@ -584,6 +619,11 @@ extern char rfbEndianTest;
#define Swap24IfLE(l) (rfbEndianTest ? Swap24(l) : (l))
#define Swap32IfLE(l) (rfbEndianTest ? Swap32(l) : (l))
/* UltraVNC uses some windows structures unmodified, so the viewer expects LittleEndian Data */
#define Swap16IfBE(s) (rfbEndianTest ? (s) : Swap16(s))
#define Swap24IfBE(l) (rfbEndianTest ? (l) : Swap24(l))
#define Swap32IfBE(l) (rfbEndianTest ? (l) : Swap32(l))
/* sockets.c */
extern int rfbMaxClientWait;
......@@ -634,6 +674,13 @@ extern rfbBool rfbSendNewFBSize(rfbClientPtr cl, int w, int h);
extern rfbBool rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour, int nColours);
extern void rfbSendBell(rfbScreenInfoPtr rfbScreen);
extern char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length);
extern rfbBool rfbSendFileTransferChunk(rfbClientPtr cl);
extern rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer);
extern rfbBool rfbSendFileTransferMessage(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length, char *buffer);
extern char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length);
extern rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length);
void rfbGotXCutText(rfbScreenInfoPtr rfbScreen, char *str, int len);
/* translate.c */
......@@ -880,6 +927,38 @@ extern rfbBool rfbIsActive(rfbScreenInfoPtr screenInfo);
void rfbRegisterTightVNCFileTransferExtension();
void rfbUnregisterTightVNCFileTransferExtension();
/* Statistics */
extern char *messageNameServer2Client(uint32_t type, char *buf, int len);
extern char *messageNameClient2Server(uint32_t type, char *buf, int len);
extern char *encodingName(uint32_t enc, char *buf, int len);
extern rfbStatList *rfbStatLookupEncoding(rfbClientPtr cl, uint32_t type);
extern rfbStatList *rfbStatLookupMessage(rfbClientPtr cl, uint32_t type);
/* Each call to rfbStatRecord* adds one to the rect count for that type */
extern void rfbStatRecordEncodingSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
extern void rfbStatRecordEncodingSentAdd(rfbClientPtr cl, uint32_t type, int byteCount); /* Specifically for tight encoding */
extern void rfbStatRecordEncodingRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
extern void rfbStatRecordMessageSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
extern void rfbStatRecordMessageRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
extern void rfbResetStats(rfbClientPtr cl);
extern void rfbPrintStats(rfbClientPtr cl);
extern int rfbStatGetSentBytes(rfbClientPtr cl);
extern int rfbStatGetSentBytesIfRaw(rfbClientPtr cl);
extern int rfbStatGetRcvdBytes(rfbClientPtr cl);
extern int rfbStatGetRcvdBytesIfRaw(rfbClientPtr cl);
extern int rfbStatGetMessageCountSent(rfbClientPtr cl, uint32_t type);
extern int rfbStatGetMessageCountRcvd(rfbClientPtr cl, uint32_t type);
extern int rfbStatGetEncodingCountSent(rfbClientPtr cl, uint32_t type);
extern int rfbStatGetEncodingCountRcvd(rfbClientPtr cl, uint32_t type);
/* Set which version you want to advertise 3.3, 3.6, 3.7 and 3.8 are currently supported*/
extern void rfbSetProtocolVersion(rfbScreenInfoPtr rfbScreen, int major_, int minor_);
#endif
#if(defined __cplusplus)
......
......@@ -96,6 +96,7 @@ typedef struct {
struct _rfbClient;
typedef void (*HandleTextChatProc)(struct _rfbClient* client, int value, char *text);
typedef void (*HandleKeyboardLedStateProc)(struct _rfbClient* client, int value, int pad);
typedef rfbBool (*HandleCursorPosProc)(struct _rfbClient* client, int x, int y);
typedef void (*SoftCursorLockAreaProc)(struct _rfbClient* client, int x, int y, int w, int h);
......@@ -210,6 +211,7 @@ typedef struct _rfbClient {
int canHandleNewFBSize;
/* hooks */
HandleTextChatProc HandleTextChat;
HandleKeyboardLedStateProc HandleKeyboardLedState;
HandleCursorPosProc HandleCursorPos;
SoftCursorLockAreaProc SoftCursorLockArea;
......@@ -219,6 +221,19 @@ typedef struct _rfbClient {
GetPasswordProc GetPassword;
MallocFrameBufferProc MallocFrameBuffer;
BellProc Bell;
/* Which messages are supported by the server
* This is a *guess* for most servers.
* (If we can even detect the type of server)
*
* If the server supports the "rfbEncodingSupportedMessages"
* then this will be updated when the encoding is received to
* accurately reflect the servers capabilities.
*/
rfbSupportedMessages supportedMessages;
/* negotiated protocol version */
int major, minor;
} rfbClient;
/* cursor.c */
......@@ -247,6 +262,12 @@ extern rfbBool SendKeyEvent(rfbClient* client,uint32_t key, rfbBool down);
extern rfbBool SendClientCutText(rfbClient* client,char *str, int len);
extern rfbBool HandleRFBServerMessage(rfbClient* client);
extern rfbBool TextChatSend(rfbClient* client, char *text);
extern rfbBool TextChatOpen(rfbClient* client);
extern rfbBool TextChatClose(rfbClient* client);
extern rfbBool TextChatFinish(rfbClient* client);
extern rfbBool PermitServerInput(rfbClient* client, int enabled);
extern void PrintPixelFormat(rfbPixelFormat *format);
/* client data */
......
......@@ -218,8 +218,10 @@ typedef struct {
#define rfbProtocolVersionFormat "RFB %03d.%03d\n"
#define rfbProtocolMajorVersion 3
#define rfbProtocolMinorVersion 7
#define rfbProtocolFallbackMinorVersion 3
#define rfbProtocolMinorVersion 6
/* UltraVNC Viewer examines rfbProtocolMinorVersion number (4, and 6)
* to identify if the server supports File Transfer
*/
typedef char rfbProtocolVersionMsg[13]; /* allow extra byte for null */
......@@ -397,24 +399,18 @@ typedef struct {
#define rfbEncodingRRE 2
#define rfbEncodingCoRRE 4
#define rfbEncodingHextile 5
#ifdef LIBVNCSERVER_HAVE_LIBZ
#define rfbEncodingZlib 6
#define rfbEncodingTight 7
#define rfbEncodingZlibHex 8
#endif
#define rfbEncodingUltra 9
#ifdef LIBVNCSERVER_HAVE_LIBZ
#define rfbEncodingZRLE 16
#endif
/* Cache & XOR-Zlib - rdv@2002 */
#define rfbEncodingCache 0xFFFF0000
#define rfbEncodingCacheEnable 0xFFFF0001
#ifdef LIBVNCSERVER_HAVE_LIBZ
#define rfbEncodingXOR_Zlib 0xFFFF0002
#define rfbEncodingXORMonoColor_Zlib 0xFFFF0003
#define rfbEncodingXORMultiColor_Zlib 0xFFFF0004
#endif
#define rfbEncodingSolidColor 0xFFFF0005
#define rfbEncodingXOREnable 0xFFFF0006
#define rfbEncodingCacheZip 0xFFFF0007
......@@ -649,11 +645,11 @@ typedef struct {
#define rfbHextileExtractW(byte) (((byte) >> 4) + 1)
#define rfbHextileExtractH(byte) (((byte) & 0xf) + 1)
#ifdef LIBVNCSERVER_HAVE_LIBZ
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* zlib - zlib compressed Encoding. We have an rfbZlibHeader structure
* giving the number of bytes following. Finally the data follows is
* zlib compressed version of the raw pixel data as negotiated.
* (NOTE: also used by Ultra Encoding)
*/
typedef struct {
......@@ -662,6 +658,7 @@ typedef struct {
#define sz_rfbZlibHeader 4
#ifdef LIBVNCSERVER_HAVE_LIBZ
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Tight Encoding.
......@@ -935,9 +932,10 @@ typedef struct {
typedef struct _rfbFileTransferMsg {
uint8_t type; /* always rfbFileTransfer */
uint8_t contentType; /* See defines below */
uint16_t contentParam;/* Other possible content classification (Dir or File name, etc..) */
uint32_t size; /* FileSize or packet index or error or other */
/* uint32_t sizeH; Additional 32Bits params to handle big values. Only for V2 (we want backward compatibility between all V1 versions) */
uint8_t contentParam;/* Other possible content classification (Dir or File name, etc..) */
uint8_t pad; /* It appears that UltraVNC *forgot* to Swap16IfLE(contentParam) */
uint32_t size; /* FileSize or packet index or error or other */
/* uint32_t sizeH; Additional 32Bits params to handle big values. Only for V2 (we want backward compatibility between all V1 versions) */
uint32_t length;
/* followed by data char text[length] */
} rfbFileTransferMsg;
......
......@@ -350,11 +350,8 @@ db = 0;
}
nclients++;
cbs = 0;
for (i=0; i<MAX_ENCODINGS; i++) {
cbs += cl->bytesSent[i];
}
rbs = cl->rawBytesEquivalent;
cbs = rfbStatGetSentBytes(cl);
rbs = rfbStatGetSentBytesIfRaw(cl);
if (init) {
......@@ -435,7 +432,7 @@ if (db) fprintf(stderr, "%d client num rects req: %d mod: %d cbs: %d "
if (db) fprintf(stderr, "dt2 calc: num rects req: %d/%d mod: %d/%d "
"fbu-sent: %d dt: %.4f dt2: %.4f tm: %.4f\n",
req0, req1, mod0, mod1, cl->framebufferUpdateMessagesSent, dt, dt2, tm);
req0, req1, mod0, mod1, rfbStatGetMessageCountSent(cl, rfbFramebufferUpdate), dt, dt2, tm);
if (req1 != 0 && mod1 == 0) {
got_t2 = 1;
break;
......@@ -502,7 +499,7 @@ if (db) fprintf(stderr, "dt2 calc: num rects req: %d/%d mod: %d/%d "
if (db) fprintf(stderr, "dt3 calc: num rects req: %d/%d mod: %d/%d "
"fbu-sent: %d dt: %.4f dt3: %.4f tm: %.4f\n",
req0, req1, mod0, mod1, cl->framebufferUpdateMessagesSent, dt, dt3, tm);
req0, req1, mod0, mod1, rfbStatGetMessageCountSent(cl, rfbFramebufferUpdate), dt, dt3, tm);
if (req1 != 0 && mod1 == 0) {
dts[got_t3++] = dt3;
......
......@@ -4082,7 +4082,7 @@ int fb_update_sent(int *count) {
i = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(i)) ) {
sent += cl->framebufferUpdateMessagesSent;
sent += rfbStatGetMessageCountSent(cl, rfbFramebufferUpdate);
}
rfbReleaseClientIterator(i);
if (sent != last_count) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment