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
);
1126 qio_channel_close(vs
->ioc
, NULL
);
1127 vs
->disconnecting
= TRUE
;
1130 void vnc_disconnect_finish(VncState
*vs
)
1134 trace_vnc_client_disconnect_finish(vs
, vs
->ioc
);
1136 vnc_jobs_join(vs
); /* Wait encoding jobs */
1138 vnc_lock_output(vs
);
1139 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1141 buffer_free(&vs
->input
);
1142 buffer_free(&vs
->output
);
1144 qapi_free_VncClientInfo(vs
->info
);
1147 vnc_tight_clear(vs
);
1150 #ifdef CONFIG_VNC_SASL
1151 vnc_sasl_client_cleanup(vs
);
1152 #endif /* CONFIG_VNC_SASL */
1154 vnc_release_modifiers(vs
);
1156 if (vs
->mouse_mode_notifier
.notify
!= NULL
) {
1157 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1159 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1160 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1161 /* last client gone */
1162 vnc_update_server_surface(vs
->vd
);
1165 vnc_unlock_output(vs
);
1167 qemu_mutex_destroy(&vs
->output_mutex
);
1168 if (vs
->bh
!= NULL
) {
1169 qemu_bh_delete(vs
->bh
);
1171 buffer_free(&vs
->jobs_buffer
);
1173 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1174 g_free(vs
->lossy_rect
[i
]);
1176 g_free(vs
->lossy_rect
);
1178 object_unref(OBJECT(vs
->ioc
));
1180 object_unref(OBJECT(vs
->sioc
));
1185 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1189 trace_vnc_client_eof(vs
, vs
->ioc
);
1190 vnc_disconnect_start(vs
);
1191 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1192 trace_vnc_client_io_error(vs
, vs
->ioc
,
1193 errp
? error_get_pretty(*errp
) :
1195 vnc_disconnect_start(vs
);
1208 void vnc_client_error(VncState
*vs
)
1210 VNC_DEBUG("Closing down client sock: protocol error\n");
1211 vnc_disconnect_start(vs
);
1216 * Called to write a chunk of data to the client socket. The data may
1217 * be the raw data, or may have already been encoded by SASL.
1218 * The data will be written either straight onto the socket, or
1219 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1221 * NB, it is theoretically possible to have 2 layers of encryption,
1222 * both SASL, and this TLS layer. It is highly unlikely in practice
1223 * though, since SASL encryption will typically be a no-op if TLS
1226 * Returns the number of bytes written, which may be less than
1227 * the requested 'datalen' if the socket would block. Returns
1228 * -1 on error, and disconnects the client socket.
1230 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1234 ret
= qio_channel_write(
1235 vs
->ioc
, (const char *)data
, datalen
, &err
);
1236 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1237 return vnc_client_io_error(vs
, ret
, &err
);
1242 * Called to write buffered data to the client socket, when not
1243 * using any SASL SSF encryption layers. Will write as much data
1244 * as possible without blocking. If all buffered data is written,
1245 * will switch the FD poll() handler back to read monitoring.
1247 * Returns the number of bytes written, which may be less than
1248 * the buffered output data if the socket would block. Returns
1249 * -1 on error, and disconnects the client socket.
1251 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1255 #ifdef CONFIG_VNC_SASL
1256 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1257 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1258 vs
->sasl
.waitWriteSSF
);
1260 if (vs
->sasl
.conn
&&
1262 vs
->sasl
.waitWriteSSF
) {
1263 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1265 vs
->sasl
.waitWriteSSF
-= ret
;
1267 #endif /* CONFIG_VNC_SASL */
1268 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1272 buffer_advance(&vs
->output
, ret
);
1274 if (vs
->output
.offset
== 0) {
1276 g_source_remove(vs
->ioc_tag
);
1278 vs
->ioc_tag
= qio_channel_add_watch(
1279 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1287 * First function called whenever there is data to be written to
1288 * the client socket. Will delegate actual work according to whether
1289 * SASL SSF layers are enabled (thus requiring encryption calls)
1291 static void vnc_client_write_locked(VncState
*vs
)
1293 #ifdef CONFIG_VNC_SASL
1294 if (vs
->sasl
.conn
&&
1296 !vs
->sasl
.waitWriteSSF
) {
1297 vnc_client_write_sasl(vs
);
1299 #endif /* CONFIG_VNC_SASL */
1301 vnc_client_write_plain(vs
);
1305 static void vnc_client_write(VncState
*vs
)
1308 vnc_lock_output(vs
);
1309 if (vs
->output
.offset
) {
1310 vnc_client_write_locked(vs
);
1311 } else if (vs
->ioc
!= NULL
) {
1313 g_source_remove(vs
->ioc_tag
);
1315 vs
->ioc_tag
= qio_channel_add_watch(
1316 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1318 vnc_unlock_output(vs
);
1321 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1323 vs
->read_handler
= func
;
1324 vs
->read_handler_expect
= expecting
;
1329 * Called to read a chunk of data from the client socket. The data may
1330 * be the raw data, or may need to be further decoded by SASL.
1331 * The data will be read either straight from to the socket, or
1332 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1334 * NB, it is theoretically possible to have 2 layers of encryption,
1335 * both SASL, and this TLS layer. It is highly unlikely in practice
1336 * though, since SASL encryption will typically be a no-op if TLS
1339 * Returns the number of bytes read, which may be less than
1340 * the requested 'datalen' if the socket would block. Returns
1341 * -1 on error, and disconnects the client socket.
1343 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1347 ret
= qio_channel_read(
1348 vs
->ioc
, (char *)data
, datalen
, &err
);
1349 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1350 return vnc_client_io_error(vs
, ret
, &err
);
1355 * Called to read data from the client socket to the input buffer,
1356 * when not using any SASL SSF encryption layers. Will read as much
1357 * data as possible without blocking.
1359 * Returns the number of bytes read. Returns -1 on error, and
1360 * disconnects the client socket.
1362 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1365 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1366 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1367 buffer_reserve(&vs
->input
, 4096);
1368 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1371 vs
->input
.offset
+= ret
;
1375 static void vnc_jobs_bh(void *opaque
)
1377 VncState
*vs
= opaque
;
1379 vnc_jobs_consume_buffer(vs
);
1383 * First function called whenever there is more data to be read from
1384 * the client socket. Will delegate actual work according to whether
1385 * SASL SSF layers are enabled (thus requiring decryption calls)
1386 * Returns 0 on success, -1 if client disconnected
1388 static int vnc_client_read(VncState
*vs
)
1392 #ifdef CONFIG_VNC_SASL
1393 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1394 ret
= vnc_client_read_sasl(vs
);
1396 #endif /* CONFIG_VNC_SASL */
1397 ret
= vnc_client_read_plain(vs
);
1399 if (vs
->disconnecting
) {
1400 vnc_disconnect_finish(vs
);
1406 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1407 size_t len
= vs
->read_handler_expect
;
1410 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1411 if (vs
->disconnecting
) {
1412 vnc_disconnect_finish(vs
);
1417 buffer_advance(&vs
->input
, len
);
1419 vs
->read_handler_expect
= ret
;
1425 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1426 GIOCondition condition
, void *opaque
)
1428 VncState
*vs
= opaque
;
1429 if (condition
& G_IO_IN
) {
1430 if (vnc_client_read(vs
) < 0) {
1434 if (condition
& G_IO_OUT
) {
1435 vnc_client_write(vs
);
1441 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1443 buffer_reserve(&vs
->output
, len
);
1445 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1447 g_source_remove(vs
->ioc_tag
);
1449 vs
->ioc_tag
= qio_channel_add_watch(
1450 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1453 buffer_append(&vs
->output
, data
, len
);
1456 void vnc_write_s32(VncState
*vs
, int32_t value
)
1458 vnc_write_u32(vs
, *(uint32_t *)&value
);
1461 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1465 buf
[0] = (value
>> 24) & 0xFF;
1466 buf
[1] = (value
>> 16) & 0xFF;
1467 buf
[2] = (value
>> 8) & 0xFF;
1468 buf
[3] = value
& 0xFF;
1470 vnc_write(vs
, buf
, 4);
1473 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1477 buf
[0] = (value
>> 8) & 0xFF;
1478 buf
[1] = value
& 0xFF;
1480 vnc_write(vs
, buf
, 2);
1483 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1485 vnc_write(vs
, (char *)&value
, 1);
1488 void vnc_flush(VncState
*vs
)
1490 vnc_lock_output(vs
);
1491 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1492 vnc_client_write_locked(vs
);
1494 vnc_unlock_output(vs
);
1497 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1499 return data
[offset
];
1502 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1504 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1507 static int32_t read_s32(uint8_t *data
, size_t offset
)
1509 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1510 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1513 uint32_t read_u32(uint8_t *data
, size_t offset
)
1515 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1516 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1519 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1523 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1525 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1526 int absolute
= qemu_input_is_absolute();
1528 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1529 vnc_lock_output(vs
);
1530 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1531 vnc_write_u8(vs
, 0);
1532 vnc_write_u16(vs
, 1);
1533 vnc_framebuffer_update(vs
, absolute
, 0,
1534 pixman_image_get_width(vs
->vd
->server
),
1535 pixman_image_get_height(vs
->vd
->server
),
1536 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1537 vnc_unlock_output(vs
);
1540 vs
->absolute
= absolute
;
1543 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1545 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1546 [INPUT_BUTTON_LEFT
] = 0x01,
1547 [INPUT_BUTTON_MIDDLE
] = 0x02,
1548 [INPUT_BUTTON_RIGHT
] = 0x04,
1549 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1550 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1552 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1553 int width
= pixman_image_get_width(vs
->vd
->server
);
1554 int height
= pixman_image_get_height(vs
->vd
->server
);
1556 if (vs
->last_bmask
!= button_mask
) {
1557 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1558 vs
->last_bmask
= button_mask
;
1562 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, 0, width
);
1563 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, 0, height
);
1564 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1565 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1566 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1568 if (vs
->last_x
!= -1) {
1569 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1570 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1575 qemu_input_event_sync();
1578 static void reset_keys(VncState
*vs
)
1581 for(i
= 0; i
< 256; i
++) {
1582 if (vs
->modifiers_state
[i
]) {
1583 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1584 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1585 vs
->modifiers_state
[i
] = 0;
1590 static void press_key(VncState
*vs
, int keysym
)
1592 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1593 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1594 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1595 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1596 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1599 static void vnc_led_state_change(VncState
*vs
)
1601 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1605 vnc_lock_output(vs
);
1606 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1607 vnc_write_u8(vs
, 0);
1608 vnc_write_u16(vs
, 1);
1609 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1610 vnc_write_u8(vs
, vs
->vd
->ledstate
);
1611 vnc_unlock_output(vs
);
1615 static void kbd_leds(void *opaque
, int ledstate
)
1617 VncDisplay
*vd
= opaque
;
1620 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1621 (ledstate
& QEMU_NUM_LOCK_LED
),
1622 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1624 if (ledstate
== vd
->ledstate
) {
1628 vd
->ledstate
= ledstate
;
1630 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
1631 vnc_led_state_change(client
);
1635 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1637 /* QEMU console switch */
1639 case 0x2a: /* Left Shift */
1640 case 0x36: /* Right Shift */
1641 case 0x1d: /* Left CTRL */
1642 case 0x9d: /* Right CTRL */
1643 case 0x38: /* Left ALT */
1644 case 0xb8: /* Right ALT */
1646 vs
->modifiers_state
[keycode
] = 1;
1648 vs
->modifiers_state
[keycode
] = 0;
1650 case 0x02 ... 0x0a: /* '1' to '9' keys */
1651 if (vs
->vd
->dcl
.con
== NULL
&&
1652 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1653 /* Reset the modifiers sent to the current console */
1655 console_select(keycode
- 0x02);
1659 case 0x3a: /* CapsLock */
1660 case 0x45: /* NumLock */
1662 vs
->modifiers_state
[keycode
] ^= 1;
1666 /* Turn off the lock state sync logic if the client support the led
1669 if (down
&& vs
->vd
->lock_key_sync
&&
1670 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1671 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1672 /* If the numlock state needs to change then simulate an additional
1673 keypress before sending this one. This will happen if the user
1674 toggles numlock away from the VNC window.
1676 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1677 if (!vs
->modifiers_state
[0x45]) {
1678 trace_vnc_key_sync_numlock(true);
1679 vs
->modifiers_state
[0x45] = 1;
1680 press_key(vs
, 0xff7f);
1683 if (vs
->modifiers_state
[0x45]) {
1684 trace_vnc_key_sync_numlock(false);
1685 vs
->modifiers_state
[0x45] = 0;
1686 press_key(vs
, 0xff7f);
1691 if (down
&& vs
->vd
->lock_key_sync
&&
1692 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1693 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1694 /* If the capslock state needs to change then simulate an additional
1695 keypress before sending this one. This will happen if the user
1696 toggles capslock away from the VNC window.
1698 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1699 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1700 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1702 if (uppercase
== shift
) {
1703 trace_vnc_key_sync_capslock(false);
1704 vs
->modifiers_state
[0x3a] = 0;
1705 press_key(vs
, 0xffe5);
1708 if (uppercase
!= shift
) {
1709 trace_vnc_key_sync_capslock(true);
1710 vs
->modifiers_state
[0x3a] = 1;
1711 press_key(vs
, 0xffe5);
1716 if (qemu_console_is_graphic(NULL
)) {
1717 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1718 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1720 bool numlock
= vs
->modifiers_state
[0x45];
1721 bool control
= (vs
->modifiers_state
[0x1d] ||
1722 vs
->modifiers_state
[0x9d]);
1723 /* QEMU console emulation */
1726 case 0x2a: /* Left Shift */
1727 case 0x36: /* Right Shift */
1728 case 0x1d: /* Left CTRL */
1729 case 0x9d: /* Right CTRL */
1730 case 0x38: /* Left ALT */
1731 case 0xb8: /* Right ALT */
1734 kbd_put_keysym(QEMU_KEY_UP
);
1737 kbd_put_keysym(QEMU_KEY_DOWN
);
1740 kbd_put_keysym(QEMU_KEY_LEFT
);
1743 kbd_put_keysym(QEMU_KEY_RIGHT
);
1746 kbd_put_keysym(QEMU_KEY_DELETE
);
1749 kbd_put_keysym(QEMU_KEY_HOME
);
1752 kbd_put_keysym(QEMU_KEY_END
);
1755 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1758 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1762 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1765 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1768 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1771 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1774 kbd_put_keysym('5');
1777 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1780 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1783 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1786 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1789 kbd_put_keysym('0');
1792 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1796 kbd_put_keysym('/');
1799 kbd_put_keysym('*');
1802 kbd_put_keysym('-');
1805 kbd_put_keysym('+');
1808 kbd_put_keysym('\n');
1813 kbd_put_keysym(sym
& 0x1f);
1815 kbd_put_keysym(sym
);
1823 static void vnc_release_modifiers(VncState
*vs
)
1825 static const int keycodes
[] = {
1826 /* shift, control, alt keys, both left & right */
1827 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1831 if (!qemu_console_is_graphic(NULL
)) {
1834 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1835 keycode
= keycodes
[i
];
1836 if (!vs
->modifiers_state
[keycode
]) {
1839 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1840 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1844 static const char *code2name(int keycode
)
1846 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode
));
1849 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1854 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1855 lsym
= lsym
- 'A' + 'a';
1858 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1859 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1860 do_key_event(vs
, down
, keycode
, sym
);
1863 static void ext_key_event(VncState
*vs
, int down
,
1864 uint32_t sym
, uint16_t keycode
)
1866 /* if the user specifies a keyboard layout, always use it */
1867 if (keyboard_layout
) {
1868 key_event(vs
, down
, sym
);
1870 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
1871 do_key_event(vs
, down
, keycode
, sym
);
1875 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1876 int x
, int y
, int w
, int h
)
1878 vs
->need_update
= 1;
1884 vs
->force_update
= 1;
1885 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
1888 static void send_ext_key_event_ack(VncState
*vs
)
1890 vnc_lock_output(vs
);
1891 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1892 vnc_write_u8(vs
, 0);
1893 vnc_write_u16(vs
, 1);
1894 vnc_framebuffer_update(vs
, 0, 0,
1895 pixman_image_get_width(vs
->vd
->server
),
1896 pixman_image_get_height(vs
->vd
->server
),
1897 VNC_ENCODING_EXT_KEY_EVENT
);
1898 vnc_unlock_output(vs
);
1902 static void send_ext_audio_ack(VncState
*vs
)
1904 vnc_lock_output(vs
);
1905 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1906 vnc_write_u8(vs
, 0);
1907 vnc_write_u16(vs
, 1);
1908 vnc_framebuffer_update(vs
, 0, 0,
1909 pixman_image_get_width(vs
->vd
->server
),
1910 pixman_image_get_height(vs
->vd
->server
),
1911 VNC_ENCODING_AUDIO
);
1912 vnc_unlock_output(vs
);
1916 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
1919 unsigned int enc
= 0;
1922 vs
->vnc_encoding
= 0;
1923 vs
->tight
.compression
= 9;
1924 vs
->tight
.quality
= -1; /* Lossless by default */
1928 * Start from the end because the encodings are sent in order of preference.
1929 * This way the preferred encoding (first encoding defined in the array)
1930 * will be set at the end of the loop.
1932 for (i
= n_encodings
- 1; i
>= 0; i
--) {
1935 case VNC_ENCODING_RAW
:
1936 vs
->vnc_encoding
= enc
;
1938 case VNC_ENCODING_COPYRECT
:
1939 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
1941 case VNC_ENCODING_HEXTILE
:
1942 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
1943 vs
->vnc_encoding
= enc
;
1945 case VNC_ENCODING_TIGHT
:
1946 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
1947 vs
->vnc_encoding
= enc
;
1949 #ifdef CONFIG_VNC_PNG
1950 case VNC_ENCODING_TIGHT_PNG
:
1951 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
1952 vs
->vnc_encoding
= enc
;
1955 case VNC_ENCODING_ZLIB
:
1956 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
1957 vs
->vnc_encoding
= enc
;
1959 case VNC_ENCODING_ZRLE
:
1960 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
1961 vs
->vnc_encoding
= enc
;
1963 case VNC_ENCODING_ZYWRLE
:
1964 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
1965 vs
->vnc_encoding
= enc
;
1967 case VNC_ENCODING_DESKTOPRESIZE
:
1968 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
1970 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
1971 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
1973 case VNC_ENCODING_RICH_CURSOR
:
1974 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
1975 if (vs
->vd
->cursor
) {
1976 vnc_cursor_define(vs
);
1979 case VNC_ENCODING_EXT_KEY_EVENT
:
1980 send_ext_key_event_ack(vs
);
1982 case VNC_ENCODING_AUDIO
:
1983 send_ext_audio_ack(vs
);
1985 case VNC_ENCODING_WMVi
:
1986 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
1988 case VNC_ENCODING_LED_STATE
:
1989 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
1991 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
1992 vs
->tight
.compression
= (enc
& 0x0F);
1994 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
1995 if (vs
->vd
->lossy
) {
1996 vs
->tight
.quality
= (enc
& 0x0F);
2000 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2004 vnc_desktop_resize(vs
);
2005 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2006 vnc_led_state_change(vs
);
2009 static void set_pixel_conversion(VncState
*vs
)
2011 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2013 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2014 vs
->write_pixels
= vnc_write_pixels_copy
;
2015 vnc_hextile_set_pixel_conversion(vs
, 0);
2017 vs
->write_pixels
= vnc_write_pixels_generic
;
2018 vnc_hextile_set_pixel_conversion(vs
, 1);
2022 static void send_color_map(VncState
*vs
)
2026 vnc_write_u8(vs
, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES
);
2027 vnc_write_u8(vs
, 0); /* padding */
2028 vnc_write_u16(vs
, 0); /* first color */
2029 vnc_write_u16(vs
, 256); /* # of colors */
2031 for (i
= 0; i
< 256; i
++) {
2032 PixelFormat
*pf
= &vs
->client_pf
;
2034 vnc_write_u16(vs
, (((i
>> pf
->rshift
) & pf
->rmax
) << (16 - pf
->rbits
)));
2035 vnc_write_u16(vs
, (((i
>> pf
->gshift
) & pf
->gmax
) << (16 - pf
->gbits
)));
2036 vnc_write_u16(vs
, (((i
>> pf
->bshift
) & pf
->bmax
) << (16 - pf
->bbits
)));
2040 static void set_pixel_format(VncState
*vs
, int bits_per_pixel
,
2041 int big_endian_flag
, int true_color_flag
,
2042 int red_max
, int green_max
, int blue_max
,
2043 int red_shift
, int green_shift
, int blue_shift
)
2045 if (!true_color_flag
) {
2046 /* Expose a reasonable default 256 color map */
2056 switch (bits_per_pixel
) {
2062 vnc_client_error(vs
);
2066 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2067 vs
->client_pf
.rbits
= ctpopl(red_max
);
2068 vs
->client_pf
.rshift
= red_shift
;
2069 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2070 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2071 vs
->client_pf
.gbits
= ctpopl(green_max
);
2072 vs
->client_pf
.gshift
= green_shift
;
2073 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2074 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2075 vs
->client_pf
.bbits
= ctpopl(blue_max
);
2076 vs
->client_pf
.bshift
= blue_shift
;
2077 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2078 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2079 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2080 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2081 vs
->client_be
= big_endian_flag
;
2083 if (!true_color_flag
) {
2087 set_pixel_conversion(vs
);
2089 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2090 graphic_hw_update(vs
->vd
->dcl
.con
);
2093 static void pixel_format_message (VncState
*vs
) {
2094 char pad
[3] = { 0, 0, 0 };
2096 vs
->client_pf
= qemu_default_pixelformat(32);
2098 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2099 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2101 #ifdef HOST_WORDS_BIGENDIAN
2102 vnc_write_u8(vs
, 1); /* big-endian-flag */
2104 vnc_write_u8(vs
, 0); /* big-endian-flag */
2106 vnc_write_u8(vs
, 1); /* true-color-flag */
2107 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2108 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2109 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2110 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2111 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2112 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2113 vnc_write(vs
, pad
, 3); /* padding */
2115 vnc_hextile_set_pixel_conversion(vs
, 0);
2116 vs
->write_pixels
= vnc_write_pixels_copy
;
2119 static void vnc_colordepth(VncState
*vs
)
2121 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2122 /* Sending a WMVi message to notify the client*/
2123 vnc_lock_output(vs
);
2124 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2125 vnc_write_u8(vs
, 0);
2126 vnc_write_u16(vs
, 1); /* number of rects */
2127 vnc_framebuffer_update(vs
, 0, 0,
2128 pixman_image_get_width(vs
->vd
->server
),
2129 pixman_image_get_height(vs
->vd
->server
),
2131 pixel_format_message(vs
);
2132 vnc_unlock_output(vs
);
2135 set_pixel_conversion(vs
);
2139 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2143 VncDisplay
*vd
= vs
->vd
;
2146 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2150 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2154 set_pixel_format(vs
, read_u8(data
, 4),
2155 read_u8(data
, 6), read_u8(data
, 7),
2156 read_u16(data
, 8), read_u16(data
, 10),
2157 read_u16(data
, 12), read_u8(data
, 14),
2158 read_u8(data
, 15), read_u8(data
, 16));
2160 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2165 limit
= read_u16(data
, 2);
2167 return 4 + (limit
* 4);
2169 limit
= read_u16(data
, 2);
2171 for (i
= 0; i
< limit
; i
++) {
2172 int32_t val
= read_s32(data
, 4 + (i
* 4));
2173 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2176 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2178 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2182 framebuffer_update_request(vs
,
2183 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2184 read_u16(data
, 6), read_u16(data
, 8));
2186 case VNC_MSG_CLIENT_KEY_EVENT
:
2190 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2192 case VNC_MSG_CLIENT_POINTER_EVENT
:
2196 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2198 case VNC_MSG_CLIENT_CUT_TEXT
:
2203 uint32_t dlen
= read_u32(data
, 4);
2204 if (dlen
> (1 << 20)) {
2205 error_report("vnc: client_cut_text msg payload has %u bytes"
2206 " which exceeds our limit of 1MB.", dlen
);
2207 vnc_client_error(vs
);
2215 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2217 case VNC_MSG_CLIENT_QEMU
:
2221 switch (read_u8(data
, 1)) {
2222 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2226 ext_key_event(vs
, read_u16(data
, 2),
2227 read_u32(data
, 4), read_u32(data
, 8));
2229 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2233 switch (read_u16 (data
, 2)) {
2234 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2237 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2240 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2243 switch (read_u8(data
, 4)) {
2244 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2245 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2246 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2247 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2248 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2249 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2251 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2252 vnc_client_error(vs
);
2255 vs
->as
.nchannels
= read_u8(data
, 5);
2256 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2257 VNC_DEBUG("Invalid audio channel coount %d\n",
2259 vnc_client_error(vs
);
2262 vs
->as
.freq
= read_u32(data
, 6);
2265 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2266 vnc_client_error(vs
);
2272 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2273 vnc_client_error(vs
);
2278 VNC_DEBUG("Msg: %d\n", data
[0]);
2279 vnc_client_error(vs
);
2283 vnc_read_when(vs
, protocol_client_msg
, 1);
2287 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2293 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2294 switch (vs
->vd
->share_policy
) {
2295 case VNC_SHARE_POLICY_IGNORE
:
2297 * Ignore the shared flag. Nothing to do here.
2299 * Doesn't conform to the rfb spec but is traditional qemu
2300 * behavior, thus left here as option for compatibility
2304 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2306 * Policy: Allow clients ask for exclusive access.
2308 * Implementation: When a client asks for exclusive access,
2309 * disconnect all others. Shared connects are allowed as long
2310 * as no exclusive connection exists.
2312 * This is how the rfb spec suggests to handle the shared flag.
2314 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2316 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2320 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2321 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2324 vnc_disconnect_start(client
);
2327 if (mode
== VNC_SHARE_MODE_SHARED
) {
2328 if (vs
->vd
->num_exclusive
> 0) {
2329 vnc_disconnect_start(vs
);
2334 case VNC_SHARE_POLICY_FORCE_SHARED
:
2336 * Policy: Shared connects only.
2337 * Implementation: Disallow clients asking for exclusive access.
2339 * Useful for shared desktop sessions where you don't want
2340 * someone forgetting to say -shared when running the vnc
2341 * client disconnect everybody else.
2343 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2344 vnc_disconnect_start(vs
);
2349 vnc_set_share_mode(vs
, mode
);
2351 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2352 vnc_disconnect_start(vs
);
2356 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2357 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2358 vnc_write_u16(vs
, vs
->client_width
);
2359 vnc_write_u16(vs
, vs
->client_height
);
2361 pixel_format_message(vs
);
2364 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2365 if (size
> sizeof(buf
)) {
2369 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2372 vnc_write_u32(vs
, size
);
2373 vnc_write(vs
, buf
, size
);
2376 vnc_client_cache_auth(vs
);
2377 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2379 vnc_read_when(vs
, protocol_client_msg
, 1);
2384 void start_client_init(VncState
*vs
)
2386 vnc_read_when(vs
, protocol_client_init
, 1);
2389 static void make_challenge(VncState
*vs
)
2393 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2395 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2396 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2399 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2401 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2403 unsigned char key
[8];
2404 time_t now
= time(NULL
);
2405 QCryptoCipher
*cipher
= NULL
;
2408 if (!vs
->vd
->password
) {
2409 trace_vnc_auth_fail(vs
, vs
->auth
, "password is not set", "");
2412 if (vs
->vd
->expires
< now
) {
2413 trace_vnc_auth_fail(vs
, vs
->auth
, "password is expired", "");
2417 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2419 /* Calculate the expected challenge response */
2420 pwlen
= strlen(vs
->vd
->password
);
2421 for (i
=0; i
<sizeof(key
); i
++)
2422 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2424 cipher
= qcrypto_cipher_new(
2425 QCRYPTO_CIPHER_ALG_DES_RFB
,
2426 QCRYPTO_CIPHER_MODE_ECB
,
2427 key
, G_N_ELEMENTS(key
),
2430 trace_vnc_auth_fail(vs
, vs
->auth
, "cannot create cipher",
2431 error_get_pretty(err
));
2436 if (qcrypto_cipher_encrypt(cipher
,
2439 VNC_AUTH_CHALLENGE_SIZE
,
2441 trace_vnc_auth_fail(vs
, vs
->auth
, "cannot encrypt challenge response",
2442 error_get_pretty(err
));
2447 /* Compare expected vs actual challenge response */
2448 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2449 trace_vnc_auth_fail(vs
, vs
->auth
, "mis-matched challenge response", "");
2452 trace_vnc_auth_pass(vs
, vs
->auth
);
2453 vnc_write_u32(vs
, 0); /* Accept auth */
2456 start_client_init(vs
);
2459 qcrypto_cipher_free(cipher
);
2463 vnc_write_u32(vs
, 1); /* Reject auth */
2464 if (vs
->minor
>= 8) {
2465 static const char err
[] = "Authentication failed";
2466 vnc_write_u32(vs
, sizeof(err
));
2467 vnc_write(vs
, err
, sizeof(err
));
2470 vnc_client_error(vs
);
2471 qcrypto_cipher_free(cipher
);
2475 void start_auth_vnc(VncState
*vs
)
2478 /* Send client a 'random' challenge */
2479 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2482 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2486 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2488 /* We only advertise 1 auth scheme at a time, so client
2489 * must pick the one we sent. Verify this */
2490 if (data
[0] != vs
->auth
) { /* Reject auth */
2491 trace_vnc_auth_reject(vs
, vs
->auth
, (int)data
[0]);
2492 vnc_write_u32(vs
, 1);
2493 if (vs
->minor
>= 8) {
2494 static const char err
[] = "Authentication failed";
2495 vnc_write_u32(vs
, sizeof(err
));
2496 vnc_write(vs
, err
, sizeof(err
));
2498 vnc_client_error(vs
);
2499 } else { /* Accept requested auth */
2500 trace_vnc_auth_start(vs
, vs
->auth
);
2503 if (vs
->minor
>= 8) {
2504 vnc_write_u32(vs
, 0); /* Accept auth completion */
2507 trace_vnc_auth_pass(vs
, vs
->auth
);
2508 start_client_init(vs
);
2515 case VNC_AUTH_VENCRYPT
:
2516 start_auth_vencrypt(vs
);
2519 #ifdef CONFIG_VNC_SASL
2521 start_auth_sasl(vs
);
2523 #endif /* CONFIG_VNC_SASL */
2525 default: /* Should not be possible, but just in case */
2526 trace_vnc_auth_fail(vs
, vs
->auth
, "Unhandled auth method", "");
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 trace_vnc_auth_start(vs
, vs
->auth
);
2572 if (vs
->auth
== VNC_AUTH_NONE
) {
2573 vnc_write_u32(vs
, vs
->auth
);
2575 trace_vnc_auth_pass(vs
, vs
->auth
);
2576 start_client_init(vs
);
2577 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2578 VNC_DEBUG("Tell client VNC auth\n");
2579 vnc_write_u32(vs
, vs
->auth
);
2583 trace_vnc_auth_fail(vs
, vs
->auth
,
2584 "Unsupported auth method for v3.3", "");
2585 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2587 vnc_client_error(vs
);
2590 vnc_write_u8(vs
, 1); /* num auth */
2591 vnc_write_u8(vs
, vs
->auth
);
2592 vnc_read_when(vs
, protocol_client_auth
, 1);
2599 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2601 struct VncSurface
*vs
= &vd
->guest
;
2603 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2606 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2610 w
= (x
+ w
) / VNC_STAT_RECT
;
2611 h
= (y
+ h
) / VNC_STAT_RECT
;
2615 for (j
= y
; j
<= h
; j
++) {
2616 for (i
= x
; i
<= w
; i
++) {
2617 vs
->lossy_rect
[j
][i
] = 1;
2622 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2625 int sty
= y
/ VNC_STAT_RECT
;
2626 int stx
= x
/ VNC_STAT_RECT
;
2629 y
= QEMU_ALIGN_DOWN(y
, VNC_STAT_RECT
);
2630 x
= QEMU_ALIGN_DOWN(x
, VNC_STAT_RECT
);
2632 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2635 /* kernel send buffers are full -> refresh later */
2636 if (vs
->output
.offset
) {
2640 if (!vs
->lossy_rect
[sty
][stx
]) {
2644 vs
->lossy_rect
[sty
][stx
] = 0;
2645 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2646 bitmap_set(vs
->dirty
[y
+ j
],
2647 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2648 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2656 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2658 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2659 pixman_image_get_width(vd
->server
));
2660 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2661 pixman_image_get_height(vd
->server
));
2666 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2667 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2668 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2670 rect
->updated
= false;
2674 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2676 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2679 vd
->guest
.last_freq_check
= *tv
;
2681 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2682 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2683 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2684 int count
= ARRAY_SIZE(rect
->times
);
2685 struct timeval min
, max
;
2687 if (!timerisset(&rect
->times
[count
- 1])) {
2691 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2692 qemu_timersub(tv
, &max
, &res
);
2694 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2696 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2697 memset(rect
->times
, 0, sizeof (rect
->times
));
2701 min
= rect
->times
[rect
->idx
];
2702 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2703 qemu_timersub(&max
, &min
, &res
);
2705 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2706 rect
->freq
/= count
;
2707 rect
->freq
= 1. / rect
->freq
;
2713 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2719 x
= QEMU_ALIGN_DOWN(x
, VNC_STAT_RECT
);
2720 y
= QEMU_ALIGN_DOWN(y
, VNC_STAT_RECT
);
2722 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2723 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2724 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2736 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2740 rect
= vnc_stat_rect(vd
, x
, y
);
2741 if (rect
->updated
) {
2744 rect
->times
[rect
->idx
] = *tv
;
2745 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2746 rect
->updated
= true;
2749 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2751 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2752 pixman_image_get_width(vd
->server
));
2753 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2754 pixman_image_get_height(vd
->server
));
2755 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2756 uint8_t *guest_row0
= NULL
, *server_row0
;
2759 pixman_image_t
*tmpbuf
= NULL
;
2761 struct timeval tv
= { 0, 0 };
2763 if (!vd
->non_adaptive
) {
2764 gettimeofday(&tv
, NULL
);
2765 has_dirty
= vnc_update_stats(vd
, &tv
);
2769 * Walk through the guest dirty map.
2770 * Check and copy modified bits from guest to server surface.
2771 * Update server dirty map.
2773 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2774 server_stride
= guest_stride
= guest_ll
=
2775 pixman_image_get_stride(vd
->server
);
2776 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2778 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2779 int width
= pixman_image_get_width(vd
->server
);
2780 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2783 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2784 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2785 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2786 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * (DIV_ROUND_UP(guest_bpp
, 8));
2788 line_bytes
= MIN(server_stride
, guest_ll
);
2792 uint8_t *guest_ptr
, *server_ptr
;
2793 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2794 height
* VNC_DIRTY_BPL(&vd
->guest
),
2795 y
* VNC_DIRTY_BPL(&vd
->guest
));
2796 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2797 /* no more dirty bits */
2800 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2801 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2803 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2805 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2806 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2807 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2809 guest_ptr
= guest_row0
+ y
* guest_stride
;
2811 guest_ptr
+= x
* cmp_bytes
;
2813 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2814 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2815 int _cmp_bytes
= cmp_bytes
;
2816 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2819 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2820 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2822 assert(_cmp_bytes
>= 0);
2823 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2826 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2827 if (!vd
->non_adaptive
) {
2828 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2831 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2832 set_bit(x
, vs
->dirty
[y
]);
2839 qemu_pixman_image_unref(tmpbuf
);
2843 static void vnc_refresh(DisplayChangeListener
*dcl
)
2845 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2847 int has_dirty
, rects
= 0;
2849 if (QTAILQ_EMPTY(&vd
->clients
)) {
2850 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2854 graphic_hw_update(vd
->dcl
.con
);
2856 if (vnc_trylock_display(vd
)) {
2857 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2861 has_dirty
= vnc_refresh_server_surface(vd
);
2862 vnc_unlock_display(vd
);
2864 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2865 rects
+= vnc_update_client(vs
, has_dirty
, false);
2866 /* vs might be free()ed here */
2869 if (has_dirty
&& rects
) {
2870 vd
->dcl
.update_interval
/= 2;
2871 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2872 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2875 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2876 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2877 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2882 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2883 bool skipauth
, bool websocket
)
2885 VncState
*vs
= g_new0(VncState
, 1);
2886 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
2889 trace_vnc_client_connect(vs
, sioc
);
2891 object_ref(OBJECT(vs
->sioc
));
2892 vs
->ioc
= QIO_CHANNEL(sioc
);
2893 object_ref(OBJECT(vs
->ioc
));
2896 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
2897 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
2898 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
2900 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
2901 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
2902 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
2903 #ifdef CONFIG_VNC_JPEG
2904 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
2906 #ifdef CONFIG_VNC_PNG
2907 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
2909 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
2910 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
2911 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
2912 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
2915 vs
->auth
= VNC_AUTH_NONE
;
2916 vs
->subauth
= VNC_AUTH_INVALID
;
2919 vs
->auth
= vd
->ws_auth
;
2920 vs
->subauth
= VNC_AUTH_INVALID
;
2922 vs
->auth
= vd
->auth
;
2923 vs
->subauth
= vd
->subauth
;
2926 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2927 sioc
, websocket
, vs
->auth
, vs
->subauth
);
2929 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
2930 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
2931 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
2934 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
2935 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2936 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
2940 vs
->ioc_tag
= qio_channel_add_watch(
2941 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
2943 vs
->ioc_tag
= qio_channel_add_watch(
2944 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
2947 vs
->ioc_tag
= qio_channel_add_watch(
2948 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
2951 vnc_client_cache_addr(vs
);
2952 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
2953 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
2958 vs
->as
.freq
= 44100;
2959 vs
->as
.nchannels
= 2;
2960 vs
->as
.fmt
= AUD_FMT_S16
;
2961 vs
->as
.endianness
= 0;
2963 qemu_mutex_init(&vs
->output_mutex
);
2964 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
2966 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
2968 vnc_update_server_surface(vd
);
2971 graphic_hw_update(vd
->dcl
.con
);
2973 if (!vs
->websocket
) {
2974 vnc_start_protocol(vs
);
2977 if (vd
->num_connecting
> vd
->connections_limit
) {
2978 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2979 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
2980 vnc_disconnect_start(vs
);
2987 void vnc_start_protocol(VncState
*vs
)
2989 vnc_write(vs
, "RFB 003.008\n", 12);
2991 vnc_read_when(vs
, protocol_version
, 12);
2993 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
2994 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
2997 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
2998 GIOCondition condition
,
3001 VncDisplay
*vd
= opaque
;
3002 QIOChannelSocket
*sioc
= NULL
;
3004 bool isWebsock
= false;
3007 for (i
= 0; i
< vd
->nlwebsock
; i
++) {
3008 if (ioc
== QIO_CHANNEL(vd
->lwebsock
[i
])) {
3014 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3016 qio_channel_set_name(QIO_CHANNEL(sioc
),
3017 isWebsock
? "vnc-ws-server" : "vnc-server");
3018 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3019 vnc_connect(vd
, sioc
, false, isWebsock
);
3020 object_unref(OBJECT(sioc
));
3022 /* client probably closed connection before we got there */
3029 static const DisplayChangeListenerOps dcl_ops
= {
3031 .dpy_refresh
= vnc_refresh
,
3032 .dpy_gfx_update
= vnc_dpy_update
,
3033 .dpy_gfx_switch
= vnc_dpy_switch
,
3034 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3035 .dpy_mouse_set
= vnc_mouse_set
,
3036 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3039 void vnc_display_init(const char *id
)
3043 if (vnc_display_find(id
) != NULL
) {
3046 vd
= g_malloc0(sizeof(*vd
));
3048 vd
->id
= strdup(id
);
3049 QTAILQ_INSERT_TAIL(&vnc_displays
, vd
, next
);
3051 QTAILQ_INIT(&vd
->clients
);
3052 vd
->expires
= TIME_MAX
;
3054 if (keyboard_layout
) {
3055 trace_vnc_key_map_init(keyboard_layout
);
3056 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3058 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3061 if (!vd
->kbd_layout
) {
3065 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3066 vd
->connections_limit
= 32;
3068 qemu_mutex_init(&vd
->mutex
);
3069 vnc_start_worker_thread();
3071 vd
->dcl
.ops
= &dcl_ops
;
3072 register_displaychangelistener(&vd
->dcl
);
3076 static void vnc_display_close(VncDisplay
*vd
)
3082 vd
->is_unix
= false;
3083 for (i
= 0; i
< vd
->nlsock
; i
++) {
3084 if (vd
->lsock_tag
[i
]) {
3085 g_source_remove(vd
->lsock_tag
[i
]);
3087 object_unref(OBJECT(vd
->lsock
[i
]));
3090 g_free(vd
->lsock_tag
);
3092 vd
->lsock_tag
= NULL
;
3095 for (i
= 0; i
< vd
->nlwebsock
; i
++) {
3096 if (vd
->lwebsock_tag
[i
]) {
3097 g_source_remove(vd
->lwebsock_tag
[i
]);
3099 object_unref(OBJECT(vd
->lwebsock
[i
]));
3101 g_free(vd
->lwebsock
);
3102 g_free(vd
->lwebsock_tag
);
3103 vd
->lwebsock
= NULL
;
3104 vd
->lwebsock_tag
= NULL
;
3107 vd
->auth
= VNC_AUTH_INVALID
;
3108 vd
->subauth
= VNC_AUTH_INVALID
;
3110 object_unparent(OBJECT(vd
->tlscreds
));
3111 vd
->tlscreds
= NULL
;
3113 g_free(vd
->tlsaclname
);
3114 vd
->tlsaclname
= NULL
;
3115 if (vd
->lock_key_sync
) {
3116 qemu_remove_led_event_handler(vd
->led
);
3121 int vnc_display_password(const char *id
, const char *password
)
3123 VncDisplay
*vd
= vnc_display_find(id
);
3128 if (vd
->auth
== VNC_AUTH_NONE
) {
3129 error_printf_unless_qmp("If you want use passwords please enable "
3130 "password auth using '-vnc ${dpy},password'.\n");
3134 g_free(vd
->password
);
3135 vd
->password
= g_strdup(password
);
3140 int vnc_display_pw_expire(const char *id
, time_t expires
)
3142 VncDisplay
*vd
= vnc_display_find(id
);
3148 vd
->expires
= expires
;
3152 static void vnc_display_print_local_addr(VncDisplay
*vd
)
3154 SocketAddress
*addr
;
3161 addr
= qio_channel_socket_get_local_address(vd
->lsock
[0], &err
);
3166 if (addr
->type
!= SOCKET_ADDRESS_TYPE_INET
) {
3167 qapi_free_SocketAddress(addr
);
3170 error_printf_unless_qmp("VNC server running on %s:%s\n",
3173 qapi_free_SocketAddress(addr
);
3176 static QemuOptsList qemu_vnc_opts
= {
3178 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3179 .implied_opt_name
= "vnc",
3183 .type
= QEMU_OPT_STRING
,
3185 .name
= "websocket",
3186 .type
= QEMU_OPT_STRING
,
3188 .name
= "tls-creds",
3189 .type
= QEMU_OPT_STRING
,
3191 /* Deprecated in favour of tls-creds */
3193 .type
= QEMU_OPT_STRING
,
3196 .type
= QEMU_OPT_STRING
,
3199 .type
= QEMU_OPT_STRING
,
3202 .type
= QEMU_OPT_NUMBER
,
3204 .name
= "connections",
3205 .type
= QEMU_OPT_NUMBER
,
3208 .type
= QEMU_OPT_NUMBER
,
3211 .type
= QEMU_OPT_BOOL
,
3214 .type
= QEMU_OPT_BOOL
,
3217 .type
= QEMU_OPT_BOOL
,
3220 .type
= QEMU_OPT_BOOL
,
3222 .name
= "lock-key-sync",
3223 .type
= QEMU_OPT_BOOL
,
3225 .name
= "key-delay-ms",
3226 .type
= QEMU_OPT_NUMBER
,
3229 .type
= QEMU_OPT_BOOL
,
3231 /* Deprecated in favour of tls-creds */
3233 .type
= QEMU_OPT_BOOL
,
3235 /* Deprecated in favour of tls-creds */
3236 .name
= "x509verify",
3237 .type
= QEMU_OPT_STRING
,
3240 .type
= QEMU_OPT_BOOL
,
3243 .type
= QEMU_OPT_BOOL
,
3245 .name
= "non-adaptive",
3246 .type
= QEMU_OPT_BOOL
,
3248 { /* end of list */ }
3254 vnc_display_setup_auth(int *auth
,
3256 QCryptoTLSCreds
*tlscreds
,
3263 * We have a choice of 3 authentication options
3269 * The channel can be run in 2 modes
3274 * And TLS can use 2 types of credentials
3279 * We thus have 9 possible logical combinations
3284 * 4. tls + anon + none
3285 * 5. tls + anon + vnc
3286 * 6. tls + anon + sasl
3287 * 7. tls + x509 + none
3288 * 8. tls + x509 + vnc
3289 * 9. tls + x509 + sasl
3291 * These need to be mapped into the VNC auth schemes
3292 * in an appropriate manner. In regular VNC, all the
3293 * TLS options get mapped into VNC_AUTH_VENCRYPT
3296 * In websockets, the https:// protocol already provides
3297 * TLS support, so there is no need to make use of the
3298 * VeNCrypt extension. Furthermore, websockets browser
3299 * clients could not use VeNCrypt even if they wanted to,
3300 * as they cannot control when the TLS handshake takes
3301 * place. Thus there is no option but to rely on https://,
3302 * meaning combinations 4->6 and 7->9 will be mapped to
3303 * VNC auth schemes in the same way as combos 1->3.
3305 * Regardless of fact that we have a different mapping to
3306 * VNC auth mechs for plain VNC vs websockets VNC, the end
3307 * result has the same security characteristics.
3309 if (websocket
|| !tlscreds
) {
3311 VNC_DEBUG("Initializing VNC server with password auth\n");
3312 *auth
= VNC_AUTH_VNC
;
3314 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3315 *auth
= VNC_AUTH_SASL
;
3317 VNC_DEBUG("Initializing VNC server with no auth\n");
3318 *auth
= VNC_AUTH_NONE
;
3320 *subauth
= VNC_AUTH_INVALID
;
3322 bool is_x509
= object_dynamic_cast(OBJECT(tlscreds
),
3323 TYPE_QCRYPTO_TLS_CREDS_X509
) != NULL
;
3324 bool is_anon
= object_dynamic_cast(OBJECT(tlscreds
),
3325 TYPE_QCRYPTO_TLS_CREDS_ANON
) != NULL
;
3327 if (!is_x509
&& !is_anon
) {
3329 "Unsupported TLS cred type %s",
3330 object_get_typename(OBJECT(tlscreds
)));
3333 *auth
= VNC_AUTH_VENCRYPT
;
3336 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3337 *subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3339 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3340 *subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3345 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3346 *subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3348 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3349 *subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3353 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3354 *subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3356 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3357 *subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3366 * Handle back compat with old CLI syntax by creating some
3367 * suitable QCryptoTLSCreds objects
3369 static QCryptoTLSCreds
*
3370 vnc_display_create_creds(bool x509
,
3376 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3377 Object
*parent
= object_get_objects_root();
3382 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3386 "endpoint", "server",
3388 "verify-peer", x509verify
? "yes" : "no",
3391 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3395 "endpoint", "server",
3402 error_propagate(errp
, err
);
3406 return QCRYPTO_TLS_CREDS(creds
);
3410 static int vnc_display_get_address(const char *addrstr
,
3419 SocketAddress
**retaddr
,
3423 SocketAddress
*addr
= NULL
;
3425 addr
= g_new0(SocketAddress
, 1);
3427 if (strncmp(addrstr
, "unix:", 5) == 0) {
3428 addr
->type
= SOCKET_ADDRESS_TYPE_UNIX
;
3429 addr
->u
.q_unix
.path
= g_strdup(addrstr
+ 5);
3432 error_setg(errp
, "UNIX sockets not supported with websock");
3437 error_setg(errp
, "Port range not support with UNIX socket");
3444 unsigned long long baseport
= 0;
3445 InetSocketAddress
*inet
;
3447 port
= strrchr(addrstr
, ':');
3453 error_setg(errp
, "no vnc port specified");
3457 hostlen
= port
- addrstr
;
3459 if (*port
== '\0') {
3460 error_setg(errp
, "vnc port cannot be empty");
3465 addr
->type
= SOCKET_ADDRESS_TYPE_INET
;
3466 inet
= &addr
->u
.inet
;
3467 if (addrstr
[0] == '[' && addrstr
[hostlen
- 1] == ']') {
3468 inet
->host
= g_strndup(addrstr
+ 1, hostlen
- 2);
3470 inet
->host
= g_strndup(addrstr
, hostlen
);
3472 /* plain VNC port is just an offset, for websocket
3473 * port is absolute */
3475 if (g_str_equal(addrstr
, "") ||
3476 g_str_equal(addrstr
, "on")) {
3477 if (displaynum
== -1) {
3478 error_setg(errp
, "explicit websocket port is required");
3481 inet
->port
= g_strdup_printf(
3482 "%d", displaynum
+ 5700);
3484 inet
->has_to
= true;
3485 inet
->to
= to
+ 5700;
3488 inet
->port
= g_strdup(port
);
3491 int offset
= reverse
? 0 : 5900;
3492 if (parse_uint_full(port
, &baseport
, 10) < 0) {
3493 error_setg(errp
, "can't convert to a number: %s", port
);
3496 if (baseport
> 65535 ||
3497 baseport
+ offset
> 65535) {
3498 error_setg(errp
, "port %s out of range", port
);
3501 inet
->port
= g_strdup_printf(
3502 "%d", (int)baseport
+ offset
);
3505 inet
->has_to
= true;
3506 inet
->to
= to
+ offset
;
3511 inet
->has_ipv4
= has_ipv4
;
3513 inet
->has_ipv6
= has_ipv6
;
3522 qapi_free_SocketAddress(addr
);
3527 static void vnc_free_addresses(SocketAddress
***retsaddr
,
3532 for (i
= 0; i
< *retnsaddr
; i
++) {
3533 qapi_free_SocketAddress((*retsaddr
)[i
]);
3541 static int vnc_display_get_addresses(QemuOpts
*opts
,
3543 SocketAddress
***retsaddr
,
3545 SocketAddress
***retwsaddr
,
3549 SocketAddress
*saddr
= NULL
;
3550 SocketAddress
*wsaddr
= NULL
;
3551 QemuOptsIter addriter
;
3553 int to
= qemu_opt_get_number(opts
, "to", 0);
3554 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3555 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3556 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3557 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3558 int displaynum
= -1;
3566 addr
= qemu_opt_get(opts
, "vnc");
3567 if (addr
== NULL
|| g_str_equal(addr
, "none")) {
3571 if (qemu_opt_get(opts
, "websocket") &&
3572 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3574 "SHA1 hash support is required for websockets");
3578 qemu_opt_iter_init(&addriter
, opts
, "vnc");
3579 while ((addr
= qemu_opt_iter_next(&addriter
)) != NULL
) {
3581 rv
= vnc_display_get_address(addr
, false, reverse
, 0, to
,
3588 /* Historical compat - first listen address can be used
3589 * to set the default websocket port
3591 if (displaynum
== -1) {
3594 *retsaddr
= g_renew(SocketAddress
*, *retsaddr
, *retnsaddr
+ 1);
3595 (*retsaddr
)[(*retnsaddr
)++] = saddr
;
3598 /* If we had multiple primary displays, we don't do defaults
3599 * for websocket, and require explicit config instead. */
3600 if (*retnsaddr
> 1) {
3604 qemu_opt_iter_init(&addriter
, opts
, "websocket");
3605 while ((addr
= qemu_opt_iter_next(&addriter
)) != NULL
) {
3606 if (vnc_display_get_address(addr
, true, reverse
, displaynum
, to
,
3609 &wsaddr
, errp
) < 0) {
3613 /* Historical compat - if only a single listen address was
3614 * provided, then this is used to set the default listen
3615 * address for websocket too
3617 if (*retnsaddr
== 1 &&
3618 (*retsaddr
)[0]->type
== SOCKET_ADDRESS_TYPE_INET
&&
3619 wsaddr
->type
== SOCKET_ADDRESS_TYPE_INET
&&
3620 g_str_equal(wsaddr
->u
.inet
.host
, "") &&
3621 !g_str_equal((*retsaddr
)[0]->u
.inet
.host
, "")) {
3622 g_free(wsaddr
->u
.inet
.host
);
3623 wsaddr
->u
.inet
.host
= g_strdup((*retsaddr
)[0]->u
.inet
.host
);
3626 *retwsaddr
= g_renew(SocketAddress
*, *retwsaddr
, *retnwsaddr
+ 1);
3627 (*retwsaddr
)[(*retnwsaddr
)++] = wsaddr
;
3633 vnc_free_addresses(retsaddr
, retnsaddr
);
3634 vnc_free_addresses(retwsaddr
, retnwsaddr
);
3639 static int vnc_display_connect(VncDisplay
*vd
,
3640 SocketAddress
**saddr
,
3642 SocketAddress
**wsaddr
,
3646 /* connect to viewer */
3647 QIOChannelSocket
*sioc
= NULL
;
3649 error_setg(errp
, "Cannot use websockets in reverse mode");
3653 error_setg(errp
, "Expected a single address in reverse mode");
3656 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3657 vd
->is_unix
= saddr
[0]->type
== SOCKET_ADDRESS_TYPE_UNIX
;
3658 sioc
= qio_channel_socket_new();
3659 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-reverse");
3660 if (qio_channel_socket_connect_sync(sioc
, saddr
[0], errp
) < 0) {
3663 vnc_connect(vd
, sioc
, false, false);
3664 object_unref(OBJECT(sioc
));
3669 static int vnc_display_listen_addr(VncDisplay
*vd
,
3670 SocketAddress
*addr
,
3672 QIOChannelSocket
***lsock
,
3677 QIODNSResolver
*resolver
= qio_dns_resolver_get_instance();
3678 SocketAddress
**rawaddrs
= NULL
;
3679 size_t nrawaddrs
= 0;
3680 Error
*listenerr
= NULL
;
3681 bool listening
= false;
3684 if (qio_dns_resolver_lookup_sync(resolver
, addr
, &nrawaddrs
,
3685 &rawaddrs
, errp
) < 0) {
3689 for (i
= 0; i
< nrawaddrs
; i
++) {
3690 QIOChannelSocket
*sioc
= qio_channel_socket_new();
3692 qio_channel_set_name(QIO_CHANNEL(sioc
), name
);
3693 if (qio_channel_socket_listen_sync(
3694 sioc
, rawaddrs
[i
], listenerr
== NULL
? &listenerr
: NULL
) < 0) {
3695 object_unref(OBJECT(sioc
));
3700 *lsock
= g_renew(QIOChannelSocket
*, *lsock
, *nlsock
);
3701 *lsock_tag
= g_renew(guint
, *lsock_tag
, *nlsock
);
3703 (*lsock
)[*nlsock
- 1] = sioc
;
3704 (*lsock_tag
)[*nlsock
- 1] = 0;
3707 for (i
= 0; i
< nrawaddrs
; i
++) {
3708 qapi_free_SocketAddress(rawaddrs
[i
]);
3714 error_propagate(errp
, listenerr
);
3717 error_free(listenerr
);
3721 for (i
= 0; i
< *nlsock
; i
++) {
3722 (*lsock_tag
)[i
] = qio_channel_add_watch(
3723 QIO_CHANNEL((*lsock
)[i
]),
3724 G_IO_IN
, vnc_listen_io
, vd
, NULL
);
3731 static int vnc_display_listen(VncDisplay
*vd
,
3732 SocketAddress
**saddr
,
3734 SocketAddress
**wsaddr
,
3740 for (i
= 0; i
< nsaddr
; i
++) {
3741 if (vnc_display_listen_addr(vd
, saddr
[i
],
3750 for (i
= 0; i
< nwsaddr
; i
++) {
3751 if (vnc_display_listen_addr(vd
, wsaddr
[i
],
3765 void vnc_display_open(const char *id
, Error
**errp
)
3767 VncDisplay
*vd
= vnc_display_find(id
);
3768 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3769 SocketAddress
**saddr
= NULL
, **wsaddr
= NULL
;
3770 size_t nsaddr
, nwsaddr
;
3771 const char *share
, *device_id
;
3773 bool password
= false;
3774 bool reverse
= false;
3777 #ifdef CONFIG_VNC_SASL
3781 int lock_key_sync
= 1;
3785 error_setg(errp
, "VNC display not active");
3788 vnc_display_close(vd
);
3794 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3795 if (vnc_display_get_addresses(opts
, reverse
, &saddr
, &nsaddr
,
3796 &wsaddr
, &nwsaddr
, errp
) < 0) {
3800 password
= qemu_opt_get_bool(opts
, "password", false);
3802 if (fips_get_state()) {
3804 "VNC password auth disabled due to FIPS mode, "
3805 "consider using the VeNCrypt or SASL authentication "
3806 "methods as an alternative");
3809 if (!qcrypto_cipher_supports(
3810 QCRYPTO_CIPHER_ALG_DES_RFB
, QCRYPTO_CIPHER_MODE_ECB
)) {
3812 "Cipher backend does not support DES RFB algorithm");
3817 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3818 key_delay_ms
= qemu_opt_get_number(opts
, "key-delay-ms", 10);
3819 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3820 #ifndef CONFIG_VNC_SASL
3822 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3825 #endif /* CONFIG_VNC_SASL */
3826 credid
= qemu_opt_get(opts
, "tls-creds");
3829 if (qemu_opt_get(opts
, "tls") ||
3830 qemu_opt_get(opts
, "x509") ||
3831 qemu_opt_get(opts
, "x509verify")) {
3833 "'tls-creds' parameter is mutually exclusive with "
3834 "'tls', 'x509' and 'x509verify' parameters");
3838 creds
= object_resolve_path_component(
3839 object_get_objects_root(), credid
);
3841 error_setg(errp
, "No TLS credentials with id '%s'",
3845 vd
->tlscreds
= (QCryptoTLSCreds
*)
3846 object_dynamic_cast(creds
,
3847 TYPE_QCRYPTO_TLS_CREDS
);
3848 if (!vd
->tlscreds
) {
3849 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3853 object_ref(OBJECT(vd
->tlscreds
));
3855 if (vd
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3857 "Expecting TLS credentials with a server endpoint");
3862 bool tls
= false, x509
= false, x509verify
= false;
3863 tls
= qemu_opt_get_bool(opts
, "tls", false);
3865 path
= qemu_opt_get(opts
, "x509");
3870 path
= qemu_opt_get(opts
, "x509verify");
3876 vd
->tlscreds
= vnc_display_create_creds(x509
,
3881 if (!vd
->tlscreds
) {
3886 acl
= qemu_opt_get_bool(opts
, "acl", false);
3888 share
= qemu_opt_get(opts
, "share");
3890 if (strcmp(share
, "ignore") == 0) {
3891 vd
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3892 } else if (strcmp(share
, "allow-exclusive") == 0) {
3893 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3894 } else if (strcmp(share
, "force-shared") == 0) {
3895 vd
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3897 error_setg(errp
, "unknown vnc share= option");
3901 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3903 vd
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3905 #ifdef CONFIG_VNC_JPEG
3906 vd
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3908 vd
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3909 /* adaptive updates are only used with tight encoding and
3910 * if lossy updates are enabled so we can disable all the
3911 * calculations otherwise */
3913 vd
->non_adaptive
= true;
3917 if (strcmp(vd
->id
, "default") == 0) {
3918 vd
->tlsaclname
= g_strdup("vnc.x509dname");
3920 vd
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vd
->id
);
3922 qemu_acl_init(vd
->tlsaclname
);
3924 #ifdef CONFIG_VNC_SASL
3928 if (strcmp(vd
->id
, "default") == 0) {
3929 aclname
= g_strdup("vnc.username");
3931 aclname
= g_strdup_printf("vnc.%s.username", vd
->id
);
3933 vd
->sasl
.acl
= qemu_acl_init(aclname
);
3938 if (vnc_display_setup_auth(&vd
->auth
, &vd
->subauth
,
3939 vd
->tlscreds
, password
,
3940 sasl
, false, errp
) < 0) {
3943 trace_vnc_auth_init(vd
, 0, vd
->auth
, vd
->subauth
);
3945 if (vnc_display_setup_auth(&vd
->ws_auth
, &vd
->ws_subauth
,
3946 vd
->tlscreds
, password
,
3947 sasl
, true, errp
) < 0) {
3950 trace_vnc_auth_init(vd
, 1, vd
->ws_auth
, vd
->ws_subauth
);
3952 #ifdef CONFIG_VNC_SASL
3953 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3954 error_setg(errp
, "Failed to initialize SASL auth: %s",
3955 sasl_errstring(saslErr
, NULL
, NULL
));
3959 vd
->lock_key_sync
= lock_key_sync
;
3960 if (lock_key_sync
) {
3961 vd
->led
= qemu_add_led_event_handler(kbd_leds
, vd
);
3964 vd
->key_delay_ms
= key_delay_ms
;
3966 device_id
= qemu_opt_get(opts
, "display");
3968 int head
= qemu_opt_get_number(opts
, "head", 0);
3971 con
= qemu_console_lookup_by_device_name(device_id
, head
, &err
);
3973 error_propagate(errp
, err
);
3980 if (con
!= vd
->dcl
.con
) {
3981 unregister_displaychangelistener(&vd
->dcl
);
3983 register_displaychangelistener(&vd
->dcl
);
3986 if (saddr
== NULL
) {
3991 if (vnc_display_connect(vd
, saddr
, nsaddr
, wsaddr
, nwsaddr
, errp
) < 0) {
3995 if (vnc_display_listen(vd
, saddr
, nsaddr
, wsaddr
, nwsaddr
, errp
) < 0) {
4000 if (qemu_opt_get(opts
, "to")) {
4001 vnc_display_print_local_addr(vd
);
4005 vnc_free_addresses(&saddr
, &nsaddr
);
4006 vnc_free_addresses(&wsaddr
, &nwsaddr
);
4010 vnc_display_close(vd
);
4014 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
4016 VncDisplay
*vd
= vnc_display_find(id
);
4017 QIOChannelSocket
*sioc
;
4023 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
4025 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-server");
4026 vnc_connect(vd
, sioc
, skipauth
, false);
4027 object_unref(OBJECT(sioc
));
4031 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
4036 id
= g_strdup("default");
4037 while (qemu_opts_find(olist
, id
)) {
4039 id
= g_strdup_printf("vnc%d", i
++);
4041 qemu_opts_set_id(opts
, id
);
4044 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
4046 QemuOptsList
*olist
= qemu_find_opts("vnc");
4047 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
4054 id
= qemu_opts_id(opts
);
4056 /* auto-assign id if not present */
4057 vnc_auto_assign_id(olist
, opts
);
4062 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
4064 Error
*local_err
= NULL
;
4065 char *id
= (char *)qemu_opts_id(opts
);
4068 vnc_display_init(id
);
4069 vnc_display_open(id
, &local_err
);
4070 if (local_err
!= NULL
) {
4071 error_reportf_err(local_err
, "Failed to start VNC server: ");
4077 static void vnc_register_config(void)
4079 qemu_add_opts(&qemu_vnc_opts
);
4081 opts_init(vnc_register_config
);