Revision 41b4bef6

b/vnc.c
356 356
        *ret_data = qobject_from_jsonf("{ 'enabled': false }");
357 357
    } else {
358 358
        QList *clist;
359
        VncState *client;
359 360

  
360 361
        clist = qlist_new();
361
        if (vnc_display->clients) {
362
            VncState *client = vnc_display->clients;
363
            while (client) {
364
                if (client->info) {
365
                    /* incref so that it's not freed by upper layers */
366
                    qobject_incref(client->info);
367
                    qlist_append_obj(clist, client->info);
368
                }
369
                client = client->next;
362
        QTAILQ_FOREACH(client, &vnc_display->clients, next) {
363
            if (client->info) {
364
                /* incref so that it's not freed by upper layers */
365
                qobject_incref(client->info);
366
                qlist_append_obj(clist, client->info);
370 367
            }
371 368
        }
372 369

  
......
519 516
{
520 517
    int size_changed;
521 518
    VncDisplay *vd = ds->opaque;
522
    VncState *vs = vd->clients;
519
    VncState *vs;
523 520

  
524 521
    /* server surface */
525 522
    if (!vd->server)
......
540 537
    *(vd->guest.ds) = *(ds->surface);
541 538
    memset(vd->guest.dirty, 0xFF, sizeof(vd->guest.dirty));
542 539

  
543
    while (vs != NULL) {
540
    QTAILQ_FOREACH(vs, &vd->clients, next) {
544 541
        vnc_colordepth(vs);
545 542
        if (size_changed) {
546 543
            if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
......
553 550
            }
554 551
        }
555 552
        memset(vs->dirty, 0xFF, sizeof(vs->dirty));
556
        vs = vs->next;
557 553
    }
558 554
}
559 555

  
......
867 863
    int cmp_bytes;
868 864

  
869 865
    vnc_refresh_server_surface(vd);
870
    for (vs = vd->clients; vs != NULL; vs = vn) {
871
        vn = vs->next;
866
    QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
872 867
        if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
873 868
            vs->force_update = 1;
874 869
            vnc_update_client(vs, 1);
......
912 907
            if (memcmp(src_row, dst_row, cmp_bytes) == 0)
913 908
                continue;
914 909
            memmove(dst_row, src_row, cmp_bytes);
915
            vs = vd->clients;
916
            while (vs != NULL) {
917
                if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT))
910
            QTAILQ_FOREACH(vs, &vd->clients, next) {
911
                if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
918 912
                    vnc_set_bit(vs->dirty[y], ((x + dst_x) / 16));
919
                vs = vs->next;
913
                }
920 914
            }
921 915
        }
922 916
        src_row += pitch - w * depth;
......
924 918
        y += inc;
925 919
    }
926 920

  
927
    for (vs = vd->clients; vs != NULL; vs = vs->next) {
928
        if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT))
921
    QTAILQ_FOREACH(vs, &vd->clients, next) {
922
        if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
929 923
            vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
924
        }
930 925
    }
931 926
}
932 927

  
......
1109 1104
#endif /* CONFIG_VNC_SASL */
1110 1105
    audio_del(vs);
1111 1106

  
1112
    VncState *p, *parent = NULL;
1113
    for (p = vs->vd->clients; p != NULL; p = p->next) {
1114
        if (p == vs) {
1115
            if (parent)
1116
                parent->next = p->next;
1117
            else
1118
                vs->vd->clients = p->next;
1119
            break;
1120
        }
1121
        parent = p;
1122
    }
1123
    if (!vs->vd->clients)
1107
    QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1108

  
1109
    if (QTAILQ_EMPTY(&vs->vd->clients)) {
1124 1110
        dcl->idle = 1;
1111
    }
1125 1112

  
1126 1113
    vnc_remove_timer(vs->vd);
1127 1114
    qemu_free(vs);
......
2299 2286
    uint8_t *server_row;
2300 2287
    int cmp_bytes;
2301 2288
    uint32_t width_mask[VNC_DIRTY_WORDS];
2302
    VncState *vs = NULL;
