summaryrefslogtreecommitdiffstats
path: root/libvncserver/stats.c
diff options
context:
space:
mode:
authorsteven_carr <steven_carr>2006-05-15 05:37:39 +0000
committersteven_carr <steven_carr>2006-05-15 05:37:39 +0000
commitccdbe8f3256c3c776a1cc1a0517a38437b9e2c65 (patch)
tree9853559d1c965946b196cccd03ce0f466d524950 /libvncserver/stats.c
parent347c4a98475d1dba8030efe33aa0b35856c4d17f (diff)
downloadlibtdevnc-ccdbe8f3256c3c776a1cc1a0517a38437b9e2c65.tar.gz
libtdevnc-ccdbe8f3256c3c776a1cc1a0517a38437b9e2c65.zip
The great UltraVNC Compatibility Commit
Diffstat (limited to 'libvncserver/stats.c')
-rwxr-xr-xlibvncserver/stats.c476
1 files changed, 410 insertions, 66 deletions
diff --git a/libvncserver/stats.c b/libvncserver/stats.c
index ed9a3d0..0f8758f 100755
--- a/libvncserver/stats.c
+++ b/libvncserver/stats.c
@@ -26,90 +26,434 @@
#include <rfb/rfb.h>
-static const char* encNames[] = {
- "raw", "copyRect", "RRE", "[encoding 3]", "CoRRE", "hextile",
- "zlib", "tight", "[encoding 8]", "ultra", "[encoding 10]",
- "[encoding 11]", "[encoding 12]", "[encoding 13]", "[encoding 14]",
- "[encoding 15]",
- "ZRLE", "[encoding 17]", "[encoding 18]", "[encoding 19]", "[encoding 20]"
-};
+char *messageNameServer2Client(uint32_t type, char *buf, int len);
+char *messageNameClient2Server(uint32_t type, char *buf, int len);
+char *encodingName(uint32_t enc, char *buf, int len);
+rfbStatList *rfbStatLookupEncoding(rfbClientPtr cl, uint32_t type);
+rfbStatList *rfbStatLookupMessage(rfbClientPtr cl, uint32_t type);
-void
-rfbResetStats(rfbClientPtr cl)
+void rfbStatRecordEncodingSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
+void rfbStatRecordEncodingRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
+void rfbStatRecordMessageSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
+void rfbStatRecordMessageRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
+void rfbResetStats(rfbClientPtr cl);
+void rfbPrintStats(rfbClientPtr cl);
+
+
+
+
+char *messageNameServer2Client(uint32_t type, char *buf, int len) {
+ if (buf==NULL) return "error";
+ switch (type) {
+ case rfbFramebufferUpdate: snprintf(buf, len, "FramebufferUpdate"); break;
+ case rfbSetColourMapEntries: snprintf(buf, len, "SetColourMapEntries"); break;
+ case rfbBell: snprintf(buf, len, "Bell"); break;
+ case rfbServerCutText: snprintf(buf, len, "ServerCutText"); break;
+ case rfbResizeFrameBuffer: snprintf(buf, len, "ResizeFrameBuffer"); break;
+ case rfbKeyFrameUpdate: snprintf(buf, len, "KeyFrameUpdate"); break;
+ case rfbFileTransfer: snprintf(buf, len, "FileTransfer"); break;
+ case rfbTextChat: snprintf(buf, len, "TextChat"); break;
+ case rfbPalmVNCReSizeFrameBuffer: snprintf(buf, len, "PalmVNCReSize"); break;
+ default:
+ snprintf(buf, len, "server2client(0x%04X)", type);
+ }
+ return buf;
+}
+
+char *messageNameClient2Server(uint32_t type, char *buf, int len) {
+ if (buf==NULL) return "error";
+ switch (type) {
+ case rfbSetPixelFormat: snprintf(buf, len, "SetPixelFormat"); break;
+ case rfbFixColourMapEntries: snprintf(buf, len, "FixColourMapEntries"); break;
+ case rfbSetEncodings: snprintf(buf, len, "SetEncodings"); break;
+ case rfbFramebufferUpdateRequest: snprintf(buf, len, "FramebufferUpdate"); break;
+ case rfbKeyEvent: snprintf(buf, len, "KeyEvent"); break;
+ case rfbPointerEvent: snprintf(buf, len, "PointerEvent"); break;
+ case rfbClientCutText: snprintf(buf, len, "ClientCutText"); break;
+ case rfbFileTransfer: snprintf(buf, len, "FileTransfer"); break;
+ case rfbSetScale: snprintf(buf, len, "SetScale"); break;
+ case rfbSetServerInput: snprintf(buf, len, "SetServerInput"); break;
+ case rfbSetSW: snprintf(buf, len, "SetSingleWindow"); break;
+ case rfbTextChat: snprintf(buf, len, "TextChat"); break;
+ case rfbKeyFrameRequest: snprintf(buf, len, "KeyFrameRequest"); break;
+ case rfbPalmVNCSetScaleFactor: snprintf(buf, len, "PalmVNCSetScale"); break;
+ default:
+ snprintf(buf, len, "client2server(0x%04X)", type);
+
+
+ }
+ return buf;
+}
+
+char *encodingName(uint32_t type, char *buf, int len) {
+ if (buf==NULL) return "error";
+
+ switch (type) {
+ case rfbEncodingRaw: snprintf(buf, len, "raw"); break;
+ case rfbEncodingCopyRect: snprintf(buf, len, "copyRect"); break;
+ case rfbEncodingRRE: snprintf(buf, len, "RRE"); break;
+ case rfbEncodingCoRRE: snprintf(buf, len, "CoRRE"); break;
+ case rfbEncodingHextile: snprintf(buf, len, "hextile"); break;
+ case rfbEncodingZlib: snprintf(buf, len, "zlib"); break;
+ case rfbEncodingTight: snprintf(buf, len, "tight"); break;
+ case rfbEncodingZlibHex: snprintf(buf, len, "zlibhex"); break;
+ case rfbEncodingUltra: snprintf(buf, len, "ultra"); break;
+ case rfbEncodingZRLE: snprintf(buf, len, "ZRLE"); break;
+ case rfbEncodingCache: snprintf(buf, len, "cache"); break;
+ case rfbEncodingCacheEnable: snprintf(buf, len, "cacheEnable"); break;
+ case rfbEncodingXOR_Zlib: snprintf(buf, len, "xorZlib"); break;
+ case rfbEncodingXORMonoColor_Zlib: snprintf(buf, len, "xorMonoZlib"); break;
+ case rfbEncodingXORMultiColor_Zlib: snprintf(buf, len, "xorColorZlib"); break;
+ case rfbEncodingSolidColor: snprintf(buf, len, "solidColor"); break;
+ case rfbEncodingXOREnable: snprintf(buf, len, "xorEnable"); break;
+ case rfbEncodingCacheZip: snprintf(buf, len, "cacheZip"); break;
+ case rfbEncodingSolMonoZip: snprintf(buf, len, "monoZip"); break;
+ case rfbEncodingUltraZip: snprintf(buf, len, "ultraZip"); break;
+
+ case rfbEncodingXCursor: snprintf(buf, len, "Xcursor"); break;
+ case rfbEncodingRichCursor: snprintf(buf, len, "RichCursor"); break;
+ case rfbEncodingPointerPos: snprintf(buf, len, "PointerPos"); break;
+
+ case rfbEncodingLastRect: snprintf(buf, len, "LastRect"); break;
+ case rfbEncodingNewFBSize: snprintf(buf, len, "NewFBSize"); break;
+ case rfbEncodingKeyboardLedState: snprintf(buf, len, "LedState"); break;
+ case rfbEncodingSupportedMessages: snprintf(buf, len, "SupportedMessages"); break;
+ case rfbEncodingSupportedEncodings: snprintf(buf, len, "SupportedEncodings"); break;
+ case rfbEncodingServerIdentity: snprintf(buf, len, "ServerIdentity"); break;
+
+ case rfbEncodingCompressLevel0: snprintf(buf, len, "CompressLevel0"); break;
+ case rfbEncodingCompressLevel1: snprintf(buf, len, "CompressLevel1"); break;
+ case rfbEncodingCompressLevel2: snprintf(buf, len, "CompressLevel2"); break;
+ case rfbEncodingCompressLevel3: snprintf(buf, len, "CompressLevel3"); break;
+ case rfbEncodingCompressLevel4: snprintf(buf, len, "CompressLevel4"); break;
+ case rfbEncodingCompressLevel5: snprintf(buf, len, "CompressLevel5"); break;
+ case rfbEncodingCompressLevel6: snprintf(buf, len, "CompressLevel6"); break;
+ case rfbEncodingCompressLevel7: snprintf(buf, len, "CompressLevel7"); break;
+ case rfbEncodingCompressLevel8: snprintf(buf, len, "CompressLevel8"); break;
+ case rfbEncodingCompressLevel9: snprintf(buf, len, "CompressLevel9"); break;
+
+ case rfbEncodingQualityLevel0: snprintf(buf, len, "QualityLevel0"); break;
+ case rfbEncodingQualityLevel1: snprintf(buf, len, "QualityLevel1"); break;
+ case rfbEncodingQualityLevel2: snprintf(buf, len, "QualityLevel2"); break;
+ case rfbEncodingQualityLevel3: snprintf(buf, len, "QualityLevel3"); break;
+ case rfbEncodingQualityLevel4: snprintf(buf, len, "QualityLevel4"); break;
+ case rfbEncodingQualityLevel5: snprintf(buf, len, "QualityLevel5"); break;
+ case rfbEncodingQualityLevel6: snprintf(buf, len, "QualityLevel6"); break;
+ case rfbEncodingQualityLevel7: snprintf(buf, len, "QualityLevel7"); break;
+ case rfbEncodingQualityLevel8: snprintf(buf, len, "QualityLevel8"); break;
+ case rfbEncodingQualityLevel9: snprintf(buf, len, "QualityLevel9"); break;
+
+
+ default:
+ snprintf(buf, len, "encoding(0x%04X)", type);
+ }
+
+ return buf;
+}
+
+
+
+
+
+rfbStatList *rfbStatLookupEncoding(rfbClientPtr cl, uint32_t type)
{
- int i;
- for (i = 0; i < MAX_ENCODINGS; i++) {
- cl->bytesSent[i] = 0;
- cl->rectanglesSent[i] = 0;
+ rfbStatList *ptr;
+ if (cl==NULL) return NULL;
+ for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
+ {
+ if (ptr->type==type) return ptr;
+ }
+ /* Well, we are here... need to *CREATE* an entry */
+ ptr = (rfbStatList *)malloc(sizeof(rfbStatList));
+ if (ptr!=NULL)
+ {
+ memset((char *)ptr, 0, sizeof(rfbStatList));
+ ptr->type = type;
+ /* add to the top of the list */
+ ptr->Next = cl->statEncList;
+ cl->statEncList = ptr;
}
- cl->lastRectMarkersSent = 0;
- cl->lastRectBytesSent = 0;
- cl->cursorShapeBytesSent = 0;
- cl->cursorShapeUpdatesSent = 0;
- cl->cursorPosBytesSent = 0;
- cl->cursorPosUpdatesSent = 0;
- cl->framebufferUpdateMessagesSent = 0;
- cl->rawBytesEquivalent = 0;
- cl->keyEventsRcvd = 0;
- cl->pointerEventsRcvd = 0;
+ return ptr;
}
-void
-rfbPrintStats(rfbClientPtr cl)
+
+rfbStatList *rfbStatLookupMessage(rfbClientPtr cl, uint32_t type)
{
- int i;
- int totalRectanglesSent = 0;
- int totalBytesSent = 0;
+ rfbStatList *ptr;
+ if (cl==NULL) return NULL;
+ for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
+ {
+ if (ptr->type==type) return ptr;
+ }
+ /* Well, we are here... need to *CREATE* an entry */
+ ptr = (rfbStatList *)malloc(sizeof(rfbStatList));
+ if (ptr!=NULL)
+ {
+ memset((char *)ptr, 0, sizeof(rfbStatList));
+ ptr->type = type;
+ /* add to the top of the list */
+ ptr->Next = cl->statMsgList;
+ cl->statMsgList = ptr;
+ }
+ return ptr;
+}
- rfbLog("Statistics:\n");
+void rfbStatRecordEncodingSentAdd(rfbClientPtr cl, uint32_t type, int byteCount) /* Specifically for tight encoding */
+{
+ rfbStatList *ptr;
- if ((cl->keyEventsRcvd != 0) || (cl->pointerEventsRcvd != 0))
- rfbLog(" key events received %d, pointer events %d\n",
- cl->keyEventsRcvd, cl->pointerEventsRcvd);
+ ptr = rfbStatLookupEncoding(cl, type);
+ if (ptr!=NULL)
+ ptr->bytesSent += byteCount;
+}
- for (i = 0; i < MAX_ENCODINGS; i++) {
- totalRectanglesSent += cl->rectanglesSent[i];
- totalBytesSent += cl->bytesSent[i];
+
+void rfbStatRecordEncodingSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw)
+{
+ rfbStatList *ptr;
+
+ ptr = rfbStatLookupEncoding(cl, type);
+ if (ptr!=NULL)
+ {
+ ptr->sentCount++;
+ ptr->bytesSent += byteCount;
+ ptr->bytesSentIfRaw += byteIfRaw;
}
+}
- totalRectanglesSent += (cl->cursorShapeUpdatesSent +
- cl->cursorPosUpdatesSent +
- cl->lastRectMarkersSent);
- totalBytesSent += (cl->cursorShapeBytesSent +
- cl->cursorPosBytesSent +
- cl->lastRectBytesSent);
+void rfbStatRecordEncodingRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw)
+{
+ rfbStatList *ptr;
- rfbLog(" framebuffer updates %d, rectangles %d, bytes %d\n",
- cl->framebufferUpdateMessagesSent, totalRectanglesSent,
- totalBytesSent);
+ ptr = rfbStatLookupEncoding(cl, type);
+ if (ptr!=NULL)
+ {
+ ptr->rcvdCount++;
+ ptr->bytesRcvd += byteCount;
+ ptr->bytesRcvdIfRaw += byteIfRaw;
+ }
+}
- if (cl->lastRectMarkersSent != 0)
- rfbLog(" LastRect and NewFBSize markers %d, bytes %d\n",
- cl->lastRectMarkersSent, cl->lastRectBytesSent);
+void rfbStatRecordMessageSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw)
+{
+ rfbStatList *ptr;
- if (cl->cursorShapeUpdatesSent != 0)
- rfbLog(" cursor shape updates %d, bytes %d\n",
- cl->cursorShapeUpdatesSent, cl->cursorShapeBytesSent);
+ ptr = rfbStatLookupMessage(cl, type);
+ if (ptr!=NULL)
+ {
+ ptr->sentCount++;
+ ptr->bytesSent += byteCount;
+ ptr->bytesSentIfRaw += byteIfRaw;
+ }
+}
- if (cl->cursorPosUpdatesSent != 0)
- rfbLog(" cursor position updates %d, bytes %d\n",
- cl->cursorPosUpdatesSent, cl->cursorPosBytesSent);
+void rfbStatRecordMessageRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw)
+{
+ rfbStatList *ptr;
- for (i = 0; i < MAX_ENCODINGS; i++) {
- if (cl->rectanglesSent[i] != 0)
- rfbLog(" %s rectangles %d, bytes %d\n",
- encNames[i], cl->rectanglesSent[i], cl->bytesSent[i]);
+ ptr = rfbStatLookupMessage(cl, type);
+ if (ptr!=NULL)
+ {
+ ptr->rcvdCount++;
+ ptr->bytesRcvd += byteCount;
+ ptr->bytesRcvdIfRaw += byteIfRaw;
}
+}
+
+
+int rfbStatGetSentBytes(rfbClientPtr cl)
+{
+ rfbStatList *ptr=NULL;
+ int bytes=0;
+ if (cl==NULL) return 0;
+ for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
+ bytes += ptr->bytesSent;
+ for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
+ bytes += ptr->bytesSent;
+ return bytes;
+}
+
+int rfbStatGetSentBytesIfRaw(rfbClientPtr cl)
+{
+ rfbStatList *ptr=NULL;
+ int bytes=0;
+ if (cl==NULL) return 0;
+ for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
+ bytes += ptr->bytesSentIfRaw;
+ for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
+ bytes += ptr->bytesSentIfRaw;
+ return bytes;
+}
+
+int rfbStatGetRcvdBytes(rfbClientPtr cl)
+{
+ rfbStatList *ptr=NULL;
+ int bytes=0;
+ if (cl==NULL) return 0;
+ for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
+ bytes += ptr->bytesRcvd;
+ for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
+ bytes += ptr->bytesRcvd;
+ return bytes;
+}
+
+int rfbStatGetRcvdBytesIfRaw(rfbClientPtr cl)
+{
+ rfbStatList *ptr=NULL;
+ int bytes=0;
+ if (cl==NULL) return 0;
+ for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
+ bytes += ptr->bytesRcvdIfRaw;
+ for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
+ bytes += ptr->bytesRcvdIfRaw;
+ return bytes;
+}
+
+int rfbStatGetMessageCountSent(rfbClientPtr cl, uint32_t type)
+{
+ rfbStatList *ptr=NULL;
+ if (cl==NULL) return 0;
+ for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
+ if (ptr->type==type) return ptr->sentCount;
+ return 0;
+}
+int rfbStatGetMessageCountRcvd(rfbClientPtr cl, uint32_t type)
+{
+ rfbStatList *ptr=NULL;
+ if (cl==NULL) return 0;
+ for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
+ if (ptr->type==type) return ptr->rcvdCount;
+ return 0;
+}
+
+int rfbStatGetEncodingCountSent(rfbClientPtr cl, uint32_t type)
+{
+ rfbStatList *ptr=NULL;
+ if (cl==NULL) return 0;
+ for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
+ if (ptr->type==type) return ptr->sentCount;
+ return 0;
+}
+int rfbStatGetEncodingCountRcvd(rfbClientPtr cl, uint32_t type)
+{
+ rfbStatList *ptr=NULL;
+ if (cl==NULL) return 0;
+ for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
+ if (ptr->type==type) return ptr->rcvdCount;
+ return 0;
+}
+
+
- if ((totalBytesSent - cl->bytesSent[rfbEncodingCopyRect]) != 0) {
- rfbLog(" raw bytes equivalent %d, compression ratio %f\n",
- cl->rawBytesEquivalent,
- (double)cl->rawBytesEquivalent
- / (double)(totalBytesSent
- - cl->bytesSent[rfbEncodingCopyRect]-
- cl->cursorShapeBytesSent -
- cl->cursorPosBytesSent -
- cl->lastRectBytesSent));
+
+void rfbResetStats(rfbClientPtr cl)
+{
+ rfbStatList *ptr;
+ if (cl==NULL) return;
+ while (cl->statEncList!=NULL)
+ {
+ ptr = cl->statEncList;
+ cl->statEncList = ptr->Next;
+ free(ptr);
+ }
+ while (cl->statMsgList!=NULL)
+ {
+ ptr = cl->statMsgList;
+ cl->statMsgList = ptr->Next;
+ free(ptr);
}
}
+
+
+void rfbPrintStats(rfbClientPtr cl)
+{
+ rfbStatList *ptr=NULL;
+ char encBuf[64];
+ double savings=0.0;
+ int totalRectsSent=0;
+ double totalBytesSent=0.0;
+ double totalBytesIfRawSent=0.0;
+ int totalRectsRcvd=0;
+ double totalBytesRcvd=0.0;
+ double totalBytesIfRawRcvd=0.0;
+
+ char *name=NULL;
+ int bytes=0;
+ int count=0;
+
+ if (cl==NULL) return;
+
+ rfbLog("Statistics: Transmit\n");
+ for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
+ {
+ name = messageNameServer2Client(ptr->type, encBuf, sizeof(encBuf));
+ count = ptr->sentCount;
+ bytes = ptr->bytesSent;
+ savings = 0.0;
+ if (ptr->bytesSentIfRaw>0.0)
+ savings = 100.0 - (((double)ptr->bytesSent / (double)ptr->bytesSentIfRaw) * 100.0);
+ if ((bytes>0) || (count>0))
+ rfbLog(" %-24.24s: %6d events %9d/%9d bytes (%5.2f%% saved)\n",
+ name, count, bytes, ptr->bytesSentIfRaw, savings);
+ totalRectsSent += count;
+ totalBytesSent += bytes;
+ totalBytesIfRawSent += ptr->bytesSentIfRaw;
+ }
+ for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
+ {
+ name = encodingName(ptr->type, encBuf, sizeof(encBuf));
+ count = ptr->sentCount;
+ bytes = ptr->bytesSent;
+ savings = 0.0;
+ if (ptr->bytesSentIfRaw>0.0)
+ savings = 100.0 - (((double)ptr->bytesSent / (double)ptr->bytesSentIfRaw) * 100.0);
+ if ((bytes>0) || (count>0))
+ rfbLog(" %-24.24s: %6d events %9d/%9d bytes (%5.2f%% saved)\n",
+ name, count, bytes, ptr->bytesSentIfRaw, savings);
+ totalRectsSent += count;
+ totalBytesSent += bytes;
+ totalBytesIfRawSent += ptr->bytesSentIfRaw;
+ }
+ savings = 100.0 - ((totalBytesSent/totalBytesIfRawSent)*100.0);
+ rfbLog(" %-24.24s: %6d events %9.0f/%9.0f bytes (%5.2f%% savings)\n",
+ "TOTALS", totalRectsSent, totalBytesSent, totalBytesIfRawSent, savings);
+
+
+ rfbLog("Statistics: Receive\n");
+ for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
+ {
+ name = messageNameClient2Server(ptr->type, encBuf, sizeof(encBuf));
+ count = ptr->rcvdCount;
+ bytes = ptr->bytesRcvd;
+ savings = 0.0;
+ if (ptr->bytesSentIfRaw>0.0)
+ savings = 100.0 - (((double)ptr->bytesRcvd / (double)ptr->bytesRcvdIfRaw) * 100.0);
+ if ((bytes>0) || (count>0))
+ rfbLog(" %-24.24s: %6d events %9d/%9d bytes (%5.2f%% saved)\n",
+ name, count, bytes, ptr->bytesRcvdIfRaw, savings);
+ totalRectsRcvd += count;
+ totalBytesRcvd += bytes;
+ totalBytesIfRawRcvd += ptr->bytesRcvdIfRaw;
+ }
+ for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
+ {
+ name = encodingName(ptr->type, encBuf, sizeof(encBuf));
+ count = ptr->rcvdCount;
+ bytes = ptr->bytesRcvd;
+ savings = 0.0;
+ if (ptr->bytesSentIfRaw>0.0)
+ savings = 100.0 - (((double)ptr->bytesRcvd / (double)ptr->bytesRcvdIfRaw) * 100.0);
+ if ((bytes>0) || (count>0))
+ rfbLog(" %-24.24s: %6d events %9d/%9d bytes (%5.2f%% saved)\n",
+ name, count, bytes, ptr->bytesRcvdIfRaw, savings);
+ totalRectsRcvd += count;
+ totalBytesRcvd += bytes;
+ totalBytesIfRawRcvd += ptr->bytesRcvdIfRaw;
+ }
+ savings = 100.0 - ((totalBytesRcvd/totalBytesIfRawRcvd)*100.0);
+ rfbLog(" %-24.24s: %6d events %9.0f/%9.0f bytes (%5.2f%% savings)\n",
+ "TOTALS", totalRectsRcvd, totalBytesRcvd,totalBytesIfRawRcvd, savings);
+
+}
+