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"
32 #include "sysemu/sysemu.h"
33 #include "qemu/error-report.h"
34 #include "qemu/sockets.h"
35 #include "qemu/timer.h"
37 #include "qemu/config-file.h"
38 #include "qapi/qmp/qerror.h"
39 #include "qapi/qmp/types.h"
40 #include "qmp-commands.h"
42 #include "qapi-event.h"
43 #include "crypto/hash.h"
44 #include "crypto/tlscredsanon.h"
45 #include "crypto/tlscredsx509.h"
46 #include "qom/object_interfaces.h"
47 #include "qemu/cutils.h"
48 #include "io/dns-resolver.h"
50 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
51 #define VNC_REFRESH_INTERVAL_INC 50
52 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
53 static const struct timeval VNC_REFRESH_STATS
= { 0, 500000 };
54 static const struct timeval VNC_REFRESH_LOSSY
= { 2, 0 };
56 #include "vnc_keysym.h"
57 #include "crypto/cipher.h"
59 static QTAILQ_HEAD(, VncDisplay
) vnc_displays
=
60 QTAILQ_HEAD_INITIALIZER(vnc_displays
);
62 static int vnc_cursor_define(VncState
*vs
);
63 static void vnc_release_modifiers(VncState
*vs
);
65 static void vnc_set_share_mode(VncState
*vs
, VncShareMode mode
)
68 static const char *mn
[] = {
70 [VNC_SHARE_MODE_CONNECTING
] = "connecting",
71 [VNC_SHARE_MODE_SHARED
] = "shared",
72 [VNC_SHARE_MODE_EXCLUSIVE
] = "exclusive",
73 [VNC_SHARE_MODE_DISCONNECTED
] = "disconnected",
75 fprintf(stderr
, "%s/%p: %s -> %s\n", __func__
,
76 vs
->ioc
, mn
[vs
->share_mode
], mn
[mode
]);
79 switch (vs
->share_mode
) {
80 case VNC_SHARE_MODE_CONNECTING
:
81 vs
->vd
->num_connecting
--;
83 case VNC_SHARE_MODE_SHARED
:
86 case VNC_SHARE_MODE_EXCLUSIVE
:
87 vs
->vd
->num_exclusive
--;
93 vs
->share_mode
= mode
;
95 switch (vs
->share_mode
) {
96 case VNC_SHARE_MODE_CONNECTING
:
97 vs
->vd
->num_connecting
++;
99 case VNC_SHARE_MODE_SHARED
:
100 vs
->vd
->num_shared
++;
102 case VNC_SHARE_MODE_EXCLUSIVE
:
103 vs
->vd
->num_exclusive
++;
111 static void vnc_init_basic_info(SocketAddress
*addr
,
115 switch (addr
->type
) {
116 case SOCKET_ADDRESS_TYPE_INET
:
117 info
->host
= g_strdup(addr
->u
.inet
.host
);
118 info
->service
= g_strdup(addr
->u
.inet
.port
);
119 if (addr
->u
.inet
.ipv6
) {
120 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
122 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
126 case SOCKET_ADDRESS_TYPE_UNIX
:
127 info
->host
= g_strdup("");
128 info
->service
= g_strdup(addr
->u
.q_unix
.path
);
129 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
132 case SOCKET_ADDRESS_TYPE_VSOCK
:
133 case SOCKET_ADDRESS_TYPE_FD
:
134 error_setg(errp
, "Unsupported socket address type %s",
135 SocketAddressType_lookup
[addr
->type
]);
144 static void vnc_init_basic_info_from_server_addr(QIOChannelSocket
*ioc
,
148 SocketAddress
*addr
= NULL
;
151 error_setg(errp
, "No listener socket available");
155 addr
= qio_channel_socket_get_local_address(ioc
, errp
);
160 vnc_init_basic_info(addr
, info
, errp
);
161 qapi_free_SocketAddress(addr
);
164 static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket
*ioc
,
168 SocketAddress
*addr
= NULL
;
170 addr
= qio_channel_socket_get_remote_address(ioc
, errp
);
175 vnc_init_basic_info(addr
, info
, errp
);
176 qapi_free_SocketAddress(addr
);
179 static const char *vnc_auth_name(VncDisplay
*vd
) {
181 case VNC_AUTH_INVALID
:
197 case VNC_AUTH_VENCRYPT
:
198 switch (vd
->subauth
) {
199 case VNC_AUTH_VENCRYPT_PLAIN
:
200 return "vencrypt+plain";
201 case VNC_AUTH_VENCRYPT_TLSNONE
:
202 return "vencrypt+tls+none";
203 case VNC_AUTH_VENCRYPT_TLSVNC
:
204 return "vencrypt+tls+vnc";
205 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
206 return "vencrypt+tls+plain";
207 case VNC_AUTH_VENCRYPT_X509NONE
:
208 return "vencrypt+x509+none";
209 case VNC_AUTH_VENCRYPT_X509VNC
:
210 return "vencrypt+x509+vnc";
211 case VNC_AUTH_VENCRYPT_X509PLAIN
:
212 return "vencrypt+x509+plain";
213 case VNC_AUTH_VENCRYPT_TLSSASL
:
214 return "vencrypt+tls+sasl";
215 case VNC_AUTH_VENCRYPT_X509SASL
:
216 return "vencrypt+x509+sasl";
226 static VncServerInfo
*vnc_server_info_get(VncDisplay
*vd
)
235 info
= g_malloc0(sizeof(*info
));
236 vnc_init_basic_info_from_server_addr(vd
->lsock
[0],
237 qapi_VncServerInfo_base(info
), &err
);
238 info
->has_auth
= true;
239 info
->auth
= g_strdup(vnc_auth_name(vd
));
241 qapi_free_VncServerInfo(info
);
248 static void vnc_client_cache_auth(VncState
*client
)
255 client
->info
->x509_dname
=
256 qcrypto_tls_session_get_peer_name(client
->tls
);
257 client
->info
->has_x509_dname
=
258 client
->info
->x509_dname
!= NULL
;
260 #ifdef CONFIG_VNC_SASL
261 if (client
->sasl
.conn
&&
262 client
->sasl
.username
) {
263 client
->info
->has_sasl_username
= true;
264 client
->info
->sasl_username
= g_strdup(client
->sasl
.username
);
269 static void vnc_client_cache_addr(VncState
*client
)
273 client
->info
= g_malloc0(sizeof(*client
->info
));
274 vnc_init_basic_info_from_remote_addr(client
->sioc
,
275 qapi_VncClientInfo_base(client
->info
),
278 qapi_free_VncClientInfo(client
->info
);
284 static void vnc_qmp_event(VncState
*vs
, QAPIEvent event
)
292 si
= vnc_server_info_get(vs
->vd
);
298 case QAPI_EVENT_VNC_CONNECTED
:
299 qapi_event_send_vnc_connected(si
, qapi_VncClientInfo_base(vs
->info
),
302 case QAPI_EVENT_VNC_INITIALIZED
:
303 qapi_event_send_vnc_initialized(si
, vs
->info
, &error_abort
);
305 case QAPI_EVENT_VNC_DISCONNECTED
:
306 qapi_event_send_vnc_disconnected(si
, vs
->info
, &error_abort
);
312 qapi_free_VncServerInfo(si
);
315 static VncClientInfo
*qmp_query_vnc_client(const VncState
*client
)
320 info
= g_malloc0(sizeof(*info
));
322 vnc_init_basic_info_from_remote_addr(client
->sioc
,
323 qapi_VncClientInfo_base(info
),
327 qapi_free_VncClientInfo(info
);
331 info
->websocket
= client
->websocket
;
334 info
->x509_dname
= qcrypto_tls_session_get_peer_name(client
->tls
);
335 info
->has_x509_dname
= info
->x509_dname
!= NULL
;
337 #ifdef CONFIG_VNC_SASL
338 if (client
->sasl
.conn
&& client
->sasl
.username
) {
339 info
->has_sasl_username
= true;
340 info
->sasl_username
= g_strdup(client
->sasl
.username
);
347 static VncDisplay
*vnc_display_find(const char *id
)
352 return QTAILQ_FIRST(&vnc_displays
);
354 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
355 if (strcmp(id
, vd
->id
) == 0) {
362 static VncClientInfoList
*qmp_query_client_list(VncDisplay
*vd
)
364 VncClientInfoList
*cinfo
, *prev
= NULL
;
367 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
368 cinfo
= g_new0(VncClientInfoList
, 1);
369 cinfo
->value
= qmp_query_vnc_client(client
);
376 VncInfo
*qmp_query_vnc(Error
**errp
)
378 VncInfo
*info
= g_malloc0(sizeof(*info
));
379 VncDisplay
*vd
= vnc_display_find(NULL
);
380 SocketAddress
*addr
= NULL
;
382 if (vd
== NULL
|| !vd
->nlsock
) {
383 info
->enabled
= false;
385 info
->enabled
= true;
387 /* for compatibility with the original command */
388 info
->has_clients
= true;
389 info
->clients
= qmp_query_client_list(vd
);
391 if (vd
->lsock
== NULL
) {
395 addr
= qio_channel_socket_get_local_address(vd
->lsock
[0], errp
);
400 switch (addr
->type
) {
401 case SOCKET_ADDRESS_TYPE_INET
:
402 info
->host
= g_strdup(addr
->u
.inet
.host
);
403 info
->service
= g_strdup(addr
->u
.inet
.port
);
404 if (addr
->u
.inet
.ipv6
) {
405 info
->family
= NETWORK_ADDRESS_FAMILY_IPV6
;
407 info
->family
= NETWORK_ADDRESS_FAMILY_IPV4
;
411 case SOCKET_ADDRESS_TYPE_UNIX
:
412 info
->host
= g_strdup("");
413 info
->service
= g_strdup(addr
->u
.q_unix
.path
);
414 info
->family
= NETWORK_ADDRESS_FAMILY_UNIX
;
417 case SOCKET_ADDRESS_TYPE_VSOCK
:
418 case SOCKET_ADDRESS_TYPE_FD
:
419 error_setg(errp
, "Unsupported socket address type %s",
420 SocketAddressType_lookup
[addr
->type
]);
426 info
->has_host
= true;
427 info
->has_service
= true;
428 info
->has_family
= true;
430 info
->has_auth
= true;
431 info
->auth
= g_strdup(vnc_auth_name(vd
));
434 qapi_free_SocketAddress(addr
);
438 qapi_free_SocketAddress(addr
);
439 qapi_free_VncInfo(info
);
444 static void qmp_query_auth(int auth
, int subauth
,
445 VncPrimaryAuth
*qmp_auth
,
446 VncVencryptSubAuth
*qmp_vencrypt
,
447 bool *qmp_has_vencrypt
);
449 static VncServerInfo2List
*qmp_query_server_entry(QIOChannelSocket
*ioc
,
453 VncServerInfo2List
*prev
)
455 VncServerInfo2List
*list
;
456 VncServerInfo2
*info
;
460 addr
= qio_channel_socket_get_local_address(ioc
, &err
);
466 info
= g_new0(VncServerInfo2
, 1);
467 vnc_init_basic_info(addr
, qapi_VncServerInfo2_base(info
), &err
);
468 qapi_free_SocketAddress(addr
);
470 qapi_free_VncServerInfo2(info
);
474 info
->websocket
= websocket
;
476 qmp_query_auth(auth
, subauth
, &info
->auth
,
477 &info
->vencrypt
, &info
->has_vencrypt
);
479 list
= g_new0(VncServerInfo2List
, 1);
485 static void qmp_query_auth(int auth
, int subauth
,
486 VncPrimaryAuth
*qmp_auth
,
487 VncVencryptSubAuth
*qmp_vencrypt
,
488 bool *qmp_has_vencrypt
)
492 *qmp_auth
= VNC_PRIMARY_AUTH_VNC
;
495 *qmp_auth
= VNC_PRIMARY_AUTH_RA2
;
498 *qmp_auth
= VNC_PRIMARY_AUTH_RA2NE
;
501 *qmp_auth
= VNC_PRIMARY_AUTH_TIGHT
;
504 *qmp_auth
= VNC_PRIMARY_AUTH_ULTRA
;
507 *qmp_auth
= VNC_PRIMARY_AUTH_TLS
;
509 case VNC_AUTH_VENCRYPT
:
510 *qmp_auth
= VNC_PRIMARY_AUTH_VENCRYPT
;
511 *qmp_has_vencrypt
= true;
513 case VNC_AUTH_VENCRYPT_PLAIN
:
514 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_PLAIN
;
516 case VNC_AUTH_VENCRYPT_TLSNONE
:
517 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_NONE
;
519 case VNC_AUTH_VENCRYPT_TLSVNC
:
520 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_VNC
;
522 case VNC_AUTH_VENCRYPT_TLSPLAIN
:
523 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN
;
525 case VNC_AUTH_VENCRYPT_X509NONE
:
526 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_NONE
;
528 case VNC_AUTH_VENCRYPT_X509VNC
:
529 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_VNC
;
531 case VNC_AUTH_VENCRYPT_X509PLAIN
:
532 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_PLAIN
;
534 case VNC_AUTH_VENCRYPT_TLSSASL
:
535 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_TLS_SASL
;
537 case VNC_AUTH_VENCRYPT_X509SASL
:
538 *qmp_vencrypt
= VNC_VENCRYPT_SUB_AUTH_X509_SASL
;
541 *qmp_has_vencrypt
= false;
546 *qmp_auth
= VNC_PRIMARY_AUTH_SASL
;
550 *qmp_auth
= VNC_PRIMARY_AUTH_NONE
;
555 VncInfo2List
*qmp_query_vnc_servers(Error
**errp
)
557 VncInfo2List
*item
, *prev
= NULL
;
563 QTAILQ_FOREACH(vd
, &vnc_displays
, next
) {
564 info
= g_new0(VncInfo2
, 1);
565 info
->id
= g_strdup(vd
->id
);
566 info
->clients
= qmp_query_client_list(vd
);
567 qmp_query_auth(vd
->auth
, vd
->subauth
, &info
->auth
,
568 &info
->vencrypt
, &info
->has_vencrypt
);
570 dev
= DEVICE(object_property_get_link(OBJECT(vd
->dcl
.con
),
572 info
->has_display
= true;
573 info
->display
= g_strdup(dev
->id
);
575 for (i
= 0; i
< vd
->nlsock
; i
++) {
576 info
->server
= qmp_query_server_entry(
577 vd
->lsock
[i
], false, vd
->auth
, vd
->subauth
, info
->server
);
579 for (i
= 0; i
< vd
->nlwebsock
; i
++) {
580 info
->server
= qmp_query_server_entry(
581 vd
->lwebsock
[i
], true, vd
->ws_auth
,
582 vd
->ws_subauth
, info
->server
);
585 item
= g_new0(VncInfo2List
, 1);
594 1) Get the queue working for IO.
595 2) there is some weirdness when using the -S option (the screen is grey
596 and not totally invalidated
597 3) resolutions > 1024
600 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
);
601 static void vnc_disconnect_start(VncState
*vs
);
603 static void vnc_colordepth(VncState
*vs
);
604 static void framebuffer_update_request(VncState
*vs
, int incremental
,
605 int x_position
, int y_position
,
607 static void vnc_refresh(DisplayChangeListener
*dcl
);
608 static int vnc_refresh_server_surface(VncDisplay
*vd
);
610 static int vnc_width(VncDisplay
*vd
)
612 return MIN(VNC_MAX_WIDTH
, ROUND_UP(surface_width(vd
->ds
),
613 VNC_DIRTY_PIXELS_PER_BIT
));
616 static int vnc_height(VncDisplay
*vd
)
618 return MIN(VNC_MAX_HEIGHT
, surface_height(vd
->ds
));
621 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty
[VNC_MAX_HEIGHT
],
622 VNC_MAX_WIDTH
/ VNC_DIRTY_PIXELS_PER_BIT
),
624 int x
, int y
, int w
, int h
)
626 int width
= vnc_width(vd
);
627 int height
= vnc_height(vd
);
629 /* this is needed this to ensure we updated all affected
630 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
631 w
+= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
632 x
-= (x
% VNC_DIRTY_PIXELS_PER_BIT
);
636 w
= MIN(x
+ w
, width
) - x
;
637 h
= MIN(y
+ h
, height
);
640 bitmap_set(dirty
[y
], x
/ VNC_DIRTY_PIXELS_PER_BIT
,
641 DIV_ROUND_UP(w
, VNC_DIRTY_PIXELS_PER_BIT
));
645 static void vnc_dpy_update(DisplayChangeListener
*dcl
,
646 int x
, int y
, int w
, int h
)
648 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
649 struct VncSurface
*s
= &vd
->guest
;
651 vnc_set_area_dirty(s
->dirty
, vd
, x
, y
, w
, h
);
654 void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
657 vnc_write_u16(vs
, x
);
658 vnc_write_u16(vs
, y
);
659 vnc_write_u16(vs
, w
);
660 vnc_write_u16(vs
, h
);
662 vnc_write_s32(vs
, encoding
);
666 static void vnc_desktop_resize(VncState
*vs
)
668 if (vs
->ioc
== NULL
|| !vnc_has_feature(vs
, VNC_FEATURE_RESIZE
)) {
671 if (vs
->client_width
== pixman_image_get_width(vs
->vd
->server
) &&
672 vs
->client_height
== pixman_image_get_height(vs
->vd
->server
)) {
675 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
676 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
678 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
680 vnc_write_u16(vs
, 1); /* number of rects */
681 vnc_framebuffer_update(vs
, 0, 0, vs
->client_width
, vs
->client_height
,
682 VNC_ENCODING_DESKTOPRESIZE
);
683 vnc_unlock_output(vs
);
687 static void vnc_abort_display_jobs(VncDisplay
*vd
)
691 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
694 vnc_unlock_output(vs
);
696 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
699 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
702 vnc_unlock_output(vs
);
706 int vnc_server_fb_stride(VncDisplay
*vd
)
708 return pixman_image_get_stride(vd
->server
);
711 void *vnc_server_fb_ptr(VncDisplay
*vd
, int x
, int y
)
715 ptr
= (uint8_t *)pixman_image_get_data(vd
->server
);
716 ptr
+= y
* vnc_server_fb_stride(vd
);
717 ptr
+= x
* VNC_SERVER_FB_BYTES
;
721 static void vnc_update_server_surface(VncDisplay
*vd
)
725 qemu_pixman_image_unref(vd
->server
);
728 if (QTAILQ_EMPTY(&vd
->clients
)) {
732 width
= vnc_width(vd
);
733 height
= vnc_height(vd
);
734 vd
->server
= pixman_image_create_bits(VNC_SERVER_FB_FORMAT
,
738 memset(vd
->guest
.dirty
, 0x00, sizeof(vd
->guest
.dirty
));
739 vnc_set_area_dirty(vd
->guest
.dirty
, vd
, 0, 0,
743 static void vnc_dpy_switch(DisplayChangeListener
*dcl
,
744 DisplaySurface
*surface
)
746 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
749 vnc_abort_display_jobs(vd
);
753 vnc_update_server_surface(vd
);
756 qemu_pixman_image_unref(vd
->guest
.fb
);
757 vd
->guest
.fb
= pixman_image_ref(surface
->image
);
758 vd
->guest
.format
= surface
->format
;
760 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
762 vnc_desktop_resize(vs
);
763 if (vs
->vd
->cursor
) {
764 vnc_cursor_define(vs
);
766 memset(vs
->dirty
, 0x00, sizeof(vs
->dirty
));
767 vnc_set_area_dirty(vs
->dirty
, vd
, 0, 0,
774 static void vnc_write_pixels_copy(VncState
*vs
,
775 void *pixels
, int size
)
777 vnc_write(vs
, pixels
, size
);
780 /* slowest but generic code. */
781 void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
785 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
786 r
= (((v
& 0x00ff0000) >> 16) << vs
->client_pf
.rbits
) >> 8;
787 g
= (((v
& 0x0000ff00) >> 8) << vs
->client_pf
.gbits
) >> 8;
788 b
= (((v
& 0x000000ff) >> 0) << vs
->client_pf
.bbits
) >> 8;
790 # error need some bits here if you change VNC_SERVER_FB_FORMAT
792 v
= (r
<< vs
->client_pf
.rshift
) |
793 (g
<< vs
->client_pf
.gshift
) |
794 (b
<< vs
->client_pf
.bshift
);
795 switch (vs
->client_pf
.bytes_per_pixel
) {
825 static void vnc_write_pixels_generic(VncState
*vs
,
826 void *pixels1
, int size
)
830 if (VNC_SERVER_FB_BYTES
== 4) {
831 uint32_t *pixels
= pixels1
;
834 for (i
= 0; i
< n
; i
++) {
835 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
836 vnc_write(vs
, buf
, vs
->client_pf
.bytes_per_pixel
);
841 int vnc_raw_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
845 VncDisplay
*vd
= vs
->vd
;
847 row
= vnc_server_fb_ptr(vd
, x
, y
);
848 for (i
= 0; i
< h
; i
++) {
849 vs
->write_pixels(vs
, row
, w
* VNC_SERVER_FB_BYTES
);
850 row
+= vnc_server_fb_stride(vd
);
855 int vnc_send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
858 bool encode_raw
= false;
859 size_t saved_offs
= vs
->output
.offset
;
861 switch(vs
->vnc_encoding
) {
862 case VNC_ENCODING_ZLIB
:
863 n
= vnc_zlib_send_framebuffer_update(vs
, x
, y
, w
, h
);
865 case VNC_ENCODING_HEXTILE
:
866 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
867 n
= vnc_hextile_send_framebuffer_update(vs
, x
, y
, w
, h
);
869 case VNC_ENCODING_TIGHT
:
870 n
= vnc_tight_send_framebuffer_update(vs
, x
, y
, w
, h
);
872 case VNC_ENCODING_TIGHT_PNG
:
873 n
= vnc_tight_png_send_framebuffer_update(vs
, x
, y
, w
, h
);
875 case VNC_ENCODING_ZRLE
:
876 n
= vnc_zrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
878 case VNC_ENCODING_ZYWRLE
:
879 n
= vnc_zywrle_send_framebuffer_update(vs
, x
, y
, w
, h
);
886 /* If the client has the same pixel format as our internal buffer and
887 * a RAW encoding would need less space fall back to RAW encoding to
888 * save bandwidth and processing power in the client. */
889 if (!encode_raw
&& vs
->write_pixels
== vnc_write_pixels_copy
&&
890 12 + h
* w
* VNC_SERVER_FB_BYTES
<= (vs
->output
.offset
- saved_offs
)) {
891 vs
->output
.offset
= saved_offs
;
896 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
897 n
= vnc_raw_send_framebuffer_update(vs
, x
, y
, w
, h
);
903 static void vnc_mouse_set(DisplayChangeListener
*dcl
,
904 int x
, int y
, int visible
)
906 /* can we ask the client(s) to move the pointer ??? */
909 static int vnc_cursor_define(VncState
*vs
)
911 QEMUCursor
*c
= vs
->vd
->cursor
;
914 if (vnc_has_feature(vs
, VNC_FEATURE_RICH_CURSOR
)) {
916 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
917 vnc_write_u8(vs
, 0); /* padding */
918 vnc_write_u16(vs
, 1); /* # of rects */
919 vnc_framebuffer_update(vs
, c
->hot_x
, c
->hot_y
, c
->width
, c
->height
,
920 VNC_ENCODING_RICH_CURSOR
);
921 isize
= c
->width
* c
->height
* vs
->client_pf
.bytes_per_pixel
;
922 vnc_write_pixels_generic(vs
, c
->data
, isize
);
923 vnc_write(vs
, vs
->vd
->cursor_mask
, vs
->vd
->cursor_msize
);
924 vnc_unlock_output(vs
);
930 static void vnc_dpy_cursor_define(DisplayChangeListener
*dcl
,
933 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
936 cursor_put(vd
->cursor
);
937 g_free(vd
->cursor_mask
);
940 cursor_get(vd
->cursor
);
941 vd
->cursor_msize
= cursor_get_mono_bpl(c
) * c
->height
;
942 vd
->cursor_mask
= g_malloc0(vd
->cursor_msize
);
943 cursor_get_mono_mask(c
, 0, vd
->cursor_mask
);
945 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
946 vnc_cursor_define(vs
);
950 static int find_and_clear_dirty_height(VncState
*vs
,
951 int y
, int last_x
, int x
, int height
)
955 for (h
= 1; h
< (height
- y
); h
++) {
956 if (!test_bit(last_x
, vs
->dirty
[y
+ h
])) {
959 bitmap_clear(vs
->dirty
[y
+ h
], last_x
, x
- last_x
);
965 static int vnc_update_client(VncState
*vs
, int has_dirty
, bool sync
)
967 if (vs
->disconnecting
) {
968 vnc_disconnect_finish(vs
);
972 vs
->has_dirty
+= has_dirty
;
973 if (vs
->need_update
&& !vs
->disconnecting
) {
974 VncDisplay
*vd
= vs
->vd
;
980 if (vs
->output
.offset
&& !vs
->audio_cap
&& !vs
->force_update
)
981 /* kernel send buffers are full -> drop frames to throttle */
984 if (!vs
->has_dirty
&& !vs
->audio_cap
&& !vs
->force_update
)
988 * Send screen updates to the vnc client using the server
989 * surface and server dirty map. guest surface updates
990 * happening in parallel don't disturb us, the next pass will
991 * send them to the client.
993 job
= vnc_job_new(vs
);
995 height
= pixman_image_get_height(vd
->server
);
996 width
= pixman_image_get_width(vd
->server
);
1002 unsigned long offset
= find_next_bit((unsigned long *) &vs
->dirty
,
1003 height
* VNC_DIRTY_BPL(vs
),
1004 y
* VNC_DIRTY_BPL(vs
));
1005 if (offset
== height
* VNC_DIRTY_BPL(vs
)) {
1006 /* no more dirty bits */
1009 y
= offset
/ VNC_DIRTY_BPL(vs
);
1010 x
= offset
% VNC_DIRTY_BPL(vs
);
1011 x2
= find_next_zero_bit((unsigned long *) &vs
->dirty
[y
],
1012 VNC_DIRTY_BPL(vs
), x
);
1013 bitmap_clear(vs
->dirty
[y
], x
, x2
- x
);
1014 h
= find_and_clear_dirty_height(vs
, y
, x
, x2
, height
);
1015 x2
= MIN(x2
, width
/ VNC_DIRTY_PIXELS_PER_BIT
);
1017 n
+= vnc_job_add_rect(job
, x
* VNC_DIRTY_PIXELS_PER_BIT
, y
,
1018 (x2
- x
) * VNC_DIRTY_PIXELS_PER_BIT
, h
);
1020 if (!x
&& x2
== width
/ VNC_DIRTY_PIXELS_PER_BIT
) {
1032 vs
->force_update
= 0;
1037 if (vs
->disconnecting
) {
1038 vnc_disconnect_finish(vs
);
1047 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
1049 VncState
*vs
= opaque
;
1052 case AUD_CNOTIFY_DISABLE
:
1053 vnc_lock_output(vs
);
1054 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1055 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1056 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_END
);
1057 vnc_unlock_output(vs
);
1061 case AUD_CNOTIFY_ENABLE
:
1062 vnc_lock_output(vs
);
1063 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1064 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1065 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN
);
1066 vnc_unlock_output(vs
);
1072 static void audio_capture_destroy(void *opaque
)
1076 static void audio_capture(void *opaque
, void *buf
, int size
)
1078 VncState
*vs
= opaque
;
1080 vnc_lock_output(vs
);
1081 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU
);
1082 vnc_write_u8(vs
, VNC_MSG_SERVER_QEMU_AUDIO
);
1083 vnc_write_u16(vs
, VNC_MSG_SERVER_QEMU_AUDIO_DATA
);
1084 vnc_write_u32(vs
, size
);
1085 vnc_write(vs
, buf
, size
);
1086 vnc_unlock_output(vs
);
1090 static void audio_add(VncState
*vs
)
1092 struct audio_capture_ops ops
;
1094 if (vs
->audio_cap
) {
1095 error_report("audio already running");
1099 ops
.notify
= audio_capture_notify
;
1100 ops
.destroy
= audio_capture_destroy
;
1101 ops
.capture
= audio_capture
;
1103 vs
->audio_cap
= AUD_add_capture(&vs
->as
, &ops
, vs
);
1104 if (!vs
->audio_cap
) {
1105 error_report("Failed to add audio capture");
1109 static void audio_del(VncState
*vs
)
1111 if (vs
->audio_cap
) {
1112 AUD_del_capture(vs
->audio_cap
, vs
);
1113 vs
->audio_cap
= NULL
;
1117 static void vnc_disconnect_start(VncState
*vs
)
1119 if (vs
->disconnecting
) {
1122 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1124 g_source_remove(vs
->ioc_tag
);
1126 qio_channel_close(vs
->ioc
, NULL
);
1127 vs
->disconnecting
= TRUE
;
1130 void vnc_disconnect_finish(VncState
*vs
)
1134 vnc_jobs_join(vs
); /* Wait encoding jobs */
1136 vnc_lock_output(vs
);
1137 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1139 buffer_free(&vs
->input
);
1140 buffer_free(&vs
->output
);
1142 qapi_free_VncClientInfo(vs
->info
);
1145 vnc_tight_clear(vs
);
1148 #ifdef CONFIG_VNC_SASL
1149 vnc_sasl_client_cleanup(vs
);
1150 #endif /* CONFIG_VNC_SASL */
1152 vnc_release_modifiers(vs
);
1154 if (vs
->mouse_mode_notifier
.notify
!= NULL
) {
1155 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1157 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1158 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1159 /* last client gone */
1160 vnc_update_server_surface(vs
->vd
);
1163 vnc_unlock_output(vs
);
1165 qemu_mutex_destroy(&vs
->output_mutex
);
1166 if (vs
->bh
!= NULL
) {
1167 qemu_bh_delete(vs
->bh
);
1169 buffer_free(&vs
->jobs_buffer
);
1171 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1172 g_free(vs
->lossy_rect
[i
]);
1174 g_free(vs
->lossy_rect
);
1176 object_unref(OBJECT(vs
->ioc
));
1178 object_unref(OBJECT(vs
->sioc
));
1183 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1187 VNC_DEBUG("Closing down client sock: EOF\n");
1188 vnc_disconnect_start(vs
);
1189 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1190 VNC_DEBUG("Closing down client sock: ret %zd (%s)\n",
1191 ret
, errp
? error_get_pretty(*errp
) : "Unknown");
1192 vnc_disconnect_start(vs
);
1205 void vnc_client_error(VncState
*vs
)
1207 VNC_DEBUG("Closing down client sock: protocol error\n");
1208 vnc_disconnect_start(vs
);
1213 * Called to write a chunk of data to the client socket. The data may
1214 * be the raw data, or may have already been encoded by SASL.
1215 * The data will be written either straight onto the socket, or
1216 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1218 * NB, it is theoretically possible to have 2 layers of encryption,
1219 * both SASL, and this TLS layer. It is highly unlikely in practice
1220 * though, since SASL encryption will typically be a no-op if TLS
1223 * Returns the number of bytes written, which may be less than
1224 * the requested 'datalen' if the socket would block. Returns
1225 * -1 on error, and disconnects the client socket.
1227 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1231 ret
= qio_channel_write(
1232 vs
->ioc
, (const char *)data
, datalen
, &err
);
1233 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1234 return vnc_client_io_error(vs
, ret
, &err
);
1239 * Called to write buffered data to the client socket, when not
1240 * using any SASL SSF encryption layers. Will write as much data
1241 * as possible without blocking. If all buffered data is written,
1242 * will switch the FD poll() handler back to read monitoring.
1244 * Returns the number of bytes written, which may be less than
1245 * the buffered output data if the socket would block. Returns
1246 * -1 on error, and disconnects the client socket.
1248 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1252 #ifdef CONFIG_VNC_SASL
1253 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1254 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1255 vs
->sasl
.waitWriteSSF
);
1257 if (vs
->sasl
.conn
&&
1259 vs
->sasl
.waitWriteSSF
) {
1260 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1262 vs
->sasl
.waitWriteSSF
-= ret
;
1264 #endif /* CONFIG_VNC_SASL */
1265 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1269 buffer_advance(&vs
->output
, ret
);
1271 if (vs
->output
.offset
== 0) {
1273 g_source_remove(vs
->ioc_tag
);
1275 vs
->ioc_tag
= qio_channel_add_watch(
1276 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1284 * First function called whenever there is data to be written to
1285 * the client socket. Will delegate actual work according to whether
1286 * SASL SSF layers are enabled (thus requiring encryption calls)
1288 static void vnc_client_write_locked(VncState
*vs
)
1290 #ifdef CONFIG_VNC_SASL
1291 if (vs
->sasl
.conn
&&
1293 !vs
->sasl
.waitWriteSSF
) {
1294 vnc_client_write_sasl(vs
);
1296 #endif /* CONFIG_VNC_SASL */
1298 vnc_client_write_plain(vs
);
1302 static void vnc_client_write(VncState
*vs
)
1305 vnc_lock_output(vs
);
1306 if (vs
->output
.offset
) {
1307 vnc_client_write_locked(vs
);
1308 } else if (vs
->ioc
!= NULL
) {
1310 g_source_remove(vs
->ioc_tag
);
1312 vs
->ioc_tag
= qio_channel_add_watch(
1313 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1315 vnc_unlock_output(vs
);
1318 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1320 vs
->read_handler
= func
;
1321 vs
->read_handler_expect
= expecting
;
1326 * Called to read a chunk of data from the client socket. The data may
1327 * be the raw data, or may need to be further decoded by SASL.
1328 * The data will be read either straight from to the socket, or
1329 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1331 * NB, it is theoretically possible to have 2 layers of encryption,
1332 * both SASL, and this TLS layer. It is highly unlikely in practice
1333 * though, since SASL encryption will typically be a no-op if TLS
1336 * Returns the number of bytes read, which may be less than
1337 * the requested 'datalen' if the socket would block. Returns
1338 * -1 on error, and disconnects the client socket.
1340 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1344 ret
= qio_channel_read(
1345 vs
->ioc
, (char *)data
, datalen
, &err
);
1346 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1347 return vnc_client_io_error(vs
, ret
, &err
);
1352 * Called to read data from the client socket to the input buffer,
1353 * when not using any SASL SSF encryption layers. Will read as much
1354 * data as possible without blocking.
1356 * Returns the number of bytes read. Returns -1 on error, and
1357 * disconnects the client socket.
1359 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1362 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1363 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1364 buffer_reserve(&vs
->input
, 4096);
1365 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1368 vs
->input
.offset
+= ret
;
1372 static void vnc_jobs_bh(void *opaque
)
1374 VncState
*vs
= opaque
;
1376 vnc_jobs_consume_buffer(vs
);
1380 * First function called whenever there is more data to be read from
1381 * the client socket. Will delegate actual work according to whether
1382 * SASL SSF layers are enabled (thus requiring decryption calls)
1383 * Returns 0 on success, -1 if client disconnected
1385 static int vnc_client_read(VncState
*vs
)
1389 #ifdef CONFIG_VNC_SASL
1390 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1391 ret
= vnc_client_read_sasl(vs
);
1393 #endif /* CONFIG_VNC_SASL */
1394 ret
= vnc_client_read_plain(vs
);
1396 if (vs
->disconnecting
) {
1397 vnc_disconnect_finish(vs
);
1403 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1404 size_t len
= vs
->read_handler_expect
;
1407 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1408 if (vs
->disconnecting
) {
1409 vnc_disconnect_finish(vs
);
1414 buffer_advance(&vs
->input
, len
);
1416 vs
->read_handler_expect
= ret
;
1422 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1423 GIOCondition condition
, void *opaque
)
1425 VncState
*vs
= opaque
;
1426 if (condition
& G_IO_IN
) {
1427 if (vnc_client_read(vs
) < 0) {
1431 if (condition
& G_IO_OUT
) {
1432 vnc_client_write(vs
);
1438 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1440 buffer_reserve(&vs
->output
, len
);
1442 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1444 g_source_remove(vs
->ioc_tag
);
1446 vs
->ioc_tag
= qio_channel_add_watch(
1447 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1450 buffer_append(&vs
->output
, data
, len
);
1453 void vnc_write_s32(VncState
*vs
, int32_t value
)
1455 vnc_write_u32(vs
, *(uint32_t *)&value
);
1458 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1462 buf
[0] = (value
>> 24) & 0xFF;
1463 buf
[1] = (value
>> 16) & 0xFF;
1464 buf
[2] = (value
>> 8) & 0xFF;
1465 buf
[3] = value
& 0xFF;
1467 vnc_write(vs
, buf
, 4);
1470 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1474 buf
[0] = (value
>> 8) & 0xFF;
1475 buf
[1] = value
& 0xFF;
1477 vnc_write(vs
, buf
, 2);
1480 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1482 vnc_write(vs
, (char *)&value
, 1);
1485 void vnc_flush(VncState
*vs
)
1487 vnc_lock_output(vs
);
1488 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1489 vnc_client_write_locked(vs
);
1491 vnc_unlock_output(vs
);
1494 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1496 return data
[offset
];
1499 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1501 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1504 static int32_t read_s32(uint8_t *data
, size_t offset
)
1506 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1507 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1510 uint32_t read_u32(uint8_t *data
, size_t offset
)
1512 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1513 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1516 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1520 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1522 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1523 int absolute
= qemu_input_is_absolute();
1525 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1526 vnc_lock_output(vs
);
1527 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1528 vnc_write_u8(vs
, 0);
1529 vnc_write_u16(vs
, 1);
1530 vnc_framebuffer_update(vs
, absolute
, 0,
1531 pixman_image_get_width(vs
->vd
->server
),
1532 pixman_image_get_height(vs
->vd
->server
),
1533 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1534 vnc_unlock_output(vs
);
1537 vs
->absolute
= absolute
;
1540 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1542 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1543 [INPUT_BUTTON_LEFT
] = 0x01,
1544 [INPUT_BUTTON_MIDDLE
] = 0x02,
1545 [INPUT_BUTTON_RIGHT
] = 0x04,
1546 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1547 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1549 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1550 int width
= pixman_image_get_width(vs
->vd
->server
);
1551 int height
= pixman_image_get_height(vs
->vd
->server
);
1553 if (vs
->last_bmask
!= button_mask
) {
1554 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1555 vs
->last_bmask
= button_mask
;
1559 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, width
);
1560 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, height
);
1561 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1562 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1563 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1565 if (vs
->last_x
!= -1) {
1566 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1567 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1572 qemu_input_event_sync();
1575 static void reset_keys(VncState
*vs
)
1578 for(i
= 0; i
< 256; i
++) {
1579 if (vs
->modifiers_state
[i
]) {
1580 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1581 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1582 vs
->modifiers_state
[i
] = 0;
1587 static void press_key(VncState
*vs
, int keysym
)
1589 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1590 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1591 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1592 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1593 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1596 static void vnc_led_state_change(VncState
*vs
)
1598 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1602 vnc_lock_output(vs
);
1603 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1604 vnc_write_u8(vs
, 0);
1605 vnc_write_u16(vs
, 1);
1606 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1607 vnc_write_u8(vs
, vs
->vd
->ledstate
);
1608 vnc_unlock_output(vs
);
1612 static void kbd_leds(void *opaque
, int ledstate
)
1614 VncDisplay
*vd
= opaque
;
1617 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1618 (ledstate
& QEMU_NUM_LOCK_LED
),
1619 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1621 if (ledstate
== vd
->ledstate
) {
1625 vd
->ledstate
= ledstate
;
1627 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
1628 vnc_led_state_change(client
);
1632 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1634 /* QEMU console switch */
1636 case 0x2a: /* Left Shift */
1637 case 0x36: /* Right Shift */
1638 case 0x1d: /* Left CTRL */
1639 case 0x9d: /* Right CTRL */
1640 case 0x38: /* Left ALT */
1641 case 0xb8: /* Right ALT */
1643 vs
->modifiers_state
[keycode
] = 1;
1645 vs
->modifiers_state
[keycode
] = 0;
1647 case 0x02 ... 0x0a: /* '1' to '9' keys */
1648 if (vs
->vd
->dcl
.con
== NULL
&&
1649 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1650 /* Reset the modifiers sent to the current console */
1652 console_select(keycode
- 0x02);
1656 case 0x3a: /* CapsLock */
1657 case 0x45: /* NumLock */
1659 vs
->modifiers_state
[keycode
] ^= 1;
1663 /* Turn off the lock state sync logic if the client support the led
1666 if (down
&& vs
->vd
->lock_key_sync
&&
1667 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1668 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1669 /* If the numlock state needs to change then simulate an additional
1670 keypress before sending this one. This will happen if the user
1671 toggles numlock away from the VNC window.
1673 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1674 if (!vs
->modifiers_state
[0x45]) {
1675 trace_vnc_key_sync_numlock(true);
1676 vs
->modifiers_state
[0x45] = 1;
1677 press_key(vs
, 0xff7f);
1680 if (vs
->modifiers_state
[0x45]) {
1681 trace_vnc_key_sync_numlock(false);
1682 vs
->modifiers_state
[0x45] = 0;
1683 press_key(vs
, 0xff7f);
1688 if (down
&& vs
->vd
->lock_key_sync
&&
1689 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1690 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1691 /* If the capslock state needs to change then simulate an additional
1692 keypress before sending this one. This will happen if the user
1693 toggles capslock away from the VNC window.
1695 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1696 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1697 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1699 if (uppercase
== shift
) {
1700 trace_vnc_key_sync_capslock(false);
1701 vs
->modifiers_state
[0x3a] = 0;
1702 press_key(vs
, 0xffe5);
1705 if (uppercase
!= shift
) {
1706 trace_vnc_key_sync_capslock(true);
1707 vs
->modifiers_state
[0x3a] = 1;
1708 press_key(vs
, 0xffe5);
1713 if (qemu_console_is_graphic(NULL
)) {
1714 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1715 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1717 bool numlock
= vs
->modifiers_state
[0x45];
1718 bool control
= (vs
->modifiers_state
[0x1d] ||
1719 vs
->modifiers_state
[0x9d]);
1720 /* QEMU console emulation */
1723 case 0x2a: /* Left Shift */
1724 case 0x36: /* Right Shift */
1725 case 0x1d: /* Left CTRL */
1726 case 0x9d: /* Right CTRL */
1727 case 0x38: /* Left ALT */
1728 case 0xb8: /* Right ALT */
1731 kbd_put_keysym(QEMU_KEY_UP
);
1734 kbd_put_keysym(QEMU_KEY_DOWN
);
1737 kbd_put_keysym(QEMU_KEY_LEFT
);
1740 kbd_put_keysym(QEMU_KEY_RIGHT
);
1743 kbd_put_keysym(QEMU_KEY_DELETE
);
1746 kbd_put_keysym(QEMU_KEY_HOME
);
1749 kbd_put_keysym(QEMU_KEY_END
);
1752 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1755 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1759 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1762 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1765 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1768 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1771 kbd_put_keysym('5');
1774 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1777 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1780 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1783 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1786 kbd_put_keysym('0');
1789 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1793 kbd_put_keysym('/');
1796 kbd_put_keysym('*');
1799 kbd_put_keysym('-');
1802 kbd_put_keysym('+');
1805 kbd_put_keysym('\n');
1810 kbd_put_keysym(sym
& 0x1f);
1812 kbd_put_keysym(sym
);
1820 static void vnc_release_modifiers(VncState
*vs
)
1822 static const int keycodes
[] = {
1823 /* shift, control, alt keys, both left & right */
1824 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1828 if (!qemu_console_is_graphic(NULL
)) {
1831 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1832 keycode
= keycodes
[i
];
1833 if (!vs
->modifiers_state
[keycode
]) {
1836 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1837 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1841 static const char *code2name(int keycode
)
1843 return QKeyCode_lookup
[qemu_input_key_number_to_qcode(keycode
)];
1846 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1851 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1852 lsym
= lsym
- 'A' + 'a';
1855 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1856 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1857 do_key_event(vs
, down
, keycode
, sym
);
1860 static void ext_key_event(VncState
*vs
, int down
,
1861 uint32_t sym
, uint16_t keycode
)
1863 /* if the user specifies a keyboard layout, always use it */
1864 if (keyboard_layout
) {
1865 key_event(vs
, down
, sym
);
1867 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
1868 do_key_event(vs
, down
, keycode
, sym
);
1872 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1873 int x
, int y
, int w
, int h
)
1875 vs
->need_update
= 1;
1881 vs
->force_update
= 1;
1882 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
1885 static void send_ext_key_event_ack(VncState
*vs
)
1887 vnc_lock_output(vs
);
1888 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1889 vnc_write_u8(vs
, 0);
1890 vnc_write_u16(vs
, 1);
1891 vnc_framebuffer_update(vs
, 0, 0,
1892 pixman_image_get_width(vs
->vd
->server
),
1893 pixman_image_get_height(vs
->vd
->server
),
1894 VNC_ENCODING_EXT_KEY_EVENT
);
1895 vnc_unlock_output(vs
);
1899 static void send_ext_audio_ack(VncState
*vs
)
1901 vnc_lock_output(vs
);
1902 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1903 vnc_write_u8(vs
, 0);
1904 vnc_write_u16(vs
, 1);
1905 vnc_framebuffer_update(vs
, 0, 0,
1906 pixman_image_get_width(vs
->vd
->server
),
1907 pixman_image_get_height(vs
->vd
->server
),
1908 VNC_ENCODING_AUDIO
);
1909 vnc_unlock_output(vs
);
1913 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
1916 unsigned int enc
= 0;
1919 vs
->vnc_encoding
= 0;
1920 vs
->tight
.compression
= 9;
1921 vs
->tight
.quality
= -1; /* Lossless by default */
1925 * Start from the end because the encodings are sent in order of preference.
1926 * This way the preferred encoding (first encoding defined in the array)
1927 * will be set at the end of the loop.
1929 for (i
= n_encodings
- 1; i
>= 0; i
--) {
1932 case VNC_ENCODING_RAW
:
1933 vs
->vnc_encoding
= enc
;
1935 case VNC_ENCODING_COPYRECT
:
1936 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
1938 case VNC_ENCODING_HEXTILE
:
1939 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
1940 vs
->vnc_encoding
= enc
;
1942 case VNC_ENCODING_TIGHT
:
1943 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
1944 vs
->vnc_encoding
= enc
;
1946 #ifdef CONFIG_VNC_PNG
1947 case VNC_ENCODING_TIGHT_PNG
:
1948 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
1949 vs
->vnc_encoding
= enc
;
1952 case VNC_ENCODING_ZLIB
:
1953 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
1954 vs
->vnc_encoding
= enc
;
1956 case VNC_ENCODING_ZRLE
:
1957 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
1958 vs
->vnc_encoding
= enc
;
1960 case VNC_ENCODING_ZYWRLE
:
1961 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
1962 vs
->vnc_encoding
= enc
;
1964 case VNC_ENCODING_DESKTOPRESIZE
:
1965 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
1967 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
1968 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
1970 case VNC_ENCODING_RICH_CURSOR
:
1971 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
1972 if (vs
->vd
->cursor
) {
1973 vnc_cursor_define(vs
);
1976 case VNC_ENCODING_EXT_KEY_EVENT
:
1977 send_ext_key_event_ack(vs
);
1979 case VNC_ENCODING_AUDIO
:
1980 send_ext_audio_ack(vs
);
1982 case VNC_ENCODING_WMVi
:
1983 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
1985 case VNC_ENCODING_LED_STATE
:
1986 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
1988 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
1989 vs
->tight
.compression
= (enc
& 0x0F);
1991 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
1992 if (vs
->vd
->lossy
) {
1993 vs
->tight
.quality
= (enc
& 0x0F);
1997 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2001 vnc_desktop_resize(vs
);
2002 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2003 vnc_led_state_change(vs
);
2006 static void set_pixel_conversion(VncState
*vs
)
2008 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2010 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2011 vs
->write_pixels
= vnc_write_pixels_copy
;
2012 vnc_hextile_set_pixel_conversion(vs
, 0);
2014 vs
->write_pixels
= vnc_write_pixels_generic
;
2015 vnc_hextile_set_pixel_conversion(vs
, 1);
2019 static void send_color_map(VncState
*vs
)
2023 vnc_write_u8(vs
, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES
);
2024 vnc_write_u8(vs
, 0); /* padding */
2025 vnc_write_u16(vs
, 0); /* first color */
2026 vnc_write_u16(vs
, 256); /* # of colors */
2028 for (i
= 0; i
< 256; i
++) {
2029 PixelFormat
*pf
= &vs
->client_pf
;
2031 vnc_write_u16(vs
, (((i
>> pf
->rshift
) & pf
->rmax
) << (16 - pf
->rbits
)));
2032 vnc_write_u16(vs
, (((i
>> pf
->gshift
) & pf
->gmax
) << (16 - pf
->gbits
)));
2033 vnc_write_u16(vs
, (((i
>> pf
->bshift
) & pf
->bmax
) << (16 - pf
->bbits
)));
2037 static void set_pixel_format(VncState
*vs
, int bits_per_pixel
,
2038 int big_endian_flag
, int true_color_flag
,
2039 int red_max
, int green_max
, int blue_max
,
2040 int red_shift
, int green_shift
, int blue_shift
)
2042 if (!true_color_flag
) {
2043 /* Expose a reasonable default 256 color map */
2053 switch (bits_per_pixel
) {
2059 vnc_client_error(vs
);
2063 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2064 vs
->client_pf
.rbits
= hweight_long(red_max
);
2065 vs
->client_pf
.rshift
= red_shift
;
2066 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2067 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2068 vs
->client_pf
.gbits
= hweight_long(green_max
);
2069 vs
->client_pf
.gshift
= green_shift
;
2070 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2071 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2072 vs
->client_pf
.bbits
= hweight_long(blue_max
);
2073 vs
->client_pf
.bshift
= blue_shift
;
2074 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2075 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2076 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2077 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2078 vs
->client_be
= big_endian_flag
;
2080 if (!true_color_flag
) {
2084 set_pixel_conversion(vs
);
2086 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2087 graphic_hw_update(vs
->vd
->dcl
.con
);
2090 static void pixel_format_message (VncState
*vs
) {
2091 char pad
[3] = { 0, 0, 0 };
2093 vs
->client_pf
= qemu_default_pixelformat(32);
2095 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2096 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2098 #ifdef HOST_WORDS_BIGENDIAN
2099 vnc_write_u8(vs
, 1); /* big-endian-flag */
2101 vnc_write_u8(vs
, 0); /* big-endian-flag */
2103 vnc_write_u8(vs
, 1); /* true-color-flag */
2104 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2105 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2106 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2107 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2108 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2109 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2110 vnc_write(vs
, pad
, 3); /* padding */
2112 vnc_hextile_set_pixel_conversion(vs
, 0);
2113 vs
->write_pixels
= vnc_write_pixels_copy
;
2116 static void vnc_colordepth(VncState
*vs
)
2118 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2119 /* Sending a WMVi message to notify the client*/
2120 vnc_lock_output(vs
);
2121 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2122 vnc_write_u8(vs
, 0);
2123 vnc_write_u16(vs
, 1); /* number of rects */
2124 vnc_framebuffer_update(vs
, 0, 0,
2125 pixman_image_get_width(vs
->vd
->server
),
2126 pixman_image_get_height(vs
->vd
->server
),
2128 pixel_format_message(vs
);
2129 vnc_unlock_output(vs
);
2132 set_pixel_conversion(vs
);
2136 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2140 VncDisplay
*vd
= vs
->vd
;
2143 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2147 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2151 set_pixel_format(vs
, read_u8(data
, 4),
2152 read_u8(data
, 6), read_u8(data
, 7),
2153 read_u16(data
, 8), read_u16(data
, 10),
2154 read_u16(data
, 12), read_u8(data
, 14),
2155 read_u8(data
, 15), read_u8(data
, 16));
2157 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2162 limit
= read_u16(data
, 2);
2164 return 4 + (limit
* 4);
2166 limit
= read_u16(data
, 2);
2168 for (i
= 0; i
< limit
; i
++) {
2169 int32_t val
= read_s32(data
, 4 + (i
* 4));
2170 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2173 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2175 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2179 framebuffer_update_request(vs
,
2180 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2181 read_u16(data
, 6), read_u16(data
, 8));
2183 case VNC_MSG_CLIENT_KEY_EVENT
:
2187 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2189 case VNC_MSG_CLIENT_POINTER_EVENT
:
2193 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2195 case VNC_MSG_CLIENT_CUT_TEXT
:
2200 uint32_t dlen
= read_u32(data
, 4);
2201 if (dlen
> (1 << 20)) {
2202 error_report("vnc: client_cut_text msg payload has %u bytes"
2203 " which exceeds our limit of 1MB.", dlen
);
2204 vnc_client_error(vs
);
2212 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2214 case VNC_MSG_CLIENT_QEMU
:
2218 switch (read_u8(data
, 1)) {
2219 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2223 ext_key_event(vs
, read_u16(data
, 2),
2224 read_u32(data
, 4), read_u32(data
, 8));
2226 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2230 switch (read_u16 (data
, 2)) {
2231 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2234 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2237 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2240 switch (read_u8(data
, 4)) {
2241 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2242 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2243 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2244 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2245 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2246 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2248 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2249 vnc_client_error(vs
);
2252 vs
->as
.nchannels
= read_u8(data
, 5);
2253 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2254 VNC_DEBUG("Invalid audio channel coount %d\n",
2256 vnc_client_error(vs
);
2259 vs
->as
.freq
= read_u32(data
, 6);
2262 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2263 vnc_client_error(vs
);
2269 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2270 vnc_client_error(vs
);
2275 VNC_DEBUG("Msg: %d\n", data
[0]);
2276 vnc_client_error(vs
);
2280 vnc_read_when(vs
, protocol_client_msg
, 1);
2284 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2290 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2291 switch (vs
->vd
->share_policy
) {
2292 case VNC_SHARE_POLICY_IGNORE
:
2294 * Ignore the shared flag. Nothing to do here.
2296 * Doesn't conform to the rfb spec but is traditional qemu
2297 * behavior, thus left here as option for compatibility
2301 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2303 * Policy: Allow clients ask for exclusive access.
2305 * Implementation: When a client asks for exclusive access,
2306 * disconnect all others. Shared connects are allowed as long
2307 * as no exclusive connection exists.
2309 * This is how the rfb spec suggests to handle the shared flag.
2311 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2313 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2317 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2318 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2321 vnc_disconnect_start(client
);
2324 if (mode
== VNC_SHARE_MODE_SHARED
) {
2325 if (vs
->vd
->num_exclusive
> 0) {
2326 vnc_disconnect_start(vs
);
2331 case VNC_SHARE_POLICY_FORCE_SHARED
:
2333 * Policy: Shared connects only.
2334 * Implementation: Disallow clients asking for exclusive access.
2336 * Useful for shared desktop sessions where you don't want
2337 * someone forgetting to say -shared when running the vnc
2338 * client disconnect everybody else.
2340 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2341 vnc_disconnect_start(vs
);
2346 vnc_set_share_mode(vs
, mode
);
2348 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2349 vnc_disconnect_start(vs
);
2353 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2354 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2355 vnc_write_u16(vs
, vs
->client_width
);
2356 vnc_write_u16(vs
, vs
->client_height
);
2358 pixel_format_message(vs
);
2361 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2362 if (size
> sizeof(buf
)) {
2366 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2369 vnc_write_u32(vs
, size
);
2370 vnc_write(vs
, buf
, size
);
2373 vnc_client_cache_auth(vs
);
2374 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2376 vnc_read_when(vs
, protocol_client_msg
, 1);
2381 void start_client_init(VncState
*vs
)
2383 vnc_read_when(vs
, protocol_client_init
, 1);
2386 static void make_challenge(VncState
*vs
)
2390 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2392 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2393 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2396 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2398 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2400 unsigned char key
[8];
2401 time_t now
= time(NULL
);
2402 QCryptoCipher
*cipher
= NULL
;
2405 if (!vs
->vd
->password
) {
2406 VNC_DEBUG("No password configured on server");
2409 if (vs
->vd
->expires
< now
) {
2410 VNC_DEBUG("Password is expired");
2414 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2416 /* Calculate the expected challenge response */
2417 pwlen
= strlen(vs
->vd
->password
);
2418 for (i
=0; i
<sizeof(key
); i
++)
2419 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2421 cipher
= qcrypto_cipher_new(
2422 QCRYPTO_CIPHER_ALG_DES_RFB
,
2423 QCRYPTO_CIPHER_MODE_ECB
,
2424 key
, G_N_ELEMENTS(key
),
2427 VNC_DEBUG("Cannot initialize cipher %s",
2428 error_get_pretty(err
));
2433 if (qcrypto_cipher_encrypt(cipher
,
2436 VNC_AUTH_CHALLENGE_SIZE
,
2438 VNC_DEBUG("Cannot encrypt challenge %s",
2439 error_get_pretty(err
));
2444 /* Compare expected vs actual challenge response */
2445 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2446 VNC_DEBUG("Client challenge response did not match\n");
2449 VNC_DEBUG("Accepting VNC challenge response\n");
2450 vnc_write_u32(vs
, 0); /* Accept auth */
2453 start_client_init(vs
);
2456 qcrypto_cipher_free(cipher
);
2460 vnc_write_u32(vs
, 1); /* Reject auth */
2461 if (vs
->minor
>= 8) {
2462 static const char err
[] = "Authentication failed";
2463 vnc_write_u32(vs
, sizeof(err
));
2464 vnc_write(vs
, err
, sizeof(err
));
2467 vnc_client_error(vs
);
2468 qcrypto_cipher_free(cipher
);
2472 void start_auth_vnc(VncState
*vs
)
2475 /* Send client a 'random' challenge */
2476 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2479 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2483 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2485 /* We only advertise 1 auth scheme at a time, so client
2486 * must pick the one we sent. Verify this */
2487 if (data
[0] != vs
->auth
) { /* Reject auth */
2488 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2489 vnc_write_u32(vs
, 1);
2490 if (vs
->minor
>= 8) {
2491 static const char err
[] = "Authentication failed";
2492 vnc_write_u32(vs
, sizeof(err
));
2493 vnc_write(vs
, err
, sizeof(err
));
2495 vnc_client_error(vs
);
2496 } else { /* Accept requested auth */
2497 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2500 VNC_DEBUG("Accept auth none\n");
2501 if (vs
->minor
>= 8) {
2502 vnc_write_u32(vs
, 0); /* Accept auth completion */
2505 start_client_init(vs
);
2509 VNC_DEBUG("Start VNC auth\n");
2513 case VNC_AUTH_VENCRYPT
:
2514 VNC_DEBUG("Accept VeNCrypt auth\n");
2515 start_auth_vencrypt(vs
);
2518 #ifdef CONFIG_VNC_SASL
2520 VNC_DEBUG("Accept SASL auth\n");
2521 start_auth_sasl(vs
);
2523 #endif /* CONFIG_VNC_SASL */
2525 default: /* Should not be possible, but just in case */
2526 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2527 vnc_write_u8(vs
, 1);
2528 if (vs
->minor
>= 8) {
2529 static const char err
[] = "Authentication failed";
2530 vnc_write_u32(vs
, sizeof(err
));
2531 vnc_write(vs
, err
, sizeof(err
));
2533 vnc_client_error(vs
);
2539 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2543 memcpy(local
, version
, 12);
2546 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2547 VNC_DEBUG("Malformed protocol version %s\n", local
);
2548 vnc_client_error(vs
);
2551 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2552 if (vs
->major
!= 3 ||
2558 VNC_DEBUG("Unsupported client version\n");
2559 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2561 vnc_client_error(vs
);
2564 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2565 * as equivalent to v3.3 by servers
2567 if (vs
->minor
== 4 || vs
->minor
== 5)
2570 if (vs
->minor
== 3) {
2571 if (vs
->auth
== VNC_AUTH_NONE
) {
2572 VNC_DEBUG("Tell client auth none\n");
2573 vnc_write_u32(vs
, vs
->auth
);
2575 start_client_init(vs
);
2576 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2577 VNC_DEBUG("Tell client VNC auth\n");
2578 vnc_write_u32(vs
, vs
->auth
);
2582 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2583 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2585 vnc_client_error(vs
);
2588 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2589 vnc_write_u8(vs
, 1); /* num auth */
2590 vnc_write_u8(vs
, vs
->auth
);
2591 vnc_read_when(vs
, protocol_client_auth
, 1);
2598 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2600 struct VncSurface
*vs
= &vd
->guest
;
2602 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2605 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2609 w
= (x
+ w
) / VNC_STAT_RECT
;
2610 h
= (y
+ h
) / VNC_STAT_RECT
;
2614 for (j
= y
; j
<= h
; j
++) {
2615 for (i
= x
; i
<= w
; i
++) {
2616 vs
->lossy_rect
[j
][i
] = 1;
2621 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2624 int sty
= y
/ VNC_STAT_RECT
;
2625 int stx
= x
/ VNC_STAT_RECT
;
2628 y
= y
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2629 x
= x
/ VNC_STAT_RECT
* VNC_STAT_RECT
;
2631 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2634 /* kernel send buffers are full -> refresh later */
2635 if (vs
->output
.offset
) {
2639 if (!vs
->lossy_rect
[sty
][stx
]) {
2643 vs
->lossy_rect
[sty
][stx
] = 0;
2644 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2645 bitmap_set(vs
->dirty
[y
+ j
],
2646 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2647 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2655 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2657 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2658 pixman_image_get_width(vd
->server
));
2659 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2660 pixman_image_get_height(vd
->server
));
2665 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2666 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2667 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2669 rect
->updated
= false;
2673 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2675 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2678 vd
->guest
.last_freq_check
= *tv
;
2680 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2681 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2682 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2683 int count
= ARRAY_SIZE(rect
->times
);
2684 struct timeval min
, max
;
2686 if (!timerisset(&rect
->times
[count
- 1])) {
2690 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2691 qemu_timersub(tv
, &max
, &res
);
2693 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2695 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2696 memset(rect
->times
, 0, sizeof (rect
->times
));
2700 min
= rect
->times
[rect
->idx
];
2701 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2702 qemu_timersub(&max
, &min
, &res
);
2704 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2705 rect
->freq
/= count
;
2706 rect
->freq
= 1. / rect
->freq
;
2712 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2718 x
= (x
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2719 y
= (y
/ VNC_STAT_RECT
) * VNC_STAT_RECT
;
2721 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2722 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2723 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2735 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2739 rect
= vnc_stat_rect(vd
, x
, y
);
2740 if (rect
->updated
) {
2743 rect
->times
[rect
->idx
] = *tv
;
2744 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2745 rect
->updated
= true;
2748 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2750 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2751 pixman_image_get_width(vd
->server
));
2752 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2753 pixman_image_get_height(vd
->server
));
2754 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2755 uint8_t *guest_row0
= NULL
, *server_row0
;
2758 pixman_image_t
*tmpbuf
= NULL
;
2760 struct timeval tv
= { 0, 0 };
2762 if (!vd
->non_adaptive
) {
2763 gettimeofday(&tv
, NULL
);
2764 has_dirty
= vnc_update_stats(vd
, &tv
);
2768 * Walk through the guest dirty map.
2769 * Check and copy modified bits from guest to server surface.
2770 * Update server dirty map.
2772 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2773 server_stride
= guest_stride
= guest_ll
=
2774 pixman_image_get_stride(vd
->server
);
2775 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2777 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2778 int width
= pixman_image_get_width(vd
->server
);
2779 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2782 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2783 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2784 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2785 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * ((guest_bpp
+ 7) / 8);
2787 line_bytes
= MIN(server_stride
, guest_ll
);
2791 uint8_t *guest_ptr
, *server_ptr
;
2792 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2793 height
* VNC_DIRTY_BPL(&vd
->guest
),
2794 y
* VNC_DIRTY_BPL(&vd
->guest
));
2795 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2796 /* no more dirty bits */
2799 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2800 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2802 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2804 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2805 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2806 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2808 guest_ptr
= guest_row0
+ y
* guest_stride
;
2810 guest_ptr
+= x
* cmp_bytes
;
2812 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2813 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2814 int _cmp_bytes
= cmp_bytes
;
2815 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2818 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2819 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2821 assert(_cmp_bytes
>= 0);
2822 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2825 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2826 if (!vd
->non_adaptive
) {
2827 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2830 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2831 set_bit(x
, vs
->dirty
[y
]);
2838 qemu_pixman_image_unref(tmpbuf
);
2842 static void vnc_refresh(DisplayChangeListener
*dcl
)
2844 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2846 int has_dirty
, rects
= 0;
2848 if (QTAILQ_EMPTY(&vd
->clients
)) {
2849 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2853 graphic_hw_update(vd
->dcl
.con
);
2855 if (vnc_trylock_display(vd
)) {
2856 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2860 has_dirty
= vnc_refresh_server_surface(vd
);
2861 vnc_unlock_display(vd
);
2863 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2864 rects
+= vnc_update_client(vs
, has_dirty
, false);
2865 /* vs might be free()ed here */
2868 if (has_dirty
&& rects
) {
2869 vd
->dcl
.update_interval
/= 2;
2870 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2871 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2874 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2875 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2876 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2881 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2882 bool skipauth
, bool websocket
)
2884 VncState
*vs
= g_new0(VncState
, 1);
2885 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
2889 object_ref(OBJECT(vs
->sioc
));
2890 vs
->ioc
= QIO_CHANNEL(sioc
);
2891 object_ref(OBJECT(vs
->ioc
));
2894 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
2895 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
2896 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
2898 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
2899 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
2900 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
2901 #ifdef CONFIG_VNC_JPEG
2902 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
2904 #ifdef CONFIG_VNC_PNG
2905 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
2907 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
2908 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
2909 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
2910 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
2913 vs
->auth
= VNC_AUTH_NONE
;
2914 vs
->subauth
= VNC_AUTH_INVALID
;
2917 vs
->auth
= vd
->ws_auth
;
2918 vs
->subauth
= VNC_AUTH_INVALID
;
2920 vs
->auth
= vd
->auth
;
2921 vs
->subauth
= vd
->subauth
;
2924 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2925 sioc
, websocket
, vs
->auth
, vs
->subauth
);
2927 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
2928 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
2929 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
2932 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
2933 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2934 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
2938 vs
->ioc_tag
= qio_channel_add_watch(
2939 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
2941 vs
->ioc_tag
= qio_channel_add_watch(
2942 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
2945 vs
->ioc_tag
= qio_channel_add_watch(
2946 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
2949 vnc_client_cache_addr(vs
);
2950 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
2951 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
2956 vs
->as
.freq
= 44100;
2957 vs
->as
.nchannels
= 2;
2958 vs
->as
.fmt
= AUD_FMT_S16
;
2959 vs
->as
.endianness
= 0;
2961 qemu_mutex_init(&vs
->output_mutex
);
2962 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
2964 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
2966 vnc_update_server_surface(vd
);
2969 graphic_hw_update(vd
->dcl
.con
);
2971 if (!vs
->websocket
) {
2972 vnc_start_protocol(vs
);
2975 if (vd
->num_connecting
> vd
->connections_limit
) {
2976 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2977 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
2978 vnc_disconnect_start(vs
);
2985 void vnc_start_protocol(VncState
*vs
)
2987 vnc_write(vs
, "RFB 003.008\n", 12);
2989 vnc_read_when(vs
, protocol_version
, 12);
2991 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
2992 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
2995 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
2996 GIOCondition condition
,
2999 VncDisplay
*vd
= opaque
;
3000 QIOChannelSocket
*sioc
= NULL
;
3002 bool isWebsock
= false;
3005 for (i
= 0; i
< vd
->nlwebsock
; i
++) {
3006 if (ioc
== QIO_CHANNEL(vd
->lwebsock
[i
])) {
3012 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3014 qio_channel_set_name(QIO_CHANNEL(sioc
),
3015 isWebsock
? "vnc-ws-server" : "vnc-server");
3016 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3017 vnc_connect(vd
, sioc
, false, isWebsock
);
3018 object_unref(OBJECT(sioc
));
3020 /* client probably closed connection before we got there */
3027 static const DisplayChangeListenerOps dcl_ops
= {
3029 .dpy_refresh
= vnc_refresh
,
3030 .dpy_gfx_update
= vnc_dpy_update
,
3031 .dpy_gfx_switch
= vnc_dpy_switch
,
3032 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3033 .dpy_mouse_set
= vnc_mouse_set
,
3034 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3037 void vnc_display_init(const char *id
)
3041 if (vnc_display_find(id
) != NULL
) {
3044 vd
= g_malloc0(sizeof(*vd
));
3046 vd
->id
= strdup(id
);
3047 QTAILQ_INSERT_TAIL(&vnc_displays
, vd
, next
);
3049 QTAILQ_INIT(&vd
->clients
);
3050 vd
->expires
= TIME_MAX
;
3052 if (keyboard_layout
) {
3053 trace_vnc_key_map_init(keyboard_layout
);
3054 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3056 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3059 if (!vd
->kbd_layout
) {
3063 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3064 vd
->connections_limit
= 32;
3066 qemu_mutex_init(&vd
->mutex
);
3067 vnc_start_worker_thread();
3069 vd
->dcl
.ops
= &dcl_ops
;
3070 register_displaychangelistener(&vd
->dcl
);
3074 static void vnc_display_close(VncDisplay
*vd
)
3080 vd
->is_unix
= false;
3081 for (i
= 0; i
< vd
->nlsock
; i
++) {
3082 if (vd
->lsock_tag
[i
]) {
3083 g_source_remove(vd
->lsock_tag
[i
]);
3085 object_unref(OBJECT(vd
->lsock
[i
]));
3088 g_free(vd
->lsock_tag
);
3090 vd
->lsock_tag
= NULL
;
3093 for (i
= 0; i
< vd
->nlwebsock
; i
++) {
3094 if (vd
->lwebsock_tag
[i
]) {
3095 g_source_remove(vd
->lwebsock_tag
[i
]);
3097 object_unref(OBJECT(vd
->lwebsock
[i
]));
3099 g_free(vd
->lwebsock
);
3100 g_free(vd
->lwebsock_tag
);
3101 vd
->lwebsock
= NULL
;
3102 vd
->lwebsock_tag
= NULL
;
3105 vd
->auth
= VNC_AUTH_INVALID
;
3106 vd
->subauth
= VNC_AUTH_INVALID
;
3108 object_unparent(OBJECT(vd
->tlscreds
));
3109 vd
->tlscreds
= NULL
;
3111 g_free(vd
->tlsaclname
);
3112 vd
->tlsaclname
= NULL
;
3113 if (vd
->lock_key_sync
) {
3114 qemu_remove_led_event_handler(vd
->led
);
3119 int vnc_display_password(const char *id
, const char *password
)
3121 VncDisplay
*vd
= vnc_display_find(id
);
3126 if (vd
->auth
== VNC_AUTH_NONE
) {
3127 error_printf_unless_qmp("If you want use passwords please enable "
3128 "password auth using '-vnc ${dpy},password'.\n");
3132 g_free(vd
->password
);
3133 vd
->password
= g_strdup(password
);
3138 int vnc_display_pw_expire(const char *id
, time_t expires
)
3140 VncDisplay
*vd
= vnc_display_find(id
);
3146 vd
->expires
= expires
;
3150 static void vnc_display_print_local_addr(VncDisplay
*vd
)
3152 SocketAddress
*addr
;
3159 addr
= qio_channel_socket_get_local_address(vd
->lsock
[0], &err
);
3164 if (addr
->type
!= SOCKET_ADDRESS_TYPE_INET
) {
3165 qapi_free_SocketAddress(addr
);
3168 error_printf_unless_qmp("VNC server running on %s:%s\n",
3171 qapi_free_SocketAddress(addr
);
3174 static QemuOptsList qemu_vnc_opts
= {
3176 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3177 .implied_opt_name
= "vnc",
3181 .type
= QEMU_OPT_STRING
,
3183 .name
= "websocket",
3184 .type
= QEMU_OPT_STRING
,
3186 .name
= "tls-creds",
3187 .type
= QEMU_OPT_STRING
,
3189 /* Deprecated in favour of tls-creds */
3191 .type
= QEMU_OPT_STRING
,
3194 .type
= QEMU_OPT_STRING
,
3197 .type
= QEMU_OPT_STRING
,
3200 .type
= QEMU_OPT_NUMBER
,
3202 .name
= "connections",
3203 .type
= QEMU_OPT_NUMBER
,
3206 .type
= QEMU_OPT_NUMBER
,
3209 .type
= QEMU_OPT_BOOL
,
3212 .type
= QEMU_OPT_BOOL
,
3215 .type
= QEMU_OPT_BOOL
,
3218 .type
= QEMU_OPT_BOOL
,
3220 .name
= "lock-key-sync",
3221 .type
= QEMU_OPT_BOOL
,
3223 .name
= "key-delay-ms",
3224 .type
= QEMU_OPT_NUMBER
,
3227 .type
= QEMU_OPT_BOOL
,
3229 /* Deprecated in favour of tls-creds */
3231 .type
= QEMU_OPT_BOOL
,
3233 /* Deprecated in favour of tls-creds */
3234 .name
= "x509verify",
3235 .type
= QEMU_OPT_STRING
,
3238 .type
= QEMU_OPT_BOOL
,
3241 .type
= QEMU_OPT_BOOL
,
3243 .name
= "non-adaptive",
3244 .type
= QEMU_OPT_BOOL
,
3246 { /* end of list */ }
3252 vnc_display_setup_auth(int *auth
,
3254 QCryptoTLSCreds
*tlscreds
,
3261 * We have a choice of 3 authentication options
3267 * The channel can be run in 2 modes
3272 * And TLS can use 2 types of credentials
3277 * We thus have 9 possible logical combinations
3282 * 4. tls + anon + none
3283 * 5. tls + anon + vnc
3284 * 6. tls + anon + sasl
3285 * 7. tls + x509 + none
3286 * 8. tls + x509 + vnc
3287 * 9. tls + x509 + sasl
3289 * These need to be mapped into the VNC auth schemes
3290 * in an appropriate manner. In regular VNC, all the
3291 * TLS options get mapped into VNC_AUTH_VENCRYPT
3294 * In websockets, the https:// protocol already provides
3295 * TLS support, so there is no need to make use of the
3296 * VeNCrypt extension. Furthermore, websockets browser
3297 * clients could not use VeNCrypt even if they wanted to,
3298 * as they cannot control when the TLS handshake takes
3299 * place. Thus there is no option but to rely on https://,
3300 * meaning combinations 4->6 and 7->9 will be mapped to
3301 * VNC auth schemes in the same way as combos 1->3.
3303 * Regardless of fact that we have a different mapping to
3304 * VNC auth mechs for plain VNC vs websockets VNC, the end
3305 * result has the same security characteristics.
3307 if (websocket
|| !tlscreds
) {
3309 VNC_DEBUG("Initializing VNC server with password auth\n");
3310 *auth
= VNC_AUTH_VNC
;
3312 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3313 *auth
= VNC_AUTH_SASL
;
3315 VNC_DEBUG("Initializing VNC server with no auth\n");
3316 *auth
= VNC_AUTH_NONE
;
3318 *subauth
= VNC_AUTH_INVALID
;
3320 bool is_x509
= object_dynamic_cast(OBJECT(tlscreds
),
3321 TYPE_QCRYPTO_TLS_CREDS_X509
) != NULL
;
3322 bool is_anon
= object_dynamic_cast(OBJECT(tlscreds
),
3323 TYPE_QCRYPTO_TLS_CREDS_ANON
) != NULL
;
3325 if (!is_x509
&& !is_anon
) {
3327 "Unsupported TLS cred type %s",
3328 object_get_typename(OBJECT(tlscreds
)));
3331 *auth
= VNC_AUTH_VENCRYPT
;
3334 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3335 *subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3337 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3338 *subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3343 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3344 *subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3346 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3347 *subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3351 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3352 *subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3354 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3355 *subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3364 * Handle back compat with old CLI syntax by creating some
3365 * suitable QCryptoTLSCreds objects
3367 static QCryptoTLSCreds
*
3368 vnc_display_create_creds(bool x509
,
3374 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3375 Object
*parent
= object_get_objects_root();
3380 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3384 "endpoint", "server",
3386 "verify-peer", x509verify
? "yes" : "no",
3389 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3393 "endpoint", "server",
3400 error_propagate(errp
, err
);
3404 return QCRYPTO_TLS_CREDS(creds
);
3408 static int vnc_display_get_address(const char *addrstr
,
3417 SocketAddress
**retaddr
,
3421 SocketAddress
*addr
= NULL
;
3423 addr
= g_new0(SocketAddress
, 1);
3425 if (strncmp(addrstr
, "unix:", 5) == 0) {
3426 addr
->type
= SOCKET_ADDRESS_TYPE_UNIX
;
3427 addr
->u
.q_unix
.path
= g_strdup(addrstr
+ 5);
3430 error_setg(errp
, "UNIX sockets not supported with websock");
3435 error_setg(errp
, "Port range not support with UNIX socket");
3442 unsigned long long baseport
= 0;
3443 InetSocketAddress
*inet
;
3445 port
= strrchr(addrstr
, ':');
3451 error_setg(errp
, "no vnc port specified");
3455 hostlen
= port
- addrstr
;
3457 if (*port
== '\0') {
3458 error_setg(errp
, "vnc port cannot be empty");
3463 addr
->type
= SOCKET_ADDRESS_TYPE_INET
;
3464 inet
= &addr
->u
.inet
;
3465 if (addrstr
[0] == '[' && addrstr
[hostlen
- 1] == ']') {
3466 inet
->host
= g_strndup(addrstr
+ 1, hostlen
- 2);
3468 inet
->host
= g_strndup(addrstr
, hostlen
);
3470 /* plain VNC port is just an offset, for websocket
3471 * port is absolute */
3473 if (g_str_equal(addrstr
, "") ||
3474 g_str_equal(addrstr
, "on")) {
3475 if (displaynum
== -1) {
3476 error_setg(errp
, "explicit websocket port is required");
3479 inet
->port
= g_strdup_printf(
3480 "%d", displaynum
+ 5700);
3482 inet
->has_to
= true;
3483 inet
->to
= to
+ 5700;
3486 inet
->port
= g_strdup(port
);
3489 int offset
= reverse
? 0 : 5900;
3490 if (parse_uint_full(port
, &baseport
, 10) < 0) {
3491 error_setg(errp
, "can't convert to a number: %s", port
);
3494 if (baseport
> 65535 ||
3495 baseport
+ offset
> 65535) {
3496 error_setg(errp
, "port %s out of range", port
);
3499 inet
->port
= g_strdup_printf(
3500 "%d", (int)baseport
+ offset
);
3503 inet
->has_to
= true;
3504 inet
->to
= to
+ offset
;
3509 inet
->has_ipv4
= has_ipv4
;
3511 inet
->has_ipv6
= has_ipv6
;
3520 qapi_free_SocketAddress(addr
);
3525 static int vnc_display_get_addresses(QemuOpts
*opts
,
3527 SocketAddress
***retsaddr
,
3529 SocketAddress
***retwsaddr
,
3533 SocketAddress
*saddr
= NULL
;
3534 SocketAddress
*wsaddr
= NULL
;
3535 QemuOptsIter addriter
;
3537 int to
= qemu_opt_get_number(opts
, "to", 0);
3538 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3539 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3540 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3541 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3543 int displaynum
= -1;
3551 addr
= qemu_opt_get(opts
, "vnc");
3552 if (addr
== NULL
|| g_str_equal(addr
, "none")) {
3556 if (qemu_opt_get(opts
, "websocket") &&
3557 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3559 "SHA1 hash support is required for websockets");
3563 qemu_opt_iter_init(&addriter
, opts
, "vnc");
3564 while ((addr
= qemu_opt_iter_next(&addriter
)) != NULL
) {
3566 rv
= vnc_display_get_address(addr
, false, reverse
, 0, to
,
3573 /* Historical compat - first listen address can be used
3574 * to set the default websocket port
3576 if (displaynum
== -1) {
3579 *retsaddr
= g_renew(SocketAddress
*, *retsaddr
, *retnsaddr
+ 1);
3580 (*retsaddr
)[(*retnsaddr
)++] = saddr
;
3583 /* If we had multiple primary displays, we don't do defaults
3584 * for websocket, and require explicit config instead. */
3585 if (*retnsaddr
> 1) {
3589 qemu_opt_iter_init(&addriter
, opts
, "websocket");
3590 while ((addr
= qemu_opt_iter_next(&addriter
)) != NULL
) {
3591 if (vnc_display_get_address(addr
, true, reverse
, displaynum
, to
,
3594 &wsaddr
, errp
) < 0) {
3598 /* Historical compat - if only a single listen address was
3599 * provided, then this is used to set the default listen
3600 * address for websocket too
3602 if (*retnsaddr
== 1 &&
3603 (*retsaddr
)[0]->type
== SOCKET_ADDRESS_TYPE_INET
&&
3604 wsaddr
->type
== SOCKET_ADDRESS_TYPE_INET
&&
3605 g_str_equal(wsaddr
->u
.inet
.host
, "") &&
3606 !g_str_equal((*retsaddr
)[0]->u
.inet
.host
, "")) {
3607 g_free(wsaddr
->u
.inet
.host
);
3608 wsaddr
->u
.inet
.host
= g_strdup((*retsaddr
)[0]->u
.inet
.host
);
3611 *retwsaddr
= g_renew(SocketAddress
*, *retwsaddr
, *retnwsaddr
+ 1);
3612 (*retwsaddr
)[(*retnwsaddr
)++] = wsaddr
;
3618 for (i
= 0; i
< *retnsaddr
; i
++) {
3619 qapi_free_SocketAddress((*retsaddr
)[i
]);
3622 for (i
= 0; i
< *retnwsaddr
; i
++) {
3623 qapi_free_SocketAddress((*retwsaddr
)[i
]);
3626 *retsaddr
= *retwsaddr
= NULL
;
3627 *retnsaddr
= *retnwsaddr
= 0;
3632 static int vnc_display_connect(VncDisplay
*vd
,
3633 SocketAddress
**saddr
,
3635 SocketAddress
**wsaddr
,
3639 /* connect to viewer */
3640 QIOChannelSocket
*sioc
= NULL
;
3642 error_setg(errp
, "Cannot use websockets in reverse mode");
3646 error_setg(errp
, "Expected a single address in reverse mode");
3649 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3650 vd
->is_unix
= saddr
[0]->type
== SOCKET_ADDRESS_TYPE_UNIX
;
3651 sioc
= qio_channel_socket_new();
3652 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-reverse");
3653 if (qio_channel_socket_connect_sync(sioc
, saddr
[0], errp
) < 0) {
3656 vnc_connect(vd
, sioc
, false, false);
3657 object_unref(OBJECT(sioc
));
3662 static int vnc_display_listen_addr(VncDisplay
*vd
,
3663 SocketAddress
*addr
,
3665 QIOChannelSocket
***lsock
,
3670 QIODNSResolver
*resolver
= qio_dns_resolver_get_instance();
3671 SocketAddress
**rawaddrs
= NULL
;
3672 size_t nrawaddrs
= 0;
3673 Error
*listenerr
= NULL
;
3674 bool listening
= false;
3677 if (qio_dns_resolver_lookup_sync(resolver
, addr
, &nrawaddrs
,
3678 &rawaddrs
, errp
) < 0) {
3682 for (i
= 0; i
< nrawaddrs
; i
++) {
3683 QIOChannelSocket
*sioc
= qio_channel_socket_new();
3685 qio_channel_set_name(QIO_CHANNEL(sioc
), name
);
3686 if (qio_channel_socket_listen_sync(
3687 sioc
, rawaddrs
[i
], listenerr
== NULL
? &listenerr
: NULL
) < 0) {
3688 object_unref(OBJECT(sioc
));
3693 *lsock
= g_renew(QIOChannelSocket
*, *lsock
, *nlsock
);
3694 *lsock_tag
= g_renew(guint
, *lsock_tag
, *nlsock
);
3696 (*lsock
)[*nlsock
- 1] = sioc
;
3697 (*lsock_tag
)[*nlsock
- 1] = 0;
3700 for (i
= 0; i
< nrawaddrs
; i
++) {
3701 qapi_free_SocketAddress(rawaddrs
[i
]);
3707 error_propagate(errp
, listenerr
);
3710 error_free(listenerr
);
3714 for (i
= 0; i
< *nlsock
; i
++) {
3715 (*lsock_tag
)[i
] = qio_channel_add_watch(
3716 QIO_CHANNEL((*lsock
)[i
]),
3717 G_IO_IN
, vnc_listen_io
, vd
, NULL
);
3724 static int vnc_display_listen(VncDisplay
*vd
,
3725 SocketAddress
**saddr
,
3727 SocketAddress
**wsaddr
,
3733 for (i
= 0; i
< nsaddr
; i
++) {
3734 if (vnc_display_listen_addr(vd
, saddr
[i
],
3743 for (i
= 0; i
< nwsaddr
; i
++) {
3744 if (vnc_display_listen_addr(vd
, wsaddr
[i
],
3758 void vnc_display_open(const char *id
, Error
**errp
)
3760 VncDisplay
*vd
= vnc_display_find(id
);
3761 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3762 SocketAddress
**saddr
= NULL
, **wsaddr
= NULL
;
3763 size_t nsaddr
, nwsaddr
;
3764 const char *share
, *device_id
;
3766 bool password
= false;
3767 bool reverse
= false;
3770 #ifdef CONFIG_VNC_SASL
3774 int lock_key_sync
= 1;
3779 error_setg(errp
, "VNC display not active");
3782 vnc_display_close(vd
);
3788 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3789 if (vnc_display_get_addresses(opts
, reverse
, &saddr
, &nsaddr
,
3790 &wsaddr
, &nwsaddr
, errp
) < 0) {
3794 password
= qemu_opt_get_bool(opts
, "password", false);
3796 if (fips_get_state()) {
3798 "VNC password auth disabled due to FIPS mode, "
3799 "consider using the VeNCrypt or SASL authentication "
3800 "methods as an alternative");
3803 if (!qcrypto_cipher_supports(
3804 QCRYPTO_CIPHER_ALG_DES_RFB
, QCRYPTO_CIPHER_MODE_ECB
)) {
3806 "Cipher backend does not support DES RFB algorithm");
3811 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3812 key_delay_ms
= qemu_opt_get_number(opts
, "key-delay-ms", 1);
3813 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3814 #ifndef CONFIG_VNC_SASL
3816 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3819 #endif /* CONFIG_VNC_SASL */
3820 credid
= qemu_opt_get(opts
, "tls-creds");
3823 if (qemu_opt_get(opts
, "tls") ||
3824 qemu_opt_get(opts
, "x509") ||
3825 qemu_opt_get(opts
, "x509verify")) {
3827 "'tls-creds' parameter is mutually exclusive with "
3828 "'tls', 'x509' and 'x509verify' parameters");
3832 creds
= object_resolve_path_component(
3833 object_get_objects_root(), credid
);
3835 error_setg(errp
, "No TLS credentials with id '%s'",
3839 vd
->tlscreds
= (QCryptoTLSCreds
*)
3840 object_dynamic_cast(creds
,
3841 TYPE_QCRYPTO_TLS_CREDS
);
3842 if (!vd
->tlscreds
) {
3843 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3847 object_ref(OBJECT(vd
->tlscreds
));
3849 if (vd
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3851 "Expecting TLS credentials with a server endpoint");
3856 bool tls
= false, x509
= false, x509verify
= false;
3857 tls
= qemu_opt_get_bool(opts
, "tls", false);
3859 path
= qemu_opt_get(opts
, "x509");
3864 path
= qemu_opt_get(opts
, "x509verify");
3870 vd
->tlscreds
= vnc_display_create_creds(x509
,
3875 if (!vd
->tlscreds
) {
3880 acl
= qemu_opt_get_bool(opts
, "acl", false);
3882 share
= qemu_opt_get(opts
, "share");
3884 if (strcmp(share
, "ignore") == 0) {
3885 vd
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3886 } else if (strcmp(share
, "allow-exclusive") == 0) {
3887 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3888 } else if (strcmp(share
, "force-shared") == 0) {
3889 vd
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3891 error_setg(errp
, "unknown vnc share= option");
3895 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3897 vd
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3899 #ifdef CONFIG_VNC_JPEG
3900 vd
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3902 vd
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3903 /* adaptive updates are only used with tight encoding and
3904 * if lossy updates are enabled so we can disable all the
3905 * calculations otherwise */
3907 vd
->non_adaptive
= true;
3911 if (strcmp(vd
->id
, "default") == 0) {
3912 vd
->tlsaclname
= g_strdup("vnc.x509dname");
3914 vd
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vd
->id
);
3916 qemu_acl_init(vd
->tlsaclname
);
3918 #ifdef CONFIG_VNC_SASL
3922 if (strcmp(vd
->id
, "default") == 0) {
3923 aclname
= g_strdup("vnc.username");
3925 aclname
= g_strdup_printf("vnc.%s.username", vd
->id
);
3927 vd
->sasl
.acl
= qemu_acl_init(aclname
);
3932 if (vnc_display_setup_auth(&vd
->auth
, &vd
->subauth
,
3933 vd
->tlscreds
, password
,
3934 sasl
, false, errp
) < 0) {
3938 if (vnc_display_setup_auth(&vd
->ws_auth
, &vd
->ws_subauth
,
3939 vd
->tlscreds
, password
,
3940 sasl
, true, errp
) < 0) {
3944 #ifdef CONFIG_VNC_SASL
3945 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3946 error_setg(errp
, "Failed to initialize SASL auth: %s",
3947 sasl_errstring(saslErr
, NULL
, NULL
));
3951 vd
->lock_key_sync
= lock_key_sync
;
3952 if (lock_key_sync
) {
3953 vd
->led
= qemu_add_led_event_handler(kbd_leds
, vd
);
3956 vd
->key_delay_ms
= key_delay_ms
;
3958 device_id
= qemu_opt_get(opts
, "display");
3960 int head
= qemu_opt_get_number(opts
, "head", 0);
3963 con
= qemu_console_lookup_by_device_name(device_id
, head
, &err
);
3965 error_propagate(errp
, err
);
3972 if (con
!= vd
->dcl
.con
) {
3973 unregister_displaychangelistener(&vd
->dcl
);
3975 register_displaychangelistener(&vd
->dcl
);
3978 if (saddr
== NULL
) {
3983 if (vnc_display_connect(vd
, saddr
, nsaddr
, wsaddr
, nwsaddr
, errp
) < 0) {
3987 if (vnc_display_listen(vd
, saddr
, nsaddr
, wsaddr
, nwsaddr
, errp
) < 0) {
3992 if (qemu_opt_get(opts
, "to")) {
3993 vnc_display_print_local_addr(vd
);
3997 for (i
= 0; i
< nsaddr
; i
++) {
3998 qapi_free_SocketAddress(saddr
[i
]);
4000 for (i
= 0; i
< nwsaddr
; i
++) {
4001 qapi_free_SocketAddress(wsaddr
[i
]);
4006 vnc_display_close(vd
);
4010 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
4012 VncDisplay
*vd
= vnc_display_find(id
);
4013 QIOChannelSocket
*sioc
;
4019 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
4021 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-server");
4022 vnc_connect(vd
, sioc
, skipauth
, false);
4023 object_unref(OBJECT(sioc
));
4027 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
4032 id
= g_strdup("default");
4033 while (qemu_opts_find(olist
, id
)) {
4035 id
= g_strdup_printf("vnc%d", i
++);
4037 qemu_opts_set_id(opts
, id
);
4040 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
4042 QemuOptsList
*olist
= qemu_find_opts("vnc");
4043 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
4050 id
= qemu_opts_id(opts
);
4052 /* auto-assign id if not present */
4053 vnc_auto_assign_id(olist
, opts
);
4058 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
4060 Error
*local_err
= NULL
;
4061 char *id
= (char *)qemu_opts_id(opts
);
4064 vnc_display_init(id
);
4065 vnc_display_open(id
, &local_err
);
4066 if (local_err
!= NULL
) {
4067 error_reportf_err(local_err
, "Failed to start VNC server: ");
4073 static void vnc_register_config(void)
4075 qemu_add_opts(&qemu_vnc_opts
);
4077 opts_init(vnc_register_config
);