2289
    VncState *vs;
2303 2290
    int has_dirty = 0;
2304 2291

  
2305 2292
    /*
......
2328 2315
                if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0)
2329 2316
                    continue;
2330 2317
                memcpy(server_ptr, guest_ptr, cmp_bytes);
2331
                vs = vd->clients;
2332
                while (vs != NULL) {
2318
                QTAILQ_FOREACH(vs, &vd->clients, next) {
2333 2319
                    vnc_set_bit(vs->dirty[y], (x / 16));
2334
                    vs = vs->next;
2335 2320
                }
2336 2321
                has_dirty++;
2337 2322
            }
......
2345 2330
static void vnc_refresh(void *opaque)
2346 2331
{
2347 2332
    VncDisplay *vd = opaque;
2348
    VncState *vs = NULL, *vn = NULL;
2349
    int has_dirty = 0, rects = 0;
2333
    VncState *vs, *vn;
2334
    int has_dirty, rects = 0;
2350 2335

  
2351 2336
    vga_hw_update();
2352 2337

  
2353 2338
    has_dirty = vnc_refresh_server_surface(vd);
2354 2339

  
2355
    vs = vd->clients;
2356
    while (vs != NULL) {
2357
        vn = vs->next;
2340
    QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2358 2341
        rects += vnc_update_client(vs, has_dirty);
2359 2342
        /* vs might be free()ed here */
2360
        vs = vn;
2361 2343
    }
2362 2344
    /* vd->timer could be NULL now if the last client disconnected,
2363 2345
     * in this case don't update the timer */
......
2379 2361
static void vnc_init_timer(VncDisplay *vd)
2380 2362
{
2381 2363
    vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
2382
    if (vd->timer == NULL && vd->clients != NULL) {
2364
    if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {
2383 2365
        vd->timer = qemu_new_timer(rt_clock, vnc_refresh, vd);
2384 2366
        vnc_refresh(vd);
2385 2367
    }
......
2387 2369

  
2388 2370
static void vnc_remove_timer(VncDisplay *vd)
2389 2371
{
2390
    if (vd->timer != NULL && vd->clients == NULL) {
2372
    if (vd->timer != NULL && QTAILQ_EMPTY(&vd->clients)) {
2391 2373
        qemu_del_timer(vd->timer);
2392 2374
        qemu_free_timer(vd->timer);
2393 2375
        vd->timer = NULL;
......
2417 2399
    vs->as.fmt = AUD_FMT_S16;
2418 2400
    vs->as.endianness = 0;
2419 2401

  
2420
    vs->next = vd->clients;
2421
    vd->clients = vs;
2402
    QTAILQ_INSERT_HEAD(&vd->clients, vs, next);
2422 2403

  
2423 2404
    vga_hw_update();
2424 2405

  
......
2460 2441
    vs->lsock = -1;
2461 2442

  
2462 2443
    vs->ds = ds;
2444
    QTAILQ_INIT(&vs->clients);
2463 2445

  
2464 2446
    if (keyboard_layout)
2465 2447
        vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
b/vnc.h
28 28
#define __QEMU_VNC_H
29 29

  
30 30
#include "qemu-common.h"
31
#include "qemu-queue.h"
31 32
#include "console.h"
32 33
#include "monitor.h"
33 34
#include "audio/audio.h"
......
92 93

  
93 94
struct VncDisplay
94 95
{
96
    QTAILQ_HEAD(, VncState) clients;
95 97
    QEMUTimer *timer;
96 98
    int timer_interval;
97 99
    int lsock;
98 100
    DisplayState *ds;
99
    VncState *clients;
100 101
    kbd_layout_t *kbd_layout;
101 102

  
102 103
    struct VncSurface guest;   /* guest visible surface (aka ds->surface) */
......
165 166
    Buffer zlib_tmp;
166 167
    z_stream zlib_stream[4];
167 168

  
168
    VncState *next;
169
    QTAILQ_ENTRY(VncState) next;
169 170
};
170 171

  
171 172

  

Also available in: Unified diff