6
* Copyright (C) 2002 RealVNC Ltd.
7
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
8
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
11
* This is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
16
* This software is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with this software; if not, write to the Free Software
23
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
29
char *messageNameServer2Client(uint32_t type, char *buf, int len);
30
char *messageNameClient2Server(uint32_t type, char *buf, int len);
31
char *encodingName(uint32_t enc, char *buf, int len);
33
rfbStatList *rfbStatLookupEncoding(rfbClientPtr cl, uint32_t type);
34
rfbStatList *rfbStatLookupMessage(rfbClientPtr cl, uint32_t type);
36
void rfbStatRecordEncodingSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
37
void rfbStatRecordEncodingRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
38
void rfbStatRecordMessageSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
39
void rfbStatRecordMessageRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
40
void rfbResetStats(rfbClientPtr cl);
41
void rfbPrintStats(rfbClientPtr cl);
46
char *messageNameServer2Client(uint32_t type, char *buf, int len) {
47
if (buf==NULL) return "error";
49
case rfbFramebufferUpdate: snprintf(buf, len, "FramebufferUpdate"); break;
50
case rfbSetColourMapEntries: snprintf(buf, len, "SetColourMapEntries"); break;
51
case rfbBell: snprintf(buf, len, "Bell"); break;
52
case rfbServerCutText: snprintf(buf, len, "ServerCutText"); break;
53
case rfbResizeFrameBuffer: snprintf(buf, len, "ResizeFrameBuffer"); break;
54
case rfbKeyFrameUpdate: snprintf(buf, len, "KeyFrameUpdate"); break;
55
case rfbFileTransfer: snprintf(buf, len, "FileTransfer"); break;
56
case rfbTextChat: snprintf(buf, len, "TextChat"); break;
57
case rfbPalmVNCReSizeFrameBuffer: snprintf(buf, len, "PalmVNCReSize"); break;
59
snprintf(buf, len, "svr2cli-0x%08X", 0xFF);
64
char *messageNameClient2Server(uint32_t type, char *buf, int len) {
65
if (buf==NULL) return "error";
67
case rfbSetPixelFormat: snprintf(buf, len, "SetPixelFormat"); break;
68
case rfbFixColourMapEntries: snprintf(buf, len, "FixColourMapEntries"); break;
69
case rfbSetEncodings: snprintf(buf, len, "SetEncodings"); break;
70
case rfbFramebufferUpdateRequest: snprintf(buf, len, "FramebufferUpdate"); break;
71
case rfbKeyEvent: snprintf(buf, len, "KeyEvent"); break;
72
case rfbPointerEvent: snprintf(buf, len, "PointerEvent"); break;
73
case rfbClientCutText: snprintf(buf, len, "ClientCutText"); break;
74
case rfbFileTransfer: snprintf(buf, len, "FileTransfer"); break;
75
case rfbSetScale: snprintf(buf, len, "SetScale"); break;
76
case rfbSetServerInput: snprintf(buf, len, "SetServerInput"); break;
77
case rfbSetSW: snprintf(buf, len, "SetSingleWindow"); break;
78
case rfbTextChat: snprintf(buf, len, "TextChat"); break;
79
case rfbKeyFrameRequest: snprintf(buf, len, "KeyFrameRequest"); break;
80
case rfbPalmVNCSetScaleFactor: snprintf(buf, len, "PalmVNCSetScale"); break;
82
snprintf(buf, len, "cli2svr-0x%08X", type);
89
/* Encoding name must be <=16 characters to fit nicely on the status output in
90
* an 80 column terminal window
92
char *encodingName(uint32_t type, char *buf, int len) {
93
if (buf==NULL) return "error";
96
case rfbEncodingRaw: snprintf(buf, len, "raw"); break;
97
case rfbEncodingCopyRect: snprintf(buf, len, "copyRect"); break;
98
case rfbEncodingRRE: snprintf(buf, len, "RRE"); break;
99
case rfbEncodingCoRRE: snprintf(buf, len, "CoRRE"); break;
100
case rfbEncodingHextile: snprintf(buf, len, "hextile"); break;
101
case rfbEncodingZlib: snprintf(buf, len, "zlib"); break;
102
case rfbEncodingTight: snprintf(buf, len, "tight"); break;
103
case rfbEncodingZlibHex: snprintf(buf, len, "zlibhex"); break;
104
case rfbEncodingUltra: snprintf(buf, len, "ultra"); break;
105
case rfbEncodingZRLE: snprintf(buf, len, "ZRLE"); break;
106
case rfbEncodingCache: snprintf(buf, len, "cache"); break;
107
case rfbEncodingCacheEnable: snprintf(buf, len, "cacheEnable"); break;
108
case rfbEncodingXOR_Zlib: snprintf(buf, len, "xorZlib"); break;
109
case rfbEncodingXORMonoColor_Zlib: snprintf(buf, len, "xorMonoZlib"); break;
110
case rfbEncodingXORMultiColor_Zlib: snprintf(buf, len, "xorColorZlib"); break;
111
case rfbEncodingSolidColor: snprintf(buf, len, "solidColor"); break;
112
case rfbEncodingXOREnable: snprintf(buf, len, "xorEnable"); break;
113
case rfbEncodingCacheZip: snprintf(buf, len, "cacheZip"); break;
114
case rfbEncodingSolMonoZip: snprintf(buf, len, "monoZip"); break;
115
case rfbEncodingUltraZip: snprintf(buf, len, "ultraZip"); break;
117
case rfbEncodingXCursor: snprintf(buf, len, "Xcursor"); break;
118
case rfbEncodingRichCursor: snprintf(buf, len, "RichCursor"); break;
119
case rfbEncodingPointerPos: snprintf(buf, len, "PointerPos"); break;
121
case rfbEncodingLastRect: snprintf(buf, len, "LastRect"); break;
122
case rfbEncodingNewFBSize: snprintf(buf, len, "NewFBSize"); break;
123
case rfbEncodingKeyboardLedState: snprintf(buf, len, "LedState"); break;
124
case rfbEncodingSupportedMessages: snprintf(buf, len, "SupportedMessage"); break;
125
case rfbEncodingSupportedEncodings: snprintf(buf, len, "SupportedEncoding"); break;
126
case rfbEncodingServerIdentity: snprintf(buf, len, "ServerIdentify"); break;
128
/* The following lookups do not report in stats */
129
case rfbEncodingCompressLevel0: snprintf(buf, len, "CompressLevel0"); break;
130
case rfbEncodingCompressLevel1: snprintf(buf, len, "CompressLevel1"); break;
131
case rfbEncodingCompressLevel2: snprintf(buf, len, "CompressLevel2"); break;
132
case rfbEncodingCompressLevel3: snprintf(buf, len, "CompressLevel3"); break;
133
case rfbEncodingCompressLevel4: snprintf(buf, len, "CompressLevel4"); break;
134
case rfbEncodingCompressLevel5: snprintf(buf, len, "CompressLevel5"); break;
135
case rfbEncodingCompressLevel6: snprintf(buf, len, "CompressLevel6"); break;
136
case rfbEncodingCompressLevel7: snprintf(buf, len, "CompressLevel7"); break;
137
case rfbEncodingCompressLevel8: snprintf(buf, len, "CompressLevel8"); break;
138
case rfbEncodingCompressLevel9: snprintf(buf, len, "CompressLevel9"); break;
140
case rfbEncodingQualityLevel0: snprintf(buf, len, "QualityLevel0"); break;
141
case rfbEncodingQualityLevel1: snprintf(buf, len, "QualityLevel1"); break;
142
case rfbEncodingQualityLevel2: snprintf(buf, len, "QualityLevel2"); break;
143
case rfbEncodingQualityLevel3: snprintf(buf, len, "QualityLevel3"); break;
144
case rfbEncodingQualityLevel4: snprintf(buf, len, "QualityLevel4"); break;
145
case rfbEncodingQualityLevel5: snprintf(buf, len, "QualityLevel5"); break;
146
case rfbEncodingQualityLevel6: snprintf(buf, len, "QualityLevel6"); break;
147
case rfbEncodingQualityLevel7: snprintf(buf, len, "QualityLevel7"); break;
148
case rfbEncodingQualityLevel8: snprintf(buf, len, "QualityLevel8"); break;
149
case rfbEncodingQualityLevel9: snprintf(buf, len, "QualityLevel9"); break;
153
snprintf(buf, len, "Enc(0x%08X)", type);
163
rfbStatList *rfbStatLookupEncoding(rfbClientPtr cl, uint32_t type)
166
if (cl==NULL) return NULL;
167
for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
169
if (ptr->type==type) return ptr;
171
/* Well, we are here... need to *CREATE* an entry */
172
ptr = (rfbStatList *)malloc(sizeof(rfbStatList));
175
memset((char *)ptr, 0, sizeof(rfbStatList));
177
/* add to the top of the list */
178
ptr->Next = cl->statEncList;
179
cl->statEncList = ptr;
185
rfbStatList *rfbStatLookupMessage(rfbClientPtr cl, uint32_t type)
188
if (cl==NULL) return NULL;
189
for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
191
if (ptr->type==type) return ptr;
193
/* Well, we are here... need to *CREATE* an entry */
194
ptr = (rfbStatList *)malloc(sizeof(rfbStatList));
197
memset((char *)ptr, 0, sizeof(rfbStatList));
199
/* add to the top of the list */
200
ptr->Next = cl->statMsgList;
201
cl->statMsgList = ptr;
206
void rfbStatRecordEncodingSentAdd(rfbClientPtr cl, uint32_t type, int byteCount) /* Specifically for tight encoding */
210
ptr = rfbStatLookupEncoding(cl, type);
212
ptr->bytesSent += byteCount;
216
void rfbStatRecordEncodingSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw)
220
ptr = rfbStatLookupEncoding(cl, type);
224
ptr->bytesSent += byteCount;
225
ptr->bytesSentIfRaw += byteIfRaw;
229
void rfbStatRecordEncodingRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw)
233
ptr = rfbStatLookupEncoding(cl, type);
237
ptr->bytesRcvd += byteCount;
238
ptr->bytesRcvdIfRaw += byteIfRaw;
242
void rfbStatRecordMessageSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw)
246
ptr = rfbStatLookupMessage(cl, type);
250
ptr->bytesSent += byteCount;
251
ptr->bytesSentIfRaw += byteIfRaw;
255
void rfbStatRecordMessageRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw)
259
ptr = rfbStatLookupMessage(cl, type);
263
ptr->bytesRcvd += byteCount;
264
ptr->bytesRcvdIfRaw += byteIfRaw;
269
int rfbStatGetSentBytes(rfbClientPtr cl)
271
rfbStatList *ptr=NULL;
273
if (cl==NULL) return 0;
274
for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
275
bytes += ptr->bytesSent;
276
for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
277
bytes += ptr->bytesSent;
281
int rfbStatGetSentBytesIfRaw(rfbClientPtr cl)
283
rfbStatList *ptr=NULL;
285
if (cl==NULL) return 0;
286
for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
287
bytes += ptr->bytesSentIfRaw;
288
for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
289
bytes += ptr->bytesSentIfRaw;
293
int rfbStatGetRcvdBytes(rfbClientPtr cl)
295
rfbStatList *ptr=NULL;
297
if (cl==NULL) return 0;
298
for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
299
bytes += ptr->bytesRcvd;
300
for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
301
bytes += ptr->bytesRcvd;
305
int rfbStatGetRcvdBytesIfRaw(rfbClientPtr cl)
307
rfbStatList *ptr=NULL;
309
if (cl==NULL) return 0;
310
for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
311
bytes += ptr->bytesRcvdIfRaw;
312
for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
313
bytes += ptr->bytesRcvdIfRaw;
317
int rfbStatGetMessageCountSent(rfbClientPtr cl, uint32_t type)
319
rfbStatList *ptr=NULL;
320
if (cl==NULL) return 0;
321
for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
322
if (ptr->type==type) return ptr->sentCount;
325
int rfbStatGetMessageCountRcvd(rfbClientPtr cl, uint32_t type)
327
rfbStatList *ptr=NULL;
328
if (cl==NULL) return 0;
329
for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
330
if (ptr->type==type) return ptr->rcvdCount;
334
int rfbStatGetEncodingCountSent(rfbClientPtr cl, uint32_t type)
336
rfbStatList *ptr=NULL;
337
if (cl==NULL) return 0;
338
for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
339
if (ptr->type==type) return ptr->sentCount;
342
int rfbStatGetEncodingCountRcvd(rfbClientPtr cl, uint32_t type)
344
rfbStatList *ptr=NULL;
345
if (cl==NULL) return 0;
346
for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
347
if (ptr->type==type) return ptr->rcvdCount;
354
void rfbResetStats(rfbClientPtr cl)
357
if (cl==NULL) return;
358
while (cl->statEncList!=NULL)
360
ptr = cl->statEncList;
361
cl->statEncList = ptr->Next;
364
while (cl->statMsgList!=NULL)
366
ptr = cl->statMsgList;
367
cl->statMsgList = ptr->Next;
373
void rfbPrintStats(rfbClientPtr cl)
375
rfbStatList *ptr=NULL;
379
double totalBytes=0.0;
380
double totalBytesIfRaw=0.0;
387
if (cl==NULL) return;
389
rfbLog("%-21.21s %-6.6s %9.9s/%9.9s (%6.6s)\n", "Statistics", "events", "Transmit","RawEquiv","saved");
390
for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
392
name = messageNameServer2Client(ptr->type, encBuf, sizeof(encBuf));
393
count = ptr->sentCount;
394
bytes = ptr->bytesSent;
395
bytesIfRaw = ptr->bytesSentIfRaw;
399
savings = 100.0 - (((double)bytes / (double)bytesIfRaw) * 100.0);
400
if ((bytes>0) || (count>0) || (bytesIfRaw>0))
401
rfbLog(" %-20.20s: %6d | %9d/%9d (%5.1f%%)\n",
402
name, count, bytes, bytesIfRaw, savings);
405
totalBytesIfRaw += bytesIfRaw;
408
for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
410
name = encodingName(ptr->type, encBuf, sizeof(encBuf));
411
count = ptr->sentCount;
412
bytes = ptr->bytesSent;
413
bytesIfRaw = ptr->bytesSentIfRaw;
417
savings = 100.0 - (((double)bytes / (double)bytesIfRaw) * 100.0);
418
if ((bytes>0) || (count>0) || (bytesIfRaw>0))
419
rfbLog(" %-20.20s: %6d | %9d/%9d (%5.1f%%)\n",
420
name, count, bytes, bytesIfRaw, savings);
423
totalBytesIfRaw += bytesIfRaw;
426
if (totalBytesIfRaw>0.0)
427
savings = 100.0 - ((totalBytes/totalBytesIfRaw)*100.0);
428
rfbLog(" %-20.20s: %6d | %9.0f/%9.0f (%5.1f%%)\n",
429
"TOTALS", totalRects, totalBytes,totalBytesIfRaw, savings);
435
rfbLog("%-21.21s %-6.6s %9.9s/%9.9s (%6.6s)\n", "Statistics", "events", "Received","RawEquiv","saved");
436
for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
438
name = messageNameClient2Server(ptr->type, encBuf, sizeof(encBuf));
439
count = ptr->rcvdCount;
440
bytes = ptr->bytesRcvd;
441
bytesIfRaw = ptr->bytesRcvdIfRaw;
445
savings = 100.0 - (((double)bytes / (double)bytesIfRaw) * 100.0);
446
if ((bytes>0) || (count>0) || (bytesIfRaw>0))
447
rfbLog(" %-20.20s: %6d | %9d/%9d (%5.1f%%)\n",
448
name, count, bytes, bytesIfRaw, savings);
451
totalBytesIfRaw += bytesIfRaw;
453
for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
455
name = encodingName(ptr->type, encBuf, sizeof(encBuf));
456
count = ptr->rcvdCount;
457
bytes = ptr->bytesRcvd;
458
bytesIfRaw = ptr->bytesRcvdIfRaw;
462
savings = 100.0 - (((double)bytes / (double)bytesIfRaw) * 100.0);
463
if ((bytes>0) || (count>0) || (bytesIfRaw>0))
464
rfbLog(" %-20.20s: %6d | %9d/%9d (%5.1f%%)\n",
465
name, count, bytes, bytesIfRaw, savings);
468
totalBytesIfRaw += bytesIfRaw;
471
if (totalBytesIfRaw>0.0)
472
savings = 100.0 - ((totalBytes/totalBytesIfRaw)*100.0);
473
rfbLog(" %-20.20s: %6d | %9.0f/%9.0f (%5.1f%%)\n",
474
"TOTALS", totalRects, totalBytes,totalBytesIfRaw, savings);