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 vnc_set_share_mode(vs
, VNC_SHARE_MODE_DISCONNECTED
);
1123 g_source_remove(vs
->ioc_tag
);
1125 qio_channel_close(vs
->ioc
, NULL
);
1126 vs
->disconnecting
= TRUE
;
1129 void vnc_disconnect_finish(VncState
*vs
)
1133 vnc_jobs_join(vs
); /* Wait encoding jobs */
1135 vnc_lock_output(vs
);
1136 vnc_qmp_event(vs
, QAPI_EVENT_VNC_DISCONNECTED
);
1138 buffer_free(&vs
->input
);
1139 buffer_free(&vs
->output
);
1141 qapi_free_VncClientInfo(vs
->info
);
1144 vnc_tight_clear(vs
);
1147 #ifdef CONFIG_VNC_SASL
1148 vnc_sasl_client_cleanup(vs
);
1149 #endif /* CONFIG_VNC_SASL */
1151 vnc_release_modifiers(vs
);
1153 if (vs
->mouse_mode_notifier
.notify
!= NULL
) {
1154 qemu_remove_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
1156 QTAILQ_REMOVE(&vs
->vd
->clients
, vs
, next
);
1157 if (QTAILQ_EMPTY(&vs
->vd
->clients
)) {
1158 /* last client gone */
1159 vnc_update_server_surface(vs
->vd
);
1162 vnc_unlock_output(vs
);
1164 qemu_mutex_destroy(&vs
->output_mutex
);
1165 if (vs
->bh
!= NULL
) {
1166 qemu_bh_delete(vs
->bh
);
1168 buffer_free(&vs
->jobs_buffer
);
1170 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
1171 g_free(vs
->lossy_rect
[i
]);
1173 g_free(vs
->lossy_rect
);
1175 object_unref(OBJECT(vs
->ioc
));
1177 object_unref(OBJECT(vs
->sioc
));
1182 ssize_t
vnc_client_io_error(VncState
*vs
, ssize_t ret
, Error
**errp
)
1186 VNC_DEBUG("Closing down client sock: EOF\n");
1187 vnc_disconnect_start(vs
);
1188 } else if (ret
!= QIO_CHANNEL_ERR_BLOCK
) {
1189 VNC_DEBUG("Closing down client sock: ret %zd (%s)\n",
1190 ret
, errp
? error_get_pretty(*errp
) : "Unknown");
1191 vnc_disconnect_start(vs
);
1204 void vnc_client_error(VncState
*vs
)
1206 VNC_DEBUG("Closing down client sock: protocol error\n");
1207 vnc_disconnect_start(vs
);
1212 * Called to write a chunk of data to the client socket. The data may
1213 * be the raw data, or may have already been encoded by SASL.
1214 * The data will be written either straight onto the socket, or
1215 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1217 * NB, it is theoretically possible to have 2 layers of encryption,
1218 * both SASL, and this TLS layer. It is highly unlikely in practice
1219 * though, since SASL encryption will typically be a no-op if TLS
1222 * Returns the number of bytes written, which may be less than
1223 * the requested 'datalen' if the socket would block. Returns
1224 * -1 on error, and disconnects the client socket.
1226 ssize_t
vnc_client_write_buf(VncState
*vs
, const uint8_t *data
, size_t datalen
)
1230 ret
= qio_channel_write(
1231 vs
->ioc
, (const char *)data
, datalen
, &err
);
1232 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data
, datalen
, ret
);
1233 return vnc_client_io_error(vs
, ret
, &err
);
1238 * Called to write buffered data to the client socket, when not
1239 * using any SASL SSF encryption layers. Will write as much data
1240 * as possible without blocking. If all buffered data is written,
1241 * will switch the FD poll() handler back to read monitoring.
1243 * Returns the number of bytes written, which may be less than
1244 * the buffered output data if the socket would block. Returns
1245 * -1 on error, and disconnects the client socket.
1247 static ssize_t
vnc_client_write_plain(VncState
*vs
)
1251 #ifdef CONFIG_VNC_SASL
1252 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1253 vs
->output
.buffer
, vs
->output
.capacity
, vs
->output
.offset
,
1254 vs
->sasl
.waitWriteSSF
);
1256 if (vs
->sasl
.conn
&&
1258 vs
->sasl
.waitWriteSSF
) {
1259 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->sasl
.waitWriteSSF
);
1261 vs
->sasl
.waitWriteSSF
-= ret
;
1263 #endif /* CONFIG_VNC_SASL */
1264 ret
= vnc_client_write_buf(vs
, vs
->output
.buffer
, vs
->output
.offset
);
1268 buffer_advance(&vs
->output
, ret
);
1270 if (vs
->output
.offset
== 0) {
1272 g_source_remove(vs
->ioc_tag
);
1274 vs
->ioc_tag
= qio_channel_add_watch(
1275 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1283 * First function called whenever there is data to be written to
1284 * the client socket. Will delegate actual work according to whether
1285 * SASL SSF layers are enabled (thus requiring encryption calls)
1287 static void vnc_client_write_locked(VncState
*vs
)
1289 #ifdef CONFIG_VNC_SASL
1290 if (vs
->sasl
.conn
&&
1292 !vs
->sasl
.waitWriteSSF
) {
1293 vnc_client_write_sasl(vs
);
1295 #endif /* CONFIG_VNC_SASL */
1297 vnc_client_write_plain(vs
);
1301 static void vnc_client_write(VncState
*vs
)
1304 vnc_lock_output(vs
);
1305 if (vs
->output
.offset
) {
1306 vnc_client_write_locked(vs
);
1307 } else if (vs
->ioc
!= NULL
) {
1309 g_source_remove(vs
->ioc_tag
);
1311 vs
->ioc_tag
= qio_channel_add_watch(
1312 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
1314 vnc_unlock_output(vs
);
1317 void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
1319 vs
->read_handler
= func
;
1320 vs
->read_handler_expect
= expecting
;
1325 * Called to read a chunk of data from the client socket. The data may
1326 * be the raw data, or may need to be further decoded by SASL.
1327 * The data will be read either straight from to the socket, or
1328 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1330 * NB, it is theoretically possible to have 2 layers of encryption,
1331 * both SASL, and this TLS layer. It is highly unlikely in practice
1332 * though, since SASL encryption will typically be a no-op if TLS
1335 * Returns the number of bytes read, which may be less than
1336 * the requested 'datalen' if the socket would block. Returns
1337 * -1 on error, and disconnects the client socket.
1339 ssize_t
vnc_client_read_buf(VncState
*vs
, uint8_t *data
, size_t datalen
)
1343 ret
= qio_channel_read(
1344 vs
->ioc
, (char *)data
, datalen
, &err
);
1345 VNC_DEBUG("Read wire %p %zd -> %ld\n", data
, datalen
, ret
);
1346 return vnc_client_io_error(vs
, ret
, &err
);
1351 * Called to read data from the client socket to the input buffer,
1352 * when not using any SASL SSF encryption layers. Will read as much
1353 * data as possible without blocking.
1355 * Returns the number of bytes read. Returns -1 on error, and
1356 * disconnects the client socket.
1358 static ssize_t
vnc_client_read_plain(VncState
*vs
)
1361 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1362 vs
->input
.buffer
, vs
->input
.capacity
, vs
->input
.offset
);
1363 buffer_reserve(&vs
->input
, 4096);
1364 ret
= vnc_client_read_buf(vs
, buffer_end(&vs
->input
), 4096);
1367 vs
->input
.offset
+= ret
;
1371 static void vnc_jobs_bh(void *opaque
)
1373 VncState
*vs
= opaque
;
1375 vnc_jobs_consume_buffer(vs
);
1379 * First function called whenever there is more data to be read from
1380 * the client socket. Will delegate actual work according to whether
1381 * SASL SSF layers are enabled (thus requiring decryption calls)
1382 * Returns 0 on success, -1 if client disconnected
1384 static int vnc_client_read(VncState
*vs
)
1388 #ifdef CONFIG_VNC_SASL
1389 if (vs
->sasl
.conn
&& vs
->sasl
.runSSF
)
1390 ret
= vnc_client_read_sasl(vs
);
1392 #endif /* CONFIG_VNC_SASL */
1393 ret
= vnc_client_read_plain(vs
);
1395 if (vs
->disconnecting
) {
1396 vnc_disconnect_finish(vs
);
1402 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
1403 size_t len
= vs
->read_handler_expect
;
1406 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
1407 if (vs
->disconnecting
) {
1408 vnc_disconnect_finish(vs
);
1413 buffer_advance(&vs
->input
, len
);
1415 vs
->read_handler_expect
= ret
;
1421 gboolean
vnc_client_io(QIOChannel
*ioc G_GNUC_UNUSED
,
1422 GIOCondition condition
, void *opaque
)
1424 VncState
*vs
= opaque
;
1425 if (condition
& G_IO_IN
) {
1426 if (vnc_client_read(vs
) < 0) {
1430 if (condition
& G_IO_OUT
) {
1431 vnc_client_write(vs
);
1437 void vnc_write(VncState
*vs
, const void *data
, size_t len
)
1439 buffer_reserve(&vs
->output
, len
);
1441 if (vs
->ioc
!= NULL
&& buffer_empty(&vs
->output
)) {
1443 g_source_remove(vs
->ioc_tag
);
1445 vs
->ioc_tag
= qio_channel_add_watch(
1446 vs
->ioc
, G_IO_IN
| G_IO_OUT
, vnc_client_io
, vs
, NULL
);
1449 buffer_append(&vs
->output
, data
, len
);
1452 void vnc_write_s32(VncState
*vs
, int32_t value
)
1454 vnc_write_u32(vs
, *(uint32_t *)&value
);
1457 void vnc_write_u32(VncState
*vs
, uint32_t value
)
1461 buf
[0] = (value
>> 24) & 0xFF;
1462 buf
[1] = (value
>> 16) & 0xFF;
1463 buf
[2] = (value
>> 8) & 0xFF;
1464 buf
[3] = value
& 0xFF;
1466 vnc_write(vs
, buf
, 4);
1469 void vnc_write_u16(VncState
*vs
, uint16_t value
)
1473 buf
[0] = (value
>> 8) & 0xFF;
1474 buf
[1] = value
& 0xFF;
1476 vnc_write(vs
, buf
, 2);
1479 void vnc_write_u8(VncState
*vs
, uint8_t value
)
1481 vnc_write(vs
, (char *)&value
, 1);
1484 void vnc_flush(VncState
*vs
)
1486 vnc_lock_output(vs
);
1487 if (vs
->ioc
!= NULL
&& vs
->output
.offset
) {
1488 vnc_client_write_locked(vs
);
1490 vnc_unlock_output(vs
);
1493 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1495 return data
[offset
];
1498 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1500 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1503 static int32_t read_s32(uint8_t *data
, size_t offset
)
1505 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1506 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1509 uint32_t read_u32(uint8_t *data
, size_t offset
)
1511 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1512 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1515 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1519 static void check_pointer_type_change(Notifier
*notifier
, void *data
)
1521 VncState
*vs
= container_of(notifier
, VncState
, mouse_mode_notifier
);
1522 int absolute
= qemu_input_is_absolute();
1524 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1525 vnc_lock_output(vs
);
1526 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1527 vnc_write_u8(vs
, 0);
1528 vnc_write_u16(vs
, 1);
1529 vnc_framebuffer_update(vs
, absolute
, 0,
1530 pixman_image_get_width(vs
->vd
->server
),
1531 pixman_image_get_height(vs
->vd
->server
),
1532 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1533 vnc_unlock_output(vs
);
1536 vs
->absolute
= absolute
;
1539 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1541 static uint32_t bmap
[INPUT_BUTTON__MAX
] = {
1542 [INPUT_BUTTON_LEFT
] = 0x01,
1543 [INPUT_BUTTON_MIDDLE
] = 0x02,
1544 [INPUT_BUTTON_RIGHT
] = 0x04,
1545 [INPUT_BUTTON_WHEEL_UP
] = 0x08,
1546 [INPUT_BUTTON_WHEEL_DOWN
] = 0x10,
1548 QemuConsole
*con
= vs
->vd
->dcl
.con
;
1549 int width
= pixman_image_get_width(vs
->vd
->server
);
1550 int height
= pixman_image_get_height(vs
->vd
->server
);
1552 if (vs
->last_bmask
!= button_mask
) {
1553 qemu_input_update_buttons(con
, bmap
, vs
->last_bmask
, button_mask
);
1554 vs
->last_bmask
= button_mask
;
1558 qemu_input_queue_abs(con
, INPUT_AXIS_X
, x
, 0, width
);
1559 qemu_input_queue_abs(con
, INPUT_AXIS_Y
, y
, 0, height
);
1560 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1561 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- 0x7FFF);
1562 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- 0x7FFF);
1564 if (vs
->last_x
!= -1) {
1565 qemu_input_queue_rel(con
, INPUT_AXIS_X
, x
- vs
->last_x
);
1566 qemu_input_queue_rel(con
, INPUT_AXIS_Y
, y
- vs
->last_y
);
1571 qemu_input_event_sync();
1574 static void reset_keys(VncState
*vs
)
1577 for(i
= 0; i
< 256; i
++) {
1578 if (vs
->modifiers_state
[i
]) {
1579 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, i
, false);
1580 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1581 vs
->modifiers_state
[i
] = 0;
1586 static void press_key(VncState
*vs
, int keysym
)
1588 int keycode
= keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & SCANCODE_KEYMASK
;
1589 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, true);
1590 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1591 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1592 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1595 static void vnc_led_state_change(VncState
*vs
)
1597 if (!vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
)) {
1601 vnc_lock_output(vs
);
1602 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1603 vnc_write_u8(vs
, 0);
1604 vnc_write_u16(vs
, 1);
1605 vnc_framebuffer_update(vs
, 0, 0, 1, 1, VNC_ENCODING_LED_STATE
);
1606 vnc_write_u8(vs
, vs
->vd
->ledstate
);
1607 vnc_unlock_output(vs
);
1611 static void kbd_leds(void *opaque
, int ledstate
)
1613 VncDisplay
*vd
= opaque
;
1616 trace_vnc_key_guest_leds((ledstate
& QEMU_CAPS_LOCK_LED
),
1617 (ledstate
& QEMU_NUM_LOCK_LED
),
1618 (ledstate
& QEMU_SCROLL_LOCK_LED
));
1620 if (ledstate
== vd
->ledstate
) {
1624 vd
->ledstate
= ledstate
;
1626 QTAILQ_FOREACH(client
, &vd
->clients
, next
) {
1627 vnc_led_state_change(client
);
1631 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1633 /* QEMU console switch */
1635 case 0x2a: /* Left Shift */
1636 case 0x36: /* Right Shift */
1637 case 0x1d: /* Left CTRL */
1638 case 0x9d: /* Right CTRL */
1639 case 0x38: /* Left ALT */
1640 case 0xb8: /* Right ALT */
1642 vs
->modifiers_state
[keycode
] = 1;
1644 vs
->modifiers_state
[keycode
] = 0;
1646 case 0x02 ... 0x0a: /* '1' to '9' keys */
1647 if (vs
->vd
->dcl
.con
== NULL
&&
1648 down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1649 /* Reset the modifiers sent to the current console */
1651 console_select(keycode
- 0x02);
1655 case 0x3a: /* CapsLock */
1656 case 0x45: /* NumLock */
1658 vs
->modifiers_state
[keycode
] ^= 1;
1662 /* Turn off the lock state sync logic if the client support the led
1665 if (down
&& vs
->vd
->lock_key_sync
&&
1666 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1667 keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1668 /* If the numlock state needs to change then simulate an additional
1669 keypress before sending this one. This will happen if the user
1670 toggles numlock away from the VNC window.
1672 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1673 if (!vs
->modifiers_state
[0x45]) {
1674 trace_vnc_key_sync_numlock(true);
1675 vs
->modifiers_state
[0x45] = 1;
1676 press_key(vs
, 0xff7f);
1679 if (vs
->modifiers_state
[0x45]) {
1680 trace_vnc_key_sync_numlock(false);
1681 vs
->modifiers_state
[0x45] = 0;
1682 press_key(vs
, 0xff7f);
1687 if (down
&& vs
->vd
->lock_key_sync
&&
1688 !vnc_has_feature(vs
, VNC_FEATURE_LED_STATE
) &&
1689 ((sym
>= 'A' && sym
<= 'Z') || (sym
>= 'a' && sym
<= 'z'))) {
1690 /* If the capslock state needs to change then simulate an additional
1691 keypress before sending this one. This will happen if the user
1692 toggles capslock away from the VNC window.
1694 int uppercase
= !!(sym
>= 'A' && sym
<= 'Z');
1695 int shift
= !!(vs
->modifiers_state
[0x2a] | vs
->modifiers_state
[0x36]);
1696 int capslock
= !!(vs
->modifiers_state
[0x3a]);
1698 if (uppercase
== shift
) {
1699 trace_vnc_key_sync_capslock(false);
1700 vs
->modifiers_state
[0x3a] = 0;
1701 press_key(vs
, 0xffe5);
1704 if (uppercase
!= shift
) {
1705 trace_vnc_key_sync_capslock(true);
1706 vs
->modifiers_state
[0x3a] = 1;
1707 press_key(vs
, 0xffe5);
1712 if (qemu_console_is_graphic(NULL
)) {
1713 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, down
);
1714 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1716 bool numlock
= vs
->modifiers_state
[0x45];
1717 bool control
= (vs
->modifiers_state
[0x1d] ||
1718 vs
->modifiers_state
[0x9d]);
1719 /* QEMU console emulation */
1722 case 0x2a: /* Left Shift */
1723 case 0x36: /* Right Shift */
1724 case 0x1d: /* Left CTRL */
1725 case 0x9d: /* Right CTRL */
1726 case 0x38: /* Left ALT */
1727 case 0xb8: /* Right ALT */
1730 kbd_put_keysym(QEMU_KEY_UP
);
1733 kbd_put_keysym(QEMU_KEY_DOWN
);
1736 kbd_put_keysym(QEMU_KEY_LEFT
);
1739 kbd_put_keysym(QEMU_KEY_RIGHT
);
1742 kbd_put_keysym(QEMU_KEY_DELETE
);
1745 kbd_put_keysym(QEMU_KEY_HOME
);
1748 kbd_put_keysym(QEMU_KEY_END
);
1751 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1754 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1758 kbd_put_keysym(numlock
? '7' : QEMU_KEY_HOME
);
1761 kbd_put_keysym(numlock
? '8' : QEMU_KEY_UP
);
1764 kbd_put_keysym(numlock
? '9' : QEMU_KEY_PAGEUP
);
1767 kbd_put_keysym(numlock
? '4' : QEMU_KEY_LEFT
);
1770 kbd_put_keysym('5');
1773 kbd_put_keysym(numlock
? '6' : QEMU_KEY_RIGHT
);
1776 kbd_put_keysym(numlock
? '1' : QEMU_KEY_END
);
1779 kbd_put_keysym(numlock
? '2' : QEMU_KEY_DOWN
);
1782 kbd_put_keysym(numlock
? '3' : QEMU_KEY_PAGEDOWN
);
1785 kbd_put_keysym('0');
1788 kbd_put_keysym(numlock
? '.' : QEMU_KEY_DELETE
);
1792 kbd_put_keysym('/');
1795 kbd_put_keysym('*');
1798 kbd_put_keysym('-');
1801 kbd_put_keysym('+');
1804 kbd_put_keysym('\n');
1809 kbd_put_keysym(sym
& 0x1f);
1811 kbd_put_keysym(sym
);
1819 static void vnc_release_modifiers(VncState
*vs
)
1821 static const int keycodes
[] = {
1822 /* shift, control, alt keys, both left & right */
1823 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1827 if (!qemu_console_is_graphic(NULL
)) {
1830 for (i
= 0; i
< ARRAY_SIZE(keycodes
); i
++) {
1831 keycode
= keycodes
[i
];
1832 if (!vs
->modifiers_state
[keycode
]) {
1835 qemu_input_event_send_key_number(vs
->vd
->dcl
.con
, keycode
, false);
1836 qemu_input_event_send_key_delay(vs
->vd
->key_delay_ms
);
1840 static const char *code2name(int keycode
)
1842 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode
));
1845 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1850 if (lsym
>= 'A' && lsym
<= 'Z' && qemu_console_is_graphic(NULL
)) {
1851 lsym
= lsym
- 'A' + 'a';
1854 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, lsym
& 0xFFFF) & SCANCODE_KEYMASK
;
1855 trace_vnc_key_event_map(down
, sym
, keycode
, code2name(keycode
));
1856 do_key_event(vs
, down
, keycode
, sym
);
1859 static void ext_key_event(VncState
*vs
, int down
,
1860 uint32_t sym
, uint16_t keycode
)
1862 /* if the user specifies a keyboard layout, always use it */
1863 if (keyboard_layout
) {
1864 key_event(vs
, down
, sym
);
1866 trace_vnc_key_event_ext(down
, sym
, keycode
, code2name(keycode
));
1867 do_key_event(vs
, down
, keycode
, sym
);
1871 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1872 int x
, int y
, int w
, int h
)
1874 vs
->need_update
= 1;
1880 vs
->force_update
= 1;
1881 vnc_set_area_dirty(vs
->dirty
, vs
->vd
, x
, y
, w
, h
);
1884 static void send_ext_key_event_ack(VncState
*vs
)
1886 vnc_lock_output(vs
);
1887 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1888 vnc_write_u8(vs
, 0);
1889 vnc_write_u16(vs
, 1);
1890 vnc_framebuffer_update(vs
, 0, 0,
1891 pixman_image_get_width(vs
->vd
->server
),
1892 pixman_image_get_height(vs
->vd
->server
),
1893 VNC_ENCODING_EXT_KEY_EVENT
);
1894 vnc_unlock_output(vs
);
1898 static void send_ext_audio_ack(VncState
*vs
)
1900 vnc_lock_output(vs
);
1901 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
1902 vnc_write_u8(vs
, 0);
1903 vnc_write_u16(vs
, 1);
1904 vnc_framebuffer_update(vs
, 0, 0,
1905 pixman_image_get_width(vs
->vd
->server
),
1906 pixman_image_get_height(vs
->vd
->server
),
1907 VNC_ENCODING_AUDIO
);
1908 vnc_unlock_output(vs
);
1912 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
1915 unsigned int enc
= 0;
1918 vs
->vnc_encoding
= 0;
1919 vs
->tight
.compression
= 9;
1920 vs
->tight
.quality
= -1; /* Lossless by default */
1924 * Start from the end because the encodings are sent in order of preference.
1925 * This way the preferred encoding (first encoding defined in the array)
1926 * will be set at the end of the loop.
1928 for (i
= n_encodings
- 1; i
>= 0; i
--) {
1931 case VNC_ENCODING_RAW
:
1932 vs
->vnc_encoding
= enc
;
1934 case VNC_ENCODING_COPYRECT
:
1935 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
1937 case VNC_ENCODING_HEXTILE
:
1938 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
1939 vs
->vnc_encoding
= enc
;
1941 case VNC_ENCODING_TIGHT
:
1942 vs
->features
|= VNC_FEATURE_TIGHT_MASK
;
1943 vs
->vnc_encoding
= enc
;
1945 #ifdef CONFIG_VNC_PNG
1946 case VNC_ENCODING_TIGHT_PNG
:
1947 vs
->features
|= VNC_FEATURE_TIGHT_PNG_MASK
;
1948 vs
->vnc_encoding
= enc
;
1951 case VNC_ENCODING_ZLIB
:
1952 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
1953 vs
->vnc_encoding
= enc
;
1955 case VNC_ENCODING_ZRLE
:
1956 vs
->features
|= VNC_FEATURE_ZRLE_MASK
;
1957 vs
->vnc_encoding
= enc
;
1959 case VNC_ENCODING_ZYWRLE
:
1960 vs
->features
|= VNC_FEATURE_ZYWRLE_MASK
;
1961 vs
->vnc_encoding
= enc
;
1963 case VNC_ENCODING_DESKTOPRESIZE
:
1964 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
1966 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
1967 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
1969 case VNC_ENCODING_RICH_CURSOR
:
1970 vs
->features
|= VNC_FEATURE_RICH_CURSOR_MASK
;
1971 if (vs
->vd
->cursor
) {
1972 vnc_cursor_define(vs
);
1975 case VNC_ENCODING_EXT_KEY_EVENT
:
1976 send_ext_key_event_ack(vs
);
1978 case VNC_ENCODING_AUDIO
:
1979 send_ext_audio_ack(vs
);
1981 case VNC_ENCODING_WMVi
:
1982 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
1984 case VNC_ENCODING_LED_STATE
:
1985 vs
->features
|= VNC_FEATURE_LED_STATE_MASK
;
1987 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
1988 vs
->tight
.compression
= (enc
& 0x0F);
1990 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
1991 if (vs
->vd
->lossy
) {
1992 vs
->tight
.quality
= (enc
& 0x0F);
1996 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
2000 vnc_desktop_resize(vs
);
2001 check_pointer_type_change(&vs
->mouse_mode_notifier
, NULL
);
2002 vnc_led_state_change(vs
);
2005 static void set_pixel_conversion(VncState
*vs
)
2007 pixman_format_code_t fmt
= qemu_pixman_get_format(&vs
->client_pf
);
2009 if (fmt
== VNC_SERVER_FB_FORMAT
) {
2010 vs
->write_pixels
= vnc_write_pixels_copy
;
2011 vnc_hextile_set_pixel_conversion(vs
, 0);
2013 vs
->write_pixels
= vnc_write_pixels_generic
;
2014 vnc_hextile_set_pixel_conversion(vs
, 1);
2018 static void send_color_map(VncState
*vs
)
2022 vnc_write_u8(vs
, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES
);
2023 vnc_write_u8(vs
, 0); /* padding */
2024 vnc_write_u16(vs
, 0); /* first color */
2025 vnc_write_u16(vs
, 256); /* # of colors */
2027 for (i
= 0; i
< 256; i
++) {
2028 PixelFormat
*pf
= &vs
->client_pf
;
2030 vnc_write_u16(vs
, (((i
>> pf
->rshift
) & pf
->rmax
) << (16 - pf
->rbits
)));
2031 vnc_write_u16(vs
, (((i
>> pf
->gshift
) & pf
->gmax
) << (16 - pf
->gbits
)));
2032 vnc_write_u16(vs
, (((i
>> pf
->bshift
) & pf
->bmax
) << (16 - pf
->bbits
)));
2036 static void set_pixel_format(VncState
*vs
, int bits_per_pixel
,
2037 int big_endian_flag
, int true_color_flag
,
2038 int red_max
, int green_max
, int blue_max
,
2039 int red_shift
, int green_shift
, int blue_shift
)
2041 if (!true_color_flag
) {
2042 /* Expose a reasonable default 256 color map */
2052 switch (bits_per_pixel
) {
2058 vnc_client_error(vs
);
2062 vs
->client_pf
.rmax
= red_max
? red_max
: 0xFF;
2063 vs
->client_pf
.rbits
= ctpopl(red_max
);
2064 vs
->client_pf
.rshift
= red_shift
;
2065 vs
->client_pf
.rmask
= red_max
<< red_shift
;
2066 vs
->client_pf
.gmax
= green_max
? green_max
: 0xFF;
2067 vs
->client_pf
.gbits
= ctpopl(green_max
);
2068 vs
->client_pf
.gshift
= green_shift
;
2069 vs
->client_pf
.gmask
= green_max
<< green_shift
;
2070 vs
->client_pf
.bmax
= blue_max
? blue_max
: 0xFF;
2071 vs
->client_pf
.bbits
= ctpopl(blue_max
);
2072 vs
->client_pf
.bshift
= blue_shift
;
2073 vs
->client_pf
.bmask
= blue_max
<< blue_shift
;
2074 vs
->client_pf
.bits_per_pixel
= bits_per_pixel
;
2075 vs
->client_pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
2076 vs
->client_pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
2077 vs
->client_be
= big_endian_flag
;
2079 if (!true_color_flag
) {
2083 set_pixel_conversion(vs
);
2085 graphic_hw_invalidate(vs
->vd
->dcl
.con
);
2086 graphic_hw_update(vs
->vd
->dcl
.con
);
2089 static void pixel_format_message (VncState
*vs
) {
2090 char pad
[3] = { 0, 0, 0 };
2092 vs
->client_pf
= qemu_default_pixelformat(32);
2094 vnc_write_u8(vs
, vs
->client_pf
.bits_per_pixel
); /* bits-per-pixel */
2095 vnc_write_u8(vs
, vs
->client_pf
.depth
); /* depth */
2097 #ifdef HOST_WORDS_BIGENDIAN
2098 vnc_write_u8(vs
, 1); /* big-endian-flag */
2100 vnc_write_u8(vs
, 0); /* big-endian-flag */
2102 vnc_write_u8(vs
, 1); /* true-color-flag */
2103 vnc_write_u16(vs
, vs
->client_pf
.rmax
); /* red-max */
2104 vnc_write_u16(vs
, vs
->client_pf
.gmax
); /* green-max */
2105 vnc_write_u16(vs
, vs
->client_pf
.bmax
); /* blue-max */
2106 vnc_write_u8(vs
, vs
->client_pf
.rshift
); /* red-shift */
2107 vnc_write_u8(vs
, vs
->client_pf
.gshift
); /* green-shift */
2108 vnc_write_u8(vs
, vs
->client_pf
.bshift
); /* blue-shift */
2109 vnc_write(vs
, pad
, 3); /* padding */
2111 vnc_hextile_set_pixel_conversion(vs
, 0);
2112 vs
->write_pixels
= vnc_write_pixels_copy
;
2115 static void vnc_colordepth(VncState
*vs
)
2117 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
2118 /* Sending a WMVi message to notify the client*/
2119 vnc_lock_output(vs
);
2120 vnc_write_u8(vs
, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE
);
2121 vnc_write_u8(vs
, 0);
2122 vnc_write_u16(vs
, 1); /* number of rects */
2123 vnc_framebuffer_update(vs
, 0, 0,
2124 pixman_image_get_width(vs
->vd
->server
),
2125 pixman_image_get_height(vs
->vd
->server
),
2127 pixel_format_message(vs
);
2128 vnc_unlock_output(vs
);
2131 set_pixel_conversion(vs
);
2135 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
2139 VncDisplay
*vd
= vs
->vd
;
2142 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2146 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT
:
2150 set_pixel_format(vs
, read_u8(data
, 4),
2151 read_u8(data
, 6), read_u8(data
, 7),
2152 read_u16(data
, 8), read_u16(data
, 10),
2153 read_u16(data
, 12), read_u8(data
, 14),
2154 read_u8(data
, 15), read_u8(data
, 16));
2156 case VNC_MSG_CLIENT_SET_ENCODINGS
:
2161 limit
= read_u16(data
, 2);
2163 return 4 + (limit
* 4);
2165 limit
= read_u16(data
, 2);
2167 for (i
= 0; i
< limit
; i
++) {
2168 int32_t val
= read_s32(data
, 4 + (i
* 4));
2169 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
2172 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
2174 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST
:
2178 framebuffer_update_request(vs
,
2179 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
2180 read_u16(data
, 6), read_u16(data
, 8));
2182 case VNC_MSG_CLIENT_KEY_EVENT
:
2186 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
2188 case VNC_MSG_CLIENT_POINTER_EVENT
:
2192 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
2194 case VNC_MSG_CLIENT_CUT_TEXT
:
2199 uint32_t dlen
= read_u32(data
, 4);
2200 if (dlen
> (1 << 20)) {
2201 error_report("vnc: client_cut_text msg payload has %u bytes"
2202 " which exceeds our limit of 1MB.", dlen
);
2203 vnc_client_error(vs
);
2211 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
2213 case VNC_MSG_CLIENT_QEMU
:
2217 switch (read_u8(data
, 1)) {
2218 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT
:
2222 ext_key_event(vs
, read_u16(data
, 2),
2223 read_u32(data
, 4), read_u32(data
, 8));
2225 case VNC_MSG_CLIENT_QEMU_AUDIO
:
2229 switch (read_u16 (data
, 2)) {
2230 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE
:
2233 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE
:
2236 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT
:
2239 switch (read_u8(data
, 4)) {
2240 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
2241 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
2242 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
2243 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
2244 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
2245 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
2247 VNC_DEBUG("Invalid audio format %d\n", read_u8(data
, 4));
2248 vnc_client_error(vs
);
2251 vs
->as
.nchannels
= read_u8(data
, 5);
2252 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
2253 VNC_DEBUG("Invalid audio channel coount %d\n",
2255 vnc_client_error(vs
);
2258 vs
->as
.freq
= read_u32(data
, 6);
2261 VNC_DEBUG("Invalid audio message %d\n", read_u8(data
, 4));
2262 vnc_client_error(vs
);
2268 VNC_DEBUG("Msg: %d\n", read_u16(data
, 0));
2269 vnc_client_error(vs
);
2274 VNC_DEBUG("Msg: %d\n", data
[0]);
2275 vnc_client_error(vs
);
2279 vnc_read_when(vs
, protocol_client_msg
, 1);
2283 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
2289 mode
= data
[0] ? VNC_SHARE_MODE_SHARED
: VNC_SHARE_MODE_EXCLUSIVE
;
2290 switch (vs
->vd
->share_policy
) {
2291 case VNC_SHARE_POLICY_IGNORE
:
2293 * Ignore the shared flag. Nothing to do here.
2295 * Doesn't conform to the rfb spec but is traditional qemu
2296 * behavior, thus left here as option for compatibility
2300 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
:
2302 * Policy: Allow clients ask for exclusive access.
2304 * Implementation: When a client asks for exclusive access,
2305 * disconnect all others. Shared connects are allowed as long
2306 * as no exclusive connection exists.
2308 * This is how the rfb spec suggests to handle the shared flag.
2310 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2312 QTAILQ_FOREACH(client
, &vs
->vd
->clients
, next
) {
2316 if (client
->share_mode
!= VNC_SHARE_MODE_EXCLUSIVE
&&
2317 client
->share_mode
!= VNC_SHARE_MODE_SHARED
) {
2320 vnc_disconnect_start(client
);
2323 if (mode
== VNC_SHARE_MODE_SHARED
) {
2324 if (vs
->vd
->num_exclusive
> 0) {
2325 vnc_disconnect_start(vs
);
2330 case VNC_SHARE_POLICY_FORCE_SHARED
:
2332 * Policy: Shared connects only.
2333 * Implementation: Disallow clients asking for exclusive access.
2335 * Useful for shared desktop sessions where you don't want
2336 * someone forgetting to say -shared when running the vnc
2337 * client disconnect everybody else.
2339 if (mode
== VNC_SHARE_MODE_EXCLUSIVE
) {
2340 vnc_disconnect_start(vs
);
2345 vnc_set_share_mode(vs
, mode
);
2347 if (vs
->vd
->num_shared
> vs
->vd
->connections_limit
) {
2348 vnc_disconnect_start(vs
);
2352 vs
->client_width
= pixman_image_get_width(vs
->vd
->server
);
2353 vs
->client_height
= pixman_image_get_height(vs
->vd
->server
);
2354 vnc_write_u16(vs
, vs
->client_width
);
2355 vnc_write_u16(vs
, vs
->client_height
);
2357 pixel_format_message(vs
);
2360 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
2361 if (size
> sizeof(buf
)) {
2365 size
= snprintf(buf
, sizeof(buf
), "QEMU");
2368 vnc_write_u32(vs
, size
);
2369 vnc_write(vs
, buf
, size
);
2372 vnc_client_cache_auth(vs
);
2373 vnc_qmp_event(vs
, QAPI_EVENT_VNC_INITIALIZED
);
2375 vnc_read_when(vs
, protocol_client_msg
, 1);
2380 void start_client_init(VncState
*vs
)
2382 vnc_read_when(vs
, protocol_client_init
, 1);
2385 static void make_challenge(VncState
*vs
)
2389 srand(time(NULL
)+getpid()+getpid()*987654+rand());
2391 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
2392 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
2395 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
2397 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
2399 unsigned char key
[8];
2400 time_t now
= time(NULL
);
2401 QCryptoCipher
*cipher
= NULL
;
2404 if (!vs
->vd
->password
) {
2405 VNC_DEBUG("No password configured on server");
2408 if (vs
->vd
->expires
< now
) {
2409 VNC_DEBUG("Password is expired");
2413 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
2415 /* Calculate the expected challenge response */
2416 pwlen
= strlen(vs
->vd
->password
);
2417 for (i
=0; i
<sizeof(key
); i
++)
2418 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
2420 cipher
= qcrypto_cipher_new(
2421 QCRYPTO_CIPHER_ALG_DES_RFB
,
2422 QCRYPTO_CIPHER_MODE_ECB
,
2423 key
, G_N_ELEMENTS(key
),
2426 VNC_DEBUG("Cannot initialize cipher %s",
2427 error_get_pretty(err
));
2432 if (qcrypto_cipher_encrypt(cipher
,
2435 VNC_AUTH_CHALLENGE_SIZE
,
2437 VNC_DEBUG("Cannot encrypt challenge %s",
2438 error_get_pretty(err
));
2443 /* Compare expected vs actual challenge response */
2444 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
2445 VNC_DEBUG("Client challenge response did not match\n");
2448 VNC_DEBUG("Accepting VNC challenge response\n");
2449 vnc_write_u32(vs
, 0); /* Accept auth */
2452 start_client_init(vs
);
2455 qcrypto_cipher_free(cipher
);
2459 vnc_write_u32(vs
, 1); /* Reject auth */
2460 if (vs
->minor
>= 8) {
2461 static const char err
[] = "Authentication failed";
2462 vnc_write_u32(vs
, sizeof(err
));
2463 vnc_write(vs
, err
, sizeof(err
));
2466 vnc_client_error(vs
);
2467 qcrypto_cipher_free(cipher
);
2471 void start_auth_vnc(VncState
*vs
)
2474 /* Send client a 'random' challenge */
2475 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
2478 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
2482 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2484 /* We only advertise 1 auth scheme at a time, so client
2485 * must pick the one we sent. Verify this */
2486 if (data
[0] != vs
->auth
) { /* Reject auth */
2487 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data
[0]);
2488 vnc_write_u32(vs
, 1);
2489 if (vs
->minor
>= 8) {
2490 static const char err
[] = "Authentication failed";
2491 vnc_write_u32(vs
, sizeof(err
));
2492 vnc_write(vs
, err
, sizeof(err
));
2494 vnc_client_error(vs
);
2495 } else { /* Accept requested auth */
2496 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2499 VNC_DEBUG("Accept auth none\n");
2500 if (vs
->minor
>= 8) {
2501 vnc_write_u32(vs
, 0); /* Accept auth completion */
2504 start_client_init(vs
);
2508 VNC_DEBUG("Start VNC auth\n");
2512 case VNC_AUTH_VENCRYPT
:
2513 VNC_DEBUG("Accept VeNCrypt auth\n");
2514 start_auth_vencrypt(vs
);
2517 #ifdef CONFIG_VNC_SASL
2519 VNC_DEBUG("Accept SASL auth\n");
2520 start_auth_sasl(vs
);
2522 #endif /* CONFIG_VNC_SASL */
2524 default: /* Should not be possible, but just in case */
2525 VNC_DEBUG("Reject auth %d server code bug\n", vs
->auth
);
2526 vnc_write_u8(vs
, 1);
2527 if (vs
->minor
>= 8) {
2528 static const char err
[] = "Authentication failed";
2529 vnc_write_u32(vs
, sizeof(err
));
2530 vnc_write(vs
, err
, sizeof(err
));
2532 vnc_client_error(vs
);
2538 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2542 memcpy(local
, version
, 12);
2545 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2546 VNC_DEBUG("Malformed protocol version %s\n", local
);
2547 vnc_client_error(vs
);
2550 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2551 if (vs
->major
!= 3 ||
2557 VNC_DEBUG("Unsupported client version\n");
2558 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2560 vnc_client_error(vs
);
2563 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2564 * as equivalent to v3.3 by servers
2566 if (vs
->minor
== 4 || vs
->minor
== 5)
2569 if (vs
->minor
== 3) {
2570 if (vs
->auth
== VNC_AUTH_NONE
) {
2571 VNC_DEBUG("Tell client auth none\n");
2572 vnc_write_u32(vs
, vs
->auth
);
2574 start_client_init(vs
);
2575 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2576 VNC_DEBUG("Tell client VNC auth\n");
2577 vnc_write_u32(vs
, vs
->auth
);
2581 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2582 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2584 vnc_client_error(vs
);
2587 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2588 vnc_write_u8(vs
, 1); /* num auth */
2589 vnc_write_u8(vs
, vs
->auth
);
2590 vnc_read_when(vs
, protocol_client_auth
, 1);
2597 static VncRectStat
*vnc_stat_rect(VncDisplay
*vd
, int x
, int y
)
2599 struct VncSurface
*vs
= &vd
->guest
;
2601 return &vs
->stats
[y
/ VNC_STAT_RECT
][x
/ VNC_STAT_RECT
];
2604 void vnc_sent_lossy_rect(VncState
*vs
, int x
, int y
, int w
, int h
)
2608 w
= (x
+ w
) / VNC_STAT_RECT
;
2609 h
= (y
+ h
) / VNC_STAT_RECT
;
2613 for (j
= y
; j
<= h
; j
++) {
2614 for (i
= x
; i
<= w
; i
++) {
2615 vs
->lossy_rect
[j
][i
] = 1;
2620 static int vnc_refresh_lossy_rect(VncDisplay
*vd
, int x
, int y
)
2623 int sty
= y
/ VNC_STAT_RECT
;
2624 int stx
= x
/ VNC_STAT_RECT
;
2627 y
= QEMU_ALIGN_DOWN(y
, VNC_STAT_RECT
);
2628 x
= QEMU_ALIGN_DOWN(x
, VNC_STAT_RECT
);
2630 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2633 /* kernel send buffers are full -> refresh later */
2634 if (vs
->output
.offset
) {
2638 if (!vs
->lossy_rect
[sty
][stx
]) {
2642 vs
->lossy_rect
[sty
][stx
] = 0;
2643 for (j
= 0; j
< VNC_STAT_RECT
; ++j
) {
2644 bitmap_set(vs
->dirty
[y
+ j
],
2645 x
/ VNC_DIRTY_PIXELS_PER_BIT
,
2646 VNC_STAT_RECT
/ VNC_DIRTY_PIXELS_PER_BIT
);
2654 static int vnc_update_stats(VncDisplay
*vd
, struct timeval
* tv
)
2656 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2657 pixman_image_get_width(vd
->server
));
2658 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2659 pixman_image_get_height(vd
->server
));
2664 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2665 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2666 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2668 rect
->updated
= false;
2672 qemu_timersub(tv
, &VNC_REFRESH_STATS
, &res
);
2674 if (timercmp(&vd
->guest
.last_freq_check
, &res
, >)) {
2677 vd
->guest
.last_freq_check
= *tv
;
2679 for (y
= 0; y
< height
; y
+= VNC_STAT_RECT
) {
2680 for (x
= 0; x
< width
; x
+= VNC_STAT_RECT
) {
2681 VncRectStat
*rect
= vnc_stat_rect(vd
, x
, y
);
2682 int count
= ARRAY_SIZE(rect
->times
);
2683 struct timeval min
, max
;
2685 if (!timerisset(&rect
->times
[count
- 1])) {
2689 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2690 qemu_timersub(tv
, &max
, &res
);
2692 if (timercmp(&res
, &VNC_REFRESH_LOSSY
, >)) {
2694 has_dirty
+= vnc_refresh_lossy_rect(vd
, x
, y
);
2695 memset(rect
->times
, 0, sizeof (rect
->times
));
2699 min
= rect
->times
[rect
->idx
];
2700 max
= rect
->times
[(rect
->idx
+ count
- 1) % count
];
2701 qemu_timersub(&max
, &min
, &res
);
2703 rect
->freq
= res
.tv_sec
+ res
.tv_usec
/ 1000000.;
2704 rect
->freq
/= count
;
2705 rect
->freq
= 1. / rect
->freq
;
2711 double vnc_update_freq(VncState
*vs
, int x
, int y
, int w
, int h
)
2717 x
= QEMU_ALIGN_DOWN(x
, VNC_STAT_RECT
);
2718 y
= QEMU_ALIGN_DOWN(y
, VNC_STAT_RECT
);
2720 for (j
= y
; j
<= y
+ h
; j
+= VNC_STAT_RECT
) {
2721 for (i
= x
; i
<= x
+ w
; i
+= VNC_STAT_RECT
) {
2722 total
+= vnc_stat_rect(vs
->vd
, i
, j
)->freq
;
2734 static void vnc_rect_updated(VncDisplay
*vd
, int x
, int y
, struct timeval
* tv
)
2738 rect
= vnc_stat_rect(vd
, x
, y
);
2739 if (rect
->updated
) {
2742 rect
->times
[rect
->idx
] = *tv
;
2743 rect
->idx
= (rect
->idx
+ 1) % ARRAY_SIZE(rect
->times
);
2744 rect
->updated
= true;
2747 static int vnc_refresh_server_surface(VncDisplay
*vd
)
2749 int width
= MIN(pixman_image_get_width(vd
->guest
.fb
),
2750 pixman_image_get_width(vd
->server
));
2751 int height
= MIN(pixman_image_get_height(vd
->guest
.fb
),
2752 pixman_image_get_height(vd
->server
));
2753 int cmp_bytes
, server_stride
, line_bytes
, guest_ll
, guest_stride
, y
= 0;
2754 uint8_t *guest_row0
= NULL
, *server_row0
;
2757 pixman_image_t
*tmpbuf
= NULL
;
2759 struct timeval tv
= { 0, 0 };
2761 if (!vd
->non_adaptive
) {
2762 gettimeofday(&tv
, NULL
);
2763 has_dirty
= vnc_update_stats(vd
, &tv
);
2767 * Walk through the guest dirty map.
2768 * Check and copy modified bits from guest to server surface.
2769 * Update server dirty map.
2771 server_row0
= (uint8_t *)pixman_image_get_data(vd
->server
);
2772 server_stride
= guest_stride
= guest_ll
=
2773 pixman_image_get_stride(vd
->server
);
2774 cmp_bytes
= MIN(VNC_DIRTY_PIXELS_PER_BIT
* VNC_SERVER_FB_BYTES
,
2776 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2777 int width
= pixman_image_get_width(vd
->server
);
2778 tmpbuf
= qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT
, width
);
2781 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd
->guest
.fb
));
2782 guest_row0
= (uint8_t *)pixman_image_get_data(vd
->guest
.fb
);
2783 guest_stride
= pixman_image_get_stride(vd
->guest
.fb
);
2784 guest_ll
= pixman_image_get_width(vd
->guest
.fb
) * (DIV_ROUND_UP(guest_bpp
, 8));
2786 line_bytes
= MIN(server_stride
, guest_ll
);
2790 uint8_t *guest_ptr
, *server_ptr
;
2791 unsigned long offset
= find_next_bit((unsigned long *) &vd
->guest
.dirty
,
2792 height
* VNC_DIRTY_BPL(&vd
->guest
),
2793 y
* VNC_DIRTY_BPL(&vd
->guest
));
2794 if (offset
== height
* VNC_DIRTY_BPL(&vd
->guest
)) {
2795 /* no more dirty bits */
2798 y
= offset
/ VNC_DIRTY_BPL(&vd
->guest
);
2799 x
= offset
% VNC_DIRTY_BPL(&vd
->guest
);
2801 server_ptr
= server_row0
+ y
* server_stride
+ x
* cmp_bytes
;
2803 if (vd
->guest
.format
!= VNC_SERVER_FB_FORMAT
) {
2804 qemu_pixman_linebuf_fill(tmpbuf
, vd
->guest
.fb
, width
, 0, y
);
2805 guest_ptr
= (uint8_t *)pixman_image_get_data(tmpbuf
);
2807 guest_ptr
= guest_row0
+ y
* guest_stride
;
2809 guest_ptr
+= x
* cmp_bytes
;
2811 for (; x
< DIV_ROUND_UP(width
, VNC_DIRTY_PIXELS_PER_BIT
);
2812 x
++, guest_ptr
+= cmp_bytes
, server_ptr
+= cmp_bytes
) {
2813 int _cmp_bytes
= cmp_bytes
;
2814 if (!test_and_clear_bit(x
, vd
->guest
.dirty
[y
])) {
2817 if ((x
+ 1) * cmp_bytes
> line_bytes
) {
2818 _cmp_bytes
= line_bytes
- x
* cmp_bytes
;
2820 assert(_cmp_bytes
>= 0);
2821 if (memcmp(server_ptr
, guest_ptr
, _cmp_bytes
) == 0) {
2824 memcpy(server_ptr
, guest_ptr
, _cmp_bytes
);
2825 if (!vd
->non_adaptive
) {
2826 vnc_rect_updated(vd
, x
* VNC_DIRTY_PIXELS_PER_BIT
,
2829 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2830 set_bit(x
, vs
->dirty
[y
]);
2837 qemu_pixman_image_unref(tmpbuf
);
2841 static void vnc_refresh(DisplayChangeListener
*dcl
)
2843 VncDisplay
*vd
= container_of(dcl
, VncDisplay
, dcl
);
2845 int has_dirty
, rects
= 0;
2847 if (QTAILQ_EMPTY(&vd
->clients
)) {
2848 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_MAX
);
2852 graphic_hw_update(vd
->dcl
.con
);
2854 if (vnc_trylock_display(vd
)) {
2855 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2859 has_dirty
= vnc_refresh_server_surface(vd
);
2860 vnc_unlock_display(vd
);
2862 QTAILQ_FOREACH_SAFE(vs
, &vd
->clients
, next
, vn
) {
2863 rects
+= vnc_update_client(vs
, has_dirty
, false);
2864 /* vs might be free()ed here */
2867 if (has_dirty
&& rects
) {
2868 vd
->dcl
.update_interval
/= 2;
2869 if (vd
->dcl
.update_interval
< VNC_REFRESH_INTERVAL_BASE
) {
2870 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_BASE
;
2873 vd
->dcl
.update_interval
+= VNC_REFRESH_INTERVAL_INC
;
2874 if (vd
->dcl
.update_interval
> VNC_REFRESH_INTERVAL_MAX
) {
2875 vd
->dcl
.update_interval
= VNC_REFRESH_INTERVAL_MAX
;
2880 static void vnc_connect(VncDisplay
*vd
, QIOChannelSocket
*sioc
,
2881 bool skipauth
, bool websocket
)
2883 VncState
*vs
= g_new0(VncState
, 1);
2884 bool first_client
= QTAILQ_EMPTY(&vd
->clients
);
2888 object_ref(OBJECT(vs
->sioc
));
2889 vs
->ioc
= QIO_CHANNEL(sioc
);
2890 object_ref(OBJECT(vs
->ioc
));
2893 buffer_init(&vs
->input
, "vnc-input/%p", sioc
);
2894 buffer_init(&vs
->output
, "vnc-output/%p", sioc
);
2895 buffer_init(&vs
->jobs_buffer
, "vnc-jobs_buffer/%p", sioc
);
2897 buffer_init(&vs
->tight
.tight
, "vnc-tight/%p", sioc
);
2898 buffer_init(&vs
->tight
.zlib
, "vnc-tight-zlib/%p", sioc
);
2899 buffer_init(&vs
->tight
.gradient
, "vnc-tight-gradient/%p", sioc
);
2900 #ifdef CONFIG_VNC_JPEG
2901 buffer_init(&vs
->tight
.jpeg
, "vnc-tight-jpeg/%p", sioc
);
2903 #ifdef CONFIG_VNC_PNG
2904 buffer_init(&vs
->tight
.png
, "vnc-tight-png/%p", sioc
);
2906 buffer_init(&vs
->zlib
.zlib
, "vnc-zlib/%p", sioc
);
2907 buffer_init(&vs
->zrle
.zrle
, "vnc-zrle/%p", sioc
);
2908 buffer_init(&vs
->zrle
.fb
, "vnc-zrle-fb/%p", sioc
);
2909 buffer_init(&vs
->zrle
.zlib
, "vnc-zrle-zlib/%p", sioc
);
2912 vs
->auth
= VNC_AUTH_NONE
;
2913 vs
->subauth
= VNC_AUTH_INVALID
;
2916 vs
->auth
= vd
->ws_auth
;
2917 vs
->subauth
= VNC_AUTH_INVALID
;
2919 vs
->auth
= vd
->auth
;
2920 vs
->subauth
= vd
->subauth
;
2923 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
2924 sioc
, websocket
, vs
->auth
, vs
->subauth
);
2926 vs
->lossy_rect
= g_malloc0(VNC_STAT_ROWS
* sizeof (*vs
->lossy_rect
));
2927 for (i
= 0; i
< VNC_STAT_ROWS
; ++i
) {
2928 vs
->lossy_rect
[i
] = g_new0(uint8_t, VNC_STAT_COLS
);
2931 VNC_DEBUG("New client on socket %p\n", vs
->sioc
);
2932 update_displaychangelistener(&vd
->dcl
, VNC_REFRESH_INTERVAL_BASE
);
2933 qio_channel_set_blocking(vs
->ioc
, false, NULL
);
2937 vs
->ioc_tag
= qio_channel_add_watch(
2938 vs
->ioc
, G_IO_IN
, vncws_tls_handshake_io
, vs
, NULL
);
2940 vs
->ioc_tag
= qio_channel_add_watch(
2941 vs
->ioc
, G_IO_IN
, vncws_handshake_io
, vs
, NULL
);
2944 vs
->ioc_tag
= qio_channel_add_watch(
2945 vs
->ioc
, G_IO_IN
, vnc_client_io
, vs
, NULL
);
2948 vnc_client_cache_addr(vs
);
2949 vnc_qmp_event(vs
, QAPI_EVENT_VNC_CONNECTED
);
2950 vnc_set_share_mode(vs
, VNC_SHARE_MODE_CONNECTING
);
2955 vs
->as
.freq
= 44100;
2956 vs
->as
.nchannels
= 2;
2957 vs
->as
.fmt
= AUD_FMT_S16
;
2958 vs
->as
.endianness
= 0;
2960 qemu_mutex_init(&vs
->output_mutex
);
2961 vs
->bh
= qemu_bh_new(vnc_jobs_bh
, vs
);
2963 QTAILQ_INSERT_TAIL(&vd
->clients
, vs
, next
);
2965 vnc_update_server_surface(vd
);
2968 graphic_hw_update(vd
->dcl
.con
);
2970 if (!vs
->websocket
) {
2971 vnc_start_protocol(vs
);
2974 if (vd
->num_connecting
> vd
->connections_limit
) {
2975 QTAILQ_FOREACH(vs
, &vd
->clients
, next
) {
2976 if (vs
->share_mode
== VNC_SHARE_MODE_CONNECTING
) {
2977 vnc_disconnect_start(vs
);
2984 void vnc_start_protocol(VncState
*vs
)
2986 vnc_write(vs
, "RFB 003.008\n", 12);
2988 vnc_read_when(vs
, protocol_version
, 12);
2990 vs
->mouse_mode_notifier
.notify
= check_pointer_type_change
;
2991 qemu_add_mouse_mode_change_notifier(&vs
->mouse_mode_notifier
);
2994 static gboolean
vnc_listen_io(QIOChannel
*ioc
,
2995 GIOCondition condition
,
2998 VncDisplay
*vd
= opaque
;
2999 QIOChannelSocket
*sioc
= NULL
;
3001 bool isWebsock
= false;
3004 for (i
= 0; i
< vd
->nlwebsock
; i
++) {
3005 if (ioc
== QIO_CHANNEL(vd
->lwebsock
[i
])) {
3011 sioc
= qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc
), &err
);
3013 qio_channel_set_name(QIO_CHANNEL(sioc
),
3014 isWebsock
? "vnc-ws-server" : "vnc-server");
3015 qio_channel_set_delay(QIO_CHANNEL(sioc
), false);
3016 vnc_connect(vd
, sioc
, false, isWebsock
);
3017 object_unref(OBJECT(sioc
));
3019 /* client probably closed connection before we got there */
3026 static const DisplayChangeListenerOps dcl_ops
= {
3028 .dpy_refresh
= vnc_refresh
,
3029 .dpy_gfx_update
= vnc_dpy_update
,
3030 .dpy_gfx_switch
= vnc_dpy_switch
,
3031 .dpy_gfx_check_format
= qemu_pixman_check_format
,
3032 .dpy_mouse_set
= vnc_mouse_set
,
3033 .dpy_cursor_define
= vnc_dpy_cursor_define
,
3036 void vnc_display_init(const char *id
)
3040 if (vnc_display_find(id
) != NULL
) {
3043 vd
= g_malloc0(sizeof(*vd
));
3045 vd
->id
= strdup(id
);
3046 QTAILQ_INSERT_TAIL(&vnc_displays
, vd
, next
);
3048 QTAILQ_INIT(&vd
->clients
);
3049 vd
->expires
= TIME_MAX
;
3051 if (keyboard_layout
) {
3052 trace_vnc_key_map_init(keyboard_layout
);
3053 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, keyboard_layout
);
3055 vd
->kbd_layout
= init_keyboard_layout(name2keysym
, "en-us");
3058 if (!vd
->kbd_layout
) {
3062 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3063 vd
->connections_limit
= 32;
3065 qemu_mutex_init(&vd
->mutex
);
3066 vnc_start_worker_thread();
3068 vd
->dcl
.ops
= &dcl_ops
;
3069 register_displaychangelistener(&vd
->dcl
);
3073 static void vnc_display_close(VncDisplay
*vd
)
3079 vd
->is_unix
= false;
3080 for (i
= 0; i
< vd
->nlsock
; i
++) {
3081 if (vd
->lsock_tag
[i
]) {
3082 g_source_remove(vd
->lsock_tag
[i
]);
3084 object_unref(OBJECT(vd
->lsock
[i
]));
3087 g_free(vd
->lsock_tag
);
3089 vd
->lsock_tag
= NULL
;
3092 for (i
= 0; i
< vd
->nlwebsock
; i
++) {
3093 if (vd
->lwebsock_tag
[i
]) {
3094 g_source_remove(vd
->lwebsock_tag
[i
]);
3096 object_unref(OBJECT(vd
->lwebsock
[i
]));
3098 g_free(vd
->lwebsock
);
3099 g_free(vd
->lwebsock_tag
);
3100 vd
->lwebsock
= NULL
;
3101 vd
->lwebsock_tag
= NULL
;
3104 vd
->auth
= VNC_AUTH_INVALID
;
3105 vd
->subauth
= VNC_AUTH_INVALID
;
3107 object_unparent(OBJECT(vd
->tlscreds
));
3108 vd
->tlscreds
= NULL
;
3110 g_free(vd
->tlsaclname
);
3111 vd
->tlsaclname
= NULL
;
3112 if (vd
->lock_key_sync
) {
3113 qemu_remove_led_event_handler(vd
->led
);
3118 int vnc_display_password(const char *id
, const char *password
)
3120 VncDisplay
*vd
= vnc_display_find(id
);
3125 if (vd
->auth
== VNC_AUTH_NONE
) {
3126 error_printf_unless_qmp("If you want use passwords please enable "
3127 "password auth using '-vnc ${dpy},password'.\n");
3131 g_free(vd
->password
);
3132 vd
->password
= g_strdup(password
);
3137 int vnc_display_pw_expire(const char *id
, time_t expires
)
3139 VncDisplay
*vd
= vnc_display_find(id
);
3145 vd
->expires
= expires
;
3149 static void vnc_display_print_local_addr(VncDisplay
*vd
)
3151 SocketAddress
*addr
;
3158 addr
= qio_channel_socket_get_local_address(vd
->lsock
[0], &err
);
3163 if (addr
->type
!= SOCKET_ADDRESS_TYPE_INET
) {
3164 qapi_free_SocketAddress(addr
);
3167 error_printf_unless_qmp("VNC server running on %s:%s\n",
3170 qapi_free_SocketAddress(addr
);
3173 static QemuOptsList qemu_vnc_opts
= {
3175 .head
= QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts
.head
),
3176 .implied_opt_name
= "vnc",
3180 .type
= QEMU_OPT_STRING
,
3182 .name
= "websocket",
3183 .type
= QEMU_OPT_STRING
,
3185 .name
= "tls-creds",
3186 .type
= QEMU_OPT_STRING
,
3188 /* Deprecated in favour of tls-creds */
3190 .type
= QEMU_OPT_STRING
,
3193 .type
= QEMU_OPT_STRING
,
3196 .type
= QEMU_OPT_STRING
,
3199 .type
= QEMU_OPT_NUMBER
,
3201 .name
= "connections",
3202 .type
= QEMU_OPT_NUMBER
,
3205 .type
= QEMU_OPT_NUMBER
,
3208 .type
= QEMU_OPT_BOOL
,
3211 .type
= QEMU_OPT_BOOL
,
3214 .type
= QEMU_OPT_BOOL
,
3217 .type
= QEMU_OPT_BOOL
,
3219 .name
= "lock-key-sync",
3220 .type
= QEMU_OPT_BOOL
,
3222 .name
= "key-delay-ms",
3223 .type
= QEMU_OPT_NUMBER
,
3226 .type
= QEMU_OPT_BOOL
,
3228 /* Deprecated in favour of tls-creds */
3230 .type
= QEMU_OPT_BOOL
,
3232 /* Deprecated in favour of tls-creds */
3233 .name
= "x509verify",
3234 .type
= QEMU_OPT_STRING
,
3237 .type
= QEMU_OPT_BOOL
,
3240 .type
= QEMU_OPT_BOOL
,
3242 .name
= "non-adaptive",
3243 .type
= QEMU_OPT_BOOL
,
3245 { /* end of list */ }
3251 vnc_display_setup_auth(int *auth
,
3253 QCryptoTLSCreds
*tlscreds
,
3260 * We have a choice of 3 authentication options
3266 * The channel can be run in 2 modes
3271 * And TLS can use 2 types of credentials
3276 * We thus have 9 possible logical combinations
3281 * 4. tls + anon + none
3282 * 5. tls + anon + vnc
3283 * 6. tls + anon + sasl
3284 * 7. tls + x509 + none
3285 * 8. tls + x509 + vnc
3286 * 9. tls + x509 + sasl
3288 * These need to be mapped into the VNC auth schemes
3289 * in an appropriate manner. In regular VNC, all the
3290 * TLS options get mapped into VNC_AUTH_VENCRYPT
3293 * In websockets, the https:// protocol already provides
3294 * TLS support, so there is no need to make use of the
3295 * VeNCrypt extension. Furthermore, websockets browser
3296 * clients could not use VeNCrypt even if they wanted to,
3297 * as they cannot control when the TLS handshake takes
3298 * place. Thus there is no option but to rely on https://,
3299 * meaning combinations 4->6 and 7->9 will be mapped to
3300 * VNC auth schemes in the same way as combos 1->3.
3302 * Regardless of fact that we have a different mapping to
3303 * VNC auth mechs for plain VNC vs websockets VNC, the end
3304 * result has the same security characteristics.
3306 if (websocket
|| !tlscreds
) {
3308 VNC_DEBUG("Initializing VNC server with password auth\n");
3309 *auth
= VNC_AUTH_VNC
;
3311 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3312 *auth
= VNC_AUTH_SASL
;
3314 VNC_DEBUG("Initializing VNC server with no auth\n");
3315 *auth
= VNC_AUTH_NONE
;
3317 *subauth
= VNC_AUTH_INVALID
;
3319 bool is_x509
= object_dynamic_cast(OBJECT(tlscreds
),
3320 TYPE_QCRYPTO_TLS_CREDS_X509
) != NULL
;
3321 bool is_anon
= object_dynamic_cast(OBJECT(tlscreds
),
3322 TYPE_QCRYPTO_TLS_CREDS_ANON
) != NULL
;
3324 if (!is_x509
&& !is_anon
) {
3326 "Unsupported TLS cred type %s",
3327 object_get_typename(OBJECT(tlscreds
)));
3330 *auth
= VNC_AUTH_VENCRYPT
;
3333 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3334 *subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
3336 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3337 *subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
3342 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3343 *subauth
= VNC_AUTH_VENCRYPT_X509SASL
;
3345 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3346 *subauth
= VNC_AUTH_VENCRYPT_TLSSASL
;
3350 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3351 *subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
3353 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3354 *subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
3363 * Handle back compat with old CLI syntax by creating some
3364 * suitable QCryptoTLSCreds objects
3366 static QCryptoTLSCreds
*
3367 vnc_display_create_creds(bool x509
,
3373 gchar
*credsid
= g_strdup_printf("tlsvnc%s", id
);
3374 Object
*parent
= object_get_objects_root();
3379 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509
,
3383 "endpoint", "server",
3385 "verify-peer", x509verify
? "yes" : "no",
3388 creds
= object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON
,
3392 "endpoint", "server",
3399 error_propagate(errp
, err
);
3403 return QCRYPTO_TLS_CREDS(creds
);
3407 static int vnc_display_get_address(const char *addrstr
,
3416 SocketAddress
**retaddr
,
3420 SocketAddress
*addr
= NULL
;
3422 addr
= g_new0(SocketAddress
, 1);
3424 if (strncmp(addrstr
, "unix:", 5) == 0) {
3425 addr
->type
= SOCKET_ADDRESS_TYPE_UNIX
;
3426 addr
->u
.q_unix
.path
= g_strdup(addrstr
+ 5);
3429 error_setg(errp
, "UNIX sockets not supported with websock");
3434 error_setg(errp
, "Port range not support with UNIX socket");
3441 unsigned long long baseport
= 0;
3442 InetSocketAddress
*inet
;
3444 port
= strrchr(addrstr
, ':');
3450 error_setg(errp
, "no vnc port specified");
3454 hostlen
= port
- addrstr
;
3456 if (*port
== '\0') {
3457 error_setg(errp
, "vnc port cannot be empty");
3462 addr
->type
= SOCKET_ADDRESS_TYPE_INET
;
3463 inet
= &addr
->u
.inet
;
3464 if (addrstr
[0] == '[' && addrstr
[hostlen
- 1] == ']') {
3465 inet
->host
= g_strndup(addrstr
+ 1, hostlen
- 2);
3467 inet
->host
= g_strndup(addrstr
, hostlen
);
3469 /* plain VNC port is just an offset, for websocket
3470 * port is absolute */
3472 if (g_str_equal(addrstr
, "") ||
3473 g_str_equal(addrstr
, "on")) {
3474 if (displaynum
== -1) {
3475 error_setg(errp
, "explicit websocket port is required");
3478 inet
->port
= g_strdup_printf(
3479 "%d", displaynum
+ 5700);
3481 inet
->has_to
= true;
3482 inet
->to
= to
+ 5700;
3485 inet
->port
= g_strdup(port
);
3488 int offset
= reverse
? 0 : 5900;
3489 if (parse_uint_full(port
, &baseport
, 10) < 0) {
3490 error_setg(errp
, "can't convert to a number: %s", port
);
3493 if (baseport
> 65535 ||
3494 baseport
+ offset
> 65535) {
3495 error_setg(errp
, "port %s out of range", port
);
3498 inet
->port
= g_strdup_printf(
3499 "%d", (int)baseport
+ offset
);
3502 inet
->has_to
= true;
3503 inet
->to
= to
+ offset
;
3508 inet
->has_ipv4
= has_ipv4
;
3510 inet
->has_ipv6
= has_ipv6
;
3519 qapi_free_SocketAddress(addr
);
3524 static void vnc_free_addresses(SocketAddress
***retsaddr
,
3529 for (i
= 0; i
< *retnsaddr
; i
++) {
3530 qapi_free_SocketAddress((*retsaddr
)[i
]);
3538 static int vnc_display_get_addresses(QemuOpts
*opts
,
3540 SocketAddress
***retsaddr
,
3542 SocketAddress
***retwsaddr
,
3546 SocketAddress
*saddr
= NULL
;
3547 SocketAddress
*wsaddr
= NULL
;
3548 QemuOptsIter addriter
;
3550 int to
= qemu_opt_get_number(opts
, "to", 0);
3551 bool has_ipv4
= qemu_opt_get(opts
, "ipv4");
3552 bool has_ipv6
= qemu_opt_get(opts
, "ipv6");
3553 bool ipv4
= qemu_opt_get_bool(opts
, "ipv4", false);
3554 bool ipv6
= qemu_opt_get_bool(opts
, "ipv6", false);
3555 int displaynum
= -1;
3563 addr
= qemu_opt_get(opts
, "vnc");
3564 if (addr
== NULL
|| g_str_equal(addr
, "none")) {
3568 if (qemu_opt_get(opts
, "websocket") &&
3569 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1
)) {
3571 "SHA1 hash support is required for websockets");
3575 qemu_opt_iter_init(&addriter
, opts
, "vnc");
3576 while ((addr
= qemu_opt_iter_next(&addriter
)) != NULL
) {
3578 rv
= vnc_display_get_address(addr
, false, reverse
, 0, to
,
3585 /* Historical compat - first listen address can be used
3586 * to set the default websocket port
3588 if (displaynum
== -1) {
3591 *retsaddr
= g_renew(SocketAddress
*, *retsaddr
, *retnsaddr
+ 1);
3592 (*retsaddr
)[(*retnsaddr
)++] = saddr
;
3595 /* If we had multiple primary displays, we don't do defaults
3596 * for websocket, and require explicit config instead. */
3597 if (*retnsaddr
> 1) {
3601 qemu_opt_iter_init(&addriter
, opts
, "websocket");
3602 while ((addr
= qemu_opt_iter_next(&addriter
)) != NULL
) {
3603 if (vnc_display_get_address(addr
, true, reverse
, displaynum
, to
,
3606 &wsaddr
, errp
) < 0) {
3610 /* Historical compat - if only a single listen address was
3611 * provided, then this is used to set the default listen
3612 * address for websocket too
3614 if (*retnsaddr
== 1 &&
3615 (*retsaddr
)[0]->type
== SOCKET_ADDRESS_TYPE_INET
&&
3616 wsaddr
->type
== SOCKET_ADDRESS_TYPE_INET
&&
3617 g_str_equal(wsaddr
->u
.inet
.host
, "") &&
3618 !g_str_equal((*retsaddr
)[0]->u
.inet
.host
, "")) {
3619 g_free(wsaddr
->u
.inet
.host
);
3620 wsaddr
->u
.inet
.host
= g_strdup((*retsaddr
)[0]->u
.inet
.host
);
3623 *retwsaddr
= g_renew(SocketAddress
*, *retwsaddr
, *retnwsaddr
+ 1);
3624 (*retwsaddr
)[(*retnwsaddr
)++] = wsaddr
;
3630 vnc_free_addresses(retsaddr
, retnsaddr
);
3631 vnc_free_addresses(retwsaddr
, retnwsaddr
);
3636 static int vnc_display_connect(VncDisplay
*vd
,
3637 SocketAddress
**saddr
,
3639 SocketAddress
**wsaddr
,
3643 /* connect to viewer */
3644 QIOChannelSocket
*sioc
= NULL
;
3646 error_setg(errp
, "Cannot use websockets in reverse mode");
3650 error_setg(errp
, "Expected a single address in reverse mode");
3653 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3654 vd
->is_unix
= saddr
[0]->type
== SOCKET_ADDRESS_TYPE_UNIX
;
3655 sioc
= qio_channel_socket_new();
3656 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-reverse");
3657 if (qio_channel_socket_connect_sync(sioc
, saddr
[0], errp
) < 0) {
3660 vnc_connect(vd
, sioc
, false, false);
3661 object_unref(OBJECT(sioc
));
3666 static int vnc_display_listen_addr(VncDisplay
*vd
,
3667 SocketAddress
*addr
,
3669 QIOChannelSocket
***lsock
,
3674 QIODNSResolver
*resolver
= qio_dns_resolver_get_instance();
3675 SocketAddress
**rawaddrs
= NULL
;
3676 size_t nrawaddrs
= 0;
3677 Error
*listenerr
= NULL
;
3678 bool listening
= false;
3681 if (qio_dns_resolver_lookup_sync(resolver
, addr
, &nrawaddrs
,
3682 &rawaddrs
, errp
) < 0) {
3686 for (i
= 0; i
< nrawaddrs
; i
++) {
3687 QIOChannelSocket
*sioc
= qio_channel_socket_new();
3689 qio_channel_set_name(QIO_CHANNEL(sioc
), name
);
3690 if (qio_channel_socket_listen_sync(
3691 sioc
, rawaddrs
[i
], listenerr
== NULL
? &listenerr
: NULL
) < 0) {
3692 object_unref(OBJECT(sioc
));
3697 *lsock
= g_renew(QIOChannelSocket
*, *lsock
, *nlsock
);
3698 *lsock_tag
= g_renew(guint
, *lsock_tag
, *nlsock
);
3700 (*lsock
)[*nlsock
- 1] = sioc
;
3701 (*lsock_tag
)[*nlsock
- 1] = 0;
3704 for (i
= 0; i
< nrawaddrs
; i
++) {
3705 qapi_free_SocketAddress(rawaddrs
[i
]);
3711 error_propagate(errp
, listenerr
);
3714 error_free(listenerr
);
3718 for (i
= 0; i
< *nlsock
; i
++) {
3719 (*lsock_tag
)[i
] = qio_channel_add_watch(
3720 QIO_CHANNEL((*lsock
)[i
]),
3721 G_IO_IN
, vnc_listen_io
, vd
, NULL
);
3728 static int vnc_display_listen(VncDisplay
*vd
,
3729 SocketAddress
**saddr
,
3731 SocketAddress
**wsaddr
,
3737 for (i
= 0; i
< nsaddr
; i
++) {
3738 if (vnc_display_listen_addr(vd
, saddr
[i
],
3747 for (i
= 0; i
< nwsaddr
; i
++) {
3748 if (vnc_display_listen_addr(vd
, wsaddr
[i
],
3762 void vnc_display_open(const char *id
, Error
**errp
)
3764 VncDisplay
*vd
= vnc_display_find(id
);
3765 QemuOpts
*opts
= qemu_opts_find(&qemu_vnc_opts
, id
);
3766 SocketAddress
**saddr
= NULL
, **wsaddr
= NULL
;
3767 size_t nsaddr
, nwsaddr
;
3768 const char *share
, *device_id
;
3770 bool password
= false;
3771 bool reverse
= false;
3774 #ifdef CONFIG_VNC_SASL
3778 int lock_key_sync
= 1;
3782 error_setg(errp
, "VNC display not active");
3785 vnc_display_close(vd
);
3791 reverse
= qemu_opt_get_bool(opts
, "reverse", false);
3792 if (vnc_display_get_addresses(opts
, reverse
, &saddr
, &nsaddr
,
3793 &wsaddr
, &nwsaddr
, errp
) < 0) {
3797 password
= qemu_opt_get_bool(opts
, "password", false);
3799 if (fips_get_state()) {
3801 "VNC password auth disabled due to FIPS mode, "
3802 "consider using the VeNCrypt or SASL authentication "
3803 "methods as an alternative");
3806 if (!qcrypto_cipher_supports(
3807 QCRYPTO_CIPHER_ALG_DES_RFB
, QCRYPTO_CIPHER_MODE_ECB
)) {
3809 "Cipher backend does not support DES RFB algorithm");
3814 lock_key_sync
= qemu_opt_get_bool(opts
, "lock-key-sync", true);
3815 key_delay_ms
= qemu_opt_get_number(opts
, "key-delay-ms", 10);
3816 sasl
= qemu_opt_get_bool(opts
, "sasl", false);
3817 #ifndef CONFIG_VNC_SASL
3819 error_setg(errp
, "VNC SASL auth requires cyrus-sasl support");
3822 #endif /* CONFIG_VNC_SASL */
3823 credid
= qemu_opt_get(opts
, "tls-creds");
3826 if (qemu_opt_get(opts
, "tls") ||
3827 qemu_opt_get(opts
, "x509") ||
3828 qemu_opt_get(opts
, "x509verify")) {
3830 "'tls-creds' parameter is mutually exclusive with "
3831 "'tls', 'x509' and 'x509verify' parameters");
3835 creds
= object_resolve_path_component(
3836 object_get_objects_root(), credid
);
3838 error_setg(errp
, "No TLS credentials with id '%s'",
3842 vd
->tlscreds
= (QCryptoTLSCreds
*)
3843 object_dynamic_cast(creds
,
3844 TYPE_QCRYPTO_TLS_CREDS
);
3845 if (!vd
->tlscreds
) {
3846 error_setg(errp
, "Object with id '%s' is not TLS credentials",
3850 object_ref(OBJECT(vd
->tlscreds
));
3852 if (vd
->tlscreds
->endpoint
!= QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
) {
3854 "Expecting TLS credentials with a server endpoint");
3859 bool tls
= false, x509
= false, x509verify
= false;
3860 tls
= qemu_opt_get_bool(opts
, "tls", false);
3862 path
= qemu_opt_get(opts
, "x509");
3867 path
= qemu_opt_get(opts
, "x509verify");
3873 vd
->tlscreds
= vnc_display_create_creds(x509
,
3878 if (!vd
->tlscreds
) {
3883 acl
= qemu_opt_get_bool(opts
, "acl", false);
3885 share
= qemu_opt_get(opts
, "share");
3887 if (strcmp(share
, "ignore") == 0) {
3888 vd
->share_policy
= VNC_SHARE_POLICY_IGNORE
;
3889 } else if (strcmp(share
, "allow-exclusive") == 0) {
3890 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3891 } else if (strcmp(share
, "force-shared") == 0) {
3892 vd
->share_policy
= VNC_SHARE_POLICY_FORCE_SHARED
;
3894 error_setg(errp
, "unknown vnc share= option");
3898 vd
->share_policy
= VNC_SHARE_POLICY_ALLOW_EXCLUSIVE
;
3900 vd
->connections_limit
= qemu_opt_get_number(opts
, "connections", 32);
3902 #ifdef CONFIG_VNC_JPEG
3903 vd
->lossy
= qemu_opt_get_bool(opts
, "lossy", false);
3905 vd
->non_adaptive
= qemu_opt_get_bool(opts
, "non-adaptive", false);
3906 /* adaptive updates are only used with tight encoding and
3907 * if lossy updates are enabled so we can disable all the
3908 * calculations otherwise */
3910 vd
->non_adaptive
= true;
3914 if (strcmp(vd
->id
, "default") == 0) {
3915 vd
->tlsaclname
= g_strdup("vnc.x509dname");
3917 vd
->tlsaclname
= g_strdup_printf("vnc.%s.x509dname", vd
->id
);
3919 qemu_acl_init(vd
->tlsaclname
);
3921 #ifdef CONFIG_VNC_SASL
3925 if (strcmp(vd
->id
, "default") == 0) {
3926 aclname
= g_strdup("vnc.username");
3928 aclname
= g_strdup_printf("vnc.%s.username", vd
->id
);
3930 vd
->sasl
.acl
= qemu_acl_init(aclname
);
3935 if (vnc_display_setup_auth(&vd
->auth
, &vd
->subauth
,
3936 vd
->tlscreds
, password
,
3937 sasl
, false, errp
) < 0) {
3941 if (vnc_display_setup_auth(&vd
->ws_auth
, &vd
->ws_subauth
,
3942 vd
->tlscreds
, password
,
3943 sasl
, true, errp
) < 0) {
3947 #ifdef CONFIG_VNC_SASL
3948 if ((saslErr
= sasl_server_init(NULL
, "qemu")) != SASL_OK
) {
3949 error_setg(errp
, "Failed to initialize SASL auth: %s",
3950 sasl_errstring(saslErr
, NULL
, NULL
));
3954 vd
->lock_key_sync
= lock_key_sync
;
3955 if (lock_key_sync
) {
3956 vd
->led
= qemu_add_led_event_handler(kbd_leds
, vd
);
3959 vd
->key_delay_ms
= key_delay_ms
;
3961 device_id
= qemu_opt_get(opts
, "display");
3963 int head
= qemu_opt_get_number(opts
, "head", 0);
3966 con
= qemu_console_lookup_by_device_name(device_id
, head
, &err
);
3968 error_propagate(errp
, err
);
3975 if (con
!= vd
->dcl
.con
) {
3976 unregister_displaychangelistener(&vd
->dcl
);
3978 register_displaychangelistener(&vd
->dcl
);
3981 if (saddr
== NULL
) {
3986 if (vnc_display_connect(vd
, saddr
, nsaddr
, wsaddr
, nwsaddr
, errp
) < 0) {
3990 if (vnc_display_listen(vd
, saddr
, nsaddr
, wsaddr
, nwsaddr
, errp
) < 0) {
3995 if (qemu_opt_get(opts
, "to")) {
3996 vnc_display_print_local_addr(vd
);
4000 vnc_free_addresses(&saddr
, &nsaddr
);
4001 vnc_free_addresses(&wsaddr
, &nwsaddr
);
4005 vnc_display_close(vd
);
4009 void vnc_display_add_client(const char *id
, int csock
, bool skipauth
)
4011 VncDisplay
*vd
= vnc_display_find(id
);
4012 QIOChannelSocket
*sioc
;
4018 sioc
= qio_channel_socket_new_fd(csock
, NULL
);
4020 qio_channel_set_name(QIO_CHANNEL(sioc
), "vnc-server");
4021 vnc_connect(vd
, sioc
, skipauth
, false);
4022 object_unref(OBJECT(sioc
));
4026 static void vnc_auto_assign_id(QemuOptsList
*olist
, QemuOpts
*opts
)
4031 id
= g_strdup("default");
4032 while (qemu_opts_find(olist
, id
)) {
4034 id
= g_strdup_printf("vnc%d", i
++);
4036 qemu_opts_set_id(opts
, id
);
4039 QemuOpts
*vnc_parse(const char *str
, Error
**errp
)
4041 QemuOptsList
*olist
= qemu_find_opts("vnc");
4042 QemuOpts
*opts
= qemu_opts_parse(olist
, str
, true, errp
);
4049 id
= qemu_opts_id(opts
);
4051 /* auto-assign id if not present */
4052 vnc_auto_assign_id(olist
, opts
);
4057 int vnc_init_func(void *opaque
, QemuOpts
*opts
, Error
**errp
)
4059 Error
*local_err
= NULL
;
4060 char *id
= (char *)qemu_opts_id(opts
);
4063 vnc_display_init(id
);
4064 vnc_display_open(id
, &local_err
);
4065 if (local_err
!= NULL
) {
4066 error_reportf_err(local_err
, "Failed to start VNC server: ");
4072 static void vnc_register_config(void)
4074 qemu_add_opts(&qemu_vnc_opts
);
4076 opts_init(vnc_register_config
);