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
27 #include "qemu/osdep.h"
31 #include "sysemu/sysemu.h"
32 #include "qemu/error-report.h"
33 #include "qemu/sockets.h"
34 #include "qemu/timer.h"
36 #include "qemu/config-file.h"
37 #include "qapi/qmp/qerror.h"
38 #include "qapi/qmp/types.h"
39 #include "qmp-commands.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
)
67 static const char *mn
[] = {
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
]);
78 switch (vs
->share_mode
) {
79 case VNC_SHARE_MODE_CONNECTING
:
80 vs
->vd
->num_connecting
--;
82 case VNC_SHARE_MODE_SHARED
:
85 case VNC_SHARE_MODE_EXCLUSIVE
:
86 vs
->vd
->num_exclusive
--;
92 vs
->share_mode
= mode
;
94 switch (vs
->share_mode
) {
95 case VNC_SHARE_MODE_CONNECTING
:
96 vs
->vd
->num_connecting
++;
98 case VNC_SHARE_MODE_SHARED
:
101 case VNC_SHARE_MODE_EXCLUSIVE
:
102 vs
->vd
->num_exclusive
++;
110 static void vnc_init_basic_info(SocketAddress
*addr
,
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
;
121 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
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
;
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
));
143 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket
*ioc
,
147 SocketAddress
*addr
= NULL
;
150 error_setg(errp
, "No listener socket available");
154 addr
= qio_channel_socket_get_local_address(ioc
, errp
);
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
,
167 SocketAddress
*addr
= NULL
;
169 addr
= qio_channel_socket_get_remote_address(ioc
, errp
);
174 vnc_init_basic_info(addr
, info
, errp
);
175 qapi_free_SocketAddress(addr
);
178 static const char *vnc_auth_name(VncDisplay
*vd
) {
180 case VNC_AUTH_INVALID
:
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";
225 static VncServerInfo
*vnc_server_info_get(VncDisplay
*vd
)
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
));
240 qapi_free_VncServerInfo(info
);
247 static void vnc_client_cache_auth(VncState
*client
)
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
);
268 static void vnc_client_cache_addr(VncState
*client
)
272 client
->info
= g_malloc0(sizeof(*client
->info
));
273 vnc_init_basic_info_from_remote_addr(client
->sioc
,
274 qapi_VncClientInfo_base(client
->info
),
277 qapi_free_VncClientInfo(client
->info
);
283 static void vnc_qmp_event(VncState
*vs
, QAPIEvent event
)
291 si
= vnc_server_info_get(vs
->vd
);
297 case QAPI_EVENT_VNC_CONNECTED
:
298 qapi_event_send_vnc_connected(si
, qapi_VncClientInfo_base(vs
->info
),
301 case QAPI_EVENT_VNC_INITIALIZED
:
302 qapi_event_send_vnc_initialized(si
, vs
->info
, &error_abort
);
304 case QAPI_EVENT_VNC_DISCONNECTED
:
305 qapi_event_send_vnc_disconnected(si
, vs
->info
, &error_abort
);
311 qapi_free_VncServerInfo(si
);
314 static VncClientInfo
*qmp_query_vnc_client(const VncState
*client
)
319 info
= g_malloc0(sizeof(*info
));
321 vnc_init_basic_info_from_remote_addr(client
->sioc
,
322 qapi_VncClientInfo_base(info
),
326 qapi_free_VncClientInfo(info
);
330 info
->websocket
= client
->websocket
;
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
);
346 static VncDisplay
*vnc_display_find(const char *id
)
351 return QTAILQ_FIRST(&vnc_displays
);
353 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
354 if (strcmp(id
, vd
->id
) == 0) {
361 static VncClientInfoList
*qmp_query_client_list(VncDisplay
*vd
)
363 VncClientInfoList
*cinfo
, *prev
= NULL
;
366 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
367 cinfo
= g_new0(VncClientInfoList
, 1);
368 cinfo
->value
= qmp_query_vnc_client(client
);
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;
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
) {
394 addr
= qio_channel_socket_get_local_address(vd
->lsock
[0], errp
);
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
;
406 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
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
;
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
));
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
);
437 qapi_free_SocketAddress(addr
);
438 qapi_free_VncInfo(info
);
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
,
452 VncServerInfo2List
*prev
)
454 VncServerInfo2List
*list
;
455 VncServerInfo2
*info
;
459 addr
= qio_channel_socket_get_local_address(ioc
, &err
);
465 info
= g_new0(VncServerInfo2
, 1);
466 vnc_init_basic_info(addr
, qapi_VncServerInfo2_base(info
), &err
);
467 qapi_free_SocketAddress(addr
);
469 qapi_free_VncServerInfo2(info
);
473 info
->websocket
= websocket
;
475 qmp_query_auth(auth
, subauth
, &info
->auth
,
476 &info
->vencrypt
, &info
->has_vencrypt
);
478 list
= g_new0(VncServerInfo2List
, 1);
484 static void qmp_query_auth(int auth
, int subauth
,
485 VncPrimaryAuth
*qmp_auth
,
486 VncVencryptSubAuth
*qmp_vencrypt
,
487 bool *qmp_has_vencrypt
)
491 *qmp_auth
= VNC_PRIMARY_AUTH_VNC
;
494 *qmp_auth
= VNC_PRIMARY_AUTH_RA2
;
497 *qmp_auth
= VNC_PRIMARY_AUTH_RA2NE
;
500 *qmp_auth
= VNC_PRIMARY_AUTH_TIGHT
;
503 *qmp_auth
= VNC_PRIMARY_AUTH_ULTRA
;
506 *qmp_auth
= VNC_PRIMARY_AUTH_TLS
;
508 case VNC_AUTH_VENCRYPT
:
509 *qmp_auth
= VNC_PRIMARY_AUTH_VENCRYPT
;
510 *qmp_has_vencrypt
= true;
512 case VNC_AUTH_VENCRYPT_PLAIN
:
513 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_PLAIN
;
515 case VNC_AUTH_VENCRYPT_TLSNONE
:
516 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_NONE
;
518 case VNC_AUTH_VENCRYPT_TLSVNC
:
519 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_VNC
;
521 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
522 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN
;
524 case VNC_AUTH_VENCRYPT_X509NONE
:
525 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_NONE
;
527 case VNC_AUTH_VENCRYPT_X509VNC
:
528 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_VNC
;
530 case VNC_AUTH_VENCRYPT_X509PLAIN
:
531 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_PLAIN
;
533 case VNC_AUTH_VENCRYPT_TLSSASL
:
534 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_SASL
;
536 case VNC_AUTH_VENCRYPT_X509SASL
:
537 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_SASL
;
540 *qmp_has_vencrypt
= false;
545 *qmp_auth
= VNC_PRIMARY_AUTH_SASL
;
549 *qmp_auth
= VNC_PRIMARY_AUTH_NONE
;
554 VncInfo2List
*qmp_query_vnc_servers(Error
**errp
)
556 VncInfo2List
*item
, *prev
= NULL
;
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
);
569 dev
= DEVICE(object_property_get_link(OBJECT(vd
->dcl
.con
),
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);
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
, bool sync
);
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
,
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
),
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
);
635 w
= MIN(x
+ w
, width
) - x
;
636 h
= MIN(y
+ h
, height
);
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
,
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
)) {
670 if (vs
->client_width
== pixman_image_get_width(vs
->vd
->server
) &&
671 vs
->client_height
== pixman_image_get_height(vs
->vd
->server
)) {
674 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
675 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
677 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
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
);
686 static void vnc_abort_display_jobs(VncDisplay
*vd
)
690 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
693 vnc_unlock_output(vs
);
695 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
698 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
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
)
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
;
720 static void vnc_update_server_surface(VncDisplay
*vd
)
724 qemu_pixman_image_unref(vd
->server
);
727 if (QTAILQ_EMPTY(&vd
->clients
)) {
731 width
= vnc_width(vd
);
732 height
= vnc_height(vd
);
733 vd
->server
= pixman_image_create_bits(VNC_SERVER_FB_FORMAT
,
737 memset(vd
->guest
.dirty
, 0x00, sizeof(vd
->guest
.dirty
));
738 vnc_set_area_dirty(vd
->guest
.dirty
, vd
, 0, 0,
742 static void vnc_dpy_switch(DisplayChangeListener
*dcl
,
743 DisplaySurface
*surface
)
745 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
748 vnc_abort_display_jobs(vd
);
752 vnc_update_server_surface(vd
);
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
) {
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,
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
)
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;
789 # error need some bits here if you change VNC_SERVER_FB_FORMAT
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
) {
824 static void vnc_write_pixels_generic(VncState
*vs
,
825 void *pixels1
, int size
)
829 if (VNC_SERVER_FB_BYTES
== 4) {
830 uint32_t *pixels
= pixels1
;
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
)
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
);
854 int vnc_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
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
);
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
);
868 case VNC_ENCODING_TIGHT
:
869 n
= vnc_tight_send_framebuffer_update(vs
, x
, y
, w
, h
);
871 case VNC_ENCODING_TIGHT_PNG
:
872 n
= vnc_tight_png_send_framebuffer_update(vs
, x
, y
, w
, h
);
874 case VNC_ENCODING_ZRLE
:
875 n
= vnc_zrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
877 case VNC_ENCODING_ZYWRLE
:
878 n
= vnc_zywrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
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
;
895 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
896 n
= vnc_raw_send_framebuffer_update(vs
, x
, y
, w
, h
);
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
;
913 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
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
);
929 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
932 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
935 cursor_put(vd
->cursor
);
936 g_free(vd
->cursor_mask
);
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
)
954 for (h
= 1; h
< (height
- y
); h
++) {
955 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
958 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
964 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
)
966 if (vs
->disconnecting
) {
967 vnc_disconnect_finish(vs
);
971 vs
->has_dirty
+= has_dirty
;
972 if (vs
->need_update
&& !vs
->disconnecting
) {
973 VncDisplay
*vd
= vs
->vd
;
979 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
980 /* kernel send buffers are full -> drop frames to throttle */
983 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
987 * Send screen updates to the vnc client using the server
988 * surface and server dirty map. guest surface updates
989 * happening in parallel don't disturb us, the next pass will
990 * send them to the client.
992 job
= vnc_job_new(vs
);
994 height
= pixman_image_get_height(vd
->server
);
995 width
= pixman_image_get_width(vd
->server
);
1001 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1002 height
* VNC_DIRTY_BPL(vs
),
1003 y
* VNC_DIRTY_BPL(vs
));
1004 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1005 /* no more dirty bits */
1008 y
= offset
/ VNC_DIRTY_BPL(vs
);
1009 x
= offset
% VNC_DIRTY_BPL(vs
);
1010 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1011 VNC_DIRTY_BPL(vs
), x
);
1012 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1013 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1014 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1016 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1017 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1019 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1031 vs
->force_update
= 0;
1036 if (vs
->disconnecting
) {
1037 vnc_disconnect_finish(vs
);
1046 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1048 VncState
*vs
= opaque
;
1051 case AUD_CNOTIFY_DISABLE
:
1052 vnc_lock_output(vs
);
1053 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1054 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1055 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1056 vnc_unlock_output(vs
);
1060 case AUD_CNOTIFY_ENABLE
:
1061 vnc_lock_output(vs
);
1062 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1063 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1064 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1065 vnc_unlock_output(vs
);
1071 static void audio_capture_destroy(void *opaque
)
1075 static void audio_capture(void *opaque
, void *buf
, int size
)
1077 VncState
*vs
= opaque
;
1079 vnc_lock_output(vs
);
1080 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1081 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1082 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1083 vnc_write_u32(vs
, size
);
1084 vnc_write(vs
, buf
, size
);
1085 vnc_unlock_output(vs
);
1089 static void audio_add(VncState
*vs
)
1091 struct audio_capture_ops ops
;
1093 if (vs
->audio_cap
) {
1094 error_report("audio already running");
1098 ops
.notify
= audio_capture_notify
;
1099 ops
.destroy
= audio_capture_destroy
;
1100 ops
.capture
= audio_capture
;
1102 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1103 if (!vs
->audio_cap
) {
1104 error_report("Failed to add audio capture");
1108 static void audio_del(VncState
*vs
)
1110 if (vs
->audio_cap
) {
1111 AUD_del_capture(vs
->audio_cap
, vs
);
1112 vs
->audio_cap
= NULL
;
1116 static void vnc_disconnect_start(VncState
*vs
)
1118 if (vs
->disconnecting
) {
1121 trace_vnc_client_disconnect_start(vs
, vs
->ioc
);
1122 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1124 g_source_remove(vs
->ioc_tag
);
1127 qio_channel_close(vs
->ioc
, NULL
);
1128 vs
->disconnecting
= TRUE
;
1131 void vnc_disconnect_finish(VncState
*vs
)
1135 trace_vnc_client_disconnect_finish(vs
, vs
->ioc
);
1137 vnc_jobs_join(vs
); /* Wait encoding jobs */
1139 vnc_lock_output(vs
);
1140 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1142 buffer_free(&vs
->input
);
1143 buffer_free(&vs
->output
);
1145 qapi_free_VncClientInfo(vs
->info
);
1148 vnc_tight_clear(vs
);
1151 #ifdef CONFIG_VNC_SASL
1152 vnc_sasl_client_cleanup(vs
);
1153 #endif /* CONFIG_VNC_SASL */
1155 vnc_release_modifiers(vs
);
1157 if (vs
->mouse_mode_notifier
.notify
!= NULL
) {
1158 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1160 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1161 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1162 /* last client gone */
1163 vnc_update_server_surface(vs
->vd
);
1166 vnc_unlock_output(vs
);
1168 qemu_mutex_destroy(&vs
->output_mutex
);
1169 if (vs
->bh
!= NULL
) {
1170 qemu_bh_delete(vs
->bh
);
1172 buffer_free(&vs
->jobs_buffer
);
1174 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1175 g_free(vs
->lossy_rect
[i
]);
1177 g_free(vs
->lossy_rect
);
1179 object_unref(OBJECT(vs
->ioc
));
1181 object_unref(OBJECT(vs
->sioc
));
1186 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1190 trace_vnc_client_eof(vs
, vs
->ioc
);
1191 vnc_disconnect_start(vs
);
1192 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1193 trace_vnc_client_io_error(vs
, vs
->ioc
,
1194 errp
? error_get_pretty(*errp
) :
1196 vnc_disconnect_start(vs
);
1209 void vnc_client_error(VncState
*vs
)
1211 VNC_DEBUG("Closing down client sock: protocol error\n");
1212 vnc_disconnect_start(vs
);
1217 * Called to write a chunk of data to the client socket. The data may
1218 * be the raw data, or may have already been encoded by SASL.
1219 * The data will be written either straight onto the socket, or
1220 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1222 * NB, it is theoretically possible to have 2 layers of encryption,
1223 * both SASL, and this TLS layer. It is highly unlikely in practice
1224 * though, since SASL encryption will typically be a no-op if TLS
1227 * Returns the number of bytes written, which may be less than
1228 * the requested 'datalen' if the socket would block. Returns
1229 * -1 on error, and disconnects the client socket.
1231 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1235 ret
= qio_channel_write(
1236 vs
->ioc
, (const char *)data
, datalen
, &err
);
1237 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1238 return vnc_client_io_error(vs
, ret
, &err
);
1243 * Called to write buffered data to the client socket, when not
1244 * using any SASL SSF encryption layers. Will write as much data
1245 * as possible without blocking. If all buffered data is written,
1246 * will switch the FD poll() handler back to read monitoring.
1248 * Returns the number of bytes written, which may be less than
1249 * the buffered output data if the socket would block. Returns
1250 * -1 on error, and disconnects the client socket.
1252 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1256 #ifdef CONFIG_VNC_SASL
1257 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1258 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1259 vs
->sasl
.waitWriteSSF
);
1261 if (vs
->sasl
.conn
&&
1263 vs
->sasl
.waitWriteSSF
) {
1264 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1266 vs
->sasl
.waitWriteSSF
-= ret
;
1268 #endif /* CONFIG_VNC_SASL */
1269 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1273 buffer_advance(&vs
->output
, ret
);
1275 if (vs
->output
.offset
== 0) {
1277 g_source_remove(vs
->ioc_tag
);
1279 vs
->ioc_tag
= qio_channel_add_watch(
1280 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1288 * First function called whenever there is data to be written to
1289 * the client socket. Will delegate actual work according to whether
1290 * SASL SSF layers are enabled (thus requiring encryption calls)
1292 static void vnc_client_write_locked(VncState
*vs
)
1294 #ifdef CONFIG_VNC_SASL
1295 if (vs
->sasl
.conn
&&
1297 !vs
->sasl
.waitWriteSSF
) {
1298 vnc_client_write_sasl(vs
);
1300 #endif /* CONFIG_VNC_SASL */
1302 vnc_client_write_plain(vs
);
1306 static void vnc_client_write(VncState
*vs
)
1309 vnc_lock_output(vs
);
1310 if (vs
->output
.offset
) {
1311 vnc_client_write_locked(vs
);
1312 } else if (vs
->ioc
!= NULL
) {
1314 g_source_remove(vs
->ioc_tag
);
1316 vs
->ioc_tag
= qio_channel_add_watch(
1317 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1319 vnc_unlock_output(vs
);
1322 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1324 vs
->read_handler
= func
;
1325 vs
->read_handler_expect
= expecting
;
1330 * Called to read a chunk of data from the client socket. The data may
1331 * be the raw data, or may need to be further decoded by SASL.
1332 * The data will be read either straight from to the socket, or
1333 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1335 * NB, it is theoretically possible to have 2 layers of encryption,
1336 * both SASL, and this TLS layer. It is highly unlikely in practice
1337 * though, since SASL encryption will typically be a no-op if TLS
1340 * Returns the number of bytes read, which may be less than
1341 * the requested 'datalen' if the socket would block. Returns
1342 * -1 on error, and disconnects the client socket.
1344 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1348 ret
= qio_channel_read(
1349 vs
->ioc
, (char *)data
, datalen
, &err
);
1350 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1351 return vnc_client_io_error(vs
, ret
, &err
);
1356 * Called to read data from the client socket to the input buffer,
1357 * when not using any SASL SSF encryption layers. Will read as much
1358 * data as possible without blocking.
1360 * Returns the number of bytes read. Returns -1 on error, and
1361 * disconnects the client socket.
1363 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1366 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1367 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1368 buffer_reserve(&vs
->input
, 4096);
1369 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1372 vs
->input
.offset
+= ret
;
1376 static void vnc_jobs_bh(void *opaque
)
1378 VncState
*vs
= opaque
;
1380 vnc_jobs_consume_buffer(vs
);
1384 * First function called whenever there is more data to be read from
1385 * the client socket. Will delegate actual work according to whether
1386 * SASL SSF layers are enabled (thus requiring decryption calls)
1387 * Returns 0 on success, -1 if client disconnected
1389 static int vnc_client_read(VncState
*vs
)
1393 #ifdef CONFIG_VNC_SASL
1394 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1395 ret
= vnc_client_read_sasl(vs
);
1397 #endif /* CONFIG_VNC_SASL */
1398 ret
= vnc_client_read_plain(vs
);
1400 if (vs
->disconnecting
) {
1401 vnc_disconnect_finish(vs
);
1407 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1408 size_t len
= vs
->read_handler_expect
;
1411 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1412 if (vs
->disconnecting
) {
1413 vnc_disconnect_finish(vs
);
1418 buffer_advance(&vs
->input
, len
);
1420 vs
->read_handler_expect
= ret
;
1426 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1427 GIOCondition condition
, void *opaque
)
1429 VncState
*vs
= opaque
;
1430 if (condition
& G_IO_IN
) {
1431 if (vnc_client_read(vs
) < 0) {
1435 if (condition
& G_IO_OUT
) {
1436 vnc_client_write(vs
);
1442 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1444 buffer_reserve(&vs
->output
, len
);
1446 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1448 g_source_remove(vs
->ioc_tag
);
1450 vs
->ioc_tag
= qio_channel_add_watch(
1451 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1454 buffer_append(&vs
->output
, data
, len
);
1457 void vnc_write_s32(VncState
*vs
, int32_t value
)
1459 vnc_write_u32(vs
, *(uint32_t *)&value
);
1462 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1466 buf
[0] = (value
>> 24) & 0xFF;
1467 buf
[1] = (value
>> 16) & 0xFF;
1468 buf
[2] = (value
>> 8) & 0xFF;
1469 buf
[3] = value
& 0xFF;
1471 vnc_write(vs
, buf
, 4);
1474 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1478 buf
[0] = (value
>> 8) & 0xFF;
1479 buf
[1] = value
& 0xFF;
1481 vnc_write(vs
, buf
, 2);
1484 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1486 vnc_write(vs
, (char *)&value
, 1);
1489 void vnc_flush(VncState
*vs
)
1491 vnc_lock_output(vs
);
1492 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1493 vnc_client_write_locked(vs
);
1495 vnc_unlock_output(vs
);
1498 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1500 return data
[offset
];
1503 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1505 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1508 static int32_t read_s32(uint8_t *data
, size_t offset
)
1510 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1511 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1514 uint32_t read_u32(uint8_t *data
, size_t offset
)
1516 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1517 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1520 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1524 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1526 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1527 int absolute
= qemu_input_is_absolute();
1529 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1530 vnc_lock_output(vs
);
1531 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1532 vnc_write_u8(vs
, 0);
1533 vnc_write_u16(vs
, 1);
1534 vnc_framebuffer_update(vs
, absolute
, 0,
1535 pixman_image_get_width(vs
->vd
->server
),
1536 pixman_image_get_height(vs
->vd
->server
),
1537 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1538 vnc_unlock_output(vs
);
1541 vs
->absolute
= absolute
;
1544 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1546 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1547 [INPUT_BUTTON_LEFT
] = 0x01,
1548 [INPUT_BUTTON_MIDDLE
] = 0x02,
1549 [INPUT_BUTTON_RIGHT
] = 0x04,
1550 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1551 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1553 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1554 int width
= pixman_image_get_width(vs
->vd
->server
);
1555 int height
= pixman_image_get_height(vs
->vd
->server
);
1557 if (vs
->last_bmask
!= button_mask
) {
1558 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1559 vs
->last_bmask
= button_mask
;
1563 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, 0, width
);
1564 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, 0, height
);
1565 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1566 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1567 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1569 if (vs
->last_x
!= -1) {
1570 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1571 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1576 qemu_input_event_sync();
1579 static void reset_keys(VncState
*vs
)
1582 for(i
= 0; i
< 256; i
++) {
1583 if (vs
->modifiers_state
[i
]) {
1584 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1585 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1586 vs
->modifiers_state
[i
] = 0;
1591 static void press_key(VncState
*vs
, int keysym
)
1593 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1594 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1595 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1596 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1597 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1600 static void vnc_led_state_change(VncState
*vs
)
1602 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1606 vnc_lock_output(vs
);
1607 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1608 vnc_write_u8(vs
, 0);
1609 vnc_write_u16(vs
, 1);
1610 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1611 vnc_write_u8(vs
, vs
->vd
->ledstate
);
1612 vnc_unlock_output(vs
);
1616 static void kbd_leds(void *opaque
, int ledstate
)
1618 VncDisplay
*vd
= opaque
;
1621 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1622 (ledstate
& QEMU_NUM_LOCK_LED
),
1623 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1625 if (ledstate
== vd
->ledstate
) {
1629 vd
->ledstate
= ledstate
;
1631 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
1632 vnc_led_state_change(client
);
1636 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1638 /* QEMU console switch */
1640 case 0x2a: /* Left Shift */
1641 case 0x36: /* Right Shift */
1642 case 0x1d: /* Left CTRL */
1643 case 0x9d: /* Right CTRL */
1644 case 0x38: /* Left ALT */
1645 case 0xb8: /* Right ALT */
1647 vs
->modifiers_state
[keycode
] = 1;
1649 vs
->modifiers_state
[keycode
] = 0;
1651 case 0x02 ... 0x0a: /* '1' to '9' keys */
1652 if (vs
->vd
->dcl
.con
== NULL
&&
1653 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1654 /* Reset the modifiers sent to the current console */
1656 console_select(keycode
- 0x02);
1660 case 0x3a: /* CapsLock */
1661 case 0x45: /* NumLock */
1663 vs
->modifiers_state
[keycode
] ^= 1;
1667 /* Turn off the lock state sync logic if the client support the led
1670 if (down
&& vs
->vd
->lock_key_sync
&&
1671 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1672 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1673 /* If the numlock state needs to change then simulate an additional
1674 keypress before sending this one. This will happen if the user
1675 toggles numlock away from the VNC window.
1677 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1678 if (!vs
->modifiers_state
[0x45]) {
1679 trace_vnc_key_sync_numlock(true);
1680 vs
->modifiers_state
[0x45] = 1;
1681 press_key(vs
, 0xff7f);
1684 if (vs
->modifiers_state
[0x45]) {
1685 trace_vnc_key_sync_numlock(false);
1686 vs
->modifiers_state
[0x45] = 0;
1687 press_key(vs
, 0xff7f);
1692 if (down
&& vs
->vd
->lock_key_sync
&&
1693 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1694 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1695 /* If the capslock state needs to change then simulate an additional
1696 keypress before sending this one. This will happen if the user
1697 toggles capslock away from the VNC window.
1699 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1700 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1701 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1703 if (uppercase
== shift
) {
1704 trace_vnc_key_sync_capslock(false);
1705 vs
->modifiers_state
[0x3a] = 0;
1706 press_key(vs
, 0xffe5);
1709 if (uppercase
!= shift
) {
1710 trace_vnc_key_sync_capslock(true);
1711 vs
->modifiers_state
[0x3a] = 1;
1712 press_key(vs
, 0xffe5);
1717 if (qemu_console_is_graphic(NULL
)) {
1718 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1719 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1721 bool numlock
= vs
->modifiers_state
[0x45];
1722 bool control
= (vs
->modifiers_state
[0x1d] ||
1723 vs
->modifiers_state
[0x9d]);
1724 /* QEMU console emulation */
1727 case 0x2a: /* Left Shift */
1728 case 0x36: /* Right Shift */
1729 case 0x1d: /* Left CTRL */
1730 case 0x9d: /* Right CTRL */
1731 case 0x38: /* Left ALT */
1732 case 0xb8: /* Right ALT */
1735 kbd_put_keysym(QEMU_KEY_UP
);
1738 kbd_put_keysym(QEMU_KEY_DOWN
);
1741 kbd_put_keysym(QEMU_KEY_LEFT
);
1744 kbd_put_keysym(QEMU_KEY_RIGHT
);
1747 kbd_put_keysym(QEMU_KEY_DELETE
);
1750 kbd_put_keysym(QEMU_KEY_HOME
);
1753 kbd_put_keysym(QEMU_KEY_END
);
1756 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1759 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1763 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1766 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1769 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1772 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1775 kbd_put_keysym('5');
1778 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1781 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1784 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1787 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1790 kbd_put_keysym('0');
1793 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1797 kbd_put_keysym('/');
1800 kbd_put_keysym('*');
1803 kbd_put_keysym('-');
1806 kbd_put_keysym('+');
1809 kbd_put_keysym('\n');
1814 kbd_put_keysym(sym
& 0x1f);
1816 kbd_put_keysym(sym
);
1824 static void vnc_release_modifiers(VncState
*vs
)
1826 static const int keycodes
[] = {
1827 /* shift, control, alt keys, both left & right */
1828 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1832 if (!qemu_console_is_graphic(NULL
)) {
1835 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1836 keycode
= keycodes
[i
];
1837 if (!vs
->modifiers_state
[keycode
]) {
1840 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1841 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1845 static const char *code2name(int keycode
)
1847 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode
));
1850 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1855 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1856 lsym
= lsym
- 'A' + 'a';
1859 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1860 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1861 do_key_event(vs
, down
, keycode
, sym
);
1864 static void ext_key_event(VncState
*vs
, int down
,
1865 uint32_t sym
, uint16_t keycode
)
1867 /* if the user specifies a keyboard layout, always use it */
1868 if (keyboard_layout
) {
1869 key_event(vs
, down
, sym
);
1871 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
1872 do_key_event(vs
, down
, keycode
, sym
);
1876 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1877 int x
, int y
, int w
, int h
)
1879 vs
->need_update
= 1;
1885 vs
->force_update
= 1;
1886 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
1889 static void send_ext_key_event_ack(VncState
*vs
)
1891 vnc_lock_output(vs
);
1892 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1893 vnc_write_u8(vs
, 0);
1894 vnc_write_u16(vs
, 1);
1895 vnc_framebuffer_update(vs
, 0, 0,
1896 pixman_image_get_width(vs
->vd
->server
),
1897 pixman_image_get_height(vs
->vd
->server
),
1898 VNC_ENCODING_EXT_KEY_EVENT
);
1899 vnc_unlock_output(vs
);
1903 static void send_ext_audio_ack(VncState
*vs
)
1905 vnc_lock_output(vs
);
1906 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1907 vnc_write_u8(vs
, 0);
1908 vnc_write_u16(vs
, 1);
1909 vnc_framebuffer_update(vs
, 0, 0,
1910 pixman_image_get_width(vs
->vd
->server
),
1911 pixman_image_get_height(vs
->vd
->server
),
1912 VNC_ENCODING_AUDIO
);
1913 vnc_unlock_output(vs
);
1917 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
1920 unsigned int enc
= 0;
1923 vs
->vnc_encoding
= 0;
1924 vs
->tight
.compression
= 9;
1925 vs
->tight
.quality
= -1; /* Lossless by default */
1929 * Start from the end because the encodings are sent in order of preference.
1930 * This way the preferred encoding (first encoding defined in the array)
1931 * will be set at the end of the loop.
1933 for (i
= n_encodings
- 1; i
>= 0; i
--) {
1936 case VNC_ENCODING_RAW
:
1937 vs
->vnc_encoding
= enc
;
1939 case VNC_ENCODING_COPYRECT
:
1940 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
1942 case VNC_ENCODING_HEXTILE
:
1943 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
1944 vs
->vnc_encoding
= enc
;
1946 case VNC_ENCODING_TIGHT
:
1947 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
1948 vs
->vnc_encoding
= enc
;
1950 #ifdef CONFIG_VNC_PNG
1951 case VNC_ENCODING_TIGHT_PNG
:
1952 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
1953 vs
->vnc_encoding
= enc
;
1956 case VNC_ENCODING_ZLIB
:
1957 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
1958 vs
->vnc_encoding
= enc
;
1960 case VNC_ENCODING_ZRLE
:
1961 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
1962 vs
->vnc_encoding
= enc
;
1964 case VNC_ENCODING_ZYWRLE
:
1965 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
1966 vs
->vnc_encoding
= enc
;
1968 case VNC_ENCODING_DESKTOPRESIZE
:
1969 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
1971 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
1972 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
1974 case VNC_ENCODING_RICH_CURSOR
:
1975 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
1976 if (vs
->vd
->cursor
) {
1977 vnc_cursor_define(vs
);
1980 case VNC_ENCODING_EXT_KEY_EVENT
:
1981 send_ext_key_event_ack(vs
);
1983 case VNC_ENCODING_AUDIO
:
1984 send_ext_audio_ack(vs
);
1986 case VNC_ENCODING_WMVi
:
1987 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
1989 case VNC_ENCODING_LED_STATE
:
1990 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
1992 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
1993 vs
->tight
.compression
= (enc
& 0x0F);
1995 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
1996 if (vs
->vd
->lossy
) {
1997 vs
->tight
.quality
= (enc
& 0x0F);
2001 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2005 vnc_desktop_resize(vs
);
2006 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2007 vnc_led_state_change(vs
);
2010 static void set_pixel_conversion(VncState
*vs
)
2012 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2014 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2015 vs
->write_pixels
= vnc_write_pixels_copy
;
2016 vnc_hextile_set_pixel_conversion(vs
, 0);
2018 vs
->write_pixels
= vnc_write_pixels_generic
;
2019 vnc_hextile_set_pixel_conversion(vs
, 1);
2023 static void send_color_map(VncState
*vs
)
2027 vnc_write_u8(vs
, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES
);
2028 vnc_write_u8(vs
, 0); /* padding */
2029 vnc_write_u16(vs
, 0); /* first color */
2030 vnc_write_u16(vs
, 256); /* # of colors */
2032 for (i
= 0; i
< 256; i
++) {
2033 PixelFormat
*pf
= &vs
->client_pf
;
2035 vnc_write_u16(vs
, (((i
>> pf
->rshift
) & pf
->rmax
) << (16 - pf
->rbits
)));
2036 vnc_write_u16(vs
, (((i
>> pf
->gshift
) & pf
->gmax
) << (16 - pf
->gbits
)));
2037 vnc_write_u16(vs
, (((i
>> pf
->bshift
) & pf
->bmax
) << (16 - pf
->bbits
)));
2041 static void set_pixel_format(VncState
*vs
, int bits_per_pixel
,
2042 int big_endian_flag
, int true_color_flag
,
2043 int red_max
, int green_max
, int blue_max
,
2044 int red_shift
, int green_shift
, int blue_shift
)
2046 if (!true_color_flag
) {
2047 /* Expose a reasonable default 256 color map */
2057 switch (bits_per_pixel
) {
2063 vnc_client_error(vs
);
2067 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2068 vs
->client_pf
.rbits
= ctpopl(red_max
);
2069 vs
->client_pf
.rshift
= red_shift
;
2070 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2071 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2072 vs
->client_pf
.gbits
= ctpopl(green_max
);
2073 vs
->client_pf
.gshift
= green_shift
;
2074 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2075 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2076 vs
->client_pf
.bbits
= ctpopl(blue_max
);
2077 vs
->client_pf
.bshift
= blue_shift
;
2078 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2079 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2080 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2081 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2082 vs
->client_be
= big_endian_flag
;
2084 if (!true_color_flag
) {
2088 set_pixel_conversion(vs
);
2090 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2091 graphic_hw_update(vs
->vd
->dcl
.con
);
2094 static void pixel_format_message (VncState
*vs
) {
2095 char pad
[3] = { 0, 0, 0 };
2097 vs
->client_pf
= qemu_default_pixelformat(32);
2099 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2100 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2102 #ifdef HOST_WORDS_BIGENDIAN
2103 vnc_write_u8(vs
, 1); /* big-endian-flag */
2105 vnc_write_u8(vs
, 0); /* big-endian-flag */
2107 vnc_write_u8(vs
, 1); /* true-color-flag */
2108 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2109 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2110 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2111 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2112 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2113 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2114 vnc_write(vs
, pad
, 3); /* padding */
2116 vnc_hextile_set_pixel_conversion(vs
, 0);
2117 vs
->write_pixels
= vnc_write_pixels_copy
;
2120 static void vnc_colordepth(VncState
*vs
)
2122 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2123 /* Sending a WMVi message to notify the client*/
2124 vnc_lock_output(vs
);
2125 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2126 vnc_write_u8(vs
, 0);
2127 vnc_write_u16(vs
, 1); /* number of rects */
2128 vnc_framebuffer_update(vs
, 0, 0,
2129 pixman_image_get_width(vs
->vd
->server
),
2130 pixman_image_get_height(vs
->vd
->server
),
2132 pixel_format_message(vs
);
2133 vnc_unlock_output(vs
);
2136 set_pixel_conversion(vs
);
2140 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2144 VncDisplay
*vd
= vs
->vd
;
2147 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2151 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2155 set_pixel_format(vs
, read_u8(data
, 4),
2156 read_u8(data
, 6), read_u8(data
, 7),
2157 read_u16(data
, 8), read_u16(data
, 10),
2158 read_u16(data
, 12), read_u8(data
, 14),
2159 read_u8(data
, 15), read_u8(data
, 16));
2161 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2166 limit
= read_u16(data
, 2);
2168 return 4 + (limit
* 4);
2170 limit
= read_u16(data
, 2);
2172 for (i
= 0; i
< limit
; i
++) {
2173 int32_t val
= read_s32(data
, 4 + (i
* 4));
2174 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2177 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2179 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2183 framebuffer_update_request(vs
,
2184 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2185 read_u16(data
, 6), read_u16(data
, 8));
2187 case VNC_MSG_CLIENT_KEY_EVENT
:
2191 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2193 case VNC_MSG_CLIENT_POINTER_EVENT
:
2197 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2199 case VNC_MSG_CLIENT_CUT_TEXT
:
2204 uint32_t dlen
= read_u32(data
, 4);
2205 if (dlen
> (1 << 20)) {
2206 error_report("vnc: client_cut_text msg payload has %u bytes"
2207 " which exceeds our limit of 1MB.", dlen
);
2208 vnc_client_error(vs
);
2216 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2218 case VNC_MSG_CLIENT_QEMU
:
2222 switch (read_u8(data
, 1)) {
2223 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2227 ext_key_event(vs
, read_u16(data
, 2),
2228 read_u32(data
, 4), read_u32(data
, 8));
2230 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2234 switch (read_u16 (data
, 2)) {
2235 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2238 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2241 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2244 switch (read_u8(data
, 4)) {
2245 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2246 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2247 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2248 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2249 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2250 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2252 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2253 vnc_client_error(vs
);
2256 vs
->as
.nchannels
= read_u8(data
, 5);
2257 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2258 VNC_DEBUG("Invalid audio channel coount %d\n",
2260 vnc_client_error(vs
);
2263 vs
->as
.freq
= read_u32(data
, 6);
2266 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2267 vnc_client_error(vs
);
2273 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2274 vnc_client_error(vs
);
2279 VNC_DEBUG("Msg: %d\n", data
[0]);
2280 vnc_client_error(vs
);
2284 vnc_read_when(vs
, protocol_client_msg
, 1);
2288 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2294 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2295 switch (vs
->vd
->share_policy
) {
2296 case VNC_SHARE_POLICY_IGNORE
:
2298 * Ignore the shared flag. Nothing to do here.
2300 * Doesn't conform to the rfb spec but is traditional qemu
2301 * behavior, thus left here as option for compatibility
2305 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2307 * Policy: Allow clients ask for exclusive access.
2309 * Implementation: When a client asks for exclusive access,
2310 * disconnect all others. Shared connects are allowed as long
2311 * as no exclusive connection exists.
2313 * This is how the rfb spec suggests to handle the shared flag.
2315 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2317 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2321 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2322 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2325 vnc_disconnect_start(client
);
2328 if (mode
== VNC_SHARE_MODE_SHARED
) {
2329 if (vs
->vd
->num_exclusive
> 0) {
2330 vnc_disconnect_start(vs
);
2335 case VNC_SHARE_POLICY_FORCE_SHARED
:
2337 * Policy: Shared connects only.
2338 * Implementation: Disallow clients asking for exclusive access.
2340 * Useful for shared desktop sessions where you don't want
2341 * someone forgetting to say -shared when running the vnc
2342 * client disconnect everybody else.
2344 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2345 vnc_disconnect_start(vs
);
2350 vnc_set_share_mode(vs
, mode
);
2352 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2353 vnc_disconnect_start(vs
);
2357 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2358 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2359 vnc_write_u16(vs
, vs
->client_width
);
2360 vnc_write_u16(vs
, vs
->client_height
);
2362 pixel_format_message(vs
);
2365 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2366 if (size
> sizeof(buf
)) {
2370 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2373 vnc_write_u32(vs
, size
);
2374 vnc_write(vs
, buf
, size
);
2377 vnc_client_cache_auth(vs
);
2378 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2380 vnc_read_when(vs
, protocol_client_msg
, 1);
2385 void start_client_init(VncState
*vs
)
2387 vnc_read_when(vs
, protocol_client_init
, 1);
2390 static void make_challenge(VncState
*vs
)
2394 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2396 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2397 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2400 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2402 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2404 unsigned char key
[8];
2405 time_t now
= time(NULL
);
2406 QCryptoCipher
*cipher
= NULL
;
2409 if (!vs
->vd
->password
) {
2410 trace_vnc_auth_fail(vs
, vs
->auth
, "password is not set", "");
2413 if (vs
->vd
->expires
< now
) {
2414 trace_vnc_auth_fail(vs
, vs
->auth
, "password is expired", "");
2418 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2420 /* Calculate the expected challenge response */
2421 pwlen
= strlen(vs
->vd
->password
);
2422 for (i
=0; i
<sizeof(key
); i
++)
2423 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2425 cipher
= qcrypto_cipher_new(
2426 QCRYPTO_CIPHER_ALG_DES_RFB
,
2427 QCRYPTO_CIPHER_MODE_ECB
,
2428 key
, G_N_ELEMENTS(key
),
2431 trace_vnc_auth_fail(vs
, vs
->auth
, "cannot create cipher",
2432 error_get_pretty(err
));
2437 if (qcrypto_cipher_encrypt(cipher
,
2440 VNC_AUTH_CHALLENGE_SIZE
,
2442 trace_vnc_auth_fail(vs
, vs
->auth
, "cannot encrypt challenge response",
2443 error_get_pretty(err
));
2448 /* Compare expected vs actual challenge response */
2449 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2450 trace_vnc_auth_fail(vs
, vs
->auth
, "mis-matched challenge response", "");
2453 trace_vnc_auth_pass(vs
, vs
->auth
);
2454 vnc_write_u32(vs
, 0); /* Accept auth */
2457 start_client_init(vs
);
2460 qcrypto_cipher_free(cipher
);
2464 vnc_write_u32(vs
, 1); /* Reject auth */
2465 if (vs
->minor
>= 8) {
2466 static const char err
[] = "Authentication failed";
2467 vnc_write_u32(vs
, sizeof(err
));
2468 vnc_write(vs
, err
, sizeof(err
));
2471 vnc_client_error(vs
);
2472 qcrypto_cipher_free(cipher
);
2476 void start_auth_vnc(VncState
*vs
)
2479 /* Send client a 'random' challenge */
2480 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2483 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2487 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2489 /* We only advertise 1 auth scheme at a time, so client
2490 * must pick the one we sent. Verify this */
2491 if (data
[0] != vs
->auth
) { /* Reject auth */
2492 trace_vnc_auth_reject(vs
, vs
->auth
, (int)data
[0]);
2493 vnc_write_u32(vs
, 1);
2494 if (vs
->minor
>= 8) {
2495 static const char err
[] = "Authentication failed";
2496 vnc_write_u32(vs
, sizeof(err
));
2497 vnc_write(vs
, err
, sizeof(err
));
2499 vnc_client_error(vs
);
2500 } else { /* Accept requested auth */
2501 trace_vnc_auth_start(vs
, vs
->auth
);
2504 if (vs
->minor
>= 8) {
2505 vnc_write_u32(vs
, 0); /* Accept auth completion */
2508 trace_vnc_auth_pass(vs
, vs
->auth
);
2509 start_client_init(vs
);
2516 case VNC_AUTH_VENCRYPT
:
2517 start_auth_vencrypt(vs
);
2520 #ifdef CONFIG_VNC_SASL
2522 start_auth_sasl(vs
);
2524 #endif /* CONFIG_VNC_SASL */
2526 default: /* Should not be possible, but just in case */
2527 trace_vnc_auth_fail(vs
, vs
->auth
, "Unhandled auth method", "");
2528 vnc_write_u8(vs
, 1);
2529 if (vs
->minor
>= 8) {
2530 static const char err
[] = "Authentication failed";
2531 vnc_write_u32(vs
, sizeof(err
));
2532 vnc_write(vs
, err
, sizeof(err
));
2534 vnc_client_error(vs
);
2540 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2544 memcpy(local
, version
, 12);
2547 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2548 VNC_DEBUG("Malformed protocol version %s\n", local
);
2549 vnc_client_error(vs
);
2552 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2553 if (vs
->major
!= 3 ||
2559 VNC_DEBUG("Unsupported client version\n");
2560 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2562 vnc_client_error(vs
);
2565 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2566 * as equivalent to v3.3 by servers
2568 if (vs
->minor
== 4 || vs
->minor
== 5)
2571 if (vs
->minor
== 3) {
2572 trace_vnc_auth_start(vs
, vs
->auth
);
2573 if (vs
->auth
== VNC_AUTH_NONE
) {
2574 vnc_write_u32(vs
, vs
->auth
);
2576 trace_vnc_auth_pass(vs
, vs
->auth
);
2577 start_client_init(vs
);
2578 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2579 VNC_DEBUG("Tell client VNC auth\n");
2580 vnc_write_u32(vs
, vs
->auth
);
2584 trace_vnc_auth_fail(vs
, vs
->auth
,
2585 "Unsupported auth method for v3.3", "");
2586 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2588 vnc_client_error(vs
);
2591 vnc_write_u8(vs
, 1); /* num auth */
2592 vnc_write_u8(vs
, vs
->auth
);
2593 vnc_read_when(vs
, protocol_client_auth
, 1);
2600 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2602 struct VncSurface
*vs
= &vd
->guest
;
2604 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2607 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2611 w
= (x
+ w
) / VNC_STAT_RECT
;
2612 h
= (y
+ h
) / VNC_STAT_RECT
;
2616 for (j
= y
; j
<= h
; j
++) {
2617 for (i
= x
; i
<= w
; i
++) {
2618 vs
->lossy_rect
[j
][i
] = 1;
2623 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2626 int sty
= y
/ VNC_STAT_RECT
;
2627 int stx
= x
/ VNC_STAT_RECT
;
2630 y
= QEMU_ALIGN_DOWN(y
, VNC_STAT_RECT
);
2631 x
= QEMU_ALIGN_DOWN(x
, VNC_STAT_RECT
);
2633 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2636 /* kernel send buffers are full -> refresh later */
2637 if (vs
->output
.offset
) {
2641 if (!vs
->lossy_rect
[sty
][stx
]) {
2645 vs
->lossy_rect
[sty
][stx
] = 0;
2646 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2647 bitmap_set(vs
->dirty
[y
+ j
],
2648 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2649 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2657 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2659 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2660 pixman_image_get_width(vd
->server
));
2661 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2662 pixman_image_get_height(vd
->server
));
2667 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2668 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2669 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2671 rect
->updated
= false;
2675 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2677 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2680 vd
->guest
.last_freq_check
= *tv
;
2682 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2683 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2684 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2685 int count
= ARRAY_SIZE(rect
->times
);
2686 struct timeval min
, max
;
2688 if (!timerisset(&rect
->times
[count
- 1])) {
2692 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2693 qemu_timersub(tv
, &max
, &res
);
2695 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2697 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2698 memset(rect
->times
, 0, sizeof (rect
->times
));
2702 min
= rect
->times
[rect
->idx
];
2703 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2704 qemu_timersub(&max
, &min
, &res
);
2706 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2707 rect
->freq
/= count
;
2708 rect
->freq
= 1. / rect
->freq
;
2714 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2720 x
= QEMU_ALIGN_DOWN(x
, VNC_STAT_RECT
);
2721 y
= QEMU_ALIGN_DOWN(y
, VNC_STAT_RECT
);
2723 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2724 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2725 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2737 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2741 rect
= vnc_stat_rect(vd
, x
, y
);
2742 if (rect
->updated
) {
2745 rect
->times
[rect
->idx
] = *tv
;
2746 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2747 rect
->updated
= true;
2750 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2752 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2753 pixman_image_get_width(vd
->server
));
2754 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2755 pixman_image_get_height(vd
->server
));
2756 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2757 uint8_t *guest_row0
= NULL
, *server_row0
;
2760 pixman_image_t
*tmpbuf
= NULL
;
2762 struct timeval tv
= { 0, 0 };
2764 if (!vd
->non_adaptive
) {
2765 gettimeofday(&tv
, NULL
);
2766 has_dirty
= vnc_update_stats(vd
, &tv
);
2770 * Walk through the guest dirty map.
2771 * Check and copy modified bits from guest to server surface.
2772 * Update server dirty map.
2774 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2775 server_stride
= guest_stride
= guest_ll
=
2776 pixman_image_get_stride(vd
->server
);
2777 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2779 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2780 int width
= pixman_image_get_width(vd
->server
);
2781 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2784 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2785 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2786 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2787 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * (DIV_ROUND_UP(guest_bpp
, 8));
2789 line_bytes
= MIN(server_stride
, guest_ll
);
2793 uint8_t *guest_ptr
, *server_ptr
;
2794 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2795 height
* VNC_DIRTY_BPL(&vd
->guest
),
2796 y
* VNC_DIRTY_BPL(&vd
->guest
));
2797 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2798 /* no more dirty bits */
2801 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2802 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2804 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2806 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2807 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2808 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2810 guest_ptr
= guest_row0
+ y
* guest_stride
;
2812 guest_ptr
+= x
* cmp_bytes
;
2814 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2815 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2816 int _cmp_bytes
= cmp_bytes
;
2817 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2820 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2821 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2823 assert(_cmp_bytes
>= 0);
2824 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2827 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2828 if (!vd
->non_adaptive
) {
2829 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2832 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2833 set_bit(x
, vs
->dirty
[y
]);
2840 qemu_pixman_image_unref(tmpbuf
);
2844 static void vnc_refresh(DisplayChangeListener
*dcl
)
2846 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2848 int has_dirty
, rects
= 0;
2850 if (QTAILQ_EMPTY(&vd
->clients
)) {
2851 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2855 graphic_hw_update(vd
->dcl
.con
);
2857 if (vnc_trylock_display(vd
)) {
2858 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2862 has_dirty
= vnc_refresh_server_surface(vd
);
2863 vnc_unlock_display(vd
);
2865 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2866 rects
+= vnc_update_client(vs
, has_dirty
, false);
2867 /* vs might be free()ed here */
2870 if (has_dirty
&& rects
) {
2871 vd
->dcl
.update_interval
/= 2;
2872 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2873 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2876 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2877 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2878 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2883 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2884 bool skipauth
, bool websocket
)
2886 VncState
*vs
= g_new0(VncState
, 1);
2887 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
2890 trace_vnc_client_connect(vs
, sioc
);
2892 object_ref(OBJECT(vs
->sioc
));
2893 vs
->ioc
= QIO_CHANNEL(sioc
);
2894 object_ref(OBJECT(vs
->ioc
));
2897 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
2898 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
2899 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
2901 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
2902 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
2903 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
2904 #ifdef CONFIG_VNC_JPEG
2905 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
2907 #ifdef CONFIG_VNC_PNG
2908 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
2910 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
2911 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
2912 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
2913 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
2916 vs
->auth
= VNC_AUTH_NONE
;
2917 vs
->subauth
= VNC_AUTH_INVALID
;
2920 vs
->auth
= vd
->ws_auth
;
2921 vs
->subauth
= VNC_AUTH_INVALID
;
2923 vs
->auth
= vd
->auth
;
2924 vs
->subauth
= vd
->subauth
;
2927 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2928 sioc
, websocket
, vs
->auth
, vs
->subauth
);
2930 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
2931 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
2932 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
2935 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
2936 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2937 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
2939 g_source_remove(vs
->ioc_tag
);
2944 vs
->ioc_tag
= qio_channel_add_watch(
2945 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
2947 vs
->ioc_tag
= qio_channel_add_watch(
2948 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
2951 vs
->ioc_tag
= qio_channel_add_watch(
2952 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
2955 vnc_client_cache_addr(vs
);
2956 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
2957 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
2962 vs
->as
.freq
= 44100;
2963 vs
->as
.nchannels
= 2;
2964 vs
->as
.fmt
= AUD_FMT_S16
;
2965 vs
->as
.endianness
= 0;
2967 qemu_mutex_init(&vs
->output_mutex
);
2968 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
2970 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
2972 vnc_update_server_surface(vd
);
2975 graphic_hw_update(vd
->dcl
.con
);
2977 if (!vs
->websocket
) {
2978 vnc_start_protocol(vs
);
2981 if (vd
->num_connecting
> vd
->connections_limit
) {
2982 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2983 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
2984 vnc_disconnect_start(vs
);
2991 void vnc_start_protocol(VncState
*vs
)
2993 vnc_write(vs
, "RFB 003.008\n", 12);
2995 vnc_read_when(vs
, protocol_version
, 12);
2997 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
2998 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
3001 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
3002 GIOCondition condition
,
3005 VncDisplay
*vd
= opaque
;
3006 QIOChannelSocket
*sioc
= NULL
;
3008 bool isWebsock
= false;
3011 for (i
= 0; i
< vd
->nlwebsock
; i
++) {
3012 if (ioc
== QIO_CHANNEL(vd
->lwebsock
[i
])) {
3018 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3020 qio_channel_set_name(QIO_CHANNEL(sioc
),
3021 isWebsock
? "vnc-ws-server" : "vnc-server");
3022 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3023 vnc_connect(vd
, sioc
, false, isWebsock
);
3024 object_unref(OBJECT(sioc
));
3026 /* client probably closed connection before we got there */
3033 static const DisplayChangeListenerOps dcl_ops
= {
3035 .dpy_refresh
= vnc_refresh
,
3036 .dpy_gfx_update
= vnc_dpy_update
,
3037 .dpy_gfx_switch
= vnc_dpy_switch
,
3038 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3039 .dpy_mouse_set
= vnc_mouse_set
,
3040 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3043 void vnc_display_init(const char *id
)
3047 if (vnc_display_find(id
) != NULL
) {
3050 vd
= g_malloc0(sizeof(*vd
));
3052 vd
->id
= strdup(id
);
3053 QTAILQ_INSERT_TAIL(&vnc_displays
, vd
, next
);
3055 QTAILQ_INIT(&vd
->clients
);
3056 vd
->expires
= TIME_MAX
;
3058 if (keyboard_layout
) {
3059 trace_vnc_key_map_init(keyboard_layout
);
3060 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3062 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3065 if (!vd
->kbd_layout
) {
3069 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3070 vd
->connections_limit
= 32;
3072 qemu_mutex_init(&vd
->mutex
);
3073 vnc_start_worker_thread();
3075 vd
->dcl
.ops
= &dcl_ops
;
3076 register_displaychangelistener(&vd
->dcl
);
3080 static void vnc_display_close(VncDisplay
*vd
)
3086 vd
->is_unix
= false;
3087 for (i
= 0; i
< vd
->nlsock
; i
++) {
3088 if (vd
->lsock_tag
[i
]) {
3089 g_source_remove(vd
->lsock_tag
[i
]);
3091 object_unref(OBJECT(vd
->lsock
[i
]));
3094 g_free(vd
->lsock_tag
);
3096 vd
->lsock_tag
= NULL
;
3099 for (i
= 0; i
< vd
->nlwebsock
; i
++) {
3100 if (vd
->lwebsock_tag
[i
]) {
3101 g_source_remove(vd
->lwebsock_tag
[i
]);
3103 object_unref(OBJECT(vd
->lwebsock
[i
]));
3105 g_free(vd
->lwebsock
);
3106 g_free(vd
->lwebsock_tag
);
3107 vd
->lwebsock
= NULL
;
3108 vd
->lwebsock_tag
= NULL
;
3111 vd
->auth
= VNC_AUTH_INVALID
;
3112 vd
->subauth
= VNC_AUTH_INVALID
;
3114 object_unparent(OBJECT(vd
->tlscreds
));
3115 vd
->tlscreds
= NULL
;
3117 g_free(vd
->tlsaclname
);
3118 vd
->tlsaclname
= NULL
;
3119 if (vd
->lock_key_sync
) {
3120 qemu_remove_led_event_handler(vd
->led
);
3125 int vnc_display_password(const char *id
, const char *password
)
3127 VncDisplay
*vd
= vnc_display_find(id
);
3132 if (vd
->auth
== VNC_AUTH_NONE
) {
3133 error_printf_unless_qmp("If you want use passwords please enable "
3134 "password auth using '-vnc ${dpy},password'.\n");
3138 g_free(vd
->password
);
3139 vd
->password
= g_strdup(password
);
3144 int vnc_display_pw_expire(const char *id
, time_t expires
)
3146 VncDisplay
*vd
= vnc_display_find(id
);
3152 vd
->expires
= expires
;
3156 static void vnc_display_print_local_addr(VncDisplay
*vd
)
3158 SocketAddress
*addr
;
3165 addr
= qio_channel_socket_get_local_address(vd
->lsock
[0], &err
);
3170 if (addr
->type
!= SOCKET_ADDRESS_TYPE_INET
) {
3171 qapi_free_SocketAddress(addr
);
3174 error_printf_unless_qmp("VNC server running on %s:%s\n",
3177 qapi_free_SocketAddress(addr
);
3180 static QemuOptsList qemu_vnc_opts
= {
3182 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3183 .implied_opt_name
= "vnc",
3187 .type
= QEMU_OPT_STRING
,
3189 .name
= "websocket",
3190 .type
= QEMU_OPT_STRING
,
3192 .name
= "tls-creds",
3193 .type
= QEMU_OPT_STRING
,
3195 /* Deprecated in favour of tls-creds */
3197 .type
= QEMU_OPT_STRING
,
3200 .type
= QEMU_OPT_STRING
,
3203 .type
= QEMU_OPT_STRING
,
3206 .type
= QEMU_OPT_NUMBER
,
3208 .name
= "connections",
3209 .type
= QEMU_OPT_NUMBER
,
3212 .type
= QEMU_OPT_NUMBER
,
3215 .type
= QEMU_OPT_BOOL
,
3218 .type
= QEMU_OPT_BOOL
,
3221 .type
= QEMU_OPT_BOOL
,
3224 .type
= QEMU_OPT_BOOL
,
3226 .name
= "lock-key-sync",
3227 .type
= QEMU_OPT_BOOL
,
3229 .name
= "key-delay-ms",
3230 .type
= QEMU_OPT_NUMBER
,
3233 .type
= QEMU_OPT_BOOL
,
3235 /* Deprecated in favour of tls-creds */
3237 .type
= QEMU_OPT_BOOL
,
3239 /* Deprecated in favour of tls-creds */
3240 .name
= "x509verify",
3241 .type
= QEMU_OPT_STRING
,
3244 .type
= QEMU_OPT_BOOL
,
3247 .type
= QEMU_OPT_BOOL
,
3249 .name
= "non-adaptive",
3250 .type
= QEMU_OPT_BOOL
,
3252 { /* end of list */ }
3258 vnc_display_setup_auth(int *auth
,
3260 QCryptoTLSCreds
*tlscreds
,
3267 * We have a choice of 3 authentication options
3273 * The channel can be run in 2 modes
3278 * And TLS can use 2 types of credentials
3283 * We thus have 9 possible logical combinations
3288 * 4. tls + anon + none
3289 * 5. tls + anon + vnc
3290 * 6. tls + anon + sasl
3291 * 7. tls + x509 + none
3292 * 8. tls + x509 + vnc
3293 * 9. tls + x509 + sasl
3295 * These need to be mapped into the VNC auth schemes
3296 * in an appropriate manner. In regular VNC, all the
3297 * TLS options get mapped into VNC_AUTH_VENCRYPT
3300 * In websockets, the https:// protocol already provides
3301 * TLS support, so there is no need to make use of the
3302 * VeNCrypt extension. Furthermore, websockets browser
3303 * clients could not use VeNCrypt even if they wanted to,
3304 * as they cannot control when the TLS handshake takes
3305 * place. Thus there is no option but to rely on https://,
3306 * meaning combinations 4->6 and 7->9 will be mapped to
3307 * VNC auth schemes in the same way as combos 1->3.
3309 * Regardless of fact that we have a different mapping to
3310 * VNC auth mechs for plain VNC vs websockets VNC, the end
3311 * result has the same security characteristics.
3313 if (websocket
|| !tlscreds
) {
3315 VNC_DEBUG("Initializing VNC server with password auth\n");
3316 *auth
= VNC_AUTH_VNC
;
3318 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3319 *auth
= VNC_AUTH_SASL
;
3321 VNC_DEBUG("Initializing VNC server with no auth\n");
3322 *auth
= VNC_AUTH_NONE
;
3324 *subauth
= VNC_AUTH_INVALID
;
3326 bool is_x509
= object_dynamic_cast(OBJECT(tlscreds
),
3327 TYPE_QCRYPTO_TLS_CREDS_X509
) != NULL
;
3328 bool is_anon
= object_dynamic_cast(OBJECT(tlscreds
),
3329 TYPE_QCRYPTO_TLS_CREDS_ANON
) != NULL
;
3331 if (!is_x509
&& !is_anon
) {
3333 "Unsupported TLS cred type %s",
3334 object_get_typename(OBJECT(tlscreds
)));
3337 *auth
= VNC_AUTH_VENCRYPT
;
3340 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3341 *subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3343 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3344 *subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3349 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3350 *subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3352 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3353 *subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3357 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3358 *subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3360 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3361 *subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3370 * Handle back compat with old CLI syntax by creating some
3371 * suitable QCryptoTLSCreds objects
3373 static QCryptoTLSCreds
*
3374 vnc_display_create_creds(bool x509
,
3380 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3381 Object
*parent
= object_get_objects_root();
3386 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3390 "endpoint", "server",
3392 "verify-peer", x509verify
? "yes" : "no",
3395 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3399 "endpoint", "server",
3406 error_propagate(errp
, err
);
3410 return QCRYPTO_TLS_CREDS(creds
);
3414 static int vnc_display_get_address(const char *addrstr
,
3423 SocketAddress
**retaddr
,
3427 SocketAddress
*addr
= NULL
;
3429 addr
= g_new0(SocketAddress
, 1);
3431 if (strncmp(addrstr
, "unix:", 5) == 0) {
3432 addr
->type
= SOCKET_ADDRESS_TYPE_UNIX
;
3433 addr
->u
.q_unix
.path
= g_strdup(addrstr
+ 5);
3436 error_setg(errp
, "UNIX sockets not supported with websock");
3441 error_setg(errp
, "Port range not support with UNIX socket");
3448 unsigned long long baseport
= 0;
3449 InetSocketAddress
*inet
;
3451 port
= strrchr(addrstr
, ':');
3457 error_setg(errp
, "no vnc port specified");
3461 hostlen
= port
- addrstr
;
3463 if (*port
== '\0') {
3464 error_setg(errp
, "vnc port cannot be empty");
3469 addr
->type
= SOCKET_ADDRESS_TYPE_INET
;
3470 inet
= &addr
->u
.inet
;
3471 if (addrstr
[0] == '[' && addrstr
[hostlen
- 1] == ']') {
3472 inet
->host
= g_strndup(addrstr
+ 1, hostlen
- 2);
3474 inet
->host
= g_strndup(addrstr
, hostlen
);
3476 /* plain VNC port is just an offset, for websocket
3477 * port is absolute */
3479 if (g_str_equal(addrstr
, "") ||
3480 g_str_equal(addrstr
, "on")) {
3481 if (displaynum
== -1) {
3482 error_setg(errp
, "explicit websocket port is required");
3485 inet
->port
= g_strdup_printf(
3486 "%d", displaynum
+ 5700);
3488 inet
->has_to
= true;
3489 inet
->to
= to
+ 5700;
3492 inet
->port
= g_strdup(port
);
3495 int offset
= reverse
? 0 : 5900;
3496 if (parse_uint_full(port
, &baseport
, 10) < 0) {
3497 error_setg(errp
, "can't convert to a number: %s", port
);
3500 if (baseport
> 65535 ||
3501 baseport
+ offset
> 65535) {
3502 error_setg(errp
, "port %s out of range", port
);
3505 inet
->port
= g_strdup_printf(
3506 "%d", (int)baseport
+ offset
);
3509 inet
->has_to
= true;
3510 inet
->to
= to
+ offset
;
3515 inet
->has_ipv4
= has_ipv4
;
3517 inet
->has_ipv6
= has_ipv6
;
3526 qapi_free_SocketAddress(addr
);
3531 static void vnc_free_addresses(SocketAddress
***retsaddr
,
3536 for (i
= 0; i
< *retnsaddr
; i
++) {
3537 qapi_free_SocketAddress((*retsaddr
)[i
]);
3545 static int vnc_display_get_addresses(QemuOpts
*opts
,
3547 SocketAddress
***retsaddr
,
3549 SocketAddress
***retwsaddr
,
3553 SocketAddress
*saddr
= NULL
;
3554 SocketAddress
*wsaddr
= NULL
;
3555 QemuOptsIter addriter
;
3557 int to
= qemu_opt_get_number(opts
, "to", 0);
3558 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3559 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3560 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3561 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3562 int displaynum
= -1;
3570 addr
= qemu_opt_get(opts
, "vnc");
3571 if (addr
== NULL
|| g_str_equal(addr
, "none")) {
3575 if (qemu_opt_get(opts
, "websocket") &&
3576 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3578 "SHA1 hash support is required for websockets");
3582 qemu_opt_iter_init(&addriter
, opts
, "vnc");
3583 while ((addr
= qemu_opt_iter_next(&addriter
)) != NULL
) {
3585 rv
= vnc_display_get_address(addr
, false, reverse
, 0, to
,
3592 /* Historical compat - first listen address can be used
3593 * to set the default websocket port
3595 if (displaynum
== -1) {
3598 *retsaddr
= g_renew(SocketAddress
*, *retsaddr
, *retnsaddr
+ 1);
3599 (*retsaddr
)[(*retnsaddr
)++] = saddr
;
3602 /* If we had multiple primary displays, we don't do defaults
3603 * for websocket, and require explicit config instead. */
3604 if (*retnsaddr
> 1) {
3608 qemu_opt_iter_init(&addriter
, opts
, "websocket");
3609 while ((addr
= qemu_opt_iter_next(&addriter
)) != NULL
) {
3610 if (vnc_display_get_address(addr
, true, reverse
, displaynum
, to
,
3613 &wsaddr
, errp
) < 0) {
3617 /* Historical compat - if only a single listen address was
3618 * provided, then this is used to set the default listen
3619 * address for websocket too
3621 if (*retnsaddr
== 1 &&
3622 (*retsaddr
)[0]->type
== SOCKET_ADDRESS_TYPE_INET
&&
3623 wsaddr
->type
== SOCKET_ADDRESS_TYPE_INET
&&
3624 g_str_equal(wsaddr
->u
.inet
.host
, "") &&
3625 !g_str_equal((*retsaddr
)[0]->u
.inet
.host
, "")) {
3626 g_free(wsaddr
->u
.inet
.host
);
3627 wsaddr
->u
.inet
.host
= g_strdup((*retsaddr
)[0]->u
.inet
.host
);
3630 *retwsaddr
= g_renew(SocketAddress
*, *retwsaddr
, *retnwsaddr
+ 1);
3631 (*retwsaddr
)[(*retnwsaddr
)++] = wsaddr
;
3637 vnc_free_addresses(retsaddr
, retnsaddr
);
3638 vnc_free_addresses(retwsaddr
, retnwsaddr
);
3643 static int vnc_display_connect(VncDisplay
*vd
,
3644 SocketAddress
**saddr
,
3646 SocketAddress
**wsaddr
,
3650 /* connect to viewer */
3651 QIOChannelSocket
*sioc
= NULL
;
3653 error_setg(errp
, "Cannot use websockets in reverse mode");
3657 error_setg(errp
, "Expected a single address in reverse mode");
3660 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3661 vd
->is_unix
= saddr
[0]->type
== SOCKET_ADDRESS_TYPE_UNIX
;
3662 sioc
= qio_channel_socket_new();
3663 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-reverse");
3664 if (qio_channel_socket_connect_sync(sioc
, saddr
[0], errp
) < 0) {
3667 vnc_connect(vd
, sioc
, false, false);
3668 object_unref(OBJECT(sioc
));
3673 static int vnc_display_listen_addr(VncDisplay
*vd
,
3674 SocketAddress
*addr
,
3676 QIOChannelSocket
***lsock
,
3681 QIODNSResolver
*resolver
= qio_dns_resolver_get_instance();
3682 SocketAddress
**rawaddrs
= NULL
;
3683 size_t nrawaddrs
= 0;
3684 Error
*listenerr
= NULL
;
3685 bool listening
= false;
3688 if (qio_dns_resolver_lookup_sync(resolver
, addr
, &nrawaddrs
,
3689 &rawaddrs
, errp
) < 0) {
3693 for (i
= 0; i
< nrawaddrs
; i
++) {
3694 QIOChannelSocket
*sioc
= qio_channel_socket_new();
3696 qio_channel_set_name(QIO_CHANNEL(sioc
), name
);
3697 if (qio_channel_socket_listen_sync(
3698 sioc
, rawaddrs
[i
], listenerr
== NULL
? &listenerr
: NULL
) < 0) {
3699 object_unref(OBJECT(sioc
));
3704 *lsock
= g_renew(QIOChannelSocket
*, *lsock
, *nlsock
);
3705 *lsock_tag
= g_renew(guint
, *lsock_tag
, *nlsock
);
3707 (*lsock
)[*nlsock
- 1] = sioc
;
3708 (*lsock_tag
)[*nlsock
- 1] = 0;
3711 for (i
= 0; i
< nrawaddrs
; i
++) {
3712 qapi_free_SocketAddress(rawaddrs
[i
]);
3718 error_propagate(errp
, listenerr
);
3721 error_free(listenerr
);
3725 for (i
= 0; i
< *nlsock
; i
++) {
3726 (*lsock_tag
)[i
] = qio_channel_add_watch(
3727 QIO_CHANNEL((*lsock
)[i
]),
3728 G_IO_IN
, vnc_listen_io
, vd
, NULL
);
3735 static int vnc_display_listen(VncDisplay
*vd
,
3736 SocketAddress
**saddr
,
3738 SocketAddress
**wsaddr
,
3744 for (i
= 0; i
< nsaddr
; i
++) {
3745 if (vnc_display_listen_addr(vd
, saddr
[i
],
3754 for (i
= 0; i
< nwsaddr
; i
++) {
3755 if (vnc_display_listen_addr(vd
, wsaddr
[i
],
3769 void vnc_display_open(const char *id
, Error
**errp
)
3771 VncDisplay
*vd
= vnc_display_find(id
);
3772 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3773 SocketAddress
**saddr
= NULL
, **wsaddr
= NULL
;
3774 size_t nsaddr
, nwsaddr
;
3775 const char *share
, *device_id
;
3777 bool password
= false;
3778 bool reverse
= false;
3781 #ifdef CONFIG_VNC_SASL
3785 int lock_key_sync
= 1;
3789 error_setg(errp
, "VNC display not active");
3792 vnc_display_close(vd
);
3798 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3799 if (vnc_display_get_addresses(opts
, reverse
, &saddr
, &nsaddr
,
3800 &wsaddr
, &nwsaddr
, errp
) < 0) {
3804 password
= qemu_opt_get_bool(opts
, "password", false);
3806 if (fips_get_state()) {
3808 "VNC password auth disabled due to FIPS mode, "
3809 "consider using the VeNCrypt or SASL authentication "
3810 "methods as an alternative");
3813 if (!qcrypto_cipher_supports(
3814 QCRYPTO_CIPHER_ALG_DES_RFB
, QCRYPTO_CIPHER_MODE_ECB
)) {
3816 "Cipher backend does not support DES RFB algorithm");
3821 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3822 key_delay_ms
= qemu_opt_get_number(opts
, "key-delay-ms", 10);
3823 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3824 #ifndef CONFIG_VNC_SASL
3826 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3829 #endif /* CONFIG_VNC_SASL */
3830 credid
= qemu_opt_get(opts
, "tls-creds");
3833 if (qemu_opt_get(opts
, "tls") ||
3834 qemu_opt_get(opts
, "x509") ||
3835 qemu_opt_get(opts
, "x509verify")) {
3837 "'tls-creds' parameter is mutually exclusive with "
3838 "'tls', 'x509' and 'x509verify' parameters");
3842 creds
= object_resolve_path_component(
3843 object_get_objects_root(), credid
);
3845 error_setg(errp
, "No TLS credentials with id '%s'",
3849 vd
->tlscreds
= (QCryptoTLSCreds
*)
3850 object_dynamic_cast(creds
,
3851 TYPE_QCRYPTO_TLS_CREDS
);
3852 if (!vd
->tlscreds
) {
3853 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3857 object_ref(OBJECT(vd
->tlscreds
));
3859 if (vd
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3861 "Expecting TLS credentials with a server endpoint");
3866 bool tls
= false, x509
= false, x509verify
= false;
3867 tls
= qemu_opt_get_bool(opts
, "tls", false);
3869 path
= qemu_opt_get(opts
, "x509");
3874 path
= qemu_opt_get(opts
, "x509verify");
3880 vd
->tlscreds
= vnc_display_create_creds(x509
,
3885 if (!vd
->tlscreds
) {
3890 acl
= qemu_opt_get_bool(opts
, "acl", false);
3892 share
= qemu_opt_get(opts
, "share");
3894 if (strcmp(share
, "ignore") == 0) {
3895 vd
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3896 } else if (strcmp(share
, "allow-exclusive") == 0) {
3897 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3898 } else if (strcmp(share
, "force-shared") == 0) {
3899 vd
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3901 error_setg(errp
, "unknown vnc share= option");
3905 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3907 vd
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3909 #ifdef CONFIG_VNC_JPEG
3910 vd
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3912 vd
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3913 /* adaptive updates are only used with tight encoding and
3914 * if lossy updates are enabled so we can disable all the
3915 * calculations otherwise */
3917 vd
->non_adaptive
= true;
3921 if (strcmp(vd
->id
, "default") == 0) {
3922 vd
->tlsaclname
= g_strdup("vnc.x509dname");
3924 vd
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vd
->id
);
3926 qemu_acl_init(vd
->tlsaclname
);
3928 #ifdef CONFIG_VNC_SASL
3932 if (strcmp(vd
->id
, "default") == 0) {
3933 aclname
= g_strdup("vnc.username");
3935 aclname
= g_strdup_printf("vnc.%s.username", vd
->id
);
3937 vd
->sasl
.acl
= qemu_acl_init(aclname
);
3942 if (vnc_display_setup_auth(&vd
->auth
, &vd
->subauth
,
3943 vd
->tlscreds
, password
,
3944 sasl
, false, errp
) < 0) {
3947 trace_vnc_auth_init(vd
, 0, vd
->auth
, vd
->subauth
);
3949 if (vnc_display_setup_auth(&vd
->ws_auth
, &vd
->ws_subauth
,
3950 vd
->tlscreds
, password
,
3951 sasl
, true, errp
) < 0) {
3954 trace_vnc_auth_init(vd
, 1, vd
->ws_auth
, vd
->ws_subauth
);
3956 #ifdef CONFIG_VNC_SASL
3957 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3958 error_setg(errp
, "Failed to initialize SASL auth: %s",
3959 sasl_errstring(saslErr
, NULL
, NULL
));
3963 vd
->lock_key_sync
= lock_key_sync
;
3964 if (lock_key_sync
) {
3965 vd
->led
= qemu_add_led_event_handler(kbd_leds
, vd
);
3968 vd
->key_delay_ms
= key_delay_ms
;
3970 device_id
= qemu_opt_get(opts
, "display");
3972 int head
= qemu_opt_get_number(opts
, "head", 0);
3975 con
= qemu_console_lookup_by_device_name(device_id
, head
, &err
);
3977 error_propagate(errp
, err
);
3984 if (con
!= vd
->dcl
.con
) {
3985 unregister_displaychangelistener(&vd
->dcl
);
3987 register_displaychangelistener(&vd
->dcl
);
3990 if (saddr
== NULL
) {
3995 if (vnc_display_connect(vd
, saddr
, nsaddr
, wsaddr
, nwsaddr
, errp
) < 0) {
3999 if (vnc_display_listen(vd
, saddr
, nsaddr
, wsaddr
, nwsaddr
, errp
) < 0) {
4004 if (qemu_opt_get(opts
, "to")) {
4005 vnc_display_print_local_addr(vd
);
4009 vnc_free_addresses(&saddr
, &nsaddr
);
4010 vnc_free_addresses(&wsaddr
, &nwsaddr
);
4014 vnc_display_close(vd
);
4018 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
4020 VncDisplay
*vd
= vnc_display_find(id
);
4021 QIOChannelSocket
*sioc
;
4027 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
4029 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-server");
4030 vnc_connect(vd
, sioc
, skipauth
, false);
4031 object_unref(OBJECT(sioc
));
4035 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
4040 id
= g_strdup("default");
4041 while (qemu_opts_find(olist
, id
)) {
4043 id
= g_strdup_printf("vnc%d", i
++);
4045 qemu_opts_set_id(opts
, id
);
4048 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
4050 QemuOptsList
*olist
= qemu_find_opts("vnc");
4051 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
4058 id
= qemu_opts_id(opts
);
4060 /* auto-assign id if not present */
4061 vnc_auto_assign_id(olist
, opts
);
4066 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
4068 Error
*local_err
= NULL
;
4069 char *id
= (char *)qemu_opts_id(opts
);
4072 vnc_display_init(id
);
4073 vnc_display_open(id
, &local_err
);
4074 if (local_err
!= NULL
) {
4075 error_reportf_err(local_err
, "Failed to start VNC server: ");
4081 static void vnc_register_config(void)
4083 qemu_add_opts(&qemu_vnc_opts
);
4085 opts_init(vnc_register_config
);