Revision 41b4bef6 vnc.c
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); |
Also available in: Unified diff