~ubuntu-branches/debian/lenny/italc/lenny

« back to all changes in this revision

Viewing changes to ica/x11/x11vnc/rates.c

  • Committer: Bazaar Package Importer
  • Author(s): Patrick Winnertz
  • Date: 2008-06-17 13:46:54 UTC
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20080617134654-2y5m7ki93r5c1ysf
Tags: upstream-1.0.9~rc3
ImportĀ upstreamĀ versionĀ 1.0.9~rc3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -- rates.c -- */
 
2
 
 
3
#include "x11vnc.h"
 
4
#include "xwrappers.h"
 
5
#include "scan.h"
 
6
 
 
7
int measure_speeds = 1;
 
8
int speeds_net_rate = 0;
 
9
int speeds_net_rate_measured = 0;
 
10
int speeds_net_latency = 0;
 
11
int speeds_net_latency_measured = 0;
 
12
int speeds_read_rate = 0;
 
13
int speeds_read_rate_measured = 0;
 
14
 
 
15
 
 
16
int get_cmp_rate(void);
 
17
int get_raw_rate(void);
 
18
void initialize_speeds(void);
 
19
int get_read_rate(void);
 
20
int link_rate(int *latency, int *netrate);
 
21
int get_net_rate(void);
 
22
int get_net_latency(void);
 
23
void measure_send_rates(int init);
 
24
 
 
25
 
 
26
static void measure_display_hook(rfbClientPtr cl);
 
27
static int get_rate(int which);
 
28
static int get_latency(void);
 
29
 
 
30
 
 
31
static void measure_display_hook(rfbClientPtr cl) {
 
32
        ClientData *cd = (ClientData *) cl->clientData;
 
33
        if (! cd) {
 
34
                return;
 
35
        }
 
36
        dtime0(&cd->timer);
 
37
}
 
38
 
 
39
static int get_rate(int which) {
 
40
        rfbClientIteratorPtr iter;
 
41
        rfbClientPtr cl;
 
42
        int irate, irate_min = 1;       /* 1 KB/sec */
 
43
        int irate_max = 100000;         /* 100 MB/sec */
 
44
        int count = 0;
 
45
        double slowest = -1.0, rate;
 
46
        static double save_rate = 1000 * NETRATE0;
 
47
 
 
48
        if (!screen) {
 
49
                return 0;
 
50
        }
 
51
 
 
52
        iter = rfbGetClientIterator(screen);
 
53
        while( (cl = rfbClientIteratorNext(iter)) ) {
 
54
                ClientData *cd = (ClientData *) cl->clientData;
 
55
 
 
56
                if (! cd) {
 
57
                        continue;
 
58
                }
 
59
                if (cl->state != RFB_NORMAL) {
 
60
                        continue;
 
61
                }
 
62
                if (cd->send_cmp_rate == 0.0 || cd->send_raw_rate == 0.0) {
 
63
                        continue;
 
64
                }
 
65
                count++;
 
66
                
 
67
                if (which == 0) {
 
68
                        rate = cd->send_cmp_rate;
 
69
                } else {
 
70
                        rate = cd->send_raw_rate;
 
71
                }
 
72
                if (slowest == -1.0 || rate < slowest) {
 
73
                        slowest = rate;
 
74
                }
 
75
                
 
76
        }
 
77
        rfbReleaseClientIterator(iter);
 
78
 
 
79
        if (! count) {
 
80
                return NETRATE0;
 
81
        }
 
82
 
 
83
        if (slowest == -1.0) {
 
84
                slowest = save_rate;
 
85
        } else {
 
86
                save_rate = slowest;
 
87
        }
 
88
 
 
89
        irate = (int) (slowest/1000.0);
 
90
        if (irate < irate_min) {
 
91
                irate = irate_min;
 
92
        }
 
93
        if (irate > irate_max) {
 
94
                irate = irate_max;
 
95
        }
 
96
if (0) fprintf(stderr, "get_rate(%d) %d %.3f/%.3f\n", which, irate, save_rate, slowest); 
 
97
 
 
98
        return irate;
 
99
}
 
