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);
|