ui: avoid pointless VNC updates if framebuffer isn't dirty
[qemu/ar7.git] / ui / vnc.c
bloba79848f083a13bab9bd1e8c31340f13661f6c8bc
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
27 #include "qemu/osdep.h"
28 #include "vnc.h"
29 #include "vnc-jobs.h"
30 #include "trace.h"
31 #include "sysemu/sysemu.h"
32 #include "qemu/error-report.h"
33 #include "qemu/sockets.h"
34 #include "qemu/timer.h"
35 #include "qemu/acl.h"
36 #include "qemu/config-file.h"
37 #include "qapi/qmp/qerror.h"
38 #include "qapi/qmp/types.h"
39 #include "qmp-commands.h"
40 #include "ui/input.h"
41 #include "qapi-event.h"
42 #include "crypto/hash.h"
43 #include "crypto/tlscredsanon.h"
44 #include "crypto/tlscredsx509.h"
45 #include "qom/object_interfaces.h"
46 #include "qemu/cutils.h"
47 #include "io/dns-resolver.h"
49 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
50 #define VNC_REFRESH_INTERVAL_INC 50
51 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
52 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
53 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
55 #include "vnc_keysym.h"
56 #include "crypto/cipher.h"
58 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
59 QTAILQ_HEAD_INITIALIZER(vnc_displays);
61 static int vnc_cursor_define(VncState *vs);
62 static void vnc_release_modifiers(VncState *vs);
64 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
66 #ifdef _VNC_DEBUG
67 static const char *mn[] = {
68 [0] = "undefined",
69 [VNC_SHARE_MODE_CONNECTING] = "connecting",
70 [VNC_SHARE_MODE_SHARED] = "shared",
71 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
72 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
74 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
75 vs->ioc, mn[vs->share_mode], mn[mode]);
76 #endif
78 switch (vs->share_mode) {
79 case VNC_SHARE_MODE_CONNECTING:
80 vs->vd->num_connecting--;
81 break;
82 case VNC_SHARE_MODE_SHARED:
83 vs->vd->num_shared--;
84 break;
85 case VNC_SHARE_MODE_EXCLUSIVE:
86 vs->vd->num_exclusive--;
87 break;
88 default:
89 break;
92 vs->share_mode = mode;
94 switch (vs->share_mode) {
95 case VNC_SHARE_MODE_CONNECTING:
96 vs->vd->num_connecting++;
97 break;
98 case VNC_SHARE_MODE_SHARED:
99 vs->vd->num_shared++;
100 break;
101 case VNC_SHARE_MODE_EXCLUSIVE:
102 vs->vd->num_exclusive++;
103 break;
104 default:
105 break;
110 static void vnc_init_basic_info(SocketAddress *addr,
111 VncBasicInfo *info,
112 Error **errp)
114 switch (addr->type) {
115 case SOCKET_ADDRESS_TYPE_INET:
116 info->host = g_strdup(addr->u.inet.host);
117 info->service = g_strdup(addr->u.inet.port);
118 if (addr->u.inet.ipv6) {
119 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
120 } else {
121 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
123 break;
125 case SOCKET_ADDRESS_TYPE_UNIX:
126 info->host = g_strdup("");
127 info->service = g_strdup(addr->u.q_unix.path);
128 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
129 break;
131 case SOCKET_ADDRESS_TYPE_VSOCK:
132 case SOCKET_ADDRESS_TYPE_FD:
133 error_setg(errp, "Unsupported socket address type %s",
134 SocketAddressType_str(addr->type));
135 break;
136 default:
137 abort();
140 return;
143 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
144 VncBasicInfo *info,
145 Error **errp)
147 SocketAddress *addr = NULL;
149 if (!ioc) {
150 error_setg(errp, "No listener socket available");
151 return;
154 addr = qio_channel_socket_get_local_address(ioc, errp);
155 if (!addr) {
156 return;
159 vnc_init_basic_info(addr, info, errp);
160 qapi_free_SocketAddress(addr);
163 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
164 VncBasicInfo *info,
165 Error **errp)
167 SocketAddress *addr = NULL;
169 addr = qio_channel_socket_get_remote_address(ioc, errp);
170 if (!addr) {
171 return;
174 vnc_init_basic_info(addr, info, errp);
175 qapi_free_SocketAddress(addr);
178 static const char *vnc_auth_name(VncDisplay *vd) {
179 switch (vd->auth) {
180 case VNC_AUTH_INVALID:
181 return "invalid";
182 case VNC_AUTH_NONE:
183 return "none";
184 case VNC_AUTH_VNC:
185 return "vnc";
186 case VNC_AUTH_RA2:
187 return "ra2";
188 case VNC_AUTH_RA2NE:
189 return "ra2ne";
190 case VNC_AUTH_TIGHT:
191 return "tight";
192 case VNC_AUTH_ULTRA:
193 return "ultra";
194 case VNC_AUTH_TLS:
195 return "tls";
196 case VNC_AUTH_VENCRYPT:
197 switch (vd->subauth) {
198 case VNC_AUTH_VENCRYPT_PLAIN:
199 return "vencrypt+plain";
200 case VNC_AUTH_VENCRYPT_TLSNONE:
201 return "vencrypt+tls+none";
202 case VNC_AUTH_VENCRYPT_TLSVNC:
203 return "vencrypt+tls+vnc";
204 case VNC_AUTH_VENCRYPT_TLSPLAIN:
205 return "vencrypt+tls+plain";
206 case VNC_AUTH_VENCRYPT_X509NONE:
207 return "vencrypt+x509+none";
208 case VNC_AUTH_VENCRYPT_X509VNC:
209 return "vencrypt+x509+vnc";
210 case VNC_AUTH_VENCRYPT_X509PLAIN:
211 return "vencrypt+x509+plain";
212 case VNC_AUTH_VENCRYPT_TLSSASL:
213 return "vencrypt+tls+sasl";
214 case VNC_AUTH_VENCRYPT_X509SASL:
215 return "vencrypt+x509+sasl";
216 default:
217 return "vencrypt";
219 case VNC_AUTH_SASL:
220 return "sasl";
222 return "unknown";
225 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
227 VncServerInfo *info;
228 Error *err = NULL;
230 if (!vd->nlsock) {
231 return NULL;
234 info = g_malloc0(sizeof(*info));
235 vnc_init_basic_info_from_server_addr(vd->lsock[0],
236 qapi_VncServerInfo_base(info), &err);
237 info->has_auth = true;
238 info->auth = g_strdup(vnc_auth_name(vd));
239 if (err) {
240 qapi_free_VncServerInfo(info);
241 info = NULL;
242 error_free(err);
244 return info;
247 static void vnc_client_cache_auth(VncState *client)
249 if (!client->info) {
250 return;
253 if (client->tls) {
254 client->info->x509_dname =
255 qcrypto_tls_session_get_peer_name(client->tls);
256 client->info->has_x509_dname =
257 client->info->x509_dname != NULL;
259 #ifdef CONFIG_VNC_SASL
260 if (client->sasl.conn &&
261 client->sasl.username) {
262 client->info->has_sasl_username = true;
263 client->info->sasl_username = g_strdup(client->sasl.username);
265 #endif
268 static void vnc_client_cache_addr(VncState *client)
270 Error *err = NULL;
272 client->info = g_malloc0(sizeof(*client->info));
273 vnc_init_basic_info_from_remote_addr(client->sioc,
274 qapi_VncClientInfo_base(client->info),
275 &err);
276 if (err) {
277 qapi_free_VncClientInfo(client->info);
278 client->info = NULL;
279 error_free(err);
283 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
285 VncServerInfo *si;
287 if (!vs->info) {
288 return;
291 si = vnc_server_info_get(vs->vd);
292 if (!si) {
293 return;
296 switch (event) {
297 case QAPI_EVENT_VNC_CONNECTED:
298 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
299 &error_abort);
300 break;
301 case QAPI_EVENT_VNC_INITIALIZED:
302 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
303 break;
304 case QAPI_EVENT_VNC_DISCONNECTED:
305 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
306 break;
307 default:
308 break;
311 qapi_free_VncServerInfo(si);
314 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
316 VncClientInfo *info;
317 Error *err = NULL;
319 info = g_malloc0(sizeof(*info));
321 vnc_init_basic_info_from_remote_addr(client->sioc,
322 qapi_VncClientInfo_base(info),
323 &err);
324 if (err) {
325 error_free(err);
326 qapi_free_VncClientInfo(info);
327 return NULL;
330 info->websocket = client->websocket;
332 if (client->tls) {
333 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
334 info->has_x509_dname = info->x509_dname != NULL;
336 #ifdef CONFIG_VNC_SASL
337 if (client->sasl.conn && client->sasl.username) {
338 info->has_sasl_username = true;
339 info->sasl_username = g_strdup(client->sasl.username);
341 #endif
343 return info;
346 static VncDisplay *vnc_display_find(const char *id)
348 VncDisplay *vd;
350 if (id == NULL) {
351 return QTAILQ_FIRST(&vnc_displays);
353 QTAILQ_FOREACH(vd, &vnc_displays, next) {
354 if (strcmp(id, vd->id) == 0) {
355 return vd;
358 return NULL;
361 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
363 VncClientInfoList *cinfo, *prev = NULL;
364 VncState *client;
366 QTAILQ_FOREACH(client, &vd->clients, next) {
367 cinfo = g_new0(VncClientInfoList, 1);
368 cinfo->value = qmp_query_vnc_client(client);
369 cinfo->next = prev;
370 prev = cinfo;
372 return prev;
375 VncInfo *qmp_query_vnc(Error **errp)
377 VncInfo *info = g_malloc0(sizeof(*info));
378 VncDisplay *vd = vnc_display_find(NULL);
379 SocketAddress *addr = NULL;
381 if (vd == NULL || !vd->nlsock) {
382 info->enabled = false;
383 } else {
384 info->enabled = true;
386 /* for compatibility with the original command */
387 info->has_clients = true;
388 info->clients = qmp_query_client_list(vd);
390 if (vd->lsock == NULL) {
391 return info;
394 addr = qio_channel_socket_get_local_address(vd->lsock[0], errp);
395 if (!addr) {
396 goto out_error;
399 switch (addr->type) {
400 case SOCKET_ADDRESS_TYPE_INET:
401 info->host = g_strdup(addr->u.inet.host);
402 info->service = g_strdup(addr->u.inet.port);
403 if (addr->u.inet.ipv6) {
404 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
405 } else {
406 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
408 break;
410 case SOCKET_ADDRESS_TYPE_UNIX:
411 info->host = g_strdup("");
412 info->service = g_strdup(addr->u.q_unix.path);
413 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
414 break;
416 case SOCKET_ADDRESS_TYPE_VSOCK:
417 case SOCKET_ADDRESS_TYPE_FD:
418 error_setg(errp, "Unsupported socket address type %s",
419 SocketAddressType_str(addr->type));
420 goto out_error;
421 default:
422 abort();
425 info->has_host = true;
426 info->has_service = true;
427 info->has_family = true;
429 info->has_auth = true;
430 info->auth = g_strdup(vnc_auth_name(vd));
433 qapi_free_SocketAddress(addr);
434 return info;
436 out_error:
437 qapi_free_SocketAddress(addr);
438 qapi_free_VncInfo(info);
439 return NULL;
443 static void qmp_query_auth(int auth, int subauth,
444 VncPrimaryAuth *qmp_auth,
445 VncVencryptSubAuth *qmp_vencrypt,
446 bool *qmp_has_vencrypt);
448 static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc,
449 bool websocket,
450 int auth,
451 int subauth,
452 VncServerInfo2List *prev)
454 VncServerInfo2List *list;
455 VncServerInfo2 *info;
456 Error *err = NULL;
457 SocketAddress *addr;
459 addr = qio_channel_socket_get_local_address(ioc, &err);
460 if (!addr) {
461 error_free(err);
462 return prev;
465 info = g_new0(VncServerInfo2, 1);
466 vnc_init_basic_info(addr, qapi_VncServerInfo2_base(info), &err);
467 qapi_free_SocketAddress(addr);
468 if (err) {
469 qapi_free_VncServerInfo2(info);
470 error_free(err);
471 return prev;
473 info->websocket = websocket;
475 qmp_query_auth(auth, subauth, &info->auth,
476 &info->vencrypt, &info->has_vencrypt);
478 list = g_new0(VncServerInfo2List, 1);
479 list->value = info;
480 list->next = prev;
481 return list;
484 static void qmp_query_auth(int auth, int subauth,
485 VncPrimaryAuth *qmp_auth,
486 VncVencryptSubAuth *qmp_vencrypt,
487 bool *qmp_has_vencrypt)
489 switch (auth) {
490 case VNC_AUTH_VNC:
491 *qmp_auth = VNC_PRIMARY_AUTH_VNC;
492 break;
493 case VNC_AUTH_RA2:
494 *qmp_auth = VNC_PRIMARY_AUTH_RA2;
495 break;
496 case VNC_AUTH_RA2NE:
497 *qmp_auth = VNC_PRIMARY_AUTH_RA2NE;
498 break;
499 case VNC_AUTH_TIGHT:
500 *qmp_auth = VNC_PRIMARY_AUTH_TIGHT;
501 break;
502 case VNC_AUTH_ULTRA:
503 *qmp_auth = VNC_PRIMARY_AUTH_ULTRA;
504 break;
505 case VNC_AUTH_TLS:
506 *qmp_auth = VNC_PRIMARY_AUTH_TLS;
507 break;
508 case VNC_AUTH_VENCRYPT:
509 *qmp_auth = VNC_PRIMARY_AUTH_VENCRYPT;
510 *qmp_has_vencrypt = true;
511 switch (subauth) {
512 case VNC_AUTH_VENCRYPT_PLAIN:
513 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
514 break;
515 case VNC_AUTH_VENCRYPT_TLSNONE:
516 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
517 break;
518 case VNC_AUTH_VENCRYPT_TLSVNC:
519 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
520 break;
521 case VNC_AUTH_VENCRYPT_TLSPLAIN:
522 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
523 break;
524 case VNC_AUTH_VENCRYPT_X509NONE:
525 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
526 break;
527 case VNC_AUTH_VENCRYPT_X509VNC:
528 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
529 break;
530 case VNC_AUTH_VENCRYPT_X509PLAIN:
531 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
532 break;
533 case VNC_AUTH_VENCRYPT_TLSSASL:
534 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
535 break;
536 case VNC_AUTH_VENCRYPT_X509SASL:
537 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
538 break;
539 default:
540 *qmp_has_vencrypt = false;
541 break;
543 break;
544 case VNC_AUTH_SASL:
545 *qmp_auth = VNC_PRIMARY_AUTH_SASL;
546 break;
547 case VNC_AUTH_NONE:
548 default:
549 *qmp_auth = VNC_PRIMARY_AUTH_NONE;
550 break;
554 VncInfo2List *qmp_query_vnc_servers(Error **errp)
556 VncInfo2List *item, *prev = NULL;
557 VncInfo2 *info;
558 VncDisplay *vd;
559 DeviceState *dev;
560 size_t i;
562 QTAILQ_FOREACH(vd, &vnc_displays, next) {
563 info = g_new0(VncInfo2, 1);
564 info->id = g_strdup(vd->id);
565 info->clients = qmp_query_client_list(vd);
566 qmp_query_auth(vd->auth, vd->subauth, &info->auth,
567 &info->vencrypt, &info->has_vencrypt);
568 if (vd->dcl.con) {
569 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
570 "device", NULL));
571 info->has_display = true;
572 info->display = g_strdup(dev->id);
574 for (i = 0; i < vd->nlsock; i++) {
575 info->server = qmp_query_server_entry(
576 vd->lsock[i], false, vd->auth, vd->subauth, info->server);
578 for (i = 0; i < vd->nlwebsock; i++) {
579 info->server = qmp_query_server_entry(
580 vd->lwebsock[i], true, vd->ws_auth,
581 vd->ws_subauth, info->server);
584 item = g_new0(VncInfo2List, 1);
585 item->value = info;
586 item->next = prev;
587 prev = item;
589 return prev;
592 /* TODO
593 1) Get the queue working for IO.
594 2) there is some weirdness when using the -S option (the screen is grey
595 and not totally invalidated
596 3) resolutions > 1024
599 static int vnc_update_client(VncState *vs, int has_dirty);
600 static void vnc_disconnect_start(VncState *vs);
602 static void vnc_colordepth(VncState *vs);
603 static void framebuffer_update_request(VncState *vs, int incremental,
604 int x_position, int y_position,
605 int w, int h);
606 static void vnc_refresh(DisplayChangeListener *dcl);
607 static int vnc_refresh_server_surface(VncDisplay *vd);
609 static int vnc_width(VncDisplay *vd)
611 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
612 VNC_DIRTY_PIXELS_PER_BIT));
615 static int vnc_height(VncDisplay *vd)
617 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
620 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
621 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
622 VncDisplay *vd,
623 int x, int y, int w, int h)
625 int width = vnc_width(vd);
626 int height = vnc_height(vd);
628 /* this is needed this to ensure we updated all affected
629 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
630 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
631 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
633 x = MIN(x, width);
634 y = MIN(y, height);
635 w = MIN(x + w, width) - x;
636 h = MIN(y + h, height);
638 for (; y < h; y++) {
639 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
640 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
644 static void vnc_dpy_update(DisplayChangeListener *dcl,
645 int x, int y, int w, int h)
647 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
648 struct VncSurface *s = &vd->guest;
650 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
653 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
654 int32_t encoding)
656 vnc_write_u16(vs, x);
657 vnc_write_u16(vs, y);
658 vnc_write_u16(vs, w);
659 vnc_write_u16(vs, h);
661 vnc_write_s32(vs, encoding);
665 static void vnc_desktop_resize(VncState *vs)
667 if (vs->ioc == NULL || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
668 return;
670 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
671 vs->client_height == pixman_image_get_height(vs->vd->server)) {
672 return;
674 vs->client_width = pixman_image_get_width(vs->vd->server);
675 vs->client_height = pixman_image_get_height(vs->vd->server);
676 vnc_lock_output(vs);
677 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
678 vnc_write_u8(vs, 0);
679 vnc_write_u16(vs, 1); /* number of rects */
680 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
681 VNC_ENCODING_DESKTOPRESIZE);
682 vnc_unlock_output(vs);
683 vnc_flush(vs);
686 static void vnc_abort_display_jobs(VncDisplay *vd)
688 VncState *vs;
690 QTAILQ_FOREACH(vs, &vd->clients, next) {
691 vnc_lock_output(vs);
692 vs->abort = true;
693 vnc_unlock_output(vs);
695 QTAILQ_FOREACH(vs, &vd->clients, next) {
696 vnc_jobs_join(vs);
698 QTAILQ_FOREACH(vs, &vd->clients, next) {
699 vnc_lock_output(vs);
700 vs->abort = false;
701 vnc_unlock_output(vs);
705 int vnc_server_fb_stride(VncDisplay *vd)
707 return pixman_image_get_stride(vd->server);
710 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
712 uint8_t *ptr;
714 ptr = (uint8_t *)pixman_image_get_data(vd->server);
715 ptr += y * vnc_server_fb_stride(vd);
716 ptr += x * VNC_SERVER_FB_BYTES;
717 return ptr;
720 static void vnc_update_server_surface(VncDisplay *vd)
722 int width, height;
724 qemu_pixman_image_unref(vd->server);
725 vd->server = NULL;
727 if (QTAILQ_EMPTY(&vd->clients)) {
728 return;
731 width = vnc_width(vd);
732 height = vnc_height(vd);
733 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
734 width, height,
735 NULL, 0);
737 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
738 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
739 width, height);
742 static void vnc_dpy_switch(DisplayChangeListener *dcl,
743 DisplaySurface *surface)
745 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
746 VncState *vs;
748 vnc_abort_display_jobs(vd);
749 vd->ds = surface;
751 /* server surface */
752 vnc_update_server_surface(vd);
754 /* guest surface */
755 qemu_pixman_image_unref(vd->guest.fb);
756 vd->guest.fb = pixman_image_ref(surface->image);
757 vd->guest.format = surface->format;
759 QTAILQ_FOREACH(vs, &vd->clients, next) {
760 vnc_colordepth(vs);
761 vnc_desktop_resize(vs);
762 if (vs->vd->cursor) {
763 vnc_cursor_define(vs);
765 memset(vs->dirty, 0x00, sizeof(vs->dirty));
766 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
767 vnc_width(vd),
768 vnc_height(vd));
772 /* fastest code */
773 static void vnc_write_pixels_copy(VncState *vs,
774 void *pixels, int size)
776 vnc_write(vs, pixels, size);
779 /* slowest but generic code. */
780 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
782 uint8_t r, g, b;
784 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
785 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
786 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
787 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
788 #else
789 # error need some bits here if you change VNC_SERVER_FB_FORMAT
790 #endif
791 v = (r << vs->client_pf.rshift) |
792 (g << vs->client_pf.gshift) |
793 (b << vs->client_pf.bshift);
794 switch (vs->client_pf.bytes_per_pixel) {
795 case 1:
796 buf[0] = v;
797 break;
798 case 2:
799 if (vs->client_be) {
800 buf[0] = v >> 8;
801 buf[1] = v;
802 } else {
803 buf[1] = v >> 8;
804 buf[0] = v;
806 break;
807 default:
808 case 4:
809 if (vs->client_be) {
810 buf[0] = v >> 24;
811 buf[1] = v >> 16;
812 buf[2] = v >> 8;
813 buf[3] = v;
814 } else {
815 buf[3] = v >> 24;
816 buf[2] = v >> 16;
817 buf[1] = v >> 8;
818 buf[0] = v;
820 break;
824 static void vnc_write_pixels_generic(VncState *vs,
825 void *pixels1, int size)
827 uint8_t buf[4];
829 if (VNC_SERVER_FB_BYTES == 4) {
830 uint32_t *pixels = pixels1;
831 int n, i;
832 n = size >> 2;
833 for (i = 0; i < n; i++) {
834 vnc_convert_pixel(vs, buf, pixels[i]);
835 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
840 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
842 int i;
843 uint8_t *row;
844 VncDisplay *vd = vs->vd;
846 row = vnc_server_fb_ptr(vd, x, y);
847 for (i = 0; i < h; i++) {
848 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
849 row += vnc_server_fb_stride(vd);
851 return 1;
854 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
856 int n = 0;
857 bool encode_raw = false;
858 size_t saved_offs = vs->output.offset;
860 switch(vs->vnc_encoding) {
861 case VNC_ENCODING_ZLIB:
862 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
863 break;
864 case VNC_ENCODING_HEXTILE:
865 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
866 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
867 break;
868 case VNC_ENCODING_TIGHT:
869 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
870 break;
871 case VNC_ENCODING_TIGHT_PNG:
872 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
873 break;
874 case VNC_ENCODING_ZRLE:
875 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
876 break;
877 case VNC_ENCODING_ZYWRLE:
878 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
879 break;
880 default:
881 encode_raw = true;
882 break;
885 /* If the client has the same pixel format as our internal buffer and
886 * a RAW encoding would need less space fall back to RAW encoding to
887 * save bandwidth and processing power in the client. */
888 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
889 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
890 vs->output.offset = saved_offs;
891 encode_raw = true;
894 if (encode_raw) {
895 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
896 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
899 return n;
902 static void vnc_mouse_set(DisplayChangeListener *dcl,
903 int x, int y, int visible)
905 /* can we ask the client(s) to move the pointer ??? */
908 static int vnc_cursor_define(VncState *vs)
910 QEMUCursor *c = vs->vd->cursor;
911 int isize;
913 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
914 vnc_lock_output(vs);
915 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
916 vnc_write_u8(vs, 0); /* padding */
917 vnc_write_u16(vs, 1); /* # of rects */
918 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
919 VNC_ENCODING_RICH_CURSOR);
920 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
921 vnc_write_pixels_generic(vs, c->data, isize);
922 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
923 vnc_unlock_output(vs);
924 return 0;
926 return -1;
929 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
930 QEMUCursor *c)
932 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
933 VncState *vs;
935 cursor_put(vd->cursor);
936 g_free(vd->cursor_mask);
938 vd->cursor = c;
939 cursor_get(vd->cursor);
940 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
941 vd->cursor_mask = g_malloc0(vd->cursor_msize);
942 cursor_get_mono_mask(c, 0, vd->cursor_mask);
944 QTAILQ_FOREACH(vs, &vd->clients, next) {
945 vnc_cursor_define(vs);
949 static int find_and_clear_dirty_height(VncState *vs,
950 int y, int last_x, int x, int height)
952 int h;
954 for (h = 1; h < (height - y); h++) {
955 if (!test_bit(last_x, vs->dirty[y + h])) {
956 break;
958 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
961 return h;
964 static int vnc_update_client(VncState *vs, int has_dirty)
966 VncDisplay *vd = vs->vd;
967 VncJob *job;
968 int y;
969 int height, width;
970 int n = 0;
972 if (vs->disconnecting) {
973 vnc_disconnect_finish(vs);
974 return 0;
977 vs->has_dirty += has_dirty;
978 if (!vs->need_update) {
979 return 0;
982 if (vs->output.offset && !vs->audio_cap && !vs->force_update) {
983 /* kernel send buffers are full -> drop frames to throttle */
984 return 0;
987 if (!vs->has_dirty && !vs->force_update) {
988 return 0;
992 * Send screen updates to the vnc client using the server
993 * surface and server dirty map. guest surface updates
994 * happening in parallel don't disturb us, the next pass will
995 * send them to the client.
997 job = vnc_job_new(vs);
999 height = pixman_image_get_height(vd->server);
1000 width = pixman_image_get_width(vd->server);
1002 y = 0;
1003 for (;;) {
1004 int x, h;
1005 unsigned long x2;
1006 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1007 height * VNC_DIRTY_BPL(vs),
1008 y * VNC_DIRTY_BPL(vs));
1009 if (offset == height * VNC_DIRTY_BPL(vs)) {
1010 /* no more dirty bits */
1011 break;
1013 y = offset / VNC_DIRTY_BPL(vs);
1014 x = offset % VNC_DIRTY_BPL(vs);
1015 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1016 VNC_DIRTY_BPL(vs), x);
1017 bitmap_clear(vs->dirty[y], x, x2 - x);
1018 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1019 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1020 if (x2 > x) {
1021 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1022 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1024 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1025 y += h;
1026 if (y == height) {
1027 break;
1032 vnc_job_push(job);
1033 vs->force_update = 0;
1034 vs->has_dirty = 0;
1035 return n;
1038 /* audio */
1039 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1041 VncState *vs = opaque;
1043 switch (cmd) {
1044 case AUD_CNOTIFY_DISABLE:
1045 vnc_lock_output(vs);
1046 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1047 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1048 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1049 vnc_unlock_output(vs);
1050 vnc_flush(vs);
1051 break;
1053 case AUD_CNOTIFY_ENABLE:
1054 vnc_lock_output(vs);
1055 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1056 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1057 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1058 vnc_unlock_output(vs);
1059 vnc_flush(vs);
1060 break;
1064 static void audio_capture_destroy(void *opaque)
1068 static void audio_capture(void *opaque, void *buf, int size)
1070 VncState *vs = opaque;
1072 vnc_lock_output(vs);
1073 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1074 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1075 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1076 vnc_write_u32(vs, size);
1077 vnc_write(vs, buf, size);
1078 vnc_unlock_output(vs);
1079 vnc_flush(vs);
1082 static void audio_add(VncState *vs)
1084 struct audio_capture_ops ops;
1086 if (vs->audio_cap) {
1087 error_report("audio already running");
1088 return;
1091 ops.notify = audio_capture_notify;
1092 ops.destroy = audio_capture_destroy;
1093 ops.capture = audio_capture;
1095 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1096 if (!vs->audio_cap) {
1097 error_report("Failed to add audio capture");
1101 static void audio_del(VncState *vs)
1103 if (vs->audio_cap) {
1104 AUD_del_capture(vs->audio_cap, vs);
1105 vs->audio_cap = NULL;
1109 static void vnc_disconnect_start(VncState *vs)
1111 if (vs->disconnecting) {
1112 return;
1114 trace_vnc_client_disconnect_start(vs, vs->ioc);
1115 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1116 if (vs->ioc_tag) {
1117 g_source_remove(vs->ioc_tag);
1118 vs->ioc_tag = 0;
1120 qio_channel_close(vs->ioc, NULL);
1121 vs->disconnecting = TRUE;
1124 void vnc_disconnect_finish(VncState *vs)
1126 int i;
1128 trace_vnc_client_disconnect_finish(vs, vs->ioc);
1130 vnc_jobs_join(vs); /* Wait encoding jobs */
1132 vnc_lock_output(vs);
1133 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1135 buffer_free(&vs->input);
1136 buffer_free(&vs->output);
1138 qapi_free_VncClientInfo(vs->info);
1140 vnc_zlib_clear(vs);
1141 vnc_tight_clear(vs);
1142 vnc_zrle_clear(vs);
1144 #ifdef CONFIG_VNC_SASL
1145 vnc_sasl_client_cleanup(vs);
1146 #endif /* CONFIG_VNC_SASL */
1147 audio_del(vs);
1148 vnc_release_modifiers(vs);
1150 if (vs->mouse_mode_notifier.notify != NULL) {
1151 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1153 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1154 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1155 /* last client gone */
1156 vnc_update_server_surface(vs->vd);
1159 vnc_unlock_output(vs);
1161 qemu_mutex_destroy(&vs->output_mutex);
1162 if (vs->bh != NULL) {
1163 qemu_bh_delete(vs->bh);
1165 buffer_free(&vs->jobs_buffer);
1167 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1168 g_free(vs->lossy_rect[i]);
1170 g_free(vs->lossy_rect);
1172 object_unref(OBJECT(vs->ioc));
1173 vs->ioc = NULL;
1174 object_unref(OBJECT(vs->sioc));
1175 vs->sioc = NULL;
1176 g_free(vs);
1179 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
1181 if (ret <= 0) {
1182 if (ret == 0) {
1183 trace_vnc_client_eof(vs, vs->ioc);
1184 vnc_disconnect_start(vs);
1185 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1186 trace_vnc_client_io_error(vs, vs->ioc,
1187 errp ? error_get_pretty(*errp) :
1188 "Unknown");
1189 vnc_disconnect_start(vs);
1192 if (errp) {
1193 error_free(*errp);
1194 *errp = NULL;
1196 return 0;
1198 return ret;
1202 void vnc_client_error(VncState *vs)
1204 VNC_DEBUG("Closing down client sock: protocol error\n");
1205 vnc_disconnect_start(vs);
1210 * Called to write a chunk of data to the client socket. The data may
1211 * be the raw data, or may have already been encoded by SASL.
1212 * The data will be written either straight onto the socket, or
1213 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1215 * NB, it is theoretically possible to have 2 layers of encryption,
1216 * both SASL, and this TLS layer. It is highly unlikely in practice
1217 * though, since SASL encryption will typically be a no-op if TLS
1218 * is active
1220 * Returns the number of bytes written, which may be less than
1221 * the requested 'datalen' if the socket would block. Returns
1222 * -1 on error, and disconnects the client socket.
1224 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1226 Error *err = NULL;
1227 ssize_t ret;
1228 ret = qio_channel_write(
1229 vs->ioc, (const char *)data, datalen, &err);
1230 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1231 return vnc_client_io_error(vs, ret, &err);
1236 * Called to write buffered data to the client socket, when not
1237 * using any SASL SSF encryption layers. Will write as much data
1238 * as possible without blocking. If all buffered data is written,
1239 * will switch the FD poll() handler back to read monitoring.
1241 * Returns the number of bytes written, which may be less than
1242 * the buffered output data if the socket would block. Returns
1243 * -1 on error, and disconnects the client socket.
1245 static ssize_t vnc_client_write_plain(VncState *vs)
1247 ssize_t ret;
1249 #ifdef CONFIG_VNC_SASL
1250 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1251 vs->output.buffer, vs->output.capacity, vs->output.offset,
1252 vs->sasl.waitWriteSSF);
1254 if (vs->sasl.conn &&
1255 vs->sasl.runSSF &&
1256 vs->sasl.waitWriteSSF) {
1257 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1258 if (ret)
1259 vs->sasl.waitWriteSSF -= ret;
1260 } else
1261 #endif /* CONFIG_VNC_SASL */
1262 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1263 if (!ret)
1264 return 0;
1266 buffer_advance(&vs->output, ret);
1268 if (vs->output.offset == 0) {
1269 if (vs->ioc_tag) {
1270 g_source_remove(vs->ioc_tag);
1272 vs->ioc_tag = qio_channel_add_watch(
1273 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1276 return ret;
1281 * First function called whenever there is data to be written to
1282 * the client socket. Will delegate actual work according to whether
1283 * SASL SSF layers are enabled (thus requiring encryption calls)
1285 static void vnc_client_write_locked(VncState *vs)
1287 #ifdef CONFIG_VNC_SASL
1288 if (vs->sasl.conn &&
1289 vs->sasl.runSSF &&
1290 !vs->sasl.waitWriteSSF) {
1291 vnc_client_write_sasl(vs);
1292 } else
1293 #endif /* CONFIG_VNC_SASL */
1295 vnc_client_write_plain(vs);
1299 static void vnc_client_write(VncState *vs)
1302 vnc_lock_output(vs);
1303 if (vs->output.offset) {
1304 vnc_client_write_locked(vs);
1305 } else if (vs->ioc != NULL) {
1306 if (vs->ioc_tag) {
1307 g_source_remove(vs->ioc_tag);
1309 vs->ioc_tag = qio_channel_add_watch(
1310 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
1312 vnc_unlock_output(vs);
1315 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1317 vs->read_handler = func;
1318 vs->read_handler_expect = expecting;
1323 * Called to read a chunk of data from the client socket. The data may
1324 * be the raw data, or may need to be further decoded by SASL.
1325 * The data will be read either straight from to the socket, or
1326 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1328 * NB, it is theoretically possible to have 2 layers of encryption,
1329 * both SASL, and this TLS layer. It is highly unlikely in practice
1330 * though, since SASL encryption will typically be a no-op if TLS
1331 * is active
1333 * Returns the number of bytes read, which may be less than
1334 * the requested 'datalen' if the socket would block. Returns
1335 * -1 on error, and disconnects the client socket.
1337 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1339 ssize_t ret;
1340 Error *err = NULL;
1341 ret = qio_channel_read(
1342 vs->ioc, (char *)data, datalen, &err);
1343 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1344 return vnc_client_io_error(vs, ret, &err);
1349 * Called to read data from the client socket to the input buffer,
1350 * when not using any SASL SSF encryption layers. Will read as much
1351 * data as possible without blocking.
1353 * Returns the number of bytes read. Returns -1 on error, and
1354 * disconnects the client socket.
1356 static ssize_t vnc_client_read_plain(VncState *vs)
1358 ssize_t ret;
1359 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1360 vs->input.buffer, vs->input.capacity, vs->input.offset);
1361 buffer_reserve(&vs->input, 4096);
1362 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1363 if (!ret)
1364 return 0;
1365 vs->input.offset += ret;
1366 return ret;
1369 static void vnc_jobs_bh(void *opaque)
1371 VncState *vs = opaque;
1373 vnc_jobs_consume_buffer(vs);
1377 * First function called whenever there is more data to be read from
1378 * the client socket. Will delegate actual work according to whether
1379 * SASL SSF layers are enabled (thus requiring decryption calls)
1380 * Returns 0 on success, -1 if client disconnected
1382 static int vnc_client_read(VncState *vs)
1384 ssize_t ret;
1386 #ifdef CONFIG_VNC_SASL
1387 if (vs->sasl.conn && vs->sasl.runSSF)
1388 ret = vnc_client_read_sasl(vs);
1389 else
1390 #endif /* CONFIG_VNC_SASL */
1391 ret = vnc_client_read_plain(vs);
1392 if (!ret) {
1393 if (vs->disconnecting) {
1394 vnc_disconnect_finish(vs);
1395 return -1;
1397 return 0;
1400 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1401 size_t len = vs->read_handler_expect;
1402 int ret;
1404 ret = vs->read_handler(vs, vs->input.buffer, len);
1405 if (vs->disconnecting) {
1406 vnc_disconnect_finish(vs);
1407 return -1;
1410 if (!ret) {
1411 buffer_advance(&vs->input, len);
1412 } else {
1413 vs->read_handler_expect = ret;
1416 return 0;
1419 gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1420 GIOCondition condition, void *opaque)
1422 VncState *vs = opaque;
1423 if (condition & G_IO_IN) {
1424 if (vnc_client_read(vs) < 0) {
1425 return TRUE;
1428 if (condition & G_IO_OUT) {
1429 vnc_client_write(vs);
1431 return TRUE;
1435 void vnc_write(VncState *vs, const void *data, size_t len)
1437 buffer_reserve(&vs->output, len);
1439 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1440 if (vs->ioc_tag) {
1441 g_source_remove(vs->ioc_tag);
1443 vs->ioc_tag = qio_channel_add_watch(
1444 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
1447 buffer_append(&vs->output, data, len);
1450 void vnc_write_s32(VncState *vs, int32_t value)
1452 vnc_write_u32(vs, *(uint32_t *)&value);
1455 void vnc_write_u32(VncState *vs, uint32_t value)
1457 uint8_t buf[4];
1459 buf[0] = (value >> 24) & 0xFF;
1460 buf[1] = (value >> 16) & 0xFF;
1461 buf[2] = (value >> 8) & 0xFF;
1462 buf[3] = value & 0xFF;
1464 vnc_write(vs, buf, 4);
1467 void vnc_write_u16(VncState *vs, uint16_t value)
1469 uint8_t buf[2];
1471 buf[0] = (value >> 8) & 0xFF;
1472 buf[1] = value & 0xFF;
1474 vnc_write(vs, buf, 2);
1477 void vnc_write_u8(VncState *vs, uint8_t value)
1479 vnc_write(vs, (char *)&value, 1);
1482 void vnc_flush(VncState *vs)
1484 vnc_lock_output(vs);
1485 if (vs->ioc != NULL && vs->output.offset) {
1486 vnc_client_write_locked(vs);
1488 vnc_unlock_output(vs);
1491 static uint8_t read_u8(uint8_t *data, size_t offset)
1493 return data[offset];
1496 static uint16_t read_u16(uint8_t *data, size_t offset)
1498 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1501 static int32_t read_s32(uint8_t *data, size_t offset)
1503 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1504 (data[offset + 2] << 8) | data[offset + 3]);
1507 uint32_t read_u32(uint8_t *data, size_t offset)
1509 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1510 (data[offset + 2] << 8) | data[offset + 3]);
1513 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1517 static void check_pointer_type_change(Notifier *notifier, void *data)
1519 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1520 int absolute = qemu_input_is_absolute();
1522 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1523 vnc_lock_output(vs);
1524 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1525 vnc_write_u8(vs, 0);
1526 vnc_write_u16(vs, 1);
1527 vnc_framebuffer_update(vs, absolute, 0,
1528 pixman_image_get_width(vs->vd->server),
1529 pixman_image_get_height(vs->vd->server),
1530 VNC_ENCODING_POINTER_TYPE_CHANGE);
1531 vnc_unlock_output(vs);
1532 vnc_flush(vs);
1534 vs->absolute = absolute;
1537 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1539 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1540 [INPUT_BUTTON_LEFT] = 0x01,
1541 [INPUT_BUTTON_MIDDLE] = 0x02,
1542 [INPUT_BUTTON_RIGHT] = 0x04,
1543 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1544 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1546 QemuConsole *con = vs->vd->dcl.con;
1547 int width = pixman_image_get_width(vs->vd->server);
1548 int height = pixman_image_get_height(vs->vd->server);
1550 if (vs->last_bmask != button_mask) {
1551 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1552 vs->last_bmask = button_mask;
1555 if (vs->absolute) {
1556 qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
1557 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
1558 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1559 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1560 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1561 } else {
1562 if (vs->last_x != -1) {
1563 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1564 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1566 vs->last_x = x;
1567 vs->last_y = y;
1569 qemu_input_event_sync();
1572 static void reset_keys(VncState *vs)
1574 int i;
1575 for(i = 0; i < 256; i++) {
1576 if (vs->modifiers_state[i]) {
1577 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1578 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1579 vs->modifiers_state[i] = 0;
1584 static void press_key(VncState *vs, int keysym)
1586 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1587 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1588 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1589 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1590 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1593 static void vnc_led_state_change(VncState *vs)
1595 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1596 return;
1599 vnc_lock_output(vs);
1600 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1601 vnc_write_u8(vs, 0);
1602 vnc_write_u16(vs, 1);
1603 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1604 vnc_write_u8(vs, vs->vd->ledstate);
1605 vnc_unlock_output(vs);
1606 vnc_flush(vs);
1609 static void kbd_leds(void *opaque, int ledstate)
1611 VncDisplay *vd = opaque;
1612 VncState *client;
1614 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1615 (ledstate & QEMU_NUM_LOCK_LED),
1616 (ledstate & QEMU_SCROLL_LOCK_LED));
1618 if (ledstate == vd->ledstate) {
1619 return;
1622 vd->ledstate = ledstate;
1624 QTAILQ_FOREACH(client, &vd->clients, next) {
1625 vnc_led_state_change(client);
1629 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1631 /* QEMU console switch */
1632 switch(keycode) {
1633 case 0x2a: /* Left Shift */
1634 case 0x36: /* Right Shift */
1635 case 0x1d: /* Left CTRL */
1636 case 0x9d: /* Right CTRL */
1637 case 0x38: /* Left ALT */
1638 case 0xb8: /* Right ALT */
1639 if (down)
1640 vs->modifiers_state[keycode] = 1;
1641 else
1642 vs->modifiers_state[keycode] = 0;
1643 break;
1644 case 0x02 ... 0x0a: /* '1' to '9' keys */
1645 if (vs->vd->dcl.con == NULL &&
1646 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1647 /* Reset the modifiers sent to the current console */
1648 reset_keys(vs);
1649 console_select(keycode - 0x02);
1650 return;
1652 break;
1653 case 0x3a: /* CapsLock */
1654 case 0x45: /* NumLock */
1655 if (down)
1656 vs->modifiers_state[keycode] ^= 1;
1657 break;
1660 /* Turn off the lock state sync logic if the client support the led
1661 state extension.
1663 if (down && vs->vd->lock_key_sync &&
1664 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1665 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1666 /* If the numlock state needs to change then simulate an additional
1667 keypress before sending this one. This will happen if the user
1668 toggles numlock away from the VNC window.
1670 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1671 if (!vs->modifiers_state[0x45]) {
1672 trace_vnc_key_sync_numlock(true);
1673 vs->modifiers_state[0x45] = 1;
1674 press_key(vs, 0xff7f);
1676 } else {
1677 if (vs->modifiers_state[0x45]) {
1678 trace_vnc_key_sync_numlock(false);
1679 vs->modifiers_state[0x45] = 0;
1680 press_key(vs, 0xff7f);
1685 if (down && vs->vd->lock_key_sync &&
1686 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1687 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1688 /* If the capslock state needs to change then simulate an additional
1689 keypress before sending this one. This will happen if the user
1690 toggles capslock away from the VNC window.
1692 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1693 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1694 int capslock = !!(vs->modifiers_state[0x3a]);
1695 if (capslock) {
1696 if (uppercase == shift) {
1697 trace_vnc_key_sync_capslock(false);
1698 vs->modifiers_state[0x3a] = 0;
1699 press_key(vs, 0xffe5);
1701 } else {
1702 if (uppercase != shift) {
1703 trace_vnc_key_sync_capslock(true);
1704 vs->modifiers_state[0x3a] = 1;
1705 press_key(vs, 0xffe5);
1710 if (qemu_console_is_graphic(NULL)) {
1711 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1712 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1713 } else {
1714 bool numlock = vs->modifiers_state[0x45];
1715 bool control = (vs->modifiers_state[0x1d] ||
1716 vs->modifiers_state[0x9d]);
1717 /* QEMU console emulation */
1718 if (down) {
1719 switch (keycode) {
1720 case 0x2a: /* Left Shift */
1721 case 0x36: /* Right Shift */
1722 case 0x1d: /* Left CTRL */
1723 case 0x9d: /* Right CTRL */
1724 case 0x38: /* Left ALT */
1725 case 0xb8: /* Right ALT */
1726 break;
1727 case 0xc8:
1728 kbd_put_keysym(QEMU_KEY_UP);
1729 break;
1730 case 0xd0:
1731 kbd_put_keysym(QEMU_KEY_DOWN);
1732 break;
1733 case 0xcb:
1734 kbd_put_keysym(QEMU_KEY_LEFT);
1735 break;
1736 case 0xcd:
1737 kbd_put_keysym(QEMU_KEY_RIGHT);
1738 break;
1739 case 0xd3:
1740 kbd_put_keysym(QEMU_KEY_DELETE);
1741 break;
1742 case 0xc7:
1743 kbd_put_keysym(QEMU_KEY_HOME);
1744 break;
1745 case 0xcf:
1746 kbd_put_keysym(QEMU_KEY_END);
1747 break;
1748 case 0xc9:
1749 kbd_put_keysym(QEMU_KEY_PAGEUP);
1750 break;
1751 case 0xd1:
1752 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1753 break;
1755 case 0x47:
1756 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1757 break;
1758 case 0x48:
1759 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1760 break;
1761 case 0x49:
1762 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1763 break;
1764 case 0x4b:
1765 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1766 break;
1767 case 0x4c:
1768 kbd_put_keysym('5');
1769 break;
1770 case 0x4d:
1771 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1772 break;
1773 case 0x4f:
1774 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1775 break;
1776 case 0x50:
1777 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1778 break;
1779 case 0x51:
1780 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1781 break;
1782 case 0x52:
1783 kbd_put_keysym('0');
1784 break;
1785 case 0x53:
1786 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1787 break;
1789 case 0xb5:
1790 kbd_put_keysym('/');
1791 break;
1792 case 0x37:
1793 kbd_put_keysym('*');
1794 break;
1795 case 0x4a:
1796 kbd_put_keysym('-');
1797 break;
1798 case 0x4e:
1799 kbd_put_keysym('+');
1800 break;
1801 case 0x9c:
1802 kbd_put_keysym('\n');
1803 break;
1805 default:
1806 if (control) {
1807 kbd_put_keysym(sym & 0x1f);
1808 } else {
1809 kbd_put_keysym(sym);
1811 break;
1817 static void vnc_release_modifiers(VncState *vs)
1819 static const int keycodes[] = {
1820 /* shift, control, alt keys, both left & right */
1821 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1823 int i, keycode;
1825 if (!qemu_console_is_graphic(NULL)) {
1826 return;
1828 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1829 keycode = keycodes[i];
1830 if (!vs->modifiers_state[keycode]) {
1831 continue;
1833 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1834 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
1838 static const char *code2name(int keycode)
1840 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode));
1843 static void key_event(VncState *vs, int down, uint32_t sym)
1845 int keycode;
1846 int lsym = sym;
1848 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
1849 lsym = lsym - 'A' + 'a';
1852 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
1853 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
1854 do_key_event(vs, down, keycode, sym);
1857 static void ext_key_event(VncState *vs, int down,
1858 uint32_t sym, uint16_t keycode)
1860 /* if the user specifies a keyboard layout, always use it */
1861 if (keyboard_layout) {
1862 key_event(vs, down, sym);
1863 } else {
1864 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
1865 do_key_event(vs, down, keycode, sym);
1869 static void framebuffer_update_request(VncState *vs, int incremental,
1870 int x, int y, int w, int h)
1872 vs->need_update = 1;
1874 if (incremental) {
1875 return;
1878 vs->force_update = 1;
1879 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
1882 static void send_ext_key_event_ack(VncState *vs)
1884 vnc_lock_output(vs);
1885 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1886 vnc_write_u8(vs, 0);
1887 vnc_write_u16(vs, 1);
1888 vnc_framebuffer_update(vs, 0, 0,
1889 pixman_image_get_width(vs->vd->server),
1890 pixman_image_get_height(vs->vd->server),
1891 VNC_ENCODING_EXT_KEY_EVENT);
1892 vnc_unlock_output(vs);
1893 vnc_flush(vs);
1896 static void send_ext_audio_ack(VncState *vs)
1898 vnc_lock_output(vs);
1899 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1900 vnc_write_u8(vs, 0);
1901 vnc_write_u16(vs, 1);
1902 vnc_framebuffer_update(vs, 0, 0,
1903 pixman_image_get_width(vs->vd->server),
1904 pixman_image_get_height(vs->vd->server),
1905 VNC_ENCODING_AUDIO);
1906 vnc_unlock_output(vs);
1907 vnc_flush(vs);
1910 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1912 int i;
1913 unsigned int enc = 0;
1915 vs->features = 0;
1916 vs->vnc_encoding = 0;
1917 vs->tight.compression = 9;
1918 vs->tight.quality = -1; /* Lossless by default */
1919 vs->absolute = -1;
1922 * Start from the end because the encodings are sent in order of preference.
1923 * This way the preferred encoding (first encoding defined in the array)
1924 * will be set at the end of the loop.
1926 for (i = n_encodings - 1; i >= 0; i--) {
1927 enc = encodings[i];
1928 switch (enc) {
1929 case VNC_ENCODING_RAW:
1930 vs->vnc_encoding = enc;
1931 break;
1932 case VNC_ENCODING_COPYRECT:
1933 vs->features |= VNC_FEATURE_COPYRECT_MASK;
1934 break;
1935 case VNC_ENCODING_HEXTILE:
1936 vs->features |= VNC_FEATURE_HEXTILE_MASK;
1937 vs->vnc_encoding = enc;
1938 break;
1939 case VNC_ENCODING_TIGHT:
1940 vs->features |= VNC_FEATURE_TIGHT_MASK;
1941 vs->vnc_encoding = enc;
1942 break;
1943 #ifdef CONFIG_VNC_PNG
1944 case VNC_ENCODING_TIGHT_PNG:
1945 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
1946 vs->vnc_encoding = enc;
1947 break;
1948 #endif
1949 case VNC_ENCODING_ZLIB:
1950 vs->features |= VNC_FEATURE_ZLIB_MASK;
1951 vs->vnc_encoding = enc;
1952 break;
1953 case VNC_ENCODING_ZRLE:
1954 vs->features |= VNC_FEATURE_ZRLE_MASK;
1955 vs->vnc_encoding = enc;
1956 break;
1957 case VNC_ENCODING_ZYWRLE:
1958 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
1959 vs->vnc_encoding = enc;
1960 break;
1961 case VNC_ENCODING_DESKTOPRESIZE:
1962 vs->features |= VNC_FEATURE_RESIZE_MASK;
1963 break;
1964 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1965 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1966 break;
1967 case VNC_ENCODING_RICH_CURSOR:
1968 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
1969 if (vs->vd->cursor) {
1970 vnc_cursor_define(vs);
1972 break;
1973 case VNC_ENCODING_EXT_KEY_EVENT:
1974 send_ext_key_event_ack(vs);
1975 break;
1976 case VNC_ENCODING_AUDIO:
1977 send_ext_audio_ack(vs);
1978 break;
1979 case VNC_ENCODING_WMVi:
1980 vs->features |= VNC_FEATURE_WMVI_MASK;
1981 break;
1982 case VNC_ENCODING_LED_STATE:
1983 vs->features |= VNC_FEATURE_LED_STATE_MASK;
1984 break;
1985 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
1986 vs->tight.compression = (enc & 0x0F);
1987 break;
1988 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
1989 if (vs->vd->lossy) {
1990 vs->tight.quality = (enc & 0x0F);
1992 break;
1993 default:
1994 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
1995 break;
1998 vnc_desktop_resize(vs);
1999 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2000 vnc_led_state_change(vs);
2003 static void set_pixel_conversion(VncState *vs)
2005 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2007 if (fmt == VNC_SERVER_FB_FORMAT) {
2008 vs->write_pixels = vnc_write_pixels_copy;
2009 vnc_hextile_set_pixel_conversion(vs, 0);
2010 } else {
2011 vs->write_pixels = vnc_write_pixels_generic;
2012 vnc_hextile_set_pixel_conversion(vs, 1);
2016 static void send_color_map(VncState *vs)
2018 int i;
2020 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2021 vnc_write_u8(vs, 0); /* padding */
2022 vnc_write_u16(vs, 0); /* first color */
2023 vnc_write_u16(vs, 256); /* # of colors */
2025 for (i = 0; i < 256; i++) {
2026 PixelFormat *pf = &vs->client_pf;
2028 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2029 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2030 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2034 static void set_pixel_format(VncState *vs, int bits_per_pixel,
2035 int big_endian_flag, int true_color_flag,
2036 int red_max, int green_max, int blue_max,
2037 int red_shift, int green_shift, int blue_shift)
2039 if (!true_color_flag) {
2040 /* Expose a reasonable default 256 color map */
2041 bits_per_pixel = 8;
2042 red_max = 7;
2043 green_max = 7;
2044 blue_max = 3;
2045 red_shift = 0;
2046 green_shift = 3;
2047 blue_shift = 6;
2050 switch (bits_per_pixel) {
2051 case 8:
2052 case 16:
2053 case 32:
2054 break;
2055 default:
2056 vnc_client_error(vs);
2057 return;
2060 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2061 vs->client_pf.rbits = ctpopl(red_max);
2062 vs->client_pf.rshift = red_shift;
2063 vs->client_pf.rmask = red_max << red_shift;
2064 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2065 vs->client_pf.gbits = ctpopl(green_max);
2066 vs->client_pf.gshift = green_shift;
2067 vs->client_pf.gmask = green_max << green_shift;
2068 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2069 vs->client_pf.bbits = ctpopl(blue_max);
2070 vs->client_pf.bshift = blue_shift;
2071 vs->client_pf.bmask = blue_max << blue_shift;
2072 vs->client_pf.bits_per_pixel = bits_per_pixel;
2073 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2074 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2075 vs->client_be = big_endian_flag;
2077 if (!true_color_flag) {
2078 send_color_map(vs);
2081 set_pixel_conversion(vs);
2083 graphic_hw_invalidate(vs->vd->dcl.con);
2084 graphic_hw_update(vs->vd->dcl.con);
2087 static void pixel_format_message (VncState *vs) {
2088 char pad[3] = { 0, 0, 0 };
2090 vs->client_pf = qemu_default_pixelformat(32);
2092 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2093 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2095 #ifdef HOST_WORDS_BIGENDIAN
2096 vnc_write_u8(vs, 1); /* big-endian-flag */
2097 #else
2098 vnc_write_u8(vs, 0); /* big-endian-flag */
2099 #endif
2100 vnc_write_u8(vs, 1); /* true-color-flag */
2101 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2102 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2103 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2104 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2105 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2106 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2107 vnc_write(vs, pad, 3); /* padding */
2109 vnc_hextile_set_pixel_conversion(vs, 0);
2110 vs->write_pixels = vnc_write_pixels_copy;
2113 static void vnc_colordepth(VncState *vs)
2115 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2116 /* Sending a WMVi message to notify the client*/
2117 vnc_lock_output(vs);
2118 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2119 vnc_write_u8(vs, 0);
2120 vnc_write_u16(vs, 1); /* number of rects */
2121 vnc_framebuffer_update(vs, 0, 0,
2122 pixman_image_get_width(vs->vd->server),
2123 pixman_image_get_height(vs->vd->server),
2124 VNC_ENCODING_WMVi);
2125 pixel_format_message(vs);
2126 vnc_unlock_output(vs);
2127 vnc_flush(vs);
2128 } else {
2129 set_pixel_conversion(vs);
2133 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2135 int i;
2136 uint16_t limit;
2137 VncDisplay *vd = vs->vd;
2139 if (data[0] > 3) {
2140 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2143 switch (data[0]) {
2144 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2145 if (len == 1)
2146 return 20;
2148 set_pixel_format(vs, read_u8(data, 4),
2149 read_u8(data, 6), read_u8(data, 7),
2150 read_u16(data, 8), read_u16(data, 10),
2151 read_u16(data, 12), read_u8(data, 14),
2152 read_u8(data, 15), read_u8(data, 16));
2153 break;
2154 case VNC_MSG_CLIENT_SET_ENCODINGS:
2155 if (len == 1)
2156 return 4;
2158 if (len == 4) {
2159 limit = read_u16(data, 2);
2160 if (limit > 0)
2161 return 4 + (limit * 4);
2162 } else
2163 limit = read_u16(data, 2);
2165 for (i = 0; i < limit; i++) {
2166 int32_t val = read_s32(data, 4 + (i * 4));
2167 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2170 set_encodings(vs, (int32_t *)(data + 4), limit);
2171 break;
2172 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2173 if (len == 1)
2174 return 10;
2176 framebuffer_update_request(vs,
2177 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2178 read_u16(data, 6), read_u16(data, 8));
2179 break;
2180 case VNC_MSG_CLIENT_KEY_EVENT:
2181 if (len == 1)
2182 return 8;
2184 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2185 break;
2186 case VNC_MSG_CLIENT_POINTER_EVENT:
2187 if (len == 1)
2188 return 6;
2190 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2191 break;
2192 case VNC_MSG_CLIENT_CUT_TEXT:
2193 if (len == 1) {
2194 return 8;
2196 if (len == 8) {
2197 uint32_t dlen = read_u32(data, 4);
2198 if (dlen > (1 << 20)) {
2199 error_report("vnc: client_cut_text msg payload has %u bytes"
2200 " which exceeds our limit of 1MB.", dlen);
2201 vnc_client_error(vs);
2202 break;
2204 if (dlen > 0) {
2205 return 8 + dlen;
2209 client_cut_text(vs, read_u32(data, 4), data + 8);
2210 break;
2211 case VNC_MSG_CLIENT_QEMU:
2212 if (len == 1)
2213 return 2;
2215 switch (read_u8(data, 1)) {
2216 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2217 if (len == 2)
2218 return 12;
2220 ext_key_event(vs, read_u16(data, 2),
2221 read_u32(data, 4), read_u32(data, 8));
2222 break;
2223 case VNC_MSG_CLIENT_QEMU_AUDIO:
2224 if (len == 2)
2225 return 4;
2227 switch (read_u16 (data, 2)) {
2228 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2229 audio_add(vs);
2230 break;
2231 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2232 audio_del(vs);
2233 break;
2234 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2235 if (len == 4)
2236 return 10;
2237 switch (read_u8(data, 4)) {
2238 case 0: vs->as.fmt = AUD_FMT_U8; break;
2239 case 1: vs->as.fmt = AUD_FMT_S8; break;
2240 case 2: vs->as.fmt = AUD_FMT_U16; break;
2241 case 3: vs->as.fmt = AUD_FMT_S16; break;
2242 case 4: vs->as.fmt = AUD_FMT_U32; break;
2243 case 5: vs->as.fmt = AUD_FMT_S32; break;
2244 default:
2245 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2246 vnc_client_error(vs);
2247 break;
2249 vs->as.nchannels = read_u8(data, 5);
2250 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2251 VNC_DEBUG("Invalid audio channel count %d\n",
2252 read_u8(data, 5));
2253 vnc_client_error(vs);
2254 break;
2256 vs->as.freq = read_u32(data, 6);
2257 break;
2258 default:
2259 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2260 vnc_client_error(vs);
2261 break;
2263 break;
2265 default:
2266 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2267 vnc_client_error(vs);
2268 break;
2270 break;
2271 default:
2272 VNC_DEBUG("Msg: %d\n", data[0]);
2273 vnc_client_error(vs);
2274 break;
2277 vnc_read_when(vs, protocol_client_msg, 1);
2278 return 0;
2281 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2283 char buf[1024];
2284 VncShareMode mode;
2285 int size;
2287 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2288 switch (vs->vd->share_policy) {
2289 case VNC_SHARE_POLICY_IGNORE:
2291 * Ignore the shared flag. Nothing to do here.
2293 * Doesn't conform to the rfb spec but is traditional qemu
2294 * behavior, thus left here as option for compatibility
2295 * reasons.
2297 break;
2298 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2300 * Policy: Allow clients ask for exclusive access.
2302 * Implementation: When a client asks for exclusive access,
2303 * disconnect all others. Shared connects are allowed as long
2304 * as no exclusive connection exists.
2306 * This is how the rfb spec suggests to handle the shared flag.
2308 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2309 VncState *client;
2310 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2311 if (vs == client) {
2312 continue;
2314 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2315 client->share_mode != VNC_SHARE_MODE_SHARED) {
2316 continue;
2318 vnc_disconnect_start(client);
2321 if (mode == VNC_SHARE_MODE_SHARED) {
2322 if (vs->vd->num_exclusive > 0) {
2323 vnc_disconnect_start(vs);
2324 return 0;
2327 break;
2328 case VNC_SHARE_POLICY_FORCE_SHARED:
2330 * Policy: Shared connects only.
2331 * Implementation: Disallow clients asking for exclusive access.
2333 * Useful for shared desktop sessions where you don't want
2334 * someone forgetting to say -shared when running the vnc
2335 * client disconnect everybody else.
2337 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2338 vnc_disconnect_start(vs);
2339 return 0;
2341 break;
2343 vnc_set_share_mode(vs, mode);
2345 if (vs->vd->num_shared > vs->vd->connections_limit) {
2346 vnc_disconnect_start(vs);
2347 return 0;
2350 vs->client_width = pixman_image_get_width(vs->vd->server);
2351 vs->client_height = pixman_image_get_height(vs->vd->server);
2352 vnc_write_u16(vs, vs->client_width);
2353 vnc_write_u16(vs, vs->client_height);
2355 pixel_format_message(vs);
2357 if (qemu_name) {
2358 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2359 if (size > sizeof(buf)) {
2360 size = sizeof(buf);
2362 } else {
2363 size = snprintf(buf, sizeof(buf), "QEMU");
2366 vnc_write_u32(vs, size);
2367 vnc_write(vs, buf, size);
2368 vnc_flush(vs);
2370 vnc_client_cache_auth(vs);
2371 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2373 vnc_read_when(vs, protocol_client_msg, 1);
2375 return 0;
2378 void start_client_init(VncState *vs)
2380 vnc_read_when(vs, protocol_client_init, 1);
2383 static void make_challenge(VncState *vs)
2385 int i;
2387 srand(time(NULL)+getpid()+getpid()*987654+rand());
2389 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2390 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2393 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2395 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2396 size_t i, pwlen;
2397 unsigned char key[8];
2398 time_t now = time(NULL);
2399 QCryptoCipher *cipher = NULL;
2400 Error *err = NULL;
2402 if (!vs->vd->password) {
2403 trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
2404 goto reject;
2406 if (vs->vd->expires < now) {
2407 trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
2408 goto reject;
2411 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2413 /* Calculate the expected challenge response */
2414 pwlen = strlen(vs->vd->password);
2415 for (i=0; i<sizeof(key); i++)
2416 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2418 cipher = qcrypto_cipher_new(
2419 QCRYPTO_CIPHER_ALG_DES_RFB,
2420 QCRYPTO_CIPHER_MODE_ECB,
2421 key, G_N_ELEMENTS(key),
2422 &err);
2423 if (!cipher) {
2424 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
2425 error_get_pretty(err));
2426 error_free(err);
2427 goto reject;
2430 if (qcrypto_cipher_encrypt(cipher,
2431 vs->challenge,
2432 response,
2433 VNC_AUTH_CHALLENGE_SIZE,
2434 &err) < 0) {
2435 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
2436 error_get_pretty(err));
2437 error_free(err);
2438 goto reject;
2441 /* Compare expected vs actual challenge response */
2442 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2443 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
2444 goto reject;
2445 } else {
2446 trace_vnc_auth_pass(vs, vs->auth);
2447 vnc_write_u32(vs, 0); /* Accept auth */
2448 vnc_flush(vs);
2450 start_client_init(vs);
2453 qcrypto_cipher_free(cipher);
2454 return 0;
2456 reject:
2457 vnc_write_u32(vs, 1); /* Reject auth */
2458 if (vs->minor >= 8) {
2459 static const char err[] = "Authentication failed";
2460 vnc_write_u32(vs, sizeof(err));
2461 vnc_write(vs, err, sizeof(err));
2463 vnc_flush(vs);
2464 vnc_client_error(vs);
2465 qcrypto_cipher_free(cipher);
2466 return 0;
2469 void start_auth_vnc(VncState *vs)
2471 make_challenge(vs);
2472 /* Send client a 'random' challenge */
2473 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2474 vnc_flush(vs);
2476 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2480 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2482 /* We only advertise 1 auth scheme at a time, so client
2483 * must pick the one we sent. Verify this */
2484 if (data[0] != vs->auth) { /* Reject auth */
2485 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
2486 vnc_write_u32(vs, 1);
2487 if (vs->minor >= 8) {
2488 static const char err[] = "Authentication failed";
2489 vnc_write_u32(vs, sizeof(err));
2490 vnc_write(vs, err, sizeof(err));
2492 vnc_client_error(vs);
2493 } else { /* Accept requested auth */
2494 trace_vnc_auth_start(vs, vs->auth);
2495 switch (vs->auth) {
2496 case VNC_AUTH_NONE:
2497 if (vs->minor >= 8) {
2498 vnc_write_u32(vs, 0); /* Accept auth completion */
2499 vnc_flush(vs);
2501 trace_vnc_auth_pass(vs, vs->auth);
2502 start_client_init(vs);
2503 break;
2505 case VNC_AUTH_VNC:
2506 start_auth_vnc(vs);
2507 break;
2509 case VNC_AUTH_VENCRYPT:
2510 start_auth_vencrypt(vs);
2511 break;
2513 #ifdef CONFIG_VNC_SASL
2514 case VNC_AUTH_SASL:
2515 start_auth_sasl(vs);
2516 break;
2517 #endif /* CONFIG_VNC_SASL */
2519 default: /* Should not be possible, but just in case */
2520 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
2521 vnc_write_u8(vs, 1);
2522 if (vs->minor >= 8) {
2523 static const char err[] = "Authentication failed";
2524 vnc_write_u32(vs, sizeof(err));
2525 vnc_write(vs, err, sizeof(err));
2527 vnc_client_error(vs);
2530 return 0;
2533 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2535 char local[13];
2537 memcpy(local, version, 12);
2538 local[12] = 0;
2540 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2541 VNC_DEBUG("Malformed protocol version %s\n", local);
2542 vnc_client_error(vs);
2543 return 0;
2545 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2546 if (vs->major != 3 ||
2547 (vs->minor != 3 &&
2548 vs->minor != 4 &&
2549 vs->minor != 5 &&
2550 vs->minor != 7 &&
2551 vs->minor != 8)) {
2552 VNC_DEBUG("Unsupported client version\n");
2553 vnc_write_u32(vs, VNC_AUTH_INVALID);
2554 vnc_flush(vs);
2555 vnc_client_error(vs);
2556 return 0;
2558 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2559 * as equivalent to v3.3 by servers
2561 if (vs->minor == 4 || vs->minor == 5)
2562 vs->minor = 3;
2564 if (vs->minor == 3) {
2565 trace_vnc_auth_start(vs, vs->auth);
2566 if (vs->auth == VNC_AUTH_NONE) {
2567 vnc_write_u32(vs, vs->auth);
2568 vnc_flush(vs);
2569 trace_vnc_auth_pass(vs, vs->auth);
2570 start_client_init(vs);
2571 } else if (vs->auth == VNC_AUTH_VNC) {
2572 VNC_DEBUG("Tell client VNC auth\n");
2573 vnc_write_u32(vs, vs->auth);
2574 vnc_flush(vs);
2575 start_auth_vnc(vs);
2576 } else {
2577 trace_vnc_auth_fail(vs, vs->auth,
2578 "Unsupported auth method for v3.3", "");
2579 vnc_write_u32(vs, VNC_AUTH_INVALID);
2580 vnc_flush(vs);
2581 vnc_client_error(vs);
2583 } else {
2584 vnc_write_u8(vs, 1); /* num auth */
2585 vnc_write_u8(vs, vs->auth);
2586 vnc_read_when(vs, protocol_client_auth, 1);
2587 vnc_flush(vs);
2590 return 0;
2593 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2595 struct VncSurface *vs = &vd->guest;
2597 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2600 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2602 int i, j;
2604 w = (x + w) / VNC_STAT_RECT;
2605 h = (y + h) / VNC_STAT_RECT;
2606 x /= VNC_STAT_RECT;
2607 y /= VNC_STAT_RECT;
2609 for (j = y; j <= h; j++) {
2610 for (i = x; i <= w; i++) {
2611 vs->lossy_rect[j][i] = 1;
2616 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2618 VncState *vs;
2619 int sty = y / VNC_STAT_RECT;
2620 int stx = x / VNC_STAT_RECT;
2621 int has_dirty = 0;
2623 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2624 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2626 QTAILQ_FOREACH(vs, &vd->clients, next) {
2627 int j;
2629 /* kernel send buffers are full -> refresh later */
2630 if (vs->output.offset) {
2631 continue;
2634 if (!vs->lossy_rect[sty][stx]) {
2635 continue;
2638 vs->lossy_rect[sty][stx] = 0;
2639 for (j = 0; j < VNC_STAT_RECT; ++j) {
2640 bitmap_set(vs->dirty[y + j],
2641 x / VNC_DIRTY_PIXELS_PER_BIT,
2642 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2644 has_dirty++;
2647 return has_dirty;
2650 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2652 int width = MIN(pixman_image_get_width(vd->guest.fb),
2653 pixman_image_get_width(vd->server));
2654 int height = MIN(pixman_image_get_height(vd->guest.fb),
2655 pixman_image_get_height(vd->server));
2656 int x, y;
2657 struct timeval res;
2658 int has_dirty = 0;
2660 for (y = 0; y < height; y += VNC_STAT_RECT) {
2661 for (x = 0; x < width; x += VNC_STAT_RECT) {
2662 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2664 rect->updated = false;
2668 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2670 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2671 return has_dirty;
2673 vd->guest.last_freq_check = *tv;
2675 for (y = 0; y < height; y += VNC_STAT_RECT) {
2676 for (x = 0; x < width; x += VNC_STAT_RECT) {
2677 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2678 int count = ARRAY_SIZE(rect->times);
2679 struct timeval min, max;
2681 if (!timerisset(&rect->times[count - 1])) {
2682 continue ;
2685 max = rect->times[(rect->idx + count - 1) % count];
2686 qemu_timersub(tv, &max, &res);
2688 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2689 rect->freq = 0;
2690 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2691 memset(rect->times, 0, sizeof (rect->times));
2692 continue ;
2695 min = rect->times[rect->idx];
2696 max = rect->times[(rect->idx + count - 1) % count];
2697 qemu_timersub(&max, &min, &res);
2699 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2700 rect->freq /= count;
2701 rect->freq = 1. / rect->freq;
2704 return has_dirty;
2707 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2709 int i, j;
2710 double total = 0;
2711 int num = 0;
2713 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2714 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2716 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2717 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2718 total += vnc_stat_rect(vs->vd, i, j)->freq;
2719 num++;
2723 if (num) {
2724 return total / num;
2725 } else {
2726 return 0;
2730 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2732 VncRectStat *rect;
2734 rect = vnc_stat_rect(vd, x, y);
2735 if (rect->updated) {
2736 return ;
2738 rect->times[rect->idx] = *tv;
2739 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2740 rect->updated = true;
2743 static int vnc_refresh_server_surface(VncDisplay *vd)
2745 int width = MIN(pixman_image_get_width(vd->guest.fb),
2746 pixman_image_get_width(vd->server));
2747 int height = MIN(pixman_image_get_height(vd->guest.fb),
2748 pixman_image_get_height(vd->server));
2749 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2750 uint8_t *guest_row0 = NULL, *server_row0;
2751 VncState *vs;
2752 int has_dirty = 0;
2753 pixman_image_t *tmpbuf = NULL;
2755 struct timeval tv = { 0, 0 };
2757 if (!vd->non_adaptive) {
2758 gettimeofday(&tv, NULL);
2759 has_dirty = vnc_update_stats(vd, &tv);
2763 * Walk through the guest dirty map.
2764 * Check and copy modified bits from guest to server surface.
2765 * Update server dirty map.
2767 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2768 server_stride = guest_stride = guest_ll =
2769 pixman_image_get_stride(vd->server);
2770 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2771 server_stride);
2772 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2773 int width = pixman_image_get_width(vd->server);
2774 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2775 } else {
2776 int guest_bpp =
2777 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2778 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2779 guest_stride = pixman_image_get_stride(vd->guest.fb);
2780 guest_ll = pixman_image_get_width(vd->guest.fb) * (DIV_ROUND_UP(guest_bpp, 8));
2782 line_bytes = MIN(server_stride, guest_ll);
2784 for (;;) {
2785 int x;
2786 uint8_t *guest_ptr, *server_ptr;
2787 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2788 height * VNC_DIRTY_BPL(&vd->guest),
2789 y * VNC_DIRTY_BPL(&vd->guest));
2790 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2791 /* no more dirty bits */
2792 break;
2794 y = offset / VNC_DIRTY_BPL(&vd->guest);
2795 x = offset % VNC_DIRTY_BPL(&vd->guest);
2797 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2799 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2800 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2801 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2802 } else {
2803 guest_ptr = guest_row0 + y * guest_stride;
2805 guest_ptr += x * cmp_bytes;
2807 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2808 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2809 int _cmp_bytes = cmp_bytes;
2810 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2811 continue;
2813 if ((x + 1) * cmp_bytes > line_bytes) {
2814 _cmp_bytes = line_bytes - x * cmp_bytes;
2816 assert(_cmp_bytes >= 0);
2817 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2818 continue;
2820 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2821 if (!vd->non_adaptive) {
2822 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2823 y, &tv);
2825 QTAILQ_FOREACH(vs, &vd->clients, next) {
2826 set_bit(x, vs->dirty[y]);
2828 has_dirty++;
2831 y++;
2833 qemu_pixman_image_unref(tmpbuf);
2834 return has_dirty;
2837 static void vnc_refresh(DisplayChangeListener *dcl)
2839 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2840 VncState *vs, *vn;
2841 int has_dirty, rects = 0;
2843 if (QTAILQ_EMPTY(&vd->clients)) {
2844 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2845 return;
2848 graphic_hw_update(vd->dcl.con);
2850 if (vnc_trylock_display(vd)) {
2851 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2852 return;
2855 has_dirty = vnc_refresh_server_surface(vd);
2856 vnc_unlock_display(vd);
2858 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2859 rects += vnc_update_client(vs, has_dirty);
2860 /* vs might be free()ed here */
2863 if (has_dirty && rects) {
2864 vd->dcl.update_interval /= 2;
2865 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2866 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2868 } else {
2869 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2870 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2871 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2876 static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2877 bool skipauth, bool websocket)
2879 VncState *vs = g_new0(VncState, 1);
2880 bool first_client = QTAILQ_EMPTY(&vd->clients);
2881 int i;
2883 trace_vnc_client_connect(vs, sioc);
2884 vs->sioc = sioc;
2885 object_ref(OBJECT(vs->sioc));
2886 vs->ioc = QIO_CHANNEL(sioc);
2887 object_ref(OBJECT(vs->ioc));
2888 vs->vd = vd;
2890 buffer_init(&vs->input, "vnc-input/%p", sioc);
2891 buffer_init(&vs->output, "vnc-output/%p", sioc);
2892 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
2894 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
2895 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
2896 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
2897 #ifdef CONFIG_VNC_JPEG
2898 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
2899 #endif
2900 #ifdef CONFIG_VNC_PNG
2901 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
2902 #endif
2903 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
2904 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
2905 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
2906 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
2908 if (skipauth) {
2909 vs->auth = VNC_AUTH_NONE;
2910 vs->subauth = VNC_AUTH_INVALID;
2911 } else {
2912 if (websocket) {
2913 vs->auth = vd->ws_auth;
2914 vs->subauth = VNC_AUTH_INVALID;
2915 } else {
2916 vs->auth = vd->auth;
2917 vs->subauth = vd->subauth;
2920 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2921 sioc, websocket, vs->auth, vs->subauth);
2923 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
2924 for (i = 0; i < VNC_STAT_ROWS; ++i) {
2925 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
2928 VNC_DEBUG("New client on socket %p\n", vs->sioc);
2929 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2930 qio_channel_set_blocking(vs->ioc, false, NULL);
2931 if (vs->ioc_tag) {
2932 g_source_remove(vs->ioc_tag);
2934 if (websocket) {
2935 vs->websocket = 1;
2936 if (vd->tlscreds) {
2937 vs->ioc_tag = qio_channel_add_watch(
2938 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
2939 } else {
2940 vs->ioc_tag = qio_channel_add_watch(
2941 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
2943 } else {
2944 vs->ioc_tag = qio_channel_add_watch(
2945 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
2948 vnc_client_cache_addr(vs);
2949 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
2950 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
2952 vs->last_x = -1;
2953 vs->last_y = -1;
2955 vs->as.freq = 44100;
2956 vs->as.nchannels = 2;
2957 vs->as.fmt = AUD_FMT_S16;
2958 vs->as.endianness = 0;
2960 qemu_mutex_init(&vs->output_mutex);
2961 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
2963 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
2964 if (first_client) {
2965 vnc_update_server_surface(vd);
2968 graphic_hw_update(vd->dcl.con);
2970 if (!vs->websocket) {
2971 vnc_start_protocol(vs);
2974 if (vd->num_connecting > vd->connections_limit) {
2975 QTAILQ_FOREACH(vs, &vd->clients, next) {
2976 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
2977 vnc_disconnect_start(vs);
2978 return;
2984 void vnc_start_protocol(VncState *vs)
2986 vnc_write(vs, "RFB 003.008\n", 12);
2987 vnc_flush(vs);
2988 vnc_read_when(vs, protocol_version, 12);
2990 vs->mouse_mode_notifier.notify = check_pointer_type_change;
2991 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
2994 static gboolean vnc_listen_io(QIOChannel *ioc,
2995 GIOCondition condition,
2996 void *opaque)
2998 VncDisplay *vd = opaque;
2999 QIOChannelSocket *sioc = NULL;
3000 Error *err = NULL;
3001 bool isWebsock = false;
3002 size_t i;
3004 for (i = 0; i < vd->nlwebsock; i++) {
3005 if (ioc == QIO_CHANNEL(vd->lwebsock[i])) {
3006 isWebsock = true;
3007 break;
3011 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
3012 if (sioc != NULL) {
3013 qio_channel_set_name(QIO_CHANNEL(sioc),
3014 isWebsock ? "vnc-ws-server" : "vnc-server");
3015 qio_channel_set_delay(QIO_CHANNEL(sioc), false);
3016 vnc_connect(vd, sioc, false, isWebsock);
3017 object_unref(OBJECT(sioc));
3018 } else {
3019 /* client probably closed connection before we got there */
3020 error_free(err);
3023 return TRUE;
3026 static const DisplayChangeListenerOps dcl_ops = {
3027 .dpy_name = "vnc",
3028 .dpy_refresh = vnc_refresh,
3029 .dpy_gfx_update = vnc_dpy_update,
3030 .dpy_gfx_switch = vnc_dpy_switch,
3031 .dpy_gfx_check_format = qemu_pixman_check_format,
3032 .dpy_mouse_set = vnc_mouse_set,
3033 .dpy_cursor_define = vnc_dpy_cursor_define,
3036 void vnc_display_init(const char *id)
3038 VncDisplay *vd;
3040 if (vnc_display_find(id) != NULL) {
3041 return;
3043 vd = g_malloc0(sizeof(*vd));
3045 vd->id = strdup(id);
3046 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
3048 QTAILQ_INIT(&vd->clients);
3049 vd->expires = TIME_MAX;
3051 if (keyboard_layout) {
3052 trace_vnc_key_map_init(keyboard_layout);
3053 vd->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3054 } else {
3055 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3058 if (!vd->kbd_layout) {
3059 exit(1);
3062 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3063 vd->connections_limit = 32;
3065 qemu_mutex_init(&vd->mutex);
3066 vnc_start_worker_thread();
3068 vd->dcl.ops = &dcl_ops;
3069 register_displaychangelistener(&vd->dcl);
3073 static void vnc_display_close(VncDisplay *vd)
3075 size_t i;
3076 if (!vd) {
3077 return;
3079 vd->is_unix = false;
3080 for (i = 0; i < vd->nlsock; i++) {
3081 if (vd->lsock_tag[i]) {
3082 g_source_remove(vd->lsock_tag[i]);
3084 object_unref(OBJECT(vd->lsock[i]));
3086 g_free(vd->lsock);
3087 g_free(vd->lsock_tag);
3088 vd->lsock = NULL;
3089 vd->lsock_tag = NULL;
3090 vd->nlsock = 0;
3092 for (i = 0; i < vd->nlwebsock; i++) {
3093 if (vd->lwebsock_tag[i]) {
3094 g_source_remove(vd->lwebsock_tag[i]);
3096 object_unref(OBJECT(vd->lwebsock[i]));
3098 g_free(vd->lwebsock);
3099 g_free(vd->lwebsock_tag);
3100 vd->lwebsock = NULL;
3101 vd->lwebsock_tag = NULL;
3102 vd->nlwebsock = 0;
3104 vd->auth = VNC_AUTH_INVALID;
3105 vd->subauth = VNC_AUTH_INVALID;
3106 if (vd->tlscreds) {
3107 object_unparent(OBJECT(vd->tlscreds));
3108 vd->tlscreds = NULL;
3110 g_free(vd->tlsaclname);
3111 vd->tlsaclname = NULL;
3112 if (vd->lock_key_sync) {
3113 qemu_remove_led_event_handler(vd->led);
3114 vd->led = NULL;
3118 int vnc_display_password(const char *id, const char *password)
3120 VncDisplay *vd = vnc_display_find(id);
3122 if (!vd) {
3123 return -EINVAL;
3125 if (vd->auth == VNC_AUTH_NONE) {
3126 error_printf_unless_qmp("If you want use passwords please enable "
3127 "password auth using '-vnc ${dpy},password'.\n");
3128 return -EINVAL;
3131 g_free(vd->password);
3132 vd->password = g_strdup(password);
3134 return 0;
3137 int vnc_display_pw_expire(const char *id, time_t expires)
3139 VncDisplay *vd = vnc_display_find(id);
3141 if (!vd) {
3142 return -EINVAL;
3145 vd->expires = expires;
3146 return 0;
3149 static void vnc_display_print_local_addr(VncDisplay *vd)
3151 SocketAddress *addr;
3152 Error *err = NULL;
3154 if (!vd->nlsock) {
3155 return;
3158 addr = qio_channel_socket_get_local_address(vd->lsock[0], &err);
3159 if (!addr) {
3160 return;
3163 if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
3164 qapi_free_SocketAddress(addr);
3165 return;
3167 error_printf_unless_qmp("VNC server running on %s:%s\n",
3168 addr->u.inet.host,
3169 addr->u.inet.port);
3170 qapi_free_SocketAddress(addr);
3173 static QemuOptsList qemu_vnc_opts = {
3174 .name = "vnc",
3175 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3176 .implied_opt_name = "vnc",
3177 .desc = {
3179 .name = "vnc",
3180 .type = QEMU_OPT_STRING,
3182 .name = "websocket",
3183 .type = QEMU_OPT_STRING,
3185 .name = "tls-creds",
3186 .type = QEMU_OPT_STRING,
3188 /* Deprecated in favour of tls-creds */
3189 .name = "x509",
3190 .type = QEMU_OPT_STRING,
3192 .name = "share",
3193 .type = QEMU_OPT_STRING,
3195 .name = "display",
3196 .type = QEMU_OPT_STRING,
3198 .name = "head",
3199 .type = QEMU_OPT_NUMBER,
3201 .name = "connections",
3202 .type = QEMU_OPT_NUMBER,
3204 .name = "to",
3205 .type = QEMU_OPT_NUMBER,
3207 .name = "ipv4",
3208 .type = QEMU_OPT_BOOL,
3210 .name = "ipv6",
3211 .type = QEMU_OPT_BOOL,
3213 .name = "password",
3214 .type = QEMU_OPT_BOOL,
3216 .name = "reverse",
3217 .type = QEMU_OPT_BOOL,
3219 .name = "lock-key-sync",
3220 .type = QEMU_OPT_BOOL,
3222 .name = "key-delay-ms",
3223 .type = QEMU_OPT_NUMBER,
3225 .name = "sasl",
3226 .type = QEMU_OPT_BOOL,
3228 /* Deprecated in favour of tls-creds */
3229 .name = "tls",
3230 .type = QEMU_OPT_BOOL,
3232 /* Deprecated in favour of tls-creds */
3233 .name = "x509verify",
3234 .type = QEMU_OPT_STRING,
3236 .name = "acl",
3237 .type = QEMU_OPT_BOOL,
3239 .name = "lossy",
3240 .type = QEMU_OPT_BOOL,
3242 .name = "non-adaptive",
3243 .type = QEMU_OPT_BOOL,
3245 { /* end of list */ }
3250 static int
3251 vnc_display_setup_auth(int *auth,
3252 int *subauth,
3253 QCryptoTLSCreds *tlscreds,
3254 bool password,
3255 bool sasl,
3256 bool websocket,
3257 Error **errp)
3260 * We have a choice of 3 authentication options
3262 * 1. none
3263 * 2. vnc
3264 * 3. sasl
3266 * The channel can be run in 2 modes
3268 * 1. clear
3269 * 2. tls
3271 * And TLS can use 2 types of credentials
3273 * 1. anon
3274 * 2. x509
3276 * We thus have 9 possible logical combinations
3278 * 1. clear + none
3279 * 2. clear + vnc
3280 * 3. clear + sasl
3281 * 4. tls + anon + none
3282 * 5. tls + anon + vnc
3283 * 6. tls + anon + sasl
3284 * 7. tls + x509 + none
3285 * 8. tls + x509 + vnc
3286 * 9. tls + x509 + sasl
3288 * These need to be mapped into the VNC auth schemes
3289 * in an appropriate manner. In regular VNC, all the
3290 * TLS options get mapped into VNC_AUTH_VENCRYPT
3291 * sub-auth types.
3293 * In websockets, the https:// protocol already provides
3294 * TLS support, so there is no need to make use of the
3295 * VeNCrypt extension. Furthermore, websockets browser
3296 * clients could not use VeNCrypt even if they wanted to,
3297 * as they cannot control when the TLS handshake takes
3298 * place. Thus there is no option but to rely on https://,
3299 * meaning combinations 4->6 and 7->9 will be mapped to
3300 * VNC auth schemes in the same way as combos 1->3.
3302 * Regardless of fact that we have a different mapping to
3303 * VNC auth mechs for plain VNC vs websockets VNC, the end
3304 * result has the same security characteristics.
3306 if (websocket || !tlscreds) {
3307 if (password) {
3308 VNC_DEBUG("Initializing VNC server with password auth\n");
3309 *auth = VNC_AUTH_VNC;
3310 } else if (sasl) {
3311 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3312 *auth = VNC_AUTH_SASL;
3313 } else {
3314 VNC_DEBUG("Initializing VNC server with no auth\n");
3315 *auth = VNC_AUTH_NONE;
3317 *subauth = VNC_AUTH_INVALID;
3318 } else {
3319 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3320 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3321 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3322 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3324 if (!is_x509 && !is_anon) {
3325 error_setg(errp,
3326 "Unsupported TLS cred type %s",
3327 object_get_typename(OBJECT(tlscreds)));
3328 return -1;
3330 *auth = VNC_AUTH_VENCRYPT;
3331 if (password) {
3332 if (is_x509) {
3333 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3334 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3335 } else {
3336 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3337 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3340 } else if (sasl) {
3341 if (is_x509) {
3342 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3343 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3344 } else {
3345 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3346 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3348 } else {
3349 if (is_x509) {
3350 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3351 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3352 } else {
3353 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3354 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3358 return 0;
3363 * Handle back compat with old CLI syntax by creating some
3364 * suitable QCryptoTLSCreds objects
3366 static QCryptoTLSCreds *
3367 vnc_display_create_creds(bool x509,
3368 bool x509verify,
3369 const char *dir,
3370 const char *id,
3371 Error **errp)
3373 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3374 Object *parent = object_get_objects_root();
3375 Object *creds;
3376 Error *err = NULL;
3378 if (x509) {
3379 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3380 parent,
3381 credsid,
3382 &err,
3383 "endpoint", "server",
3384 "dir", dir,
3385 "verify-peer", x509verify ? "yes" : "no",
3386 NULL);
3387 } else {
3388 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3389 parent,
3390 credsid,
3391 &err,
3392 "endpoint", "server",
3393 NULL);
3396 g_free(credsid);
3398 if (err) {
3399 error_propagate(errp, err);
3400 return NULL;
3403 return QCRYPTO_TLS_CREDS(creds);
3407 static int vnc_display_get_address(const char *addrstr,
3408 bool websocket,
3409 bool reverse,
3410 int displaynum,
3411 int to,
3412 bool has_ipv4,
3413 bool has_ipv6,
3414 bool ipv4,
3415 bool ipv6,
3416 SocketAddress **retaddr,
3417 Error **errp)
3419 int ret = -1;
3420 SocketAddress *addr = NULL;
3422 addr = g_new0(SocketAddress, 1);
3424 if (strncmp(addrstr, "unix:", 5) == 0) {
3425 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
3426 addr->u.q_unix.path = g_strdup(addrstr + 5);
3428 if (websocket) {
3429 error_setg(errp, "UNIX sockets not supported with websock");
3430 goto cleanup;
3433 if (to) {
3434 error_setg(errp, "Port range not support with UNIX socket");
3435 goto cleanup;
3437 ret = 0;
3438 } else {
3439 const char *port;
3440 size_t hostlen;
3441 unsigned long long baseport = 0;
3442 InetSocketAddress *inet;
3444 port = strrchr(addrstr, ':');
3445 if (!port) {
3446 if (websocket) {
3447 hostlen = 0;
3448 port = addrstr;
3449 } else {
3450 error_setg(errp, "no vnc port specified");
3451 goto cleanup;
3453 } else {
3454 hostlen = port - addrstr;
3455 port++;
3456 if (*port == '\0') {
3457 error_setg(errp, "vnc port cannot be empty");
3458 goto cleanup;
3462 addr->type = SOCKET_ADDRESS_TYPE_INET;
3463 inet = &addr->u.inet;
3464 if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
3465 inet->host = g_strndup(addrstr + 1, hostlen - 2);
3466 } else {
3467 inet->host = g_strndup(addrstr, hostlen);
3469 /* plain VNC port is just an offset, for websocket
3470 * port is absolute */
3471 if (websocket) {
3472 if (g_str_equal(addrstr, "") ||
3473 g_str_equal(addrstr, "on")) {
3474 if (displaynum == -1) {
3475 error_setg(errp, "explicit websocket port is required");
3476 goto cleanup;
3478 inet->port = g_strdup_printf(
3479 "%d", displaynum + 5700);
3480 if (to) {
3481 inet->has_to = true;
3482 inet->to = to + 5700;
3484 } else {
3485 inet->port = g_strdup(port);
3487 } else {
3488 int offset = reverse ? 0 : 5900;
3489 if (parse_uint_full(port, &baseport, 10) < 0) {
3490 error_setg(errp, "can't convert to a number: %s", port);
3491 goto cleanup;
3493 if (baseport > 65535 ||
3494 baseport + offset > 65535) {
3495 error_setg(errp, "port %s out of range", port);
3496 goto cleanup;
3498 inet->port = g_strdup_printf(
3499 "%d", (int)baseport + offset);
3501 if (to) {
3502 inet->has_to = true;
3503 inet->to = to + offset;
3507 inet->ipv4 = ipv4;
3508 inet->has_ipv4 = has_ipv4;
3509 inet->ipv6 = ipv6;
3510 inet->has_ipv6 = has_ipv6;
3512 ret = baseport;
3515 *retaddr = addr;
3517 cleanup:
3518 if (ret < 0) {
3519 qapi_free_SocketAddress(addr);
3521 return ret;
3524 static void vnc_free_addresses(SocketAddress ***retsaddr,
3525 size_t *retnsaddr)
3527 size_t i;
3529 for (i = 0; i < *retnsaddr; i++) {
3530 qapi_free_SocketAddress((*retsaddr)[i]);
3532 g_free(*retsaddr);
3534 *retsaddr = NULL;
3535 *retnsaddr = 0;
3538 static int vnc_display_get_addresses(QemuOpts *opts,
3539 bool reverse,
3540 SocketAddress ***retsaddr,
3541 size_t *retnsaddr,
3542 SocketAddress ***retwsaddr,
3543 size_t *retnwsaddr,
3544 Error **errp)
3546 SocketAddress *saddr = NULL;
3547 SocketAddress *wsaddr = NULL;
3548 QemuOptsIter addriter;
3549 const char *addr;
3550 int to = qemu_opt_get_number(opts, "to", 0);
3551 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3552 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3553 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3554 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3555 int displaynum = -1;
3556 int ret = -1;
3558 *retsaddr = NULL;
3559 *retnsaddr = 0;
3560 *retwsaddr = NULL;
3561 *retnwsaddr = 0;
3563 addr = qemu_opt_get(opts, "vnc");
3564 if (addr == NULL || g_str_equal(addr, "none")) {
3565 ret = 0;
3566 goto cleanup;
3568 if (qemu_opt_get(opts, "websocket") &&
3569 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3570 error_setg(errp,
3571 "SHA1 hash support is required for websockets");
3572 goto cleanup;
3575 qemu_opt_iter_init(&addriter, opts, "vnc");
3576 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3577 int rv;
3578 rv = vnc_display_get_address(addr, false, reverse, 0, to,
3579 has_ipv4, has_ipv6,
3580 ipv4, ipv6,
3581 &saddr, errp);
3582 if (rv < 0) {
3583 goto cleanup;
3585 /* Historical compat - first listen address can be used
3586 * to set the default websocket port
3588 if (displaynum == -1) {
3589 displaynum = rv;
3591 *retsaddr = g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1);
3592 (*retsaddr)[(*retnsaddr)++] = saddr;
3595 /* If we had multiple primary displays, we don't do defaults
3596 * for websocket, and require explicit config instead. */
3597 if (*retnsaddr > 1) {
3598 displaynum = -1;
3601 qemu_opt_iter_init(&addriter, opts, "websocket");
3602 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3603 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
3604 has_ipv4, has_ipv6,
3605 ipv4, ipv6,
3606 &wsaddr, errp) < 0) {
3607 goto cleanup;
3610 /* Historical compat - if only a single listen address was
3611 * provided, then this is used to set the default listen
3612 * address for websocket too
3614 if (*retnsaddr == 1 &&
3615 (*retsaddr)[0]->type == SOCKET_ADDRESS_TYPE_INET &&
3616 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3617 g_str_equal(wsaddr->u.inet.host, "") &&
3618 !g_str_equal((*retsaddr)[0]->u.inet.host, "")) {
3619 g_free(wsaddr->u.inet.host);
3620 wsaddr->u.inet.host = g_strdup((*retsaddr)[0]->u.inet.host);
3623 *retwsaddr = g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + 1);
3624 (*retwsaddr)[(*retnwsaddr)++] = wsaddr;
3627 ret = 0;
3628 cleanup:
3629 if (ret < 0) {
3630 vnc_free_addresses(retsaddr, retnsaddr);
3631 vnc_free_addresses(retwsaddr, retnwsaddr);
3633 return ret;
3636 static int vnc_display_connect(VncDisplay *vd,
3637 SocketAddress **saddr,
3638 size_t nsaddr,
3639 SocketAddress **wsaddr,
3640 size_t nwsaddr,
3641 Error **errp)
3643 /* connect to viewer */
3644 QIOChannelSocket *sioc = NULL;
3645 if (nwsaddr != 0) {
3646 error_setg(errp, "Cannot use websockets in reverse mode");
3647 return -1;
3649 if (nsaddr != 1) {
3650 error_setg(errp, "Expected a single address in reverse mode");
3651 return -1;
3653 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3654 vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_TYPE_UNIX;
3655 sioc = qio_channel_socket_new();
3656 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
3657 if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {
3658 return -1;
3660 vnc_connect(vd, sioc, false, false);
3661 object_unref(OBJECT(sioc));
3662 return 0;
3666 static int vnc_display_listen_addr(VncDisplay *vd,
3667 SocketAddress *addr,
3668 const char *name,
3669 QIOChannelSocket ***lsock,
3670 guint **lsock_tag,
3671 size_t *nlsock,
3672 Error **errp)
3674 QIODNSResolver *resolver = qio_dns_resolver_get_instance();
3675 SocketAddress **rawaddrs = NULL;
3676 size_t nrawaddrs = 0;
3677 Error *listenerr = NULL;
3678 bool listening = false;
3679 size_t i;
3681 if (qio_dns_resolver_lookup_sync(resolver, addr, &nrawaddrs,
3682 &rawaddrs, errp) < 0) {
3683 return -1;
3686 for (i = 0; i < nrawaddrs; i++) {
3687 QIOChannelSocket *sioc = qio_channel_socket_new();
3689 qio_channel_set_name(QIO_CHANNEL(sioc), name);
3690 if (qio_channel_socket_listen_sync(
3691 sioc, rawaddrs[i], listenerr == NULL ? &listenerr : NULL) < 0) {
3692 object_unref(OBJECT(sioc));
3693 continue;
3695 listening = true;
3696 (*nlsock)++;
3697 *lsock = g_renew(QIOChannelSocket *, *lsock, *nlsock);
3698 *lsock_tag = g_renew(guint, *lsock_tag, *nlsock);
3700 (*lsock)[*nlsock - 1] = sioc;
3701 (*lsock_tag)[*nlsock - 1] = 0;
3704 for (i = 0; i < nrawaddrs; i++) {
3705 qapi_free_SocketAddress(rawaddrs[i]);
3707 g_free(rawaddrs);
3709 if (listenerr) {
3710 if (!listening) {
3711 error_propagate(errp, listenerr);
3712 return -1;
3713 } else {
3714 error_free(listenerr);
3718 for (i = 0; i < *nlsock; i++) {
3719 (*lsock_tag)[i] = qio_channel_add_watch(
3720 QIO_CHANNEL((*lsock)[i]),
3721 G_IO_IN, vnc_listen_io, vd, NULL);
3724 return 0;
3728 static int vnc_display_listen(VncDisplay *vd,
3729 SocketAddress **saddr,
3730 size_t nsaddr,
3731 SocketAddress **wsaddr,
3732 size_t nwsaddr,
3733 Error **errp)
3735 size_t i;
3737 for (i = 0; i < nsaddr; i++) {
3738 if (vnc_display_listen_addr(vd, saddr[i],
3739 "vnc-listen",
3740 &vd->lsock,
3741 &vd->lsock_tag,
3742 &vd->nlsock,
3743 errp) < 0) {
3744 return -1;
3747 for (i = 0; i < nwsaddr; i++) {
3748 if (vnc_display_listen_addr(vd, wsaddr[i],
3749 "vnc-ws-listen",
3750 &vd->lwebsock,
3751 &vd->lwebsock_tag,
3752 &vd->nlwebsock,
3753 errp) < 0) {
3754 return -1;
3758 return 0;
3762 void vnc_display_open(const char *id, Error **errp)
3764 VncDisplay *vd = vnc_display_find(id);
3765 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3766 SocketAddress **saddr = NULL, **wsaddr = NULL;
3767 size_t nsaddr, nwsaddr;
3768 const char *share, *device_id;
3769 QemuConsole *con;
3770 bool password = false;
3771 bool reverse = false;
3772 const char *credid;
3773 bool sasl = false;
3774 #ifdef CONFIG_VNC_SASL
3775 int saslErr;
3776 #endif
3777 int acl = 0;
3778 int lock_key_sync = 1;
3779 int key_delay_ms;
3781 if (!vd) {
3782 error_setg(errp, "VNC display not active");
3783 return;
3785 vnc_display_close(vd);
3787 if (!opts) {
3788 return;
3791 reverse = qemu_opt_get_bool(opts, "reverse", false);
3792 if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
3793 &wsaddr, &nwsaddr, errp) < 0) {
3794 goto fail;
3797 password = qemu_opt_get_bool(opts, "password", false);
3798 if (password) {
3799 if (fips_get_state()) {
3800 error_setg(errp,
3801 "VNC password auth disabled due to FIPS mode, "
3802 "consider using the VeNCrypt or SASL authentication "
3803 "methods as an alternative");
3804 goto fail;
3806 if (!qcrypto_cipher_supports(
3807 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
3808 error_setg(errp,
3809 "Cipher backend does not support DES RFB algorithm");
3810 goto fail;
3814 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3815 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 10);
3816 sasl = qemu_opt_get_bool(opts, "sasl", false);
3817 #ifndef CONFIG_VNC_SASL
3818 if (sasl) {
3819 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3820 goto fail;
3822 #endif /* CONFIG_VNC_SASL */
3823 credid = qemu_opt_get(opts, "tls-creds");
3824 if (credid) {
3825 Object *creds;
3826 if (qemu_opt_get(opts, "tls") ||
3827 qemu_opt_get(opts, "x509") ||
3828 qemu_opt_get(opts, "x509verify")) {
3829 error_setg(errp,
3830 "'tls-creds' parameter is mutually exclusive with "
3831 "'tls', 'x509' and 'x509verify' parameters");
3832 goto fail;
3835 creds = object_resolve_path_component(
3836 object_get_objects_root(), credid);
3837 if (!creds) {
3838 error_setg(errp, "No TLS credentials with id '%s'",
3839 credid);
3840 goto fail;
3842 vd->tlscreds = (QCryptoTLSCreds *)
3843 object_dynamic_cast(creds,
3844 TYPE_QCRYPTO_TLS_CREDS);
3845 if (!vd->tlscreds) {
3846 error_setg(errp, "Object with id '%s' is not TLS credentials",
3847 credid);
3848 goto fail;
3850 object_ref(OBJECT(vd->tlscreds));
3852 if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3853 error_setg(errp,
3854 "Expecting TLS credentials with a server endpoint");
3855 goto fail;
3857 } else {
3858 const char *path;
3859 bool tls = false, x509 = false, x509verify = false;
3860 tls = qemu_opt_get_bool(opts, "tls", false);
3861 if (tls) {
3862 path = qemu_opt_get(opts, "x509");
3864 if (path) {
3865 x509 = true;
3866 } else {
3867 path = qemu_opt_get(opts, "x509verify");
3868 if (path) {
3869 x509 = true;
3870 x509verify = true;
3873 vd->tlscreds = vnc_display_create_creds(x509,
3874 x509verify,
3875 path,
3876 vd->id,
3877 errp);
3878 if (!vd->tlscreds) {
3879 goto fail;
3883 acl = qemu_opt_get_bool(opts, "acl", false);
3885 share = qemu_opt_get(opts, "share");
3886 if (share) {
3887 if (strcmp(share, "ignore") == 0) {
3888 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
3889 } else if (strcmp(share, "allow-exclusive") == 0) {
3890 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3891 } else if (strcmp(share, "force-shared") == 0) {
3892 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3893 } else {
3894 error_setg(errp, "unknown vnc share= option");
3895 goto fail;
3897 } else {
3898 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3900 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3902 #ifdef CONFIG_VNC_JPEG
3903 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
3904 #endif
3905 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3906 /* adaptive updates are only used with tight encoding and
3907 * if lossy updates are enabled so we can disable all the
3908 * calculations otherwise */
3909 if (!vd->lossy) {
3910 vd->non_adaptive = true;
3913 if (acl) {
3914 if (strcmp(vd->id, "default") == 0) {
3915 vd->tlsaclname = g_strdup("vnc.x509dname");
3916 } else {
3917 vd->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vd->id);
3919 qemu_acl_init(vd->tlsaclname);
3921 #ifdef CONFIG_VNC_SASL
3922 if (acl && sasl) {
3923 char *aclname;
3925 if (strcmp(vd->id, "default") == 0) {
3926 aclname = g_strdup("vnc.username");
3927 } else {
3928 aclname = g_strdup_printf("vnc.%s.username", vd->id);
3930 vd->sasl.acl = qemu_acl_init(aclname);
3931 g_free(aclname);
3933 #endif
3935 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
3936 vd->tlscreds, password,
3937 sasl, false, errp) < 0) {
3938 goto fail;
3940 trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
3942 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
3943 vd->tlscreds, password,
3944 sasl, true, errp) < 0) {
3945 goto fail;
3947 trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
3949 #ifdef CONFIG_VNC_SASL
3950 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3951 error_setg(errp, "Failed to initialize SASL auth: %s",
3952 sasl_errstring(saslErr, NULL, NULL));
3953 goto fail;
3955 #endif
3956 vd->lock_key_sync = lock_key_sync;
3957 if (lock_key_sync) {
3958 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
3960 vd->ledstate = 0;
3961 vd->key_delay_ms = key_delay_ms;
3963 device_id = qemu_opt_get(opts, "display");
3964 if (device_id) {
3965 int head = qemu_opt_get_number(opts, "head", 0);
3966 Error *err = NULL;
3968 con = qemu_console_lookup_by_device_name(device_id, head, &err);
3969 if (err) {
3970 error_propagate(errp, err);
3971 goto fail;
3973 } else {
3974 con = NULL;
3977 if (con != vd->dcl.con) {
3978 unregister_displaychangelistener(&vd->dcl);
3979 vd->dcl.con = con;
3980 register_displaychangelistener(&vd->dcl);
3983 if (saddr == NULL) {
3984 goto cleanup;
3987 if (reverse) {
3988 if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
3989 goto fail;
3991 } else {
3992 if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
3993 goto fail;
3997 if (qemu_opt_get(opts, "to")) {
3998 vnc_display_print_local_addr(vd);
4001 cleanup:
4002 vnc_free_addresses(&saddr, &nsaddr);
4003 vnc_free_addresses(&wsaddr, &nwsaddr);
4004 return;
4006 fail:
4007 vnc_display_close(vd);
4008 goto cleanup;
4011 void vnc_display_add_client(const char *id, int csock, bool skipauth)
4013 VncDisplay *vd = vnc_display_find(id);
4014 QIOChannelSocket *sioc;
4016 if (!vd) {
4017 return;
4020 sioc = qio_channel_socket_new_fd(csock, NULL);
4021 if (sioc) {
4022 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
4023 vnc_connect(vd, sioc, skipauth, false);
4024 object_unref(OBJECT(sioc));
4028 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
4030 int i = 2;
4031 char *id;
4033 id = g_strdup("default");
4034 while (qemu_opts_find(olist, id)) {
4035 g_free(id);
4036 id = g_strdup_printf("vnc%d", i++);
4038 qemu_opts_set_id(opts, id);
4041 QemuOpts *vnc_parse(const char *str, Error **errp)
4043 QemuOptsList *olist = qemu_find_opts("vnc");
4044 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
4045 const char *id;
4047 if (!opts) {
4048 return NULL;
4051 id = qemu_opts_id(opts);
4052 if (!id) {
4053 /* auto-assign id if not present */
4054 vnc_auto_assign_id(olist, opts);
4056 return opts;
4059 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
4061 Error *local_err = NULL;
4062 char *id = (char *)qemu_opts_id(opts);
4064 assert(id);
4065 vnc_display_init(id);
4066 vnc_display_open(id, &local_err);
4067 if (local_err != NULL) {
4068 error_reportf_err(local_err, "Failed to start VNC server: ");
4069 exit(1);
4071 return 0;
4074 static void vnc_register_config(void)
4076 qemu_add_opts(&qemu_vnc_opts);
4078 opts_init(vnc_register_config);