100
 
 
101
static int get_latency(void) {
 
102
        rfbClientIteratorPtr iter;
 
103
        rfbClientPtr cl;
 
104
        int ilat, ilat_min = 1; /* 1 ms */
 
105
        int ilat_max = 2000;    /* 2 sec */
 
106
        double slowest = -1.0, lat;
 
107
        static double save_lat = ((double) LATENCY0)/1000.0;
 
108
        int count = 0;
 
109
        
 
110
        if (!screen) {
 
111
                return 0;
 
112
        }
 
113
 
 
114
        iter = rfbGetClientIterator(screen);
 
115
        while( (cl = rfbClientIteratorNext(iter)) ) {
 
116
                ClientData *cd = (ClientData *) cl->clientData;
 
117
                
 
118
                if (! cd) {
 
119
                        continue;
 
120
                }
 
121
                if (cl->state != RFB_NORMAL) {
 
122
                        continue;
 
123
                }
 
124
                if (cd->latency == 0.0) {
 
125
                        continue;
 
126
                }
 
127
                count++;
 
128
 
 
129
                lat = cd->latency;
 
130
                if (slowest == -1.0 || lat > slowest) {
 
131
                        slowest = lat;
 
132
                }
 
133
        }
 
134
        rfbReleaseClientIterator(iter);
 
135
 
 
136
        if (! count) {
 
137
                return LATENCY0;
 
138
        }
 
139
 
 
140
        if (slowest == -1.0) {
 
141
                slowest = save_lat;
 
142
        } else {
 
143
                save_lat = slowest;
 
144
        }
 
145
 
 
146
        ilat = (int) (slowest * 1000.0);
 
147
        if (ilat < ilat_min) {
 
148
                ilat = ilat_min;
 
149
        }
 
150
        if (ilat > ilat_max) {
 
151
                ilat = ilat_max;
 
152
        }
 
153
 
 
154
        return ilat;
 
155
}
 
156
 
 
157
int get_cmp_rate(void) {
 
158
        return get_rate(0);
 
159
}
 
160
 
 
161
int get_raw_rate(void) {
 
162
        return get_rate(1);
 
163
}
 
164
 
 
165
void initialize_speeds(void) {
 
166
        char *s, *s_in, *p;
 
167
        int i;
 
168
 
 
169
        speeds_read_rate = 0;
 
170
        speeds_net_rate = 0;
 
171
        speeds_net_latency = 0;
 
172
        if (! speeds_str || *speeds_str == '\0') {
 
173
                s_in = strdup("");
 
174
        } else {
 
175
                s_in = strdup(speeds_str);
 
176
        }
 
177
 
 
178
        if (!strcmp(s_in, "modem")) {
 
179
                s = strdup("6,4,200");
 
180
        } else if (!strcmp(s_in, "dsl")) {
 
181
                s = strdup("6,100,50");
 
182
        } else if (!strcmp(s_in, "lan")) {
 
183
                s = strdup("6,5000,1");
 
184
        } else {
 
185
                s = strdup(s_in);
 
186
        }
 
187
 
 
188
        p = strtok(s, ",");
 
189
        i = 0;
 
190
        while (p) {
 
191
                double val;
 
192
                if (*p != '\0') {
 
193
                        val = atof(p);
 
194
                        if (i==0) {
 
195
                                speeds_read_rate = (int) 1000000 * val;
 
196
                        } else if (i==1) {
 
197
                                speeds_net_rate = (int) 1000 * val;
 
198
                        } else if (i==2) {
 
199
                                speeds_net_latency = (int) val;
 
200
                        }
 
201
                }
 
202
                i++;
 
203
                p = strtok(NULL, ",");
 
204
        }
 
205
        free(s);
 
206
        free(s_in);
 
207
 
 
208
        if (! speeds_read_rate) {
 
209
                int n = 0;
 
210
                double dt, timer;
 
211
                dtime0(&timer);
 
212
                if (fullscreen) {
 
213
                        copy_image(fullscreen, 0, 0, 0, 0);
 
214
                        n = fullscreen->bytes_per_line * fullscreen->height;
 
215
                } else if (scanline) {
 
216
                        copy_image(scanline, 0, 0, 0, 0);
 
217
                        n = scanline->bytes_per_line * scanline->height;
 
218
                }
 
219
                dt = dtime(&timer);
 
220
                if (n && dt > 0.0) {
 
221
                        double rate = ((double) n) / dt;
 
222
                        speeds_read_rate_measured = (int) (rate/1000000.0);
 
223
                        if (speeds_read_rate_measured < 1) {
 
224
                                speeds_read_rate_measured = 1;
 
225
                        } else {
 
226
                                rfbLog("fb read rate: %d MB/sec\n",
 
227
                                    speeds_read_rate_measured);
 
228
                        }
 
229
                }
 
230
        }
 
231
}
 
232
 
 
233
int get_read_rate(void) {
 
234
        if (speeds_read_rate) {
 
235
                return speeds_read_rate;
 
236
        }
 
237
        if (speeds_read_rate_measured) {
 
238
                return speeds_read_rate_measured;
 
239
        }
 
240
        return 0;
 
241
}
 
242
 
 
243
int link_rate(int *latency, int *netrate) {
 
244
        *latency = get_net_latency();
 
245
        *netrate = get_net_rate();
 
246
 
 
247
        if (speeds_str) {
 
248
                if (!strcmp(speeds_str, "modem")) {
 
249
                        return LR_DIALUP;
 
250
                } else if (!strcmp(speeds_str, "dsl")) {
 
251
                        return LR_BROADBAND;
 
252
                } else if (!strcmp(speeds_str, "lan")) {
 
253
                        return LR_LAN;
 
254
                }
 
255
        }
 
256
 
 
257
        if (*latency == LATENCY0 && *netrate == NETRATE0)  {
 
258
                return LR_UNSET;
 
259
        } else if (*latency > 150 || *netrate < 20) {
 
260
                return LR_DIALUP;
 
261
        } else if (*latency > 50 || *netrate < 150) {
 
262
                return LR_BROADBAND;
 
263
        } else if (*latency < 10 && *netrate > 300) {
 
264
                return LR_LAN;
 
265
        } else {
 
266
                return LR_UNKNOWN;
 
267
        }
 
268
}
 
269
 
 
270
int get_net_rate(void) {
 
271
        int spm = speeds_net_rate_measured;
 
272
        if (speeds_net_rate) {
 
273
                return speeds_net_rate;
 
274
        }
 
275
        if (! spm || spm == NETRATE0) {
 
276
                speeds_net_rate_measured = get_cmp_rate();
 
277
        }
 
278
        if (speeds_net_rate_measured) {
 
279
                return speeds_net_rate_measured;
 
280
        }
 
281
        return 0;
 
282
}
 
283
 
 
284
int get_net_latency(void) {
 
285
        int spm = speeds_net_latency_measured;
 
286
        if (speeds_net_latency) {
 
287
                return speeds_net_latency;
 
288
        }
 
289
        if (! spm || spm == LATENCY0) {
 
290
                speeds_net_latency_measured = get_latency();
 
291
        }
 
292
        if (speeds_net_latency_measured) {
 
293
                return speeds_net_latency_measured;
 
294
        }
 
295
        return 0;
 
296
}
 
297
 
 
298
void measure_send_rates(int init) {
 
299
        double cmp_rate, raw_rate;
 
300
        static double now, start = 0.0;
 
301
        static rfbDisplayHookPtr orig_display_hook = NULL;
 
302
        double cmp_max = 1.0e+08;       /* 100 MB/sec */
 
303
        double cmp_min = 1000.0;        /* 9600baud */
 
304
        double lat_max = 5.0;           /* 5 sec */
 
305
        double lat_min = .0005;         /* 0.5 ms */
 
306
        int min_cmp = 10000, nclients;
 
307
        rfbClientIteratorPtr iter;
 
308
        rfbClientPtr cl0, cl;
 
309
        int msg = 0, clcnt0 = 0, cc;
 
310
        int db = 0, ouch_db = 0, ouch = 0;
 
311
 
 
312
        if (! measure_speeds) {
 
313
                return;
 
314
        }
 
315
        if (speeds_net_rate && speeds_net_latency) {
 
316
                return;
 
317
        }
 
318
        if (!client_count) {
 
319
                return;
 
320
        }
 
321
 
 
322
        if (! orig_display_hook) {
 
323
                orig_display_hook = screen->displayHook;
 
324
        }
 
325
 
 
326
        if (start == 0.0) {
 
327
                dtime(&start);
 
328
        }
 
329
 
 
330
        dtime0(&now);
 
331
        if (now < last_client_gone+4.0) {
 
332
                return;
 
333
        }
 
334
        now = now - start;
 
335
 
 
336
        nclients = 0;
 
337
 
 
338
        if (!screen) {
 
339
                return;
 
340
        }
 
341
 
 
342
        cl0 = NULL;
 
343
        iter = rfbGetClientIterator(screen);
 
344
        while( (cl = rfbClientIteratorNext(iter)) ) {
 
345
                ClientData *cd = (ClientData *) cl->clientData;
 
346
 
 
347
                if (! cd) {
 
348
                        continue;
 
349
                }
 
350
                if (cd->send_cmp_rate > 0.0) {
 
351
                        continue;
 
352
                }
 
353
                if (cl->onHold) {
 
354
                        continue;
 
355
                }
 
356
                nclients++;
 
357
                if (cl0 == NULL)  {
 
358
                        cl0 = cl;
 
359
                }
 
360
        }
 
361
        rfbReleaseClientIterator(iter);
 
362
 
 
363
        cl = cl0;
 
364
        cc = 0;
 
365
 
 
366
        while (cl != NULL && cc++ == 0) {
 
367
                int defer, i, cbs, rbs;
 
368
                char *httpdir;
 
369
                double dt, dt1 = 0.0, dt2, dt3;
 
370
                double tm, spin_max = 15.0, spin_lat_max = 1.5;
 
371
                int got_t2 = 0, got_t3 = 0;
 
372
                ClientData *cd = (ClientData *) cl->clientData;
 
373
 
 
374
#if 0
 
375
                for (i=0; i<MAX_ENCODINGS; i++) {
 
376
                        cbs += cl->bytesSent[i];
 
377
                }
 
378
                rbs = cl->rawBytesEquivalent;
 
379
#else
 
380
                cbs = rfbStatGetSentBytes(cl);
 
381
                rbs = rfbStatGetSentBytesIfRaw(cl);
 
382
#endif
 
383
 
 
384
                if (init) {
 
385
 
 
386
if (db) fprintf(stderr, "%d client num rects req: %d  mod: %d  cbs: %d  "
 
387
    "rbs: %d  dt1: %.3f  t: %.3f\n", init,
 
388
    (int) sraRgnCountRects(cl->requestedRegion),
 
389
    (int) sraRgnCountRects(cl->modifiedRegion), cbs, rbs, dt1, now);
 
390
 
 
391
                        cd->timer = dnow();
 
392
                        cd->cmp_bytes_sent = cbs;
 
393
                        cd->raw_bytes_sent = rbs;
 
394
                        continue;
 
395
                }
 
396
 
 
397
                /* first part of the bulk transfer of initial screen */
 
398
                dt1 = dtime(&cd->timer);
 
399
 
 
400
if (db) fprintf(stderr, "%d client num rects req: %d  mod: %d  cbs: %d  "
 
401
    "rbs: %d  dt1: %.3f  t: %.3f\n", init,
 
402
    (int) sraRgnCountRects(cl->requestedRegion),
 
403
    (int) sraRgnCountRects(cl->modifiedRegion), cbs, rbs, dt1, now);
 
404
 
 
405
                if (dt1 <= 0.0) {
 
406
                        continue;
 
407
                }
 
408
 
 
409
                cbs = cbs - cd->cmp_bytes_sent;
 
410
                rbs = rbs - cd->raw_bytes_sent;
 
411
 
 
412
                if (cbs < min_cmp) {
 
413
                        continue;
 
414
                }
 
415
 
 
416
                if (ouch_db) fprintf(stderr, "START-OUCH: %d\n", client_count);
 
417
                clcnt0 = client_count;
 
418
#define OUCH ( ouch || (ouch = (!client_count || client_count != clcnt0 || dnow() < last_client_gone+4.0)) )
 
419
 
 
420
                rfbPE(1000);
 
421
                if (OUCH && ouch_db) fprintf(stderr, "***OUCH-A\n");
 
422
                if (OUCH) continue;
 
423
 
 
424
                if (sraRgnCountRects(cl->modifiedRegion)) {
 
425
                        rfbPE(1000);
 
426
                        if (OUCH && ouch_db) fprintf(stderr, "***OUCH-B\n");
 
427
                        if (OUCH) continue;
 
428
                }
 
429
 
 
430
                defer = screen->deferUpdateTime;
 
431
                httpdir = screen->httpDir;
 
432
                screen->deferUpdateTime = 0;
 
433
                screen->httpDir = NULL;
 
434
 
 
435
                /* mark a small rectangle: */
 
436
                mark_rect_as_modified(0, 0, 16, 16, 1);
 
437
 
 
438
                dtime0(&tm);
 
439
 
 
440
                dt2 = 0.0;
 
441
                dt3 = 0.0;
 
442
 
 
443
                if (dt1 < 0.25) {
 
444
                        /* try to cut it down to avoid long pauses. */
 
445
                        spin_max = 5.0;
 
446
                }
 
447
 
 
448
                /* when req1 = 1 mod1 == 0, end of 2nd part of bulk transfer */
 
449
                while (1) {
 
450
                        int req0, req1, mod0, mod1;
 
451
 
 
452
                        if (OUCH && ouch_db) fprintf(stderr, "***OUCH-C1\n");
 
453
                        if (OUCH) break;
 
454
 
 
455
                        req0 = sraRgnCountRects(cl->requestedRegion);
 
456
                        mod0 = sraRgnCountRects(cl->modifiedRegion);
 
457
                        if (use_threads) {
 
458
                                usleep(1000);
 
459
                        } else {
 
460
                                if (mod0) {
 
461
                                        rfbPE(1000);
 
462
                                } else {
 
463
                                        rfbCFD(1000);
 
464
                                }
 
465
                        }
 
466
                        dt = dtime(&tm);
 
467
                        dt2 += dt;
 
468
                        if (dt2 > spin_max) {
 
469
                                break;
 
470
                        }
 
471
 
 
472
                        if (OUCH && ouch_db) fprintf(stderr, "***OUCH-C2\n");
 
473
                        if (OUCH) break;
 
474
 
 
475
                        req1 = sraRgnCountRects(cl->requestedRegion);
 
476
                        mod1 = sraRgnCountRects(cl->modifiedRegion);
 
477
 
 
478
if (db) fprintf(stderr, "dt2 calc: num rects req: %d/%d mod: %d/%d  "
 
479
    "fbu-sent: %d  dt: %.4f dt2: %.4f  tm: %.4f\n",
 
480
    req0, req1, mod0, mod1,
 
481
#if 0
 
482
    cl->framebufferUpdateMessagesSent,
 
483
#else
 
484
    rfbStatGetMessageCountSent(cl, rfbFramebufferUpdate),
 
485
#endif
 
486
    dt, dt2, tm);
 
487
                        if (req1 != 0 && mod1 == 0) {
 
488
                                got_t2 = 1;
 
489
                                break;
 
490
                        }
 
491
                }
 
492
                if (OUCH && ouch_db) fprintf(stderr, "***OUCH-D\n");
 
493
                if (OUCH) goto ouch;
 
494
 
 
495
                if (! got_t2) {
 
496
                        dt2 = 0.0;
 
497
                } else {
 
498
                        int tr, trm = 3;
 
499
                        double dts[10];
 
500
                        
 
501
                        /*
 
502
                         * Note: since often select(2) cannot sleep
 
503
                         * less than 1/HZ (e.g. 10ms), the resolution
 
504
                         * of the latency may be messed up by something
 
505
                         * of this order.  Effect may occur on both ends,
 
506
                         * i.e. the viewer may not respond immediately.
 
507
                         */
 
508
                
 
509
                        for (tr = 0; tr < trm; tr++) {
 
510
                                usleep(5000);
 
511
 
 
512
                                /* mark a 2nd small rectangle: */
 
513
                                mark_rect_as_modified(0, 0, 16, 16, 1);
 
514
                                i = 0;
 
515
                                dtime0(&tm);
 
516
                                dt3 = 0.0;
 
517
 
 
518
                                /*
 
519
                                 * when req1 > 0 and mod1 == 0, we say
 
520
                                 * that is the "ping" time.
 
521
                                 */
 
522
                                while (1) {
 
523
                                        int req0, req1, mod0, mod1;
 
524
 
 
525
                                        req0 = sraRgnCountRects(
 
526
                                            cl->requestedRegion);
 
527
                                        mod0 = sraRgnCountRects(
 
528
                                            cl->modifiedRegion);
 
529
 
 
530
                                        if (i == 0) {
 
531
                                                rfbPE(0);
 
532
                                        } else {
 
533
                                                if (use_threads) {
 
534
                                                        usleep(1000);
 
535
                                                } else {
 
536
                                                        /* try to get it all */
 
537
                                                        rfbCFD(1000*1000);
 
538
                                                }
 
539
                                        }
 
540
                                        if (OUCH && ouch_db) fprintf(stderr, "***OUCH-E\n");
 
541
                                        if (OUCH) goto ouch;
 
542
                                        dt = dtime(&tm);
 
543
                                        i++;
 
544
 
 
545
                                        dt3 += dt;
 
546
                                        if (dt3 > spin_lat_max) {
 
547
                                                break;
 
548
                                        }
 
549
                                        req1 = sraRgnCountRects(
 
550
                                            cl->requestedRegion);
 
551
 
 
552
                                        mod1 = sraRgnCountRects(
 
553
                                            cl->modifiedRegion);
 
554
 
 
555
if (db) fprintf(stderr, "dt3 calc: num rects req: %d/%d mod: %d/%d  "
 
556
    "fbu-sent: %d  dt: %.4f dt3: %.4f  tm: %.4f\n",
 
557
    req0, req1, mod0, mod1,
 
558
#if 0
 
559
    cl->framebufferUpdateMessagesSent,
 
560
#else
 
561
    rfbStatGetMessageCountSent(cl, rfbFramebufferUpdate),
 
562
#endif
 
563
    dt, dt3, tm);
 
564
 
 
565
                                        if (req1 != 0 && mod1 == 0) {
 
566
                                                dts[got_t3++] = dt3;
 
567
                                                break;
 
568
                                        }
 
569
                                }
 
570
                        }
 
571
                
 
572
                        if (! got_t3) {
 
573
                                dt3 = 0.0;
 
574
                        } else {
 
575
                                if (got_t3 == 1) {
 
576
                                        dt3 = dts[0];
 
577
                                } else if (got_t3 == 2) {
 
578
                                        dt3 = dts[1];
 
579
                                } else {
 
580
                                        if (dts[2] > 0.0) {
 
581
                                                double rat = dts[1]/dts[2];
 
582
                                                if (rat > 0.5 && rat < 2.0) {
 
583
                                                        dt3 = dts[1]+dts[2];
 
584
                                                        dt3 *= 0.5;
 
585
                                                } else {
 
586
                                                        dt3 = dts[1];
 
587
                                                }
 
588
                                        } else {
 
589
                                                dt3 = dts[1];
 
590
                                        }
 
591
                                }
 
592
                        }
 
593
                }
 
594
 
 
595
                ouch:
 
596
                
 
597
                screen->deferUpdateTime = defer;
 
598
                screen->httpDir = httpdir;
 
599
 
 
600
                if (OUCH && ouch_db) fprintf(stderr, "***OUCH-F\n");
 
601
                if (OUCH) break;
 
602
 
 
603
                dt = dt1 + dt2;
 
604
 
 
605
 
 
606
                if (dt3 <= dt2/2.0) {
 
607
                        /* guess only 1/2 a ping for reply... */
 
608
                        dt = dt - dt3/2.0;
 
609
                }
 
610
 
 
611
                cmp_rate = cbs/dt;
 
612
                raw_rate = rbs/dt;
 
613
 
 
614
                if (cmp_rate > cmp_max) {
 
615
                        cmp_rate = cmp_max;
 
616
                }
 
617
                if (cmp_rate <= cmp_min) {
 
618
                        cmp_rate = cmp_min;
 
619
                }
 
620
 
 
621
                cd->send_cmp_rate = cmp_rate;
 
622
                cd->send_raw_rate = raw_rate;
 
623
 
 
624
                if (dt3 > lat_max) {
 
625
                        dt3 = lat_max;
 
626
                }
 
627
                if (dt3 <= lat_min) {
 
628
                        dt3 = lat_min;
 
629
                }
 
630
 
 
631
                cd->latency = dt3;
 
632
                
 
633
                rfbLog("client %d network rate %.1f KB/sec (%.1f eff KB/sec)\n",
 
634
                    cd->uid, cmp_rate/1000.0, raw_rate/1000.0);
 
635
                rfbLog("client %d latency:  %.1f ms\n", cd->uid, 1000.0*dt3);
 
636
                rfbLog("dt1: %.4f, dt2: %.4f dt3: %.4f bytes: %d\n",
 
637
                    dt1, dt2, dt3, cbs);
 
638
                msg = 1;
 
639
        }
 
640
 
 
641
        if (msg) {
 
642
                int link, latency, netrate;
 
643
                char *str = "error";
 
644
 
 
645
                link = link_rate(&latency, &netrate);
 
646
                if (link == LR_UNSET) {
 
647
                        str = "LR_UNSET";
 
648
                } else if (link == LR_UNKNOWN) {
 
649
                        str = "LR_UNKNOWN";
 
650
                } else if (link == LR_DIALUP) {
 
651
                        str = "LR_DIALUP";
 
652
                } else if (link == LR_BROADBAND) {
 
653
                        str = "LR_BROADBAND";
 
654
                } else if (link == LR_LAN) {
 
655
                        str = "LR_LAN";
 
656
                }
 
657
                rfbLog("link_rate: %s - %d ms, %d KB/s\n", str, latency,
 
658
                    netrate);
 
659
        }
 
660
 
 
661
        if (init) {
 
662
                if (nclients) {
 
663
                        screen->displayHook = measure_display_hook;
 
664
                }
 
665
        } else {
 
666
                screen->displayHook = orig_display_hook;
 
667
        }
 
668
}
 
669